@aura-stack/auth 0.1.0-rc.8 → 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/dist/@types/index.cjs +15 -15
- package/dist/@types/index.d.ts +7 -31
- package/dist/@types/index.js +1 -1
- package/dist/@types/router.d.cjs +1 -1
- package/dist/@types/router.d.d.ts +7 -7
- package/dist/@types/utility.cjs +15 -15
- package/dist/@types/utility.d.ts +6 -6
- package/dist/@types/utility.js +1 -1
- package/dist/actions/callback/access-token.cjs +143 -143
- package/dist/actions/callback/access-token.d.ts +15 -20
- package/dist/actions/callback/access-token.js +8 -4
- package/dist/actions/callback/callback.cjs +437 -455
- package/dist/actions/callback/callback.d.ts +10 -12
- package/dist/actions/callback/callback.js +16 -12
- package/dist/actions/callback/userinfo.cjs +131 -134
- package/dist/actions/callback/userinfo.d.ts +9 -9
- package/dist/actions/callback/userinfo.js +10 -6
- package/dist/actions/csrfToken/csrfToken.cjs +162 -171
- package/dist/actions/csrfToken/csrfToken.d.ts +3 -3
- package/dist/actions/csrfToken/csrfToken.js +12 -8
- package/dist/actions/index.cjs +746 -773
- package/dist/actions/index.d.ts +13 -13
- package/dist/actions/index.js +34 -18
- package/dist/actions/session/session.cjs +149 -155
- package/dist/actions/session/session.d.ts +3 -3
- package/dist/actions/session/session.js +11 -7
- package/dist/actions/signIn/authorization.cjs +231 -249
- package/dist/actions/signIn/authorization.d.ts +12 -18
- package/dist/actions/signIn/authorization.js +16 -6
- package/dist/actions/signIn/signIn.cjs +396 -423
- package/dist/actions/signIn/signIn.d.ts +10 -10
- package/dist/actions/signIn/signIn.js +14 -10
- package/dist/actions/signOut/signOut.cjs +417 -440
- package/dist/actions/signOut/signOut.d.ts +3 -3
- package/dist/actions/signOut/signOut.js +15 -11
- package/dist/assert.cjs +35 -36
- package/dist/assert.d.ts +4 -4
- package/dist/assert.js +10 -2
- package/dist/chunk-256KIVJL.js +85 -96
- package/dist/chunk-42XB3YCW.js +19 -17
- package/dist/chunk-6SM22VVJ.js +13 -10
- package/dist/chunk-CAKJT3KS.js +84 -69
- package/dist/chunk-E3OXBRYF.js +19 -17
- package/dist/chunk-EBPE35JT.js +28 -26
- package/dist/chunk-FIPU4MLT.js +18 -16
- package/dist/chunk-FJUDBLCP.js +50 -43
- package/dist/chunk-FKRDCWBF.js +19 -17
- package/dist/chunk-GZU3RBTB.js +51 -40
- package/dist/chunk-HGJ4TXY4.js +132 -100
- package/dist/chunk-HMRKN75I.js +63 -63
- package/dist/chunk-IKHPGFCW.js +11 -9
- package/dist/chunk-JAPMIE6S.js +7 -5
- package/dist/chunk-KRNOMBXQ.js +19 -17
- package/dist/chunk-LLR722CL.js +91 -70
- package/dist/chunk-RLT4RFKV.js +39 -30
- package/dist/chunk-SJPDVKUS.js +107 -88
- package/dist/chunk-SMQO5WD7.js +26 -16
- package/dist/chunk-STHEPPUZ.js +8 -6
- package/dist/chunk-UJJ7R56J.js +47 -37
- package/dist/chunk-UTDLUEEG.js +27 -21
- package/dist/chunk-VFTYH33W.js +54 -37
- package/dist/chunk-XXJKNKGQ.js +33 -23
- package/dist/chunk-ZV4BH47P.js +132 -134
- package/dist/cookie.cjs +169 -175
- package/dist/cookie.d.ts +23 -51
- package/dist/cookie.js +34 -34
- package/dist/error.cjs +75 -75
- package/dist/error.d.ts +30 -30
- package/dist/error.js +15 -8
- package/dist/headers.cjs +28 -28
- package/dist/headers.d.ts +2 -2
- package/dist/headers.js +6 -2
- package/dist/index-DpfbvTZ_.d.ts +249 -298
- package/dist/index.cjs +936 -969
- package/dist/index.d.ts +10 -31
- package/dist/index.js +70 -50
- package/dist/jose.cjs +61 -64
- package/dist/jose.d.ts +8 -8
- package/dist/jose.js +9 -5
- package/dist/oauth/bitbucket.cjs +38 -38
- package/dist/oauth/bitbucket.d.ts +7 -7
- package/dist/oauth/bitbucket.js +6 -2
- package/dist/oauth/discord.cjs +48 -48
- package/dist/oauth/discord.d.ts +7 -7
- package/dist/oauth/discord.js +6 -2
- package/dist/oauth/figma.cjs +39 -39
- package/dist/oauth/figma.d.ts +7 -7
- package/dist/oauth/figma.js +6 -2
- package/dist/oauth/github.cjs +31 -31
- package/dist/oauth/github.d.ts +7 -7
- package/dist/oauth/github.js +6 -2
- package/dist/oauth/gitlab.cjs +39 -39
- package/dist/oauth/gitlab.d.ts +7 -7
- package/dist/oauth/gitlab.js +6 -2
- package/dist/oauth/index.cjs +180 -180
- package/dist/oauth/index.d.ts +7 -26
- package/dist/oauth/index.js +36 -9
- package/dist/oauth/spotify.cjs +39 -39
- package/dist/oauth/spotify.d.ts +7 -7
- package/dist/oauth/spotify.js +6 -2
- package/dist/oauth/x.cjs +39 -39
- package/dist/oauth/x.d.ts +7 -7
- package/dist/oauth/x.js +6 -2
- package/dist/response.cjs +27 -27
- package/dist/response.d.ts +2 -2
- package/dist/response.js +6 -2
- package/dist/schemas.cjs +91 -91
- package/dist/schemas.d.ts +93 -126
- package/dist/schemas.js +18 -18
- package/dist/secure.cjs +95 -98
- package/dist/secure.d.ts +17 -17
- package/dist/secure.js +18 -4
- package/dist/utils.cjs +119 -132
- package/dist/utils.d.ts +11 -26
- package/dist/utils.js +21 -21
- package/package.json +2 -2
|
@@ -1,513 +1,490 @@
|
|
|
1
|
-
"use strict"
|
|
2
|
-
var __create = Object.create
|
|
3
|
-
var __defProp = Object.defineProperty
|
|
4
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor
|
|
5
|
-
var __getOwnPropNames = Object.getOwnPropertyNames
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf
|
|
7
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
8
|
var __export = (target, all) => {
|
|
9
|
-
|
|
10
|
-
}
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
11
12
|
var __copyProps = (to, from, except, desc) => {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
var __toESM = (mod, isNodeMode, target) => (
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
)
|
|
29
|
-
)
|
|
30
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod)
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
31
29
|
|
|
32
30
|
// src/actions/signOut/signOut.ts
|
|
33
|
-
var signOut_exports = {}
|
|
31
|
+
var signOut_exports = {};
|
|
34
32
|
__export(signOut_exports, {
|
|
35
|
-
|
|
36
|
-
})
|
|
37
|
-
module.exports = __toCommonJS(signOut_exports)
|
|
38
|
-
var import_zod = __toESM(require("zod"), 1)
|
|
39
|
-
var import_router2 = require("@aura-stack/router")
|
|
33
|
+
signOutAction: () => signOutAction
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(signOut_exports);
|
|
36
|
+
var import_zod = __toESM(require("zod"), 1);
|
|
37
|
+
var import_router2 = require("@aura-stack/router");
|
|
40
38
|
|
|
41
39
|
// src/secure.ts
|
|
42
|
-
var import_node_crypto = __toESM(require("crypto"), 1)
|
|
40
|
+
var import_node_crypto = __toESM(require("crypto"), 1);
|
|
43
41
|
|
|
44
42
|
// src/utils.ts
|
|
45
|
-
var import_router = require("@aura-stack/router")
|
|
43
|
+
var import_router = require("@aura-stack/router");
|
|
46
44
|
|
|
47
45
|
// src/error.ts
|
|
48
46
|
var AuthError = class extends Error {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
47
|
+
constructor(type, message) {
|
|
48
|
+
super(message);
|
|
49
|
+
this.type = type;
|
|
50
|
+
this.name = "AuthError";
|
|
51
|
+
}
|
|
52
|
+
};
|
|
55
53
|
var InvalidCsrfTokenError = class extends AuthError {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
54
|
+
constructor(message = "The provided CSRF token is invalid or has expired") {
|
|
55
|
+
super("invalid_csrf_token", message);
|
|
56
|
+
this.name = "InvalidCsrfTokenError";
|
|
57
|
+
}
|
|
58
|
+
};
|
|
61
59
|
var InvalidRedirectToError = class extends AuthError {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}
|
|
60
|
+
constructor(message = "The redirectTo parameter does not match the hosted origin.") {
|
|
61
|
+
super("invalid_redirect_to", message);
|
|
62
|
+
this.name = "InvalidRedirectToError";
|
|
63
|
+
}
|
|
64
|
+
};
|
|
67
65
|
var isAuthError = (error) => {
|
|
68
|
-
|
|
69
|
-
}
|
|
66
|
+
return error instanceof AuthError;
|
|
67
|
+
};
|
|
70
68
|
var ERROR_RESPONSE = {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
69
|
+
AUTHORIZATION: {
|
|
70
|
+
INVALID_REQUEST: "invalid_request",
|
|
71
|
+
UNAUTHORIZED_CLIENT: "unauthorized_client",
|
|
72
|
+
ACCESS_DENIED: "access_denied",
|
|
73
|
+
UNSUPPORTED_RESPONSE_TYPE: "unsupported_response_type",
|
|
74
|
+
INVALID_SCOPE: "invalid_scope",
|
|
75
|
+
SERVER_ERROR: "server_error",
|
|
76
|
+
TEMPORARILY_UNAVAILABLE: "temporarily_unavailable"
|
|
77
|
+
},
|
|
78
|
+
ACCESS_TOKEN: {
|
|
79
|
+
INVALID_REQUEST: "invalid_request",
|
|
80
|
+
INVALID_CLIENT: "invalid_client",
|
|
81
|
+
INVALID_GRANT: "invalid_grant",
|
|
82
|
+
UNAUTHORIZED_CLIENT: "unauthorized_client",
|
|
83
|
+
UNSUPPORTED_GRANT_TYPE: "unsupported_grant_type",
|
|
84
|
+
INVALID_SCOPE: "invalid_scope"
|
|
85
|
+
}
|
|
86
|
+
};
|
|
89
87
|
|
|
90
88
|
// src/utils.ts
|
|
91
89
|
var equals = (a, b) => {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
90
|
+
if (a === null || b === null || a === void 0 || b === void 0) return false;
|
|
91
|
+
return a === b;
|
|
92
|
+
};
|
|
95
93
|
var sanitizeURL = (url2) => {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
path = path.replace(/\/+$/, "/")
|
|
117
|
-
} else if (path !== "/") {
|
|
118
|
-
path = path.replace(/\/+$/, "")
|
|
119
|
-
}
|
|
120
|
-
return protocol + domain + path
|
|
121
|
-
}
|
|
122
|
-
let sanitized = decodedURL
|
|
123
|
-
.replace(/\/\.\.\//g, "/")
|
|
124
|
-
.replace(/\/\.\.$/, "")
|
|
125
|
-
.replace(/\.{2,}/g, "")
|
|
126
|
-
.replace(/\/{2,}/g, "/")
|
|
127
|
-
if (sanitized !== "/" && sanitized.endsWith("/")) {
|
|
128
|
-
sanitized = sanitized.replace(/\/+$/, "/")
|
|
129
|
-
} else if (sanitized !== "/") {
|
|
130
|
-
sanitized = sanitized.replace(/\/+$/, "")
|
|
131
|
-
}
|
|
132
|
-
return sanitized
|
|
133
|
-
} catch {
|
|
134
|
-
return url2.trim()
|
|
94
|
+
try {
|
|
95
|
+
let decodedURL = decodeURIComponent(url2).trim();
|
|
96
|
+
const protocolMatch = decodedURL.match(/^([a-zA-Z][a-zA-Z0-9+.-]*:\/\/)/);
|
|
97
|
+
let protocol = "";
|
|
98
|
+
let rest = decodedURL;
|
|
99
|
+
if (protocolMatch) {
|
|
100
|
+
protocol = protocolMatch[1];
|
|
101
|
+
rest = decodedURL.slice(protocol.length);
|
|
102
|
+
const slashIndex = rest.indexOf("/");
|
|
103
|
+
if (slashIndex === -1) {
|
|
104
|
+
return protocol + rest;
|
|
105
|
+
}
|
|
106
|
+
const domain = rest.slice(0, slashIndex);
|
|
107
|
+
let path = rest.slice(slashIndex).replace(/\/\.\.\//g, "/").replace(/\/\.\.$/, "").replace(/\.{2,}/g, "").replace(/\/{2,}/g, "/");
|
|
108
|
+
if (path !== "/" && path.endsWith("/")) {
|
|
109
|
+
path = path.replace(/\/+$/, "/");
|
|
110
|
+
} else if (path !== "/") {
|
|
111
|
+
path = path.replace(/\/+$/, "");
|
|
112
|
+
}
|
|
113
|
+
return protocol + domain + path;
|
|
135
114
|
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
url2.search = ""
|
|
142
|
-
return `${url2.origin}${url2.pathname}`
|
|
143
|
-
} catch {
|
|
144
|
-
return sanitizeURL(path)
|
|
115
|
+
let sanitized = decodedURL.replace(/\/\.\.\//g, "/").replace(/\/\.\.$/, "").replace(/\.{2,}/g, "").replace(/\/{2,}/g, "/");
|
|
116
|
+
if (sanitized !== "/" && sanitized.endsWith("/")) {
|
|
117
|
+
sanitized = sanitized.replace(/\/+$/, "/");
|
|
118
|
+
} else if (sanitized !== "/") {
|
|
119
|
+
sanitized = sanitized.replace(/\/+$/, "");
|
|
145
120
|
}
|
|
146
|
-
|
|
121
|
+
return sanitized;
|
|
122
|
+
} catch {
|
|
123
|
+
return url2.trim();
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
var getNormalizedOriginPath = (path) => {
|
|
127
|
+
try {
|
|
128
|
+
const url2 = new URL(path);
|
|
129
|
+
url2.hash = "";
|
|
130
|
+
url2.search = "";
|
|
131
|
+
return `${url2.origin}${url2.pathname}`;
|
|
132
|
+
} catch {
|
|
133
|
+
return sanitizeURL(path);
|
|
134
|
+
}
|
|
135
|
+
};
|
|
147
136
|
|
|
148
137
|
// src/secure.ts
|
|
149
138
|
var verifyCSRF = async (jose, cookie, header) => {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
}
|
|
161
|
-
return true
|
|
162
|
-
} catch {
|
|
163
|
-
throw new InvalidCsrfTokenError()
|
|
139
|
+
try {
|
|
140
|
+
const { token: cookieToken } = await jose.verifyJWS(cookie);
|
|
141
|
+
const { token: headerToken } = await jose.verifyJWS(header);
|
|
142
|
+
const cookieBuffer = Buffer.from(cookieToken);
|
|
143
|
+
const headerBuffer = Buffer.from(headerToken);
|
|
144
|
+
if (!equals(headerBuffer.length, cookieBuffer.length)) {
|
|
145
|
+
throw new InvalidCsrfTokenError();
|
|
146
|
+
}
|
|
147
|
+
if (!import_node_crypto.default.timingSafeEqual(cookieBuffer, headerBuffer)) {
|
|
148
|
+
throw new InvalidCsrfTokenError();
|
|
164
149
|
}
|
|
165
|
-
|
|
150
|
+
return true;
|
|
151
|
+
} catch {
|
|
152
|
+
throw new InvalidCsrfTokenError();
|
|
153
|
+
}
|
|
154
|
+
};
|
|
166
155
|
|
|
167
156
|
// src/headers.ts
|
|
168
157
|
var cacheControl = {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
}
|
|
158
|
+
"Cache-Control": "no-store",
|
|
159
|
+
Pragma: "no-cache",
|
|
160
|
+
Expires: "0",
|
|
161
|
+
Vary: "Cookie"
|
|
162
|
+
};
|
|
174
163
|
|
|
175
164
|
// src/response.ts
|
|
176
165
|
var AuraResponse = class extends Response {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
}
|
|
166
|
+
static json(body, init) {
|
|
167
|
+
return Response.json(body, init);
|
|
168
|
+
}
|
|
169
|
+
};
|
|
181
170
|
|
|
182
171
|
// src/assert.ts
|
|
183
172
|
var isRequest = (value) => {
|
|
184
|
-
|
|
185
|
-
}
|
|
173
|
+
return typeof Request !== "undefined" && value instanceof Request;
|
|
174
|
+
};
|
|
186
175
|
var isValidURL = (value) => {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
}
|
|
176
|
+
if (value.includes("\r\n") || value.includes("\n") || value.includes("\r")) return false;
|
|
177
|
+
const regex = /^https?:\/\/(?:[a-zA-Z0-9._-]+|localhost|\[[0-9a-fA-F:]+\])(?::\d{1,5})?(?:\/[a-zA-Z0-9._~!$&'()*+,;=:@-]*)*\/?$/;
|
|
178
|
+
return regex.test(value);
|
|
179
|
+
};
|
|
192
180
|
|
|
193
181
|
// src/schemas.ts
|
|
194
|
-
var import_v4 = require("zod/v4")
|
|
182
|
+
var import_v4 = require("zod/v4");
|
|
195
183
|
var OAuthProviderConfigSchema = (0, import_v4.object)({
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
})
|
|
184
|
+
authorizeURL: (0, import_v4.url)(),
|
|
185
|
+
accessToken: (0, import_v4.url)(),
|
|
186
|
+
scope: (0, import_v4.string)().optional(),
|
|
187
|
+
userInfo: (0, import_v4.url)(),
|
|
188
|
+
responseType: (0, import_v4.enum)(["code", "token", "id_token"]),
|
|
189
|
+
clientId: (0, import_v4.string)(),
|
|
190
|
+
clientSecret: (0, import_v4.string)()
|
|
191
|
+
});
|
|
204
192
|
var OAuthAuthorization = OAuthProviderConfigSchema.extend({
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
})
|
|
193
|
+
redirectURI: (0, import_v4.string)(),
|
|
194
|
+
state: (0, import_v4.string)(),
|
|
195
|
+
codeChallenge: (0, import_v4.string)(),
|
|
196
|
+
codeChallengeMethod: (0, import_v4.enum)(["plain", "S256"])
|
|
197
|
+
});
|
|
210
198
|
var OAuthAuthorizationResponse = (0, import_v4.object)({
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
})
|
|
199
|
+
state: (0, import_v4.string)(),
|
|
200
|
+
code: (0, import_v4.string)()
|
|
201
|
+
});
|
|
214
202
|
var OAuthAuthorizationErrorResponse = (0, import_v4.object)({
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
})
|
|
203
|
+
error: (0, import_v4.enum)([
|
|
204
|
+
"invalid_request",
|
|
205
|
+
"unauthorized_client",
|
|
206
|
+
"access_denied",
|
|
207
|
+
"unsupported_response_type",
|
|
208
|
+
"invalid_scope",
|
|
209
|
+
"server_error",
|
|
210
|
+
"temporarily_unavailable"
|
|
211
|
+
]),
|
|
212
|
+
error_description: (0, import_v4.string)().optional(),
|
|
213
|
+
error_uri: (0, import_v4.string)().optional(),
|
|
214
|
+
state: (0, import_v4.string)()
|
|
215
|
+
});
|
|
228
216
|
var OAuthAccessToken = OAuthProviderConfigSchema.extend({
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
})
|
|
217
|
+
redirectURI: (0, import_v4.string)(),
|
|
218
|
+
code: (0, import_v4.string)(),
|
|
219
|
+
codeVerifier: (0, import_v4.string)().min(43).max(128)
|
|
220
|
+
});
|
|
233
221
|
var OAuthAccessTokenResponse = (0, import_v4.object)({
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
})
|
|
222
|
+
access_token: (0, import_v4.string)(),
|
|
223
|
+
token_type: (0, import_v4.string)(),
|
|
224
|
+
expires_in: (0, import_v4.number)().optional(),
|
|
225
|
+
refresh_token: (0, import_v4.string)().optional(),
|
|
226
|
+
scope: (0, import_v4.string)().optional()
|
|
227
|
+
});
|
|
240
228
|
var OAuthAccessTokenErrorResponse = (0, import_v4.object)({
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
})
|
|
229
|
+
error: (0, import_v4.enum)([
|
|
230
|
+
"invalid_request",
|
|
231
|
+
"invalid_client",
|
|
232
|
+
"invalid_grant",
|
|
233
|
+
"unauthorized_client",
|
|
234
|
+
"unsupported_grant_type",
|
|
235
|
+
"invalid_scope"
|
|
236
|
+
]),
|
|
237
|
+
error_description: (0, import_v4.string)().optional(),
|
|
238
|
+
error_uri: (0, import_v4.string)().optional()
|
|
239
|
+
});
|
|
252
240
|
var OAuthErrorResponse = (0, import_v4.object)({
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
})
|
|
241
|
+
error: (0, import_v4.string)(),
|
|
242
|
+
error_description: (0, import_v4.string)().optional()
|
|
243
|
+
});
|
|
256
244
|
|
|
257
245
|
// src/actions/signIn/authorization.ts
|
|
258
246
|
var getOriginURL = (request, trustedProxyHeaders) => {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
} else {
|
|
269
|
-
return new URL(getNormalizedOriginPath(request.url))
|
|
270
|
-
}
|
|
271
|
-
}
|
|
247
|
+
const headers = request.headers;
|
|
248
|
+
if (trustedProxyHeaders) {
|
|
249
|
+
const protocol = headers.get("X-Forwarded-Proto") ?? headers.get("Forwarded")?.match(/proto=([^;]+)/i)?.[1] ?? "http";
|
|
250
|
+
const host = headers.get("X-Forwarded-Host") ?? headers.get("Host") ?? headers.get("Forwarded")?.match(/host=([^;]+)/i)?.[1] ?? null;
|
|
251
|
+
return new URL(`${protocol}://${host}${getNormalizedOriginPath(new URL(request.url).pathname)}`);
|
|
252
|
+
} else {
|
|
253
|
+
return new URL(getNormalizedOriginPath(request.url));
|
|
254
|
+
}
|
|
255
|
+
};
|
|
272
256
|
var createRedirectTo = (request, redirectTo, trustedProxyHeaders) => {
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
}
|
|
305
|
-
return "/"
|
|
306
|
-
} catch (error) {
|
|
307
|
-
if (isAuthError(error)) {
|
|
308
|
-
throw error
|
|
309
|
-
}
|
|
310
|
-
throw new AuthError(ERROR_RESPONSE.AUTHORIZATION.INVALID_REQUEST, "Invalid origin (potential CSRF).")
|
|
257
|
+
try {
|
|
258
|
+
const headers = request.headers;
|
|
259
|
+
const origin = headers.get("Origin");
|
|
260
|
+
const referer = headers.get("Referer");
|
|
261
|
+
let hostedURL = getOriginURL(request, trustedProxyHeaders);
|
|
262
|
+
if (redirectTo) {
|
|
263
|
+
if (redirectTo.startsWith("/")) {
|
|
264
|
+
return sanitizeURL(redirectTo);
|
|
265
|
+
}
|
|
266
|
+
const redirectToURL = new URL(sanitizeURL(getNormalizedOriginPath(redirectTo)));
|
|
267
|
+
if (!isValidURL(redirectTo) || !equals(redirectToURL.origin, hostedURL.origin)) {
|
|
268
|
+
throw new InvalidRedirectToError();
|
|
269
|
+
}
|
|
270
|
+
return sanitizeURL(redirectToURL.pathname);
|
|
271
|
+
}
|
|
272
|
+
if (referer) {
|
|
273
|
+
const refererURL = new URL(sanitizeURL(referer));
|
|
274
|
+
if (!isValidURL(referer) || !equals(refererURL.origin, hostedURL.origin)) {
|
|
275
|
+
throw new AuthError(
|
|
276
|
+
ERROR_RESPONSE.AUTHORIZATION.INVALID_REQUEST,
|
|
277
|
+
"The referer of the request does not match the hosted origin."
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
return sanitizeURL(refererURL.pathname);
|
|
281
|
+
}
|
|
282
|
+
if (origin) {
|
|
283
|
+
const originURL = new URL(sanitizeURL(getNormalizedOriginPath(origin)));
|
|
284
|
+
if (!isValidURL(origin) || !equals(originURL.origin, hostedURL.origin)) {
|
|
285
|
+
throw new AuthError(ERROR_RESPONSE.AUTHORIZATION.INVALID_REQUEST, "Invalid origin (potential CSRF).");
|
|
286
|
+
}
|
|
287
|
+
return sanitizeURL(originURL.pathname);
|
|
311
288
|
}
|
|
312
|
-
|
|
289
|
+
return "/";
|
|
290
|
+
} catch (error) {
|
|
291
|
+
if (isAuthError(error)) {
|
|
292
|
+
throw error;
|
|
293
|
+
}
|
|
294
|
+
throw new AuthError(ERROR_RESPONSE.AUTHORIZATION.INVALID_REQUEST, "Invalid origin (potential CSRF).");
|
|
295
|
+
}
|
|
296
|
+
};
|
|
313
297
|
|
|
314
298
|
// src/cookie.ts
|
|
315
|
-
var import_cookie = require("cookie")
|
|
316
|
-
var import_cookie2 = require("cookie")
|
|
317
|
-
var COOKIE_NAME = "aura-auth"
|
|
299
|
+
var import_cookie = require("cookie");
|
|
300
|
+
var import_cookie2 = require("cookie");
|
|
301
|
+
var COOKIE_NAME = "aura-auth";
|
|
318
302
|
var defaultCookieOptions = {
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
}
|
|
303
|
+
httpOnly: true,
|
|
304
|
+
sameSite: "lax",
|
|
305
|
+
path: "/",
|
|
306
|
+
maxAge: 60 * 60 * 24 * 15
|
|
307
|
+
};
|
|
324
308
|
var defaultStandardCookieConfig = {
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
}
|
|
309
|
+
secure: false,
|
|
310
|
+
httpOnly: true,
|
|
311
|
+
prefix: ""
|
|
312
|
+
};
|
|
329
313
|
var defaultSecureCookieConfig = {
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
}
|
|
314
|
+
secure: true,
|
|
315
|
+
prefix: "__Secure-"
|
|
316
|
+
};
|
|
333
317
|
var defaultHostCookieConfig = {
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
}
|
|
318
|
+
secure: true,
|
|
319
|
+
prefix: "__Host-",
|
|
320
|
+
path: "/",
|
|
321
|
+
domain: void 0
|
|
322
|
+
};
|
|
339
323
|
var expiredCookieOptions = {
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
}
|
|
324
|
+
...defaultCookieOptions,
|
|
325
|
+
expires: /* @__PURE__ */ new Date(0),
|
|
326
|
+
maxAge: 0
|
|
327
|
+
};
|
|
344
328
|
var defineDefaultCookieOptions = (options2) => {
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
}
|
|
329
|
+
return {
|
|
330
|
+
name: options2?.name ?? COOKIE_NAME,
|
|
331
|
+
prefix: options2?.prefix ?? (options2?.secure ? "__Secure-" : ""),
|
|
332
|
+
...defaultCookieOptions,
|
|
333
|
+
...options2
|
|
334
|
+
};
|
|
335
|
+
};
|
|
352
336
|
var setCookie = (cookieName, value, options2) => {
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
}
|
|
337
|
+
const { prefix, name } = defineDefaultCookieOptions(options2);
|
|
338
|
+
const cookieNameWithPrefix = `${prefix}${name}.${cookieName}`;
|
|
339
|
+
return (0, import_cookie.serialize)(cookieNameWithPrefix, value, {
|
|
340
|
+
...defaultCookieOptions,
|
|
341
|
+
...options2
|
|
342
|
+
});
|
|
343
|
+
};
|
|
360
344
|
var getCookie = (petition, cookie, options2, optional = false) => {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
}
|
|
366
|
-
throw new AuthError("invalid_request", "No cookies found. There is no active session")
|
|
345
|
+
const cookies = isRequest(petition) ? petition.headers.get("Cookie") : petition.headers.getSetCookie().join("; ");
|
|
346
|
+
if (!cookies) {
|
|
347
|
+
if (optional) {
|
|
348
|
+
return "";
|
|
367
349
|
}
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
350
|
+
throw new AuthError("invalid_request", "No cookies found. There is no active session");
|
|
351
|
+
}
|
|
352
|
+
const { name, prefix } = defineDefaultCookieOptions(options2);
|
|
353
|
+
const parsedCookies = (0, import_cookie.parse)(cookies);
|
|
354
|
+
const value = parsedCookies[`${prefix}${name}.${cookie}`];
|
|
355
|
+
if (value === void 0) {
|
|
356
|
+
if (optional) {
|
|
357
|
+
return "";
|
|
376
358
|
}
|
|
377
|
-
|
|
378
|
-
}
|
|
359
|
+
throw new AuthError("invalid_request", `Cookie "${cookie}" not found. There is no active session`);
|
|
360
|
+
}
|
|
361
|
+
return value;
|
|
362
|
+
};
|
|
379
363
|
var secureCookieOptions = (request, cookieOptions, trustedProxyHeaders) => {
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
364
|
+
const name = cookieOptions.name ?? COOKIE_NAME;
|
|
365
|
+
const isSecure = trustedProxyHeaders ? request.url.startsWith("https://") || request.headers.get("X-Forwarded-Proto") === "https" || request.headers.get("Forwarded")?.includes("proto=https") : request.url.startsWith("https://");
|
|
366
|
+
if (!cookieOptions.options?.httpOnly) {
|
|
367
|
+
console.warn(
|
|
368
|
+
"[WARNING]: Cookie is configured without HttpOnly. This allows JavaScript access via document.cookie and increases XSS risk."
|
|
369
|
+
);
|
|
370
|
+
}
|
|
371
|
+
if (cookieOptions.options?.domain === "*") {
|
|
372
|
+
console.warn("[WARNING]: Cookie 'Domain' is set to '*', which is insecure. Avoid wildcard domains.");
|
|
373
|
+
}
|
|
374
|
+
if (!isSecure) {
|
|
375
|
+
const options2 = cookieOptions.options;
|
|
376
|
+
if (options2?.secure) {
|
|
377
|
+
console.warn(
|
|
378
|
+
"[WARNING]: The 'Secure' attribute will be disabled for this cookie. Serve over HTTPS to enforce Secure cookies."
|
|
379
|
+
);
|
|
390
380
|
}
|
|
391
|
-
if (
|
|
392
|
-
|
|
381
|
+
if (options2?.sameSite == "none") {
|
|
382
|
+
console.warn("[WARNING]: SameSite=None without a secure connection can be blocked by browsers.");
|
|
393
383
|
}
|
|
394
|
-
if (
|
|
395
|
-
|
|
396
|
-
if (options2?.secure) {
|
|
397
|
-
console.warn(
|
|
398
|
-
"[WARNING]: The 'Secure' attribute will be disabled for this cookie. Serve over HTTPS to enforce Secure cookies."
|
|
399
|
-
)
|
|
400
|
-
}
|
|
401
|
-
if (options2?.sameSite == "none") {
|
|
402
|
-
console.warn("[WARNING]: SameSite=None without a secure connection can be blocked by browsers.")
|
|
403
|
-
}
|
|
404
|
-
if (process.env.NODE_ENV === "production") {
|
|
405
|
-
console.warn("[WARNING]: In production, ensure cookies are served over HTTPS to maintain security.")
|
|
406
|
-
}
|
|
407
|
-
return {
|
|
408
|
-
...defaultCookieOptions,
|
|
409
|
-
...cookieOptions.options,
|
|
410
|
-
sameSite: options2?.sameSite === "none" ? "lax" : (options2?.sameSite ?? "lax"),
|
|
411
|
-
...defaultStandardCookieConfig,
|
|
412
|
-
name,
|
|
413
|
-
}
|
|
384
|
+
if (process.env.NODE_ENV === "production") {
|
|
385
|
+
console.warn("[WARNING]: In production, ensure cookies are served over HTTPS to maintain security.");
|
|
414
386
|
}
|
|
415
|
-
return
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
387
|
+
return {
|
|
388
|
+
...defaultCookieOptions,
|
|
389
|
+
...cookieOptions.options,
|
|
390
|
+
sameSite: options2?.sameSite === "none" ? "lax" : options2?.sameSite ?? "lax",
|
|
391
|
+
...defaultStandardCookieConfig,
|
|
392
|
+
name
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
return cookieOptions.strategy === "host" ? {
|
|
396
|
+
...defaultCookieOptions,
|
|
397
|
+
...cookieOptions.options,
|
|
398
|
+
...defaultHostCookieConfig,
|
|
399
|
+
name
|
|
400
|
+
} : { ...defaultCookieOptions, ...cookieOptions.options, ...defaultSecureCookieConfig, name };
|
|
401
|
+
};
|
|
424
402
|
var expireCookie = (name, options2) => {
|
|
425
|
-
|
|
426
|
-
}
|
|
403
|
+
return setCookie(name, "", { ...options2, ...expiredCookieOptions });
|
|
404
|
+
};
|
|
427
405
|
|
|
428
406
|
// src/actions/signOut/signOut.ts
|
|
429
407
|
var config = (0, import_router2.createEndpointConfig)({
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
})
|
|
408
|
+
schemas: {
|
|
409
|
+
searchParams: import_zod.default.object({
|
|
410
|
+
token_type_hint: import_zod.default.literal("session_token"),
|
|
411
|
+
redirectTo: import_zod.default.string().optional()
|
|
412
|
+
})
|
|
413
|
+
}
|
|
414
|
+
});
|
|
437
415
|
var signOutAction = (0, import_router2.createEndpoint)(
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
)
|
|
416
|
+
"POST",
|
|
417
|
+
"/signOut",
|
|
418
|
+
async (ctx) => {
|
|
419
|
+
const {
|
|
420
|
+
request,
|
|
421
|
+
headers,
|
|
422
|
+
searchParams: { redirectTo },
|
|
423
|
+
context: { cookies, jose, trustedProxyHeaders }
|
|
424
|
+
} = ctx;
|
|
425
|
+
try {
|
|
426
|
+
const cookiesOptions = secureCookieOptions(request, cookies, trustedProxyHeaders);
|
|
427
|
+
const session = getCookie(request, "sessionToken", cookiesOptions);
|
|
428
|
+
const csrfToken = getCookie(request, "csrfToken", {
|
|
429
|
+
...cookiesOptions,
|
|
430
|
+
prefix: cookiesOptions.secure ? "__Host-" : ""
|
|
431
|
+
});
|
|
432
|
+
const header = headers.get("X-CSRF-Token");
|
|
433
|
+
if (!header || !session || !csrfToken) {
|
|
434
|
+
throw new Error("Missing CSRF token or session token");
|
|
435
|
+
}
|
|
436
|
+
await verifyCSRF(jose, csrfToken, header);
|
|
437
|
+
await jose.decodeJWT(session);
|
|
438
|
+
const normalizedOriginPath = getNormalizedOriginPath(request.url);
|
|
439
|
+
const location = createRedirectTo(
|
|
440
|
+
new Request(normalizedOriginPath, {
|
|
441
|
+
headers
|
|
442
|
+
}),
|
|
443
|
+
redirectTo
|
|
444
|
+
);
|
|
445
|
+
const responseHeaders = new Headers(cacheControl);
|
|
446
|
+
responseHeaders.append("Set-Cookie", expireCookie("sessionToken", cookiesOptions));
|
|
447
|
+
responseHeaders.append(
|
|
448
|
+
"Set-Cookie",
|
|
449
|
+
expireCookie("csrfToken", { ...cookiesOptions, prefix: cookiesOptions.secure ? "__Host-" : "" })
|
|
450
|
+
);
|
|
451
|
+
responseHeaders.append("Location", location);
|
|
452
|
+
return Response.json(
|
|
453
|
+
{ message: "Signed out successfully" },
|
|
454
|
+
{ status: import_router2.statusCode.ACCEPTED, headers: responseHeaders }
|
|
455
|
+
);
|
|
456
|
+
} catch (error) {
|
|
457
|
+
if (error instanceof InvalidCsrfTokenError) {
|
|
458
|
+
return AuraResponse.json(
|
|
459
|
+
{
|
|
460
|
+
error: "invalid_csrf_token",
|
|
461
|
+
error_description: "The provided CSRF token is invalid or has expired"
|
|
462
|
+
},
|
|
463
|
+
{ status: import_router2.statusCode.UNAUTHORIZED }
|
|
464
|
+
);
|
|
465
|
+
}
|
|
466
|
+
if (error instanceof InvalidRedirectToError) {
|
|
467
|
+
const { type, message } = error;
|
|
468
|
+
return AuraResponse.json(
|
|
469
|
+
{
|
|
470
|
+
error: type,
|
|
471
|
+
error_description: message
|
|
472
|
+
},
|
|
473
|
+
{ status: import_router2.statusCode.BAD_REQUEST }
|
|
474
|
+
);
|
|
475
|
+
}
|
|
476
|
+
return AuraResponse.json(
|
|
477
|
+
{
|
|
478
|
+
error: "invalid_session_token",
|
|
479
|
+
error_description: "The provided sessionToken is invalid or has already expired"
|
|
480
|
+
},
|
|
481
|
+
{ status: import_router2.statusCode.UNAUTHORIZED }
|
|
482
|
+
);
|
|
483
|
+
}
|
|
484
|
+
},
|
|
485
|
+
config
|
|
486
|
+
);
|
|
509
487
|
// Annotate the CommonJS export names for ESM import in node:
|
|
510
|
-
0 &&
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
})
|
|
488
|
+
0 && (module.exports = {
|
|
489
|
+
signOutAction
|
|
490
|
+
});
|