60 lines
1.5 KiB
TypeScript
60 lines
1.5 KiB
TypeScript
/**
|
|
* Caddy 등 리버스 프록시 뒤에서 request.url 이
|
|
* http://0.0.0.0:13000 처럼 잡히는 경우가 있어, 공개 Origin 을 따로 계산한다.
|
|
*/
|
|
export function getPublicOrigin(request: Request): string {
|
|
const fromEnv =
|
|
process.env.APP_ORIGIN?.trim() ||
|
|
process.env.NEXT_PUBLIC_APP_ORIGIN?.trim();
|
|
if (fromEnv) {
|
|
try {
|
|
return new URL(fromEnv).origin;
|
|
} catch {
|
|
// fall through
|
|
}
|
|
}
|
|
|
|
const redirectUri = process.env.CHZZK_REDIRECT_URI?.trim();
|
|
if (redirectUri) {
|
|
try {
|
|
return new URL(redirectUri).origin;
|
|
} catch {
|
|
// fall through
|
|
}
|
|
}
|
|
|
|
const xfHost = request.headers.get('x-forwarded-host')?.split(',')[0]?.trim();
|
|
const xfProto =
|
|
request.headers.get('x-forwarded-proto')?.split(',')[0]?.trim() || 'https';
|
|
if (xfHost && !isBadHost(xfHost)) {
|
|
return `${xfProto}://${xfHost}`;
|
|
}
|
|
|
|
const host = request.headers.get('host')?.trim();
|
|
if (host && !isBadHost(host)) {
|
|
const proto =
|
|
request.headers.get('x-forwarded-proto')?.split(',')[0]?.trim() ||
|
|
(host.includes('localhost') || host.startsWith('127.') ? 'http' : 'https');
|
|
return `${proto}://${host}`;
|
|
}
|
|
|
|
try {
|
|
const origin = new URL(request.url).origin;
|
|
if (!isBadHost(new URL(origin).host)) return origin;
|
|
} catch {
|
|
// fall through
|
|
}
|
|
|
|
return 'https://drink.kimyu.xyz';
|
|
}
|
|
|
|
function isBadHost(host: string) {
|
|
const h = host.toLowerCase().split(':')[0];
|
|
return (
|
|
h === '0.0.0.0' ||
|
|
h === '::' ||
|
|
h === '[::]' ||
|
|
h === 'host.docker.internal'
|
|
);
|
|
}
|