@finueva/auth 0.23.0 → 0.26.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/server.js CHANGED
@@ -1,992 +1,1486 @@
1
- //#region src/errors.ts
2
- const messages = {
3
- invalid_credentials: "The credentials are invalid.",
4
- invalid_auth_input: "The authentication input is invalid.",
5
- account_conflict: "The account is not available.",
6
- social_signup_required: "No account is available for this social sign-in. Start sign-up to create one.",
7
- google_recovery_in_progress: "A Google connection is already being completed. Return to that sign-in, or wait up to ten minutes and restart.",
8
- google_recovery_not_required: "Google account recovery is not required.",
9
- google_recovery_invalid: "The Google account recovery request is invalid.",
10
- google_recovery_expired: "Google account recovery has expired. Start Google sign-in again.",
11
- google_recovery_account_mismatch: "Sign in to the existing account associated with this Google identity.",
12
- password_reset_invalid: "The password reset request is invalid.",
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 normalizeSocialIdTokenInput(value) {
71
- if (!isObject$1(value)) throw new TypeError("social ID token input is invalid");
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 socialIdTokenRequest(value) {
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 normalizeOrigin(value, name) {
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
- url = new URL(value);
22
+ return decodeURIComponent("" + text);
96
23
  } catch {
97
- throw new TypeError(`${name} must be an ASCII HTTP origin`);
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 normalizeSession(value) {
109
- if (value === null) return null;
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 normalizeDriveCredential(value, now) {
127
- 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();
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 normalizeOrganizationPageInput(value) {
135
- if (value === void 0) return new URLSearchParams();
136
- if (!isObject$1(value) || Object.keys(value).some((key) => key !== "limit" && key !== "cursor")) throw new AuthError("invalid_request", 400);
137
- const input = value;
138
- const query = new URLSearchParams();
139
- if (input.limit !== void 0) {
140
- if (!Number.isSafeInteger(input.limit) || input.limit < 1 || input.limit > 100) throw new AuthError("invalid_request", 400);
141
- query.set("limit", String(input.limit));
142
- }
143
- if (input.cursor !== void 0) {
144
- 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);
145
- query.set("cursor", input.cursor);
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 query;
46
+ return object;
148
47
  }
149
- function normalizeIdInput(value) {
150
- if (!isId(value)) throw new AuthError("invalid_request", 400);
151
- return value;
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 normalizeOrganization(value) {
154
- exact$3(value, [
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
- function normalizeOrganizationDisplayInput(value) {
185
- if (!isObject$1(value) || Object.keys(value).sort().join(",") !== "logo,name,slug") throw new AuthError("invalid_request", 400);
186
- if (!boundedString(value.name, 255) || !boundedString(value.slug, 255)) throw new AuthError("invalid_request", 400);
187
- let logo;
188
- try {
189
- logo = nullableHttpsUrl(value.logo);
190
- } catch {
191
- throw new AuthError("invalid_request", 400);
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 normalizeOrganizationDisplay(value) {
200
- try {
201
- return normalizeOrganizationDisplayInput(value);
202
- } catch {
203
- throw authorityUnavailable();
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 normalizeOrganizationTeamDisplayInput(value) {
207
- if (!isObject$1(value) || Object.keys(value).join(",") !== "name" || !boundedString(value.name, 255)) throw new AuthError("invalid_request", 400);
208
- return { name: value.name };
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 normalizeOrganizationTeamDisplay(value) {
211
- try {
212
- return normalizeOrganizationTeamDisplayInput(value);
213
- } catch {
214
- throw authorityUnavailable();
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 normalizeOrganizationCreationInput(name, slug, idempotencyKey) {
218
- if (!boundedString(name, 255) || !boundedString(idempotencyKey, 255) || typeof slug !== "string" || !/^[a-z0-9-]{1,128}$/.test(slug)) throw new AuthError("invalid_request", 400);
219
- return {
220
- name,
221
- slug,
222
- idempotencyKey
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 normalizeCreatedOrganization(value) {
226
- exact$3(value, [
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 normalizeOrganizationTeamCreationInput(name, idempotencyKey) {
239
- if (!boundedString(name, 255) || !boundedString(idempotencyKey, 255)) throw new AuthError("invalid_request", 400);
240
- return {
241
- name,
242
- idempotencyKey
243
- };
118
+ function isNonEmptyURL(url) {
119
+ return url && url !== "/";
244
120
  }
245
- function normalizeCreatedOrganizationTeam(value) {
246
- exact$3(value, ["id", "name"]);
247
- if (!isId(value.id) || !boundedString(value.name, 255)) throw authorityUnavailable();
248
- return {
249
- id: value.id,
250
- name: value.name
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
- function normalizeOrganizationMemberInvitationCreationInput(value) {
254
- if (!isObject$1(value)) throw new AuthError("invalid_request", 400);
255
- const keys = Object.keys(value).sort().join(",");
256
- if (keys !== "email,idempotencyKey" && keys !== "email,idempotencyKey,teamIds") throw new AuthError("invalid_request", 400);
257
- let normalizedEmail;
258
- try {
259
- normalizedEmail = normalizeEmail(value.email);
260
- } catch {
261
- throw new AuthError("invalid_request", 400);
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 (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);
264
- const teamIds = value.teamIds?.map((teamId) => normalizeIdInput(teamId));
265
- if (teamIds && new Set(teamIds).size !== teamIds.length) throw new AuthError("invalid_request", 400);
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
- email: normalizedEmail,
268
- ...teamIds === void 0 ? {} : { teamIds },
269
- idempotencyKey: value.idempotencyKey
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 normalizeCreatedOrganizationMemberInvitation(value) {
273
- exact$3(value, ["expiresAt", "id"]);
274
- if (!isId(value.id)) throw authorityUnavailable();
159
+ function parsePath(input = "") {
160
+ const [pathname = "", search = "", hash = ""] = (input.match(/([^#?]*)(\?[^#]*)?(#.*)?/) || []).splice(1);
275
161
  return {
276
- id: value.id,
277
- expiresAt: responseDate(value.expiresAt)
162
+ pathname,
163
+ search,
164
+ hash
278
165
  };
279
166
  }
280
- function normalizeResentOrganizationInvitation(value, invitationId) {
281
- const invitation = normalizeCreatedOrganizationMemberInvitation(value);
282
- if (invitation.id !== invitationId) throw authorityUnavailable();
283
- return invitation;
284
- }
285
- function normalizeOrganizationInvitationAdministrationInput(idempotencyKey) {
286
- if (!boundedString(idempotencyKey, 255)) throw new AuthError("invalid_request", 400);
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
- function normalizeRemovedOrganizationMember(value) {
299
- exact$3(value, ["status"]);
300
- if (value.status !== "removed") throw authorityUnavailable();
301
- return { status: "removed" };
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 normalizeOrganizationDeparture(value) {
304
- exact$3(value, ["status"]);
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 normalizeOrganizationTeamMembershipInput(idempotencyKey) {
309
- if (!boundedString(idempotencyKey, 255)) throw new AuthError("invalid_request", 400);
310
- return { idempotencyKey };
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
- function normalizeAddedOrganizationTeamMember(value) {
313
- exact$3(value, ["status"]);
314
- if (value.status !== "added") throw authorityUnavailable();
315
- return { status: "added" };
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
- function normalizeRemovedOrganizationTeamMember(value) {
318
- exact$3(value, ["status"]);
319
- if (value.status !== "removed") throw authorityUnavailable();
320
- return { status: "removed" };
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 normalizeDeletedOrganizationTeam(value) {
323
- exact$3(value, ["status"]);
324
- if (value.status !== "deleted") throw authorityUnavailable();
325
- return { status: "deleted" };
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
- function normalizeOrganizations(value) {
328
- exact$3(value, ["nextCursor", "organizations"]);
329
- if (!Array.isArray(value.organizations) || value.organizations.length > 100) throw authorityUnavailable();
330
- return {
331
- organizations: unique(value.organizations.map(normalizeOrganization), (item) => item.id),
332
- nextCursor: nullableCursor(value.nextCursor)
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 normalizeOrganizationMembers(value) {
336
- exact$3(value, ["members", "nextCursor"]);
337
- if (!Array.isArray(value.members) || value.members.length > 100) throw authorityUnavailable();
338
- return {
339
- members: unique(value.members.map((member) => {
340
- exact$3(member, [
341
- "email",
342
- "id",
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
- teams: unique(value.teams.map((team) => {
373
- exact$3(team, [
374
- "category",
375
- "createdAt",
376
- "id",
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 normalizeOrganizationTeamMembers(value) {
391
- exact$3(value, ["memberIds", "nextCursor"]);
392
- if (!Array.isArray(value.memberIds) || value.memberIds.length > 100) throw authorityUnavailable();
393
- return {
394
- memberIds: unique(value.memberIds.map((item) => normalizeResponseId(item)), (item) => item),
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 normalizeOrganizationInvitation(value) {
399
- exact$3(value, [
400
- "createdAt",
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
- function normalizeOrganizationInvitations(value) {
427
- exact$3(value, ["invitations", "nextCursor"]);
428
- if (!Array.isArray(value.invitations) || value.invitations.length > 100) throw authorityUnavailable();
429
- return {
430
- invitations: unique(value.invitations.map(normalizeOrganizationInvitation), (item) => item.id),
431
- nextCursor: nullableCursor(value.nextCursor)
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
- function normalizeReceivedInvitation(value) {
435
- exact$3(value, [
436
- "expiresAt",
437
- "id",
438
- "inviterName",
439
- "organization",
440
- "role",
441
- "teams"
442
- ]);
443
- 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();
444
- exact$3(value.organization, [
445
- "id",
446
- "logo",
447
- "name",
448
- "slug"
449
- ]);
450
- if (!isId(value.organization.id) || !boundedString(value.organization.name, 255) || !boundedString(value.organization.slug, 255)) throw authorityUnavailable();
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$3 = /^[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
- id: value.id,
453
- organization: {
454
- id: value.organization.id,
455
- name: value.organization.name,
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 normalizeReceivedInvitations(value) {
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
- invitations: unique(value.invitations.map(normalizeReceivedInvitation), (item) => item.id),
477
- nextCursor: nullableCursor(value.nextCursor)
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 normalizeInvitationInput(value) {
481
- if (!isObject$1(value) || Object.keys(value).length !== 1 || !isId(value.invitationId)) throw new AuthError("invalid_invitation", 422);
482
- return { invitationId: value.invitationId };
483
- }
484
- function normalizeInvitationAcceptance(value, invitationId) {
485
- 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();
486
- return { organizationId: value.invitation.organizationId };
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 normalizeInvitationDecline(value, invitationId) {
489
- if (!isObject$1(value) || !isObject$1(value.invitation) || value.invitation.id !== invitationId || value.invitation.status !== "rejected" || value.member !== null) throw authorityUnavailable();
490
- return { status: "declined" };
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 normalizeWorkspaceSelection(value) {
493
- if (!isObject$1(value)) throw new AuthError("invalid_workspace_selection", 422);
494
- const keys = Object.keys(value);
495
- if (value.type === "personal" && keys.length === 1 && keys[0] === "type") return { type: "personal" };
496
- if (value.type === "organization" && keys.length === 2 && keys.includes("type") && keys.includes("organizationId") && typeof value.organizationId === "string" && id.test(value.organizationId)) return {
497
- type: "organization",
498
- organizationId: value.organizationId
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 fromAccountAuthorityError(value, status, retryAfter) {
507
- const code = isObject$1(value) && typeof value.code === "string" ? value.code : void 0;
508
- if (status === 403 && (code === "INVALID_ORIGIN" || code === "MISSING_OR_NULL_ORIGIN")) return new AuthError("request_origin_denied", 403);
509
- if (code === "USER_ALREADY_EXISTS_USE_ANOTHER_EMAIL") return new AuthError("account_conflict", 409);
510
- if (code === "INVALID_TOKEN") return new AuthError("password_reset_invalid", 422);
511
- if (code === "INVALID_PASSWORD" || code === "INVALID_EMAIL_OR_PASSWORD") return new AuthError("invalid_credentials", 401);
512
- 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);
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 fromSocialIdTokenAuthorityError(value, status, retryAfter) {
521
- const code = isObject$1(value) && typeof value.code === "string" ? value.code : void 0;
522
- if (code === "INVALID_TOKEN" || code === "FAILED_TO_GET_USER_INFO" || code === "USER_EMAIL_NOT_FOUND") return new AuthError("invalid_credentials", 401);
523
- if (code === "OAUTH_LINK_ERROR") {
524
- const message = isObject$1(value) && typeof value.message === "string" ? value.message : void 0;
525
- if (message === "account not linked") return new AuthError("account_conflict", 409);
526
- if (message === "signup disabled") return new AuthError("social_signup_required", 409);
527
- return authorityUnavailable();
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
- return fromAccountAuthorityError(value, status, retryAfter);
530
- }
531
- function authorityUnavailable() {
532
- return new AuthError("identity_authority_unavailable", 503);
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 fromOrganizationInvitationAdministrationError(value, status, retryAfter) {
555
- if (status === 422 && isObject$1(value) && value.code === "RECOVERY_REQUIRED") return new AuthError("invitation_recovery_required", 422);
556
- return fromOrganizationMutationAuthorityError(value, status, retryAfter);
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 fromOrganizationMembershipRemovalError(value, status, retryAfter) {
559
- if (status === 422 && isObject$1(value) && value.code === "RECOVERY_REQUIRED") return new AuthError("membership_removal_recovery_required", 422);
560
- return fromOrganizationMutationAuthorityError(value, status, retryAfter);
604
+ function normalizeIdInput(value) {
605
+ if (!isId(value)) throw new AuthError("invalid_request", 400);
606
+ return value;
561
607
  }
562
- function normalizeOrganizationMemberAuthority(value, organizationId, memberId) {
563
- exact$3(value, [
564
- "organizationId",
565
- "actor",
566
- "target"
608
+ function normalizeOrganization(value) {
609
+ exact$6(value, [
610
+ "capabilities",
611
+ "id",
612
+ "lifecycle",
613
+ "logo",
614
+ "name",
615
+ "role",
616
+ "slug"
567
617
  ]);
568
- if (!isId(value.organizationId) || value.organizationId !== organizationId) throw authorityUnavailable();
569
- const actor = normalizeOrganizationAuthorityMemberOutcome(value.actor);
570
- const target = normalizeOrganizationAuthorityMemberOutcome(value.target);
571
- if (target.memberId !== memberId || actor.manualRole !== "owner" && actor.manualRole !== "admin") throw authorityUnavailable();
572
- for (const member of [actor, target]) if (member.manualRole === "member" ? member.role === "owner" : member.role !== member.manualRole) throw authorityUnavailable();
573
- if (actor.memberId === target.memberId && (actor.manualRole !== target.manualRole || actor.role !== target.role || actor.authorityRevision !== target.authorityRevision)) throw authorityUnavailable();
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$6(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
- organizationId: value.organizationId,
576
- actor,
577
- target
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 normalizeOrganizationAuthorityMemberOutcome(value, includesStatus = false) {
581
- exact$3(value, [
582
- "memberId",
583
- "manualRole",
584
- "role",
585
- "authorityRevision",
586
- ...includesStatus ? ["status"] : []
587
- ]);
588
- if (!isId(value.memberId) || value.manualRole !== "owner" && value.manualRole !== "admin" && value.manualRole !== "member" || value.role !== "owner" && value.role !== "admin" && value.role !== "member") throw authorityUnavailable();
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
- memberId: value.memberId,
591
- manualRole: value.manualRole,
592
- role: value.role,
593
- authorityRevision: normalizeAuthorityResultRevision(value.authorityRevision)
649
+ name: value.name,
650
+ slug: value.slug,
651
+ logo
594
652
  };
595
653
  }
596
- function normalizeAuthorityResultRevision(value) {
597
- if (!Number.isSafeInteger(value) || value < 0 || value >= Number.MAX_SAFE_INTEGER) throw authorityUnavailable();
598
- return value;
654
+ function normalizeOrganizationDisplay(value) {
655
+ try {
656
+ return normalizeOrganizationDisplayInput(value);
657
+ } catch {
658
+ throw authorityUnavailable();
659
+ }
599
660
  }
600
- function fromInvitationAuthorityError(value, status) {
601
- const code = isObject$1(value) && typeof value.code === "string" ? value.code : void 0;
602
- if (status === 401 && code === "UNAUTHORIZED") return new AuthError("authentication_required", 401);
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 fromInvitationError(error) {
610
- return error instanceof AuthError ? error : authorityUnavailable();
665
+ function normalizeOrganizationTeamDisplay(value) {
666
+ try {
667
+ return normalizeOrganizationTeamDisplayInput(value);
668
+ } catch {
669
+ throw authorityUnavailable();
670
+ }
611
671
  }
612
- function mapError(code, status) {
613
- if (code === "authentication_required") return {
614
- code,
615
- status: 401
616
- };
617
- if (code === "request_origin_denied") return {
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
- if (status === 429) return {
654
- code: "credential_rate_limited",
655
- status: 429
679
+ }
680
+ function normalizeCreatedOrganization(value) {
681
+ exact$6(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
- code: "identity_authority_unavailable",
659
- status: 503
696
+ name,
697
+ idempotencyKey
660
698
  };
661
699
  }
662
- function parseRetryAfter(value) {
663
- if (!value || !/^\d+$/.test(value)) return void 0;
664
- const seconds = Number(value);
665
- return Number.isSafeInteger(seconds) && seconds >= 1 && seconds <= 3600 ? seconds : void 0;
700
+ function normalizeCreatedOrganizationTeam(value) {
701
+ exact$6(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 toDate(value) {
668
- const result = value instanceof Date ? value : typeof value === "string" ? new Date(value) : void 0;
669
- return result && Number.isFinite(result.getTime()) ? result : void 0;
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 isId(value) {
672
- return typeof value === "string" && id.test(value);
727
+ function normalizeCreatedOrganizationMemberInvitation(value) {
728
+ exact$6(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 exact$3(value, keys) {
675
- if (!isObject$1(value) || Object.keys(value).sort().join(",") !== [...keys].sort().join(",")) throw authorityUnavailable();
735
+ function normalizeResentOrganizationInvitation(value, invitationId) {
736
+ const invitation = normalizeCreatedOrganizationMemberInvitation(value);
737
+ if (invitation.id !== invitationId) throw authorityUnavailable();
738
+ return invitation;
676
739
  }
677
- function boundedString(value, maximum) {
678
- return typeof value === "string" && value.length > 0 && new TextEncoder().encode(value).byteLength <= maximum;
740
+ function normalizeOrganizationInvitationAdministrationInput(idempotencyKey) {
741
+ if (!boundedString(idempotencyKey, 255)) throw new AuthError("invalid_request", 400);
742
+ return { idempotencyKey };
679
743
  }
680
- function role(value) {
681
- return value === "owner" || value === "admin" || value === "member";
744
+ function normalizeCanceledOrganizationInvitation(value) {
745
+ exact$6(value, ["status"]);
746
+ if (value.status !== "canceled") throw authorityUnavailable();
747
+ return { status: "canceled" };
682
748
  }
683
- function nullableHttpsUrl(value) {
684
- if (value === null) return null;
685
- if (typeof value !== "string" || value.length > 2048) throw authorityUnavailable();
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 responseDate(value) {
696
- if (typeof value !== "string") throw authorityUnavailable();
697
- const date = new Date(value);
698
- if (!Number.isFinite(date.getTime()) || date.toISOString() !== value) throw authorityUnavailable();
699
- return date;
753
+ function normalizeRemovedOrganizationMember(value) {
754
+ exact$6(value, ["status"]);
755
+ if (value.status !== "removed") throw authorityUnavailable();
756
+ return { status: "removed" };
700
757
  }
701
- function nullableCursor(value) {
702
- if (value === null) return null;
703
- if (typeof value !== "string" || value.length < 1 || value.length > 820 || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(value)) throw authorityUnavailable();
704
- return value;
758
+ function normalizeOrganizationDeparture(value) {
759
+ exact$6(value, ["status"]);
760
+ if (value.status !== "left") throw authorityUnavailable();
761
+ return { status: "left" };
705
762
  }
706
- function normalizeResponseId(value) {
707
- if (!isId(value)) throw authorityUnavailable();
708
- return value;
763
+ function normalizeOrganizationTeamMembershipInput(idempotencyKey) {
764
+ if (!boundedString(idempotencyKey, 255)) throw new AuthError("invalid_request", 400);
765
+ return { idempotencyKey };
709
766
  }
710
- function unique(items, key) {
711
- if (new Set(items.map(key)).size !== items.length) throw authorityUnavailable();
712
- return items;
767
+ function normalizeAddedOrganizationTeamMember(value) {
768
+ exact$6(value, ["status"]);
769
+ if (value.status !== "added") throw authorityUnavailable();
770
+ return { status: "added" };
713
771
  }
714
- function isObject$1(value) {
715
- return typeof value === "object" && value !== null && !Array.isArray(value);
772
+ function normalizeRemovedOrganizationTeamMember(value) {
773
+ exact$6(value, ["status"]);
774
+ if (value.status !== "removed") throw authorityUnavailable();
775
+ return { status: "removed" };
716
776
  }
717
- //#endregion
718
- //#region src/google-recovery.ts
719
- function object(value) {
720
- return value !== null && typeof value === "object" && !Array.isArray(value);
777
+ function normalizeDeletedOrganizationTeam(value) {
778
+ exact$6(value, ["status"]);
779
+ if (value.status !== "deleted") throw authorityUnavailable();
780
+ return { status: "deleted" };
721
781
  }
722
- function validTicket(value) {
723
- return typeof value === "string" && /^[A-Za-z0-9_-]{43}$/.test(value);
782
+ function normalizeOrganizations(value) {
783
+ exact$6(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 googleRecoveryInput(value, complete) {
726
- 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);
727
- const social = normalizeSocialIdTokenInput({
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$6(value, ["members", "nextCursor"]);
792
+ if (!Array.isArray(value.members) || value.members.length > 100) throw authorityUnavailable();
733
793
  return {
734
- idToken: {
735
- token: social.idToken,
736
- ...social.nonce === void 0 ? {} : { nonce: social.nonce }
794
+ members: unique(value.members.map((member) => {
795
+ exact$6(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$6(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$6(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$6(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$6(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$6(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
- ...complete ? { recoveryToken: value.recoveryToken } : {}
876
+ createdAt: responseDate(value.createdAt),
877
+ expiresAt: responseDate(value.expiresAt),
878
+ status: "pending"
739
879
  };
740
880
  }
741
- function normalizeGoogleRecovery(value, now) {
742
- if (!object(value) || Object.keys(value).sort().join(",") !== "expiresAt,recoveryToken" || !validTicket(value.recoveryToken) || typeof value.expiresAt !== "string") throw authorityUnavailable();
743
- const expiresAt = Date.parse(value.expiresAt);
744
- if (!Number.isFinite(expiresAt) || expiresAt <= now || expiresAt > now + 10 * 6e4) throw authorityUnavailable();
881
+ function normalizeOrganizationInvitations(value) {
882
+ exact$6(value, ["invitations", "nextCursor"]);
883
+ if (!Array.isArray(value.invitations) || value.invitations.length > 100) throw authorityUnavailable();
745
884
  return {
746
- recoveryToken: value.recoveryToken,
747
- expiresAt: value.expiresAt
885
+ invitations: unique(value.invitations.map(normalizeOrganizationInvitation), (item) => item.id),
886
+ nextCursor: nullableCursor(value.nextCursor)
748
887
  };
749
888
  }
750
- function normalizeGoogleRecoveryCompletion(value) {
751
- if (!object(value) || Object.keys(value).join(",") !== "linked" || value.linked !== true) throw authorityUnavailable();
752
- return { linked: true };
889
+ function normalizeReceivedInvitation(value) {
890
+ exact$6(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$6(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$6(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 fromGoogleRecoveryError(value, status, retryAfter) {
755
- const code = object(value) ? value.code : void 0;
756
- if (status === 409 && code === "GOOGLE_RECOVERY_IN_PROGRESS") return new AuthError("google_recovery_in_progress", 409);
757
- if (status === 409 && code === "GOOGLE_RECOVERY_NOT_REQUIRED") return new AuthError("google_recovery_not_required", 409);
758
- if (status === 403 && code === "GOOGLE_RECOVERY_EMAIL_VERIFICATION_REQUIRED") return new AuthError("email_verification_required", 403);
759
- if (status === 400 && code === "GOOGLE_RECOVERY_INVALID") return new AuthError("google_recovery_invalid", 400);
760
- if (status === 410 && code === "GOOGLE_RECOVERY_EXPIRED") return new AuthError("google_recovery_expired", 410);
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$6(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
- String.fromCharCode;
767
- const HASH_RE = /#/g;
768
- const AMPERSAND_RE = /&/g;
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 encodeQueryValue(input) {
780
- 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");
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 encodeQueryKey(text) {
783
- return encodeQueryValue(text).replace(EQUAL_RE, "%3D");
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 decode$1(text = "") {
786
- try {
787
- return decodeURIComponent("" + text);
788
- } catch {
789
- return "" + text;
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$3.test(value.organizationId)) return {
952
+ type: "organization",
953
+ organizationId: value.organizationId
954
+ };
955
+ throw new AuthError("invalid_workspace_selection", 422);
791
956
  }
792
- function decodeQueryKey(text) {
793
- return decode$1(text.replace(PLUS_RE, " "));
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 decodeQueryValue(text) {
796
- return decode$1(text.replace(PLUS_RE, " "));
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 parseQuery(parametersString = "") {
799
- const object = Object.create(null);
800
- if (parametersString[0] === "?") parametersString = parametersString.slice(1);
801
- for (const parameter of parametersString.split("&")) {
802
- const s = parameter.match(/([^=]+)=?(.*)/) || [];
803
- if (s.length < 2) continue;
804
- const key = decodeQueryKey(s[1]);
805
- if (key === "__proto__" || key === "constructor") continue;
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 object;
984
+ return fromAccountAuthorityError(value, status, retryAfter);
812
985
  }
813
- function encodeQueryItem(key, value) {
814
- if (typeof value === "number" || typeof value === "boolean") value = String(value);
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 stringifyQuery(query) {
820
- return Object.keys(query).filter((k) => query[k] !== void 0).map((k) => encodeQueryItem(k, query[k])).filter(Boolean).join("&");
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
- const PROTOCOL_STRICT_REGEX = /^[\s\w\0+.-]{2,}:([/\\]{1,2})/;
823
- const PROTOCOL_REGEX = /^[\s\w\0+.-]{2,}:([/\\]{2})?/;
824
- const PROTOCOL_RELATIVE_REGEX = /^([/\\]\s*){2,}[^/\\]/;
825
- const TRAILING_SLASH_RE = /\/$|\/\?|\/#/;
826
- const JOIN_LEADING_SLASH_RE = /^\.?\//;
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 isEmptyURL(url) {
881
- return !url || url === "/";
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 isNonEmptyURL(url) {
884
- return url && url !== "/";
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 joinURL(base, ...input) {
887
- let url = base || "";
888
- for (const segment of input.filter((url2) => isNonEmptyURL(url2))) if (url) {
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
- const protocolRelative = Symbol.for("ufo:protocolRelative");
895
- function parseURL(input = "", defaultProto) {
896
- const _specialProtoMatch = input.match(/^[\s\0]*(blob:|data:|javascript:|vbscript:)(.*)/i);
897
- if (_specialProtoMatch) {
898
- const [, _proto, _pathname = ""] = _specialProtoMatch;
899
- return {
900
- protocol: _proto.toLowerCase(),
901
- pathname: _pathname,
902
- href: _proto + _pathname,
903
- auth: "",
904
- host: "",
905
- search: "",
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$6(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
- protocol: protocol.toLowerCase(),
916
- auth: auth ? auth.slice(0, Math.max(0, auth.length - 1)) : "",
917
- host,
918
- pathname,
919
- search,
920
- hash,
921
- [protocolRelative]: !protocol
1030
+ organizationId: value.organizationId,
1031
+ actor,
1032
+ target
922
1033
  };
923
1034
  }
924
- function parsePath(input = "") {
925
- const [pathname = "", search = "", hash = ""] = (input.match(/([^#?]*)(\?[^#]*)?(#.*)?/) || []).splice(1);
1035
+ function normalizeOrganizationAuthorityMemberOutcome(value, includesStatus = false) {
1036
+ exact$6(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
- pathname,
928
- search,
929
- hash
1045
+ memberId: value.memberId,
1046
+ manualRole: value.manualRole,
1047
+ role: value.role,
1048
+ authorityRevision: normalizeAuthorityResultRevision(value.authorityRevision)
930
1049
  };
931
1050
  }
932
- function stringifyParsedURL(parsed) {
933
- const pathname = parsed.pathname || "";
934
- const search = parsed.search ? (parsed.search.startsWith("?") ? "" : "?") + parsed.search : "";
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
- //#endregion
941
- //#region src/user-api/credential.ts
942
- function userApiApplication(input) {
943
- 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");
944
- return input.applicationId;
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 normalizeUserApiCredential(value, startedAt) {
947
- 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);
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
- tokenType: "Bearer",
950
- token: value.token,
951
- expiresAt: new Date(startedAt + value.expiresIn * 1e3)
1113
+ code: "identity_authority_unavailable",
1114
+ status: 503
952
1115
  };
953
1116
  }
954
- //#endregion
955
- //#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/lib/buffer_utils.js
956
- const encoder$1 = new TextEncoder();
957
- const decoder = new TextDecoder();
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 encode$1(string) {
969
- const bytes = new Uint8Array(string.length);
970
- for (let i = 0; i < string.length; i++) {
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
- //#endregion
978
- //#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/lib/base64.js
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$3.test(value);
985
1128
  }
986
- function decodeBase64(encoded) {
987
- if (Uint8Array.fromBase64) return Uint8Array.fromBase64(encoded);
988
- const binary = atob(encoded);
989
- const bytes = new Uint8Array(binary.length);
1129
+ function exact$6(value, keys) {
1130
+ if (!isObject$1(value) || Object.keys(value).sort().join(",") !== [...keys].sort().join(",")) throw authorityUnavailable();
1131
+ }
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;
1142
+ try {
1143
+ url = new URL(value);
1144
+ } catch {
1145
+ throw authorityUnavailable();
1146
+ }
1147
+ if (url.protocol !== "https:" || url.username || url.password || url.toString() !== value) throw authorityUnavailable();
1148
+ return value;
1149
+ }
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;
1155
+ }
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;
1160
+ }
1161
+ function normalizeResponseId(value) {
1162
+ if (!isId(value)) throw authorityUnavailable();
1163
+ return value;
1164
+ }
1165
+ function unique(items, key) {
1166
+ if (new Set(items.map(key)).size !== items.length) throw authorityUnavailable();
1167
+ return items;
1168
+ }
1169
+ function isObject$1(value) {
1170
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1171
+ }
1172
+ //#endregion
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();
1196
+ }
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
+ };
1207
+ }
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();
1213
+ }
1214
+ if (!response.body) throw authorityUnavailable();
1215
+ if (signal?.aborted) {
1216
+ response.body.cancel().catch(() => void 0);
1217
+ throw authorityUnavailable();
1218
+ }
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();
1241
+ }
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;
1247
+ }
1248
+ try {
1249
+ return JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
1250
+ } catch {
1251
+ throw authorityUnavailable();
1252
+ }
1253
+ }
1254
+ //#endregion
1255
+ //#region src/product-operations/contract.ts
1256
+ const id$2 = /^[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$5(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));
1261
+ }
1262
+ function identifier(value) {
1263
+ return typeof value === "string" && id$2.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$5(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
+ };
1290
+ }
1291
+ function snapshotInput(value) {
1292
+ if (!exact$5(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
+ };
1297
+ }
1298
+ function operationInput(value) {
1299
+ if (!exact$5(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$5(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$5(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();
1420
+ }
1421
+ }
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$5(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
+ };
1447
+ }
1448
+ //#endregion
1449
+ //#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/lib/buffer_utils.js
1450
+ const encoder$1 = new TextEncoder();
1451
+ const decoder = new TextDecoder();
1452
+ function concat(...buffers) {
1453
+ const size = buffers.reduce((acc, { length }) => acc + length, 0);
1454
+ const buf = new Uint8Array(size);
1455
+ let i = 0;
1456
+ for (const buffer of buffers) {
1457
+ buf.set(buffer, i);
1458
+ i += buffer.length;
1459
+ }
1460
+ return buf;
1461
+ }
1462
+ function encode$1(string) {
1463
+ const bytes = new Uint8Array(string.length);
1464
+ for (let i = 0; i < string.length; i++) {
1465
+ const code = string.charCodeAt(i);
1466
+ if (code > 127) throw new TypeError("non-ASCII string encountered in encode()");
1467
+ bytes[i] = code;
1468
+ }
1469
+ return bytes;
1470
+ }
1471
+ //#endregion
1472
+ //#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/lib/base64.js
1473
+ function encodeBase64(input) {
1474
+ if (Uint8Array.prototype.toBase64) return input.toBase64();
1475
+ const CHUNK_SIZE = 32768;
1476
+ const arr = [];
1477
+ for (let i = 0; i < input.length; i += CHUNK_SIZE) arr.push(String.fromCharCode.apply(null, input.subarray(i, i + CHUNK_SIZE)));
1478
+ return btoa(arr.join(""));
1479
+ }
1480
+ function decodeBase64(encoded) {
1481
+ if (Uint8Array.fromBase64) return Uint8Array.fromBase64(encoded);
1482
+ const binary = atob(encoded);
1483
+ const bytes = new Uint8Array(binary.length);
990
1484
  for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
991
1485
  return bytes;
992
1486
  }
@@ -1907,432 +2401,231 @@ async function calculateJwkThumbprint(key, digestAlgorithm) {
1907
2401
  digestAlgorithm ??= "sha256";
1908
2402
  if (digestAlgorithm !== "sha256" && digestAlgorithm !== "sha384" && digestAlgorithm !== "sha512") throw new TypeError("digestAlgorithm must one of \"sha256\", \"sha384\", or \"sha512\"");
1909
2403
  let components;
1910
- switch (jwk.kty) {
1911
- case "AKP":
1912
- check(jwk.alg, "\"alg\" (Algorithm) Parameter");
1913
- check(jwk.pub, "\"pub\" (Public key) Parameter");
1914
- components = {
1915
- alg: jwk.alg,
1916
- kty: jwk.kty,
1917
- pub: jwk.pub
1918
- };
1919
- break;
1920
- case "EC":
1921
- check(jwk.crv, "\"crv\" (Curve) Parameter");
1922
- check(jwk.x, "\"x\" (X Coordinate) Parameter");
1923
- check(jwk.y, "\"y\" (Y Coordinate) Parameter");
1924
- components = {
1925
- crv: jwk.crv,
1926
- kty: jwk.kty,
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");
1957
- }
1958
- const data = encode$1(JSON.stringify(components));
1959
- return encode(await digest(digestAlgorithm, data));
1960
- }
1961
- //#endregion
1962
- //#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/util/decode_protected_header.js
1963
- function decodeProtectedHeader(token) {
1964
- let protectedB64u;
1965
- if (typeof token === "string") {
1966
- const parts = token.split(".");
1967
- if (parts.length === 3 || parts.length === 5) [protectedB64u] = parts;
1968
- } else if (typeof token === "object" && token) if ("protected" in token) protectedB64u = token.protected;
1969
- else throw new TypeError("Token does not contain a Protected Header");
1970
- try {
1971
- if (typeof protectedB64u !== "string" || !protectedB64u) throw new Error();
1972
- const result = JSON.parse(decoder.decode(decode(protectedB64u)));
1973
- if (!isObject(result)) throw new Error();
1974
- return result;
1975
- } catch {
1976
- throw new TypeError("Invalid Token or Protected Header formatting");
1977
- }
1978
- }
1979
- //#endregion
1980
- //#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/util/decode_jwt.js
1981
- function decodeJwt(jwt) {
1982
- if (typeof jwt !== "string") throw new JWTInvalid("JWTs must use Compact JWS serialization, JWT must be a string");
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;
2001
- }
2002
- //#endregion
2003
- //#region ../../node_modules/.pnpm/destr@2.0.5/node_modules/destr/dist/index.mjs
2004
- 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*:/;
2005
- 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*:/;
2006
- const JsonSigRx = /^\s*["[{]|^\s*-?\d{1,16}(\.\d{1,17})?([Ee][+-]?\d+)?\s*$/;
2007
- function jsonParseTransform(key, value) {
2008
- if (key === "__proto__" || key === "constructor" && value && typeof value === "object" && "prototype" in value) {
2009
- warnKeyDropped(key);
2010
- return;
2011
- }
2012
- return value;
2013
- }
2014
- function warnKeyDropped(key) {
2015
- console.warn(`[destr] Dropping "${key}" key to prevent prototype pollution.`);
2016
- }
2017
- function destr(value, options = {}) {
2018
- if (typeof value !== "string") return value;
2019
- if (value[0] === "\"" && value[value.length - 1] === "\"" && value.indexOf("\\") === -1) return value.slice(1, -1);
2020
- const _value = value.trim();
2021
- if (_value.length <= 9) switch (_value.toLowerCase()) {
2022
- case "true": return true;
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
- }
2044
- }
2045
- //#endregion
2046
- //#region ../../node_modules/.pnpm/ofetch@1.5.1/node_modules/ofetch/dist/shared/ofetch.CWycOUEr.mjs
2047
- var FetchError = class extends Error {
2048
- constructor(message, opts) {
2049
- super(message, opts);
2050
- this.name = "FetchError";
2051
- if (opts?.cause && !this.cause) this.cause = opts.cause;
2052
- }
2053
- };
2054
- function createFetchError(ctx) {
2055
- const errorMessage = ctx.error?.message || ctx.error?.toString() || "";
2056
- const method = ctx.request?.method || ctx.options?.method || "GET";
2057
- const url = ctx.request?.url || String(ctx.request) || "/";
2058
- 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);
2059
- for (const key of [
2060
- "request",
2061
- "options",
2062
- "response"
2063
- ]) Object.defineProperty(fetchError, key, { get() {
2064
- return ctx[key];
2065
- } });
2066
- for (const [key, refKey] of [
2067
- ["data", "_data"],
2068
- ["status", "status"],
2069
- ["statusCode", "status"],
2070
- ["statusText", "statusText"],
2071
- ["statusMessage", "statusText"]
2072
- ]) Object.defineProperty(fetchError, key, { get() {
2073
- return ctx.response && ctx.response[refKey];
2074
- } });
2075
- return fetchError;
2076
- }
2077
- const payloadMethods = new Set(Object.freeze([
2078
- "PATCH",
2079
- "POST",
2080
- "PUT",
2081
- "DELETE"
2082
- ]));
2083
- function isPayloadMethod(method = "GET") {
2084
- return payloadMethods.has(method.toUpperCase());
2085
- }
2086
- function isJSONSerializable(value) {
2087
- if (value === void 0) return false;
2088
- const t = typeof value;
2089
- if (t === "string" || t === "number" || t === "boolean" || t === null) return true;
2090
- if (t !== "object") return false;
2091
- if (Array.isArray(value)) return true;
2092
- if (value.buffer) return false;
2093
- if (value instanceof FormData || value instanceof URLSearchParams) return false;
2094
- return value.constructor && value.constructor.name === "Object" || typeof value.toJSON === "function";
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";
2110
- }
2111
- function resolveFetchOptions(request, input, defaults, Headers) {
2112
- const headers = mergeHeaders(input?.headers ?? request?.headers, defaults?.headers, Headers);
2113
- let query;
2114
- if (defaults?.query || defaults?.params || input?.params || input?.query) query = {
2115
- ...defaults?.params,
2116
- ...defaults?.query,
2117
- ...input?.params,
2118
- ...input?.query
2119
- };
2120
- return {
2121
- ...defaults,
2122
- ...input,
2123
- query,
2124
- params: query,
2125
- headers
2126
- };
2127
- }
2128
- function mergeHeaders(input, defaults, Headers) {
2129
- if (!defaults) return new Headers(input);
2130
- const headers = new Headers(defaults);
2131
- if (input) for (const [key, value] of Symbol.iterator in input || Array.isArray(input) ? input : new Headers(input)) headers.set(key, value);
2132
- return headers;
2133
- }
2134
- async function callHooks(context, hooks) {
2135
- if (hooks) if (Array.isArray(hooks)) for (const hook of hooks) await hook(context);
2136
- else await hooks(context);
2137
- }
2138
- const retryStatusCodes = new Set([
2139
- 408,
2140
- 409,
2141
- 425,
2142
- 429,
2143
- 500,
2144
- 502,
2145
- 503,
2146
- 504
2147
- ]);
2148
- const nullBodyResponses = new Set([
2149
- 101,
2150
- 204,
2151
- 205,
2152
- 304
2153
- ]);
2154
- function createFetch(globalOptions = {}) {
2155
- const { fetch = globalThis.fetch, Headers = globalThis.Headers, AbortController = globalThis.AbortController } = globalOptions;
2156
- async function onError(context) {
2157
- const isAbort = context.error && context.error.name === "AbortError" && !context.options.timeout || false;
2158
- if (context.options.retry !== false && !isAbort) {
2159
- let retries;
2160
- if (typeof context.options.retry === "number") retries = context.options.retry;
2161
- else retries = isPayloadMethod(context.options.method) ? 0 : 1;
2162
- const responseCode = context.response && context.response.status || 500;
2163
- if (retries > 0 && (Array.isArray(context.options.retryStatusCodes) ? context.options.retryStatusCodes.includes(responseCode) : retryStatusCodes.has(responseCode))) {
2164
- const retryDelay = typeof context.options.retryDelay === "function" ? context.options.retryDelay(context) : context.options.retryDelay || 0;
2165
- if (retryDelay > 0) await new Promise((resolve) => setTimeout(resolve, retryDelay));
2166
- return $fetchRaw(context.request, {
2167
- ...context.options,
2168
- retry: retries - 1
2169
- });
2170
- }
2171
- }
2172
- const error = createFetchError(context);
2173
- if (Error.captureStackTrace) Error.captureStackTrace(error, $fetchRaw);
2174
- throw error;
2175
- }
2176
- const $fetchRaw = async function $fetchRaw2(_request, _options = {}) {
2177
- const context = {
2178
- request: _request,
2179
- options: resolveFetchOptions(_request, _options, globalOptions.defaults, Headers),
2180
- response: void 0,
2181
- error: void 0
2182
- };
2183
- if (context.options.method) context.options.method = context.options.method.toUpperCase();
2184
- if (context.options.onRequest) {
2185
- await callHooks(context, context.options.onRequest);
2186
- if (!(context.options.headers instanceof Headers)) context.options.headers = new Headers(context.options.headers || {});
2187
- }
2188
- if (typeof context.request === "string") {
2189
- if (context.options.baseURL) context.request = withBase(context.request, context.options.baseURL);
2190
- if (context.options.query) {
2191
- context.request = withQuery(context.request, context.options.query);
2192
- delete context.options.query;
2193
- }
2194
- if ("query" in context.options) delete context.options.query;
2195
- if ("params" in context.options) delete context.options.params;
2196
- }
2197
- if (context.options.body && isPayloadMethod(context.options.method)) {
2198
- if (isJSONSerializable(context.options.body)) {
2199
- const contentType = context.options.headers.get("content-type");
2200
- 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);
2201
- if (!contentType) context.options.headers.set("content-type", "application/json");
2202
- if (!context.options.headers.has("accept")) context.options.headers.set("accept", "application/json");
2203
- } else if ("pipeTo" in context.options.body && typeof context.options.body.pipeTo === "function" || typeof context.options.body.pipe === "function") {
2204
- if (!("duplex" in context.options)) context.options.duplex = "half";
2205
- }
2206
- }
2207
- let abortTimeout;
2208
- if (!context.options.signal && context.options.timeout) {
2209
- const controller = new AbortController();
2210
- abortTimeout = setTimeout(() => {
2211
- const error = new Error("[TimeoutError]: The operation was aborted due to timeout");
2212
- error.name = "TimeoutError";
2213
- error.code = 23;
2214
- controller.abort(error);
2215
- }, context.options.timeout);
2216
- context.options.signal = controller.signal;
2217
- }
2218
- try {
2219
- context.response = await fetch(context.request, context.options);
2220
- } catch (error) {
2221
- context.error = error;
2222
- if (context.options.onRequestError) await callHooks(context, context.options.onRequestError);
2223
- return await onError(context);
2224
- } finally {
2225
- if (abortTimeout) clearTimeout(abortTimeout);
2226
- }
2227
- if ((context.response.body || context.response._bodyInit) && !nullBodyResponses.has(context.response.status) && context.options.method !== "HEAD") {
2228
- const responseType = (context.options.parseResponse ? "json" : context.options.responseType) || detectResponseType(context.response.headers.get("content-type") || "");
2229
- switch (responseType) {
2230
- case "json": {
2231
- const data = await context.response.text();
2232
- const parseFunction = context.options.parseResponse || destr;
2233
- context.response._data = parseFunction(data);
2234
- break;
2235
- }
2236
- case "stream":
2237
- context.response._data = context.response.body || context.response._bodyInit;
2238
- break;
2239
- default: context.response._data = await context.response[responseType]();
2240
- }
2241
- }
2242
- if (context.options.onResponse) await callHooks(context, context.options.onResponse);
2243
- if (!context.options.ignoreResponseError && context.response.status >= 400 && context.response.status < 600) {
2244
- if (context.options.onResponseError) await callHooks(context, context.options.onResponseError);
2245
- return await onError(context);
2246
- }
2247
- return context.response;
2248
- };
2249
- const $fetch = async function $fetch2(request, options) {
2250
- return (await $fetchRaw(request, options))._data;
2251
- };
2252
- $fetch.raw = $fetchRaw;
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;
2404
+ switch (jwk.kty) {
2405
+ case "AKP":
2406
+ check(jwk.alg, "\"alg\" (Algorithm) Parameter");
2407
+ check(jwk.pub, "\"pub\" (Public key) Parameter");
2408
+ components = {
2409
+ alg: jwk.alg,
2410
+ kty: jwk.kty,
2411
+ pub: jwk.pub
2412
+ };
2413
+ break;
2414
+ case "EC":
2415
+ check(jwk.crv, "\"crv\" (Curve) Parameter");
2416
+ check(jwk.x, "\"x\" (X Coordinate) Parameter");
2417
+ check(jwk.y, "\"y\" (Y Coordinate) Parameter");
2418
+ components = {
2419
+ crv: jwk.crv,
2420
+ kty: jwk.kty,
2421
+ x: jwk.x,
2422
+ y: jwk.y
2423
+ };
2424
+ break;
2425
+ case "OKP":
2426
+ check(jwk.crv, "\"crv\" (Subtype of Key Pair) Parameter");
2427
+ check(jwk.x, "\"x\" (Public Key) Parameter");
2428
+ components = {
2429
+ crv: jwk.crv,
2430
+ kty: jwk.kty,
2431
+ x: jwk.x
2432
+ };
2433
+ break;
2434
+ case "RSA":
2435
+ check(jwk.e, "\"e\" (Exponent) Parameter");
2436
+ check(jwk.n, "\"n\" (Modulus) Parameter");
2437
+ components = {
2438
+ e: jwk.e,
2439
+ kty: jwk.kty,
2440
+ n: jwk.n
2441
+ };
2442
+ break;
2443
+ case "oct":
2444
+ check(jwk.k, "\"k\" (Key Value) Parameter");
2445
+ components = {
2446
+ k: jwk.k,
2447
+ kty: jwk.kty
2448
+ };
2449
+ break;
2450
+ default: throw new JOSENotSupported("\"kty\" (Key Type) Parameter missing or unsupported");
2451
+ }
2452
+ const data = encode$1(JSON.stringify(components));
2453
+ return encode(await digest(digestAlgorithm, data));
2264
2454
  }
2265
2455
  //#endregion
2266
- //#region src/http.ts
2267
- const MAX_RESPONSE_BYTES = 64 * 1024;
2268
- async function requestJson(url, options) {
2269
- return (await requestJsonResponse(url, options)).value;
2456
+ //#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/util/decode_protected_header.js
2457
+ function decodeProtectedHeader(token) {
2458
+ let protectedB64u;
2459
+ if (typeof token === "string") {
2460
+ const parts = token.split(".");
2461
+ if (parts.length === 3 || parts.length === 5) [protectedB64u] = parts;
2462
+ } else if (typeof token === "object" && token) if ("protected" in token) protectedB64u = token.protected;
2463
+ else throw new TypeError("Token does not contain a Protected Header");
2464
+ try {
2465
+ if (typeof protectedB64u !== "string" || !protectedB64u) throw new Error();
2466
+ const result = JSON.parse(decoder.decode(decode(protectedB64u)));
2467
+ if (!isObject(result)) throw new Error();
2468
+ return result;
2469
+ } catch {
2470
+ throw new TypeError("Invalid Token or Protected Header formatting");
2471
+ }
2270
2472
  }
2271
- async function requestJsonResponse(url, options) {
2272
- let response;
2473
+ //#endregion
2474
+ //#region ../../node_modules/.pnpm/jose@6.2.4/node_modules/jose/dist/webapi/util/decode_jwt.js
2475
+ function decodeJwt(jwt) {
2476
+ if (typeof jwt !== "string") throw new JWTInvalid("JWTs must use Compact JWS serialization, JWT must be a string");
2477
+ const { 1: payload, length } = jwt.split(".");
2478
+ if (length === 5) throw new JWTInvalid("Only JWTs using Compact JWS serialization can be decoded");
2479
+ if (length !== 3) throw new JWTInvalid("Invalid JWT");
2480
+ if (!payload) throw new JWTInvalid("JWTs must contain a payload");
2481
+ let decoded;
2273
2482
  try {
2274
- response = await createFetch({ fetch: options.fetch }).raw(url, {
2275
- method: options.method,
2276
- headers: options.headers,
2277
- body: options.body,
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
- });
2483
+ decoded = decode(payload);
2286
2484
  } catch {
2287
- throw authorityUnavailable();
2485
+ throw new JWTInvalid("Failed to base64url decode the payload");
2288
2486
  }
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"));
2487
+ let result;
2488
+ try {
2489
+ result = JSON.parse(decoder.decode(decoded));
2490
+ } catch {
2491
+ throw new JWTInvalid("Failed to parse the decoded payload as JSON");
2294
2492
  }
2493
+ if (!isObject(result)) throw new JWTInvalid("Invalid JWT Claims Set");
2494
+ return result;
2495
+ }
2496
+ //#endregion
2497
+ //#region src/organization-presence.ts
2498
+ const id$1 = /^[A-Za-z0-9_-]{1,128}$(?![\s\S])/;
2499
+ function presenceInput(input) {
2500
+ if (!input || typeof input.applicationId !== "string" || !id$1.test(input.applicationId) || !Array.isArray(input.userIds) || input.userIds.length < 1 || input.userIds.length > 50 || input.userIds.some((value) => typeof value !== "string" || !id$1.test(value)) || new Set(input.userIds).size !== input.userIds.length) throw new TypeError("Organization presence selection is invalid");
2295
2501
  return {
2296
- value: await readJson(response, options.maxResponseBytes),
2297
- headers: response.headers
2502
+ applicationId: input.applicationId,
2503
+ userIds: [...input.userIds]
2298
2504
  };
2299
2505
  }
2300
- async function readJson(response, maximum = MAX_RESPONSE_BYTES) {
2301
- const length = response.headers.get("content-length");
2302
- if (length && (!/^\d+$/.test(length) || Number(length) > maximum)) {
2303
- await response.body?.cancel();
2304
- throw authorityUnavailable();
2305
- }
2306
- if (!response.body) throw authorityUnavailable();
2307
- const reader = response.body.getReader();
2308
- const chunks = [];
2309
- let size = 0;
2310
- try {
2311
- while (true) {
2312
- const { done, value } = await reader.read();
2313
- if (done) break;
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;
2329
- }
2506
+ function presenceProofActor(token, applicationId) {
2330
2507
  try {
2331
- return JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
2508
+ const claims = decodeJwt(token);
2509
+ if (typeof claims.sub !== "string" || !id$1.test(claims.sub) || typeof claims.sid !== "string" || !id$1.test(claims.sid) || claims.app !== applicationId) throw new Error("Invalid projection");
2510
+ return {
2511
+ userId: claims.sub,
2512
+ sessionId: claims.sid
2513
+ };
2332
2514
  } catch {
2333
- throw authorityUnavailable();
2515
+ throw new TypeError("Organization presence credential is invalid");
2334
2516
  }
2335
2517
  }
2518
+ function exact$4(value, keys) {
2519
+ return !!value && typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === keys.length && keys.every((key) => Object.hasOwn(value, key));
2520
+ }
2521
+ function normalizePresence(value, organizationId, input, actor) {
2522
+ if (!exact$4(value, [
2523
+ "organizationId",
2524
+ "applicationId",
2525
+ "actor",
2526
+ "userIds",
2527
+ "checkedAt"
2528
+ ]) || value.organizationId !== organizationId || value.applicationId !== input.applicationId || !exact$4(value.actor, ["userId", "sessionId"]) || value.actor.userId !== actor.userId || value.actor.sessionId !== actor.sessionId || !Array.isArray(value.userIds) || value.userIds.length !== input.userIds.length || value.userIds.some((userId, index) => userId !== input.userIds[index]) || typeof value.checkedAt !== "string" || !/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$(?![\s\S])/.test(value.checkedAt) || Number.isNaN(Date.parse(value.checkedAt)) || new Date(value.checkedAt).toISOString() !== value.checkedAt) throw new AuthError("identity_authority_unavailable", 503);
2529
+ return {
2530
+ organizationId,
2531
+ applicationId: input.applicationId,
2532
+ actor: { ...actor },
2533
+ userIds: [...input.userIds],
2534
+ checkedAt: new Date(value.checkedAt)
2535
+ };
2536
+ }
2537
+ //#endregion
2538
+ //#region src/application-access.ts
2539
+ const id = /^[A-Za-z0-9_-]{1,128}$(?![\s\S])/;
2540
+ function applicationAccessInput(input) {
2541
+ 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");
2542
+ return {
2543
+ applicationId: input.applicationId,
2544
+ userIds: [...input.userIds]
2545
+ };
2546
+ }
2547
+ function exact$3(value, keys) {
2548
+ return !!value && typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === keys.length && keys.every((key) => Object.hasOwn(value, key));
2549
+ }
2550
+ function normalizeApplicationAccess(value, userIds) {
2551
+ const invalid = () => new AuthError("identity_authority_unavailable", 503);
2552
+ if (!exact$3(value, ["members"]) || !Array.isArray(value.members) || value.members.length !== userIds.length) throw invalid();
2553
+ return { members: value.members.map((member, index) => {
2554
+ if (!exact$3(member, [
2555
+ "userId",
2556
+ "latestAppSessionAdmittedAt",
2557
+ "activeAppSessionCount"
2558
+ ]) || 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();
2559
+ return {
2560
+ userId: member.userId,
2561
+ latestAppSessionAdmittedAt: member.latestAppSessionAdmittedAt,
2562
+ activeAppSessionCount: member.activeAppSessionCount
2563
+ };
2564
+ }) };
2565
+ }
2566
+ //#endregion
2567
+ //#region src/google-recovery.ts
2568
+ function object(value) {
2569
+ return value !== null && typeof value === "object" && !Array.isArray(value);
2570
+ }
2571
+ function validTicket(value) {
2572
+ return typeof value === "string" && /^[A-Za-z0-9_-]{43}$/.test(value);
2573
+ }
2574
+ function googleRecoveryInput(value, complete) {
2575
+ 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);
2576
+ const social = normalizeSocialIdTokenInput({
2577
+ provider: "google",
2578
+ idToken: value.idToken.token,
2579
+ signUp: false,
2580
+ ...value.idToken.nonce === void 0 ? {} : { nonce: value.idToken.nonce }
2581
+ });
2582
+ return {
2583
+ idToken: {
2584
+ token: social.idToken,
2585
+ ...social.nonce === void 0 ? {} : { nonce: social.nonce }
2586
+ },
2587
+ ...complete ? { recoveryToken: value.recoveryToken } : {}
2588
+ };
2589
+ }
2590
+ function normalizeGoogleRecovery(value, now) {
2591
+ if (!object(value) || Object.keys(value).sort().join(",") !== "expiresAt,recoveryToken" || !validTicket(value.recoveryToken) || typeof value.expiresAt !== "string") throw authorityUnavailable();
2592
+ const expiresAt = Date.parse(value.expiresAt);
2593
+ if (!Number.isFinite(expiresAt) || expiresAt <= now || expiresAt > now + 10 * 6e4) throw authorityUnavailable();
2594
+ return {
2595
+ recoveryToken: value.recoveryToken,
2596
+ expiresAt: value.expiresAt
2597
+ };
2598
+ }
2599
+ function normalizeGoogleRecoveryCompletion(value) {
2600
+ if (!object(value) || Object.keys(value).join(",") !== "linked" || value.linked !== true) throw authorityUnavailable();
2601
+ return { linked: true };
2602
+ }
2603
+ function fromGoogleRecoveryError(value, status, retryAfter) {
2604
+ const code = object(value) ? value.code : void 0;
2605
+ if (status === 409 && code === "GOOGLE_RECOVERY_IN_PROGRESS") return new AuthError("google_recovery_in_progress", 409);
2606
+ if (status === 409 && code === "GOOGLE_RECOVERY_NOT_REQUIRED") return new AuthError("google_recovery_not_required", 409);
2607
+ if (status === 403 && code === "GOOGLE_RECOVERY_EMAIL_VERIFICATION_REQUIRED") return new AuthError("email_verification_required", 403);
2608
+ if (status === 400 && code === "GOOGLE_RECOVERY_INVALID") return new AuthError("google_recovery_invalid", 400);
2609
+ if (status === 410 && code === "GOOGLE_RECOVERY_EXPIRED") return new AuthError("google_recovery_expired", 410);
2610
+ if (status === 403 && code === "GOOGLE_RECOVERY_ACCOUNT_MISMATCH") return new AuthError("google_recovery_account_mismatch", 403);
2611
+ if (status === 401 && code === "GOOGLE_RECOVERY_FRESH_SIGN_IN_REQUIRED") return new AuthError("recent_sign_in_required", 401);
2612
+ if (code === "GOOGLE_RECOVERY_UNAVAILABLE") return authorityUnavailable();
2613
+ return fromAccountAuthorityError(value, status, retryAfter);
2614
+ }
2615
+ //#endregion
2616
+ //#region src/user-api/credential.ts
2617
+ function userApiApplication(input) {
2618
+ 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");
2619
+ return input.applicationId;
2620
+ }
2621
+ function normalizeUserApiCredential(value, startedAt) {
2622
+ 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);
2623
+ return {
2624
+ tokenType: "Bearer",
2625
+ token: value.token,
2626
+ expiresAt: new Date(startedAt + value.expiresIn * 1e3)
2627
+ };
2628
+ }
2336
2629
  //#endregion
2337
2630
  //#region src/user-api/verifier.ts
2338
2631
  const ID = /^[A-Za-z0-9_-]{1,128}$(?![\s\S])/;
@@ -3064,8 +3357,8 @@ function createServerAuth(options) {
3064
3357
  mapError: fromOrganizationMutationAuthorityError
3065
3358
  });
3066
3359
  }
3067
- async function organizationRead(path, input, normalize) {
3068
- const query = normalizeOrganizationPageInput(input);
3360
+ async function organizationRead(path, input, normalize, queryInput = normalizeOrganizationPageInput) {
3361
+ const query = queryInput(input);
3069
3362
  return normalize(await requestJson(`${joinURL(authOrigin, "api/v1/auth/organizations", path)}${query.size ? `?${query}` : ""}`, {
3070
3363
  fetch: fetchImpl,
3071
3364
  timeoutMs,
@@ -3142,6 +3435,85 @@ function createServerAuth(options) {
3142
3435
  getOrganization(organizationId) {
3143
3436
  return organizationRead(normalizeIdInput(organizationId), void 0, normalizeOrganization);
3144
3437
  },
3438
+ async authorizeOrganizationPresence(organizationId, input, serviceAssertion, options) {
3439
+ 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("Organization presence service assertion is invalid");
3440
+ const organization = normalizeIdInput(organizationId);
3441
+ const body = presenceInput(input);
3442
+ let applicationCredential;
3443
+ if (options !== void 0) {
3444
+ const supplied = options?.applicationCredential;
3445
+ 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("Organization presence credential is invalid");
3446
+ applicationCredential = supplied;
3447
+ } else {
3448
+ const startedAt = now();
3449
+ applicationCredential = normalizeUserApiCredential(await requestJson(joinURL(authOrigin, "api/v1/auth/user-api-credential"), {
3450
+ fetch: fetchImpl,
3451
+ timeoutMs,
3452
+ method: "POST",
3453
+ credentials,
3454
+ headers: {
3455
+ ...authHeaders(),
3456
+ "content-type": "application/json"
3457
+ },
3458
+ body: { applicationId: body.applicationId }
3459
+ }), startedAt).token;
3460
+ }
3461
+ const actor = presenceProofActor(applicationCredential, body.applicationId);
3462
+ return normalizePresence(await requestJson(joinURL(authOrigin, "api/v1/auth/organizations", organization, "presence/authorize"), {
3463
+ fetch: fetchImpl,
3464
+ timeoutMs,
3465
+ method: "POST",
3466
+ maxResponseBytes: 16 * 1024,
3467
+ credentials,
3468
+ headers: {
3469
+ ...authHeaders(!authorization),
3470
+ "content-type": "application/json",
3471
+ "x-finueva-application-credential": applicationCredential,
3472
+ "x-finueva-service-assertion": serviceAssertion
3473
+ },
3474
+ body,
3475
+ mapError: fromOrganizationReadAuthorityError
3476
+ }), organization, body, actor);
3477
+ },
3478
+ async getOrganizationMemberApplicationAccess(organizationId, input, serviceAssertion, options) {
3479
+ 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");
3480
+ const organization = normalizeIdInput(organizationId);
3481
+ const body = applicationAccessInput(input);
3482
+ let applicationCredential;
3483
+ if (options !== void 0) {
3484
+ const supplied = options?.applicationCredential;
3485
+ 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");
3486
+ applicationCredential = supplied;
3487
+ } else {
3488
+ const startedAt = now();
3489
+ applicationCredential = normalizeUserApiCredential(await requestJson(joinURL(authOrigin, "api/v1/auth/user-api-credential"), {
3490
+ fetch: fetchImpl,
3491
+ timeoutMs,
3492
+ method: "POST",
3493
+ credentials,
3494
+ headers: {
3495
+ ...authHeaders(),
3496
+ "content-type": "application/json"
3497
+ },
3498
+ body: { applicationId: body.applicationId }
3499
+ }), startedAt).token;
3500
+ }
3501
+ return normalizeApplicationAccess(await requestJson(joinURL(authOrigin, "api/v1/auth/organizations", organization, "members/application-access"), {
3502
+ fetch: fetchImpl,
3503
+ timeoutMs,
3504
+ method: "POST",
3505
+ maxResponseBytes: 16 * 1024,
3506
+ credentials,
3507
+ headers: {
3508
+ ...authHeaders(!authorization),
3509
+ "content-type": "application/json",
3510
+ "x-finueva-application-credential": applicationCredential,
3511
+ "x-finueva-service-assertion": serviceAssertion
3512
+ },
3513
+ body,
3514
+ mapError: fromOrganizationReadAuthorityError
3515
+ }), body.userIds);
3516
+ },
3145
3517
  async getOrganizationMemberAuthority(organizationId, memberId) {
3146
3518
  const organization = normalizeIdInput(organizationId);
3147
3519
  const member = normalizeIdInput(memberId);
@@ -3316,7 +3688,7 @@ function createServerAuth(options) {
3316
3688
  }));
3317
3689
  },
3318
3690
  listOrganizationMembers(organizationId, input) {
3319
- return organizationRead(`${normalizeIdInput(organizationId)}/members`, input, normalizeOrganizationMembers);
3691
+ return organizationRead(`${normalizeIdInput(organizationId)}/members`, input, normalizeOrganizationMembers, normalizeOrganizationMemberPageInput);
3320
3692
  },
3321
3693
  listOrganizationTeams(organizationId, input) {
3322
3694
  return organizationRead(`${normalizeIdInput(organizationId)}/teams`, input, normalizeOrganizationTeams);
@@ -3481,4 +3853,4 @@ function authAuthorizationHeader(value) {
3481
3853
  return value;
3482
3854
  }
3483
3855
  //#endregion
3484
- export { AuthError, createDriveProvisioningAuth, createDriveRecipientAuth, createIdentityResolverAuth, createMembershipResolverAuth, createServerAuth, createUserApiVerifier };
3856
+ export { AuthError, createAccountProductOperationAuth, createDriveProvisioningAuth, createDriveRecipientAuth, createIdentityResolverAuth, createMembershipResolverAuth, createServerAuth, createUserApiVerifier };