/**
* ログイン後の戻り先を安全な値に丸める(純粋関数)。
*
* ★オープンリダイレクト対策★
* proxy が `/login?next=<元のパス>` へ飛ばすので、`next` はクエリ経由=利用者が
* 自由に書ける値になる。そのまま `router.replace()` に渡すと、
* `?next=//evil.example` のような値で外部サイトへ飛ばされる(フィッシングの踏み台)。
* ★自サイト内の絶対パスだけを認め、それ以外は既定へ落とす★
*/
/** 戻り先が決められないときの既定 */
export const DEFAULT_NEXT_PATH = "/dashboard";
export function safeNextPath(value: string | null | undefined): string {
if (!value) return DEFAULT_NEXT_PATH;
// 自サイト内の絶対パスのみ。`//evil.example`(プロトコル相対)と
// `/\evil.example`(ブラウザが `//` と解釈する)を弾く
if (!value.startsWith("/")) return DEFAULT_NEXT_PATH;
if (value.startsWith("//") || value.startsWith("/\\")) {
return DEFAULT_NEXT_PATH;
}
// ログイン後に /login へ戻すとループする
if (value === "/login" || value.startsWith("/login/")) {
return DEFAULT_NEXT_PATH;
}
if (value.startsWith("/login?")) return DEFAULT_NEXT_PATH;
return value;
}