@finueva/auth 0.23.0 → 0.25.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/device.d.ts +3 -3
- package/dist/device.js +37 -9
- package/dist/index.d.ts +2 -2
- package/dist/index.js +59 -16
- package/dist/server.d.ts +79 -3
- package/dist/server.js +2389 -2098
- package/dist/{types-CgtPkDeO.d.ts → types-rx4YxsoH.d.ts} +19 -3
- package/package.json +1 -1
package/dist/server.js
CHANGED
|
@@ -1,2337 +1,2589 @@
|
|
|
1
|
-
|
|
2
|
-
const
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
authentication_required: "Authentication is required.",
|
|
14
|
-
request_origin_denied: "The request origin is not allowed.",
|
|
15
|
-
invalid_request: "The request is invalid.",
|
|
16
|
-
invalid_invitation: "The invitation is invalid.",
|
|
17
|
-
invitation_unavailable: "The invitation is not available.",
|
|
18
|
-
recipient_unavailable: "The recipient is unavailable.",
|
|
19
|
-
invitation_recipient_mismatch: "The invitation cannot be accepted by this account.",
|
|
20
|
-
invitation_recovery_required: "Invitation administration requires separate recovery.",
|
|
21
|
-
membership_removal_recovery_required: "Membership removal requires separate recovery.",
|
|
22
|
-
email_verification_required: "Email verification is required.",
|
|
23
|
-
invalid_workspace_selection: "The workspace selection is invalid.",
|
|
24
|
-
organization_context_too_large: "The organization context is too large.",
|
|
25
|
-
credential_rate_limited: "Credential requests are temporarily limited.",
|
|
26
|
-
auth_request_rate_limited: "Authentication requests are temporarily limited.",
|
|
27
|
-
organization_slug_unavailable: "The organization address is unavailable.",
|
|
28
|
-
state_conflict: "The authentication state conflicts with the request.",
|
|
29
|
-
access_denied: "Access is denied.",
|
|
30
|
-
platform_target_unavailable: "The platform administration target is unavailable.",
|
|
31
|
-
platform_quorum_unavailable: "Platform administration quorum is unavailable.",
|
|
32
|
-
platform_recovery_required: "Platform administration requires separate recovery.",
|
|
33
|
-
identity_authority_unavailable: "Authentication is temporarily unavailable.",
|
|
34
|
-
two_factor_required: "A second authentication factor is required.",
|
|
35
|
-
two_factor_code_invalid: "The verification code is invalid.",
|
|
36
|
-
two_factor_challenge_expired: "The second-factor challenge has ended. Sign in again.",
|
|
37
|
-
two_factor_locked: "Second-factor verification is temporarily locked.",
|
|
38
|
-
recent_sign_in_required: "A recent sign-in is required.",
|
|
39
|
-
enterprise_recovery_required: "Enterprise administration evidence requires operator recovery.",
|
|
40
|
-
recent_authentication_required: "A ready recent-authentication action is required.",
|
|
41
|
-
organization_closure_confirmation_mismatch: "The confirmation does not match the organization.",
|
|
42
|
-
organization_closure_cancellation_ended: "The closure cancellation period has ended.",
|
|
43
|
-
ceremony_return_refused: "The return address is not registered for this application.",
|
|
44
|
-
password_sign_in_required: "A password sign-in method is required for this passkey change."
|
|
45
|
-
};
|
|
46
|
-
var AuthError = class extends Error {
|
|
47
|
-
code;
|
|
48
|
-
status;
|
|
49
|
-
retryAfterSeconds;
|
|
50
|
-
constructor(code, status, retryAfterSeconds) {
|
|
51
|
-
super(messages[code]);
|
|
52
|
-
this.name = "AuthError";
|
|
53
|
-
this.code = code;
|
|
54
|
-
this.status = status;
|
|
55
|
-
this.retryAfterSeconds = retryAfterSeconds;
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
//#endregion
|
|
59
|
-
//#region src/shared.ts
|
|
60
|
-
const DRIVE_CREDENTIAL_LIFETIME_SECONDS = 840;
|
|
61
|
-
const id = /^[A-Za-z0-9_-]{1,128}$/;
|
|
62
|
-
const email = /^[^\s@]+@[^\s@]+$/;
|
|
63
|
-
const MAX_SOCIAL_ID_TOKEN_BYTES = 16 * 1024;
|
|
64
|
-
function normalizeEmail(value) {
|
|
65
|
-
if (typeof value !== "string") throw new TypeError("email is invalid");
|
|
66
|
-
const normalized = value.trim().toLowerCase();
|
|
67
|
-
if (normalized.length === 0 || normalized.length > 320 || !email.test(normalized)) throw new TypeError("email is invalid");
|
|
68
|
-
return normalized;
|
|
1
|
+
String.fromCharCode;
|
|
2
|
+
const HASH_RE = /#/g;
|
|
3
|
+
const AMPERSAND_RE = /&/g;
|
|
4
|
+
const SLASH_RE = /\//g;
|
|
5
|
+
const EQUAL_RE = /=/g;
|
|
6
|
+
const PLUS_RE = /\+/g;
|
|
7
|
+
const ENC_CARET_RE = /%5e/gi;
|
|
8
|
+
const ENC_BACKTICK_RE = /%60/gi;
|
|
9
|
+
const ENC_PIPE_RE = /%7c/gi;
|
|
10
|
+
const ENC_SPACE_RE = /%20/gi;
|
|
11
|
+
function encode$2(text) {
|
|
12
|
+
return encodeURI("" + text).replace(ENC_PIPE_RE, "|");
|
|
69
13
|
}
|
|
70
|
-
function
|
|
71
|
-
|
|
72
|
-
const keys = Object.keys(value);
|
|
73
|
-
if (keys.length !== 3 && keys.length !== 4 || keys.some((key) => key !== "provider" && key !== "idToken" && key !== "nonce" && key !== "signUp") || value.provider !== "google" && value.provider !== "apple" || typeof value.signUp !== "boolean" || typeof value.idToken !== "string" || value.idToken.length < 1 || new TextEncoder().encode(value.idToken).byteLength > MAX_SOCIAL_ID_TOKEN_BYTES || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(value.idToken) || value.nonce !== void 0 && (typeof value.nonce !== "string" || value.nonce.length < 1 || value.nonce.length > 256 || !/^[\x20-\x7e]+$/.test(value.nonce))) throw new TypeError("social ID token input is invalid");
|
|
74
|
-
return {
|
|
75
|
-
provider: value.provider,
|
|
76
|
-
idToken: value.idToken,
|
|
77
|
-
...value.nonce === void 0 ? {} : { nonce: value.nonce },
|
|
78
|
-
signUp: value.signUp
|
|
79
|
-
};
|
|
14
|
+
function encodeQueryValue(input) {
|
|
15
|
+
return encode$2(typeof input === "string" ? input : JSON.stringify(input)).replace(PLUS_RE, "%2B").replace(ENC_SPACE_RE, "+").replace(HASH_RE, "%23").replace(AMPERSAND_RE, "%26").replace(ENC_BACKTICK_RE, "`").replace(ENC_CARET_RE, "^").replace(SLASH_RE, "%2F");
|
|
80
16
|
}
|
|
81
|
-
function
|
|
82
|
-
return
|
|
83
|
-
provider: value.provider,
|
|
84
|
-
idToken: {
|
|
85
|
-
token: value.idToken,
|
|
86
|
-
...value.nonce === void 0 ? {} : { nonce: value.nonce }
|
|
87
|
-
},
|
|
88
|
-
requestSignUp: value.signUp
|
|
89
|
-
};
|
|
17
|
+
function encodeQueryKey(text) {
|
|
18
|
+
return encodeQueryValue(text).replace(EQUAL_RE, "%3D");
|
|
90
19
|
}
|
|
91
|
-
function
|
|
92
|
-
if (value.length === 0 || value.length > 2048 || /[^\x20-\x7e]/.test(value)) throw new TypeError(`${name} must be an ASCII HTTP origin`);
|
|
93
|
-
let url;
|
|
20
|
+
function decode$1(text = "") {
|
|
94
21
|
try {
|
|
95
|
-
|
|
22
|
+
return decodeURIComponent("" + text);
|
|
96
23
|
} catch {
|
|
97
|
-
|
|
24
|
+
return "" + text;
|
|
98
25
|
}
|
|
99
|
-
const local = url.hostname === "localhost" || url.hostname.endsWith(".localhost") || url.hostname === "127.0.0.1";
|
|
100
|
-
if (url.protocol !== "https:" && !(local && url.protocol === "http:") || url.username || url.password || url.pathname !== "/" || url.search || url.hash || url.origin !== value) throw new TypeError(`${name} must be an ASCII HTTP origin`);
|
|
101
|
-
return url.origin;
|
|
102
|
-
}
|
|
103
|
-
function normalizeTimeout(value) {
|
|
104
|
-
const timeout = value ?? 1e4;
|
|
105
|
-
if (!Number.isSafeInteger(timeout) || timeout < 1 || timeout > 6e4) throw new TypeError("timeoutMs must be an integer from 1 to 60000");
|
|
106
|
-
return timeout;
|
|
107
26
|
}
|
|
108
|
-
function
|
|
109
|
-
|
|
110
|
-
if (!isObject$1(value) || !isObject$1(value.session) || !isObject$1(value.user)) throw authorityUnavailable();
|
|
111
|
-
const expiresAt = toDate(value.session.expiresAt);
|
|
112
|
-
const image = value.user.image;
|
|
113
|
-
if (!isId(value.session.id) || !expiresAt || !isId(value.user.id) || typeof value.user.name !== "string" || value.user.name.length > 256 || typeof value.user.email !== "string" || value.user.email.length > 320 || !email.test(value.user.email) || typeof value.user.emailVerified !== "boolean" || image !== null && image !== void 0 && (typeof image !== "string" || image.length > 2048)) throw authorityUnavailable();
|
|
114
|
-
return {
|
|
115
|
-
id: value.session.id,
|
|
116
|
-
expiresAt,
|
|
117
|
-
user: {
|
|
118
|
-
id: value.user.id,
|
|
119
|
-
name: value.user.name,
|
|
120
|
-
email: value.user.email,
|
|
121
|
-
emailVerified: value.user.emailVerified,
|
|
122
|
-
image: image ?? null
|
|
123
|
-
}
|
|
124
|
-
};
|
|
27
|
+
function decodeQueryKey(text) {
|
|
28
|
+
return decode$1(text.replace(PLUS_RE, " "));
|
|
125
29
|
}
|
|
126
|
-
function
|
|
127
|
-
|
|
128
|
-
return {
|
|
129
|
-
tokenType: "Bearer",
|
|
130
|
-
token: value.token,
|
|
131
|
-
expiresAt: new Date(now + value.expiresIn * 1e3)
|
|
132
|
-
};
|
|
30
|
+
function decodeQueryValue(text) {
|
|
31
|
+
return decode$1(text.replace(PLUS_RE, " "));
|
|
133
32
|
}
|
|
134
|
-
function
|
|
135
|
-
|
|
136
|
-
if (
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
if (
|
|
145
|
-
|
|
33
|
+
function parseQuery(parametersString = "") {
|
|
34
|
+
const object = Object.create(null);
|
|
35
|
+
if (parametersString[0] === "?") parametersString = parametersString.slice(1);
|
|
36
|
+
for (const parameter of parametersString.split("&")) {
|
|
37
|
+
const s = parameter.match(/([^=]+)=?(.*)/) || [];
|
|
38
|
+
if (s.length < 2) continue;
|
|
39
|
+
const key = decodeQueryKey(s[1]);
|
|
40
|
+
if (key === "__proto__" || key === "constructor") continue;
|
|
41
|
+
const value = decodeQueryValue(s[2] || "");
|
|
42
|
+
if (object[key] === void 0) object[key] = value;
|
|
43
|
+
else if (Array.isArray(object[key])) object[key].push(value);
|
|
44
|
+
else object[key] = [object[key], value];
|
|
146
45
|
}
|
|
147
|
-
return
|
|
46
|
+
return object;
|
|
148
47
|
}
|
|
149
|
-
function
|
|
150
|
-
if (
|
|
151
|
-
return
|
|
48
|
+
function encodeQueryItem(key, value) {
|
|
49
|
+
if (typeof value === "number" || typeof value === "boolean") value = String(value);
|
|
50
|
+
if (!value) return encodeQueryKey(key);
|
|
51
|
+
if (Array.isArray(value)) return value.map((_value) => `${encodeQueryKey(key)}=${encodeQueryValue(_value)}`).join("&");
|
|
52
|
+
return `${encodeQueryKey(key)}=${encodeQueryValue(value)}`;
|
|
152
53
|
}
|
|
153
|
-
function
|
|
154
|
-
|
|
155
|
-
"capabilities",
|
|
156
|
-
"id",
|
|
157
|
-
"lifecycle",
|
|
158
|
-
"logo",
|
|
159
|
-
"name",
|
|
160
|
-
"role",
|
|
161
|
-
"slug"
|
|
162
|
-
]);
|
|
163
|
-
if (!isId(value.id) || !boundedString(value.name, 255) || !boundedString(value.slug, 255) || value.lifecycle !== "ordinary" && value.lifecycle !== "managed" || !role(value.role) || !isObject$1(value.capabilities)) throw authorityUnavailable();
|
|
164
|
-
exact$3(value.capabilities, [
|
|
165
|
-
"readInvitations",
|
|
166
|
-
"readMembers",
|
|
167
|
-
"readTeams"
|
|
168
|
-
]);
|
|
169
|
-
if (value.capabilities.readMembers !== true || value.capabilities.readTeams !== true || typeof value.capabilities.readInvitations !== "boolean") throw authorityUnavailable();
|
|
170
|
-
return {
|
|
171
|
-
id: value.id,
|
|
172
|
-
name: value.name,
|
|
173
|
-
slug: value.slug,
|
|
174
|
-
logo: nullableHttpsUrl(value.logo),
|
|
175
|
-
lifecycle: value.lifecycle,
|
|
176
|
-
role: value.role,
|
|
177
|
-
capabilities: {
|
|
178
|
-
readMembers: true,
|
|
179
|
-
readTeams: true,
|
|
180
|
-
readInvitations: value.capabilities.readInvitations
|
|
181
|
-
}
|
|
182
|
-
};
|
|
54
|
+
function stringifyQuery(query) {
|
|
55
|
+
return Object.keys(query).filter((k) => query[k] !== void 0).map((k) => encodeQueryItem(k, query[k])).filter(Boolean).join("&");
|
|
183
56
|
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
return {
|
|
194
|
-
name: value.name,
|
|
195
|
-
slug: value.slug,
|
|
196
|
-
logo
|
|
197
|
-
};
|
|
57
|
+
const PROTOCOL_STRICT_REGEX = /^[\s\w\0+.-]{2,}:([/\\]{1,2})/;
|
|
58
|
+
const PROTOCOL_REGEX = /^[\s\w\0+.-]{2,}:([/\\]{2})?/;
|
|
59
|
+
const PROTOCOL_RELATIVE_REGEX = /^([/\\]\s*){2,}[^/\\]/;
|
|
60
|
+
const TRAILING_SLASH_RE = /\/$|\/\?|\/#/;
|
|
61
|
+
const JOIN_LEADING_SLASH_RE = /^\.?\//;
|
|
62
|
+
function hasProtocol(inputString, opts = {}) {
|
|
63
|
+
if (typeof opts === "boolean") opts = { acceptRelative: opts };
|
|
64
|
+
if (opts.strict) return PROTOCOL_STRICT_REGEX.test(inputString);
|
|
65
|
+
return PROTOCOL_REGEX.test(inputString) || (opts.acceptRelative ? PROTOCOL_RELATIVE_REGEX.test(inputString) : false);
|
|
198
66
|
}
|
|
199
|
-
function
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
67
|
+
function hasTrailingSlash(input = "", respectQueryAndFragment) {
|
|
68
|
+
if (!respectQueryAndFragment) return input.endsWith("/");
|
|
69
|
+
return TRAILING_SLASH_RE.test(input);
|
|
70
|
+
}
|
|
71
|
+
function withoutTrailingSlash(input = "", respectQueryAndFragment) {
|
|
72
|
+
if (!respectQueryAndFragment) return (hasTrailingSlash(input) ? input.slice(0, -1) : input) || "/";
|
|
73
|
+
if (!hasTrailingSlash(input, true)) return input || "/";
|
|
74
|
+
let path = input;
|
|
75
|
+
let fragment = "";
|
|
76
|
+
const fragmentIndex = input.indexOf("#");
|
|
77
|
+
if (fragmentIndex !== -1) {
|
|
78
|
+
path = input.slice(0, fragmentIndex);
|
|
79
|
+
fragment = input.slice(fragmentIndex);
|
|
204
80
|
}
|
|
81
|
+
const [s0, ...s] = path.split("?");
|
|
82
|
+
return ((s0.endsWith("/") ? s0.slice(0, -1) : s0) || "/") + (s.length > 0 ? `?${s.join("?")}` : "") + fragment;
|
|
205
83
|
}
|
|
206
|
-
function
|
|
207
|
-
if (!
|
|
208
|
-
return
|
|
84
|
+
function withTrailingSlash(input = "", respectQueryAndFragment) {
|
|
85
|
+
if (!respectQueryAndFragment) return input.endsWith("/") ? input : input + "/";
|
|
86
|
+
if (hasTrailingSlash(input, true)) return input || "/";
|
|
87
|
+
let path = input;
|
|
88
|
+
let fragment = "";
|
|
89
|
+
const fragmentIndex = input.indexOf("#");
|
|
90
|
+
if (fragmentIndex !== -1) {
|
|
91
|
+
path = input.slice(0, fragmentIndex);
|
|
92
|
+
fragment = input.slice(fragmentIndex);
|
|
93
|
+
if (!path) return fragment;
|
|
94
|
+
}
|
|
95
|
+
const [s0, ...s] = path.split("?");
|
|
96
|
+
return s0 + "/" + (s.length > 0 ? `?${s.join("?")}` : "") + fragment;
|
|
209
97
|
}
|
|
210
|
-
function
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
98
|
+
function withBase(input, base) {
|
|
99
|
+
if (isEmptyURL(base) || hasProtocol(input)) return input;
|
|
100
|
+
const _base = withoutTrailingSlash(base);
|
|
101
|
+
if (input.startsWith(_base)) {
|
|
102
|
+
const nextChar = input[_base.length];
|
|
103
|
+
if (!nextChar || nextChar === "/" || nextChar === "?") return input;
|
|
215
104
|
}
|
|
105
|
+
return joinURL(_base, input);
|
|
216
106
|
}
|
|
217
|
-
function
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
107
|
+
function withQuery(input, query) {
|
|
108
|
+
const parsed = parseURL(input);
|
|
109
|
+
parsed.search = stringifyQuery({
|
|
110
|
+
...parseQuery(parsed.search),
|
|
111
|
+
...query
|
|
112
|
+
});
|
|
113
|
+
return stringifyParsedURL(parsed);
|
|
224
114
|
}
|
|
225
|
-
function
|
|
226
|
-
|
|
227
|
-
"id",
|
|
228
|
-
"name",
|
|
229
|
-
"slug"
|
|
230
|
-
]);
|
|
231
|
-
if (!isId(value.id) || !boundedString(value.name, 255) || !boundedString(value.slug, 128)) throw authorityUnavailable();
|
|
232
|
-
return {
|
|
233
|
-
id: value.id,
|
|
234
|
-
name: value.name,
|
|
235
|
-
slug: value.slug
|
|
236
|
-
};
|
|
115
|
+
function isEmptyURL(url) {
|
|
116
|
+
return !url || url === "/";
|
|
237
117
|
}
|
|
238
|
-
function
|
|
239
|
-
|
|
240
|
-
return {
|
|
241
|
-
name,
|
|
242
|
-
idempotencyKey
|
|
243
|
-
};
|
|
118
|
+
function isNonEmptyURL(url) {
|
|
119
|
+
return url && url !== "/";
|
|
244
120
|
}
|
|
245
|
-
function
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
121
|
+
function joinURL(base, ...input) {
|
|
122
|
+
let url = base || "";
|
|
123
|
+
for (const segment of input.filter((url2) => isNonEmptyURL(url2))) if (url) {
|
|
124
|
+
const _segment = segment.replace(JOIN_LEADING_SLASH_RE, "");
|
|
125
|
+
url = withTrailingSlash(url) + _segment;
|
|
126
|
+
} else url = segment;
|
|
127
|
+
return url;
|
|
252
128
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
const
|
|
256
|
-
if (
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
129
|
+
const protocolRelative = Symbol.for("ufo:protocolRelative");
|
|
130
|
+
function parseURL(input = "", defaultProto) {
|
|
131
|
+
const _specialProtoMatch = input.match(/^[\s\0]*(blob:|data:|javascript:|vbscript:)(.*)/i);
|
|
132
|
+
if (_specialProtoMatch) {
|
|
133
|
+
const [, _proto, _pathname = ""] = _specialProtoMatch;
|
|
134
|
+
return {
|
|
135
|
+
protocol: _proto.toLowerCase(),
|
|
136
|
+
pathname: _pathname,
|
|
137
|
+
href: _proto + _pathname,
|
|
138
|
+
auth: "",
|
|
139
|
+
host: "",
|
|
140
|
+
search: "",
|
|
141
|
+
hash: ""
|
|
142
|
+
};
|
|
262
143
|
}
|
|
263
|
-
if (
|
|
264
|
-
const
|
|
265
|
-
|
|
144
|
+
if (!hasProtocol(input, { acceptRelative: true })) return defaultProto ? parseURL(defaultProto + input) : parsePath(input);
|
|
145
|
+
const [, protocol = "", auth, hostAndPath = ""] = input.replace(/\\/g, "/").match(/^[\s\0]*([\w+.-]{2,}:)?\/\/([^/@]+@)?(.*)/) || [];
|
|
146
|
+
let [, host = "", path = ""] = hostAndPath.match(/([^#/?]*)(.*)?/) || [];
|
|
147
|
+
if (protocol === "file:") path = path.replace(/\/(?=[A-Za-z]:)/, "");
|
|
148
|
+
const { pathname, search, hash } = parsePath(path);
|
|
266
149
|
return {
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
150
|
+
protocol: protocol.toLowerCase(),
|
|
151
|
+
auth: auth ? auth.slice(0, Math.max(0, auth.length - 1)) : "",
|
|
152
|
+
host,
|
|
153
|
+
pathname,
|
|
154
|
+
search,
|
|
155
|
+
hash,
|
|
156
|
+
[protocolRelative]: !protocol
|
|
270
157
|
};
|
|
271
158
|
}
|
|
272
|
-
function
|
|
273
|
-
|
|
274
|
-
if (!isId(value.id)) throw authorityUnavailable();
|
|
159
|
+
function parsePath(input = "") {
|
|
160
|
+
const [pathname = "", search = "", hash = ""] = (input.match(/([^#?]*)(\?[^#]*)?(#.*)?/) || []).splice(1);
|
|
275
161
|
return {
|
|
276
|
-
|
|
277
|
-
|
|
162
|
+
pathname,
|
|
163
|
+
search,
|
|
164
|
+
hash
|
|
278
165
|
};
|
|
279
166
|
}
|
|
280
|
-
function
|
|
281
|
-
const
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
return { idempotencyKey };
|
|
288
|
-
}
|
|
289
|
-
function normalizeCanceledOrganizationInvitation(value) {
|
|
290
|
-
exact$3(value, ["status"]);
|
|
291
|
-
if (value.status !== "canceled") throw authorityUnavailable();
|
|
292
|
-
return { status: "canceled" };
|
|
293
|
-
}
|
|
294
|
-
function normalizeOrganizationMembershipRemovalInput(idempotencyKey) {
|
|
295
|
-
if (!boundedString(idempotencyKey, 255)) throw new AuthError("invalid_request", 400);
|
|
296
|
-
return { idempotencyKey };
|
|
167
|
+
function stringifyParsedURL(parsed) {
|
|
168
|
+
const pathname = parsed.pathname || "";
|
|
169
|
+
const search = parsed.search ? (parsed.search.startsWith("?") ? "" : "?") + parsed.search : "";
|
|
170
|
+
const hash = parsed.hash || "";
|
|
171
|
+
const auth = parsed.auth ? parsed.auth + "@" : "";
|
|
172
|
+
const host = parsed.host || "";
|
|
173
|
+
return (parsed.protocol || parsed[protocolRelative] ? (parsed.protocol || "") + "//" : "") + auth + host + pathname + search + hash;
|
|
297
174
|
}
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
175
|
+
//#endregion
|
|
176
|
+
//#region ../../node_modules/.pnpm/destr@2.0.5/node_modules/destr/dist/index.mjs
|
|
177
|
+
const suspectProtoRx = /"(?:_|\\u0{2}5[Ff]){2}(?:p|\\u0{2}70)(?:r|\\u0{2}72)(?:o|\\u0{2}6[Ff])(?:t|\\u0{2}74)(?:o|\\u0{2}6[Ff])(?:_|\\u0{2}5[Ff]){2}"\s*:/;
|
|
178
|
+
const suspectConstructorRx = /"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/;
|
|
179
|
+
const JsonSigRx = /^\s*["[{]|^\s*-?\d{1,16}(\.\d{1,17})?([Ee][+-]?\d+)?\s*$/;
|
|
180
|
+
function jsonParseTransform(key, value) {
|
|
181
|
+
if (key === "__proto__" || key === "constructor" && value && typeof value === "object" && "prototype" in value) {
|
|
182
|
+
warnKeyDropped(key);
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
return value;
|
|
302
186
|
}
|
|
303
|
-
function
|
|
304
|
-
|
|
305
|
-
if (value.status !== "left") throw authorityUnavailable();
|
|
306
|
-
return { status: "left" };
|
|
187
|
+
function warnKeyDropped(key) {
|
|
188
|
+
console.warn(`[destr] Dropping "${key}" key to prevent prototype pollution.`);
|
|
307
189
|
}
|
|
308
|
-
function
|
|
309
|
-
if (
|
|
310
|
-
return
|
|
190
|
+
function destr(value, options = {}) {
|
|
191
|
+
if (typeof value !== "string") return value;
|
|
192
|
+
if (value[0] === "\"" && value[value.length - 1] === "\"" && value.indexOf("\\") === -1) return value.slice(1, -1);
|
|
193
|
+
const _value = value.trim();
|
|
194
|
+
if (_value.length <= 9) switch (_value.toLowerCase()) {
|
|
195
|
+
case "true": return true;
|
|
196
|
+
case "false": return false;
|
|
197
|
+
case "undefined": return;
|
|
198
|
+
case "null": return null;
|
|
199
|
+
case "nan": return NaN;
|
|
200
|
+
case "infinity": return Number.POSITIVE_INFINITY;
|
|
201
|
+
case "-infinity": return Number.NEGATIVE_INFINITY;
|
|
202
|
+
}
|
|
203
|
+
if (!JsonSigRx.test(value)) {
|
|
204
|
+
if (options.strict) throw new SyntaxError("[destr] Invalid JSON");
|
|
205
|
+
return value;
|
|
206
|
+
}
|
|
207
|
+
try {
|
|
208
|
+
if (suspectProtoRx.test(value) || suspectConstructorRx.test(value)) {
|
|
209
|
+
if (options.strict) throw new Error("[destr] Possible prototype pollution");
|
|
210
|
+
return JSON.parse(value, jsonParseTransform);
|
|
211
|
+
}
|
|
212
|
+
return JSON.parse(value);
|
|
213
|
+
} catch (error) {
|
|
214
|
+
if (options.strict) throw error;
|
|
215
|
+
return value;
|
|
216
|
+
}
|
|
311
217
|
}
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
218
|
+
//#endregion
|
|
219
|
+
//#region ../../node_modules/.pnpm/ofetch@1.5.1/node_modules/ofetch/dist/shared/ofetch.CWycOUEr.mjs
|
|
220
|
+
var FetchError = class extends Error {
|
|
221
|
+
constructor(message, opts) {
|
|
222
|
+
super(message, opts);
|
|
223
|
+
this.name = "FetchError";
|
|
224
|
+
if (opts?.cause && !this.cause) this.cause = opts.cause;
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
function createFetchError(ctx) {
|
|
228
|
+
const errorMessage = ctx.error?.message || ctx.error?.toString() || "";
|
|
229
|
+
const method = ctx.request?.method || ctx.options?.method || "GET";
|
|
230
|
+
const url = ctx.request?.url || String(ctx.request) || "/";
|
|
231
|
+
const fetchError = new FetchError(`${`[${method}] ${JSON.stringify(url)}`}: ${ctx.response ? `${ctx.response.status} ${ctx.response.statusText}` : "<no response>"}${errorMessage ? ` ${errorMessage}` : ""}`, ctx.error ? { cause: ctx.error } : void 0);
|
|
232
|
+
for (const key of [
|
|
233
|
+
"request",
|
|
234
|
+
"options",
|
|
235
|
+
"response"
|
|
236
|
+
]) Object.defineProperty(fetchError, key, { get() {
|
|
237
|
+
return ctx[key];
|
|
238
|
+
} });
|
|
239
|
+
for (const [key, refKey] of [
|
|
240
|
+
["data", "_data"],
|
|
241
|
+
["status", "status"],
|
|
242
|
+
["statusCode", "status"],
|
|
243
|
+
["statusText", "statusText"],
|
|
244
|
+
["statusMessage", "statusText"]
|
|
245
|
+
]) Object.defineProperty(fetchError, key, { get() {
|
|
246
|
+
return ctx.response && ctx.response[refKey];
|
|
247
|
+
} });
|
|
248
|
+
return fetchError;
|
|
316
249
|
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
250
|
+
const payloadMethods = new Set(Object.freeze([
|
|
251
|
+
"PATCH",
|
|
252
|
+
"POST",
|
|
253
|
+
"PUT",
|
|
254
|
+
"DELETE"
|
|
255
|
+
]));
|
|
256
|
+
function isPayloadMethod(method = "GET") {
|
|
257
|
+
return payloadMethods.has(method.toUpperCase());
|
|
321
258
|
}
|
|
322
|
-
function
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
259
|
+
function isJSONSerializable(value) {
|
|
260
|
+
if (value === void 0) return false;
|
|
261
|
+
const t = typeof value;
|
|
262
|
+
if (t === "string" || t === "number" || t === "boolean" || t === null) return true;
|
|
263
|
+
if (t !== "object") return false;
|
|
264
|
+
if (Array.isArray(value)) return true;
|
|
265
|
+
if (value.buffer) return false;
|
|
266
|
+
if (value instanceof FormData || value instanceof URLSearchParams) return false;
|
|
267
|
+
return value.constructor && value.constructor.name === "Object" || typeof value.toJSON === "function";
|
|
326
268
|
}
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
269
|
+
const textTypes = new Set([
|
|
270
|
+
"image/svg",
|
|
271
|
+
"application/xml",
|
|
272
|
+
"application/xhtml",
|
|
273
|
+
"application/html"
|
|
274
|
+
]);
|
|
275
|
+
const JSON_RE = /^application\/(?:[\w!#$%&*.^`~-]*\+)?json(;.+)?$/i;
|
|
276
|
+
function detectResponseType(_contentType = "") {
|
|
277
|
+
if (!_contentType) return "json";
|
|
278
|
+
const contentType = _contentType.split(";").shift() || "";
|
|
279
|
+
if (JSON_RE.test(contentType)) return "json";
|
|
280
|
+
if (contentType === "text/event-stream") return "stream";
|
|
281
|
+
if (textTypes.has(contentType) || contentType.startsWith("text/")) return "text";
|
|
282
|
+
return "blob";
|
|
334
283
|
}
|
|
335
|
-
function
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
"image",
|
|
344
|
-
"joinedAt",
|
|
345
|
-
"name",
|
|
346
|
-
"owner",
|
|
347
|
-
"role",
|
|
348
|
-
"teamIds",
|
|
349
|
-
"userId"
|
|
350
|
-
]);
|
|
351
|
-
if (!isId(member.id) || !isId(member.userId) || !boundedString(member.name, 255) || typeof member.email !== "string" || member.email.length > 320 || !email.test(member.email) || !role(member.role) || typeof member.owner !== "boolean" || !Array.isArray(member.teamIds) || member.teamIds.length > 100) throw authorityUnavailable();
|
|
352
|
-
const teamIds = unique(member.teamIds.map((teamId) => normalizeResponseId(teamId)), (item) => item);
|
|
353
|
-
return {
|
|
354
|
-
id: member.id,
|
|
355
|
-
userId: member.userId,
|
|
356
|
-
name: member.name,
|
|
357
|
-
email: member.email,
|
|
358
|
-
image: nullableHttpsUrl(member.image),
|
|
359
|
-
role: member.role,
|
|
360
|
-
owner: member.owner,
|
|
361
|
-
joinedAt: responseDate(member.joinedAt),
|
|
362
|
-
teamIds
|
|
363
|
-
};
|
|
364
|
-
}), (item) => item.id),
|
|
365
|
-
nextCursor: nullableCursor(value.nextCursor)
|
|
284
|
+
function resolveFetchOptions(request, input, defaults, Headers) {
|
|
285
|
+
const headers = mergeHeaders(input?.headers ?? request?.headers, defaults?.headers, Headers);
|
|
286
|
+
let query;
|
|
287
|
+
if (defaults?.query || defaults?.params || input?.params || input?.query) query = {
|
|
288
|
+
...defaults?.params,
|
|
289
|
+
...defaults?.query,
|
|
290
|
+
...input?.params,
|
|
291
|
+
...input?.query
|
|
366
292
|
};
|
|
367
|
-
}
|
|
368
|
-
function normalizeOrganizationTeams(value) {
|
|
369
|
-
exact$3(value, ["nextCursor", "teams"]);
|
|
370
|
-
if (!Array.isArray(value.teams) || value.teams.length > 100) throw authorityUnavailable();
|
|
371
293
|
return {
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
"name"
|
|
378
|
-
]);
|
|
379
|
-
if (!isId(team.id) || !boundedString(team.name, 255) || team.category !== "manual" && team.category !== "managed") throw authorityUnavailable();
|
|
380
|
-
return {
|
|
381
|
-
id: team.id,
|
|
382
|
-
name: team.name,
|
|
383
|
-
category: team.category,
|
|
384
|
-
createdAt: responseDate(team.createdAt)
|
|
385
|
-
};
|
|
386
|
-
}), (item) => item.id),
|
|
387
|
-
nextCursor: nullableCursor(value.nextCursor)
|
|
294
|
+
...defaults,
|
|
295
|
+
...input,
|
|
296
|
+
query,
|
|
297
|
+
params: query,
|
|
298
|
+
headers
|
|
388
299
|
};
|
|
389
300
|
}
|
|
390
|
-
function
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
nextCursor: nullableCursor(value.nextCursor)
|
|
396
|
-
};
|
|
301
|
+
function mergeHeaders(input, defaults, Headers) {
|
|
302
|
+
if (!defaults) return new Headers(input);
|
|
303
|
+
const headers = new Headers(defaults);
|
|
304
|
+
if (input) for (const [key, value] of Symbol.iterator in input || Array.isArray(input) ? input : new Headers(input)) headers.set(key, value);
|
|
305
|
+
return headers;
|
|
397
306
|
}
|
|
398
|
-
function
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
"email",
|
|
402
|
-
"expiresAt",
|
|
403
|
-
"id",
|
|
404
|
-
"inviter",
|
|
405
|
-
"role",
|
|
406
|
-
"status",
|
|
407
|
-
"teamIds"
|
|
408
|
-
]);
|
|
409
|
-
if (!isId(value.id) || typeof value.email !== "string" || value.email.length > 320 || !email.test(value.email) || !role(value.role) || value.status !== "pending" || !Array.isArray(value.teamIds) || value.teamIds.length > 100 || !isObject$1(value.inviter)) throw authorityUnavailable();
|
|
410
|
-
exact$3(value.inviter, ["membershipId", "name"]);
|
|
411
|
-
if (!isId(value.inviter.membershipId) || !boundedString(value.inviter.name, 255)) throw authorityUnavailable();
|
|
412
|
-
return {
|
|
413
|
-
id: value.id,
|
|
414
|
-
email: value.email,
|
|
415
|
-
role: value.role,
|
|
416
|
-
teamIds: unique(value.teamIds.map(normalizeResponseId), (item) => item),
|
|
417
|
-
inviter: {
|
|
418
|
-
membershipId: value.inviter.membershipId,
|
|
419
|
-
name: value.inviter.name
|
|
420
|
-
},
|
|
421
|
-
createdAt: responseDate(value.createdAt),
|
|
422
|
-
expiresAt: responseDate(value.expiresAt),
|
|
423
|
-
status: "pending"
|
|
424
|
-
};
|
|
307
|
+
async function callHooks(context, hooks) {
|
|
308
|
+
if (hooks) if (Array.isArray(hooks)) for (const hook of hooks) await hook(context);
|
|
309
|
+
else await hooks(context);
|
|
425
310
|
}
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
311
|
+
const retryStatusCodes = new Set([
|
|
312
|
+
408,
|
|
313
|
+
409,
|
|
314
|
+
425,
|
|
315
|
+
429,
|
|
316
|
+
500,
|
|
317
|
+
502,
|
|
318
|
+
503,
|
|
319
|
+
504
|
|
320
|
+
]);
|
|
321
|
+
const nullBodyResponses = new Set([
|
|
322
|
+
101,
|
|
323
|
+
204,
|
|
324
|
+
205,
|
|
325
|
+
304
|
|
326
|
+
]);
|
|
327
|
+
function createFetch(globalOptions = {}) {
|
|
328
|
+
const { fetch = globalThis.fetch, Headers = globalThis.Headers, AbortController = globalThis.AbortController } = globalOptions;
|
|
329
|
+
async function onError(context) {
|
|
330
|
+
const isAbort = context.error && context.error.name === "AbortError" && !context.options.timeout || false;
|
|
331
|
+
if (context.options.retry !== false && !isAbort) {
|
|
332
|
+
let retries;
|
|
333
|
+
if (typeof context.options.retry === "number") retries = context.options.retry;
|
|
334
|
+
else retries = isPayloadMethod(context.options.method) ? 0 : 1;
|
|
335
|
+
const responseCode = context.response && context.response.status || 500;
|
|
336
|
+
if (retries > 0 && (Array.isArray(context.options.retryStatusCodes) ? context.options.retryStatusCodes.includes(responseCode) : retryStatusCodes.has(responseCode))) {
|
|
337
|
+
const retryDelay = typeof context.options.retryDelay === "function" ? context.options.retryDelay(context) : context.options.retryDelay || 0;
|
|
338
|
+
if (retryDelay > 0) await new Promise((resolve) => setTimeout(resolve, retryDelay));
|
|
339
|
+
return $fetchRaw(context.request, {
|
|
340
|
+
...context.options,
|
|
341
|
+
retry: retries - 1
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
const error = createFetchError(context);
|
|
346
|
+
if (Error.captureStackTrace) Error.captureStackTrace(error, $fetchRaw);
|
|
347
|
+
throw error;
|
|
348
|
+
}
|
|
349
|
+
const $fetchRaw = async function $fetchRaw2(_request, _options = {}) {
|
|
350
|
+
const context = {
|
|
351
|
+
request: _request,
|
|
352
|
+
options: resolveFetchOptions(_request, _options, globalOptions.defaults, Headers),
|
|
353
|
+
response: void 0,
|
|
354
|
+
error: void 0
|
|
355
|
+
};
|
|
356
|
+
if (context.options.method) context.options.method = context.options.method.toUpperCase();
|
|
357
|
+
if (context.options.onRequest) {
|
|
358
|
+
await callHooks(context, context.options.onRequest);
|
|
359
|
+
if (!(context.options.headers instanceof Headers)) context.options.headers = new Headers(context.options.headers || {});
|
|
360
|
+
}
|
|
361
|
+
if (typeof context.request === "string") {
|
|
362
|
+
if (context.options.baseURL) context.request = withBase(context.request, context.options.baseURL);
|
|
363
|
+
if (context.options.query) {
|
|
364
|
+
context.request = withQuery(context.request, context.options.query);
|
|
365
|
+
delete context.options.query;
|
|
366
|
+
}
|
|
367
|
+
if ("query" in context.options) delete context.options.query;
|
|
368
|
+
if ("params" in context.options) delete context.options.params;
|
|
369
|
+
}
|
|
370
|
+
if (context.options.body && isPayloadMethod(context.options.method)) {
|
|
371
|
+
if (isJSONSerializable(context.options.body)) {
|
|
372
|
+
const contentType = context.options.headers.get("content-type");
|
|
373
|
+
if (typeof context.options.body !== "string") context.options.body = contentType === "application/x-www-form-urlencoded" ? new URLSearchParams(context.options.body).toString() : JSON.stringify(context.options.body);
|
|
374
|
+
if (!contentType) context.options.headers.set("content-type", "application/json");
|
|
375
|
+
if (!context.options.headers.has("accept")) context.options.headers.set("accept", "application/json");
|
|
376
|
+
} else if ("pipeTo" in context.options.body && typeof context.options.body.pipeTo === "function" || typeof context.options.body.pipe === "function") {
|
|
377
|
+
if (!("duplex" in context.options)) context.options.duplex = "half";
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
let abortTimeout;
|
|
381
|
+
if (!context.options.signal && context.options.timeout) {
|
|
382
|
+
const controller = new AbortController();
|
|
383
|
+
abortTimeout = setTimeout(() => {
|
|
384
|
+
const error = new Error("[TimeoutError]: The operation was aborted due to timeout");
|
|
385
|
+
error.name = "TimeoutError";
|
|
386
|
+
error.code = 23;
|
|
387
|
+
controller.abort(error);
|
|
388
|
+
}, context.options.timeout);
|
|
389
|
+
context.options.signal = controller.signal;
|
|
390
|
+
}
|
|
391
|
+
try {
|
|
392
|
+
context.response = await fetch(context.request, context.options);
|
|
393
|
+
} catch (error) {
|
|
394
|
+
context.error = error;
|
|
395
|
+
if (context.options.onRequestError) await callHooks(context, context.options.onRequestError);
|
|
396
|
+
return await onError(context);
|
|
397
|
+
} finally {
|
|
398
|
+
if (abortTimeout) clearTimeout(abortTimeout);
|
|
399
|
+
}
|
|
400
|
+
if ((context.response.body || context.response._bodyInit) && !nullBodyResponses.has(context.response.status) && context.options.method !== "HEAD") {
|
|
401
|
+
const responseType = (context.options.parseResponse ? "json" : context.options.responseType) || detectResponseType(context.response.headers.get("content-type") || "");
|
|
402
|
+
switch (responseType) {
|
|
403
|
+
case "json": {
|
|
404
|
+
const data = await context.response.text();
|
|
405
|
+
const parseFunction = context.options.parseResponse || destr;
|
|
406
|
+
context.response._data = parseFunction(data);
|
|
407
|
+
break;
|
|
408
|
+
}
|
|
409
|
+
case "stream":
|
|
410
|
+
context.response._data = context.response.body || context.response._bodyInit;
|
|
411
|
+
break;
|
|
412
|
+
default: context.response._data = await context.response[responseType]();
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
if (context.options.onResponse) await callHooks(context, context.options.onResponse);
|
|
416
|
+
if (!context.options.ignoreResponseError && context.response.status >= 400 && context.response.status < 600) {
|
|
417
|
+
if (context.options.onResponseError) await callHooks(context, context.options.onResponseError);
|
|
418
|
+
return await onError(context);
|
|
419
|
+
}
|
|
420
|
+
return context.response;
|
|
421
|
+
};
|
|
422
|
+
const $fetch = async function $fetch2(request, options) {
|
|
423
|
+
return (await $fetchRaw(request, options))._data;
|
|
432
424
|
};
|
|
425
|
+
$fetch.raw = $fetchRaw;
|
|
426
|
+
$fetch.native = (...args) => fetch(...args);
|
|
427
|
+
$fetch.create = (defaultOptions = {}, customGlobalOptions = {}) => createFetch({
|
|
428
|
+
...globalOptions,
|
|
429
|
+
...customGlobalOptions,
|
|
430
|
+
defaults: {
|
|
431
|
+
...globalOptions.defaults,
|
|
432
|
+
...customGlobalOptions.defaults,
|
|
433
|
+
...defaultOptions
|
|
434
|
+
}
|
|
435
|
+
});
|
|
436
|
+
return $fetch;
|
|
433
437
|
}
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
438
|
+
//#endregion
|
|
439
|
+
//#region src/errors.ts
|
|
440
|
+
const messages = {
|
|
441
|
+
invalid_credentials: "The credentials are invalid.",
|
|
442
|
+
invalid_auth_input: "The authentication input is invalid.",
|
|
443
|
+
account_conflict: "The account is not available.",
|
|
444
|
+
social_signup_required: "No account is available for this social sign-in. Start sign-up to create one.",
|
|
445
|
+
google_recovery_in_progress: "A Google connection is already being completed. Return to that sign-in, or wait up to ten minutes and restart.",
|
|
446
|
+
google_recovery_not_required: "Google account recovery is not required.",
|
|
447
|
+
google_recovery_invalid: "The Google account recovery request is invalid.",
|
|
448
|
+
google_recovery_expired: "Google account recovery has expired. Start Google sign-in again.",
|
|
449
|
+
google_recovery_account_mismatch: "Sign in to the existing account associated with this Google identity.",
|
|
450
|
+
password_reset_invalid: "The password reset request is invalid.",
|
|
451
|
+
authentication_required: "Authentication is required.",
|
|
452
|
+
request_origin_denied: "The request origin is not allowed.",
|
|
453
|
+
invalid_request: "The request is invalid.",
|
|
454
|
+
invalid_invitation: "The invitation is invalid.",
|
|
455
|
+
invitation_unavailable: "The invitation is not available.",
|
|
456
|
+
recipient_unavailable: "The recipient is unavailable.",
|
|
457
|
+
invitation_recipient_mismatch: "The invitation cannot be accepted by this account.",
|
|
458
|
+
invitation_recovery_required: "Invitation administration requires separate recovery.",
|
|
459
|
+
membership_removal_recovery_required: "Membership removal requires separate recovery.",
|
|
460
|
+
email_verification_required: "Email verification is required.",
|
|
461
|
+
invalid_workspace_selection: "The workspace selection is invalid.",
|
|
462
|
+
organization_context_too_large: "The organization context is too large.",
|
|
463
|
+
credential_rate_limited: "Credential requests are temporarily limited.",
|
|
464
|
+
auth_request_rate_limited: "Authentication requests are temporarily limited.",
|
|
465
|
+
organization_slug_unavailable: "The organization address is unavailable.",
|
|
466
|
+
state_conflict: "The authentication state conflicts with the request.",
|
|
467
|
+
access_denied: "Access is denied.",
|
|
468
|
+
platform_target_unavailable: "The platform administration target is unavailable.",
|
|
469
|
+
platform_quorum_unavailable: "Platform administration quorum is unavailable.",
|
|
470
|
+
platform_recovery_required: "Platform administration requires separate recovery.",
|
|
471
|
+
identity_authority_unavailable: "Authentication is temporarily unavailable.",
|
|
472
|
+
two_factor_required: "A second authentication factor is required.",
|
|
473
|
+
two_factor_code_invalid: "The verification code is invalid.",
|
|
474
|
+
two_factor_challenge_expired: "The second-factor challenge has ended. Sign in again.",
|
|
475
|
+
two_factor_locked: "Second-factor verification is temporarily locked.",
|
|
476
|
+
recent_sign_in_required: "A recent sign-in is required.",
|
|
477
|
+
enterprise_recovery_required: "Enterprise administration evidence requires operator recovery.",
|
|
478
|
+
recent_authentication_required: "A ready recent-authentication action is required.",
|
|
479
|
+
organization_closure_confirmation_mismatch: "The confirmation does not match the organization.",
|
|
480
|
+
organization_closure_cancellation_ended: "The closure cancellation period has ended.",
|
|
481
|
+
ceremony_return_refused: "The return address is not registered for this application.",
|
|
482
|
+
password_sign_in_required: "A password sign-in method is required for this passkey change."
|
|
483
|
+
};
|
|
484
|
+
var AuthError = class extends Error {
|
|
485
|
+
code;
|
|
486
|
+
status;
|
|
487
|
+
retryAfterSeconds;
|
|
488
|
+
constructor(code, status, retryAfterSeconds) {
|
|
489
|
+
super(messages[code]);
|
|
490
|
+
this.name = "AuthError";
|
|
491
|
+
this.code = code;
|
|
492
|
+
this.status = status;
|
|
493
|
+
this.retryAfterSeconds = retryAfterSeconds;
|
|
494
|
+
}
|
|
495
|
+
};
|
|
496
|
+
//#endregion
|
|
497
|
+
//#region src/shared.ts
|
|
498
|
+
const DRIVE_CREDENTIAL_LIFETIME_SECONDS = 840;
|
|
499
|
+
const id$2 = /^[A-Za-z0-9_-]{1,128}$/;
|
|
500
|
+
const email = /^[^\s@]+@[^\s@]+$/;
|
|
501
|
+
const MAX_SOCIAL_ID_TOKEN_BYTES = 16 * 1024;
|
|
502
|
+
function normalizeEmail(value) {
|
|
503
|
+
if (typeof value !== "string") throw new TypeError("email is invalid");
|
|
504
|
+
const normalized = value.trim().toLowerCase();
|
|
505
|
+
if (normalized.length === 0 || normalized.length > 320 || !email.test(normalized)) throw new TypeError("email is invalid");
|
|
506
|
+
return normalized;
|
|
507
|
+
}
|
|
508
|
+
function normalizeSocialIdTokenInput(value) {
|
|
509
|
+
if (!isObject$1(value)) throw new TypeError("social ID token input is invalid");
|
|
510
|
+
const keys = Object.keys(value);
|
|
511
|
+
if (keys.length !== 3 && keys.length !== 4 || keys.some((key) => key !== "provider" && key !== "idToken" && key !== "nonce" && key !== "signUp") || value.provider !== "google" && value.provider !== "apple" || typeof value.signUp !== "boolean" || typeof value.idToken !== "string" || value.idToken.length < 1 || new TextEncoder().encode(value.idToken).byteLength > MAX_SOCIAL_ID_TOKEN_BYTES || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(value.idToken) || value.nonce !== void 0 && (typeof value.nonce !== "string" || value.nonce.length < 1 || value.nonce.length > 256 || !/^[\x20-\x7e]+$/.test(value.nonce))) throw new TypeError("social ID token input is invalid");
|
|
451
512
|
return {
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
slug: value.organization.slug,
|
|
457
|
-
logo: nullableHttpsUrl(value.organization.logo)
|
|
458
|
-
},
|
|
459
|
-
role: value.role,
|
|
460
|
-
teams: unique(value.teams.map((team) => {
|
|
461
|
-
exact$3(team, ["id", "name"]);
|
|
462
|
-
if (!isId(team.id) || !boundedString(team.name, 255)) throw authorityUnavailable();
|
|
463
|
-
return {
|
|
464
|
-
id: team.id,
|
|
465
|
-
name: team.name
|
|
466
|
-
};
|
|
467
|
-
}), (item) => item.id),
|
|
468
|
-
inviterName: value.inviterName,
|
|
469
|
-
expiresAt: responseDate(value.expiresAt)
|
|
513
|
+
provider: value.provider,
|
|
514
|
+
idToken: value.idToken,
|
|
515
|
+
...value.nonce === void 0 ? {} : { nonce: value.nonce },
|
|
516
|
+
signUp: value.signUp
|
|
470
517
|
};
|
|
471
518
|
}
|
|
472
|
-
function
|
|
473
|
-
exact$3(value, ["invitations", "nextCursor"]);
|
|
474
|
-
if (!Array.isArray(value.invitations) || value.invitations.length > 100) throw authorityUnavailable();
|
|
519
|
+
function socialIdTokenRequest(value) {
|
|
475
520
|
return {
|
|
476
|
-
|
|
477
|
-
|
|
521
|
+
provider: value.provider,
|
|
522
|
+
idToken: {
|
|
523
|
+
token: value.idToken,
|
|
524
|
+
...value.nonce === void 0 ? {} : { nonce: value.nonce }
|
|
525
|
+
},
|
|
526
|
+
requestSignUp: value.signUp
|
|
478
527
|
};
|
|
479
528
|
}
|
|
480
|
-
function
|
|
481
|
-
if (
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
529
|
+
function normalizeOrigin(value, name) {
|
|
530
|
+
if (value.length === 0 || value.length > 2048 || /[^\x20-\x7e]/.test(value)) throw new TypeError(`${name} must be an ASCII HTTP origin`);
|
|
531
|
+
let url;
|
|
532
|
+
try {
|
|
533
|
+
url = new URL(value);
|
|
534
|
+
} catch {
|
|
535
|
+
throw new TypeError(`${name} must be an ASCII HTTP origin`);
|
|
536
|
+
}
|
|
537
|
+
const local = url.hostname === "localhost" || url.hostname.endsWith(".localhost") || url.hostname === "127.0.0.1";
|
|
538
|
+
if (url.protocol !== "https:" && !(local && url.protocol === "http:") || url.username || url.password || url.pathname !== "/" || url.search || url.hash || url.origin !== value) throw new TypeError(`${name} must be an ASCII HTTP origin`);
|
|
539
|
+
return url.origin;
|
|
487
540
|
}
|
|
488
|
-
function
|
|
489
|
-
|
|
490
|
-
|
|
541
|
+
function normalizeTimeout(value) {
|
|
542
|
+
const timeout = value ?? 1e4;
|
|
543
|
+
if (!Number.isSafeInteger(timeout) || timeout < 1 || timeout > 6e4) throw new TypeError("timeoutMs must be an integer from 1 to 60000");
|
|
544
|
+
return timeout;
|
|
491
545
|
}
|
|
492
|
-
function
|
|
493
|
-
if (
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
546
|
+
function normalizeSession(value) {
|
|
547
|
+
if (value === null) return null;
|
|
548
|
+
if (!isObject$1(value) || !isObject$1(value.session) || !isObject$1(value.user)) throw authorityUnavailable();
|
|
549
|
+
const expiresAt = toDate(value.session.expiresAt);
|
|
550
|
+
const image = value.user.image;
|
|
551
|
+
if (!isId(value.session.id) || !expiresAt || !isId(value.user.id) || typeof value.user.name !== "string" || value.user.name.length > 256 || typeof value.user.email !== "string" || value.user.email.length > 320 || !email.test(value.user.email) || typeof value.user.emailVerified !== "boolean" || image !== null && image !== void 0 && (typeof image !== "string" || image.length > 2048)) throw authorityUnavailable();
|
|
552
|
+
return {
|
|
553
|
+
id: value.session.id,
|
|
554
|
+
expiresAt,
|
|
555
|
+
user: {
|
|
556
|
+
id: value.user.id,
|
|
557
|
+
name: value.user.name,
|
|
558
|
+
email: value.user.email,
|
|
559
|
+
emailVerified: value.user.emailVerified,
|
|
560
|
+
image: image ?? null
|
|
561
|
+
}
|
|
499
562
|
};
|
|
500
|
-
throw new AuthError("invalid_workspace_selection", 422);
|
|
501
|
-
}
|
|
502
|
-
function fromAuthorityError(value, fallbackStatus, retryAfter) {
|
|
503
|
-
const mapped = mapError(isObject$1(value) && typeof value.code === "string" ? value.code : void 0, fallbackStatus);
|
|
504
|
-
return new AuthError(mapped.code, mapped.status, parseRetryAfter(retryAfter));
|
|
505
563
|
}
|
|
506
|
-
function
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
if (status === 401) return new AuthError("authentication_required", 401);
|
|
514
|
-
if (status === 403) return new AuthError("access_denied", 403);
|
|
515
|
-
if (status === 409) return new AuthError("state_conflict", 409);
|
|
516
|
-
if (status === 429) return new AuthError("auth_request_rate_limited", 429, parseRetryAfter(retryAfter));
|
|
517
|
-
if (status === 400 || status === 422) return new AuthError("invalid_auth_input", 422);
|
|
518
|
-
return authorityUnavailable();
|
|
564
|
+
function normalizeDriveCredential(value, now) {
|
|
565
|
+
if (!isObject$1(value) || value.tokenType !== "Bearer" || value.expiresIn !== DRIVE_CREDENTIAL_LIFETIME_SECONDS || typeof value.token !== "string" || value.token.length === 0 || new TextEncoder().encode(`Bearer ${value.token}`).byteLength > 16 * 1024) throw authorityUnavailable();
|
|
566
|
+
return {
|
|
567
|
+
tokenType: "Bearer",
|
|
568
|
+
token: value.token,
|
|
569
|
+
expiresAt: new Date(now + value.expiresIn * 1e3)
|
|
570
|
+
};
|
|
519
571
|
}
|
|
520
|
-
function
|
|
521
|
-
|
|
522
|
-
if (
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
if (
|
|
527
|
-
|
|
572
|
+
function normalizeOrganizationPageInput(value) {
|
|
573
|
+
if (value === void 0) return new URLSearchParams();
|
|
574
|
+
if (!isObject$1(value) || Object.keys(value).some((key) => key !== "limit" && key !== "cursor")) throw new AuthError("invalid_request", 400);
|
|
575
|
+
const input = value;
|
|
576
|
+
const query = new URLSearchParams();
|
|
577
|
+
if (input.limit !== void 0) {
|
|
578
|
+
if (!Number.isSafeInteger(input.limit) || input.limit < 1 || input.limit > 100) throw new AuthError("invalid_request", 400);
|
|
579
|
+
query.set("limit", String(input.limit));
|
|
528
580
|
}
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
function fromOrganizationListError(error) {
|
|
535
|
-
if (error instanceof AuthError && error.status === 401) return new AuthError("authentication_required", 401);
|
|
536
|
-
if (error instanceof AuthError) return error;
|
|
537
|
-
return authorityUnavailable();
|
|
538
|
-
}
|
|
539
|
-
function fromOrganizationReadAuthorityError(value, status) {
|
|
540
|
-
if (status === 400) return new AuthError("invalid_request", 400);
|
|
541
|
-
if (status === 401) return new AuthError("authentication_required", 401);
|
|
542
|
-
if (status === 403) return new AuthError("access_denied", 403);
|
|
543
|
-
return authorityUnavailable();
|
|
544
|
-
}
|
|
545
|
-
function fromOrganizationMutationAuthorityError(value, status, retryAfter) {
|
|
546
|
-
if (status === 400 || status === 413 || status === 415) return new AuthError("invalid_request", 400);
|
|
547
|
-
if (status === 409 && isObject$1(value) && value.code === "ORGANIZATION_SLUG_UNAVAILABLE") return new AuthError("organization_slug_unavailable", 409);
|
|
548
|
-
if (status === 409) return new AuthError("state_conflict", 409);
|
|
549
|
-
if (status === 429) return new AuthError("auth_request_rate_limited", 429, parseRetryAfter(retryAfter));
|
|
550
|
-
const code = isObject$1(value) && typeof value.code === "string" ? value.code : void 0;
|
|
551
|
-
if (status === 403 && code === "REQUEST_ORIGIN_DENIED") return new AuthError("request_origin_denied", 403);
|
|
552
|
-
return fromOrganizationReadAuthorityError(value, status);
|
|
581
|
+
if (input.cursor !== void 0) {
|
|
582
|
+
if (typeof input.cursor !== "string" || input.cursor.length < 1 || input.cursor.length > 820 || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(input.cursor)) throw new AuthError("invalid_request", 400);
|
|
583
|
+
query.set("cursor", input.cursor);
|
|
584
|
+
}
|
|
585
|
+
return query;
|
|
553
586
|
}
|
|
554
|
-
function
|
|
555
|
-
if (
|
|
556
|
-
|
|
587
|
+
function normalizeOrganizationMemberPageInput(value) {
|
|
588
|
+
if (value === void 0) return new URLSearchParams();
|
|
589
|
+
if (!isObject$1(value) || Object.keys(value).some((key) => ![
|
|
590
|
+
"limit",
|
|
591
|
+
"cursor",
|
|
592
|
+
"search"
|
|
593
|
+
].includes(key))) throw new AuthError("invalid_request", 400);
|
|
594
|
+
const { search, ...page } = value;
|
|
595
|
+
const query = normalizeOrganizationPageInput(page);
|
|
596
|
+
if (search !== void 0) {
|
|
597
|
+
if (typeof search !== "string") throw new AuthError("invalid_request", 400);
|
|
598
|
+
const prefix = search.trim().replace(/[A-Z]/g, (character) => character.toLowerCase());
|
|
599
|
+
if (!prefix || prefix.length > 128 || Array.from(prefix).some((character) => character.charCodeAt(0) < 32 || character.charCodeAt(0) === 127)) throw new AuthError("invalid_request", 400);
|
|
600
|
+
query.set("search", prefix);
|
|
601
|
+
}
|
|
602
|
+
return query;
|
|
557
603
|
}
|
|
558
|
-
function
|
|
559
|
-
if (
|
|
560
|
-
return
|
|
604
|
+
function normalizeIdInput(value) {
|
|
605
|
+
if (!isId(value)) throw new AuthError("invalid_request", 400);
|
|
606
|
+
return value;
|
|
561
607
|
}
|
|
562
|
-
function
|
|
563
|
-
exact$
|
|
564
|
-
"
|
|
565
|
-
"
|
|
566
|
-
"
|
|
608
|
+
function normalizeOrganization(value) {
|
|
609
|
+
exact$5(value, [
|
|
610
|
+
"capabilities",
|
|
611
|
+
"id",
|
|
612
|
+
"lifecycle",
|
|
613
|
+
"logo",
|
|
614
|
+
"name",
|
|
615
|
+
"role",
|
|
616
|
+
"slug"
|
|
567
617
|
]);
|
|
568
|
-
if (!isId(value.
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
618
|
+
if (!isId(value.id) || !boundedString(value.name, 255) || !boundedString(value.slug, 255) || value.lifecycle !== "ordinary" && value.lifecycle !== "managed" || !role(value.role) || !isObject$1(value.capabilities)) throw authorityUnavailable();
|
|
619
|
+
exact$5(value.capabilities, [
|
|
620
|
+
"readInvitations",
|
|
621
|
+
"readMembers",
|
|
622
|
+
"readTeams"
|
|
623
|
+
]);
|
|
624
|
+
if (value.capabilities.readMembers !== true || value.capabilities.readTeams !== true || typeof value.capabilities.readInvitations !== "boolean") throw authorityUnavailable();
|
|
574
625
|
return {
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
626
|
+
id: value.id,
|
|
627
|
+
name: value.name,
|
|
628
|
+
slug: value.slug,
|
|
629
|
+
logo: nullableHttpsUrl(value.logo),
|
|
630
|
+
lifecycle: value.lifecycle,
|
|
631
|
+
role: value.role,
|
|
632
|
+
capabilities: {
|
|
633
|
+
readMembers: true,
|
|
634
|
+
readTeams: true,
|
|
635
|
+
readInvitations: value.capabilities.readInvitations
|
|
636
|
+
}
|
|
578
637
|
};
|
|
579
638
|
}
|
|
580
|
-
function
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
639
|
+
function normalizeOrganizationDisplayInput(value) {
|
|
640
|
+
if (!isObject$1(value) || Object.keys(value).sort().join(",") !== "logo,name,slug") throw new AuthError("invalid_request", 400);
|
|
641
|
+
if (!boundedString(value.name, 255) || !boundedString(value.slug, 255)) throw new AuthError("invalid_request", 400);
|
|
642
|
+
let logo;
|
|
643
|
+
try {
|
|
644
|
+
logo = nullableHttpsUrl(value.logo);
|
|
645
|
+
} catch {
|
|
646
|
+
throw new AuthError("invalid_request", 400);
|
|
647
|
+
}
|
|
589
648
|
return {
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
authorityRevision: normalizeAuthorityResultRevision(value.authorityRevision)
|
|
649
|
+
name: value.name,
|
|
650
|
+
slug: value.slug,
|
|
651
|
+
logo
|
|
594
652
|
};
|
|
595
653
|
}
|
|
596
|
-
function
|
|
597
|
-
|
|
598
|
-
|
|
654
|
+
function normalizeOrganizationDisplay(value) {
|
|
655
|
+
try {
|
|
656
|
+
return normalizeOrganizationDisplayInput(value);
|
|
657
|
+
} catch {
|
|
658
|
+
throw authorityUnavailable();
|
|
659
|
+
}
|
|
599
660
|
}
|
|
600
|
-
function
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
if (status === 403 && (code === "INVALID_ORIGIN" || code === "MISSING_OR_NULL_ORIGIN")) return new AuthError("request_origin_denied", 403);
|
|
604
|
-
if (status === 403 && code === "YOU_ARE_NOT_THE_RECIPIENT_OF_THE_INVITATION") return new AuthError("invitation_recipient_mismatch", 403);
|
|
605
|
-
if (status === 403 && code === "EMAIL_VERIFICATION_REQUIRED_BEFORE_ACCEPTING_OR_REJECTING_INVITATION") return new AuthError("email_verification_required", 403);
|
|
606
|
-
if (status === 400 && (code === "INVITATION_NOT_FOUND" || code === "ORGANIZATION_NOT_FOUND" || code === "TEAM_NOT_FOUND")) return new AuthError("invitation_unavailable", 409);
|
|
607
|
-
return authorityUnavailable();
|
|
661
|
+
function normalizeOrganizationTeamDisplayInput(value) {
|
|
662
|
+
if (!isObject$1(value) || Object.keys(value).join(",") !== "name" || !boundedString(value.name, 255)) throw new AuthError("invalid_request", 400);
|
|
663
|
+
return { name: value.name };
|
|
608
664
|
}
|
|
609
|
-
function
|
|
610
|
-
|
|
665
|
+
function normalizeOrganizationTeamDisplay(value) {
|
|
666
|
+
try {
|
|
667
|
+
return normalizeOrganizationTeamDisplayInput(value);
|
|
668
|
+
} catch {
|
|
669
|
+
throw authorityUnavailable();
|
|
670
|
+
}
|
|
611
671
|
}
|
|
612
|
-
function
|
|
613
|
-
if (
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
code,
|
|
619
|
-
status: 403
|
|
620
|
-
};
|
|
621
|
-
if (code === "invalid_workspace_selection") return {
|
|
622
|
-
code,
|
|
623
|
-
status: 422
|
|
624
|
-
};
|
|
625
|
-
if (code === "organization_context_too_large") return {
|
|
626
|
-
code,
|
|
627
|
-
status: 422
|
|
628
|
-
};
|
|
629
|
-
if (code === "credential_rate_limited") return {
|
|
630
|
-
code,
|
|
631
|
-
status: 429
|
|
632
|
-
};
|
|
633
|
-
if (code === "identity_authority_unavailable") return {
|
|
634
|
-
code,
|
|
635
|
-
status: 503
|
|
636
|
-
};
|
|
637
|
-
if (status === 401 || status === 400) return {
|
|
638
|
-
code: "invalid_credentials",
|
|
639
|
-
status: 401
|
|
640
|
-
};
|
|
641
|
-
if (status === 403) return {
|
|
642
|
-
code: "access_denied",
|
|
643
|
-
status: 403
|
|
644
|
-
};
|
|
645
|
-
if (status === 409) return {
|
|
646
|
-
code: "state_conflict",
|
|
647
|
-
status: 409
|
|
648
|
-
};
|
|
649
|
-
if (status === 422) return {
|
|
650
|
-
code: "invalid_workspace_selection",
|
|
651
|
-
status: 422
|
|
672
|
+
function normalizeOrganizationCreationInput(name, slug, idempotencyKey) {
|
|
673
|
+
if (!boundedString(name, 255) || !boundedString(idempotencyKey, 255) || typeof slug !== "string" || !/^[a-z0-9-]{1,128}$/.test(slug)) throw new AuthError("invalid_request", 400);
|
|
674
|
+
return {
|
|
675
|
+
name,
|
|
676
|
+
slug,
|
|
677
|
+
idempotencyKey
|
|
652
678
|
};
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
679
|
+
}
|
|
680
|
+
function normalizeCreatedOrganization(value) {
|
|
681
|
+
exact$5(value, [
|
|
682
|
+
"id",
|
|
683
|
+
"name",
|
|
684
|
+
"slug"
|
|
685
|
+
]);
|
|
686
|
+
if (!isId(value.id) || !boundedString(value.name, 255) || !boundedString(value.slug, 128)) throw authorityUnavailable();
|
|
687
|
+
return {
|
|
688
|
+
id: value.id,
|
|
689
|
+
name: value.name,
|
|
690
|
+
slug: value.slug
|
|
656
691
|
};
|
|
692
|
+
}
|
|
693
|
+
function normalizeOrganizationTeamCreationInput(name, idempotencyKey) {
|
|
694
|
+
if (!boundedString(name, 255) || !boundedString(idempotencyKey, 255)) throw new AuthError("invalid_request", 400);
|
|
657
695
|
return {
|
|
658
|
-
|
|
659
|
-
|
|
696
|
+
name,
|
|
697
|
+
idempotencyKey
|
|
660
698
|
};
|
|
661
699
|
}
|
|
662
|
-
function
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
return
|
|
700
|
+
function normalizeCreatedOrganizationTeam(value) {
|
|
701
|
+
exact$5(value, ["id", "name"]);
|
|
702
|
+
if (!isId(value.id) || !boundedString(value.name, 255)) throw authorityUnavailable();
|
|
703
|
+
return {
|
|
704
|
+
id: value.id,
|
|
705
|
+
name: value.name
|
|
706
|
+
};
|
|
666
707
|
}
|
|
667
|
-
function
|
|
668
|
-
|
|
669
|
-
|
|
708
|
+
function normalizeOrganizationMemberInvitationCreationInput(value) {
|
|
709
|
+
if (!isObject$1(value)) throw new AuthError("invalid_request", 400);
|
|
710
|
+
const keys = Object.keys(value).sort().join(",");
|
|
711
|
+
if (keys !== "email,idempotencyKey" && keys !== "email,idempotencyKey,teamIds") throw new AuthError("invalid_request", 400);
|
|
712
|
+
let normalizedEmail;
|
|
713
|
+
try {
|
|
714
|
+
normalizedEmail = normalizeEmail(value.email);
|
|
715
|
+
} catch {
|
|
716
|
+
throw new AuthError("invalid_request", 400);
|
|
717
|
+
}
|
|
718
|
+
if (new TextEncoder().encode(normalizedEmail).byteLength > 320 || !boundedString(value.idempotencyKey, 255) || value.teamIds !== void 0 && (!Array.isArray(value.teamIds) || value.teamIds.length > 100)) throw new AuthError("invalid_request", 400);
|
|
719
|
+
const teamIds = value.teamIds?.map((teamId) => normalizeIdInput(teamId));
|
|
720
|
+
if (teamIds && new Set(teamIds).size !== teamIds.length) throw new AuthError("invalid_request", 400);
|
|
721
|
+
return {
|
|
722
|
+
email: normalizedEmail,
|
|
723
|
+
...teamIds === void 0 ? {} : { teamIds },
|
|
724
|
+
idempotencyKey: value.idempotencyKey
|
|
725
|
+
};
|
|
670
726
|
}
|
|
671
|
-
function
|
|
672
|
-
|
|
727
|
+
function normalizeCreatedOrganizationMemberInvitation(value) {
|
|
728
|
+
exact$5(value, ["expiresAt", "id"]);
|
|
729
|
+
if (!isId(value.id)) throw authorityUnavailable();
|
|
730
|
+
return {
|
|
731
|
+
id: value.id,
|
|
732
|
+
expiresAt: responseDate(value.expiresAt)
|
|
733
|
+
};
|
|
673
734
|
}
|
|
674
|
-
function
|
|
675
|
-
|
|
735
|
+
function normalizeResentOrganizationInvitation(value, invitationId) {
|
|
736
|
+
const invitation = normalizeCreatedOrganizationMemberInvitation(value);
|
|
737
|
+
if (invitation.id !== invitationId) throw authorityUnavailable();
|
|
738
|
+
return invitation;
|
|
676
739
|
}
|
|
677
|
-
function
|
|
678
|
-
|
|
740
|
+
function normalizeOrganizationInvitationAdministrationInput(idempotencyKey) {
|
|
741
|
+
if (!boundedString(idempotencyKey, 255)) throw new AuthError("invalid_request", 400);
|
|
742
|
+
return { idempotencyKey };
|
|
679
743
|
}
|
|
680
|
-
function
|
|
681
|
-
|
|
744
|
+
function normalizeCanceledOrganizationInvitation(value) {
|
|
745
|
+
exact$5(value, ["status"]);
|
|
746
|
+
if (value.status !== "canceled") throw authorityUnavailable();
|
|
747
|
+
return { status: "canceled" };
|
|
682
748
|
}
|
|
683
|
-
function
|
|
684
|
-
if (
|
|
685
|
-
|
|
686
|
-
let url;
|
|
687
|
-
try {
|
|
688
|
-
url = new URL(value);
|
|
689
|
-
} catch {
|
|
690
|
-
throw authorityUnavailable();
|
|
691
|
-
}
|
|
692
|
-
if (url.protocol !== "https:" || url.username || url.password || url.toString() !== value) throw authorityUnavailable();
|
|
693
|
-
return value;
|
|
749
|
+
function normalizeOrganizationMembershipRemovalInput(idempotencyKey) {
|
|
750
|
+
if (!boundedString(idempotencyKey, 255)) throw new AuthError("invalid_request", 400);
|
|
751
|
+
return { idempotencyKey };
|
|
694
752
|
}
|
|
695
|
-
function
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
return date;
|
|
753
|
+
function normalizeRemovedOrganizationMember(value) {
|
|
754
|
+
exact$5(value, ["status"]);
|
|
755
|
+
if (value.status !== "removed") throw authorityUnavailable();
|
|
756
|
+
return { status: "removed" };
|
|
700
757
|
}
|
|
701
|
-
function
|
|
702
|
-
|
|
703
|
-
if (
|
|
704
|
-
return
|
|
758
|
+
function normalizeOrganizationDeparture(value) {
|
|
759
|
+
exact$5(value, ["status"]);
|
|
760
|
+
if (value.status !== "left") throw authorityUnavailable();
|
|
761
|
+
return { status: "left" };
|
|
705
762
|
}
|
|
706
|
-
function
|
|
707
|
-
if (!
|
|
708
|
-
return
|
|
763
|
+
function normalizeOrganizationTeamMembershipInput(idempotencyKey) {
|
|
764
|
+
if (!boundedString(idempotencyKey, 255)) throw new AuthError("invalid_request", 400);
|
|
765
|
+
return { idempotencyKey };
|
|
709
766
|
}
|
|
710
|
-
function
|
|
711
|
-
|
|
712
|
-
|
|
767
|
+
function normalizeAddedOrganizationTeamMember(value) {
|
|
768
|
+
exact$5(value, ["status"]);
|
|
769
|
+
if (value.status !== "added") throw authorityUnavailable();
|
|
770
|
+
return { status: "added" };
|
|
713
771
|
}
|
|
714
|
-
function
|
|
715
|
-
|
|
772
|
+
function normalizeRemovedOrganizationTeamMember(value) {
|
|
773
|
+
exact$5(value, ["status"]);
|
|
774
|
+
if (value.status !== "removed") throw authorityUnavailable();
|
|
775
|
+
return { status: "removed" };
|
|
716
776
|
}
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
return
|
|
777
|
+
function normalizeDeletedOrganizationTeam(value) {
|
|
778
|
+
exact$5(value, ["status"]);
|
|
779
|
+
if (value.status !== "deleted") throw authorityUnavailable();
|
|
780
|
+
return { status: "deleted" };
|
|
721
781
|
}
|
|
722
|
-
function
|
|
723
|
-
|
|
782
|
+
function normalizeOrganizations(value) {
|
|
783
|
+
exact$5(value, ["nextCursor", "organizations"]);
|
|
784
|
+
if (!Array.isArray(value.organizations) || value.organizations.length > 100) throw authorityUnavailable();
|
|
785
|
+
return {
|
|
786
|
+
organizations: unique(value.organizations.map(normalizeOrganization), (item) => item.id),
|
|
787
|
+
nextCursor: nullableCursor(value.nextCursor)
|
|
788
|
+
};
|
|
724
789
|
}
|
|
725
|
-
function
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
provider: "google",
|
|
729
|
-
idToken: value.idToken.token,
|
|
730
|
-
signUp: false,
|
|
731
|
-
...value.idToken.nonce === void 0 ? {} : { nonce: value.idToken.nonce }
|
|
732
|
-
});
|
|
790
|
+
function normalizeOrganizationMembers(value) {
|
|
791
|
+
exact$5(value, ["members", "nextCursor"]);
|
|
792
|
+
if (!Array.isArray(value.members) || value.members.length > 100) throw authorityUnavailable();
|
|
733
793
|
return {
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
794
|
+
members: unique(value.members.map((member) => {
|
|
795
|
+
exact$5(member, [
|
|
796
|
+
"email",
|
|
797
|
+
"id",
|
|
798
|
+
"image",
|
|
799
|
+
"joinedAt",
|
|
800
|
+
"name",
|
|
801
|
+
"owner",
|
|
802
|
+
"role",
|
|
803
|
+
"teamIds",
|
|
804
|
+
"userId"
|
|
805
|
+
]);
|
|
806
|
+
if (!isId(member.id) || !isId(member.userId) || !boundedString(member.name, 255) || typeof member.email !== "string" || member.email.length > 320 || !email.test(member.email) || !role(member.role) || typeof member.owner !== "boolean" || !Array.isArray(member.teamIds) || member.teamIds.length > 100) throw authorityUnavailable();
|
|
807
|
+
const teamIds = unique(member.teamIds.map((teamId) => normalizeResponseId(teamId)), (item) => item);
|
|
808
|
+
return {
|
|
809
|
+
id: member.id,
|
|
810
|
+
userId: member.userId,
|
|
811
|
+
name: member.name,
|
|
812
|
+
email: member.email,
|
|
813
|
+
image: nullableHttpsUrl(member.image),
|
|
814
|
+
role: member.role,
|
|
815
|
+
owner: member.owner,
|
|
816
|
+
joinedAt: responseDate(member.joinedAt),
|
|
817
|
+
teamIds
|
|
818
|
+
};
|
|
819
|
+
}), (item) => item.id),
|
|
820
|
+
nextCursor: nullableCursor(value.nextCursor)
|
|
821
|
+
};
|
|
822
|
+
}
|
|
823
|
+
function normalizeOrganizationTeams(value) {
|
|
824
|
+
exact$5(value, ["nextCursor", "teams"]);
|
|
825
|
+
if (!Array.isArray(value.teams) || value.teams.length > 100) throw authorityUnavailable();
|
|
826
|
+
return {
|
|
827
|
+
teams: unique(value.teams.map((team) => {
|
|
828
|
+
exact$5(team, [
|
|
829
|
+
"category",
|
|
830
|
+
"createdAt",
|
|
831
|
+
"id",
|
|
832
|
+
"name"
|
|
833
|
+
]);
|
|
834
|
+
if (!isId(team.id) || !boundedString(team.name, 255) || team.category !== "manual" && team.category !== "managed") throw authorityUnavailable();
|
|
835
|
+
return {
|
|
836
|
+
id: team.id,
|
|
837
|
+
name: team.name,
|
|
838
|
+
category: team.category,
|
|
839
|
+
createdAt: responseDate(team.createdAt)
|
|
840
|
+
};
|
|
841
|
+
}), (item) => item.id),
|
|
842
|
+
nextCursor: nullableCursor(value.nextCursor)
|
|
843
|
+
};
|
|
844
|
+
}
|
|
845
|
+
function normalizeOrganizationTeamMembers(value) {
|
|
846
|
+
exact$5(value, ["memberIds", "nextCursor"]);
|
|
847
|
+
if (!Array.isArray(value.memberIds) || value.memberIds.length > 100) throw authorityUnavailable();
|
|
848
|
+
return {
|
|
849
|
+
memberIds: unique(value.memberIds.map((item) => normalizeResponseId(item)), (item) => item),
|
|
850
|
+
nextCursor: nullableCursor(value.nextCursor)
|
|
851
|
+
};
|
|
852
|
+
}
|
|
853
|
+
function normalizeOrganizationInvitation(value) {
|
|
854
|
+
exact$5(value, [
|
|
855
|
+
"createdAt",
|
|
856
|
+
"email",
|
|
857
|
+
"expiresAt",
|
|
858
|
+
"id",
|
|
859
|
+
"inviter",
|
|
860
|
+
"role",
|
|
861
|
+
"status",
|
|
862
|
+
"teamIds"
|
|
863
|
+
]);
|
|
864
|
+
if (!isId(value.id) || typeof value.email !== "string" || value.email.length > 320 || !email.test(value.email) || !role(value.role) || value.status !== "pending" || !Array.isArray(value.teamIds) || value.teamIds.length > 100 || !isObject$1(value.inviter)) throw authorityUnavailable();
|
|
865
|
+
exact$5(value.inviter, ["membershipId", "name"]);
|
|
866
|
+
if (!isId(value.inviter.membershipId) || !boundedString(value.inviter.name, 255)) throw authorityUnavailable();
|
|
867
|
+
return {
|
|
868
|
+
id: value.id,
|
|
869
|
+
email: value.email,
|
|
870
|
+
role: value.role,
|
|
871
|
+
teamIds: unique(value.teamIds.map(normalizeResponseId), (item) => item),
|
|
872
|
+
inviter: {
|
|
873
|
+
membershipId: value.inviter.membershipId,
|
|
874
|
+
name: value.inviter.name
|
|
737
875
|
},
|
|
738
|
-
|
|
876
|
+
createdAt: responseDate(value.createdAt),
|
|
877
|
+
expiresAt: responseDate(value.expiresAt),
|
|
878
|
+
status: "pending"
|
|
739
879
|
};
|
|
740
880
|
}
|
|
741
|
-
function
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
if (!Number.isFinite(expiresAt) || expiresAt <= now || expiresAt > now + 10 * 6e4) throw authorityUnavailable();
|
|
881
|
+
function normalizeOrganizationInvitations(value) {
|
|
882
|
+
exact$5(value, ["invitations", "nextCursor"]);
|
|
883
|
+
if (!Array.isArray(value.invitations) || value.invitations.length > 100) throw authorityUnavailable();
|
|
745
884
|
return {
|
|
746
|
-
|
|
747
|
-
|
|
885
|
+
invitations: unique(value.invitations.map(normalizeOrganizationInvitation), (item) => item.id),
|
|
886
|
+
nextCursor: nullableCursor(value.nextCursor)
|
|
748
887
|
};
|
|
749
888
|
}
|
|
750
|
-
function
|
|
751
|
-
|
|
752
|
-
|
|
889
|
+
function normalizeReceivedInvitation(value) {
|
|
890
|
+
exact$5(value, [
|
|
891
|
+
"expiresAt",
|
|
892
|
+
"id",
|
|
893
|
+
"inviterName",
|
|
894
|
+
"organization",
|
|
895
|
+
"role",
|
|
896
|
+
"teams"
|
|
897
|
+
]);
|
|
898
|
+
if (!isId(value.id) || !boundedString(value.inviterName, 255) || !role(value.role) || !Array.isArray(value.teams) || value.teams.length > 100 || !isObject$1(value.organization)) throw authorityUnavailable();
|
|
899
|
+
exact$5(value.organization, [
|
|
900
|
+
"id",
|
|
901
|
+
"logo",
|
|
902
|
+
"name",
|
|
903
|
+
"slug"
|
|
904
|
+
]);
|
|
905
|
+
if (!isId(value.organization.id) || !boundedString(value.organization.name, 255) || !boundedString(value.organization.slug, 255)) throw authorityUnavailable();
|
|
906
|
+
return {
|
|
907
|
+
id: value.id,
|
|
908
|
+
organization: {
|
|
909
|
+
id: value.organization.id,
|
|
910
|
+
name: value.organization.name,
|
|
911
|
+
slug: value.organization.slug,
|
|
912
|
+
logo: nullableHttpsUrl(value.organization.logo)
|
|
913
|
+
},
|
|
914
|
+
role: value.role,
|
|
915
|
+
teams: unique(value.teams.map((team) => {
|
|
916
|
+
exact$5(team, ["id", "name"]);
|
|
917
|
+
if (!isId(team.id) || !boundedString(team.name, 255)) throw authorityUnavailable();
|
|
918
|
+
return {
|
|
919
|
+
id: team.id,
|
|
920
|
+
name: team.name
|
|
921
|
+
};
|
|
922
|
+
}), (item) => item.id),
|
|
923
|
+
inviterName: value.inviterName,
|
|
924
|
+
expiresAt: responseDate(value.expiresAt)
|
|
925
|
+
};
|
|
753
926
|
}
|
|
754
|
-
function
|
|
755
|
-
|
|
756
|
-
if (
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
if (status === 403 && code === "GOOGLE_RECOVERY_ACCOUNT_MISMATCH") return new AuthError("google_recovery_account_mismatch", 403);
|
|
762
|
-
if (status === 401 && code === "GOOGLE_RECOVERY_FRESH_SIGN_IN_REQUIRED") return new AuthError("recent_sign_in_required", 401);
|
|
763
|
-
if (code === "GOOGLE_RECOVERY_UNAVAILABLE") return authorityUnavailable();
|
|
764
|
-
return fromAccountAuthorityError(value, status, retryAfter);
|
|
927
|
+
function normalizeReceivedInvitations(value) {
|
|
928
|
+
exact$5(value, ["invitations", "nextCursor"]);
|
|
929
|
+
if (!Array.isArray(value.invitations) || value.invitations.length > 100) throw authorityUnavailable();
|
|
930
|
+
return {
|
|
931
|
+
invitations: unique(value.invitations.map(normalizeReceivedInvitation), (item) => item.id),
|
|
932
|
+
nextCursor: nullableCursor(value.nextCursor)
|
|
933
|
+
};
|
|
765
934
|
}
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
const SLASH_RE = /\//g;
|
|
770
|
-
const EQUAL_RE = /=/g;
|
|
771
|
-
const PLUS_RE = /\+/g;
|
|
772
|
-
const ENC_CARET_RE = /%5e/gi;
|
|
773
|
-
const ENC_BACKTICK_RE = /%60/gi;
|
|
774
|
-
const ENC_PIPE_RE = /%7c/gi;
|
|
775
|
-
const ENC_SPACE_RE = /%20/gi;
|
|
776
|
-
function encode$2(text) {
|
|
777
|
-
return encodeURI("" + text).replace(ENC_PIPE_RE, "|");
|
|
935
|
+
function normalizeInvitationInput(value) {
|
|
936
|
+
if (!isObject$1(value) || Object.keys(value).length !== 1 || !isId(value.invitationId)) throw new AuthError("invalid_invitation", 422);
|
|
937
|
+
return { invitationId: value.invitationId };
|
|
778
938
|
}
|
|
779
|
-
function
|
|
780
|
-
|
|
939
|
+
function normalizeInvitationAcceptance(value, invitationId) {
|
|
940
|
+
if (!isObject$1(value) || !isObject$1(value.invitation) || !isObject$1(value.member) || value.invitation.id !== invitationId || value.invitation.status !== "accepted" || !isId(value.invitation.organizationId) || value.member.organizationId !== value.invitation.organizationId) throw authorityUnavailable();
|
|
941
|
+
return { organizationId: value.invitation.organizationId };
|
|
781
942
|
}
|
|
782
|
-
function
|
|
783
|
-
|
|
943
|
+
function normalizeInvitationDecline(value, invitationId) {
|
|
944
|
+
if (!isObject$1(value) || !isObject$1(value.invitation) || value.invitation.id !== invitationId || value.invitation.status !== "rejected" || value.member !== null) throw authorityUnavailable();
|
|
945
|
+
return { status: "declined" };
|
|
784
946
|
}
|
|
785
|
-
function
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
947
|
+
function normalizeWorkspaceSelection(value) {
|
|
948
|
+
if (!isObject$1(value)) throw new AuthError("invalid_workspace_selection", 422);
|
|
949
|
+
const keys = Object.keys(value);
|
|
950
|
+
if (value.type === "personal" && keys.length === 1 && keys[0] === "type") return { type: "personal" };
|
|
951
|
+
if (value.type === "organization" && keys.length === 2 && keys.includes("type") && keys.includes("organizationId") && typeof value.organizationId === "string" && id$2.test(value.organizationId)) return {
|
|
952
|
+
type: "organization",
|
|
953
|
+
organizationId: value.organizationId
|
|
954
|
+
};
|
|
955
|
+
throw new AuthError("invalid_workspace_selection", 422);
|
|
791
956
|
}
|
|
792
|
-
function
|
|
793
|
-
|
|
957
|
+
function fromAuthorityError(value, fallbackStatus, retryAfter) {
|
|
958
|
+
const mapped = mapError(isObject$1(value) && typeof value.code === "string" ? value.code : void 0, fallbackStatus);
|
|
959
|
+
return new AuthError(mapped.code, mapped.status, parseRetryAfter(retryAfter));
|
|
794
960
|
}
|
|
795
|
-
function
|
|
796
|
-
|
|
961
|
+
function fromAccountAuthorityError(value, status, retryAfter) {
|
|
962
|
+
const code = isObject$1(value) && typeof value.code === "string" ? value.code : void 0;
|
|
963
|
+
if (status === 403 && (code === "INVALID_ORIGIN" || code === "MISSING_OR_NULL_ORIGIN")) return new AuthError("request_origin_denied", 403);
|
|
964
|
+
if (code === "USER_ALREADY_EXISTS_USE_ANOTHER_EMAIL") return new AuthError("account_conflict", 409);
|
|
965
|
+
if (code === "INVALID_TOKEN") return new AuthError("password_reset_invalid", 422);
|
|
966
|
+
if (code === "INVALID_PASSWORD" || code === "INVALID_EMAIL_OR_PASSWORD") return new AuthError("invalid_credentials", 401);
|
|
967
|
+
if (code === "INVALID_EMAIL" || code === "PASSWORD_TOO_SHORT" || code === "PASSWORD_TOO_LONG" || code === "BODY_MUST_BE_AN_OBJECT" || code === "EMAIL_CAN_NOT_BE_UPDATED") return new AuthError("invalid_auth_input", 422);
|
|
968
|
+
if (status === 401) return new AuthError("authentication_required", 401);
|
|
969
|
+
if (status === 403) return new AuthError("access_denied", 403);
|
|
970
|
+
if (status === 409) return new AuthError("state_conflict", 409);
|
|
971
|
+
if (status === 429) return new AuthError("auth_request_rate_limited", 429, parseRetryAfter(retryAfter));
|
|
972
|
+
if (status === 400 || status === 422) return new AuthError("invalid_auth_input", 422);
|
|
973
|
+
return authorityUnavailable();
|
|
797
974
|
}
|
|
798
|
-
function
|
|
799
|
-
const
|
|
800
|
-
if (
|
|
801
|
-
|
|
802
|
-
const
|
|
803
|
-
if (
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
const value = decodeQueryValue(s[2] || "");
|
|
807
|
-
if (object[key] === void 0) object[key] = value;
|
|
808
|
-
else if (Array.isArray(object[key])) object[key].push(value);
|
|
809
|
-
else object[key] = [object[key], value];
|
|
975
|
+
function fromSocialIdTokenAuthorityError(value, status, retryAfter) {
|
|
976
|
+
const code = isObject$1(value) && typeof value.code === "string" ? value.code : void 0;
|
|
977
|
+
if (code === "INVALID_TOKEN" || code === "FAILED_TO_GET_USER_INFO" || code === "USER_EMAIL_NOT_FOUND") return new AuthError("invalid_credentials", 401);
|
|
978
|
+
if (code === "OAUTH_LINK_ERROR") {
|
|
979
|
+
const message = isObject$1(value) && typeof value.message === "string" ? value.message : void 0;
|
|
980
|
+
if (message === "account not linked") return new AuthError("account_conflict", 409);
|
|
981
|
+
if (message === "signup disabled") return new AuthError("social_signup_required", 409);
|
|
982
|
+
return authorityUnavailable();
|
|
810
983
|
}
|
|
811
|
-
return
|
|
984
|
+
return fromAccountAuthorityError(value, status, retryAfter);
|
|
812
985
|
}
|
|
813
|
-
function
|
|
814
|
-
|
|
815
|
-
if (!value) return encodeQueryKey(key);
|
|
816
|
-
if (Array.isArray(value)) return value.map((_value) => `${encodeQueryKey(key)}=${encodeQueryValue(_value)}`).join("&");
|
|
817
|
-
return `${encodeQueryKey(key)}=${encodeQueryValue(value)}`;
|
|
986
|
+
function authorityUnavailable() {
|
|
987
|
+
return new AuthError("identity_authority_unavailable", 503);
|
|
818
988
|
}
|
|
819
|
-
function
|
|
820
|
-
|
|
989
|
+
function fromOrganizationListError(error) {
|
|
990
|
+
if (error instanceof AuthError && error.status === 401) return new AuthError("authentication_required", 401);
|
|
991
|
+
if (error instanceof AuthError) return error;
|
|
992
|
+
return authorityUnavailable();
|
|
821
993
|
}
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
function hasProtocol(inputString, opts = {}) {
|
|
828
|
-
if (typeof opts === "boolean") opts = { acceptRelative: opts };
|
|
829
|
-
if (opts.strict) return PROTOCOL_STRICT_REGEX.test(inputString);
|
|
830
|
-
return PROTOCOL_REGEX.test(inputString) || (opts.acceptRelative ? PROTOCOL_RELATIVE_REGEX.test(inputString) : false);
|
|
831
|
-
}
|
|
832
|
-
function hasTrailingSlash(input = "", respectQueryAndFragment) {
|
|
833
|
-
if (!respectQueryAndFragment) return input.endsWith("/");
|
|
834
|
-
return TRAILING_SLASH_RE.test(input);
|
|
835
|
-
}
|
|
836
|
-
function withoutTrailingSlash(input = "", respectQueryAndFragment) {
|
|
837
|
-
if (!respectQueryAndFragment) return (hasTrailingSlash(input) ? input.slice(0, -1) : input) || "/";
|
|
838
|
-
if (!hasTrailingSlash(input, true)) return input || "/";
|
|
839
|
-
let path = input;
|
|
840
|
-
let fragment = "";
|
|
841
|
-
const fragmentIndex = input.indexOf("#");
|
|
842
|
-
if (fragmentIndex !== -1) {
|
|
843
|
-
path = input.slice(0, fragmentIndex);
|
|
844
|
-
fragment = input.slice(fragmentIndex);
|
|
845
|
-
}
|
|
846
|
-
const [s0, ...s] = path.split("?");
|
|
847
|
-
return ((s0.endsWith("/") ? s0.slice(0, -1) : s0) || "/") + (s.length > 0 ? `?${s.join("?")}` : "") + fragment;
|
|
848
|
-
}
|
|
849
|
-
function withTrailingSlash(input = "", respectQueryAndFragment) {
|
|
850
|
-
if (!respectQueryAndFragment) return input.endsWith("/") ? input : input + "/";
|
|
851
|
-
if (hasTrailingSlash(input, true)) return input || "/";
|
|
852
|
-
let path = input;
|
|
853
|
-
let fragment = "";
|
|
854
|
-
const fragmentIndex = input.indexOf("#");
|
|
855
|
-
if (fragmentIndex !== -1) {
|
|
856
|
-
path = input.slice(0, fragmentIndex);
|
|
857
|
-
fragment = input.slice(fragmentIndex);
|
|
858
|
-
if (!path) return fragment;
|
|
859
|
-
}
|
|
860
|
-
const [s0, ...s] = path.split("?");
|
|
861
|
-
return s0 + "/" + (s.length > 0 ? `?${s.join("?")}` : "") + fragment;
|
|
862
|
-
}
|
|
863
|
-
function withBase(input, base) {
|
|
864
|
-
if (isEmptyURL(base) || hasProtocol(input)) return input;
|
|
865
|
-
const _base = withoutTrailingSlash(base);
|
|
866
|
-
if (input.startsWith(_base)) {
|
|
867
|
-
const nextChar = input[_base.length];
|
|
868
|
-
if (!nextChar || nextChar === "/" || nextChar === "?") return input;
|
|
869
|
-
}
|
|
870
|
-
return joinURL(_base, input);
|
|
871
|
-
}
|
|
872
|
-
function withQuery(input, query) {
|
|
873
|
-
const parsed = parseURL(input);
|
|
874
|
-
parsed.search = stringifyQuery({
|
|
875
|
-
...parseQuery(parsed.search),
|
|
876
|
-
...query
|
|
877
|
-
});
|
|
878
|
-
return stringifyParsedURL(parsed);
|
|
994
|
+
function fromOrganizationReadAuthorityError(value, status) {
|
|
995
|
+
if (status === 400) return new AuthError("invalid_request", 400);
|
|
996
|
+
if (status === 401) return new AuthError("authentication_required", 401);
|
|
997
|
+
if (status === 403) return new AuthError("access_denied", 403);
|
|
998
|
+
return authorityUnavailable();
|
|
879
999
|
}
|
|
880
|
-
function
|
|
881
|
-
|
|
1000
|
+
function fromOrganizationMutationAuthorityError(value, status, retryAfter) {
|
|
1001
|
+
if (status === 400 || status === 413 || status === 415) return new AuthError("invalid_request", 400);
|
|
1002
|
+
if (status === 409 && isObject$1(value) && value.code === "ORGANIZATION_SLUG_UNAVAILABLE") return new AuthError("organization_slug_unavailable", 409);
|
|
1003
|
+
if (status === 409) return new AuthError("state_conflict", 409);
|
|
1004
|
+
if (status === 429) return new AuthError("auth_request_rate_limited", 429, parseRetryAfter(retryAfter));
|
|
1005
|
+
const code = isObject$1(value) && typeof value.code === "string" ? value.code : void 0;
|
|
1006
|
+
if (status === 403 && code === "REQUEST_ORIGIN_DENIED") return new AuthError("request_origin_denied", 403);
|
|
1007
|
+
return fromOrganizationReadAuthorityError(value, status);
|
|
882
1008
|
}
|
|
883
|
-
function
|
|
884
|
-
|
|
1009
|
+
function fromOrganizationInvitationAdministrationError(value, status, retryAfter) {
|
|
1010
|
+
if (status === 422 && isObject$1(value) && value.code === "RECOVERY_REQUIRED") return new AuthError("invitation_recovery_required", 422);
|
|
1011
|
+
return fromOrganizationMutationAuthorityError(value, status, retryAfter);
|
|
885
1012
|
}
|
|
886
|
-
function
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
const _segment = segment.replace(JOIN_LEADING_SLASH_RE, "");
|
|
890
|
-
url = withTrailingSlash(url) + _segment;
|
|
891
|
-
} else url = segment;
|
|
892
|
-
return url;
|
|
1013
|
+
function fromOrganizationMembershipRemovalError(value, status, retryAfter) {
|
|
1014
|
+
if (status === 422 && isObject$1(value) && value.code === "RECOVERY_REQUIRED") return new AuthError("membership_removal_recovery_required", 422);
|
|
1015
|
+
return fromOrganizationMutationAuthorityError(value, status, retryAfter);
|
|
893
1016
|
}
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
hash: ""
|
|
907
|
-
};
|
|
908
|
-
}
|
|
909
|
-
if (!hasProtocol(input, { acceptRelative: true })) return defaultProto ? parseURL(defaultProto + input) : parsePath(input);
|
|
910
|
-
const [, protocol = "", auth, hostAndPath = ""] = input.replace(/\\/g, "/").match(/^[\s\0]*([\w+.-]{2,}:)?\/\/([^/@]+@)?(.*)/) || [];
|
|
911
|
-
let [, host = "", path = ""] = hostAndPath.match(/([^#/?]*)(.*)?/) || [];
|
|
912
|
-
if (protocol === "file:") path = path.replace(/\/(?=[A-Za-z]:)/, "");
|
|
913
|
-
const { pathname, search, hash } = parsePath(path);
|
|
1017
|
+
function normalizeOrganizationMemberAuthority(value, organizationId, memberId) {
|
|
1018
|
+
exact$5(value, [
|
|
1019
|
+
"organizationId",
|
|
1020
|
+
"actor",
|
|
1021
|
+
"target"
|
|
1022
|
+
]);
|
|
1023
|
+
if (!isId(value.organizationId) || value.organizationId !== organizationId) throw authorityUnavailable();
|
|
1024
|
+
const actor = normalizeOrganizationAuthorityMemberOutcome(value.actor);
|
|
1025
|
+
const target = normalizeOrganizationAuthorityMemberOutcome(value.target);
|
|
1026
|
+
if (target.memberId !== memberId || actor.manualRole !== "owner" && actor.manualRole !== "admin") throw authorityUnavailable();
|
|
1027
|
+
for (const member of [actor, target]) if (member.manualRole === "member" ? member.role === "owner" : member.role !== member.manualRole) throw authorityUnavailable();
|
|
1028
|
+
if (actor.memberId === target.memberId && (actor.manualRole !== target.manualRole || actor.role !== target.role || actor.authorityRevision !== target.authorityRevision)) throw authorityUnavailable();
|
|
914
1029
|
return {
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
pathname,
|
|
919
|
-
search,
|
|
920
|
-
hash,
|
|
921
|
-
[protocolRelative]: !protocol
|
|
1030
|
+
organizationId: value.organizationId,
|
|
1031
|
+
actor,
|
|
1032
|
+
target
|
|
922
1033
|
};
|
|
923
1034
|
}
|
|
924
|
-
function
|
|
925
|
-
|
|
1035
|
+
function normalizeOrganizationAuthorityMemberOutcome(value, includesStatus = false) {
|
|
1036
|
+
exact$5(value, [
|
|
1037
|
+
"memberId",
|
|
1038
|
+
"manualRole",
|
|
1039
|
+
"role",
|
|
1040
|
+
"authorityRevision",
|
|
1041
|
+
...includesStatus ? ["status"] : []
|
|
1042
|
+
]);
|
|
1043
|
+
if (!isId(value.memberId) || value.manualRole !== "owner" && value.manualRole !== "admin" && value.manualRole !== "member" || value.role !== "owner" && value.role !== "admin" && value.role !== "member") throw authorityUnavailable();
|
|
926
1044
|
return {
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
1045
|
+
memberId: value.memberId,
|
|
1046
|
+
manualRole: value.manualRole,
|
|
1047
|
+
role: value.role,
|
|
1048
|
+
authorityRevision: normalizeAuthorityResultRevision(value.authorityRevision)
|
|
930
1049
|
};
|
|
931
1050
|
}
|
|
932
|
-
function
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
const hash = parsed.hash || "";
|
|
936
|
-
const auth = parsed.auth ? parsed.auth + "@" : "";
|
|
937
|
-
const host = parsed.host || "";
|
|
938
|
-
return (parsed.protocol || parsed[protocolRelative] ? (parsed.protocol || "") + "//" : "") + auth + host + pathname + search + hash;
|
|
1051
|
+
function normalizeAuthorityResultRevision(value) {
|
|
1052
|
+
if (!Number.isSafeInteger(value) || value < 0 || value >= Number.MAX_SAFE_INTEGER) throw authorityUnavailable();
|
|
1053
|
+
return value;
|
|
939
1054
|
}
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
if (
|
|
944
|
-
return
|
|
1055
|
+
function fromInvitationAuthorityError(value, status) {
|
|
1056
|
+
const code = isObject$1(value) && typeof value.code === "string" ? value.code : void 0;
|
|
1057
|
+
if (status === 401 && code === "UNAUTHORIZED") return new AuthError("authentication_required", 401);
|
|
1058
|
+
if (status === 403 && (code === "INVALID_ORIGIN" || code === "MISSING_OR_NULL_ORIGIN")) return new AuthError("request_origin_denied", 403);
|
|
1059
|
+
if (status === 403 && code === "YOU_ARE_NOT_THE_RECIPIENT_OF_THE_INVITATION") return new AuthError("invitation_recipient_mismatch", 403);
|
|
1060
|
+
if (status === 403 && code === "EMAIL_VERIFICATION_REQUIRED_BEFORE_ACCEPTING_OR_REJECTING_INVITATION") return new AuthError("email_verification_required", 403);
|
|
1061
|
+
if (status === 400 && (code === "INVITATION_NOT_FOUND" || code === "ORGANIZATION_NOT_FOUND" || code === "TEAM_NOT_FOUND")) return new AuthError("invitation_unavailable", 409);
|
|
1062
|
+
return authorityUnavailable();
|
|
945
1063
|
}
|
|
946
|
-
function
|
|
947
|
-
|
|
1064
|
+
function fromInvitationError(error) {
|
|
1065
|
+
return error instanceof AuthError ? error : authorityUnavailable();
|
|
1066
|
+
}
|
|
1067
|
+
function mapError(code, status) {
|
|
1068
|
+
if (code === "authentication_required") return {
|
|
1069
|
+
code,
|
|
1070
|
+
status: 401
|
|
1071
|
+
};
|
|
1072
|
+
if (code === "request_origin_denied") return {
|
|
1073
|
+
code,
|
|
1074
|
+
status: 403
|
|
1075
|
+
};
|
|
1076
|
+
if (code === "invalid_workspace_selection") return {
|
|
1077
|
+
code,
|
|
1078
|
+
status: 422
|
|
1079
|
+
};
|
|
1080
|
+
if (code === "organization_context_too_large") return {
|
|
1081
|
+
code,
|
|
1082
|
+
status: 422
|
|
1083
|
+
};
|
|
1084
|
+
if (code === "credential_rate_limited") return {
|
|
1085
|
+
code,
|
|
1086
|
+
status: 429
|
|
1087
|
+
};
|
|
1088
|
+
if (code === "identity_authority_unavailable") return {
|
|
1089
|
+
code,
|
|
1090
|
+
status: 503
|
|
1091
|
+
};
|
|
1092
|
+
if (status === 401 || status === 400) return {
|
|
1093
|
+
code: "invalid_credentials",
|
|
1094
|
+
status: 401
|
|
1095
|
+
};
|
|
1096
|
+
if (status === 403) return {
|
|
1097
|
+
code: "access_denied",
|
|
1098
|
+
status: 403
|
|
1099
|
+
};
|
|
1100
|
+
if (status === 409) return {
|
|
1101
|
+
code: "state_conflict",
|
|
1102
|
+
status: 409
|
|
1103
|
+
};
|
|
1104
|
+
if (status === 422) return {
|
|
1105
|
+
code: "invalid_workspace_selection",
|
|
1106
|
+
status: 422
|
|
1107
|
+
};
|
|
1108
|
+
if (status === 429) return {
|
|
1109
|
+
code: "credential_rate_limited",
|
|
1110
|
+
status: 429
|
|
1111
|
+
};
|
|
948
1112
|
return {
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
expiresAt: new Date(startedAt + value.expiresIn * 1e3)
|
|
1113
|
+
code: "identity_authority_unavailable",
|
|
1114
|
+
status: 503
|
|
952
1115
|
};
|
|
953
1116
|
}
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
const
|
|
957
|
-
|
|
958
|
-
function concat(...buffers) {
|
|
959
|
-
const size = buffers.reduce((acc, { length }) => acc + length, 0);
|
|
960
|
-
const buf = new Uint8Array(size);
|
|
961
|
-
let i = 0;
|
|
962
|
-
for (const buffer of buffers) {
|
|
963
|
-
buf.set(buffer, i);
|
|
964
|
-
i += buffer.length;
|
|
965
|
-
}
|
|
966
|
-
return buf;
|
|
1117
|
+
function parseRetryAfter(value) {
|
|
1118
|
+
if (!value || !/^\d+$/.test(value)) return void 0;
|
|
1119
|
+
const seconds = Number(value);
|
|
1120
|
+
return Number.isSafeInteger(seconds) && seconds >= 1 && seconds <= 3600 ? seconds : void 0;
|
|
967
1121
|
}
|
|
968
|
-
function
|
|
969
|
-
const
|
|
970
|
-
|
|
971
|
-
const code = string.charCodeAt(i);
|
|
972
|
-
if (code > 127) throw new TypeError("non-ASCII string encountered in encode()");
|
|
973
|
-
bytes[i] = code;
|
|
974
|
-
}
|
|
975
|
-
return bytes;
|
|
1122
|
+
function toDate(value) {
|
|
1123
|
+
const result = value instanceof Date ? value : typeof value === "string" ? new Date(value) : void 0;
|
|
1124
|
+
return result && Number.isFinite(result.getTime()) ? result : void 0;
|
|
976
1125
|
}
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
function encodeBase64(input) {
|
|
980
|
-
if (Uint8Array.prototype.toBase64) return input.toBase64();
|
|
981
|
-
const CHUNK_SIZE = 32768;
|
|
982
|
-
const arr = [];
|
|
983
|
-
for (let i = 0; i < input.length; i += CHUNK_SIZE) arr.push(String.fromCharCode.apply(null, input.subarray(i, i + CHUNK_SIZE)));
|
|
984
|
-
return btoa(arr.join(""));
|
|
1126
|
+
function isId(value) {
|
|
1127
|
+
return typeof value === "string" && id$2.test(value);
|
|
985
1128
|
}
|
|
986
|
-
function
|
|
987
|
-
if (
|
|
988
|
-
const binary = atob(encoded);
|
|
989
|
-
const bytes = new Uint8Array(binary.length);
|
|
990
|
-
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
|
|
991
|
-
return bytes;
|
|
1129
|
+
function exact$5(value, keys) {
|
|
1130
|
+
if (!isObject$1(value) || Object.keys(value).sort().join(",") !== [...keys].sort().join(",")) throw authorityUnavailable();
|
|
992
1131
|
}
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1132
|
+
function boundedString(value, maximum) {
|
|
1133
|
+
return typeof value === "string" && value.length > 0 && new TextEncoder().encode(value).byteLength <= maximum;
|
|
1134
|
+
}
|
|
1135
|
+
function role(value) {
|
|
1136
|
+
return value === "owner" || value === "admin" || value === "member";
|
|
1137
|
+
}
|
|
1138
|
+
function nullableHttpsUrl(value) {
|
|
1139
|
+
if (value === null) return null;
|
|
1140
|
+
if (typeof value !== "string" || value.length > 2048) throw authorityUnavailable();
|
|
1141
|
+
let url;
|
|
1000
1142
|
try {
|
|
1001
|
-
|
|
1143
|
+
url = new URL(value);
|
|
1002
1144
|
} catch {
|
|
1003
|
-
throw
|
|
1145
|
+
throw authorityUnavailable();
|
|
1004
1146
|
}
|
|
1147
|
+
if (url.protocol !== "https:" || url.username || url.password || url.toString() !== value) throw authorityUnavailable();
|
|
1148
|
+
return value;
|
|
1005
1149
|
}
|
|
1006
|
-
function
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
if (
|
|
1010
|
-
|
|
1011
|
-
omitPadding: true
|
|
1012
|
-
});
|
|
1013
|
-
return encodeBase64(unencoded).replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
|
|
1014
|
-
}
|
|
1015
|
-
//#endregion
|
|
1016
|
-
//#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/lib/crypto_key.js
|
|
1017
|
-
const unusable = (name, prop = "algorithm.name") => new TypeError(`CryptoKey does not support this operation, its ${prop} must be ${name}`);
|
|
1018
|
-
const isAlgorithm = (algorithm, name) => algorithm.name === name;
|
|
1019
|
-
function getHashLength(hash) {
|
|
1020
|
-
return parseInt(hash.name.slice(4), 10);
|
|
1150
|
+
function responseDate(value) {
|
|
1151
|
+
if (typeof value !== "string") throw authorityUnavailable();
|
|
1152
|
+
const date = new Date(value);
|
|
1153
|
+
if (!Number.isFinite(date.getTime()) || date.toISOString() !== value) throw authorityUnavailable();
|
|
1154
|
+
return date;
|
|
1021
1155
|
}
|
|
1022
|
-
function
|
|
1023
|
-
if (
|
|
1156
|
+
function nullableCursor(value) {
|
|
1157
|
+
if (value === null) return null;
|
|
1158
|
+
if (typeof value !== "string" || value.length < 1 || value.length > 820 || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(value)) throw authorityUnavailable();
|
|
1159
|
+
return value;
|
|
1024
1160
|
}
|
|
1025
|
-
function
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
case "ES384": return "P-384";
|
|
1029
|
-
case "ES512": return "P-521";
|
|
1030
|
-
default: throw new Error("unreachable");
|
|
1031
|
-
}
|
|
1161
|
+
function normalizeResponseId(value) {
|
|
1162
|
+
if (!isId(value)) throw authorityUnavailable();
|
|
1163
|
+
return value;
|
|
1032
1164
|
}
|
|
1033
|
-
function
|
|
1034
|
-
if (
|
|
1165
|
+
function unique(items, key) {
|
|
1166
|
+
if (new Set(items.map(key)).size !== items.length) throw authorityUnavailable();
|
|
1167
|
+
return items;
|
|
1035
1168
|
}
|
|
1036
|
-
function
|
|
1037
|
-
|
|
1038
|
-
case "HS256":
|
|
1039
|
-
case "HS384":
|
|
1040
|
-
case "HS512":
|
|
1041
|
-
if (!isAlgorithm(key.algorithm, "HMAC")) throw unusable("HMAC");
|
|
1042
|
-
checkHashLength(key.algorithm, parseInt(alg.slice(2), 10));
|
|
1043
|
-
break;
|
|
1044
|
-
case "RS256":
|
|
1045
|
-
case "RS384":
|
|
1046
|
-
case "RS512":
|
|
1047
|
-
if (!isAlgorithm(key.algorithm, "RSASSA-PKCS1-v1_5")) throw unusable("RSASSA-PKCS1-v1_5");
|
|
1048
|
-
checkHashLength(key.algorithm, parseInt(alg.slice(2), 10));
|
|
1049
|
-
break;
|
|
1050
|
-
case "PS256":
|
|
1051
|
-
case "PS384":
|
|
1052
|
-
case "PS512":
|
|
1053
|
-
if (!isAlgorithm(key.algorithm, "RSA-PSS")) throw unusable("RSA-PSS");
|
|
1054
|
-
checkHashLength(key.algorithm, parseInt(alg.slice(2), 10));
|
|
1055
|
-
break;
|
|
1056
|
-
case "Ed25519":
|
|
1057
|
-
case "EdDSA":
|
|
1058
|
-
if (!isAlgorithm(key.algorithm, "Ed25519")) throw unusable("Ed25519");
|
|
1059
|
-
break;
|
|
1060
|
-
case "ML-DSA-44":
|
|
1061
|
-
case "ML-DSA-65":
|
|
1062
|
-
case "ML-DSA-87":
|
|
1063
|
-
if (!isAlgorithm(key.algorithm, alg)) throw unusable(alg);
|
|
1064
|
-
break;
|
|
1065
|
-
case "ES256":
|
|
1066
|
-
case "ES384":
|
|
1067
|
-
case "ES512": {
|
|
1068
|
-
if (!isAlgorithm(key.algorithm, "ECDSA")) throw unusable("ECDSA");
|
|
1069
|
-
const expected = getNamedCurve(alg);
|
|
1070
|
-
if (key.algorithm.namedCurve !== expected) throw unusable(expected, "algorithm.namedCurve");
|
|
1071
|
-
break;
|
|
1072
|
-
}
|
|
1073
|
-
default: throw new TypeError("CryptoKey does not support this operation");
|
|
1074
|
-
}
|
|
1075
|
-
checkUsage(key, usage);
|
|
1169
|
+
function isObject$1(value) {
|
|
1170
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1076
1171
|
}
|
|
1077
1172
|
//#endregion
|
|
1078
|
-
//#region
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1173
|
+
//#region src/http.ts
|
|
1174
|
+
const MAX_RESPONSE_BYTES = 64 * 1024;
|
|
1175
|
+
async function requestJson(url, options) {
|
|
1176
|
+
return (await requestJsonResponse(url, options)).value;
|
|
1177
|
+
}
|
|
1178
|
+
async function requestJsonResponse(url, options) {
|
|
1179
|
+
let response;
|
|
1180
|
+
try {
|
|
1181
|
+
response = await createFetch({ fetch: options.fetch }).raw(url, {
|
|
1182
|
+
method: options.method,
|
|
1183
|
+
headers: options.headers,
|
|
1184
|
+
body: options.body,
|
|
1185
|
+
credentials: options.credentials ?? "include",
|
|
1186
|
+
cache: options.cache,
|
|
1187
|
+
retry: 0,
|
|
1188
|
+
timeout: options.timeoutMs,
|
|
1189
|
+
redirect: "manual",
|
|
1190
|
+
signal: options.signal,
|
|
1191
|
+
responseType: "stream",
|
|
1192
|
+
ignoreResponseError: true
|
|
1193
|
+
});
|
|
1194
|
+
} catch {
|
|
1195
|
+
throw authorityUnavailable();
|
|
1090
1196
|
}
|
|
1091
|
-
|
|
1197
|
+
const contentType = response.headers.get("content-type")?.split(";", 1)[0]?.trim().toLowerCase();
|
|
1198
|
+
if (response.status >= 300 || response.status < 200 || contentType !== "application/json") {
|
|
1199
|
+
const body = contentType === "application/json" ? await readJson(response, options.maxResponseBytes, options.signal) : void 0;
|
|
1200
|
+
response.body?.cancel().catch(() => void 0);
|
|
1201
|
+
throw (options.mapError ?? fromAuthorityError)(body, response.status, response.headers.get("retry-after"));
|
|
1202
|
+
}
|
|
1203
|
+
return {
|
|
1204
|
+
value: await readJson(response, options.maxResponseBytes, options.signal),
|
|
1205
|
+
headers: response.headers
|
|
1206
|
+
};
|
|
1092
1207
|
}
|
|
1093
|
-
|
|
1094
|
-
const
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
static code = "ERR_JOSE_GENERIC";
|
|
1099
|
-
code = "ERR_JOSE_GENERIC";
|
|
1100
|
-
constructor(message, options) {
|
|
1101
|
-
super(message, options);
|
|
1102
|
-
this.name = this.constructor.name;
|
|
1103
|
-
Error.captureStackTrace?.(this, this.constructor);
|
|
1208
|
+
async function readJson(response, maximum = MAX_RESPONSE_BYTES, signal) {
|
|
1209
|
+
const length = response.headers.get("content-length");
|
|
1210
|
+
if (length && (!/^\d+$/.test(length) || Number(length) > maximum)) {
|
|
1211
|
+
response.body?.cancel().catch(() => void 0);
|
|
1212
|
+
throw authorityUnavailable();
|
|
1104
1213
|
}
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
claim;
|
|
1110
|
-
reason;
|
|
1111
|
-
payload;
|
|
1112
|
-
constructor(message, payload, claim = "unspecified", reason = "unspecified") {
|
|
1113
|
-
super(message, { cause: {
|
|
1114
|
-
claim,
|
|
1115
|
-
reason,
|
|
1116
|
-
payload
|
|
1117
|
-
} });
|
|
1118
|
-
this.claim = claim;
|
|
1119
|
-
this.reason = reason;
|
|
1120
|
-
this.payload = payload;
|
|
1214
|
+
if (!response.body) throw authorityUnavailable();
|
|
1215
|
+
if (signal?.aborted) {
|
|
1216
|
+
response.body.cancel().catch(() => void 0);
|
|
1217
|
+
throw authorityUnavailable();
|
|
1121
1218
|
}
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1219
|
+
const reader = response.body.getReader();
|
|
1220
|
+
const cancel = () => {
|
|
1221
|
+
reader.cancel().catch(() => void 0);
|
|
1222
|
+
};
|
|
1223
|
+
signal?.addEventListener("abort", cancel, { once: true });
|
|
1224
|
+
const chunks = [];
|
|
1225
|
+
let size = 0;
|
|
1226
|
+
try {
|
|
1227
|
+
while (true) {
|
|
1228
|
+
const { done, value } = await reader.read();
|
|
1229
|
+
if (signal?.aborted) throw authorityUnavailable();
|
|
1230
|
+
if (done) break;
|
|
1231
|
+
size += value.byteLength;
|
|
1232
|
+
if (size > maximum) throw authorityUnavailable();
|
|
1233
|
+
chunks.push(value);
|
|
1234
|
+
}
|
|
1235
|
+
} catch (error) {
|
|
1236
|
+
reader.cancel().catch(() => void 0);
|
|
1237
|
+
throw error;
|
|
1238
|
+
} finally {
|
|
1239
|
+
signal?.removeEventListener("abort", cancel);
|
|
1240
|
+
reader.releaseLock();
|
|
1138
1241
|
}
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
var JOSENotSupported = class extends JOSEError {
|
|
1145
|
-
static code = "ERR_JOSE_NOT_SUPPORTED";
|
|
1146
|
-
code = "ERR_JOSE_NOT_SUPPORTED";
|
|
1147
|
-
};
|
|
1148
|
-
var JWSInvalid = class extends JOSEError {
|
|
1149
|
-
static code = "ERR_JWS_INVALID";
|
|
1150
|
-
code = "ERR_JWS_INVALID";
|
|
1151
|
-
};
|
|
1152
|
-
var JWTInvalid = class extends JOSEError {
|
|
1153
|
-
static code = "ERR_JWT_INVALID";
|
|
1154
|
-
code = "ERR_JWT_INVALID";
|
|
1155
|
-
};
|
|
1156
|
-
var JWKInvalid = class extends JOSEError {
|
|
1157
|
-
static code = "ERR_JWK_INVALID";
|
|
1158
|
-
code = "ERR_JWK_INVALID";
|
|
1159
|
-
};
|
|
1160
|
-
var JWSSignatureVerificationFailed = class extends JOSEError {
|
|
1161
|
-
static code = "ERR_JWS_SIGNATURE_VERIFICATION_FAILED";
|
|
1162
|
-
code = "ERR_JWS_SIGNATURE_VERIFICATION_FAILED";
|
|
1163
|
-
constructor(message = "signature verification failed", options) {
|
|
1164
|
-
super(message, options);
|
|
1242
|
+
const bytes = new Uint8Array(size);
|
|
1243
|
+
let offset = 0;
|
|
1244
|
+
for (const chunk of chunks) {
|
|
1245
|
+
bytes.set(chunk, offset);
|
|
1246
|
+
offset += chunk.byteLength;
|
|
1165
1247
|
}
|
|
1166
|
-
};
|
|
1167
|
-
//#endregion
|
|
1168
|
-
//#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/lib/is_key_like.js
|
|
1169
|
-
const isCryptoKey = (key) => {
|
|
1170
|
-
if (key?.[Symbol.toStringTag] === "CryptoKey") return true;
|
|
1171
1248
|
try {
|
|
1172
|
-
return
|
|
1249
|
+
return JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
|
|
1173
1250
|
} catch {
|
|
1174
|
-
|
|
1251
|
+
throw authorityUnavailable();
|
|
1175
1252
|
}
|
|
1176
|
-
}
|
|
1177
|
-
const isKeyObject = (key) => key?.[Symbol.toStringTag] === "KeyObject";
|
|
1178
|
-
const isKeyLike = (key) => isCryptoKey(key) || isKeyObject(key);
|
|
1253
|
+
}
|
|
1179
1254
|
//#endregion
|
|
1180
|
-
//#region
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
}
|
|
1255
|
+
//#region src/product-operations/contract.ts
|
|
1256
|
+
const id$1 = /^[A-Za-z0-9_-]{1,128}$(?![\s\S])/;
|
|
1257
|
+
const digest$1 = /^[a-f0-9]{64}$(?![\s\S])/;
|
|
1258
|
+
const credential = /^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$(?![\s\S])/;
|
|
1259
|
+
function exact$4(value, keys) {
|
|
1260
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === keys.length && keys.every((key) => Object.hasOwn(value, key));
|
|
1187
1261
|
}
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1262
|
+
function identifier(value) {
|
|
1263
|
+
return typeof value === "string" && id$1.test(value);
|
|
1264
|
+
}
|
|
1265
|
+
function timestamp(value) {
|
|
1266
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0 && value <= 864e13;
|
|
1267
|
+
}
|
|
1268
|
+
function operationProof(value) {
|
|
1269
|
+
if (!exact$4(value, [
|
|
1270
|
+
"applicationCredential",
|
|
1271
|
+
"serviceAssertion",
|
|
1272
|
+
"actorUserId",
|
|
1273
|
+
"actorSessionId",
|
|
1274
|
+
"serviceId",
|
|
1275
|
+
"environment"
|
|
1276
|
+
]) || !identifier(value.actorUserId) || !identifier(value.actorSessionId) || !identifier(value.serviceId) || ![
|
|
1277
|
+
"local",
|
|
1278
|
+
"development",
|
|
1279
|
+
"staging",
|
|
1280
|
+
"production"
|
|
1281
|
+
].includes(value.environment) || [value.applicationCredential, value.serviceAssertion].some((token) => typeof token !== "string" || token.length > 16 * 1024 || !credential.test(token))) throw new AuthError("invalid_request", 400);
|
|
1282
|
+
return {
|
|
1283
|
+
applicationCredential: value.applicationCredential,
|
|
1284
|
+
serviceAssertion: value.serviceAssertion,
|
|
1285
|
+
actorUserId: value.actorUserId,
|
|
1286
|
+
actorSessionId: value.actorSessionId,
|
|
1287
|
+
serviceId: value.serviceId,
|
|
1288
|
+
environment: value.environment
|
|
1289
|
+
};
|
|
1191
1290
|
}
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
let proto = input;
|
|
1199
|
-
while (Object.getPrototypeOf(proto) !== null) proto = Object.getPrototypeOf(proto);
|
|
1200
|
-
return Object.getPrototypeOf(input) === proto;
|
|
1291
|
+
function snapshotInput(value) {
|
|
1292
|
+
if (!exact$4(value, ["applicationId", "participantUserUids"]) || !identifier(value.applicationId) || !Array.isArray(value.participantUserUids) || value.participantUserUids.length < 1 || value.participantUserUids.length > 100 || !value.participantUserUids.every((uid, index, all) => identifier(uid) && (index === 0 || all[index - 1] < uid))) throw new AuthError("invalid_request", 400);
|
|
1293
|
+
return {
|
|
1294
|
+
applicationId: value.applicationId,
|
|
1295
|
+
participantUserUids: [...value.participantUserUids]
|
|
1296
|
+
};
|
|
1201
1297
|
}
|
|
1202
|
-
function
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1298
|
+
function operationInput(value) {
|
|
1299
|
+
if (!exact$4(value, [
|
|
1300
|
+
"applicationId",
|
|
1301
|
+
"snapshotId",
|
|
1302
|
+
"operationHash",
|
|
1303
|
+
"nonce"
|
|
1304
|
+
]) || !identifier(value.applicationId) || !identifier(value.snapshotId) || typeof value.operationHash !== "string" || !digest$1.test(value.operationHash) || typeof value.nonce !== "string" || !digest$1.test(value.nonce)) throw new AuthError("invalid_request", 400);
|
|
1305
|
+
return {
|
|
1306
|
+
applicationId: value.applicationId,
|
|
1307
|
+
snapshotId: value.snapshotId,
|
|
1308
|
+
operationHash: value.operationHash,
|
|
1309
|
+
nonce: value.nonce
|
|
1310
|
+
};
|
|
1311
|
+
}
|
|
1312
|
+
const snapshotKeys = [
|
|
1313
|
+
"snapshotId",
|
|
1314
|
+
"actorUserId",
|
|
1315
|
+
"actorSessionId",
|
|
1316
|
+
"issuedAt",
|
|
1317
|
+
"expiresAt"
|
|
1318
|
+
];
|
|
1319
|
+
function snapshotFields(value) {
|
|
1320
|
+
if (!identifier(value.snapshotId) || !identifier(value.actorUserId) || !identifier(value.actorSessionId) || !timestamp(value.issuedAt) || !timestamp(value.expiresAt) || value.expiresAt <= value.issuedAt || value.expiresAt - value.issuedAt > 3e4) throw authorityUnavailable();
|
|
1321
|
+
return {
|
|
1322
|
+
snapshotId: value.snapshotId,
|
|
1323
|
+
actorUserId: value.actorUserId,
|
|
1324
|
+
actorSessionId: value.actorSessionId,
|
|
1325
|
+
issuedAt: value.issuedAt,
|
|
1326
|
+
expiresAt: value.expiresAt
|
|
1327
|
+
};
|
|
1328
|
+
}
|
|
1329
|
+
function snapshotOutput(value, participants, proof) {
|
|
1330
|
+
if (!exact$4(value, snapshotKeys)) throw authorityUnavailable();
|
|
1331
|
+
const result = snapshotFields(value);
|
|
1332
|
+
if (!participants.includes(result.actorUserId) || result.actorUserId !== proof.actorUserId || result.actorSessionId !== proof.actorSessionId) throw authorityUnavailable();
|
|
1333
|
+
return result;
|
|
1334
|
+
}
|
|
1335
|
+
function receiptOutput(value, input, proof, phase) {
|
|
1336
|
+
if (!exact$4(value, [
|
|
1337
|
+
...snapshotKeys,
|
|
1338
|
+
"serviceId",
|
|
1339
|
+
"applicationId",
|
|
1340
|
+
"actorAccountCreatedAt",
|
|
1341
|
+
"environment",
|
|
1342
|
+
"scopeKind",
|
|
1343
|
+
"organizationId",
|
|
1344
|
+
"nonce",
|
|
1345
|
+
"operationHash",
|
|
1346
|
+
"consumedAt"
|
|
1347
|
+
])) throw authorityUnavailable();
|
|
1348
|
+
const snapshot = snapshotFields(value);
|
|
1349
|
+
if (snapshot.snapshotId !== input.snapshotId || snapshot.actorUserId !== proof.actorUserId || phase === "consume" && snapshot.actorSessionId !== proof.actorSessionId || value.serviceId !== proof.serviceId || value.environment !== proof.environment || value.applicationId !== input.applicationId || value.nonce !== input.nonce || value.operationHash !== input.operationHash || !identifier(value.serviceId) || !timestamp(value.actorAccountCreatedAt) || value.scopeKind !== "account" || value.organizationId !== null || !timestamp(value.consumedAt) || value.consumedAt < snapshot.issuedAt || value.consumedAt >= snapshot.expiresAt || ![
|
|
1350
|
+
"local",
|
|
1351
|
+
"development",
|
|
1352
|
+
"staging",
|
|
1353
|
+
"production"
|
|
1354
|
+
].includes(value.environment)) throw authorityUnavailable();
|
|
1355
|
+
return {
|
|
1356
|
+
...snapshot,
|
|
1357
|
+
serviceId: value.serviceId,
|
|
1358
|
+
applicationId: input.applicationId,
|
|
1359
|
+
actorAccountCreatedAt: value.actorAccountCreatedAt,
|
|
1360
|
+
environment: value.environment,
|
|
1361
|
+
scopeKind: "account",
|
|
1362
|
+
organizationId: null,
|
|
1363
|
+
nonce: input.nonce,
|
|
1364
|
+
operationHash: input.operationHash,
|
|
1365
|
+
consumedAt: value.consumedAt
|
|
1366
|
+
};
|
|
1367
|
+
}
|
|
1368
|
+
//#endregion
|
|
1369
|
+
//#region src/product-operations/index.ts
|
|
1370
|
+
function createAccountProductOperationAuth(options) {
|
|
1371
|
+
const base = joinURL(normalizeOrigin(options.authOrigin, "authOrigin"), "api/v1/auth/product-operations/account");
|
|
1372
|
+
const fetchImpl = options.fetch ?? globalThis.fetch?.bind(globalThis);
|
|
1373
|
+
if (typeof fetchImpl !== "function") throw new TypeError("fetch is required");
|
|
1374
|
+
const timeoutMs = normalizeTimeout(options.timeoutMs);
|
|
1375
|
+
function audience(phase) {
|
|
1376
|
+
if (![
|
|
1377
|
+
"snapshot",
|
|
1378
|
+
"consume",
|
|
1379
|
+
"receipt"
|
|
1380
|
+
].includes(phase)) throw new AuthError("invalid_request", 400);
|
|
1381
|
+
return joinURL(base, phase);
|
|
1382
|
+
}
|
|
1383
|
+
async function exchange(phase, applicationId, body, proof) {
|
|
1384
|
+
const credentials = proof;
|
|
1385
|
+
const url = new URL(audience(phase));
|
|
1386
|
+
url.searchParams.set("applicationId", applicationId);
|
|
1387
|
+
const controller = new AbortController();
|
|
1388
|
+
let timer;
|
|
1389
|
+
try {
|
|
1390
|
+
const deadline = new Promise((_, reject) => {
|
|
1391
|
+
timer = setTimeout(() => {
|
|
1392
|
+
controller.abort();
|
|
1393
|
+
reject(authorityUnavailable());
|
|
1394
|
+
}, timeoutMs);
|
|
1395
|
+
});
|
|
1396
|
+
return await Promise.race([requestJson(url.toString(), {
|
|
1397
|
+
fetch: fetchImpl,
|
|
1398
|
+
timeoutMs,
|
|
1399
|
+
method: "POST",
|
|
1400
|
+
credentials: "omit",
|
|
1401
|
+
cache: "no-store",
|
|
1402
|
+
signal: controller.signal,
|
|
1403
|
+
maxResponseBytes: 4096,
|
|
1404
|
+
headers: {
|
|
1405
|
+
"x-finueva-application-credential": credentials.applicationCredential,
|
|
1406
|
+
"x-finueva-service-assertion": credentials.serviceAssertion,
|
|
1407
|
+
accept: "application/json",
|
|
1408
|
+
"content-type": "application/json"
|
|
1409
|
+
},
|
|
1410
|
+
body,
|
|
1411
|
+
mapError: (_value, status, retryAfter) => {
|
|
1412
|
+
if (status === 401) return new AuthError("access_denied", 401);
|
|
1413
|
+
if (status === 429 && retryAfter !== null && /^(?:[1-9]|[1-5][0-9]|60)$/.test(retryAfter)) return new AuthError("auth_request_rate_limited", 429, Number(retryAfter));
|
|
1414
|
+
return authorityUnavailable();
|
|
1415
|
+
}
|
|
1416
|
+
}), deadline]);
|
|
1417
|
+
} finally {
|
|
1418
|
+
clearTimeout(timer);
|
|
1419
|
+
controller.abort();
|
|
1215
1420
|
}
|
|
1216
1421
|
}
|
|
1217
|
-
return
|
|
1422
|
+
return {
|
|
1423
|
+
audience,
|
|
1424
|
+
async captureAccountOperation(input, proof) {
|
|
1425
|
+
const validated = snapshotInput(input);
|
|
1426
|
+
const expected = operationProof(proof);
|
|
1427
|
+
return snapshotOutput(await exchange("snapshot", validated.applicationId, { participantUserUids: validated.participantUserUids }, expected), validated.participantUserUids, expected);
|
|
1428
|
+
},
|
|
1429
|
+
async consumeAccountOperation(input, proof) {
|
|
1430
|
+
const validated = operationInput(input);
|
|
1431
|
+
const expected = operationProof(proof);
|
|
1432
|
+
const { applicationId, ...body } = validated;
|
|
1433
|
+
const value = await exchange("consume", applicationId, body, expected);
|
|
1434
|
+
if (!exact$4(value, ["receipt", "replayed"]) || typeof value.replayed !== "boolean") throw authorityUnavailable();
|
|
1435
|
+
return {
|
|
1436
|
+
receipt: receiptOutput(value.receipt, validated, expected, "consume"),
|
|
1437
|
+
replayed: value.replayed
|
|
1438
|
+
};
|
|
1439
|
+
},
|
|
1440
|
+
async retrieveAccountOperationReceipt(input, proof) {
|
|
1441
|
+
const validated = operationInput(input);
|
|
1442
|
+
const expected = operationProof(proof);
|
|
1443
|
+
const { applicationId, ...body } = validated;
|
|
1444
|
+
return receiptOutput(await exchange("receipt", applicationId, body, expected), validated, expected, "receipt");
|
|
1445
|
+
}
|
|
1446
|
+
};
|
|
1218
1447
|
}
|
|
1219
|
-
const isJWK = (key) => isObject(key) && typeof key.kty === "string";
|
|
1220
|
-
const isPrivateJWK = (key) => key.kty !== "oct" && (key.kty === "AKP" && typeof key.priv === "string" || typeof key.d === "string");
|
|
1221
|
-
const isPublicJWK = (key) => key.kty !== "oct" && key.d === void 0 && key.priv === void 0;
|
|
1222
|
-
const isSecretJWK = (key) => key.kty === "oct" && typeof key.k === "string";
|
|
1223
1448
|
//#endregion
|
|
1224
|
-
//#region
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1449
|
+
//#region src/application-access.ts
|
|
1450
|
+
const id = /^[A-Za-z0-9_-]{1,128}$(?![\s\S])/;
|
|
1451
|
+
function applicationAccessInput(input) {
|
|
1452
|
+
if (!input || typeof input.applicationId !== "string" || !id.test(input.applicationId) || !Array.isArray(input.userIds) || input.userIds.length < 1 || input.userIds.length > 50 || input.userIds.some((value) => typeof value !== "string" || !id.test(value)) || new Set(input.userIds).size !== input.userIds.length) throw new TypeError("Application access input is invalid");
|
|
1453
|
+
return {
|
|
1454
|
+
applicationId: input.applicationId,
|
|
1455
|
+
userIds: [...input.userIds]
|
|
1456
|
+
};
|
|
1230
1457
|
}
|
|
1231
|
-
function
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
case "RS256":
|
|
1248
|
-
case "RS384":
|
|
1249
|
-
case "RS512": return {
|
|
1250
|
-
hash,
|
|
1251
|
-
name: "RSASSA-PKCS1-v1_5"
|
|
1252
|
-
};
|
|
1253
|
-
case "ES256":
|
|
1254
|
-
case "ES384":
|
|
1255
|
-
case "ES512": return {
|
|
1256
|
-
hash,
|
|
1257
|
-
name: "ECDSA",
|
|
1258
|
-
namedCurve: algorithm.namedCurve
|
|
1458
|
+
function exact$3(value, keys) {
|
|
1459
|
+
return !!value && typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === keys.length && keys.every((key) => Object.hasOwn(value, key));
|
|
1460
|
+
}
|
|
1461
|
+
function normalizeApplicationAccess(value, userIds) {
|
|
1462
|
+
const invalid = () => new AuthError("identity_authority_unavailable", 503);
|
|
1463
|
+
if (!exact$3(value, ["members"]) || !Array.isArray(value.members) || value.members.length !== userIds.length) throw invalid();
|
|
1464
|
+
return { members: value.members.map((member, index) => {
|
|
1465
|
+
if (!exact$3(member, [
|
|
1466
|
+
"userId",
|
|
1467
|
+
"latestAppSessionAdmittedAt",
|
|
1468
|
+
"activeAppSessionCount"
|
|
1469
|
+
]) || member.userId !== userIds[index] || typeof member.activeAppSessionCount !== "number" || !Number.isSafeInteger(member.activeAppSessionCount) || member.activeAppSessionCount < 0 || member.latestAppSessionAdmittedAt !== null && (typeof member.latestAppSessionAdmittedAt !== "string" || !/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$(?![\s\S])/.test(member.latestAppSessionAdmittedAt) || Number.isNaN(Date.parse(member.latestAppSessionAdmittedAt)) || new Date(member.latestAppSessionAdmittedAt).toISOString() !== member.latestAppSessionAdmittedAt)) throw invalid();
|
|
1470
|
+
return {
|
|
1471
|
+
userId: member.userId,
|
|
1472
|
+
latestAppSessionAdmittedAt: member.latestAppSessionAdmittedAt,
|
|
1473
|
+
activeAppSessionCount: member.activeAppSessionCount
|
|
1259
1474
|
};
|
|
1260
|
-
|
|
1261
|
-
case "EdDSA": return { name: "Ed25519" };
|
|
1262
|
-
case "ML-DSA-44":
|
|
1263
|
-
case "ML-DSA-65":
|
|
1264
|
-
case "ML-DSA-87": return { name: alg };
|
|
1265
|
-
default: throw new JOSENotSupported(`alg ${alg} is not supported either by JOSE or your javascript runtime`);
|
|
1266
|
-
}
|
|
1475
|
+
}) };
|
|
1267
1476
|
}
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1477
|
+
//#endregion
|
|
1478
|
+
//#region src/google-recovery.ts
|
|
1479
|
+
function object(value) {
|
|
1480
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
1481
|
+
}
|
|
1482
|
+
function validTicket(value) {
|
|
1483
|
+
return typeof value === "string" && /^[A-Za-z0-9_-]{43}$/.test(value);
|
|
1484
|
+
}
|
|
1485
|
+
function googleRecoveryInput(value, complete) {
|
|
1486
|
+
if (!object(value) || Object.keys(value).sort().join(",") !== (complete ? "idToken,recoveryToken" : "idToken") || !object(value.idToken) || Object.keys(value.idToken).some((key) => key !== "token" && key !== "nonce") || complete && !validTicket(value.recoveryToken)) throw new AuthError("invalid_request", 400);
|
|
1487
|
+
const social = normalizeSocialIdTokenInput({
|
|
1488
|
+
provider: "google",
|
|
1489
|
+
idToken: value.idToken.token,
|
|
1490
|
+
signUp: false,
|
|
1491
|
+
...value.idToken.nonce === void 0 ? {} : { nonce: value.idToken.nonce }
|
|
1492
|
+
});
|
|
1493
|
+
return {
|
|
1494
|
+
idToken: {
|
|
1495
|
+
token: social.idToken,
|
|
1496
|
+
...social.nonce === void 0 ? {} : { nonce: social.nonce }
|
|
1497
|
+
},
|
|
1498
|
+
...complete ? { recoveryToken: value.recoveryToken } : {}
|
|
1499
|
+
};
|
|
1500
|
+
}
|
|
1501
|
+
function normalizeGoogleRecovery(value, now) {
|
|
1502
|
+
if (!object(value) || Object.keys(value).sort().join(",") !== "expiresAt,recoveryToken" || !validTicket(value.recoveryToken) || typeof value.expiresAt !== "string") throw authorityUnavailable();
|
|
1503
|
+
const expiresAt = Date.parse(value.expiresAt);
|
|
1504
|
+
if (!Number.isFinite(expiresAt) || expiresAt <= now || expiresAt > now + 10 * 6e4) throw authorityUnavailable();
|
|
1505
|
+
return {
|
|
1506
|
+
recoveryToken: value.recoveryToken,
|
|
1507
|
+
expiresAt: value.expiresAt
|
|
1508
|
+
};
|
|
1509
|
+
}
|
|
1510
|
+
function normalizeGoogleRecoveryCompletion(value) {
|
|
1511
|
+
if (!object(value) || Object.keys(value).join(",") !== "linked" || value.linked !== true) throw authorityUnavailable();
|
|
1512
|
+
return { linked: true };
|
|
1513
|
+
}
|
|
1514
|
+
function fromGoogleRecoveryError(value, status, retryAfter) {
|
|
1515
|
+
const code = object(value) ? value.code : void 0;
|
|
1516
|
+
if (status === 409 && code === "GOOGLE_RECOVERY_IN_PROGRESS") return new AuthError("google_recovery_in_progress", 409);
|
|
1517
|
+
if (status === 409 && code === "GOOGLE_RECOVERY_NOT_REQUIRED") return new AuthError("google_recovery_not_required", 409);
|
|
1518
|
+
if (status === 403 && code === "GOOGLE_RECOVERY_EMAIL_VERIFICATION_REQUIRED") return new AuthError("email_verification_required", 403);
|
|
1519
|
+
if (status === 400 && code === "GOOGLE_RECOVERY_INVALID") return new AuthError("google_recovery_invalid", 400);
|
|
1520
|
+
if (status === 410 && code === "GOOGLE_RECOVERY_EXPIRED") return new AuthError("google_recovery_expired", 410);
|
|
1521
|
+
if (status === 403 && code === "GOOGLE_RECOVERY_ACCOUNT_MISMATCH") return new AuthError("google_recovery_account_mismatch", 403);
|
|
1522
|
+
if (status === 401 && code === "GOOGLE_RECOVERY_FRESH_SIGN_IN_REQUIRED") return new AuthError("recent_sign_in_required", 401);
|
|
1523
|
+
if (code === "GOOGLE_RECOVERY_UNAVAILABLE") return authorityUnavailable();
|
|
1524
|
+
return fromAccountAuthorityError(value, status, retryAfter);
|
|
1525
|
+
}
|
|
1526
|
+
//#endregion
|
|
1527
|
+
//#region src/user-api/credential.ts
|
|
1528
|
+
function userApiApplication(input) {
|
|
1529
|
+
if (!input || typeof input.applicationId !== "string" || !/^[A-Za-z0-9_-]{1,128}$(?![\s\S])/.test(input.applicationId) || input.forceRefresh !== void 0 && typeof input.forceRefresh !== "boolean") throw new TypeError("User API credential input is invalid");
|
|
1530
|
+
return input.applicationId;
|
|
1531
|
+
}
|
|
1532
|
+
function normalizeUserApiCredential(value, startedAt) {
|
|
1533
|
+
if (!value || typeof value !== "object" || Array.isArray(value) || !("tokenType" in value) || value.tokenType !== "Bearer" || !("token" in value) || typeof value.token !== "string" || value.token.length + 7 > 16 * 1024 || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(value.token) || !("expiresIn" in value) || typeof value.expiresIn !== "number" || !Number.isInteger(value.expiresIn) || value.expiresIn < 1 || value.expiresIn > 840 || Object.keys(value).sort().join(",") !== "expiresIn,token,tokenType") throw new AuthError("identity_authority_unavailable", 503);
|
|
1534
|
+
return {
|
|
1535
|
+
tokenType: "Bearer",
|
|
1536
|
+
token: value.token,
|
|
1537
|
+
expiresAt: new Date(startedAt + value.expiresIn * 1e3)
|
|
1538
|
+
};
|
|
1539
|
+
}
|
|
1540
|
+
//#endregion
|
|
1541
|
+
//#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/lib/buffer_utils.js
|
|
1542
|
+
const encoder$1 = new TextEncoder();
|
|
1543
|
+
const decoder = new TextDecoder();
|
|
1544
|
+
function concat(...buffers) {
|
|
1545
|
+
const size = buffers.reduce((acc, { length }) => acc + length, 0);
|
|
1546
|
+
const buf = new Uint8Array(size);
|
|
1547
|
+
let i = 0;
|
|
1548
|
+
for (const buffer of buffers) {
|
|
1549
|
+
buf.set(buffer, i);
|
|
1550
|
+
i += buffer.length;
|
|
1275
1551
|
}
|
|
1276
|
-
|
|
1277
|
-
return key;
|
|
1552
|
+
return buf;
|
|
1278
1553
|
}
|
|
1279
|
-
|
|
1280
|
-
const
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
} catch {
|
|
1286
|
-
return false;
|
|
1554
|
+
function encode$1(string) {
|
|
1555
|
+
const bytes = new Uint8Array(string.length);
|
|
1556
|
+
for (let i = 0; i < string.length; i++) {
|
|
1557
|
+
const code = string.charCodeAt(i);
|
|
1558
|
+
if (code > 127) throw new TypeError("non-ASCII string encountered in encode()");
|
|
1559
|
+
bytes[i] = code;
|
|
1287
1560
|
}
|
|
1561
|
+
return bytes;
|
|
1288
1562
|
}
|
|
1289
1563
|
//#endregion
|
|
1290
|
-
//#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/lib/
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1564
|
+
//#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/lib/base64.js
|
|
1565
|
+
function encodeBase64(input) {
|
|
1566
|
+
if (Uint8Array.prototype.toBase64) return input.toBase64();
|
|
1567
|
+
const CHUNK_SIZE = 32768;
|
|
1568
|
+
const arr = [];
|
|
1569
|
+
for (let i = 0; i < input.length; i += CHUNK_SIZE) arr.push(String.fromCharCode.apply(null, input.subarray(i, i + CHUNK_SIZE)));
|
|
1570
|
+
return btoa(arr.join(""));
|
|
1571
|
+
}
|
|
1572
|
+
function decodeBase64(encoded) {
|
|
1573
|
+
if (Uint8Array.fromBase64) return Uint8Array.fromBase64(encoded);
|
|
1574
|
+
const binary = atob(encoded);
|
|
1575
|
+
const bytes = new Uint8Array(binary.length);
|
|
1576
|
+
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
|
|
1577
|
+
return bytes;
|
|
1578
|
+
}
|
|
1579
|
+
//#endregion
|
|
1580
|
+
//#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/util/base64url.js
|
|
1581
|
+
function decode(input) {
|
|
1582
|
+
if (Uint8Array.fromBase64) return Uint8Array.fromBase64(typeof input === "string" ? input : decoder.decode(input), { alphabet: "base64url" });
|
|
1583
|
+
let encoded = input;
|
|
1584
|
+
if (encoded instanceof Uint8Array) encoded = decoder.decode(encoded);
|
|
1585
|
+
encoded = encoded.replace(/-/g, "+").replace(/_/g, "/");
|
|
1586
|
+
try {
|
|
1587
|
+
return decodeBase64(encoded);
|
|
1588
|
+
} catch {
|
|
1589
|
+
throw new TypeError("The input to be decoded is not correctly encoded.");
|
|
1590
|
+
}
|
|
1591
|
+
}
|
|
1592
|
+
function encode(input) {
|
|
1593
|
+
let unencoded = input;
|
|
1594
|
+
if (typeof unencoded === "string") unencoded = encoder$1.encode(unencoded);
|
|
1595
|
+
if (Uint8Array.prototype.toBase64) return unencoded.toBase64({
|
|
1596
|
+
alphabet: "base64url",
|
|
1597
|
+
omitPadding: true
|
|
1598
|
+
});
|
|
1599
|
+
return encodeBase64(unencoded).replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
|
|
1600
|
+
}
|
|
1601
|
+
//#endregion
|
|
1602
|
+
//#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/lib/crypto_key.js
|
|
1603
|
+
const unusable = (name, prop = "algorithm.name") => new TypeError(`CryptoKey does not support this operation, its ${prop} must be ${name}`);
|
|
1604
|
+
const isAlgorithm = (algorithm, name) => algorithm.name === name;
|
|
1605
|
+
function getHashLength(hash) {
|
|
1606
|
+
return parseInt(hash.name.slice(4), 10);
|
|
1607
|
+
}
|
|
1608
|
+
function checkHashLength(algorithm, expected) {
|
|
1609
|
+
if (getHashLength(algorithm.hash) !== expected) throw unusable(`SHA-${expected}`, "algorithm.hash");
|
|
1610
|
+
}
|
|
1611
|
+
function getNamedCurve(alg) {
|
|
1612
|
+
switch (alg) {
|
|
1613
|
+
case "ES256": return "P-256";
|
|
1614
|
+
case "ES384": return "P-384";
|
|
1615
|
+
case "ES512": return "P-521";
|
|
1616
|
+
default: throw new Error("unreachable");
|
|
1617
|
+
}
|
|
1618
|
+
}
|
|
1619
|
+
function checkUsage(key, usage) {
|
|
1620
|
+
if (usage && !key.usages.includes(usage)) throw new TypeError(`CryptoKey does not support this operation, its usages must include ${usage}.`);
|
|
1621
|
+
}
|
|
1622
|
+
function checkSigCryptoKey(key, alg, usage) {
|
|
1623
|
+
switch (alg) {
|
|
1624
|
+
case "HS256":
|
|
1625
|
+
case "HS384":
|
|
1626
|
+
case "HS512":
|
|
1627
|
+
if (!isAlgorithm(key.algorithm, "HMAC")) throw unusable("HMAC");
|
|
1628
|
+
checkHashLength(key.algorithm, parseInt(alg.slice(2), 10));
|
|
1306
1629
|
break;
|
|
1307
|
-
case "
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
algorithm = {
|
|
1313
|
-
name: "RSA-PSS",
|
|
1314
|
-
hash: `SHA-${jwk.alg.slice(-3)}`
|
|
1315
|
-
};
|
|
1316
|
-
keyUsages = jwk.d ? ["sign"] : ["verify"];
|
|
1317
|
-
break;
|
|
1318
|
-
case "RS256":
|
|
1319
|
-
case "RS384":
|
|
1320
|
-
case "RS512":
|
|
1321
|
-
algorithm = {
|
|
1322
|
-
name: "RSASSA-PKCS1-v1_5",
|
|
1323
|
-
hash: `SHA-${jwk.alg.slice(-3)}`
|
|
1324
|
-
};
|
|
1325
|
-
keyUsages = jwk.d ? ["sign"] : ["verify"];
|
|
1326
|
-
break;
|
|
1327
|
-
case "RSA-OAEP":
|
|
1328
|
-
case "RSA-OAEP-256":
|
|
1329
|
-
case "RSA-OAEP-384":
|
|
1330
|
-
case "RSA-OAEP-512":
|
|
1331
|
-
algorithm = {
|
|
1332
|
-
name: "RSA-OAEP",
|
|
1333
|
-
hash: `SHA-${parseInt(jwk.alg.slice(-3), 10) || 1}`
|
|
1334
|
-
};
|
|
1335
|
-
keyUsages = jwk.d ? ["decrypt", "unwrapKey"] : ["encrypt", "wrapKey"];
|
|
1336
|
-
break;
|
|
1337
|
-
default: throw new JOSENotSupported(unsupportedAlg);
|
|
1338
|
-
}
|
|
1630
|
+
case "RS256":
|
|
1631
|
+
case "RS384":
|
|
1632
|
+
case "RS512":
|
|
1633
|
+
if (!isAlgorithm(key.algorithm, "RSASSA-PKCS1-v1_5")) throw unusable("RSASSA-PKCS1-v1_5");
|
|
1634
|
+
checkHashLength(key.algorithm, parseInt(alg.slice(2), 10));
|
|
1339
1635
|
break;
|
|
1340
|
-
case "
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
algorithm = {
|
|
1346
|
-
name: "ECDSA",
|
|
1347
|
-
namedCurve: {
|
|
1348
|
-
ES256: "P-256",
|
|
1349
|
-
ES384: "P-384",
|
|
1350
|
-
ES512: "P-521"
|
|
1351
|
-
}[jwk.alg]
|
|
1352
|
-
};
|
|
1353
|
-
keyUsages = jwk.d ? ["sign"] : ["verify"];
|
|
1354
|
-
break;
|
|
1355
|
-
case "ECDH-ES":
|
|
1356
|
-
case "ECDH-ES+A128KW":
|
|
1357
|
-
case "ECDH-ES+A192KW":
|
|
1358
|
-
case "ECDH-ES+A256KW":
|
|
1359
|
-
algorithm = {
|
|
1360
|
-
name: "ECDH",
|
|
1361
|
-
namedCurve: jwk.crv
|
|
1362
|
-
};
|
|
1363
|
-
keyUsages = jwk.d ? ["deriveBits"] : [];
|
|
1364
|
-
break;
|
|
1365
|
-
default: throw new JOSENotSupported(unsupportedAlg);
|
|
1366
|
-
}
|
|
1636
|
+
case "PS256":
|
|
1637
|
+
case "PS384":
|
|
1638
|
+
case "PS512":
|
|
1639
|
+
if (!isAlgorithm(key.algorithm, "RSA-PSS")) throw unusable("RSA-PSS");
|
|
1640
|
+
checkHashLength(key.algorithm, parseInt(alg.slice(2), 10));
|
|
1367
1641
|
break;
|
|
1368
|
-
case "
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
case "EdDSA":
|
|
1372
|
-
algorithm = { name: "Ed25519" };
|
|
1373
|
-
keyUsages = jwk.d ? ["sign"] : ["verify"];
|
|
1374
|
-
break;
|
|
1375
|
-
case "ECDH-ES":
|
|
1376
|
-
case "ECDH-ES+A128KW":
|
|
1377
|
-
case "ECDH-ES+A192KW":
|
|
1378
|
-
case "ECDH-ES+A256KW":
|
|
1379
|
-
algorithm = { name: jwk.crv };
|
|
1380
|
-
keyUsages = jwk.d ? ["deriveBits"] : [];
|
|
1381
|
-
break;
|
|
1382
|
-
default: throw new JOSENotSupported(unsupportedAlg);
|
|
1383
|
-
}
|
|
1642
|
+
case "Ed25519":
|
|
1643
|
+
case "EdDSA":
|
|
1644
|
+
if (!isAlgorithm(key.algorithm, "Ed25519")) throw unusable("Ed25519");
|
|
1384
1645
|
break;
|
|
1385
|
-
|
|
1646
|
+
case "ML-DSA-44":
|
|
1647
|
+
case "ML-DSA-65":
|
|
1648
|
+
case "ML-DSA-87":
|
|
1649
|
+
if (!isAlgorithm(key.algorithm, alg)) throw unusable(alg);
|
|
1650
|
+
break;
|
|
1651
|
+
case "ES256":
|
|
1652
|
+
case "ES384":
|
|
1653
|
+
case "ES512": {
|
|
1654
|
+
if (!isAlgorithm(key.algorithm, "ECDSA")) throw unusable("ECDSA");
|
|
1655
|
+
const expected = getNamedCurve(alg);
|
|
1656
|
+
if (key.algorithm.namedCurve !== expected) throw unusable(expected, "algorithm.namedCurve");
|
|
1657
|
+
break;
|
|
1658
|
+
}
|
|
1659
|
+
default: throw new TypeError("CryptoKey does not support this operation");
|
|
1386
1660
|
}
|
|
1387
|
-
|
|
1388
|
-
algorithm,
|
|
1389
|
-
keyUsages
|
|
1390
|
-
};
|
|
1391
|
-
}
|
|
1392
|
-
async function jwkToKey(jwk) {
|
|
1393
|
-
if (!jwk.alg) throw new TypeError("\"alg\" argument is required when \"jwk.alg\" is not present");
|
|
1394
|
-
const { algorithm, keyUsages } = subtleMapping(jwk);
|
|
1395
|
-
const keyData = { ...jwk };
|
|
1396
|
-
if (keyData.kty !== "AKP") delete keyData.alg;
|
|
1397
|
-
delete keyData.use;
|
|
1398
|
-
return crypto.subtle.importKey("jwk", keyData, algorithm, jwk.ext ?? (jwk.d || jwk.priv ? false : true), jwk.key_ops ?? keyUsages);
|
|
1661
|
+
checkUsage(key, usage);
|
|
1399
1662
|
}
|
|
1400
1663
|
//#endregion
|
|
1401
|
-
//#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/lib/
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
if (
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
if (!cached) cache.set(key, { [alg]: cryptoKey });
|
|
1414
|
-
else cached[alg] = cryptoKey;
|
|
1415
|
-
return cryptoKey;
|
|
1416
|
-
};
|
|
1417
|
-
const handleKeyObject = (keyObject, alg) => {
|
|
1418
|
-
cache ||= new WeakMap();
|
|
1419
|
-
let cached = cache.get(keyObject);
|
|
1420
|
-
if (cached?.[alg]) return cached[alg];
|
|
1421
|
-
const isPublic = keyObject.type === "public";
|
|
1422
|
-
const extractable = isPublic ? true : false;
|
|
1423
|
-
let cryptoKey;
|
|
1424
|
-
if (keyObject.asymmetricKeyType === "x25519") {
|
|
1425
|
-
switch (alg) {
|
|
1426
|
-
case "ECDH-ES":
|
|
1427
|
-
case "ECDH-ES+A128KW":
|
|
1428
|
-
case "ECDH-ES+A192KW":
|
|
1429
|
-
case "ECDH-ES+A256KW": break;
|
|
1430
|
-
default: throw new TypeError(unusableForAlg);
|
|
1431
|
-
}
|
|
1432
|
-
cryptoKey = keyObject.toCryptoKey(keyObject.asymmetricKeyType, extractable, isPublic ? [] : ["deriveBits"]);
|
|
1433
|
-
}
|
|
1434
|
-
if (keyObject.asymmetricKeyType === "ed25519") {
|
|
1435
|
-
if (alg !== "EdDSA" && alg !== "Ed25519") throw new TypeError(unusableForAlg);
|
|
1436
|
-
cryptoKey = keyObject.toCryptoKey(keyObject.asymmetricKeyType, extractable, [isPublic ? "verify" : "sign"]);
|
|
1664
|
+
//#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/lib/invalid_key_input.js
|
|
1665
|
+
function message(msg, actual, ...types) {
|
|
1666
|
+
types = types.filter(Boolean);
|
|
1667
|
+
if (types.length > 2) {
|
|
1668
|
+
const last = types.pop();
|
|
1669
|
+
msg += `one of type ${types.join(", ")}, or ${last}.`;
|
|
1670
|
+
} else if (types.length === 2) msg += `one of type ${types[0]} or ${types[1]}.`;
|
|
1671
|
+
else msg += `of type ${types[0]}.`;
|
|
1672
|
+
if (actual == null) msg += ` Received ${actual}`;
|
|
1673
|
+
else if (typeof actual === "function" && actual.name) msg += ` Received function ${actual.name}`;
|
|
1674
|
+
else if (typeof actual === "object" && actual != null) {
|
|
1675
|
+
if (actual.constructor?.name) msg += ` Received an instance of ${actual.constructor.name}`;
|
|
1437
1676
|
}
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1677
|
+
return msg;
|
|
1678
|
+
}
|
|
1679
|
+
const invalidKeyInput = (actual, ...types) => message("Key must be ", actual, ...types);
|
|
1680
|
+
const withAlg = (alg, actual, ...types) => message(`Key for the ${alg} algorithm must be `, actual, ...types);
|
|
1681
|
+
//#endregion
|
|
1682
|
+
//#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/util/errors.js
|
|
1683
|
+
var JOSEError = class extends Error {
|
|
1684
|
+
static code = "ERR_JOSE_GENERIC";
|
|
1685
|
+
code = "ERR_JOSE_GENERIC";
|
|
1686
|
+
constructor(message, options) {
|
|
1687
|
+
super(message, options);
|
|
1688
|
+
this.name = this.constructor.name;
|
|
1689
|
+
Error.captureStackTrace?.(this, this.constructor);
|
|
1444
1690
|
}
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
case "RS512":
|
|
1462
|
-
case "PS512":
|
|
1463
|
-
case "RSA-OAEP-512":
|
|
1464
|
-
hash = "SHA-512";
|
|
1465
|
-
break;
|
|
1466
|
-
default: throw new TypeError(unusableForAlg);
|
|
1467
|
-
}
|
|
1468
|
-
if (alg.startsWith("RSA-OAEP")) return keyObject.toCryptoKey({
|
|
1469
|
-
name: "RSA-OAEP",
|
|
1470
|
-
hash
|
|
1471
|
-
}, extractable, isPublic ? ["encrypt"] : ["decrypt"]);
|
|
1472
|
-
cryptoKey = keyObject.toCryptoKey({
|
|
1473
|
-
name: alg.startsWith("PS") ? "RSA-PSS" : "RSASSA-PKCS1-v1_5",
|
|
1474
|
-
hash
|
|
1475
|
-
}, extractable, [isPublic ? "verify" : "sign"]);
|
|
1476
|
-
}
|
|
1477
|
-
if (keyObject.asymmetricKeyType === "ec") {
|
|
1478
|
-
const namedCurve = new Map([
|
|
1479
|
-
["prime256v1", "P-256"],
|
|
1480
|
-
["secp384r1", "P-384"],
|
|
1481
|
-
["secp521r1", "P-521"]
|
|
1482
|
-
]).get(keyObject.asymmetricKeyDetails?.namedCurve);
|
|
1483
|
-
if (!namedCurve) throw new TypeError(unusableForAlg);
|
|
1484
|
-
const expectedCurve = {
|
|
1485
|
-
ES256: "P-256",
|
|
1486
|
-
ES384: "P-384",
|
|
1487
|
-
ES512: "P-521"
|
|
1488
|
-
};
|
|
1489
|
-
if (expectedCurve[alg] && namedCurve === expectedCurve[alg]) cryptoKey = keyObject.toCryptoKey({
|
|
1490
|
-
name: "ECDSA",
|
|
1491
|
-
namedCurve
|
|
1492
|
-
}, extractable, [isPublic ? "verify" : "sign"]);
|
|
1493
|
-
if (alg.startsWith("ECDH-ES")) cryptoKey = keyObject.toCryptoKey({
|
|
1494
|
-
name: "ECDH",
|
|
1495
|
-
namedCurve
|
|
1496
|
-
}, extractable, isPublic ? [] : ["deriveBits"]);
|
|
1691
|
+
};
|
|
1692
|
+
var JWTClaimValidationFailed = class extends JOSEError {
|
|
1693
|
+
static code = "ERR_JWT_CLAIM_VALIDATION_FAILED";
|
|
1694
|
+
code = "ERR_JWT_CLAIM_VALIDATION_FAILED";
|
|
1695
|
+
claim;
|
|
1696
|
+
reason;
|
|
1697
|
+
payload;
|
|
1698
|
+
constructor(message, payload, claim = "unspecified", reason = "unspecified") {
|
|
1699
|
+
super(message, { cause: {
|
|
1700
|
+
claim,
|
|
1701
|
+
reason,
|
|
1702
|
+
payload
|
|
1703
|
+
} });
|
|
1704
|
+
this.claim = claim;
|
|
1705
|
+
this.reason = reason;
|
|
1706
|
+
this.payload = payload;
|
|
1497
1707
|
}
|
|
1498
|
-
if (!cryptoKey) throw new TypeError(unusableForAlg);
|
|
1499
|
-
if (!cached) cache.set(keyObject, { [alg]: cryptoKey });
|
|
1500
|
-
else cached[alg] = cryptoKey;
|
|
1501
|
-
return cryptoKey;
|
|
1502
1708
|
};
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1709
|
+
var JWTExpired = class extends JOSEError {
|
|
1710
|
+
static code = "ERR_JWT_EXPIRED";
|
|
1711
|
+
code = "ERR_JWT_EXPIRED";
|
|
1712
|
+
claim;
|
|
1713
|
+
reason;
|
|
1714
|
+
payload;
|
|
1715
|
+
constructor(message, payload, claim = "unspecified", reason = "unspecified") {
|
|
1716
|
+
super(message, { cause: {
|
|
1717
|
+
claim,
|
|
1718
|
+
reason,
|
|
1719
|
+
payload
|
|
1720
|
+
} });
|
|
1721
|
+
this.claim = claim;
|
|
1722
|
+
this.reason = reason;
|
|
1723
|
+
this.payload = payload;
|
|
1515
1724
|
}
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1725
|
+
};
|
|
1726
|
+
var JOSEAlgNotAllowed = class extends JOSEError {
|
|
1727
|
+
static code = "ERR_JOSE_ALG_NOT_ALLOWED";
|
|
1728
|
+
code = "ERR_JOSE_ALG_NOT_ALLOWED";
|
|
1729
|
+
};
|
|
1730
|
+
var JOSENotSupported = class extends JOSEError {
|
|
1731
|
+
static code = "ERR_JOSE_NOT_SUPPORTED";
|
|
1732
|
+
code = "ERR_JOSE_NOT_SUPPORTED";
|
|
1733
|
+
};
|
|
1734
|
+
var JWSInvalid = class extends JOSEError {
|
|
1735
|
+
static code = "ERR_JWS_INVALID";
|
|
1736
|
+
code = "ERR_JWS_INVALID";
|
|
1737
|
+
};
|
|
1738
|
+
var JWTInvalid = class extends JOSEError {
|
|
1739
|
+
static code = "ERR_JWT_INVALID";
|
|
1740
|
+
code = "ERR_JWT_INVALID";
|
|
1741
|
+
};
|
|
1742
|
+
var JWKInvalid = class extends JOSEError {
|
|
1743
|
+
static code = "ERR_JWK_INVALID";
|
|
1744
|
+
code = "ERR_JWK_INVALID";
|
|
1745
|
+
};
|
|
1746
|
+
var JWSSignatureVerificationFailed = class extends JOSEError {
|
|
1747
|
+
static code = "ERR_JWS_SIGNATURE_VERIFICATION_FAILED";
|
|
1748
|
+
code = "ERR_JWS_SIGNATURE_VERIFICATION_FAILED";
|
|
1749
|
+
constructor(message = "signature verification failed", options) {
|
|
1750
|
+
super(message, options);
|
|
1519
1751
|
}
|
|
1520
|
-
|
|
1521
|
-
}
|
|
1752
|
+
};
|
|
1522
1753
|
//#endregion
|
|
1523
|
-
//#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/
|
|
1524
|
-
|
|
1525
|
-
if (
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
case "oct":
|
|
1531
|
-
if (typeof jwk.k !== "string" || !jwk.k) throw new TypeError("missing \"k\" (Key Value) Parameter value");
|
|
1532
|
-
return decode(jwk.k);
|
|
1533
|
-
case "RSA":
|
|
1534
|
-
if ("oth" in jwk && jwk.oth !== void 0) throw new JOSENotSupported("RSA JWK \"oth\" (Other Primes Info) Parameter value is not supported");
|
|
1535
|
-
return jwkToKey({
|
|
1536
|
-
...jwk,
|
|
1537
|
-
alg,
|
|
1538
|
-
ext
|
|
1539
|
-
});
|
|
1540
|
-
case "AKP":
|
|
1541
|
-
if (typeof jwk.alg !== "string" || !jwk.alg) throw new TypeError("missing \"alg\" (Algorithm) Parameter value");
|
|
1542
|
-
if (alg !== void 0 && alg !== jwk.alg) throw new TypeError("JWK alg and alg option value mismatch");
|
|
1543
|
-
return jwkToKey({
|
|
1544
|
-
...jwk,
|
|
1545
|
-
ext
|
|
1546
|
-
});
|
|
1547
|
-
case "EC":
|
|
1548
|
-
case "OKP": return jwkToKey({
|
|
1549
|
-
...jwk,
|
|
1550
|
-
alg,
|
|
1551
|
-
ext
|
|
1552
|
-
});
|
|
1553
|
-
default: throw new JOSENotSupported("Unsupported \"kty\" (Key Type) Parameter value");
|
|
1754
|
+
//#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/lib/is_key_like.js
|
|
1755
|
+
const isCryptoKey = (key) => {
|
|
1756
|
+
if (key?.[Symbol.toStringTag] === "CryptoKey") return true;
|
|
1757
|
+
try {
|
|
1758
|
+
return key instanceof CryptoKey;
|
|
1759
|
+
} catch {
|
|
1760
|
+
return false;
|
|
1554
1761
|
}
|
|
1555
|
-
}
|
|
1762
|
+
};
|
|
1763
|
+
const isKeyObject = (key) => key?.[Symbol.toStringTag] === "KeyObject";
|
|
1764
|
+
const isKeyLike = (key) => isCryptoKey(key) || isKeyObject(key);
|
|
1556
1765
|
//#endregion
|
|
1557
|
-
//#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/lib/
|
|
1558
|
-
function
|
|
1559
|
-
|
|
1766
|
+
//#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/lib/helpers.js
|
|
1767
|
+
function decodeBase64url(value, label, ErrorClass) {
|
|
1768
|
+
try {
|
|
1769
|
+
return decode(value);
|
|
1770
|
+
} catch {
|
|
1771
|
+
throw new ErrorClass(`Failed to base64url decode the ${label}`);
|
|
1772
|
+
}
|
|
1560
1773
|
}
|
|
1561
|
-
async function
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
if (key instanceof Uint8Array) return {
|
|
1565
|
-
kty: "oct",
|
|
1566
|
-
k: encode(key)
|
|
1567
|
-
};
|
|
1568
|
-
if (!isCryptoKey(key)) throw new TypeError(invalidKeyInput(key, "CryptoKey", "KeyObject", "Uint8Array"));
|
|
1569
|
-
if (!key.extractable) throw new TypeError("non-extractable CryptoKey cannot be exported as a JWK");
|
|
1570
|
-
const { ext, key_ops, alg, use, ...jwk } = omitUndefinedProperties(await crypto.subtle.exportKey("jwk", key));
|
|
1571
|
-
if (jwk.kty === "AKP") jwk.alg = alg;
|
|
1572
|
-
return jwk;
|
|
1774
|
+
async function digest(algorithm, data) {
|
|
1775
|
+
const subtleDigest = `SHA-${algorithm.slice(-3)}`;
|
|
1776
|
+
return new Uint8Array(await crypto.subtle.digest(subtleDigest, data));
|
|
1573
1777
|
}
|
|
1574
1778
|
//#endregion
|
|
1575
|
-
//#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/
|
|
1576
|
-
|
|
1577
|
-
|
|
1779
|
+
//#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/lib/type_checks.js
|
|
1780
|
+
const isObjectLike = (value) => typeof value === "object" && value !== null;
|
|
1781
|
+
function isObject(input) {
|
|
1782
|
+
if (!isObjectLike(input) || Object.prototype.toString.call(input) !== "[object Object]") return false;
|
|
1783
|
+
if (Object.getPrototypeOf(input) === null) return true;
|
|
1784
|
+
let proto = input;
|
|
1785
|
+
while (Object.getPrototypeOf(proto) !== null) proto = Object.getPrototypeOf(proto);
|
|
1786
|
+
return Object.getPrototypeOf(input) === proto;
|
|
1578
1787
|
}
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1788
|
+
function isDisjoint(...headers) {
|
|
1789
|
+
const sources = headers.filter(Boolean);
|
|
1790
|
+
if (sources.length === 0 || sources.length === 1) return true;
|
|
1791
|
+
let acc;
|
|
1792
|
+
for (const header of sources) {
|
|
1793
|
+
const parameters = Object.keys(header);
|
|
1794
|
+
if (!acc || acc.size === 0) {
|
|
1795
|
+
acc = new Set(parameters);
|
|
1796
|
+
continue;
|
|
1797
|
+
}
|
|
1798
|
+
for (const parameter of parameters) {
|
|
1799
|
+
if (acc.has(parameter)) return false;
|
|
1800
|
+
acc.add(parameter);
|
|
1801
|
+
}
|
|
1592
1802
|
}
|
|
1593
|
-
return
|
|
1803
|
+
return true;
|
|
1594
1804
|
}
|
|
1805
|
+
const isJWK = (key) => isObject(key) && typeof key.kty === "string";
|
|
1806
|
+
const isPrivateJWK = (key) => key.kty !== "oct" && (key.kty === "AKP" && typeof key.priv === "string" || typeof key.d === "string");
|
|
1807
|
+
const isPublicJWK = (key) => key.kty !== "oct" && key.d === void 0 && key.priv === void 0;
|
|
1808
|
+
const isSecretJWK = (key) => key.kty === "oct" && typeof key.k === "string";
|
|
1595
1809
|
//#endregion
|
|
1596
|
-
//#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/lib/
|
|
1597
|
-
function
|
|
1598
|
-
if (
|
|
1599
|
-
|
|
1600
|
-
|
|
1810
|
+
//#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/lib/signing.js
|
|
1811
|
+
function checkKeyLength(alg, key) {
|
|
1812
|
+
if (alg.startsWith("RS") || alg.startsWith("PS")) {
|
|
1813
|
+
const { modulusLength } = key.algorithm;
|
|
1814
|
+
if (typeof modulusLength !== "number" || modulusLength < 2048) throw new TypeError(`${alg} requires key modulusLength to be 2048 bits or larger`);
|
|
1815
|
+
}
|
|
1601
1816
|
}
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
}
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
expectedKeyOp = "wrapKey";
|
|
1638
|
-
break;
|
|
1639
|
-
case usage === "decrypt":
|
|
1640
|
-
expectedKeyOp = alg.startsWith("RSA") ? "unwrapKey" : "deriveBits";
|
|
1641
|
-
break;
|
|
1642
|
-
}
|
|
1643
|
-
if (expectedKeyOp && key.key_ops?.includes?.(expectedKeyOp) === false) throw new TypeError(`Invalid key for this operation, its "key_ops" must include "${expectedKeyOp}" when present`);
|
|
1644
|
-
}
|
|
1645
|
-
return true;
|
|
1646
|
-
};
|
|
1647
|
-
const symmetricTypeCheck = (alg, key, usage) => {
|
|
1648
|
-
if (key instanceof Uint8Array) return;
|
|
1649
|
-
if (isJWK(key)) {
|
|
1650
|
-
if (isSecretJWK(key) && jwkMatchesOp(alg, key, usage)) return;
|
|
1651
|
-
throw new TypeError(`JSON Web Key for symmetric algorithms must have JWK "kty" (Key Type) equal to "oct" and the JWK "k" (Key Value) present`);
|
|
1652
|
-
}
|
|
1653
|
-
if (!isKeyLike(key)) throw new TypeError(withAlg(alg, key, "CryptoKey", "KeyObject", "JSON Web Key", "Uint8Array"));
|
|
1654
|
-
if (key.type !== "secret") throw new TypeError(`${tag(key)} instances for symmetric algorithms must be of type "secret"`);
|
|
1655
|
-
};
|
|
1656
|
-
const asymmetricTypeCheck = (alg, key, usage) => {
|
|
1657
|
-
if (isJWK(key)) switch (usage) {
|
|
1658
|
-
case "decrypt":
|
|
1659
|
-
case "sign":
|
|
1660
|
-
if (isPrivateJWK(key) && jwkMatchesOp(alg, key, usage)) return;
|
|
1661
|
-
throw new TypeError(`JSON Web Key for this operation must be a private JWK`);
|
|
1662
|
-
case "encrypt":
|
|
1663
|
-
case "verify":
|
|
1664
|
-
if (isPublicJWK(key) && jwkMatchesOp(alg, key, usage)) return;
|
|
1665
|
-
throw new TypeError(`JSON Web Key for this operation must be a public JWK`);
|
|
1666
|
-
}
|
|
1667
|
-
if (!isKeyLike(key)) throw new TypeError(withAlg(alg, key, "CryptoKey", "KeyObject", "JSON Web Key"));
|
|
1668
|
-
if (key.type === "secret") throw new TypeError(`${tag(key)} instances for asymmetric algorithms must not be of type "secret"`);
|
|
1669
|
-
if (key.type === "public") switch (usage) {
|
|
1670
|
-
case "sign": throw new TypeError(`${tag(key)} instances for asymmetric algorithm signing must be of type "private"`);
|
|
1671
|
-
case "decrypt": throw new TypeError(`${tag(key)} instances for asymmetric algorithm decryption must be of type "private"`);
|
|
1672
|
-
}
|
|
1673
|
-
if (key.type === "private") switch (usage) {
|
|
1674
|
-
case "verify": throw new TypeError(`${tag(key)} instances for asymmetric algorithm verifying must be of type "public"`);
|
|
1675
|
-
case "encrypt": throw new TypeError(`${tag(key)} instances for asymmetric algorithm encryption must be of type "public"`);
|
|
1817
|
+
function subtleAlgorithm(alg, algorithm) {
|
|
1818
|
+
const hash = `SHA-${alg.slice(-3)}`;
|
|
1819
|
+
switch (alg) {
|
|
1820
|
+
case "HS256":
|
|
1821
|
+
case "HS384":
|
|
1822
|
+
case "HS512": return {
|
|
1823
|
+
hash,
|
|
1824
|
+
name: "HMAC"
|
|
1825
|
+
};
|
|
1826
|
+
case "PS256":
|
|
1827
|
+
case "PS384":
|
|
1828
|
+
case "PS512": return {
|
|
1829
|
+
hash,
|
|
1830
|
+
name: "RSA-PSS",
|
|
1831
|
+
saltLength: parseInt(alg.slice(-3), 10) >> 3
|
|
1832
|
+
};
|
|
1833
|
+
case "RS256":
|
|
1834
|
+
case "RS384":
|
|
1835
|
+
case "RS512": return {
|
|
1836
|
+
hash,
|
|
1837
|
+
name: "RSASSA-PKCS1-v1_5"
|
|
1838
|
+
};
|
|
1839
|
+
case "ES256":
|
|
1840
|
+
case "ES384":
|
|
1841
|
+
case "ES512": return {
|
|
1842
|
+
hash,
|
|
1843
|
+
name: "ECDSA",
|
|
1844
|
+
namedCurve: algorithm.namedCurve
|
|
1845
|
+
};
|
|
1846
|
+
case "Ed25519":
|
|
1847
|
+
case "EdDSA": return { name: "Ed25519" };
|
|
1848
|
+
case "ML-DSA-44":
|
|
1849
|
+
case "ML-DSA-65":
|
|
1850
|
+
case "ML-DSA-87": return { name: alg };
|
|
1851
|
+
default: throw new JOSENotSupported(`alg ${alg} is not supported either by JOSE or your javascript runtime`);
|
|
1676
1852
|
}
|
|
1677
|
-
}
|
|
1678
|
-
function
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
symmetricTypeCheck(alg, key, usage);
|
|
1686
|
-
break;
|
|
1687
|
-
default: asymmetricTypeCheck(alg, key, usage);
|
|
1853
|
+
}
|
|
1854
|
+
async function getSigKey(alg, key, usage) {
|
|
1855
|
+
if (key instanceof Uint8Array) {
|
|
1856
|
+
if (!alg.startsWith("HS")) throw new TypeError(invalidKeyInput(key, "CryptoKey", "KeyObject", "JSON Web Key"));
|
|
1857
|
+
return crypto.subtle.importKey("raw", key, {
|
|
1858
|
+
hash: `SHA-${alg.slice(-3)}`,
|
|
1859
|
+
name: "HMAC"
|
|
1860
|
+
}, false, [usage]);
|
|
1688
1861
|
}
|
|
1862
|
+
checkSigCryptoKey(key, alg, usage);
|
|
1863
|
+
return key;
|
|
1689
1864
|
}
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
if (jws.payload === void 0) throw new JWSInvalid("JWS Payload missing");
|
|
1697
|
-
if (typeof jws.signature !== "string") throw new JWSInvalid("JWS Signature missing or incorrect type");
|
|
1698
|
-
if (jws.header !== void 0 && !isObject(jws.header)) throw new JWSInvalid("JWS Unprotected Header incorrect type");
|
|
1699
|
-
let parsedProt = {};
|
|
1700
|
-
if (jws.protected) try {
|
|
1701
|
-
const protectedHeader = decode(jws.protected);
|
|
1702
|
-
parsedProt = JSON.parse(decoder.decode(protectedHeader));
|
|
1865
|
+
async function verify(alg, key, signature, data) {
|
|
1866
|
+
const cryptoKey = await getSigKey(alg, key, "verify");
|
|
1867
|
+
checkKeyLength(alg, cryptoKey);
|
|
1868
|
+
const algorithm = subtleAlgorithm(alg, cryptoKey.algorithm);
|
|
1869
|
+
try {
|
|
1870
|
+
return await crypto.subtle.verify(algorithm, cryptoKey, signature, data);
|
|
1703
1871
|
} catch {
|
|
1704
|
-
|
|
1705
|
-
}
|
|
1706
|
-
if (!isDisjoint(parsedProt, jws.header)) throw new JWSInvalid("JWS Protected and JWS Unprotected Header Parameter names must be disjoint");
|
|
1707
|
-
const joseHeader = {
|
|
1708
|
-
...parsedProt,
|
|
1709
|
-
...jws.header
|
|
1710
|
-
};
|
|
1711
|
-
const extensions = validateCrit(JWSInvalid, new Map([["b64", true]]), options?.crit, parsedProt, joseHeader);
|
|
1712
|
-
let b64 = true;
|
|
1713
|
-
if (extensions.has("b64")) {
|
|
1714
|
-
b64 = parsedProt.b64;
|
|
1715
|
-
if (typeof b64 !== "boolean") throw new JWSInvalid("The \"b64\" (base64url-encode payload) Header Parameter must be a boolean");
|
|
1716
|
-
}
|
|
1717
|
-
const { alg } = joseHeader;
|
|
1718
|
-
if (typeof alg !== "string" || !alg) throw new JWSInvalid("JWS \"alg\" (Algorithm) Header Parameter missing or invalid");
|
|
1719
|
-
const algorithms = options && validateAlgorithms("algorithms", options.algorithms);
|
|
1720
|
-
if (algorithms && !algorithms.has(alg)) throw new JOSEAlgNotAllowed("\"alg\" (Algorithm) Header Parameter value not allowed");
|
|
1721
|
-
if (b64) {
|
|
1722
|
-
if (typeof jws.payload !== "string") throw new JWSInvalid("JWS Payload must be a string");
|
|
1723
|
-
} else if (typeof jws.payload !== "string" && !(jws.payload instanceof Uint8Array)) throw new JWSInvalid("JWS Payload must be a string or an Uint8Array instance");
|
|
1724
|
-
let resolvedKey = false;
|
|
1725
|
-
if (typeof key === "function") {
|
|
1726
|
-
key = await key(parsedProt, jws);
|
|
1727
|
-
resolvedKey = true;
|
|
1872
|
+
return false;
|
|
1728
1873
|
}
|
|
1729
|
-
checkKeyType(alg, key, "verify");
|
|
1730
|
-
const data = concat(jws.protected !== void 0 ? encode$1(jws.protected) : new Uint8Array(), encode$1("."), typeof jws.payload === "string" ? b64 ? encode$1(jws.payload) : encoder$1.encode(jws.payload) : jws.payload);
|
|
1731
|
-
const signature = decodeBase64url(jws.signature, "signature", JWSInvalid);
|
|
1732
|
-
const k = await normalizeKey(key, alg);
|
|
1733
|
-
if (!await verify(alg, k, signature, data)) throw new JWSSignatureVerificationFailed();
|
|
1734
|
-
let payload;
|
|
1735
|
-
if (b64) payload = decodeBase64url(jws.payload, "payload", JWSInvalid);
|
|
1736
|
-
else if (typeof jws.payload === "string") payload = encoder$1.encode(jws.payload);
|
|
1737
|
-
else payload = jws.payload;
|
|
1738
|
-
const result = { payload };
|
|
1739
|
-
if (jws.protected !== void 0) result.protectedHeader = parsedProt;
|
|
1740
|
-
if (jws.header !== void 0) result.unprotectedHeader = jws.header;
|
|
1741
|
-
if (resolvedKey) return {
|
|
1742
|
-
...result,
|
|
1743
|
-
key: k
|
|
1744
|
-
};
|
|
1745
|
-
return result;
|
|
1746
|
-
}
|
|
1747
|
-
//#endregion
|
|
1748
|
-
//#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/jws/compact/verify.js
|
|
1749
|
-
async function compactVerify(jws, key, options) {
|
|
1750
|
-
if (jws instanceof Uint8Array) jws = decoder.decode(jws);
|
|
1751
|
-
if (typeof jws !== "string") throw new JWSInvalid("Compact JWS must be a string or Uint8Array");
|
|
1752
|
-
const { 0: protectedHeader, 1: payload, 2: signature, length } = jws.split(".");
|
|
1753
|
-
if (length !== 3) throw new JWSInvalid("Invalid Compact JWS");
|
|
1754
|
-
const verified = await flattenedVerify({
|
|
1755
|
-
payload,
|
|
1756
|
-
protected: protectedHeader,
|
|
1757
|
-
signature
|
|
1758
|
-
}, key, options);
|
|
1759
|
-
const result = {
|
|
1760
|
-
payload: verified.payload,
|
|
1761
|
-
protectedHeader: verified.protectedHeader
|
|
1762
|
-
};
|
|
1763
|
-
if (typeof key === "function") return {
|
|
1764
|
-
...result,
|
|
1765
|
-
key: verified.key
|
|
1766
|
-
};
|
|
1767
|
-
return result;
|
|
1768
1874
|
}
|
|
1769
1875
|
//#endregion
|
|
1770
|
-
//#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/lib/
|
|
1771
|
-
const
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
case "secs":
|
|
1787
|
-
case "second":
|
|
1788
|
-
case "seconds":
|
|
1789
|
-
case "s":
|
|
1790
|
-
numericDate = Math.round(value);
|
|
1791
|
-
break;
|
|
1792
|
-
case "minute":
|
|
1793
|
-
case "minutes":
|
|
1794
|
-
case "min":
|
|
1795
|
-
case "mins":
|
|
1796
|
-
case "m":
|
|
1797
|
-
numericDate = Math.round(value * minute);
|
|
1876
|
+
//#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/lib/jwk_to_key.js
|
|
1877
|
+
const unsupportedAlg = "Invalid or unsupported JWK \"alg\" (Algorithm) Parameter value";
|
|
1878
|
+
function subtleMapping(jwk) {
|
|
1879
|
+
let algorithm;
|
|
1880
|
+
let keyUsages;
|
|
1881
|
+
switch (jwk.kty) {
|
|
1882
|
+
case "AKP":
|
|
1883
|
+
switch (jwk.alg) {
|
|
1884
|
+
case "ML-DSA-44":
|
|
1885
|
+
case "ML-DSA-65":
|
|
1886
|
+
case "ML-DSA-87":
|
|
1887
|
+
algorithm = { name: jwk.alg };
|
|
1888
|
+
keyUsages = jwk.priv ? ["sign"] : ["verify"];
|
|
1889
|
+
break;
|
|
1890
|
+
default: throw new JOSENotSupported(unsupportedAlg);
|
|
1891
|
+
}
|
|
1798
1892
|
break;
|
|
1799
|
-
case "
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1893
|
+
case "RSA":
|
|
1894
|
+
switch (jwk.alg) {
|
|
1895
|
+
case "PS256":
|
|
1896
|
+
case "PS384":
|
|
1897
|
+
case "PS512":
|
|
1898
|
+
algorithm = {
|
|
1899
|
+
name: "RSA-PSS",
|
|
1900
|
+
hash: `SHA-${jwk.alg.slice(-3)}`
|
|
1901
|
+
};
|
|
1902
|
+
keyUsages = jwk.d ? ["sign"] : ["verify"];
|
|
1903
|
+
break;
|
|
1904
|
+
case "RS256":
|
|
1905
|
+
case "RS384":
|
|
1906
|
+
case "RS512":
|
|
1907
|
+
algorithm = {
|
|
1908
|
+
name: "RSASSA-PKCS1-v1_5",
|
|
1909
|
+
hash: `SHA-${jwk.alg.slice(-3)}`
|
|
1910
|
+
};
|
|
1911
|
+
keyUsages = jwk.d ? ["sign"] : ["verify"];
|
|
1912
|
+
break;
|
|
1913
|
+
case "RSA-OAEP":
|
|
1914
|
+
case "RSA-OAEP-256":
|
|
1915
|
+
case "RSA-OAEP-384":
|
|
1916
|
+
case "RSA-OAEP-512":
|
|
1917
|
+
algorithm = {
|
|
1918
|
+
name: "RSA-OAEP",
|
|
1919
|
+
hash: `SHA-${parseInt(jwk.alg.slice(-3), 10) || 1}`
|
|
1920
|
+
};
|
|
1921
|
+
keyUsages = jwk.d ? ["decrypt", "unwrapKey"] : ["encrypt", "wrapKey"];
|
|
1922
|
+
break;
|
|
1923
|
+
default: throw new JOSENotSupported(unsupportedAlg);
|
|
1924
|
+
}
|
|
1810
1925
|
break;
|
|
1811
|
-
case "
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1926
|
+
case "EC":
|
|
1927
|
+
switch (jwk.alg) {
|
|
1928
|
+
case "ES256":
|
|
1929
|
+
case "ES384":
|
|
1930
|
+
case "ES512":
|
|
1931
|
+
algorithm = {
|
|
1932
|
+
name: "ECDSA",
|
|
1933
|
+
namedCurve: {
|
|
1934
|
+
ES256: "P-256",
|
|
1935
|
+
ES384: "P-384",
|
|
1936
|
+
ES512: "P-521"
|
|
1937
|
+
}[jwk.alg]
|
|
1938
|
+
};
|
|
1939
|
+
keyUsages = jwk.d ? ["sign"] : ["verify"];
|
|
1940
|
+
break;
|
|
1941
|
+
case "ECDH-ES":
|
|
1942
|
+
case "ECDH-ES+A128KW":
|
|
1943
|
+
case "ECDH-ES+A192KW":
|
|
1944
|
+
case "ECDH-ES+A256KW":
|
|
1945
|
+
algorithm = {
|
|
1946
|
+
name: "ECDH",
|
|
1947
|
+
namedCurve: jwk.crv
|
|
1948
|
+
};
|
|
1949
|
+
keyUsages = jwk.d ? ["deriveBits"] : [];
|
|
1950
|
+
break;
|
|
1951
|
+
default: throw new JOSENotSupported(unsupportedAlg);
|
|
1952
|
+
}
|
|
1815
1953
|
break;
|
|
1816
|
-
|
|
1817
|
-
|
|
1954
|
+
case "OKP":
|
|
1955
|
+
switch (jwk.alg) {
|
|
1956
|
+
case "Ed25519":
|
|
1957
|
+
case "EdDSA":
|
|
1958
|
+
algorithm = { name: "Ed25519" };
|
|
1959
|
+
keyUsages = jwk.d ? ["sign"] : ["verify"];
|
|
1960
|
+
break;
|
|
1961
|
+
case "ECDH-ES":
|
|
1962
|
+
case "ECDH-ES+A128KW":
|
|
1963
|
+
case "ECDH-ES+A192KW":
|
|
1964
|
+
case "ECDH-ES+A256KW":
|
|
1965
|
+
algorithm = { name: jwk.crv };
|
|
1966
|
+
keyUsages = jwk.d ? ["deriveBits"] : [];
|
|
1967
|
+
break;
|
|
1968
|
+
default: throw new JOSENotSupported(unsupportedAlg);
|
|
1969
|
+
}
|
|
1818
1970
|
break;
|
|
1971
|
+
default: throw new JOSENotSupported("Invalid or unsupported JWK \"kty\" (Key Type) Parameter value");
|
|
1819
1972
|
}
|
|
1820
|
-
|
|
1821
|
-
|
|
1973
|
+
return {
|
|
1974
|
+
algorithm,
|
|
1975
|
+
keyUsages
|
|
1976
|
+
};
|
|
1822
1977
|
}
|
|
1823
|
-
|
|
1824
|
-
if (
|
|
1825
|
-
|
|
1826
|
-
};
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1978
|
+
async function jwkToKey(jwk) {
|
|
1979
|
+
if (!jwk.alg) throw new TypeError("\"alg\" argument is required when \"jwk.alg\" is not present");
|
|
1980
|
+
const { algorithm, keyUsages } = subtleMapping(jwk);
|
|
1981
|
+
const keyData = { ...jwk };
|
|
1982
|
+
if (keyData.kty !== "AKP") delete keyData.alg;
|
|
1983
|
+
delete keyData.use;
|
|
1984
|
+
return crypto.subtle.importKey("jwk", keyData, algorithm, jwk.ext ?? (jwk.d || jwk.priv ? false : true), jwk.key_ops ?? keyUsages);
|
|
1985
|
+
}
|
|
1986
|
+
//#endregion
|
|
1987
|
+
//#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/lib/normalize_key.js
|
|
1988
|
+
const unusableForAlg = "given KeyObject instance cannot be used for this algorithm";
|
|
1989
|
+
let cache;
|
|
1990
|
+
const handleJWK = async (key, jwk, alg, freeze = false) => {
|
|
1991
|
+
cache ||= new WeakMap();
|
|
1992
|
+
let cached = cache.get(key);
|
|
1993
|
+
if (cached?.[alg]) return cached[alg];
|
|
1994
|
+
const cryptoKey = await jwkToKey({
|
|
1995
|
+
...jwk,
|
|
1996
|
+
alg
|
|
1997
|
+
});
|
|
1998
|
+
if (freeze) Object.freeze(key);
|
|
1999
|
+
if (!cached) cache.set(key, { [alg]: cryptoKey });
|
|
2000
|
+
else cached[alg] = cryptoKey;
|
|
2001
|
+
return cryptoKey;
|
|
1831
2002
|
};
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
if (
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
if (subject && payload.sub !== subject) throw new JWTClaimValidationFailed("unexpected \"sub\" claim value", payload, "sub", "check_failed");
|
|
1849
|
-
if (audience && !checkAudiencePresence(payload.aud, typeof audience === "string" ? [audience] : audience)) throw new JWTClaimValidationFailed("unexpected \"aud\" claim value", payload, "aud", "check_failed");
|
|
1850
|
-
let tolerance;
|
|
1851
|
-
switch (typeof options.clockTolerance) {
|
|
1852
|
-
case "string":
|
|
1853
|
-
tolerance = secs(options.clockTolerance);
|
|
1854
|
-
break;
|
|
1855
|
-
case "number":
|
|
1856
|
-
tolerance = options.clockTolerance;
|
|
1857
|
-
break;
|
|
1858
|
-
case "undefined":
|
|
1859
|
-
tolerance = 0;
|
|
1860
|
-
break;
|
|
1861
|
-
default: throw new TypeError("Invalid clockTolerance option type");
|
|
2003
|
+
const handleKeyObject = (keyObject, alg) => {
|
|
2004
|
+
cache ||= new WeakMap();
|
|
2005
|
+
let cached = cache.get(keyObject);
|
|
2006
|
+
if (cached?.[alg]) return cached[alg];
|
|
2007
|
+
const isPublic = keyObject.type === "public";
|
|
2008
|
+
const extractable = isPublic ? true : false;
|
|
2009
|
+
let cryptoKey;
|
|
2010
|
+
if (keyObject.asymmetricKeyType === "x25519") {
|
|
2011
|
+
switch (alg) {
|
|
2012
|
+
case "ECDH-ES":
|
|
2013
|
+
case "ECDH-ES+A128KW":
|
|
2014
|
+
case "ECDH-ES+A192KW":
|
|
2015
|
+
case "ECDH-ES+A256KW": break;
|
|
2016
|
+
default: throw new TypeError(unusableForAlg);
|
|
2017
|
+
}
|
|
2018
|
+
cryptoKey = keyObject.toCryptoKey(keyObject.asymmetricKeyType, extractable, isPublic ? [] : ["deriveBits"]);
|
|
1862
2019
|
}
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
if (payload.nbf !== void 0) {
|
|
1867
|
-
if (typeof payload.nbf !== "number") throw new JWTClaimValidationFailed("\"nbf\" claim must be a number", payload, "nbf", "invalid");
|
|
1868
|
-
if (payload.nbf > now + tolerance) throw new JWTClaimValidationFailed("\"nbf\" claim timestamp check failed", payload, "nbf", "check_failed");
|
|
2020
|
+
if (keyObject.asymmetricKeyType === "ed25519") {
|
|
2021
|
+
if (alg !== "EdDSA" && alg !== "Ed25519") throw new TypeError(unusableForAlg);
|
|
2022
|
+
cryptoKey = keyObject.toCryptoKey(keyObject.asymmetricKeyType, extractable, [isPublic ? "verify" : "sign"]);
|
|
1869
2023
|
}
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
2024
|
+
switch (keyObject.asymmetricKeyType) {
|
|
2025
|
+
case "ml-dsa-44":
|
|
2026
|
+
case "ml-dsa-65":
|
|
2027
|
+
case "ml-dsa-87":
|
|
2028
|
+
if (alg !== keyObject.asymmetricKeyType.toUpperCase()) throw new TypeError(unusableForAlg);
|
|
2029
|
+
cryptoKey = keyObject.toCryptoKey(keyObject.asymmetricKeyType, extractable, [isPublic ? "verify" : "sign"]);
|
|
1873
2030
|
}
|
|
1874
|
-
if (
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
2031
|
+
if (keyObject.asymmetricKeyType === "rsa") {
|
|
2032
|
+
let hash;
|
|
2033
|
+
switch (alg) {
|
|
2034
|
+
case "RSA-OAEP":
|
|
2035
|
+
hash = "SHA-1";
|
|
2036
|
+
break;
|
|
2037
|
+
case "RS256":
|
|
2038
|
+
case "PS256":
|
|
2039
|
+
case "RSA-OAEP-256":
|
|
2040
|
+
hash = "SHA-256";
|
|
2041
|
+
break;
|
|
2042
|
+
case "RS384":
|
|
2043
|
+
case "PS384":
|
|
2044
|
+
case "RSA-OAEP-384":
|
|
2045
|
+
hash = "SHA-384";
|
|
2046
|
+
break;
|
|
2047
|
+
case "RS512":
|
|
2048
|
+
case "PS512":
|
|
2049
|
+
case "RSA-OAEP-512":
|
|
2050
|
+
hash = "SHA-512";
|
|
2051
|
+
break;
|
|
2052
|
+
default: throw new TypeError(unusableForAlg);
|
|
2053
|
+
}
|
|
2054
|
+
if (alg.startsWith("RSA-OAEP")) return keyObject.toCryptoKey({
|
|
2055
|
+
name: "RSA-OAEP",
|
|
2056
|
+
hash
|
|
2057
|
+
}, extractable, isPublic ? ["encrypt"] : ["decrypt"]);
|
|
2058
|
+
cryptoKey = keyObject.toCryptoKey({
|
|
2059
|
+
name: alg.startsWith("PS") ? "RSA-PSS" : "RSASSA-PKCS1-v1_5",
|
|
2060
|
+
hash
|
|
2061
|
+
}, extractable, [isPublic ? "verify" : "sign"]);
|
|
1879
2062
|
}
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
if (
|
|
1909
|
-
|
|
2063
|
+
if (keyObject.asymmetricKeyType === "ec") {
|
|
2064
|
+
const namedCurve = new Map([
|
|
2065
|
+
["prime256v1", "P-256"],
|
|
2066
|
+
["secp384r1", "P-384"],
|
|
2067
|
+
["secp521r1", "P-521"]
|
|
2068
|
+
]).get(keyObject.asymmetricKeyDetails?.namedCurve);
|
|
2069
|
+
if (!namedCurve) throw new TypeError(unusableForAlg);
|
|
2070
|
+
const expectedCurve = {
|
|
2071
|
+
ES256: "P-256",
|
|
2072
|
+
ES384: "P-384",
|
|
2073
|
+
ES512: "P-521"
|
|
2074
|
+
};
|
|
2075
|
+
if (expectedCurve[alg] && namedCurve === expectedCurve[alg]) cryptoKey = keyObject.toCryptoKey({
|
|
2076
|
+
name: "ECDSA",
|
|
2077
|
+
namedCurve
|
|
2078
|
+
}, extractable, [isPublic ? "verify" : "sign"]);
|
|
2079
|
+
if (alg.startsWith("ECDH-ES")) cryptoKey = keyObject.toCryptoKey({
|
|
2080
|
+
name: "ECDH",
|
|
2081
|
+
namedCurve
|
|
2082
|
+
}, extractable, isPublic ? [] : ["deriveBits"]);
|
|
2083
|
+
}
|
|
2084
|
+
if (!cryptoKey) throw new TypeError(unusableForAlg);
|
|
2085
|
+
if (!cached) cache.set(keyObject, { [alg]: cryptoKey });
|
|
2086
|
+
else cached[alg] = cryptoKey;
|
|
2087
|
+
return cryptoKey;
|
|
2088
|
+
};
|
|
2089
|
+
async function normalizeKey(key, alg) {
|
|
2090
|
+
if (key instanceof Uint8Array) return key;
|
|
2091
|
+
if (isCryptoKey(key)) return key;
|
|
2092
|
+
if (isKeyObject(key)) {
|
|
2093
|
+
if (key.type === "secret") return key.export();
|
|
2094
|
+
if ("toCryptoKey" in key && typeof key.toCryptoKey === "function") try {
|
|
2095
|
+
return handleKeyObject(key, alg);
|
|
2096
|
+
} catch (err) {
|
|
2097
|
+
if (err instanceof TypeError) throw err;
|
|
2098
|
+
}
|
|
2099
|
+
let jwk = key.export({ format: "jwk" });
|
|
2100
|
+
return handleJWK(key, jwk, alg);
|
|
2101
|
+
}
|
|
2102
|
+
if (isJWK(key)) {
|
|
2103
|
+
if (key.k) return decode(key.k);
|
|
2104
|
+
return handleJWK(key, key, alg, true);
|
|
2105
|
+
}
|
|
2106
|
+
throw new Error("unreachable");
|
|
2107
|
+
}
|
|
2108
|
+
//#endregion
|
|
2109
|
+
//#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/key/import.js
|
|
2110
|
+
async function importJWK(jwk, alg, options) {
|
|
2111
|
+
if (!isObject(jwk)) throw new TypeError("JWK must be an object");
|
|
2112
|
+
let ext;
|
|
2113
|
+
alg ??= jwk.alg;
|
|
2114
|
+
ext ??= options?.extractable ?? jwk.ext;
|
|
1910
2115
|
switch (jwk.kty) {
|
|
2116
|
+
case "oct":
|
|
2117
|
+
if (typeof jwk.k !== "string" || !jwk.k) throw new TypeError("missing \"k\" (Key Value) Parameter value");
|
|
2118
|
+
return decode(jwk.k);
|
|
2119
|
+
case "RSA":
|
|
2120
|
+
if ("oth" in jwk && jwk.oth !== void 0) throw new JOSENotSupported("RSA JWK \"oth\" (Other Primes Info) Parameter value is not supported");
|
|
2121
|
+
return jwkToKey({
|
|
2122
|
+
...jwk,
|
|
2123
|
+
alg,
|
|
2124
|
+
ext
|
|
2125
|
+
});
|
|
1911
2126
|
case "AKP":
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
};
|
|
1919
|
-
break;
|
|
2127
|
+
if (typeof jwk.alg !== "string" || !jwk.alg) throw new TypeError("missing \"alg\" (Algorithm) Parameter value");
|
|
2128
|
+
if (alg !== void 0 && alg !== jwk.alg) throw new TypeError("JWK alg and alg option value mismatch");
|
|
2129
|
+
return jwkToKey({
|
|
2130
|
+
...jwk,
|
|
2131
|
+
ext
|
|
2132
|
+
});
|
|
1920
2133
|
case "EC":
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
x: jwk.x,
|
|
1928
|
-
y: jwk.y
|
|
1929
|
-
};
|
|
1930
|
-
break;
|
|
1931
|
-
case "OKP":
|
|
1932
|
-
check(jwk.crv, "\"crv\" (Subtype of Key Pair) Parameter");
|
|
1933
|
-
check(jwk.x, "\"x\" (Public Key) Parameter");
|
|
1934
|
-
components = {
|
|
1935
|
-
crv: jwk.crv,
|
|
1936
|
-
kty: jwk.kty,
|
|
1937
|
-
x: jwk.x
|
|
1938
|
-
};
|
|
1939
|
-
break;
|
|
1940
|
-
case "RSA":
|
|
1941
|
-
check(jwk.e, "\"e\" (Exponent) Parameter");
|
|
1942
|
-
check(jwk.n, "\"n\" (Modulus) Parameter");
|
|
1943
|
-
components = {
|
|
1944
|
-
e: jwk.e,
|
|
1945
|
-
kty: jwk.kty,
|
|
1946
|
-
n: jwk.n
|
|
1947
|
-
};
|
|
1948
|
-
break;
|
|
1949
|
-
case "oct":
|
|
1950
|
-
check(jwk.k, "\"k\" (Key Value) Parameter");
|
|
1951
|
-
components = {
|
|
1952
|
-
k: jwk.k,
|
|
1953
|
-
kty: jwk.kty
|
|
1954
|
-
};
|
|
1955
|
-
break;
|
|
1956
|
-
default: throw new JOSENotSupported("\"kty\" (Key Type) Parameter missing or unsupported");
|
|
2134
|
+
case "OKP": return jwkToKey({
|
|
2135
|
+
...jwk,
|
|
2136
|
+
alg,
|
|
2137
|
+
ext
|
|
2138
|
+
});
|
|
2139
|
+
default: throw new JOSENotSupported("Unsupported \"kty\" (Key Type) Parameter value");
|
|
1957
2140
|
}
|
|
1958
|
-
const data = encode$1(JSON.stringify(components));
|
|
1959
|
-
return encode(await digest(digestAlgorithm, data));
|
|
1960
2141
|
}
|
|
1961
2142
|
//#endregion
|
|
1962
|
-
//#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/
|
|
1963
|
-
function
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
}
|
|
1976
|
-
|
|
1977
|
-
|
|
2143
|
+
//#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/lib/key_to_jwk.js
|
|
2144
|
+
function omitUndefinedProperties(jwk) {
|
|
2145
|
+
return Object.fromEntries(Object.entries(jwk).filter(([, value]) => value !== void 0));
|
|
2146
|
+
}
|
|
2147
|
+
async function keyToJWK(key) {
|
|
2148
|
+
if (isKeyObject(key)) if (key.type === "secret") key = key.export();
|
|
2149
|
+
else return key.export({ format: "jwk" });
|
|
2150
|
+
if (key instanceof Uint8Array) return {
|
|
2151
|
+
kty: "oct",
|
|
2152
|
+
k: encode(key)
|
|
2153
|
+
};
|
|
2154
|
+
if (!isCryptoKey(key)) throw new TypeError(invalidKeyInput(key, "CryptoKey", "KeyObject", "Uint8Array"));
|
|
2155
|
+
if (!key.extractable) throw new TypeError("non-extractable CryptoKey cannot be exported as a JWK");
|
|
2156
|
+
const { ext, key_ops, alg, use, ...jwk } = omitUndefinedProperties(await crypto.subtle.exportKey("jwk", key));
|
|
2157
|
+
if (jwk.kty === "AKP") jwk.alg = alg;
|
|
2158
|
+
return jwk;
|
|
1978
2159
|
}
|
|
1979
2160
|
//#endregion
|
|
1980
|
-
//#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/
|
|
1981
|
-
function
|
|
1982
|
-
|
|
1983
|
-
const { 1: payload, length } = jwt.split(".");
|
|
1984
|
-
if (length === 5) throw new JWTInvalid("Only JWTs using Compact JWS serialization can be decoded");
|
|
1985
|
-
if (length !== 3) throw new JWTInvalid("Invalid JWT");
|
|
1986
|
-
if (!payload) throw new JWTInvalid("JWTs must contain a payload");
|
|
1987
|
-
let decoded;
|
|
1988
|
-
try {
|
|
1989
|
-
decoded = decode(payload);
|
|
1990
|
-
} catch {
|
|
1991
|
-
throw new JWTInvalid("Failed to base64url decode the payload");
|
|
1992
|
-
}
|
|
1993
|
-
let result;
|
|
1994
|
-
try {
|
|
1995
|
-
result = JSON.parse(decoder.decode(decoded));
|
|
1996
|
-
} catch {
|
|
1997
|
-
throw new JWTInvalid("Failed to parse the decoded payload as JSON");
|
|
1998
|
-
}
|
|
1999
|
-
if (!isObject(result)) throw new JWTInvalid("Invalid JWT Claims Set");
|
|
2000
|
-
return result;
|
|
2161
|
+
//#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/key/export.js
|
|
2162
|
+
async function exportJWK(key) {
|
|
2163
|
+
return keyToJWK(key);
|
|
2001
2164
|
}
|
|
2002
2165
|
//#endregion
|
|
2003
|
-
//#region ../../node_modules/.pnpm/
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2166
|
+
//#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/lib/validate_crit.js
|
|
2167
|
+
function validateCrit(Err, recognizedDefault, recognizedOption, protectedHeader, joseHeader) {
|
|
2168
|
+
if (joseHeader.crit !== void 0 && protectedHeader?.crit === void 0) throw new Err("\"crit\" (Critical) Header Parameter MUST be integrity protected");
|
|
2169
|
+
if (!protectedHeader || protectedHeader.crit === void 0) return new Set();
|
|
2170
|
+
if (!Array.isArray(protectedHeader.crit) || protectedHeader.crit.length === 0 || protectedHeader.crit.some((input) => typeof input !== "string" || input.length === 0)) throw new Err("\"crit\" (Critical) Header Parameter MUST be an array of non-empty strings when present");
|
|
2171
|
+
let recognized;
|
|
2172
|
+
if (recognizedOption !== void 0) recognized = new Map([...Object.entries(recognizedOption), ...recognizedDefault.entries()]);
|
|
2173
|
+
else recognized = recognizedDefault;
|
|
2174
|
+
for (const parameter of protectedHeader.crit) {
|
|
2175
|
+
if (!recognized.has(parameter)) throw new JOSENotSupported(`Extension Header Parameter "${parameter}" is not recognized`);
|
|
2176
|
+
if (joseHeader[parameter] === void 0) throw new Err(`Extension Header Parameter "${parameter}" is missing`);
|
|
2177
|
+
if (recognized.get(parameter) && protectedHeader[parameter] === void 0) throw new Err(`Extension Header Parameter "${parameter}" MUST be integrity protected`);
|
|
2011
2178
|
}
|
|
2012
|
-
return
|
|
2013
|
-
}
|
|
2014
|
-
function warnKeyDropped(key) {
|
|
2015
|
-
console.warn(`[destr] Dropping "${key}" key to prevent prototype pollution.`);
|
|
2179
|
+
return new Set(protectedHeader.crit);
|
|
2016
2180
|
}
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
if (
|
|
2022
|
-
|
|
2023
|
-
case "false": return false;
|
|
2024
|
-
case "undefined": return;
|
|
2025
|
-
case "null": return null;
|
|
2026
|
-
case "nan": return NaN;
|
|
2027
|
-
case "infinity": return Number.POSITIVE_INFINITY;
|
|
2028
|
-
case "-infinity": return Number.NEGATIVE_INFINITY;
|
|
2029
|
-
}
|
|
2030
|
-
if (!JsonSigRx.test(value)) {
|
|
2031
|
-
if (options.strict) throw new SyntaxError("[destr] Invalid JSON");
|
|
2032
|
-
return value;
|
|
2033
|
-
}
|
|
2034
|
-
try {
|
|
2035
|
-
if (suspectProtoRx.test(value) || suspectConstructorRx.test(value)) {
|
|
2036
|
-
if (options.strict) throw new Error("[destr] Possible prototype pollution");
|
|
2037
|
-
return JSON.parse(value, jsonParseTransform);
|
|
2038
|
-
}
|
|
2039
|
-
return JSON.parse(value);
|
|
2040
|
-
} catch (error) {
|
|
2041
|
-
if (options.strict) throw error;
|
|
2042
|
-
return value;
|
|
2043
|
-
}
|
|
2181
|
+
//#endregion
|
|
2182
|
+
//#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/lib/validate_algorithms.js
|
|
2183
|
+
function validateAlgorithms(option, algorithms) {
|
|
2184
|
+
if (algorithms !== void 0 && (!Array.isArray(algorithms) || algorithms.some((s) => typeof s !== "string"))) throw new TypeError(`"${option}" option must be an array of strings`);
|
|
2185
|
+
if (!algorithms) return;
|
|
2186
|
+
return new Set(algorithms);
|
|
2044
2187
|
}
|
|
2045
2188
|
//#endregion
|
|
2046
|
-
//#region ../../node_modules/.pnpm/
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2189
|
+
//#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/lib/check_key_type.js
|
|
2190
|
+
const tag = (key) => key?.[Symbol.toStringTag];
|
|
2191
|
+
const jwkMatchesOp = (alg, key, usage) => {
|
|
2192
|
+
if (key.use !== void 0) {
|
|
2193
|
+
let expected;
|
|
2194
|
+
switch (usage) {
|
|
2195
|
+
case "sign":
|
|
2196
|
+
case "verify":
|
|
2197
|
+
expected = "sig";
|
|
2198
|
+
break;
|
|
2199
|
+
case "encrypt":
|
|
2200
|
+
case "decrypt":
|
|
2201
|
+
expected = "enc";
|
|
2202
|
+
break;
|
|
2203
|
+
}
|
|
2204
|
+
if (key.use !== expected) throw new TypeError(`Invalid key for this operation, its "use" must be "${expected}" when present`);
|
|
2052
2205
|
}
|
|
2206
|
+
if (key.alg !== void 0 && key.alg !== alg) throw new TypeError(`Invalid key for this operation, its "alg" must be "${alg}" when present`);
|
|
2207
|
+
if (Array.isArray(key.key_ops)) {
|
|
2208
|
+
let expectedKeyOp;
|
|
2209
|
+
switch (true) {
|
|
2210
|
+
case usage === "sign" || usage === "verify":
|
|
2211
|
+
case alg === "dir":
|
|
2212
|
+
case alg.includes("CBC-HS"):
|
|
2213
|
+
expectedKeyOp = usage;
|
|
2214
|
+
break;
|
|
2215
|
+
case alg.startsWith("PBES2"):
|
|
2216
|
+
expectedKeyOp = "deriveBits";
|
|
2217
|
+
break;
|
|
2218
|
+
case /^A\d{3}(?:GCM)?(?:KW)?$/.test(alg):
|
|
2219
|
+
if (!alg.includes("GCM") && alg.endsWith("KW")) expectedKeyOp = usage === "encrypt" ? "wrapKey" : "unwrapKey";
|
|
2220
|
+
else expectedKeyOp = usage;
|
|
2221
|
+
break;
|
|
2222
|
+
case usage === "encrypt" && alg.startsWith("RSA"):
|
|
2223
|
+
expectedKeyOp = "wrapKey";
|
|
2224
|
+
break;
|
|
2225
|
+
case usage === "decrypt":
|
|
2226
|
+
expectedKeyOp = alg.startsWith("RSA") ? "unwrapKey" : "deriveBits";
|
|
2227
|
+
break;
|
|
2228
|
+
}
|
|
2229
|
+
if (expectedKeyOp && key.key_ops?.includes?.(expectedKeyOp) === false) throw new TypeError(`Invalid key for this operation, its "key_ops" must include "${expectedKeyOp}" when present`);
|
|
2230
|
+
}
|
|
2231
|
+
return true;
|
|
2053
2232
|
};
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
"
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
}
|
|
2096
|
-
const textTypes = new Set([
|
|
2097
|
-
"image/svg",
|
|
2098
|
-
"application/xml",
|
|
2099
|
-
"application/xhtml",
|
|
2100
|
-
"application/html"
|
|
2101
|
-
]);
|
|
2102
|
-
const JSON_RE = /^application\/(?:[\w!#$%&*.^`~-]*\+)?json(;.+)?$/i;
|
|
2103
|
-
function detectResponseType(_contentType = "") {
|
|
2104
|
-
if (!_contentType) return "json";
|
|
2105
|
-
const contentType = _contentType.split(";").shift() || "";
|
|
2106
|
-
if (JSON_RE.test(contentType)) return "json";
|
|
2107
|
-
if (contentType === "text/event-stream") return "stream";
|
|
2108
|
-
if (textTypes.has(contentType) || contentType.startsWith("text/")) return "text";
|
|
2109
|
-
return "blob";
|
|
2233
|
+
const symmetricTypeCheck = (alg, key, usage) => {
|
|
2234
|
+
if (key instanceof Uint8Array) return;
|
|
2235
|
+
if (isJWK(key)) {
|
|
2236
|
+
if (isSecretJWK(key) && jwkMatchesOp(alg, key, usage)) return;
|
|
2237
|
+
throw new TypeError(`JSON Web Key for symmetric algorithms must have JWK "kty" (Key Type) equal to "oct" and the JWK "k" (Key Value) present`);
|
|
2238
|
+
}
|
|
2239
|
+
if (!isKeyLike(key)) throw new TypeError(withAlg(alg, key, "CryptoKey", "KeyObject", "JSON Web Key", "Uint8Array"));
|
|
2240
|
+
if (key.type !== "secret") throw new TypeError(`${tag(key)} instances for symmetric algorithms must be of type "secret"`);
|
|
2241
|
+
};
|
|
2242
|
+
const asymmetricTypeCheck = (alg, key, usage) => {
|
|
2243
|
+
if (isJWK(key)) switch (usage) {
|
|
2244
|
+
case "decrypt":
|
|
2245
|
+
case "sign":
|
|
2246
|
+
if (isPrivateJWK(key) && jwkMatchesOp(alg, key, usage)) return;
|
|
2247
|
+
throw new TypeError(`JSON Web Key for this operation must be a private JWK`);
|
|
2248
|
+
case "encrypt":
|
|
2249
|
+
case "verify":
|
|
2250
|
+
if (isPublicJWK(key) && jwkMatchesOp(alg, key, usage)) return;
|
|
2251
|
+
throw new TypeError(`JSON Web Key for this operation must be a public JWK`);
|
|
2252
|
+
}
|
|
2253
|
+
if (!isKeyLike(key)) throw new TypeError(withAlg(alg, key, "CryptoKey", "KeyObject", "JSON Web Key"));
|
|
2254
|
+
if (key.type === "secret") throw new TypeError(`${tag(key)} instances for asymmetric algorithms must not be of type "secret"`);
|
|
2255
|
+
if (key.type === "public") switch (usage) {
|
|
2256
|
+
case "sign": throw new TypeError(`${tag(key)} instances for asymmetric algorithm signing must be of type "private"`);
|
|
2257
|
+
case "decrypt": throw new TypeError(`${tag(key)} instances for asymmetric algorithm decryption must be of type "private"`);
|
|
2258
|
+
}
|
|
2259
|
+
if (key.type === "private") switch (usage) {
|
|
2260
|
+
case "verify": throw new TypeError(`${tag(key)} instances for asymmetric algorithm verifying must be of type "public"`);
|
|
2261
|
+
case "encrypt": throw new TypeError(`${tag(key)} instances for asymmetric algorithm encryption must be of type "public"`);
|
|
2262
|
+
}
|
|
2263
|
+
};
|
|
2264
|
+
function checkKeyType(alg, key, usage) {
|
|
2265
|
+
switch (alg.substring(0, 2)) {
|
|
2266
|
+
case "A1":
|
|
2267
|
+
case "A2":
|
|
2268
|
+
case "di":
|
|
2269
|
+
case "HS":
|
|
2270
|
+
case "PB":
|
|
2271
|
+
symmetricTypeCheck(alg, key, usage);
|
|
2272
|
+
break;
|
|
2273
|
+
default: asymmetricTypeCheck(alg, key, usage);
|
|
2274
|
+
}
|
|
2110
2275
|
}
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
if (
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2276
|
+
//#endregion
|
|
2277
|
+
//#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/jws/flattened/verify.js
|
|
2278
|
+
async function flattenedVerify(jws, key, options) {
|
|
2279
|
+
if (!isObject(jws)) throw new JWSInvalid("Flattened JWS must be an object");
|
|
2280
|
+
if (jws.protected === void 0 && jws.header === void 0) throw new JWSInvalid("Flattened JWS must have either of the \"protected\" or \"header\" members");
|
|
2281
|
+
if (jws.protected !== void 0 && typeof jws.protected !== "string") throw new JWSInvalid("JWS Protected Header incorrect type");
|
|
2282
|
+
if (jws.payload === void 0) throw new JWSInvalid("JWS Payload missing");
|
|
2283
|
+
if (typeof jws.signature !== "string") throw new JWSInvalid("JWS Signature missing or incorrect type");
|
|
2284
|
+
if (jws.header !== void 0 && !isObject(jws.header)) throw new JWSInvalid("JWS Unprotected Header incorrect type");
|
|
2285
|
+
let parsedProt = {};
|
|
2286
|
+
if (jws.protected) try {
|
|
2287
|
+
const protectedHeader = decode(jws.protected);
|
|
2288
|
+
parsedProt = JSON.parse(decoder.decode(protectedHeader));
|
|
2289
|
+
} catch {
|
|
2290
|
+
throw new JWSInvalid("JWS Protected Header is invalid");
|
|
2291
|
+
}
|
|
2292
|
+
if (!isDisjoint(parsedProt, jws.header)) throw new JWSInvalid("JWS Protected and JWS Unprotected Header Parameter names must be disjoint");
|
|
2293
|
+
const joseHeader = {
|
|
2294
|
+
...parsedProt,
|
|
2295
|
+
...jws.header
|
|
2119
2296
|
};
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2297
|
+
const extensions = validateCrit(JWSInvalid, new Map([["b64", true]]), options?.crit, parsedProt, joseHeader);
|
|
2298
|
+
let b64 = true;
|
|
2299
|
+
if (extensions.has("b64")) {
|
|
2300
|
+
b64 = parsedProt.b64;
|
|
2301
|
+
if (typeof b64 !== "boolean") throw new JWSInvalid("The \"b64\" (base64url-encode payload) Header Parameter must be a boolean");
|
|
2302
|
+
}
|
|
2303
|
+
const { alg } = joseHeader;
|
|
2304
|
+
if (typeof alg !== "string" || !alg) throw new JWSInvalid("JWS \"alg\" (Algorithm) Header Parameter missing or invalid");
|
|
2305
|
+
const algorithms = options && validateAlgorithms("algorithms", options.algorithms);
|
|
2306
|
+
if (algorithms && !algorithms.has(alg)) throw new JOSEAlgNotAllowed("\"alg\" (Algorithm) Header Parameter value not allowed");
|
|
2307
|
+
if (b64) {
|
|
2308
|
+
if (typeof jws.payload !== "string") throw new JWSInvalid("JWS Payload must be a string");
|
|
2309
|
+
} else if (typeof jws.payload !== "string" && !(jws.payload instanceof Uint8Array)) throw new JWSInvalid("JWS Payload must be a string or an Uint8Array instance");
|
|
2310
|
+
let resolvedKey = false;
|
|
2311
|
+
if (typeof key === "function") {
|
|
2312
|
+
key = await key(parsedProt, jws);
|
|
2313
|
+
resolvedKey = true;
|
|
2314
|
+
}
|
|
2315
|
+
checkKeyType(alg, key, "verify");
|
|
2316
|
+
const data = concat(jws.protected !== void 0 ? encode$1(jws.protected) : new Uint8Array(), encode$1("."), typeof jws.payload === "string" ? b64 ? encode$1(jws.payload) : encoder$1.encode(jws.payload) : jws.payload);
|
|
2317
|
+
const signature = decodeBase64url(jws.signature, "signature", JWSInvalid);
|
|
2318
|
+
const k = await normalizeKey(key, alg);
|
|
2319
|
+
if (!await verify(alg, k, signature, data)) throw new JWSSignatureVerificationFailed();
|
|
2320
|
+
let payload;
|
|
2321
|
+
if (b64) payload = decodeBase64url(jws.payload, "payload", JWSInvalid);
|
|
2322
|
+
else if (typeof jws.payload === "string") payload = encoder$1.encode(jws.payload);
|
|
2323
|
+
else payload = jws.payload;
|
|
2324
|
+
const result = { payload };
|
|
2325
|
+
if (jws.protected !== void 0) result.protectedHeader = parsedProt;
|
|
2326
|
+
if (jws.header !== void 0) result.unprotectedHeader = jws.header;
|
|
2327
|
+
if (resolvedKey) return {
|
|
2328
|
+
...result,
|
|
2329
|
+
key: k
|
|
2126
2330
|
};
|
|
2331
|
+
return result;
|
|
2127
2332
|
}
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
if (
|
|
2132
|
-
|
|
2133
|
-
}
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2333
|
+
//#endregion
|
|
2334
|
+
//#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/jws/compact/verify.js
|
|
2335
|
+
async function compactVerify(jws, key, options) {
|
|
2336
|
+
if (jws instanceof Uint8Array) jws = decoder.decode(jws);
|
|
2337
|
+
if (typeof jws !== "string") throw new JWSInvalid("Compact JWS must be a string or Uint8Array");
|
|
2338
|
+
const { 0: protectedHeader, 1: payload, 2: signature, length } = jws.split(".");
|
|
2339
|
+
if (length !== 3) throw new JWSInvalid("Invalid Compact JWS");
|
|
2340
|
+
const verified = await flattenedVerify({
|
|
2341
|
+
payload,
|
|
2342
|
+
protected: protectedHeader,
|
|
2343
|
+
signature
|
|
2344
|
+
}, key, options);
|
|
2345
|
+
const result = {
|
|
2346
|
+
payload: verified.payload,
|
|
2347
|
+
protectedHeader: verified.protectedHeader
|
|
2348
|
+
};
|
|
2349
|
+
if (typeof key === "function") return {
|
|
2350
|
+
...result,
|
|
2351
|
+
key: verified.key
|
|
2352
|
+
};
|
|
2353
|
+
return result;
|
|
2137
2354
|
}
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
const
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2355
|
+
//#endregion
|
|
2356
|
+
//#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/lib/jwt_claims_set.js
|
|
2357
|
+
const epoch = (date) => Math.floor(date.getTime() / 1e3);
|
|
2358
|
+
const minute = 60;
|
|
2359
|
+
const hour = minute * 60;
|
|
2360
|
+
const day = hour * 24;
|
|
2361
|
+
const week = day * 7;
|
|
2362
|
+
const year = day * 365.25;
|
|
2363
|
+
const REGEX = /^(\+|\-)? ?(\d+|\d+\.\d+) ?(seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)(?: (ago|from now))?$/i;
|
|
2364
|
+
function secs(str) {
|
|
2365
|
+
const matched = REGEX.exec(str);
|
|
2366
|
+
if (!matched || matched[4] && matched[1]) throw new TypeError("Invalid time period format");
|
|
2367
|
+
const value = parseFloat(matched[2]);
|
|
2368
|
+
const unit = matched[3].toLowerCase();
|
|
2369
|
+
let numericDate;
|
|
2370
|
+
switch (unit) {
|
|
2371
|
+
case "sec":
|
|
2372
|
+
case "secs":
|
|
2373
|
+
case "second":
|
|
2374
|
+
case "seconds":
|
|
2375
|
+
case "s":
|
|
2376
|
+
numericDate = Math.round(value);
|
|
2377
|
+
break;
|
|
2378
|
+
case "minute":
|
|
2379
|
+
case "minutes":
|
|
2380
|
+
case "min":
|
|
2381
|
+
case "mins":
|
|
2382
|
+
case "m":
|
|
2383
|
+
numericDate = Math.round(value * minute);
|
|
2384
|
+
break;
|
|
2385
|
+
case "hour":
|
|
2386
|
+
case "hours":
|
|
2387
|
+
case "hr":
|
|
2388
|
+
case "hrs":
|
|
2389
|
+
case "h":
|
|
2390
|
+
numericDate = Math.round(value * hour);
|
|
2391
|
+
break;
|
|
2392
|
+
case "day":
|
|
2393
|
+
case "days":
|
|
2394
|
+
case "d":
|
|
2395
|
+
numericDate = Math.round(value * day);
|
|
2396
|
+
break;
|
|
2397
|
+
case "week":
|
|
2398
|
+
case "weeks":
|
|
2399
|
+
case "w":
|
|
2400
|
+
numericDate = Math.round(value * week);
|
|
2401
|
+
break;
|
|
2402
|
+
default:
|
|
2403
|
+
numericDate = Math.round(value * year);
|
|
2404
|
+
break;
|
|
2405
|
+
}
|
|
2406
|
+
if (matched[1] === "-" || matched[4] === "ago") return -numericDate;
|
|
2407
|
+
return numericDate;
|
|
2408
|
+
}
|
|
2409
|
+
const normalizeTyp = (value) => {
|
|
2410
|
+
if (value.includes("/")) return value.toLowerCase();
|
|
2411
|
+
return `application/${value.toLowerCase()}`;
|
|
2412
|
+
};
|
|
2413
|
+
const checkAudiencePresence = (audPayload, audOption) => {
|
|
2414
|
+
if (typeof audPayload === "string") return audOption.includes(audPayload);
|
|
2415
|
+
if (Array.isArray(audPayload)) return audOption.some(Set.prototype.has.bind(new Set(audPayload)));
|
|
2416
|
+
return false;
|
|
2417
|
+
};
|
|
2418
|
+
function validateClaimsSet(protectedHeader, encodedPayload, options = {}) {
|
|
2419
|
+
let payload;
|
|
2420
|
+
try {
|
|
2421
|
+
payload = JSON.parse(decoder.decode(encodedPayload));
|
|
2422
|
+
} catch {}
|
|
2423
|
+
if (!isObject(payload)) throw new JWTInvalid("JWT Claims Set must be a top-level JSON object");
|
|
2424
|
+
const { typ } = options;
|
|
2425
|
+
if (typ && (typeof protectedHeader.typ !== "string" || normalizeTyp(protectedHeader.typ) !== normalizeTyp(typ))) throw new JWTClaimValidationFailed("unexpected \"typ\" JWT header value", payload, "typ", "check_failed");
|
|
2426
|
+
const { requiredClaims = [], issuer, subject, audience, maxTokenAge } = options;
|
|
2427
|
+
const presenceCheck = [...requiredClaims];
|
|
2428
|
+
if (maxTokenAge !== void 0) presenceCheck.push("iat");
|
|
2429
|
+
if (audience !== void 0) presenceCheck.push("aud");
|
|
2430
|
+
if (subject !== void 0) presenceCheck.push("sub");
|
|
2431
|
+
if (issuer !== void 0) presenceCheck.push("iss");
|
|
2432
|
+
for (const claim of new Set(presenceCheck.reverse())) if (!(claim in payload)) throw new JWTClaimValidationFailed(`missing required "${claim}" claim`, payload, claim, "missing");
|
|
2433
|
+
if (issuer && !(Array.isArray(issuer) ? issuer : [issuer]).includes(payload.iss)) throw new JWTClaimValidationFailed("unexpected \"iss\" claim value", payload, "iss", "check_failed");
|
|
2434
|
+
if (subject && payload.sub !== subject) throw new JWTClaimValidationFailed("unexpected \"sub\" claim value", payload, "sub", "check_failed");
|
|
2435
|
+
if (audience && !checkAudiencePresence(payload.aud, typeof audience === "string" ? [audience] : audience)) throw new JWTClaimValidationFailed("unexpected \"aud\" claim value", payload, "aud", "check_failed");
|
|
2436
|
+
let tolerance;
|
|
2437
|
+
switch (typeof options.clockTolerance) {
|
|
2438
|
+
case "string":
|
|
2439
|
+
tolerance = secs(options.clockTolerance);
|
|
2440
|
+
break;
|
|
2441
|
+
case "number":
|
|
2442
|
+
tolerance = options.clockTolerance;
|
|
2443
|
+
break;
|
|
2444
|
+
case "undefined":
|
|
2445
|
+
tolerance = 0;
|
|
2446
|
+
break;
|
|
2447
|
+
default: throw new TypeError("Invalid clockTolerance option type");
|
|
2448
|
+
}
|
|
2449
|
+
const { currentDate } = options;
|
|
2450
|
+
const now = epoch(currentDate || new Date());
|
|
2451
|
+
if ((payload.iat !== void 0 || maxTokenAge) && typeof payload.iat !== "number") throw new JWTClaimValidationFailed("\"iat\" claim must be a number", payload, "iat", "invalid");
|
|
2452
|
+
if (payload.nbf !== void 0) {
|
|
2453
|
+
if (typeof payload.nbf !== "number") throw new JWTClaimValidationFailed("\"nbf\" claim must be a number", payload, "nbf", "invalid");
|
|
2454
|
+
if (payload.nbf > now + tolerance) throw new JWTClaimValidationFailed("\"nbf\" claim timestamp check failed", payload, "nbf", "check_failed");
|
|
2455
|
+
}
|
|
2456
|
+
if (payload.exp !== void 0) {
|
|
2457
|
+
if (typeof payload.exp !== "number") throw new JWTClaimValidationFailed("\"exp\" claim must be a number", payload, "exp", "invalid");
|
|
2458
|
+
if (payload.exp <= now - tolerance) throw new JWTExpired("\"exp\" claim timestamp check failed", payload, "exp", "check_failed");
|
|
2459
|
+
}
|
|
2460
|
+
if (maxTokenAge) {
|
|
2461
|
+
const age = now - payload.iat;
|
|
2462
|
+
const max = typeof maxTokenAge === "number" ? maxTokenAge : secs(maxTokenAge);
|
|
2463
|
+
if (age - tolerance > max) throw new JWTExpired("\"iat\" claim timestamp check failed (too far in the past)", payload, "iat", "check_failed");
|
|
2464
|
+
if (age < 0 - tolerance) throw new JWTClaimValidationFailed("\"iat\" claim timestamp check failed (it should be in the past)", payload, "iat", "check_failed");
|
|
2465
|
+
}
|
|
2466
|
+
return payload;
|
|
2467
|
+
}
|
|
2468
|
+
//#endregion
|
|
2469
|
+
//#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/jwt/verify.js
|
|
2470
|
+
async function jwtVerify(jwt, key, options) {
|
|
2471
|
+
const verified = await compactVerify(jwt, key, options);
|
|
2472
|
+
if (verified.protectedHeader.crit?.includes("b64") && verified.protectedHeader.b64 === false) throw new JWTInvalid("JWTs MUST NOT use unencoded payload");
|
|
2473
|
+
const result = {
|
|
2474
|
+
payload: validateClaimsSet(verified.protectedHeader, verified.payload, options),
|
|
2475
|
+
protectedHeader: verified.protectedHeader
|
|
2248
2476
|
};
|
|
2249
|
-
|
|
2250
|
-
|
|
2477
|
+
if (typeof key === "function") return {
|
|
2478
|
+
...result,
|
|
2479
|
+
key: verified.key
|
|
2251
2480
|
};
|
|
2252
|
-
|
|
2253
|
-
$fetch.native = (...args) => fetch(...args);
|
|
2254
|
-
$fetch.create = (defaultOptions = {}, customGlobalOptions = {}) => createFetch({
|
|
2255
|
-
...globalOptions,
|
|
2256
|
-
...customGlobalOptions,
|
|
2257
|
-
defaults: {
|
|
2258
|
-
...globalOptions.defaults,
|
|
2259
|
-
...customGlobalOptions.defaults,
|
|
2260
|
-
...defaultOptions
|
|
2261
|
-
}
|
|
2262
|
-
});
|
|
2263
|
-
return $fetch;
|
|
2481
|
+
return result;
|
|
2264
2482
|
}
|
|
2265
2483
|
//#endregion
|
|
2266
|
-
//#region
|
|
2267
|
-
const
|
|
2268
|
-
|
|
2269
|
-
|
|
2484
|
+
//#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/jwk/thumbprint.js
|
|
2485
|
+
const check = (value, description) => {
|
|
2486
|
+
if (typeof value !== "string" || !value) throw new JWKInvalid(`${description} missing or invalid`);
|
|
2487
|
+
};
|
|
2488
|
+
async function calculateJwkThumbprint(key, digestAlgorithm) {
|
|
2489
|
+
let jwk;
|
|
2490
|
+
if (isJWK(key)) jwk = key;
|
|
2491
|
+
else if (isKeyLike(key)) jwk = await exportJWK(key);
|
|
2492
|
+
else throw new TypeError(invalidKeyInput(key, "CryptoKey", "KeyObject", "JSON Web Key"));
|
|
2493
|
+
digestAlgorithm ??= "sha256";
|
|
2494
|
+
if (digestAlgorithm !== "sha256" && digestAlgorithm !== "sha384" && digestAlgorithm !== "sha512") throw new TypeError("digestAlgorithm must one of \"sha256\", \"sha384\", or \"sha512\"");
|
|
2495
|
+
let components;
|
|
2496
|
+
switch (jwk.kty) {
|
|
2497
|
+
case "AKP":
|
|
2498
|
+
check(jwk.alg, "\"alg\" (Algorithm) Parameter");
|
|
2499
|
+
check(jwk.pub, "\"pub\" (Public key) Parameter");
|
|
2500
|
+
components = {
|
|
2501
|
+
alg: jwk.alg,
|
|
2502
|
+
kty: jwk.kty,
|
|
2503
|
+
pub: jwk.pub
|
|
2504
|
+
};
|
|
2505
|
+
break;
|
|
2506
|
+
case "EC":
|
|
2507
|
+
check(jwk.crv, "\"crv\" (Curve) Parameter");
|
|
2508
|
+
check(jwk.x, "\"x\" (X Coordinate) Parameter");
|
|
2509
|
+
check(jwk.y, "\"y\" (Y Coordinate) Parameter");
|
|
2510
|
+
components = {
|
|
2511
|
+
crv: jwk.crv,
|
|
2512
|
+
kty: jwk.kty,
|
|
2513
|
+
x: jwk.x,
|
|
2514
|
+
y: jwk.y
|
|
2515
|
+
};
|
|
2516
|
+
break;
|
|
2517
|
+
case "OKP":
|
|
2518
|
+
check(jwk.crv, "\"crv\" (Subtype of Key Pair) Parameter");
|
|
2519
|
+
check(jwk.x, "\"x\" (Public Key) Parameter");
|
|
2520
|
+
components = {
|
|
2521
|
+
crv: jwk.crv,
|
|
2522
|
+
kty: jwk.kty,
|
|
2523
|
+
x: jwk.x
|
|
2524
|
+
};
|
|
2525
|
+
break;
|
|
2526
|
+
case "RSA":
|
|
2527
|
+
check(jwk.e, "\"e\" (Exponent) Parameter");
|
|
2528
|
+
check(jwk.n, "\"n\" (Modulus) Parameter");
|
|
2529
|
+
components = {
|
|
2530
|
+
e: jwk.e,
|
|
2531
|
+
kty: jwk.kty,
|
|
2532
|
+
n: jwk.n
|
|
2533
|
+
};
|
|
2534
|
+
break;
|
|
2535
|
+
case "oct":
|
|
2536
|
+
check(jwk.k, "\"k\" (Key Value) Parameter");
|
|
2537
|
+
components = {
|
|
2538
|
+
k: jwk.k,
|
|
2539
|
+
kty: jwk.kty
|
|
2540
|
+
};
|
|
2541
|
+
break;
|
|
2542
|
+
default: throw new JOSENotSupported("\"kty\" (Key Type) Parameter missing or unsupported");
|
|
2543
|
+
}
|
|
2544
|
+
const data = encode$1(JSON.stringify(components));
|
|
2545
|
+
return encode(await digest(digestAlgorithm, data));
|
|
2270
2546
|
}
|
|
2271
|
-
|
|
2272
|
-
|
|
2547
|
+
//#endregion
|
|
2548
|
+
//#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/util/decode_protected_header.js
|
|
2549
|
+
function decodeProtectedHeader(token) {
|
|
2550
|
+
let protectedB64u;
|
|
2551
|
+
if (typeof token === "string") {
|
|
2552
|
+
const parts = token.split(".");
|
|
2553
|
+
if (parts.length === 3 || parts.length === 5) [protectedB64u] = parts;
|
|
2554
|
+
} else if (typeof token === "object" && token) if ("protected" in token) protectedB64u = token.protected;
|
|
2555
|
+
else throw new TypeError("Token does not contain a Protected Header");
|
|
2273
2556
|
try {
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
credentials: options.credentials ?? "include",
|
|
2279
|
-
retry: 0,
|
|
2280
|
-
timeout: options.timeoutMs,
|
|
2281
|
-
redirect: "manual",
|
|
2282
|
-
signal: options.signal,
|
|
2283
|
-
responseType: "stream",
|
|
2284
|
-
ignoreResponseError: true
|
|
2285
|
-
});
|
|
2557
|
+
if (typeof protectedB64u !== "string" || !protectedB64u) throw new Error();
|
|
2558
|
+
const result = JSON.parse(decoder.decode(decode(protectedB64u)));
|
|
2559
|
+
if (!isObject(result)) throw new Error();
|
|
2560
|
+
return result;
|
|
2286
2561
|
} catch {
|
|
2287
|
-
throw
|
|
2288
|
-
}
|
|
2289
|
-
const contentType = response.headers.get("content-type")?.split(";", 1)[0]?.trim().toLowerCase();
|
|
2290
|
-
if (response.status >= 300 || response.status < 200 || contentType !== "application/json") {
|
|
2291
|
-
const body = contentType === "application/json" ? await readJson(response, options.maxResponseBytes) : void 0;
|
|
2292
|
-
await response.body?.cancel();
|
|
2293
|
-
throw (options.mapError ?? fromAuthorityError)(body, response.status, response.headers.get("retry-after"));
|
|
2562
|
+
throw new TypeError("Invalid Token or Protected Header formatting");
|
|
2294
2563
|
}
|
|
2295
|
-
return {
|
|
2296
|
-
value: await readJson(response, options.maxResponseBytes),
|
|
2297
|
-
headers: response.headers
|
|
2298
|
-
};
|
|
2299
2564
|
}
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
if (
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
let size = 0;
|
|
2565
|
+
//#endregion
|
|
2566
|
+
//#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/util/decode_jwt.js
|
|
2567
|
+
function decodeJwt(jwt) {
|
|
2568
|
+
if (typeof jwt !== "string") throw new JWTInvalid("JWTs must use Compact JWS serialization, JWT must be a string");
|
|
2569
|
+
const { 1: payload, length } = jwt.split(".");
|
|
2570
|
+
if (length === 5) throw new JWTInvalid("Only JWTs using Compact JWS serialization can be decoded");
|
|
2571
|
+
if (length !== 3) throw new JWTInvalid("Invalid JWT");
|
|
2572
|
+
if (!payload) throw new JWTInvalid("JWTs must contain a payload");
|
|
2573
|
+
let decoded;
|
|
2310
2574
|
try {
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
size += value.byteLength;
|
|
2315
|
-
if (size > maximum) throw authorityUnavailable();
|
|
2316
|
-
chunks.push(value);
|
|
2317
|
-
}
|
|
2318
|
-
} catch (error) {
|
|
2319
|
-
await reader.cancel();
|
|
2320
|
-
throw error;
|
|
2321
|
-
} finally {
|
|
2322
|
-
reader.releaseLock();
|
|
2323
|
-
}
|
|
2324
|
-
const bytes = new Uint8Array(size);
|
|
2325
|
-
let offset = 0;
|
|
2326
|
-
for (const chunk of chunks) {
|
|
2327
|
-
bytes.set(chunk, offset);
|
|
2328
|
-
offset += chunk.byteLength;
|
|
2575
|
+
decoded = decode(payload);
|
|
2576
|
+
} catch {
|
|
2577
|
+
throw new JWTInvalid("Failed to base64url decode the payload");
|
|
2329
2578
|
}
|
|
2579
|
+
let result;
|
|
2330
2580
|
try {
|
|
2331
|
-
|
|
2581
|
+
result = JSON.parse(decoder.decode(decoded));
|
|
2332
2582
|
} catch {
|
|
2333
|
-
throw
|
|
2583
|
+
throw new JWTInvalid("Failed to parse the decoded payload as JSON");
|
|
2334
2584
|
}
|
|
2585
|
+
if (!isObject(result)) throw new JWTInvalid("Invalid JWT Claims Set");
|
|
2586
|
+
return result;
|
|
2335
2587
|
}
|
|
2336
2588
|
//#endregion
|
|
2337
2589
|
//#region src/user-api/verifier.ts
|
|
@@ -3064,8 +3316,8 @@ function createServerAuth(options) {
|
|
|
3064
3316
|
mapError: fromOrganizationMutationAuthorityError
|
|
3065
3317
|
});
|
|
3066
3318
|
}
|
|
3067
|
-
async function organizationRead(path, input, normalize) {
|
|
3068
|
-
const query =
|
|
3319
|
+
async function organizationRead(path, input, normalize, queryInput = normalizeOrganizationPageInput) {
|
|
3320
|
+
const query = queryInput(input);
|
|
3069
3321
|
return normalize(await requestJson(`${joinURL(authOrigin, "api/v1/auth/organizations", path)}${query.size ? `?${query}` : ""}`, {
|
|
3070
3322
|
fetch: fetchImpl,
|
|
3071
3323
|
timeoutMs,
|
|
@@ -3142,6 +3394,45 @@ function createServerAuth(options) {
|
|
|
3142
3394
|
getOrganization(organizationId) {
|
|
3143
3395
|
return organizationRead(normalizeIdInput(organizationId), void 0, normalizeOrganization);
|
|
3144
3396
|
},
|
|
3397
|
+
async getOrganizationMemberApplicationAccess(organizationId, input, serviceAssertion, options) {
|
|
3398
|
+
if (typeof serviceAssertion !== "string" || serviceAssertion.length > 16 * 1024 || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$(?![\s\S])/.test(serviceAssertion)) throw new TypeError("Application access service assertion is invalid");
|
|
3399
|
+
const organization = normalizeIdInput(organizationId);
|
|
3400
|
+
const body = applicationAccessInput(input);
|
|
3401
|
+
let applicationCredential;
|
|
3402
|
+
if (options !== void 0) {
|
|
3403
|
+
const supplied = options?.applicationCredential;
|
|
3404
|
+
if (typeof supplied !== "string" || supplied.length > 16 * 1024 || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$(?![\s\S])/.test(supplied)) throw new TypeError("Application access credential is invalid");
|
|
3405
|
+
applicationCredential = supplied;
|
|
3406
|
+
} else {
|
|
3407
|
+
const startedAt = now();
|
|
3408
|
+
applicationCredential = normalizeUserApiCredential(await requestJson(joinURL(authOrigin, "api/v1/auth/user-api-credential"), {
|
|
3409
|
+
fetch: fetchImpl,
|
|
3410
|
+
timeoutMs,
|
|
3411
|
+
method: "POST",
|
|
3412
|
+
credentials,
|
|
3413
|
+
headers: {
|
|
3414
|
+
...authHeaders(),
|
|
3415
|
+
"content-type": "application/json"
|
|
3416
|
+
},
|
|
3417
|
+
body: { applicationId: body.applicationId }
|
|
3418
|
+
}), startedAt).token;
|
|
3419
|
+
}
|
|
3420
|
+
return normalizeApplicationAccess(await requestJson(joinURL(authOrigin, "api/v1/auth/organizations", organization, "members/application-access"), {
|
|
3421
|
+
fetch: fetchImpl,
|
|
3422
|
+
timeoutMs,
|
|
3423
|
+
method: "POST",
|
|
3424
|
+
maxResponseBytes: 16 * 1024,
|
|
3425
|
+
credentials,
|
|
3426
|
+
headers: {
|
|
3427
|
+
...authHeaders(!authorization),
|
|
3428
|
+
"content-type": "application/json",
|
|
3429
|
+
"x-finueva-application-credential": applicationCredential,
|
|
3430
|
+
"x-finueva-service-assertion": serviceAssertion
|
|
3431
|
+
},
|
|
3432
|
+
body,
|
|
3433
|
+
mapError: fromOrganizationReadAuthorityError
|
|
3434
|
+
}), body.userIds);
|
|
3435
|
+
},
|
|
3145
3436
|
async getOrganizationMemberAuthority(organizationId, memberId) {
|
|
3146
3437
|
const organization = normalizeIdInput(organizationId);
|
|
3147
3438
|
const member = normalizeIdInput(memberId);
|
|
@@ -3316,7 +3607,7 @@ function createServerAuth(options) {
|
|
|
3316
3607
|
}));
|
|
3317
3608
|
},
|
|
3318
3609
|
listOrganizationMembers(organizationId, input) {
|
|
3319
|
-
return organizationRead(`${normalizeIdInput(organizationId)}/members`, input, normalizeOrganizationMembers);
|
|
3610
|
+
return organizationRead(`${normalizeIdInput(organizationId)}/members`, input, normalizeOrganizationMembers, normalizeOrganizationMemberPageInput);
|
|
3320
3611
|
},
|
|
3321
3612
|
listOrganizationTeams(organizationId, input) {
|
|
3322
3613
|
return organizationRead(`${normalizeIdInput(organizationId)}/teams`, input, normalizeOrganizationTeams);
|
|
@@ -3481,4 +3772,4 @@ function authAuthorizationHeader(value) {
|
|
|
3481
3772
|
return value;
|
|
3482
3773
|
}
|
|
3483
3774
|
//#endregion
|
|
3484
|
-
export { AuthError, createDriveProvisioningAuth, createDriveRecipientAuth, createIdentityResolverAuth, createMembershipResolverAuth, createServerAuth, createUserApiVerifier };
|
|
3775
|
+
export { AuthError, createAccountProductOperationAuth, createDriveProvisioningAuth, createDriveRecipientAuth, createIdentityResolverAuth, createMembershipResolverAuth, createServerAuth, createUserApiVerifier };
|