Files
drinkmarble/lib/auth/public-origin.ts

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'
);
}