36 lines
1.2 KiB
JavaScript
36 lines
1.2 KiB
JavaScript
/** 登录后的站内回跳规则;只接受单斜杠开头路径,拒绝外站、反斜杠和控制字符。 */
|
|
function e(e) {
|
|
if (
|
|
typeof e != `string` ||
|
|
!e.startsWith(`/`) ||
|
|
e.startsWith(`//`) ||
|
|
// eslint-disable-next-line no-control-regex -- 安全边界:拒绝跳转路径中的控制字符。
|
|
/[\\\u0000-\u0020\u007f]/.test(e)
|
|
)
|
|
return `/`;
|
|
try {
|
|
// 路径解码后再次检查,避免编码后的双斜杠或反斜杠绕过站内限制。
|
|
let t = decodeURIComponent(e.split(/[?#]/, 1)[0] || ``);
|
|
// eslint-disable-next-line no-control-regex -- 安全边界:解码后仍须拒绝控制字符绕过。
|
|
if (t.startsWith(`//`) || /[\\\u0000-\u0020\u007f]/.test(t)) return `/`;
|
|
} catch {
|
|
return `/`;
|
|
}
|
|
return e;
|
|
}
|
|
// 首页不需要额外 query;无效的 redirect 也会被归一为首页。
|
|
function t(t) {
|
|
let n = e(t);
|
|
return n === `/`
|
|
? {}
|
|
: {
|
|
redirect: n,
|
|
};
|
|
}
|
|
// t 是调用方提供的登录/注册入口,n 是待校验回跳路径;整段编码后作为单一参数附加。
|
|
function n(t, n) {
|
|
let r = e(n);
|
|
return r === `/` ? t : `${t}?redirect=${encodeURIComponent(r)}`;
|
|
}
|
|
export { t as n, e as r, n as t };
|