feat: refine registration UX and migrate middleware CORS
This commit is contained in:
parent
fee51ac323
commit
caa658cabb
BIN
frontend.log
Normal file
BIN
frontend.log
Normal file
Binary file not shown.
@ -62,6 +62,20 @@ const nextConfig = {
|
|||||||
|
|
||||||
return config;
|
return config;
|
||||||
},
|
},
|
||||||
|
async headers() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
source: "/api/:path*",
|
||||||
|
headers: [
|
||||||
|
{ key: "Access-Control-Allow-Credentials", value: "true" },
|
||||||
|
{ key: "Access-Control-Allow-Origin", value: process.env.CORS_ALLOWED_ORIGINS || "https://console.svc.plus,http://localhost:3000" },
|
||||||
|
{ key: "Access-Control-Allow-Methods", value: "GET,POST,PUT,PATCH,DELETE,OPTIONS" },
|
||||||
|
{ key: "Access-Control-Allow-Headers", value: "Content-Type, Authorization, X-Requested-With, X-Account-Session" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
},
|
||||||
|
|
||||||
reactStrictMode: true,
|
reactStrictMode: true,
|
||||||
typedRoutes: false,
|
typedRoutes: false,
|
||||||
turbopack: {
|
turbopack: {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -222,6 +222,8 @@ type AuthRegisterTranslation = {
|
|||||||
form: {
|
form: {
|
||||||
title: string
|
title: string
|
||||||
subtitle: string
|
subtitle: string
|
||||||
|
name: string
|
||||||
|
namePlaceholder: string
|
||||||
email: string
|
email: string
|
||||||
emailPlaceholder: string
|
emailPlaceholder: string
|
||||||
password: string
|
password: string
|
||||||
@ -723,6 +725,8 @@ export const translations: Record<'en' | 'zh', Translation> = {
|
|||||||
form: {
|
form: {
|
||||||
title: 'Create your account',
|
title: 'Create your account',
|
||||||
subtitle: 'Submit your email and password, request the code, and enter it to activate your account.',
|
subtitle: 'Submit your email and password, request the code, and enter it to activate your account.',
|
||||||
|
name: 'Username',
|
||||||
|
namePlaceholder: '4-16 chars, starts with letter',
|
||||||
email: 'Work email',
|
email: 'Work email',
|
||||||
emailPlaceholder: 'name@example.com',
|
emailPlaceholder: 'name@example.com',
|
||||||
password: 'Password',
|
password: 'Password',
|
||||||
@ -1384,6 +1388,8 @@ export const translations: Record<'en' | 'zh', Translation> = {
|
|||||||
form: {
|
form: {
|
||||||
title: '创建账号',
|
title: '创建账号',
|
||||||
subtitle: '先提交邮箱和密码获取验证码,再输入邮箱收到的验证码完成注册。',
|
subtitle: '先提交邮箱和密码获取验证码,再输入邮箱收到的验证码完成注册。',
|
||||||
|
name: '用户名',
|
||||||
|
namePlaceholder: '4-16位字母或数字,字母开头',
|
||||||
email: '邮箱',
|
email: '邮箱',
|
||||||
emailPlaceholder: 'name@example.com',
|
emailPlaceholder: 'name@example.com',
|
||||||
password: '密码',
|
password: '密码',
|
||||||
|
|||||||
@ -1,50 +0,0 @@
|
|||||||
import { NextResponse } from 'next/server'
|
|
||||||
import type { NextRequest } from 'next/server'
|
|
||||||
|
|
||||||
const DEFAULT_ALLOWED_ORIGINS = 'https://console.svc.plus,http://localhost:3000'
|
|
||||||
|
|
||||||
function parseAllowedOrigins() {
|
|
||||||
const raw = process.env.CORS_ALLOWED_ORIGINS ?? DEFAULT_ALLOWED_ORIGINS
|
|
||||||
return raw
|
|
||||||
.split(',')
|
|
||||||
.map((value) => value.trim())
|
|
||||||
.filter(Boolean)
|
|
||||||
}
|
|
||||||
|
|
||||||
function resolveAllowedOrigin(origin: string | null, allowed: string[]) {
|
|
||||||
if (!origin) return null
|
|
||||||
if (allowed.includes('*')) return '*'
|
|
||||||
return allowed.includes(origin) ? origin : null
|
|
||||||
}
|
|
||||||
|
|
||||||
function applyCorsHeaders(response: NextResponse, origin: string | null) {
|
|
||||||
if (!origin) return
|
|
||||||
response.headers.set('Access-Control-Allow-Origin', origin)
|
|
||||||
response.headers.set('Access-Control-Allow-Credentials', 'true')
|
|
||||||
response.headers.set('Access-Control-Allow-Methods', 'GET,POST,PUT,PATCH,DELETE,OPTIONS')
|
|
||||||
response.headers.set(
|
|
||||||
'Access-Control-Allow-Headers',
|
|
||||||
'Content-Type, Authorization, X-Requested-With, X-Account-Session',
|
|
||||||
)
|
|
||||||
response.headers.set('Vary', 'Origin')
|
|
||||||
}
|
|
||||||
|
|
||||||
export function middleware(request: NextRequest) {
|
|
||||||
const allowedOrigins = parseAllowedOrigins()
|
|
||||||
const originHeader = request.headers.get('origin')
|
|
||||||
const allowedOrigin = resolveAllowedOrigin(originHeader, allowedOrigins)
|
|
||||||
|
|
||||||
if (request.method === 'OPTIONS') {
|
|
||||||
const response = new NextResponse(null, { status: 204 })
|
|
||||||
applyCorsHeaders(response, allowedOrigin)
|
|
||||||
return response
|
|
||||||
}
|
|
||||||
|
|
||||||
const response = NextResponse.next()
|
|
||||||
applyCorsHeaders(response, allowedOrigin)
|
|
||||||
return response
|
|
||||||
}
|
|
||||||
|
|
||||||
export const config = {
|
|
||||||
matcher: ['/api/:path*'],
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user