fix login and some errors while login
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
function normalizeAssetPrefix(rawValue, basePath) {
|
||||
if (!rawValue) return undefined
|
||||
|
||||
try {
|
||||
const url = new URL(rawValue)
|
||||
const pathname = url.pathname.replace(/\/$/, '')
|
||||
if (!pathname.endsWith(basePath)) {
|
||||
url.pathname = `${pathname}${basePath}`
|
||||
}
|
||||
return url.toString().replace(/\/$/, '')
|
||||
} catch {
|
||||
const trimmed = rawValue.replace(/\/$/, '')
|
||||
return trimmed.endsWith(basePath) ? trimmed : `${trimmed}${basePath}`
|
||||
}
|
||||
}
|
||||
|
||||
function collectOrigins(assetSources) {
|
||||
const origins = new Set()
|
||||
|
||||
for (const source of assetSources) {
|
||||
if (!source) continue
|
||||
|
||||
try {
|
||||
origins.add(new URL(source).origin)
|
||||
} catch {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
return [...origins]
|
||||
}
|
||||
|
||||
function collectWebSocketOrigins(assetSources) {
|
||||
const origins = new Set()
|
||||
|
||||
for (const source of assetSources) {
|
||||
if (!source) continue
|
||||
|
||||
try {
|
||||
const url = new URL(source)
|
||||
const protocol = url.protocol === 'https:' ? 'wss:' : 'ws:'
|
||||
origins.add(`${protocol}//${url.host}`)
|
||||
} catch {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
return [...origins]
|
||||
}
|
||||
|
||||
function collectBrowserApiSources() {
|
||||
const sources = [process.env.NEXT_PUBLIC_API_URL, process.env.API_URL]
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
sources.push('http://localhost:4000/api/v1')
|
||||
}
|
||||
|
||||
return sources
|
||||
}
|
||||
|
||||
function buildSecurityHeaders({ assetSources = [], connectSources = collectBrowserApiSources() } = {}) {
|
||||
const assetOrigins = collectOrigins(assetSources)
|
||||
const connectOrigins = collectOrigins(connectSources)
|
||||
const websocketOrigins = [
|
||||
...collectWebSocketOrigins(assetSources),
|
||||
...collectWebSocketOrigins(connectSources),
|
||||
]
|
||||
|
||||
const scriptSrc = ["'self'", "'unsafe-inline'"]
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
scriptSrc.push("'unsafe-eval'")
|
||||
}
|
||||
scriptSrc.push(...assetOrigins)
|
||||
|
||||
const styleSrc = ["'self'", "'unsafe-inline'", ...assetOrigins]
|
||||
const imgSrc = ["'self'", 'data:', 'blob:', 'https:', ...assetOrigins]
|
||||
const fontSrc = ["'self'", 'data:', ...assetOrigins]
|
||||
const connectSrc = [...new Set(["'self'", 'https:', 'wss:', ...assetOrigins, ...connectOrigins, ...websocketOrigins])]
|
||||
|
||||
return [
|
||||
{ key: 'Strict-Transport-Security', value: 'max-age=31536000; includeSubDomains' },
|
||||
{ key: 'X-Content-Type-Options', value: 'nosniff' },
|
||||
{ key: 'X-Frame-Options', value: 'DENY' },
|
||||
{ key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' },
|
||||
{ key: 'Permissions-Policy', value: 'camera=(), microphone=(), geolocation=()' },
|
||||
{
|
||||
key: 'Content-Security-Policy',
|
||||
value: [
|
||||
"default-src 'self'",
|
||||
`script-src ${scriptSrc.join(' ')}`,
|
||||
`style-src ${styleSrc.join(' ')}`,
|
||||
`img-src ${imgSrc.join(' ')}`,
|
||||
`font-src ${fontSrc.join(' ')}`,
|
||||
`connect-src ${connectSrc.join(' ')}`,
|
||||
"frame-ancestors 'none'",
|
||||
"base-uri 'self'",
|
||||
"form-action 'self'",
|
||||
"object-src 'none'",
|
||||
].join('; '),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
buildSecurityHeaders,
|
||||
normalizeAssetPrefix,
|
||||
}
|
||||
Reference in New Issue
Block a user