@aura-stack/auth 0.4.0-rc.5 → 0.4.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/dist/@types/index.d.ts +4 -3
- package/dist/@types/router.d.cjs +0 -17
- package/dist/@types/router.d.d.ts +3 -2
- package/dist/@types/router.d.js +0 -1
- package/dist/actions/callback/access-token.cjs +40 -25
- package/dist/actions/callback/access-token.d.ts +4 -3
- package/dist/actions/callback/access-token.js +3 -4
- package/dist/actions/callback/callback.cjs +287 -77
- package/dist/actions/callback/callback.d.ts +5 -26
- package/dist/actions/callback/callback.js +13 -10
- package/dist/actions/callback/userinfo.cjs +68 -7
- package/dist/actions/callback/userinfo.d.ts +4 -3
- package/dist/actions/callback/userinfo.js +8 -6
- package/dist/actions/csrfToken/csrfToken.cjs +63 -4
- package/dist/actions/csrfToken/csrfToken.d.ts +1 -3
- package/dist/actions/csrfToken/csrfToken.js +8 -6
- package/dist/actions/index.cjs +400 -175
- package/dist/actions/index.d.ts +3 -2
- package/dist/actions/index.js +21 -19
- package/dist/actions/session/session.cjs +40 -11
- package/dist/actions/session/session.d.ts +1 -3
- package/dist/actions/session/session.js +4 -4
- package/dist/actions/signIn/authorization.cjs +171 -132
- package/dist/actions/signIn/authorization.d.ts +21 -11
- package/dist/actions/signIn/authorization.js +8 -6
- package/dist/actions/signIn/signIn.cjs +220 -113
- package/dist/actions/signIn/signIn.d.ts +5 -25
- package/dist/actions/signIn/signIn.js +9 -7
- package/dist/actions/signOut/signOut.cjs +268 -119
- package/dist/actions/signOut/signOut.d.ts +1 -9
- package/dist/actions/signOut/signOut.js +10 -8
- package/dist/assert.cjs +117 -5
- package/dist/assert.d.ts +22 -3
- package/dist/assert.js +17 -3
- package/dist/chunk-4EKY7655.js +123 -0
- package/dist/chunk-4MYWAOLG.js +31 -0
- package/dist/chunk-4YHJ4IEQ.js +25 -0
- package/dist/chunk-54CZPKR4.js +25 -0
- package/dist/chunk-5LZ7TOM3.js +25 -0
- package/dist/{chunk-W6LG7BFW.js → chunk-5W4BRQYG.js} +24 -20
- package/dist/chunk-6MXFPFR3.js +143 -0
- package/dist/{chunk-3EUWD5BB.js → chunk-7QF22LHP.js} +13 -9
- package/dist/chunk-ALG3GIV4.js +95 -0
- package/dist/chunk-E6G5YCI6.js +25 -0
- package/dist/chunk-EBAMFRB7.js +34 -0
- package/dist/chunk-EEE7UM5T.js +25 -0
- package/dist/{chunk-TLE4PXY3.js → chunk-FRJFWTOY.js} +38 -7
- package/dist/chunk-FW4W3REU.js +25 -0
- package/dist/{chunk-HT4YLL7N.js → chunk-ICAZ4OVS.js} +10 -8
- package/dist/chunk-IPKO6UQN.js +25 -0
- package/dist/{chunk-YRCB5FLE.js → chunk-KJBAQZX2.js} +13 -0
- package/dist/chunk-KMMAZFSJ.js +25 -0
- package/dist/chunk-LDU7A2JE.js +25 -0
- package/dist/{chunk-N2APGLXA.js → chunk-NUDITUKX.js} +18 -16
- package/dist/chunk-OVHNRULD.js +33 -0
- package/dist/{chunk-JVFTCTTE.js → chunk-PHFH2MGS.js} +12 -9
- package/dist/chunk-QQVSRXGX.js +149 -0
- package/dist/chunk-TM5IPSNF.js +113 -0
- package/dist/{chunk-GA2SMTJO.js → chunk-TZB6MUXN.js} +33 -13
- package/dist/chunk-VNCNJKS2.js +267 -0
- package/dist/{chunk-IVET23KF.js → chunk-XGLBNXL4.js} +31 -14
- package/dist/chunk-XUP6KKNG.js +106 -0
- package/dist/cookie.cjs +24 -20
- package/dist/cookie.d.ts +4 -3
- package/dist/cookie.js +1 -1
- package/dist/env.cjs +56 -0
- package/dist/env.d.ts +7 -0
- package/dist/env.js +6 -0
- package/dist/errors.d.ts +4 -3
- package/dist/headers.cjs +28 -2
- package/dist/headers.d.ts +25 -1
- package/dist/headers.js +9 -3
- package/dist/{index-B8jeIElf.d.ts → index-CSyIJmCM.d.ts} +373 -45
- package/dist/index.cjs +1128 -483
- package/dist/index.d.ts +7 -67
- package/dist/index.js +83 -42
- package/dist/jose.cjs +62 -25
- package/dist/jose.d.ts +7 -5
- package/dist/jose.js +8 -6
- package/dist/logger.cjs +292 -0
- package/dist/logger.d.ts +8 -0
- package/dist/logger.js +8 -0
- package/dist/oauth/bitbucket.cjs +19 -15
- package/dist/oauth/bitbucket.d.ts +3 -2
- package/dist/oauth/bitbucket.js +1 -1
- package/dist/oauth/discord.cjs +27 -24
- package/dist/oauth/discord.d.ts +3 -2
- package/dist/oauth/discord.js +1 -1
- package/dist/oauth/figma.cjs +19 -16
- package/dist/oauth/figma.d.ts +3 -2
- package/dist/oauth/figma.js +1 -1
- package/dist/oauth/github.cjs +19 -8
- package/dist/oauth/github.d.ts +3 -2
- package/dist/oauth/github.js +1 -1
- package/dist/oauth/gitlab.cjs +19 -16
- package/dist/oauth/gitlab.d.ts +3 -2
- package/dist/oauth/gitlab.js +1 -1
- package/dist/oauth/index.cjs +266 -166
- package/dist/oauth/index.d.ts +3 -2
- package/dist/oauth/index.js +22 -21
- package/dist/oauth/mailchimp.cjs +19 -16
- package/dist/oauth/mailchimp.d.ts +3 -2
- package/dist/oauth/mailchimp.js +1 -1
- package/dist/oauth/pinterest.cjs +19 -16
- package/dist/oauth/pinterest.d.ts +3 -2
- package/dist/oauth/pinterest.js +1 -1
- package/dist/oauth/spotify.cjs +19 -16
- package/dist/oauth/spotify.d.ts +3 -2
- package/dist/oauth/spotify.js +1 -1
- package/dist/oauth/strava.cjs +19 -16
- package/dist/oauth/strava.d.ts +3 -2
- package/dist/oauth/strava.js +1 -1
- package/dist/oauth/x.cjs +19 -16
- package/dist/oauth/x.d.ts +3 -2
- package/dist/oauth/x.js +1 -1
- package/dist/schemas.cjs +16 -2
- package/dist/schemas.d.ts +17 -1
- package/dist/schemas.js +5 -3
- package/dist/secure.cjs +58 -16
- package/dist/secure.d.ts +4 -10
- package/dist/secure.js +5 -5
- package/dist/utils.cjs +94 -87
- package/dist/utils.d.ts +9 -39
- package/dist/utils.js +11 -9
- package/package.json +3 -4
- package/dist/chunk-42XB3YCW.js +0 -22
- package/dist/chunk-6R2YZ4AC.js +0 -22
- package/dist/chunk-A3N4PVAT.js +0 -70
- package/dist/chunk-B737EUJV.js +0 -22
- package/dist/chunk-CXLATHS5.js +0 -143
- package/dist/chunk-DIVDFNAP.js +0 -0
- package/dist/chunk-E3OXBRYF.js +0 -22
- package/dist/chunk-EIL2FPSS.js +0 -22
- package/dist/chunk-EMKJA2GJ.js +0 -89
- package/dist/chunk-FIPU4MLT.js +0 -21
- package/dist/chunk-FKRDCWBF.js +0 -22
- package/dist/chunk-HP34YGGJ.js +0 -22
- package/dist/chunk-IKHPGFCW.js +0 -14
- package/dist/chunk-IUYZQTJV.js +0 -30
- package/dist/chunk-KRNOMBXQ.js +0 -22
- package/dist/chunk-KSWLO5ZU.js +0 -102
- package/dist/chunk-N4SX7TZT.js +0 -96
- package/dist/chunk-STHEPPUZ.js +0 -11
package/dist/assert.cjs
CHANGED
|
@@ -22,28 +22,140 @@ var assert_exports = {};
|
|
|
22
22
|
__export(assert_exports, {
|
|
23
23
|
isFalsy: () => isFalsy,
|
|
24
24
|
isJWTPayloadWithToken: () => isJWTPayloadWithToken,
|
|
25
|
+
isRelativeURL: () => isRelativeURL,
|
|
25
26
|
isRequest: () => isRequest,
|
|
26
|
-
|
|
27
|
+
isSameOrigin: () => isSameOrigin,
|
|
28
|
+
isTrustedOrigin: () => isTrustedOrigin,
|
|
29
|
+
isValidURL: () => isValidURL,
|
|
30
|
+
patternToRegex: () => patternToRegex,
|
|
31
|
+
safeEquals: () => safeEquals,
|
|
32
|
+
unsafeChars: () => unsafeChars
|
|
27
33
|
});
|
|
28
34
|
module.exports = __toCommonJS(assert_exports);
|
|
35
|
+
|
|
36
|
+
// src/utils.ts
|
|
37
|
+
var import_router = require("@aura-stack/router");
|
|
38
|
+
var equals = (a, b) => {
|
|
39
|
+
if (a === null || b === null || a === void 0 || b === void 0) return false;
|
|
40
|
+
return a === b;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// src/assert.ts
|
|
44
|
+
var import_crypto = require("crypto");
|
|
29
45
|
var isFalsy = (value) => {
|
|
30
46
|
return value === false || value === 0 || value === "" || value === null || value === void 0 || Number.isNaN(value);
|
|
31
47
|
};
|
|
32
48
|
var isRequest = (value) => {
|
|
33
49
|
return typeof Request !== "undefined" && value instanceof Request;
|
|
34
50
|
};
|
|
51
|
+
var unsafeChars = [
|
|
52
|
+
"<",
|
|
53
|
+
">",
|
|
54
|
+
'"',
|
|
55
|
+
"`",
|
|
56
|
+
" ",
|
|
57
|
+
"\r",
|
|
58
|
+
"\n",
|
|
59
|
+
" ",
|
|
60
|
+
"\\",
|
|
61
|
+
"%2F",
|
|
62
|
+
"%5C",
|
|
63
|
+
"%2f",
|
|
64
|
+
"%5c",
|
|
65
|
+
"\r\n",
|
|
66
|
+
"%0A",
|
|
67
|
+
"%0D",
|
|
68
|
+
"%0a",
|
|
69
|
+
"%0d",
|
|
70
|
+
"..",
|
|
71
|
+
"//",
|
|
72
|
+
"///",
|
|
73
|
+
"...",
|
|
74
|
+
"%20",
|
|
75
|
+
"\0"
|
|
76
|
+
];
|
|
35
77
|
var isValidURL = (value) => {
|
|
36
|
-
if (
|
|
37
|
-
|
|
38
|
-
|
|
78
|
+
if (!new RegExp(/^https?:\/\/[^/]/).test(value)) {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
const match = value.match(/^(https?:\/\/)(.*)$/);
|
|
82
|
+
if (!match) return false;
|
|
83
|
+
const rest = match[2];
|
|
84
|
+
for (const char of unsafeChars) {
|
|
85
|
+
if (rest.includes(char)) return false;
|
|
86
|
+
}
|
|
87
|
+
const regex = /^https?:\/\/(?:[a-zA-Z0-9._-]+|localhost|\[[0-9a-fA-F:]+\])(?::\d{1,5})?(?:\/[a-zA-Z0-9._~!$&'()?#*+,;=:@-]*)*\/?$/;
|
|
88
|
+
return regex.test(match[0]);
|
|
39
89
|
};
|
|
40
90
|
var isJWTPayloadWithToken = (payload) => {
|
|
41
91
|
return typeof payload === "object" && payload !== null && "token" in payload && typeof payload?.token === "string";
|
|
42
92
|
};
|
|
93
|
+
var isRelativeURL = (value) => {
|
|
94
|
+
if (value.length > 100) return false;
|
|
95
|
+
for (const char of unsafeChars) {
|
|
96
|
+
if (value.includes(char)) return false;
|
|
97
|
+
}
|
|
98
|
+
const regex = /^\/[a-zA-Z0-9\-_\/.?&=#]*\/?$/;
|
|
99
|
+
return regex.test(value);
|
|
100
|
+
};
|
|
101
|
+
var isSameOrigin = (origin, expected) => {
|
|
102
|
+
const originURL = new URL(origin);
|
|
103
|
+
const expectedURL = new URL(expected);
|
|
104
|
+
return equals(originURL.origin, expectedURL.origin);
|
|
105
|
+
};
|
|
106
|
+
var patternToRegex = (pattern) => {
|
|
107
|
+
try {
|
|
108
|
+
if (pattern.length > 2048) return null;
|
|
109
|
+
pattern = pattern.replace(/\\/g, "");
|
|
110
|
+
const match = pattern.match(/^(https?):\/\/([a-zA-Z0-9.*-]{1,253})(?::(\d{1,5}|\*))?(?:\/.*)?$/);
|
|
111
|
+
if (!match) return null;
|
|
112
|
+
const [, protocol, host, port] = match;
|
|
113
|
+
const hasWildcard = host.includes("*");
|
|
114
|
+
if (hasWildcard && !host.startsWith("*.")) return null;
|
|
115
|
+
if (hasWildcard && host.slice(2).includes("*")) return null;
|
|
116
|
+
const domain = hasWildcard ? host.slice(2) : host;
|
|
117
|
+
const escapedDomain = domain.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
118
|
+
const hostRegex = hasWildcard ? `[^.]+\\.${escapedDomain}` : escapedDomain;
|
|
119
|
+
const portRegex = port === "*" ? ":\\d{1,5}" : port ? `:${port}` : "";
|
|
120
|
+
return new RegExp(`^${protocol}:\\/\\/${hostRegex}${portRegex}$`);
|
|
121
|
+
} catch {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
var isTrustedOrigin = (url, trustedOrigins) => {
|
|
126
|
+
if (!isValidURL(url) || trustedOrigins.length === 0) return false;
|
|
127
|
+
try {
|
|
128
|
+
const urlOrigin = new URL(url).origin;
|
|
129
|
+
for (const pattern of trustedOrigins) {
|
|
130
|
+
const regex = patternToRegex(pattern);
|
|
131
|
+
if (regex?.test(urlOrigin)) return true;
|
|
132
|
+
try {
|
|
133
|
+
if (isValidURL(pattern) && equals(new URL(pattern).origin, urlOrigin)) return true;
|
|
134
|
+
} catch {
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
} catch {
|
|
138
|
+
}
|
|
139
|
+
return false;
|
|
140
|
+
};
|
|
141
|
+
var safeEquals = (a, b) => {
|
|
142
|
+
const bufferA = Buffer.from(a);
|
|
143
|
+
const bufferB = Buffer.from(b);
|
|
144
|
+
if (bufferA.length !== bufferB.length) {
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
return (0, import_crypto.timingSafeEqual)(bufferA, bufferB);
|
|
148
|
+
};
|
|
43
149
|
// Annotate the CommonJS export names for ESM import in node:
|
|
44
150
|
0 && (module.exports = {
|
|
45
151
|
isFalsy,
|
|
46
152
|
isJWTPayloadWithToken,
|
|
153
|
+
isRelativeURL,
|
|
47
154
|
isRequest,
|
|
48
|
-
|
|
155
|
+
isSameOrigin,
|
|
156
|
+
isTrustedOrigin,
|
|
157
|
+
isValidURL,
|
|
158
|
+
patternToRegex,
|
|
159
|
+
safeEquals,
|
|
160
|
+
unsafeChars
|
|
49
161
|
});
|
package/dist/assert.d.ts
CHANGED
|
@@ -1,14 +1,33 @@
|
|
|
1
|
-
import { J as JWTPayloadWithToken } from './index-
|
|
1
|
+
import { J as JWTPayloadWithToken } from './index-CSyIJmCM.js';
|
|
2
2
|
import 'zod';
|
|
3
3
|
import './schemas.js';
|
|
4
|
-
import '
|
|
4
|
+
import './jose.js';
|
|
5
5
|
import '@aura-stack/jose';
|
|
6
6
|
import '@aura-stack/jose/jose';
|
|
7
|
+
import '@aura-stack/router/cookie';
|
|
7
8
|
import './@types/utility.js';
|
|
8
9
|
|
|
9
10
|
declare const isFalsy: (value: unknown) => boolean;
|
|
10
11
|
declare const isRequest: (value: unknown) => value is Request;
|
|
12
|
+
declare const unsafeChars: string[];
|
|
11
13
|
declare const isValidURL: (value: string) => boolean;
|
|
12
14
|
declare const isJWTPayloadWithToken: (payload: unknown) => payload is JWTPayloadWithToken;
|
|
15
|
+
declare const isRelativeURL: (value: string) => boolean;
|
|
16
|
+
declare const isSameOrigin: (origin: string, expected: string) => boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Converts a trusted origin pattern to a regex for matching.
|
|
19
|
+
* Supports `*` as subdomain wildcard: `https://*.example.com` matches `https://app.example.com`
|
|
20
|
+
* @todo: add support to Custom URI Schemes (e.g. `myapp://*`).
|
|
21
|
+
*/
|
|
22
|
+
declare const patternToRegex: (pattern: string) => RegExp | null;
|
|
23
|
+
/**
|
|
24
|
+
* Checks if a URL matches any of the trusted origin patterns.
|
|
25
|
+
* A URL is trusted if its origin matches any pattern (exact or wildcard).
|
|
26
|
+
*
|
|
27
|
+
* @param url - The URL to validate (e.g. from Referer, Origin, redirectTo)
|
|
28
|
+
* @param trustedOrigins - Array of exact URLs or patterns (e.g. `https://*.example.com`)
|
|
29
|
+
*/
|
|
30
|
+
declare const isTrustedOrigin: (url: string, trustedOrigins: string[]) => boolean;
|
|
31
|
+
declare const safeEquals: (a: string, b: string) => boolean;
|
|
13
32
|
|
|
14
|
-
export { isFalsy, isJWTPayloadWithToken, isRequest, isValidURL };
|
|
33
|
+
export { isFalsy, isJWTPayloadWithToken, isRelativeURL, isRequest, isSameOrigin, isTrustedOrigin, isValidURL, patternToRegex, safeEquals, unsafeChars };
|
package/dist/assert.js
CHANGED
|
@@ -1,12 +1,26 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isFalsy,
|
|
3
3
|
isJWTPayloadWithToken,
|
|
4
|
+
isRelativeURL,
|
|
4
5
|
isRequest,
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
isSameOrigin,
|
|
7
|
+
isTrustedOrigin,
|
|
8
|
+
isValidURL,
|
|
9
|
+
patternToRegex,
|
|
10
|
+
safeEquals,
|
|
11
|
+
unsafeChars
|
|
12
|
+
} from "./chunk-4EKY7655.js";
|
|
13
|
+
import "./chunk-QQVSRXGX.js";
|
|
14
|
+
import "./chunk-RRLIF4PQ.js";
|
|
7
15
|
export {
|
|
8
16
|
isFalsy,
|
|
9
17
|
isJWTPayloadWithToken,
|
|
18
|
+
isRelativeURL,
|
|
10
19
|
isRequest,
|
|
11
|
-
|
|
20
|
+
isSameOrigin,
|
|
21
|
+
isTrustedOrigin,
|
|
22
|
+
isValidURL,
|
|
23
|
+
patternToRegex,
|
|
24
|
+
safeEquals,
|
|
25
|
+
unsafeChars
|
|
12
26
|
};
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import {
|
|
2
|
+
equals
|
|
3
|
+
} from "./chunk-QQVSRXGX.js";
|
|
4
|
+
|
|
5
|
+
// src/assert.ts
|
|
6
|
+
import { timingSafeEqual } from "crypto";
|
|
7
|
+
var isFalsy = (value) => {
|
|
8
|
+
return value === false || value === 0 || value === "" || value === null || value === void 0 || Number.isNaN(value);
|
|
9
|
+
};
|
|
10
|
+
var isRequest = (value) => {
|
|
11
|
+
return typeof Request !== "undefined" && value instanceof Request;
|
|
12
|
+
};
|
|
13
|
+
var unsafeChars = [
|
|
14
|
+
"<",
|
|
15
|
+
">",
|
|
16
|
+
'"',
|
|
17
|
+
"`",
|
|
18
|
+
" ",
|
|
19
|
+
"\r",
|
|
20
|
+
"\n",
|
|
21
|
+
" ",
|
|
22
|
+
"\\",
|
|
23
|
+
"%2F",
|
|
24
|
+
"%5C",
|
|
25
|
+
"%2f",
|
|
26
|
+
"%5c",
|
|
27
|
+
"\r\n",
|
|
28
|
+
"%0A",
|
|
29
|
+
"%0D",
|
|
30
|
+
"%0a",
|
|
31
|
+
"%0d",
|
|
32
|
+
"..",
|
|
33
|
+
"//",
|
|
34
|
+
"///",
|
|
35
|
+
"...",
|
|
36
|
+
"%20",
|
|
37
|
+
"\0"
|
|
38
|
+
];
|
|
39
|
+
var isValidURL = (value) => {
|
|
40
|
+
if (!new RegExp(/^https?:\/\/[^/]/).test(value)) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
const match = value.match(/^(https?:\/\/)(.*)$/);
|
|
44
|
+
if (!match) return false;
|
|
45
|
+
const rest = match[2];
|
|
46
|
+
for (const char of unsafeChars) {
|
|
47
|
+
if (rest.includes(char)) return false;
|
|
48
|
+
}
|
|
49
|
+
const regex = /^https?:\/\/(?:[a-zA-Z0-9._-]+|localhost|\[[0-9a-fA-F:]+\])(?::\d{1,5})?(?:\/[a-zA-Z0-9._~!$&'()?#*+,;=:@-]*)*\/?$/;
|
|
50
|
+
return regex.test(match[0]);
|
|
51
|
+
};
|
|
52
|
+
var isJWTPayloadWithToken = (payload) => {
|
|
53
|
+
return typeof payload === "object" && payload !== null && "token" in payload && typeof payload?.token === "string";
|
|
54
|
+
};
|
|
55
|
+
var isRelativeURL = (value) => {
|
|
56
|
+
if (value.length > 100) return false;
|
|
57
|
+
for (const char of unsafeChars) {
|
|
58
|
+
if (value.includes(char)) return false;
|
|
59
|
+
}
|
|
60
|
+
const regex = /^\/[a-zA-Z0-9\-_\/.?&=#]*\/?$/;
|
|
61
|
+
return regex.test(value);
|
|
62
|
+
};
|
|
63
|
+
var isSameOrigin = (origin, expected) => {
|
|
64
|
+
const originURL = new URL(origin);
|
|
65
|
+
const expectedURL = new URL(expected);
|
|
66
|
+
return equals(originURL.origin, expectedURL.origin);
|
|
67
|
+
};
|
|
68
|
+
var patternToRegex = (pattern) => {
|
|
69
|
+
try {
|
|
70
|
+
if (pattern.length > 2048) return null;
|
|
71
|
+
pattern = pattern.replace(/\\/g, "");
|
|
72
|
+
const match = pattern.match(/^(https?):\/\/([a-zA-Z0-9.*-]{1,253})(?::(\d{1,5}|\*))?(?:\/.*)?$/);
|
|
73
|
+
if (!match) return null;
|
|
74
|
+
const [, protocol, host, port] = match;
|
|
75
|
+
const hasWildcard = host.includes("*");
|
|
76
|
+
if (hasWildcard && !host.startsWith("*.")) return null;
|
|
77
|
+
if (hasWildcard && host.slice(2).includes("*")) return null;
|
|
78
|
+
const domain = hasWildcard ? host.slice(2) : host;
|
|
79
|
+
const escapedDomain = domain.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
80
|
+
const hostRegex = hasWildcard ? `[^.]+\\.${escapedDomain}` : escapedDomain;
|
|
81
|
+
const portRegex = port === "*" ? ":\\d{1,5}" : port ? `:${port}` : "";
|
|
82
|
+
return new RegExp(`^${protocol}:\\/\\/${hostRegex}${portRegex}$`);
|
|
83
|
+
} catch {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
var isTrustedOrigin = (url, trustedOrigins) => {
|
|
88
|
+
if (!isValidURL(url) || trustedOrigins.length === 0) return false;
|
|
89
|
+
try {
|
|
90
|
+
const urlOrigin = new URL(url).origin;
|
|
91
|
+
for (const pattern of trustedOrigins) {
|
|
92
|
+
const regex = patternToRegex(pattern);
|
|
93
|
+
if (regex?.test(urlOrigin)) return true;
|
|
94
|
+
try {
|
|
95
|
+
if (isValidURL(pattern) && equals(new URL(pattern).origin, urlOrigin)) return true;
|
|
96
|
+
} catch {
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
} catch {
|
|
100
|
+
}
|
|
101
|
+
return false;
|
|
102
|
+
};
|
|
103
|
+
var safeEquals = (a, b) => {
|
|
104
|
+
const bufferA = Buffer.from(a);
|
|
105
|
+
const bufferB = Buffer.from(b);
|
|
106
|
+
if (bufferA.length !== bufferB.length) {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
return timingSafeEqual(bufferA, bufferB);
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
export {
|
|
113
|
+
isFalsy,
|
|
114
|
+
isRequest,
|
|
115
|
+
unsafeChars,
|
|
116
|
+
isValidURL,
|
|
117
|
+
isJWTPayloadWithToken,
|
|
118
|
+
isRelativeURL,
|
|
119
|
+
isSameOrigin,
|
|
120
|
+
patternToRegex,
|
|
121
|
+
isTrustedOrigin,
|
|
122
|
+
safeEquals
|
|
123
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// src/env.ts
|
|
2
|
+
var env = new Proxy({}, {
|
|
3
|
+
get(_, prop) {
|
|
4
|
+
if (typeof prop !== "string") return void 0;
|
|
5
|
+
const hasProperty = (process2) => {
|
|
6
|
+
return process2 && Object.prototype.hasOwnProperty.call(process2, prop);
|
|
7
|
+
};
|
|
8
|
+
try {
|
|
9
|
+
if (typeof process !== "undefined" && hasProperty(process.env)) {
|
|
10
|
+
return process.env[prop];
|
|
11
|
+
}
|
|
12
|
+
if (typeof import.meta !== "undefined" && hasProperty(import.meta.env)) {
|
|
13
|
+
return import.meta.env[prop];
|
|
14
|
+
}
|
|
15
|
+
if (typeof Deno !== "undefined" && Deno.env?.get) {
|
|
16
|
+
return Deno.env.get(prop);
|
|
17
|
+
}
|
|
18
|
+
if (typeof Bun !== "undefined" && hasProperty(Bun.env)) {
|
|
19
|
+
return Bun.env[prop];
|
|
20
|
+
}
|
|
21
|
+
const globalValue = globalThis[prop];
|
|
22
|
+
return typeof globalValue === "string" ? globalValue : void 0;
|
|
23
|
+
} catch {
|
|
24
|
+
return void 0;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
export {
|
|
30
|
+
env
|
|
31
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// src/oauth/bitbucket.ts
|
|
2
|
+
var bitbucket = (options) => {
|
|
3
|
+
return {
|
|
4
|
+
id: "bitbucket",
|
|
5
|
+
name: "Bitbucket",
|
|
6
|
+
authorizeURL: "https://bitbucket.org/site/oauth2/authorize",
|
|
7
|
+
accessToken: "https://bitbucket.org/site/oauth2/access_token",
|
|
8
|
+
userInfo: "https://api.bitbucket.org/2.0/user",
|
|
9
|
+
scope: "account email",
|
|
10
|
+
responseType: "code",
|
|
11
|
+
profile(profile) {
|
|
12
|
+
return {
|
|
13
|
+
sub: profile.uuid ?? profile.account_id,
|
|
14
|
+
name: profile.display_name ?? profile.nickname,
|
|
15
|
+
image: profile.links.avatar?.href,
|
|
16
|
+
email: void 0
|
|
17
|
+
};
|
|
18
|
+
},
|
|
19
|
+
...options
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export {
|
|
24
|
+
bitbucket
|
|
25
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// src/oauth/strava.ts
|
|
2
|
+
var strava = (options) => {
|
|
3
|
+
return {
|
|
4
|
+
id: "strava",
|
|
5
|
+
name: "Strava",
|
|
6
|
+
authorizeURL: "https://www.strava.com/oauth/authorize",
|
|
7
|
+
accessToken: "https://www.strava.com/oauth/token",
|
|
8
|
+
userInfo: "https://www.strava.com/api/v3/athlete",
|
|
9
|
+
scope: "read",
|
|
10
|
+
responseType: "code",
|
|
11
|
+
profile(profile) {
|
|
12
|
+
return {
|
|
13
|
+
sub: profile.id.toString(),
|
|
14
|
+
name: `${profile.firstname} ${profile.lastname}`,
|
|
15
|
+
image: profile.profile,
|
|
16
|
+
email: void 0
|
|
17
|
+
};
|
|
18
|
+
},
|
|
19
|
+
...options
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export {
|
|
24
|
+
strava
|
|
25
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// src/oauth/gitlab.ts
|
|
2
|
+
var gitlab = (options) => {
|
|
3
|
+
return {
|
|
4
|
+
id: "gitlab",
|
|
5
|
+
name: "GitLab",
|
|
6
|
+
authorizeURL: "https://gitlab.com/oauth/authorize",
|
|
7
|
+
accessToken: "https://gitlab.com/oauth/token",
|
|
8
|
+
userInfo: "https://gitlab.com/api/v4/user",
|
|
9
|
+
scope: "read_user",
|
|
10
|
+
responseType: "code",
|
|
11
|
+
profile(profile) {
|
|
12
|
+
return {
|
|
13
|
+
sub: profile.id.toString(),
|
|
14
|
+
name: profile.name ?? profile.username,
|
|
15
|
+
email: profile.email,
|
|
16
|
+
image: profile.avatar_url
|
|
17
|
+
};
|
|
18
|
+
},
|
|
19
|
+
...options
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export {
|
|
24
|
+
gitlab
|
|
25
|
+
};
|
|
@@ -37,7 +37,8 @@ var setCookie = (cookieName, value, options) => {
|
|
|
37
37
|
var expiredCookieAttributes = {
|
|
38
38
|
...defaultCookieOptions,
|
|
39
39
|
expires: /* @__PURE__ */ new Date(0),
|
|
40
|
-
maxAge: 0
|
|
40
|
+
maxAge: 0,
|
|
41
|
+
secure: true
|
|
41
42
|
};
|
|
42
43
|
var getCookie = (request, cookieName) => {
|
|
43
44
|
const cookies = request.headers.get("Cookie");
|
|
@@ -69,31 +70,27 @@ var createSessionCookie = async (jose, session) => {
|
|
|
69
70
|
throw new AuthInternalError("INVALID_JWT_TOKEN", "Failed to create session cookie", { cause: error });
|
|
70
71
|
}
|
|
71
72
|
};
|
|
72
|
-
var defineSecureCookieOptions = (useSecure, attributes, strategy) => {
|
|
73
|
+
var defineSecureCookieOptions = (useSecure, attributes, strategy, logger) => {
|
|
73
74
|
if (!attributes.httpOnly) {
|
|
74
|
-
|
|
75
|
-
"[WARNING]: Cookie is configured without HttpOnly. This allows JavaScript access via document.cookie and increases XSS risk."
|
|
76
|
-
);
|
|
75
|
+
logger?.log("COOKIE_HTTPONLY_DISABLED");
|
|
77
76
|
}
|
|
78
77
|
if (attributes.domain === "*") {
|
|
79
78
|
attributes.domain = void 0;
|
|
80
|
-
|
|
79
|
+
logger?.log("COOKIE_WILDCARD_DOMAIN");
|
|
81
80
|
}
|
|
82
81
|
if (!useSecure) {
|
|
83
82
|
if (attributes.secure) {
|
|
84
|
-
|
|
85
|
-
"[WARNING]: The 'Secure' attribute will be disabled for this cookie. Serve over HTTPS to enforce Secure cookies."
|
|
86
|
-
);
|
|
83
|
+
logger?.log("COOKIE_SECURE_DISABLED");
|
|
87
84
|
}
|
|
88
85
|
if (attributes.sameSite == "none") {
|
|
89
86
|
attributes.sameSite = "lax";
|
|
90
|
-
|
|
87
|
+
logger?.log("COOKIE_SAMESITE_NONE_WITHOUT_SECURE");
|
|
91
88
|
}
|
|
92
89
|
if (process.env.NODE_ENV === "production") {
|
|
93
|
-
|
|
90
|
+
logger?.log("COOKIE_INSECURE_IN_PRODUCTION");
|
|
94
91
|
}
|
|
95
92
|
if (strategy === "host") {
|
|
96
|
-
|
|
93
|
+
logger?.log("COOKIE_HOST_STRATEGY_INSECURE");
|
|
97
94
|
}
|
|
98
95
|
return {
|
|
99
96
|
...defaultCookieOptions,
|
|
@@ -107,7 +104,7 @@ var defineSecureCookieOptions = (useSecure, attributes, strategy) => {
|
|
|
107
104
|
...defaultHostCookieConfig
|
|
108
105
|
} : { ...defaultCookieOptions, ...attributes, ...defaultSecureCookieConfig };
|
|
109
106
|
};
|
|
110
|
-
var createCookieStore = (useSecure, prefix, overrides) => {
|
|
107
|
+
var createCookieStore = (useSecure, prefix, overrides, logger) => {
|
|
111
108
|
prefix ??= COOKIE_NAME;
|
|
112
109
|
const securePrefix = useSecure ? "__Secure-" : "";
|
|
113
110
|
const hostPrefix = useSecure ? "__Host-" : "";
|
|
@@ -120,7 +117,8 @@ var createCookieStore = (useSecure, prefix, overrides) => {
|
|
|
120
117
|
...defaultCookieOptions,
|
|
121
118
|
...overrides?.sessionToken?.attributes
|
|
122
119
|
},
|
|
123
|
-
overrides?.sessionToken?.attributes?.strategy ?? "secure"
|
|
120
|
+
overrides?.sessionToken?.attributes?.strategy ?? "secure",
|
|
121
|
+
logger
|
|
124
122
|
)
|
|
125
123
|
},
|
|
126
124
|
state: {
|
|
@@ -131,7 +129,8 @@ var createCookieStore = (useSecure, prefix, overrides) => {
|
|
|
131
129
|
...oauthCookieOptions,
|
|
132
130
|
...overrides?.state?.attributes
|
|
133
131
|
},
|
|
134
|
-
overrides?.state?.attributes?.strategy ?? "secure"
|
|
132
|
+
overrides?.state?.attributes?.strategy ?? "secure",
|
|
133
|
+
logger
|
|
135
134
|
)
|
|
136
135
|
},
|
|
137
136
|
csrfToken: {
|
|
@@ -140,9 +139,11 @@ var createCookieStore = (useSecure, prefix, overrides) => {
|
|
|
140
139
|
useSecure,
|
|
141
140
|
{
|
|
142
141
|
...overrides?.csrfToken?.attributes,
|
|
143
|
-
...defaultHostCookieConfig
|
|
142
|
+
...defaultHostCookieConfig,
|
|
143
|
+
sameSite: "strict"
|
|
144
144
|
},
|
|
145
|
-
overrides?.csrfToken?.attributes?.strategy ?? "host"
|
|
145
|
+
overrides?.csrfToken?.attributes?.strategy ?? "host",
|
|
146
|
+
logger
|
|
146
147
|
)
|
|
147
148
|
},
|
|
148
149
|
redirectTo: {
|
|
@@ -153,7 +154,8 @@ var createCookieStore = (useSecure, prefix, overrides) => {
|
|
|
153
154
|
...oauthCookieOptions,
|
|
154
155
|
...overrides?.redirectTo?.attributes
|
|
155
156
|
},
|
|
156
|
-
overrides?.redirectTo?.attributes?.strategy ?? "secure"
|
|
157
|
+
overrides?.redirectTo?.attributes?.strategy ?? "secure",
|
|
158
|
+
logger
|
|
157
159
|
)
|
|
158
160
|
},
|
|
159
161
|
redirectURI: {
|
|
@@ -164,7 +166,8 @@ var createCookieStore = (useSecure, prefix, overrides) => {
|
|
|
164
166
|
...oauthCookieOptions,
|
|
165
167
|
...overrides?.redirectURI?.attributes
|
|
166
168
|
},
|
|
167
|
-
overrides?.redirectURI?.attributes?.strategy ?? "secure"
|
|
169
|
+
overrides?.redirectURI?.attributes?.strategy ?? "secure",
|
|
170
|
+
logger
|
|
168
171
|
)
|
|
169
172
|
},
|
|
170
173
|
codeVerifier: {
|
|
@@ -175,7 +178,8 @@ var createCookieStore = (useSecure, prefix, overrides) => {
|
|
|
175
178
|
...oauthCookieOptions,
|
|
176
179
|
...overrides?.codeVerifier?.attributes
|
|
177
180
|
},
|
|
178
|
-
overrides?.codeVerifier?.attributes?.strategy ?? "secure"
|
|
181
|
+
overrides?.codeVerifier?.attributes?.strategy ?? "secure",
|
|
182
|
+
logger
|
|
179
183
|
)
|
|
180
184
|
}
|
|
181
185
|
};
|