28 lines
1000 B
TypeScript
28 lines
1000 B
TypeScript
const OAUTH_RETURN_COOKIE = 'shahi_google_oauth_return_to';
|
|
const DEFAULT_RETURN_PATH = '/account';
|
|
const SAFE_PATH_PATTERN = /^\/[a-zA-Z0-9/_-]*$/;
|
|
|
|
export function getOAuthReturnCookieName(): string {
|
|
return OAUTH_RETURN_COOKIE;
|
|
}
|
|
|
|
/** Only same-origin relative paths (optionally with query) are allowed after OAuth. */
|
|
export function sanitizeOAuthReturnPath(value: string | null | undefined): string {
|
|
if (!value) return DEFAULT_RETURN_PATH;
|
|
|
|
const trimmed = value.trim();
|
|
if (!trimmed.startsWith('/') || trimmed.startsWith('//') || trimmed.includes('://')) {
|
|
return DEFAULT_RETURN_PATH;
|
|
}
|
|
|
|
const withoutHash = trimmed.split('#')[0] ?? trimmed;
|
|
const queryIndex = withoutHash.indexOf('?');
|
|
const pathname = queryIndex === -1 ? withoutHash : withoutHash.slice(0, queryIndex);
|
|
const search = queryIndex === -1 ? '' : withoutHash.slice(queryIndex);
|
|
|
|
if (!pathname || !SAFE_PATH_PATTERN.test(pathname)) {
|
|
return DEFAULT_RETURN_PATH;
|
|
}
|
|
|
|
return `${pathname}${search}`;
|
|
} |