@electr0zed/auth-gateway-cf 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +59 -0
- package/dist/auth/index.d.ts +84 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +609 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/pkceState.d.ts +40 -0
- package/dist/auth/pkceState.d.ts.map +1 -0
- package/dist/auth/pkceState.js +75 -0
- package/dist/auth/pkceState.js.map +1 -0
- package/dist/config.example.d.ts +2 -0
- package/dist/config.example.d.ts.map +1 -0
- package/dist/config.example.js +83 -0
- package/dist/config.example.js.map +1 -0
- package/dist/core/gateway.d.ts +11 -0
- package/dist/core/gateway.d.ts.map +1 -0
- package/dist/core/gateway.js +97 -0
- package/dist/core/gateway.js.map +1 -0
- package/dist/do/sessionDo.d.ts +11 -0
- package/dist/do/sessionDo.d.ts.map +1 -0
- package/dist/do/sessionDo.js +96 -0
- package/dist/do/sessionDo.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/providers/baseProvider.d.ts +22 -0
- package/dist/providers/baseProvider.d.ts.map +1 -0
- package/dist/providers/baseProvider.js +129 -0
- package/dist/providers/baseProvider.js.map +1 -0
- package/dist/providers/google.d.ts +9 -0
- package/dist/providers/google.d.ts.map +1 -0
- package/dist/providers/google.js +27 -0
- package/dist/providers/google.js.map +1 -0
- package/dist/providers/index.d.ts +3 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +5 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/routing/routeMatcher.d.ts +15 -0
- package/dist/routing/routeMatcher.d.ts.map +1 -0
- package/dist/routing/routeMatcher.js +83 -0
- package/dist/routing/routeMatcher.js.map +1 -0
- package/dist/sessions/durableObjectSession.d.ts +25 -0
- package/dist/sessions/durableObjectSession.d.ts.map +1 -0
- package/dist/sessions/durableObjectSession.js +90 -0
- package/dist/sessions/durableObjectSession.js.map +1 -0
- package/dist/sessions/index.d.ts +19 -0
- package/dist/sessions/index.d.ts.map +1 -0
- package/dist/sessions/index.js +32 -0
- package/dist/sessions/index.js.map +1 -0
- package/dist/sessions/jwtSession.d.ts +19 -0
- package/dist/sessions/jwtSession.d.ts.map +1 -0
- package/dist/sessions/jwtSession.js +49 -0
- package/dist/sessions/jwtSession.js.map +1 -0
- package/dist/stores/index.d.ts +3 -0
- package/dist/stores/index.d.ts.map +1 -0
- package/dist/stores/index.js +10 -0
- package/dist/stores/index.js.map +1 -0
- package/dist/stores/postgres.d.ts +74 -0
- package/dist/stores/postgres.d.ts.map +1 -0
- package/dist/stores/postgres.js +231 -0
- package/dist/stores/postgres.js.map +1 -0
- package/dist/types.d.ts +247 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/csrf.d.ts +13 -0
- package/dist/utils/csrf.d.ts.map +1 -0
- package/dist/utils/csrf.js +42 -0
- package/dist/utils/csrf.js.map +1 -0
- package/dist/utils/helpers.d.ts +8 -0
- package/dist/utils/helpers.d.ts.map +1 -0
- package/dist/utils/helpers.js +22 -0
- package/dist/utils/helpers.js.map +1 -0
- package/dist/utils/http.d.ts +9 -0
- package/dist/utils/http.d.ts.map +1 -0
- package/dist/utils/http.js +23 -0
- package/dist/utils/http.js.map +1 -0
- package/dist/utils/jwt.d.ts +22 -0
- package/dist/utils/jwt.d.ts.map +1 -0
- package/dist/utils/jwt.js +96 -0
- package/dist/utils/jwt.js.map +1 -0
- package/dist/utils/passwordPolicy.d.ts +9 -0
- package/dist/utils/passwordPolicy.d.ts.map +1 -0
- package/dist/utils/passwordPolicy.js +29 -0
- package/dist/utils/passwordPolicy.js.map +1 -0
- package/dist/utils/passwords.d.ts +33 -0
- package/dist/utils/passwords.d.ts.map +1 -0
- package/dist/utils/passwords.js +139 -0
- package/dist/utils/passwords.js.map +1 -0
- package/dist/utils/propagation.d.ts +30 -0
- package/dist/utils/propagation.d.ts.map +1 -0
- package/dist/utils/propagation.js +60 -0
- package/dist/utils/propagation.js.map +1 -0
- package/dist/utils/returnTo.d.ts +2 -0
- package/dist/utils/returnTo.d.ts.map +1 -0
- package/dist/utils/returnTo.js +21 -0
- package/dist/utils/returnTo.js.map +1 -0
- package/dist/utils/roles.d.ts +3 -0
- package/dist/utils/roles.d.ts.map +1 -0
- package/dist/utils/roles.js +25 -0
- package/dist/utils/roles.js.map +1 -0
- package/dist/utils/turnstile.d.ts +12 -0
- package/dist/utils/turnstile.d.ts.map +1 -0
- package/dist/utils/turnstile.js +40 -0
- package/dist/utils/turnstile.js.map +1 -0
- package/dist/utils/verifyInternal.d.ts +8 -0
- package/dist/utils/verifyInternal.d.ts.map +1 -0
- package/dist/utils/verifyInternal.js +69 -0
- package/dist/utils/verifyInternal.js.map +1 -0
- package/package.json +48 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { JwtPayload } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Signs a payload using HMAC with the given secret.
|
|
4
|
+
*
|
|
5
|
+
* @export
|
|
6
|
+
* @async
|
|
7
|
+
* @param {JwtPayload} payload
|
|
8
|
+
* @param {string} secret
|
|
9
|
+
* @returns {Promise<string>}
|
|
10
|
+
*/
|
|
11
|
+
export declare function signJwtHS256(payload: JwtPayload, secret: string): Promise<string>;
|
|
12
|
+
/**
|
|
13
|
+
* Verifies a JWT signed using HS256.
|
|
14
|
+
*
|
|
15
|
+
* @export
|
|
16
|
+
* @async
|
|
17
|
+
* @param {string} token
|
|
18
|
+
* @param {string} secret
|
|
19
|
+
* @returns {Promise<JwtPayload>}
|
|
20
|
+
*/
|
|
21
|
+
export declare function verifyJwtHS256(token: string, secret: string): Promise<JwtPayload>;
|
|
22
|
+
//# sourceMappingURL=jwt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../src/utils/jwt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AA+CtC;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAcvF;AAED;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CA2BvF"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts a byte array to a base64url-encoded string.
|
|
3
|
+
*
|
|
4
|
+
* @param {Uint8Array} b
|
|
5
|
+
* @returns {string}
|
|
6
|
+
*/
|
|
7
|
+
function b64urlBytes(b) {
|
|
8
|
+
return btoa(String.fromCharCode(...b))
|
|
9
|
+
.replace(/\+/g, '-')
|
|
10
|
+
.replace(/\//g, '_')
|
|
11
|
+
.replace(/=+$/g, '');
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Converts a string to a base64url-encoded string.
|
|
15
|
+
*
|
|
16
|
+
* @param {string} s
|
|
17
|
+
* @returns {string}
|
|
18
|
+
*/
|
|
19
|
+
function b64urlEncodeUtf8(s) {
|
|
20
|
+
return b64urlBytes(new TextEncoder().encode(s));
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Converts a base64url-encoded string to a byte array.
|
|
24
|
+
*
|
|
25
|
+
* @param {string} u
|
|
26
|
+
* @returns {Uint8Array}
|
|
27
|
+
*/
|
|
28
|
+
function b64urlToBytes(u) {
|
|
29
|
+
const b64 = u.replace(/-/g, '+').replace(/_/g, '/');
|
|
30
|
+
const bin = atob(b64);
|
|
31
|
+
return Uint8Array.from(bin, (c) => c.charCodeAt(0));
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Converts a base64url-encoded string to a byte array.
|
|
35
|
+
*
|
|
36
|
+
* @param {string} u
|
|
37
|
+
* @returns {string}
|
|
38
|
+
*/
|
|
39
|
+
function b64urlDecodeUtf8(u) {
|
|
40
|
+
return new TextDecoder().decode(b64urlToBytes(u));
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Signs a payload using HMAC with the given secret.
|
|
44
|
+
*
|
|
45
|
+
* @export
|
|
46
|
+
* @async
|
|
47
|
+
* @param {JwtPayload} payload
|
|
48
|
+
* @param {string} secret
|
|
49
|
+
* @returns {Promise<string>}
|
|
50
|
+
*/
|
|
51
|
+
export async function signJwtHS256(payload, secret) {
|
|
52
|
+
if (!secret) {
|
|
53
|
+
throw new Error('Missing JWT Secret');
|
|
54
|
+
}
|
|
55
|
+
const header = b64urlEncodeUtf8(JSON.stringify({ alg: 'HS256', typ: 'JWT' }));
|
|
56
|
+
const body = b64urlEncodeUtf8(JSON.stringify(payload));
|
|
57
|
+
const enc = new TextEncoder();
|
|
58
|
+
const key = await crypto.subtle.importKey('raw', enc.encode(secret), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
|
|
59
|
+
const sigBuf = await crypto.subtle.sign('HMAC', key, enc.encode(`${header}.${body}`));
|
|
60
|
+
const sig = b64urlBytes(new Uint8Array(sigBuf));
|
|
61
|
+
return `${header}.${body}.${sig}`;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Verifies a JWT signed using HS256.
|
|
65
|
+
*
|
|
66
|
+
* @export
|
|
67
|
+
* @async
|
|
68
|
+
* @param {string} token
|
|
69
|
+
* @param {string} secret
|
|
70
|
+
* @returns {Promise<JwtPayload>}
|
|
71
|
+
*/
|
|
72
|
+
export async function verifyJwtHS256(token, secret) {
|
|
73
|
+
if (!secret) {
|
|
74
|
+
throw new Error('Missing JWT Secret');
|
|
75
|
+
}
|
|
76
|
+
const [h, p, s] = token.split('.');
|
|
77
|
+
if (!h || !p || !s) {
|
|
78
|
+
throw new Error('bad jwt');
|
|
79
|
+
}
|
|
80
|
+
const enc = new TextEncoder();
|
|
81
|
+
const key = await crypto.subtle.importKey('raw', enc.encode(secret), { name: 'HMAC', hash: 'SHA-256' }, false, ['verify']);
|
|
82
|
+
const ok = await crypto.subtle.verify('HMAC', key, b64urlToBytes(s), enc.encode(`${h}.${p}`));
|
|
83
|
+
if (!ok) {
|
|
84
|
+
throw new Error('bad sig');
|
|
85
|
+
}
|
|
86
|
+
const payload = JSON.parse(b64urlDecodeUtf8(p));
|
|
87
|
+
const now = Math.floor(Date.now() / 1000);
|
|
88
|
+
if (payload.exp && now >= payload.exp) {
|
|
89
|
+
throw new Error('expired');
|
|
90
|
+
}
|
|
91
|
+
if (payload.nbf && now < payload.nbf) {
|
|
92
|
+
throw new Error('nbf');
|
|
93
|
+
}
|
|
94
|
+
return payload;
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=jwt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jwt.js","sourceRoot":"","sources":["../../src/utils/jwt.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,SAAS,WAAW,CAAC,CAAa;IACjC,OAAO,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC;SACpC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACvB,CAAC;AAED;;;;;GAKG;AACH,SAAS,gBAAgB,CAAC,CAAS;IAClC,OAAO,WAAW,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AACjD,CAAC;AAED;;;;;GAKG;AACH,SAAS,aAAa,CAAC,CAAS;IAC/B,MAAM,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACpD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;IACtB,OAAO,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AACrD,CAAC;AAED;;;;;GAKG;AACH,SAAS,gBAAgB,CAAC,CAAS;IAClC,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;AACnD,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAmB,EAAE,MAAc;IACrE,IAAI,CAAC,MAAM,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;IACvC,CAAC;IAED,MAAM,MAAM,GAAG,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IAC9E,MAAM,IAAI,GAAG,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;IAEvD,MAAM,GAAG,GAAG,IAAI,WAAW,EAAE,CAAC;IAC9B,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAEzH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;IACtF,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;IAChD,OAAO,GAAG,MAAM,IAAI,IAAI,IAAI,GAAG,EAAE,CAAC;AACnC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,KAAa,EAAE,MAAc;IACjE,IAAI,CAAC,MAAM,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;IACvC,CAAC;IAED,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC;IAC5B,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,WAAW,EAAE,CAAC;IAC9B,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAE3H,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9F,IAAI,CAAC,EAAE,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC;IAC5B,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAC1C,IAAI,OAAO,CAAC,GAAG,IAAI,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC;IAC5B,CAAC;IACD,IAAI,OAAO,CAAC,GAAG,IAAI,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;IACxB,CAAC;IACD,OAAO,OAAO,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { PasswordPolicy } from '../types';
|
|
2
|
+
export declare function getPasswordPolicy(cfg?: PasswordPolicy): PasswordPolicy;
|
|
3
|
+
export declare function validatePassword(password: string, policy: PasswordPolicy): {
|
|
4
|
+
ok: true;
|
|
5
|
+
} | {
|
|
6
|
+
ok: false;
|
|
7
|
+
reason: string;
|
|
8
|
+
};
|
|
9
|
+
//# sourceMappingURL=passwordPolicy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"passwordPolicy.d.ts","sourceRoot":"","sources":["../../src/utils/passwordPolicy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAU/C,wBAAgB,iBAAiB,CAAC,GAAG,CAAC,EAAE,cAAc,GAAG,cAAc,CAEtE;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAsBvH"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const DEFAULT_POLICY = {
|
|
2
|
+
minLength: 12,
|
|
3
|
+
requireUppercase: true,
|
|
4
|
+
requireLowercase: true,
|
|
5
|
+
requireNumber: true,
|
|
6
|
+
requireSymbol: true,
|
|
7
|
+
};
|
|
8
|
+
export function getPasswordPolicy(cfg) {
|
|
9
|
+
return { ...DEFAULT_POLICY, ...cfg };
|
|
10
|
+
}
|
|
11
|
+
export function validatePassword(password, policy) {
|
|
12
|
+
if (password.length < policy.minLength) {
|
|
13
|
+
return { ok: false, reason: 'too_short' };
|
|
14
|
+
}
|
|
15
|
+
if (policy.requireUppercase && !/[A-Z]/.test(password)) {
|
|
16
|
+
return { ok: false, reason: 'missing_uppercase' };
|
|
17
|
+
}
|
|
18
|
+
if (policy.requireLowercase && !/[a-z]/.test(password)) {
|
|
19
|
+
return { ok: false, reason: 'missing_lowercase' };
|
|
20
|
+
}
|
|
21
|
+
if (policy.requireNumber && !/[0-9]/.test(password)) {
|
|
22
|
+
return { ok: false, reason: 'missing_number' };
|
|
23
|
+
}
|
|
24
|
+
if (policy.requireSymbol && !/[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/.test(password)) {
|
|
25
|
+
return { ok: false, reason: 'missing_symbol' };
|
|
26
|
+
}
|
|
27
|
+
return { ok: true };
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=passwordPolicy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"passwordPolicy.js","sourceRoot":"","sources":["../../src/utils/passwordPolicy.ts"],"names":[],"mappings":"AAEA,MAAM,cAAc,GAAmB;IACtC,SAAS,EAAE,EAAE;IACb,gBAAgB,EAAE,IAAI;IACtB,gBAAgB,EAAE,IAAI;IACtB,aAAa,EAAE,IAAI;IACnB,aAAa,EAAE,IAAI;CACnB,CAAC;AAEF,MAAM,UAAU,iBAAiB,CAAC,GAAoB;IACrD,OAAO,EAAE,GAAG,cAAc,EAAE,GAAG,GAAG,EAAE,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,QAAgB,EAAE,MAAsB;IACxE,IAAI,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC,SAAS,EAAE,CAAC;QACxC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IAC3C,CAAC;IAED,IAAI,MAAM,CAAC,gBAAgB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC;IACnD,CAAC;IAED,IAAI,MAAM,CAAC,gBAAgB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC;IACnD,CAAC;IAED,IAAI,MAAM,CAAC,aAAa,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACrD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAChD,CAAC;IAED,IAAI,MAAM,CAAC,aAAa,IAAI,CAAC,qCAAqC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACnF,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAChD,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
declare const DEFAULT_PARAMS: {
|
|
2
|
+
hash: "SHA-256";
|
|
3
|
+
iter: number;
|
|
4
|
+
dkLen: number;
|
|
5
|
+
};
|
|
6
|
+
export declare function getFakeStoredHash(): string;
|
|
7
|
+
/**
|
|
8
|
+
* PASSWORD_PEPPERS format:
|
|
9
|
+
* "pepper_v2,pepper_v1" (newest first)
|
|
10
|
+
*/
|
|
11
|
+
export declare function getPeppers(env: Env, pepperEnv?: string): string[];
|
|
12
|
+
/**
|
|
13
|
+
* Stored format:
|
|
14
|
+
* pbkdf2$SHA-256$600000$32$<saltB64u>$<dkB64u>
|
|
15
|
+
*/
|
|
16
|
+
export declare function hashPassword(password: string, options?: {
|
|
17
|
+
pepper?: string;
|
|
18
|
+
params?: Partial<typeof DEFAULT_PARAMS>;
|
|
19
|
+
}): Promise<string>;
|
|
20
|
+
export declare function verifyPassword(password: string, stored: string, pepper?: string): Promise<boolean>;
|
|
21
|
+
/**
|
|
22
|
+
* Verifies using multiple peppers (newest->oldest). Returns which matched.
|
|
23
|
+
* If no peppers configured, treats as "no pepper".
|
|
24
|
+
*/
|
|
25
|
+
export declare function verifyPasswordWithPepperRotation(password: string, stored: string, peppers: string[]): Promise<{
|
|
26
|
+
ok: true;
|
|
27
|
+
usedPepperIndex: number;
|
|
28
|
+
} | {
|
|
29
|
+
ok: false;
|
|
30
|
+
}>;
|
|
31
|
+
export declare function needsRehash(stored: string, desired?: Partial<typeof DEFAULT_PARAMS>): boolean;
|
|
32
|
+
export {};
|
|
33
|
+
//# sourceMappingURL=passwords.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"passwords.d.ts","sourceRoot":"","sources":["../../src/utils/passwords.ts"],"names":[],"mappings":"AAWA,QAAA,MAAM,cAAc;;;;CAInB,CAAC;AAIF,wBAAgB,iBAAiB,IAAI,MAAM,CAY1C;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,SAAS,GAAE,MAA2B,GAAG,MAAM,EAAE,CAOrF;AAED;;;GAGG;AACH,wBAAsB,YAAY,CACjC,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE;IACT,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC,OAAO,cAAc,CAAC,CAAC;CACxC,GACC,OAAO,CAAC,MAAM,CAAC,CAqBjB;AAED,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOxG;AAED;;;GAGG;AACH,wBAAsB,gCAAgC,CACrD,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EAAE,GACf,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAA;CAAE,CAAC,CAYhE;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,OAAO,cAAc,CAAC,GAAG,OAAO,CAM7F"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
// src/utils/passwords.ts
|
|
2
|
+
const DEFAULT_PARAMS = {
|
|
3
|
+
hash: 'SHA-256',
|
|
4
|
+
iter: 800_000,
|
|
5
|
+
dkLen: 32,
|
|
6
|
+
};
|
|
7
|
+
let cachedFake = null;
|
|
8
|
+
export function getFakeStoredHash() {
|
|
9
|
+
// Best-effort cache per isolate; fine if it resets on cold start.
|
|
10
|
+
if (cachedFake)
|
|
11
|
+
return cachedFake;
|
|
12
|
+
const salt = crypto.getRandomValues(new Uint8Array(32));
|
|
13
|
+
const dk = crypto.getRandomValues(new Uint8Array(32)); // dkLen must match your DEFAULT_PARAMS.dkLen
|
|
14
|
+
const saltB64u = b64urlEncodeBytes(salt);
|
|
15
|
+
const dkB64u = b64urlEncodeBytes(dk);
|
|
16
|
+
cachedFake = `pbkdf2$SHA-256$800000$32$${saltB64u}$${dkB64u}`;
|
|
17
|
+
return cachedFake;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* PASSWORD_PEPPERS format:
|
|
21
|
+
* "pepper_v2,pepper_v1" (newest first)
|
|
22
|
+
*/
|
|
23
|
+
export function getPeppers(env, pepperEnv = 'PASSWORD_PEPPERS') {
|
|
24
|
+
const raw = (env[pepperEnv] ?? '').trim();
|
|
25
|
+
if (!raw)
|
|
26
|
+
return [];
|
|
27
|
+
return raw
|
|
28
|
+
.split(',')
|
|
29
|
+
.map((s) => s.trim())
|
|
30
|
+
.filter((s) => s.length > 0);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Stored format:
|
|
34
|
+
* pbkdf2$SHA-256$600000$32$<saltB64u>$<dkB64u>
|
|
35
|
+
*/
|
|
36
|
+
export async function hashPassword(password, options) {
|
|
37
|
+
const salt = crypto.getRandomValues(new Uint8Array(32));
|
|
38
|
+
const saltB64u = b64urlEncodeBytes(salt);
|
|
39
|
+
const params = { ...DEFAULT_PARAMS, ...options?.params };
|
|
40
|
+
const dk = await deriveKeyBytes(password, {
|
|
41
|
+
alg: 'pbkdf2',
|
|
42
|
+
hash: params.hash,
|
|
43
|
+
iter: params.iter,
|
|
44
|
+
dkLen: params.dkLen,
|
|
45
|
+
saltB64u,
|
|
46
|
+
dkB64u: '',
|
|
47
|
+
}, options?.pepper);
|
|
48
|
+
const dkB64u = b64urlEncodeBytes(dk);
|
|
49
|
+
return `pbkdf2$${params.hash}$${params.iter}$${params.dkLen}$${saltB64u}$${dkB64u}`;
|
|
50
|
+
}
|
|
51
|
+
export async function verifyPassword(password, stored, pepper) {
|
|
52
|
+
const parsed = parseStored(stored);
|
|
53
|
+
if (!parsed)
|
|
54
|
+
return false;
|
|
55
|
+
const dk = await deriveKeyBytes(password, parsed, pepper);
|
|
56
|
+
const expected = b64urlDecodeBytes(parsed.dkB64u);
|
|
57
|
+
return timingSafeEqualBytes(dk, expected);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Verifies using multiple peppers (newest->oldest). Returns which matched.
|
|
61
|
+
* If no peppers configured, treats as "no pepper".
|
|
62
|
+
*/
|
|
63
|
+
export async function verifyPasswordWithPepperRotation(password, stored, peppers) {
|
|
64
|
+
if (!peppers.length) {
|
|
65
|
+
const ok = await verifyPassword(password, stored, undefined);
|
|
66
|
+
return ok ? { ok: true, usedPepperIndex: -1 } : { ok: false };
|
|
67
|
+
}
|
|
68
|
+
for (let i = 0; i < peppers.length; i++) {
|
|
69
|
+
if (await verifyPassword(password, stored, peppers[i])) {
|
|
70
|
+
return { ok: true, usedPepperIndex: i };
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return { ok: false };
|
|
74
|
+
}
|
|
75
|
+
export function needsRehash(stored, desired) {
|
|
76
|
+
const parsed = parseStored(stored);
|
|
77
|
+
if (!parsed)
|
|
78
|
+
return true;
|
|
79
|
+
const target = { ...DEFAULT_PARAMS, ...desired };
|
|
80
|
+
return parsed.hash !== target.hash || parsed.iter !== target.iter || parsed.dkLen !== target.dkLen;
|
|
81
|
+
}
|
|
82
|
+
/* ----------------------------- internals ----------------------------- */
|
|
83
|
+
async function deriveKeyBytes(password, parsed, pepper) {
|
|
84
|
+
const pw = normalizePassword(password, pepper);
|
|
85
|
+
const pwKey = await crypto.subtle.importKey('raw', new TextEncoder().encode(pw), { name: 'PBKDF2' }, false, ['deriveBits']);
|
|
86
|
+
const salt = b64urlDecodeBytes(parsed.saltB64u);
|
|
87
|
+
const bits = await crypto.subtle.deriveBits({
|
|
88
|
+
name: 'PBKDF2',
|
|
89
|
+
hash: parsed.hash,
|
|
90
|
+
salt,
|
|
91
|
+
iterations: parsed.iter,
|
|
92
|
+
}, pwKey, parsed.dkLen * 8);
|
|
93
|
+
return new Uint8Array(bits);
|
|
94
|
+
}
|
|
95
|
+
function normalizePassword(password, pepper) {
|
|
96
|
+
const p = password.normalize('NFC');
|
|
97
|
+
return pepper ? `${pepper}\u0000${p}` : p;
|
|
98
|
+
}
|
|
99
|
+
function parseStored(stored) {
|
|
100
|
+
const parts = stored.split('$');
|
|
101
|
+
if (parts.length !== 6)
|
|
102
|
+
return null;
|
|
103
|
+
const [alg, hash, iterStr, dkLenStr, saltB64u, dkB64u] = parts;
|
|
104
|
+
if (alg !== 'pbkdf2')
|
|
105
|
+
return null;
|
|
106
|
+
if (hash !== 'SHA-256' && hash !== 'SHA-512')
|
|
107
|
+
return null;
|
|
108
|
+
const iter = Number(iterStr);
|
|
109
|
+
const dkLen = Number(dkLenStr);
|
|
110
|
+
if (!Number.isFinite(iter) || iter <= 0)
|
|
111
|
+
return null;
|
|
112
|
+
if (!Number.isFinite(dkLen) || dkLen <= 0)
|
|
113
|
+
return null;
|
|
114
|
+
return { alg: 'pbkdf2', hash, iter, dkLen, saltB64u, dkB64u };
|
|
115
|
+
}
|
|
116
|
+
function b64urlEncodeBytes(bytes) {
|
|
117
|
+
return btoa(String.fromCharCode(...bytes))
|
|
118
|
+
.replace(/\+/g, '-')
|
|
119
|
+
.replace(/\//g, '_')
|
|
120
|
+
.replace(/=+$/g, '');
|
|
121
|
+
}
|
|
122
|
+
function b64urlDecodeBytes(b64u) {
|
|
123
|
+
let b64 = b64u.replace(/-/g, '+').replace(/_/g, '/');
|
|
124
|
+
const pad = b64.length % 4;
|
|
125
|
+
if (pad)
|
|
126
|
+
b64 += '='.repeat(4 - pad);
|
|
127
|
+
const bin = atob(b64);
|
|
128
|
+
return Uint8Array.from(bin, (c) => c.charCodeAt(0));
|
|
129
|
+
}
|
|
130
|
+
function timingSafeEqualBytes(a, b) {
|
|
131
|
+
if (a.length !== b.length)
|
|
132
|
+
return false;
|
|
133
|
+
let out = 0;
|
|
134
|
+
for (let i = 0; i < a.length; i++) {
|
|
135
|
+
out |= a[i] ^ b[i];
|
|
136
|
+
}
|
|
137
|
+
return out === 0;
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=passwords.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"passwords.js","sourceRoot":"","sources":["../../src/utils/passwords.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ProjectConfig, Session } from '../types';
|
|
2
|
+
export type PropagatedUserPayload = {
|
|
3
|
+
userId: string;
|
|
4
|
+
email: string;
|
|
5
|
+
systemRoles: string[];
|
|
6
|
+
ts: number;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Attaches a signed user payload to the request headers.
|
|
10
|
+
*/
|
|
11
|
+
export declare function attachSignedUser(headers: Headers, session: Session, cfg: ProjectConfig, env: Env): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Removes the user payload from the request headers.
|
|
14
|
+
*/
|
|
15
|
+
export declare function stripUser(headers: Headers, cfg: ProjectConfig): void;
|
|
16
|
+
/**
|
|
17
|
+
* Encode an object as base64(JSON).
|
|
18
|
+
* (Used by gateway to create X-User; reused by verifiers to decode.)
|
|
19
|
+
*/
|
|
20
|
+
export declare function encodeJsonToBase64(value: unknown): string;
|
|
21
|
+
/**
|
|
22
|
+
* Decode base64(JSON) into a JS value.
|
|
23
|
+
*/
|
|
24
|
+
export declare function decodeJsonFromBase64<T = unknown>(payloadB64: string): T;
|
|
25
|
+
/**
|
|
26
|
+
* Signs a payload using HMAC with the given secret.
|
|
27
|
+
* Returns base64url.
|
|
28
|
+
*/
|
|
29
|
+
export declare function signHmac(payload: string, secret: string): Promise<string>;
|
|
30
|
+
//# sourceMappingURL=propagation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"propagation.d.ts","sourceRoot":"","sources":["../../src/utils/propagation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAEvD,MAAM,MAAM,qBAAqB,GAAG;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,EAAE,EAAE,MAAM,CAAC;CACX,CAAC;AAEF;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBtH;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,aAAa,GAAG,IAAI,CAGpE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAIzD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,GAAG,OAAO,EAAE,UAAU,EAAE,MAAM,GAAG,CAAC,CAKvE;AAED;;;GAGG;AACH,wBAAsB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAS/E"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Attaches a signed user payload to the request headers.
|
|
3
|
+
*/
|
|
4
|
+
export async function attachSignedUser(headers, session, cfg, env) {
|
|
5
|
+
const name = cfg.propagation.headerName ?? 'X-User';
|
|
6
|
+
const sigName = cfg.propagation.sigHeaderName ?? 'X-User-Sig';
|
|
7
|
+
const secret = env[cfg.propagation.hmacSecretEnv];
|
|
8
|
+
if (!secret)
|
|
9
|
+
throw new Error('Missing HMAC secret');
|
|
10
|
+
const payloadObj = {
|
|
11
|
+
userId: session.userId,
|
|
12
|
+
email: session.email,
|
|
13
|
+
systemRoles: session.systemRoles,
|
|
14
|
+
ts: Math.floor(Date.now() / 1000),
|
|
15
|
+
};
|
|
16
|
+
const payload = encodeJsonToBase64(payloadObj);
|
|
17
|
+
const sig = await signHmac(payload, secret);
|
|
18
|
+
headers.set(name, payload);
|
|
19
|
+
headers.set(sigName, sig);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Removes the user payload from the request headers.
|
|
23
|
+
*/
|
|
24
|
+
export function stripUser(headers, cfg) {
|
|
25
|
+
headers.delete(cfg.propagation.headerName ?? 'X-User');
|
|
26
|
+
headers.delete(cfg.propagation.sigHeaderName ?? 'X-User-Sig');
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Encode an object as base64(JSON).
|
|
30
|
+
* (Used by gateway to create X-User; reused by verifiers to decode.)
|
|
31
|
+
*/
|
|
32
|
+
export function encodeJsonToBase64(value) {
|
|
33
|
+
const json = JSON.stringify(value);
|
|
34
|
+
const bytes = new Uint8Array(new TextEncoder().encode(json));
|
|
35
|
+
return btoa(String.fromCharCode(...bytes));
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Decode base64(JSON) into a JS value.
|
|
39
|
+
*/
|
|
40
|
+
export function decodeJsonFromBase64(payloadB64) {
|
|
41
|
+
const bin = atob(payloadB64);
|
|
42
|
+
const bytes = Uint8Array.from(bin, (c) => c.charCodeAt(0));
|
|
43
|
+
const json = new TextDecoder().decode(bytes);
|
|
44
|
+
return JSON.parse(json);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Signs a payload using HMAC with the given secret.
|
|
48
|
+
* Returns base64url.
|
|
49
|
+
*/
|
|
50
|
+
export async function signHmac(payload, secret) {
|
|
51
|
+
const enc = new TextEncoder();
|
|
52
|
+
const key = await crypto.subtle.importKey('raw', enc.encode(secret), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
|
|
53
|
+
const sigBuf = await crypto.subtle.sign('HMAC', key, enc.encode(payload));
|
|
54
|
+
const bytes = new Uint8Array(sigBuf);
|
|
55
|
+
return btoa(String.fromCharCode(...bytes))
|
|
56
|
+
.replace(/\+/g, '-')
|
|
57
|
+
.replace(/\//g, '_')
|
|
58
|
+
.replace(/=+$/, '');
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=propagation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"propagation.js","sourceRoot":"","sources":["../../src/utils/propagation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"returnTo.d.ts","sourceRoot":"","sources":["../../src/utils/returnTo.ts"],"names":[],"mappings":"AAAA,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAoBpG"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export function safeReturnTo(returnTo, publicBaseUrl) {
|
|
2
|
+
if (!returnTo)
|
|
3
|
+
return undefined;
|
|
4
|
+
// Allow only same-origin relative paths by default
|
|
5
|
+
if (returnTo.startsWith('/') && !returnTo.startsWith('//')) {
|
|
6
|
+
return returnTo;
|
|
7
|
+
}
|
|
8
|
+
// Optional: allow absolute URLs only if same origin
|
|
9
|
+
try {
|
|
10
|
+
const rt = new URL(returnTo);
|
|
11
|
+
const pub = new URL(publicBaseUrl);
|
|
12
|
+
if (rt.origin === pub.origin) {
|
|
13
|
+
return rt.pathname + rt.search + rt.hash;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
// ignore
|
|
18
|
+
}
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=returnTo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"returnTo.js","sourceRoot":"","sources":["../../src/utils/returnTo.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,YAAY,CAAC,QAA4B,EAAE,aAAqB;IAC/E,IAAI,CAAC,QAAQ;QAAE,OAAO,SAAS,CAAC;IAEhC,mDAAmD;IACnD,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5D,OAAO,QAAQ,CAAC;IACjB,CAAC;IAED,oDAAoD;IACpD,IAAI,CAAC;QACJ,MAAM,EAAE,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC7B,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,CAAC;QACnC,IAAI,EAAE,CAAC,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE,CAAC;YAC9B,OAAO,EAAE,CAAC,QAAQ,GAAG,EAAE,CAAC,MAAM,GAAG,EAAE,CAAC,IAAI,CAAC;QAC1C,CAAC;IACF,CAAC;IAAC,MAAM,CAAC;QACR,SAAS;IACV,CAAC;IAED,OAAO,SAAS,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roles.d.ts","sourceRoot":"","sources":["../../src/utils/roles.ts"],"names":[],"mappings":"AAAA,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAW3E;AAED,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAW5E"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export function hasAnyRole(userRoles, required) {
|
|
2
|
+
if (!Array.isArray(userRoles) || userRoles.length === 0)
|
|
3
|
+
return false;
|
|
4
|
+
if (!Array.isArray(required) || required.length === 0)
|
|
5
|
+
return false;
|
|
6
|
+
const roles = new Set(userRoles);
|
|
7
|
+
for (const role of required) {
|
|
8
|
+
if (roles.has(role))
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
export function hasAllRoles(userRoles, required) {
|
|
14
|
+
if (!Array.isArray(userRoles))
|
|
15
|
+
return false;
|
|
16
|
+
if (!Array.isArray(required) || required.length === 0)
|
|
17
|
+
return true;
|
|
18
|
+
const roles = new Set(userRoles);
|
|
19
|
+
for (const role of required) {
|
|
20
|
+
if (!roles.has(role))
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=roles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roles.js","sourceRoot":"","sources":["../../src/utils/roles.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,UAAU,CAAC,SAAmB,EAAE,QAAkB;IACjE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACtE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAEpE,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC;IAEjC,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC7B,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;IAClC,CAAC;IAED,OAAO,KAAK,CAAC;AACd,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,SAAmB,EAAE,QAAkB;IAClE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC;QAAE,OAAO,KAAK,CAAC;IAC5C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEnE,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC;IAEjC,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC7B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAO,KAAK,CAAC;IACpC,CAAC;IAED,OAAO,IAAI,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type TurnstileVerifyResult = {
|
|
2
|
+
ok: true;
|
|
3
|
+
} | {
|
|
4
|
+
ok: false;
|
|
5
|
+
code: string;
|
|
6
|
+
errors?: string[];
|
|
7
|
+
};
|
|
8
|
+
export declare function verifyTurnstile(token: string, secret: string, remoteip?: string): Promise<TurnstileVerifyResult>;
|
|
9
|
+
export declare function getTurnstileTokenField(cfg?: {
|
|
10
|
+
tokenField?: string;
|
|
11
|
+
}): string;
|
|
12
|
+
//# sourceMappingURL=turnstile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"turnstile.d.ts","sourceRoot":"","sources":["../../src/utils/turnstile.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,qBAAqB,GAAG;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAQlG,wBAAsB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAsCtH;AAED,wBAAgB,sBAAsB,CAAC,GAAG,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAE5E"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// src/utils/turnstile.ts
|
|
2
|
+
export async function verifyTurnstile(token, secret, remoteip) {
|
|
3
|
+
if (!token || typeof token !== 'string') {
|
|
4
|
+
return { ok: false, code: 'turnstile_missing' };
|
|
5
|
+
}
|
|
6
|
+
if (!secret || typeof secret !== 'string') {
|
|
7
|
+
return { ok: false, code: 'turnstile_misconfigured' };
|
|
8
|
+
}
|
|
9
|
+
const form = new FormData();
|
|
10
|
+
form.append('secret', secret);
|
|
11
|
+
form.append('response', token);
|
|
12
|
+
if (remoteip)
|
|
13
|
+
form.append('remoteip', remoteip);
|
|
14
|
+
let res;
|
|
15
|
+
try {
|
|
16
|
+
res = await fetch('https://challenges.cloudflare.com/turnstile/v0/siteverify', {
|
|
17
|
+
method: 'POST',
|
|
18
|
+
body: form,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return { ok: false, code: 'turnstile_unavailable' };
|
|
23
|
+
}
|
|
24
|
+
if (!res.ok) {
|
|
25
|
+
return { ok: false, code: 'turnstile_unavailable' };
|
|
26
|
+
}
|
|
27
|
+
const data = (await res.json().catch(() => null));
|
|
28
|
+
if (!data?.success) {
|
|
29
|
+
return {
|
|
30
|
+
ok: false,
|
|
31
|
+
code: 'turnstile_invalid',
|
|
32
|
+
errors: data?.['error-codes'] ?? [],
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
return { ok: true };
|
|
36
|
+
}
|
|
37
|
+
export function getTurnstileTokenField(cfg) {
|
|
38
|
+
return cfg?.tokenField ?? 'turnstileToken';
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=turnstile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"turnstile.js","sourceRoot":"","sources":["../../src/utils/turnstile.ts"],"names":[],"mappings":"AAAA,yBAAyB;AAUzB,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,KAAa,EAAE,MAAc,EAAE,QAAiB;IACrF,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACzC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC;IACjD,CAAC;IAED,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC3C,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,yBAAyB,EAAE,CAAC;IACvD,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,QAAQ,EAAE,CAAC;IAC5B,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC9B,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IAC/B,IAAI,QAAQ;QAAE,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAEhD,IAAI,GAAa,CAAC;IAClB,IAAI,CAAC;QACJ,GAAG,GAAG,MAAM,KAAK,CAAC,2DAA2D,EAAE;YAC9E,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAAI;SACV,CAAC,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,uBAAuB,EAAE,CAAC;IACrD,CAAC;IAED,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACb,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,uBAAuB,EAAE,CAAC;IACrD,CAAC;IAED,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAA8B,CAAC;IAC/E,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC;QACpB,OAAO;YACN,EAAE,EAAE,KAAK;YACT,IAAI,EAAE,mBAAmB;YACzB,MAAM,EAAE,IAAI,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE;SACnC,CAAC;IACH,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,GAA6B;IACnE,OAAO,GAAG,EAAE,UAAU,IAAI,gBAAgB,CAAC;AAC5C,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ProjectConfig } from '../types';
|
|
2
|
+
import { type PropagatedUserPayload } from './propagation';
|
|
3
|
+
export type VerifyGatewayUserOptions = {
|
|
4
|
+
maxSkewSec?: number;
|
|
5
|
+
require?: boolean;
|
|
6
|
+
};
|
|
7
|
+
export declare function verifyGatewayUser(request: Request, cfg: Pick<ProjectConfig, 'propagation'>, env: Env, options?: VerifyGatewayUserOptions): Promise<PropagatedUserPayload | null>;
|
|
8
|
+
//# sourceMappingURL=verifyInternal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verifyInternal.d.ts","sourceRoot":"","sources":["../../src/utils/verifyInternal.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAkC,KAAK,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAE3F,MAAM,MAAM,wBAAwB,GAAG;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,wBAAsB,iBAAiB,CACtC,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,IAAI,CAAC,aAAa,EAAE,aAAa,CAAC,EACvC,GAAG,EAAE,GAAG,EACR,OAAO,GAAE,wBAA6B,GACpC,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,CA0CvC"}
|