@finueva/auth 0.19.0 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -307,6 +307,18 @@ return new Response(null, { status: 303, headers });
307
307
 
308
308
  Call `applyCookies()` after server `signOut()`, `acceptInvitation()`, and `signInWithSocialIdToken()`.
309
309
 
310
+ ## Recover A Google Account Conflict
311
+
312
+ Use the request-scoped server client. If Google sign-in reports an account conflict, call `startGoogleAccountRecovery({ idToken: { token, nonce } })`. Auth verifies the Google identity and confirms that an existing verified password account requires linking. A generic sign-in error alone does not authorize recovery.
313
+
314
+ The result contains an opaque `recoveryToken` and an ISO `expiresAt`. Keep the result and Google ID token in short-lived encrypted server-managed state. Do not put them in URLs, logs, or browser storage.
315
+
316
+ Ask the user to sign in to the existing account with its password. Complete the configured second factor. Then create a new request-scoped client with that session and call `completeGoogleAccountRecovery({ recoveryToken, idToken: { token, nonce } })`. Auth requires a fresh password authentication after the recovery request. An old session or a different account cannot complete recovery. The result is `{ linked: true }`; the current session remains in use.
317
+
318
+ If completion returns `google_recovery_in_progress`, retain the current session and recovery state. A retry can confirm a committed link. Auth does not repeat an uncertain linking mutation. If the original attempt cannot finish, wait for its ten-minute expiry before restarting.
319
+
320
+ Recovery is cookie-only and bound to the registered app origin. It does not enable implicit linking or link users by an email match alone. If recovery expires, restart Google sign-in. If email verification is required, complete the existing account's verification first.
321
+
310
322
  ## Resolve A Drive Recipient
311
323
 
312
324
  Use the separate server client. Before lookup, Drive must check the caller's current permission to manage the item's shares. Recipient resolution does not grant file access.
package/dist/device.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { At as AuthError, B as OrganizationMember, D as DriveCredential, Dt as UpdateOrganizationTeamDisplayInput, Et as UpdateOrganizationDisplayInput, G as OrganizationTeam, H as OrganizationMemberPage, J as OrganizationTeamPage, K as OrganizationTeamDisplay, L as OrganizationDisplay, Mt as AuthErrorStatus, Nt as UserApiCredential, O as DriveCredentialInput, Ot as UpdateProfileInput, Pt as UserApiCredentialInput, R as OrganizationInvitation, S as CreatedOrganizationTeam, U as OrganizationPage, V as OrganizationMemberAuthority, W as OrganizationPageInput, X as PasskeyInventory, b as CreatedOrganization, c as AuthSessionInventory, i as AuthOrganization, jt as AuthErrorCode, m as CeremonyHandoffInput, ot as ReceivedOrganizationInvitation, p as CeremonyHandoff, q as OrganizationTeamMemberPage, s as AuthSession, st as ReceivedOrganizationInvitationPage, vt as SocialIdTokenInput, wt as TwoFactorStatus, x as CreatedOrganizationMemberInvitation, y as CreateOrganizationMemberInvitationInput, yt as SocialIdTokenProvider, z as OrganizationInvitationPage } from "./types-BEgD_Js1.js";
1
+ import { At as AuthError, B as OrganizationMember, D as DriveCredential, Dt as UpdateOrganizationTeamDisplayInput, Et as UpdateOrganizationDisplayInput, G as OrganizationTeam, H as OrganizationMemberPage, J as OrganizationTeamPage, K as OrganizationTeamDisplay, L as OrganizationDisplay, Mt as AuthErrorStatus, Nt as UserApiCredential, O as DriveCredentialInput, Ot as UpdateProfileInput, Pt as UserApiCredentialInput, R as OrganizationInvitation, S as CreatedOrganizationTeam, U as OrganizationPage, V as OrganizationMemberAuthority, W as OrganizationPageInput, X as PasskeyInventory, b as CreatedOrganization, c as AuthSessionInventory, i as AuthOrganization, jt as AuthErrorCode, m as CeremonyHandoffInput, ot as ReceivedOrganizationInvitation, p as CeremonyHandoff, q as OrganizationTeamMemberPage, s as AuthSession, st as ReceivedOrganizationInvitationPage, vt as SocialIdTokenInput, wt as TwoFactorStatus, x as CreatedOrganizationMemberInvitation, y as CreateOrganizationMemberInvitationInput, yt as SocialIdTokenProvider, z as OrganizationInvitationPage } from "./types-Cv_qxcBP.js";
2
2
  //#region src/device.d.ts
3
3
  type DeviceAuthorizationErrorCode = "device_access_denied" | "device_authorization_cancelled" | "device_code_expired" | "invalid_device_authorization" | "identity_authority_unavailable";
4
4
  declare class DeviceAuthorizationError extends Error {
package/dist/device.js CHANGED
@@ -178,6 +178,11 @@ const messages = {
178
178
  invalid_credentials: "The credentials are invalid.",
179
179
  invalid_auth_input: "The authentication input is invalid.",
180
180
  account_conflict: "The account is not available.",
181
+ google_recovery_in_progress: "A Google connection is already being completed. Return to that sign-in, or wait up to ten minutes and restart.",
182
+ google_recovery_not_required: "Google account recovery is not required.",
183
+ google_recovery_invalid: "The Google account recovery request is invalid.",
184
+ google_recovery_expired: "Google account recovery has expired. Start Google sign-in again.",
185
+ google_recovery_account_mismatch: "Sign in to the existing account associated with this Google identity.",
181
186
  password_reset_invalid: "The password reset request is invalid.",
182
187
  authentication_required: "Authentication is required.",
183
188
  request_origin_denied: "The request origin is not allowed.",
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { $ as PlatformBootstrapRoleChangeInput, A as FinuevaAuthClient, At as AuthError, B as OrganizationMember, C as DeclineInvitationInput, Ct as TwoFactorEnrollment, D as DriveCredential, Dt as UpdateOrganizationTeamDisplayInput, E as DepartedOrganizationMemberPage, Et as UpdateOrganizationDisplayInput, F as OrganizationClosureStartInput, G as OrganizationTeam, H as OrganizationMemberPage, I as OrganizationDeparture, J as OrganizationTeamPage, K as OrganizationTeamDisplay, L as OrganizationDisplay, M as InvitationDecline, Mt as AuthErrorStatus, N as OrganizationClosure, Nt as UserApiCredential, O as DriveCredentialInput, Ot as UpdateProfileInput, P as OrganizationClosureCancelInput, Pt as UserApiCredentialInput, Q as PersonalWorkspaceSelection, R as OrganizationInvitation, S as CreatedOrganizationTeam, St as SuspendedOrganizationMemberStatus, T as DepartedOrganizationMember, Tt as TwoFactorStepUpInput, U as OrganizationPage, V as OrganizationMemberAuthority, W as OrganizationPageInput, X as PasskeyInventory, Y as OrganizationWorkspaceSelection, Z as PasskeySummary, _ as ClosingOrganization, _t as SignInInput, a as AuthPersistence, at as PlatformStatus, b as CreatedOrganization, bt as SuspendedOrganizationMember, c as AuthSessionInventory, ct as RecentAuthenticationStatus, d as AuthUser, dt as ResentOrganizationInvitation, et as PlatformRole, f as CanceledOrganizationInvitation, ft as RestoredOrganizationMember, g as CeremonyReturnInput, gt as SendVerificationEmailInput, h as CeremonyRecentAuthenticationRequest, ht as ScimCredentialState, i as AuthOrganization, it as PlatformRoleFirstApproval, j as InvitationAcceptance, jt as AuthErrorCode, k as EnterpriseConnection, kt as WorkspaceSelection, l as AuthSessionSummary, lt as RemovedOrganizationMember, m as CeremonyHandoffInput, mt as ScimCredentialIssuance, n as AddedOrganizationTeamMember, nt as PlatformRoleApproval, o as AuthPersistenceDriver, ot as ReceivedOrganizationInvitation, p as CeremonyHandoff, pt as RotateScimCredentialInput, q as OrganizationTeamMemberPage, r as AuthClientOptions, rt as PlatformRoleChangeRecentAuthenticationInput, s as AuthSession, st as ReceivedOrganizationInvitationPage, t as AcceptInvitationInput, tt as PlatformRoleApplied, u as AuthState, ut as RemovedOrganizationTeamMember, v as ClosingOrganizationList, vt as SocialIdTokenInput, w as DeletedOrganizationTeam, wt as TwoFactorStatus, x as CreatedOrganizationMemberInvitation, xt as SuspendedOrganizationMemberPage, y as CreateOrganizationMemberInvitationInput, yt as SocialIdTokenProvider, z as OrganizationInvitationPage } from "./types-BEgD_Js1.js";
1
+ import { $ as PlatformBootstrapRoleChangeInput, A as FinuevaAuthClient, At as AuthError, B as OrganizationMember, C as DeclineInvitationInput, Ct as TwoFactorEnrollment, D as DriveCredential, Dt as UpdateOrganizationTeamDisplayInput, E as DepartedOrganizationMemberPage, Et as UpdateOrganizationDisplayInput, F as OrganizationClosureStartInput, G as OrganizationTeam, H as OrganizationMemberPage, I as OrganizationDeparture, J as OrganizationTeamPage, K as OrganizationTeamDisplay, L as OrganizationDisplay, M as InvitationDecline, Mt as AuthErrorStatus, N as OrganizationClosure, Nt as UserApiCredential, O as DriveCredentialInput, Ot as UpdateProfileInput, P as OrganizationClosureCancelInput, Pt as UserApiCredentialInput, Q as PersonalWorkspaceSelection, R as OrganizationInvitation, S as CreatedOrganizationTeam, St as SuspendedOrganizationMemberStatus, T as DepartedOrganizationMember, Tt as TwoFactorStepUpInput, U as OrganizationPage, V as OrganizationMemberAuthority, W as OrganizationPageInput, X as PasskeyInventory, Y as OrganizationWorkspaceSelection, Z as PasskeySummary, _ as ClosingOrganization, _t as SignInInput, a as AuthPersistence, at as PlatformStatus, b as CreatedOrganization, bt as SuspendedOrganizationMember, c as AuthSessionInventory, ct as RecentAuthenticationStatus, d as AuthUser, dt as ResentOrganizationInvitation, et as PlatformRole, f as CanceledOrganizationInvitation, ft as RestoredOrganizationMember, g as CeremonyReturnInput, gt as SendVerificationEmailInput, h as CeremonyRecentAuthenticationRequest, ht as ScimCredentialState, i as AuthOrganization, it as PlatformRoleFirstApproval, j as InvitationAcceptance, jt as AuthErrorCode, k as EnterpriseConnection, kt as WorkspaceSelection, l as AuthSessionSummary, lt as RemovedOrganizationMember, m as CeremonyHandoffInput, mt as ScimCredentialIssuance, n as AddedOrganizationTeamMember, nt as PlatformRoleApproval, o as AuthPersistenceDriver, ot as ReceivedOrganizationInvitation, p as CeremonyHandoff, pt as RotateScimCredentialInput, q as OrganizationTeamMemberPage, r as AuthClientOptions, rt as PlatformRoleChangeRecentAuthenticationInput, s as AuthSession, st as ReceivedOrganizationInvitationPage, t as AcceptInvitationInput, tt as PlatformRoleApplied, u as AuthState, ut as RemovedOrganizationTeamMember, v as ClosingOrganizationList, vt as SocialIdTokenInput, w as DeletedOrganizationTeam, wt as TwoFactorStatus, x as CreatedOrganizationMemberInvitation, xt as SuspendedOrganizationMemberPage, y as CreateOrganizationMemberInvitationInput, yt as SocialIdTokenProvider, z as OrganizationInvitationPage } from "./types-Cv_qxcBP.js";
2
2
  //#region src/client.d.ts
3
3
  declare function createAuthClient(options: AuthClientOptions): FinuevaAuthClient;
4
4
  //#endregion
package/dist/index.js CHANGED
@@ -2537,6 +2537,11 @@ const messages = {
2537
2537
  invalid_credentials: "The credentials are invalid.",
2538
2538
  invalid_auth_input: "The authentication input is invalid.",
2539
2539
  account_conflict: "The account is not available.",
2540
+ google_recovery_in_progress: "A Google connection is already being completed. Return to that sign-in, or wait up to ten minutes and restart.",
2541
+ google_recovery_not_required: "Google account recovery is not required.",
2542
+ google_recovery_invalid: "The Google account recovery request is invalid.",
2543
+ google_recovery_expired: "Google account recovery has expired. Start Google sign-in again.",
2544
+ google_recovery_account_mismatch: "Sign in to the existing account associated with this Google identity.",
2540
2545
  password_reset_invalid: "The password reset request is invalid.",
2541
2546
  authentication_required: "Authentication is required.",
2542
2547
  request_origin_denied: "The request origin is not allowed.",
package/dist/server.d.ts CHANGED
@@ -1,4 +1,19 @@
1
- import { At as AuthError, B as OrganizationMember, C as DeclineInvitationInput, D as DriveCredential, Dt as UpdateOrganizationTeamDisplayInput, Et as UpdateOrganizationDisplayInput, G as OrganizationTeam, H as OrganizationMemberPage, I as OrganizationDeparture, J as OrganizationTeamPage, K as OrganizationTeamDisplay, L as OrganizationDisplay, M as InvitationDecline, Mt as AuthErrorStatus, Nt as UserApiCredential, O as DriveCredentialInput, Pt as UserApiCredentialInput, Q as PersonalWorkspaceSelection, R as OrganizationInvitation, S as CreatedOrganizationTeam, U as OrganizationPage, V as OrganizationMemberAuthority, W as OrganizationPageInput, Y as OrganizationWorkspaceSelection, b as CreatedOrganization, d as AuthUser, dt as ResentOrganizationInvitation, f as CanceledOrganizationInvitation, i as AuthOrganization, j as InvitationAcceptance, jt as AuthErrorCode, kt as WorkspaceSelection, lt as RemovedOrganizationMember, n as AddedOrganizationTeamMember, ot as ReceivedOrganizationInvitation, q as OrganizationTeamMemberPage, s as AuthSession, st as ReceivedOrganizationInvitationPage, t as AcceptInvitationInput, ut as RemovedOrganizationTeamMember, vt as SocialIdTokenInput, w as DeletedOrganizationTeam, x as CreatedOrganizationMemberInvitation, y as CreateOrganizationMemberInvitationInput, yt as SocialIdTokenProvider, z as OrganizationInvitationPage } from "./types-BEgD_Js1.js";
1
+ import { At as AuthError, B as OrganizationMember, C as DeclineInvitationInput, D as DriveCredential, Dt as UpdateOrganizationTeamDisplayInput, Et as UpdateOrganizationDisplayInput, G as OrganizationTeam, H as OrganizationMemberPage, I as OrganizationDeparture, J as OrganizationTeamPage, K as OrganizationTeamDisplay, L as OrganizationDisplay, M as InvitationDecline, Mt as AuthErrorStatus, Nt as UserApiCredential, O as DriveCredentialInput, Pt as UserApiCredentialInput, Q as PersonalWorkspaceSelection, R as OrganizationInvitation, S as CreatedOrganizationTeam, U as OrganizationPage, V as OrganizationMemberAuthority, W as OrganizationPageInput, Y as OrganizationWorkspaceSelection, b as CreatedOrganization, d as AuthUser, dt as ResentOrganizationInvitation, f as CanceledOrganizationInvitation, i as AuthOrganization, j as InvitationAcceptance, jt as AuthErrorCode, kt as WorkspaceSelection, lt as RemovedOrganizationMember, n as AddedOrganizationTeamMember, ot as ReceivedOrganizationInvitation, q as OrganizationTeamMemberPage, s as AuthSession, st as ReceivedOrganizationInvitationPage, t as AcceptInvitationInput, ut as RemovedOrganizationTeamMember, vt as SocialIdTokenInput, w as DeletedOrganizationTeam, x as CreatedOrganizationMemberInvitation, y as CreateOrganizationMemberInvitationInput, yt as SocialIdTokenProvider, z as OrganizationInvitationPage } from "./types-Cv_qxcBP.js";
2
+ //#region src/google-recovery.d.ts
3
+ interface GoogleAccountRecoveryInput {
4
+ idToken: {
5
+ token: string;
6
+ nonce?: string;
7
+ };
8
+ }
9
+ interface CompleteGoogleAccountRecoveryInput extends GoogleAccountRecoveryInput {
10
+ recoveryToken: string;
11
+ }
12
+ interface GoogleAccountRecovery {
13
+ recoveryToken: string;
14
+ expiresAt: string;
15
+ }
16
+ //#endregion
2
17
  //#region src/user-api/verifier.d.ts
3
18
  interface UserApiIdentity {
4
19
  userId: string;
@@ -150,10 +165,14 @@ interface FinuevaServerAuth {
150
165
  listReceivedInvitations(input?: OrganizationPageInput): Promise<ReceivedOrganizationInvitationPage>;
151
166
  getReceivedInvitation(invitationId: string): Promise<ReceivedOrganizationInvitation>;
152
167
  signInWithSocialIdToken(input: SocialIdTokenInput): Promise<ServerSocialIdTokenSession>;
168
+ startGoogleAccountRecovery(input: GoogleAccountRecoveryInput): Promise<GoogleAccountRecovery>;
169
+ completeGoogleAccountRecovery(input: CompleteGoogleAccountRecoveryInput): Promise<{
170
+ linked: true;
171
+ }>;
153
172
  getDriveCredential(input: DriveCredentialInput): Promise<DriveCredential>;
154
173
  getUserApiCredential(input: UserApiCredentialInput): Promise<UserApiCredential>;
155
174
  signOut(): Promise<ServerSignOutResult>;
156
175
  }
157
176
  declare function createServerAuth(options: ServerAuthOptions): FinuevaServerAuth;
158
177
  //#endregion
159
- export { type AcceptInvitationInput, type AddedOrganizationTeamMember, AuthError, type AuthErrorCode, type AuthErrorStatus, type AuthOrganization, type AuthSession, type AuthUser, type CanceledOrganizationInvitation, type CreateOrganizationMemberInvitationInput, type CreatedOrganization, type CreatedOrganizationMemberInvitation, type CreatedOrganizationTeam, type DeclineInvitationInput, type DeletedOrganizationTeam, type DriveCredential, type DriveCredentialInput, type DriveProvisioningAuthOptions, type DriveProvisioningCredential, type DriveRecipient, type DriveRecipientAuthOptions, type FinuevaDriveProvisioningAuth, type FinuevaDriveRecipientAuth, type FinuevaIdentityResolverAuth, type FinuevaMembershipResolverAuth, FinuevaServerAuth, type IdentityResolverAuthOptions, type InvitationAcceptance, type InvitationDecline, type MembershipResolverAuthOptions, type OrganizationDeparture, type OrganizationDisplay, type OrganizationInvitation, type OrganizationInvitationPage, type OrganizationMember, type OrganizationMemberAuthority, type OrganizationMemberPage, type OrganizationPage, type OrganizationPageInput, type OrganizationTeam, type OrganizationTeamDisplay, type OrganizationTeamMemberPage, type OrganizationTeamPage, type OrganizationWorkspaceSelection, type PersonalWorkspaceSelection, type ReceivedOrganizationInvitation, type ReceivedOrganizationInvitationPage, type RemovedOrganizationMember, type RemovedOrganizationTeamMember, type ResentOrganizationInvitation, type ResolveDriveRecipientInput, type ResolveIdentityInput, type ResolveMembershipInput, type ResolvedIdentity, type ResolvedMembership, type ResolvedMembershipRole, ServerAuthOptions, ServerInvitationAcceptance, ServerSignOutResult, ServerSocialIdTokenSession, type SocialIdTokenInput, type SocialIdTokenProvider, type UpdateOrganizationDisplayInput, type UpdateOrganizationTeamDisplayInput, type UserApiCredential, type UserApiCredentialInput, type UserApiIdentity, type UserApiVerifierOptions, type WorkspaceSelection, createDriveProvisioningAuth, createDriveRecipientAuth, createIdentityResolverAuth, createMembershipResolverAuth, createServerAuth, createUserApiVerifier };
178
+ export { type AcceptInvitationInput, type AddedOrganizationTeamMember, AuthError, type AuthErrorCode, type AuthErrorStatus, type AuthOrganization, type AuthSession, type AuthUser, type CanceledOrganizationInvitation, type CompleteGoogleAccountRecoveryInput, type CreateOrganizationMemberInvitationInput, type CreatedOrganization, type CreatedOrganizationMemberInvitation, type CreatedOrganizationTeam, type DeclineInvitationInput, type DeletedOrganizationTeam, type DriveCredential, type DriveCredentialInput, type DriveProvisioningAuthOptions, type DriveProvisioningCredential, type DriveRecipient, type DriveRecipientAuthOptions, type FinuevaDriveProvisioningAuth, type FinuevaDriveRecipientAuth, type FinuevaIdentityResolverAuth, type FinuevaMembershipResolverAuth, FinuevaServerAuth, type GoogleAccountRecovery, type GoogleAccountRecoveryInput, type IdentityResolverAuthOptions, type InvitationAcceptance, type InvitationDecline, type MembershipResolverAuthOptions, type OrganizationDeparture, type OrganizationDisplay, type OrganizationInvitation, type OrganizationInvitationPage, type OrganizationMember, type OrganizationMemberAuthority, type OrganizationMemberPage, type OrganizationPage, type OrganizationPageInput, type OrganizationTeam, type OrganizationTeamDisplay, type OrganizationTeamMemberPage, type OrganizationTeamPage, type OrganizationWorkspaceSelection, type PersonalWorkspaceSelection, type ReceivedOrganizationInvitation, type ReceivedOrganizationInvitationPage, type RemovedOrganizationMember, type RemovedOrganizationTeamMember, type ResentOrganizationInvitation, type ResolveDriveRecipientInput, type ResolveIdentityInput, type ResolveMembershipInput, type ResolvedIdentity, type ResolvedMembership, type ResolvedMembershipRole, ServerAuthOptions, ServerInvitationAcceptance, ServerSignOutResult, ServerSocialIdTokenSession, type SocialIdTokenInput, type SocialIdTokenProvider, type UpdateOrganizationDisplayInput, type UpdateOrganizationTeamDisplayInput, type UserApiCredential, type UserApiCredentialInput, type UserApiIdentity, type UserApiVerifierOptions, type WorkspaceSelection, createDriveProvisioningAuth, createDriveRecipientAuth, createIdentityResolverAuth, createMembershipResolverAuth, createServerAuth, createUserApiVerifier };
package/dist/server.js CHANGED
@@ -1,183 +1,13 @@
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, "|");
13
- }
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");
16
- }
17
- function encodeQueryKey(text) {
18
- return encodeQueryValue(text).replace(EQUAL_RE, "%3D");
19
- }
20
- function decode$1(text = "") {
21
- try {
22
- return decodeURIComponent("" + text);
23
- } catch {
24
- return "" + text;
25
- }
26
- }
27
- function decodeQueryKey(text) {
28
- return decode$1(text.replace(PLUS_RE, " "));
29
- }
30
- function decodeQueryValue(text) {
31
- return decode$1(text.replace(PLUS_RE, " "));
32
- }
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];
45
- }
46
- return object;
47
- }
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)}`;
53
- }
54
- function stringifyQuery(query) {
55
- return Object.keys(query).filter((k) => query[k] !== void 0).map((k) => encodeQueryItem(k, query[k])).filter(Boolean).join("&");
56
- }
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);
66
- }
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);
80
- }
81
- const [s0, ...s] = path.split("?");
82
- return ((s0.endsWith("/") ? s0.slice(0, -1) : s0) || "/") + (s.length > 0 ? `?${s.join("?")}` : "") + fragment;
83
- }
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;
97
- }
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;
104
- }
105
- return joinURL(_base, input);
106
- }
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);
114
- }
115
- function isEmptyURL(url) {
116
- return !url || url === "/";
117
- }
118
- function isNonEmptyURL(url) {
119
- return url && url !== "/";
120
- }
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;
128
- }
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
- };
143
- }
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);
149
- return {
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
157
- };
158
- }
159
- function parsePath(input = "") {
160
- const [pathname = "", search = "", hash = ""] = (input.match(/([^#?]*)(\?[^#]*)?(#.*)?/) || []).splice(1);
161
- return {
162
- pathname,
163
- search,
164
- hash
165
- };
166
- }
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;
174
- }
175
- //#endregion
176
1
  //#region src/errors.ts
177
2
  const messages = {
178
3
  invalid_credentials: "The credentials are invalid.",
179
4
  invalid_auth_input: "The authentication input is invalid.",
180
5
  account_conflict: "The account is not available.",
6
+ google_recovery_in_progress: "A Google connection is already being completed. Return to that sign-in, or wait up to ten minutes and restart.",
7
+ google_recovery_not_required: "Google account recovery is not required.",
8
+ google_recovery_invalid: "The Google account recovery request is invalid.",
9
+ google_recovery_expired: "Google account recovery has expired. Start Google sign-in again.",
10
+ google_recovery_account_mismatch: "Sign in to the existing account associated with this Google identity.",
181
11
  password_reset_invalid: "The password reset request is invalid.",
182
12
  authentication_required: "Authentication is required.",
183
13
  request_origin_denied: "The request origin is not allowed.",
@@ -877,6 +707,229 @@ function isObject$1(value) {
877
707
  return typeof value === "object" && value !== null && !Array.isArray(value);
878
708
  }
879
709
  //#endregion
710
+ //#region src/google-recovery.ts
711
+ function object(value) {
712
+ return value !== null && typeof value === "object" && !Array.isArray(value);
713
+ }
714
+ function validTicket(value) {
715
+ return typeof value === "string" && /^[A-Za-z0-9_-]{43}$/.test(value);
716
+ }
717
+ function googleRecoveryInput(value, complete) {
718
+ 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);
719
+ const social = normalizeSocialIdTokenInput({
720
+ provider: "google",
721
+ idToken: value.idToken.token,
722
+ signUp: false,
723
+ ...value.idToken.nonce === void 0 ? {} : { nonce: value.idToken.nonce }
724
+ });
725
+ return {
726
+ idToken: {
727
+ token: social.idToken,
728
+ ...social.nonce === void 0 ? {} : { nonce: social.nonce }
729
+ },
730
+ ...complete ? { recoveryToken: value.recoveryToken } : {}
731
+ };
732
+ }
733
+ function normalizeGoogleRecovery(value, now) {
734
+ if (!object(value) || Object.keys(value).sort().join(",") !== "expiresAt,recoveryToken" || !validTicket(value.recoveryToken) || typeof value.expiresAt !== "string") throw authorityUnavailable();
735
+ const expiresAt = Date.parse(value.expiresAt);
736
+ if (!Number.isFinite(expiresAt) || expiresAt <= now || expiresAt > now + 10 * 6e4) throw authorityUnavailable();
737
+ return {
738
+ recoveryToken: value.recoveryToken,
739
+ expiresAt: value.expiresAt
740
+ };
741
+ }
742
+ function normalizeGoogleRecoveryCompletion(value) {
743
+ if (!object(value) || Object.keys(value).join(",") !== "linked" || value.linked !== true) throw authorityUnavailable();
744
+ return { linked: true };
745
+ }
746
+ function fromGoogleRecoveryError(value, status, retryAfter) {
747
+ const code = object(value) ? value.code : void 0;
748
+ if (status === 409 && code === "GOOGLE_RECOVERY_IN_PROGRESS") return new AuthError("google_recovery_in_progress", 409);
749
+ if (status === 409 && code === "GOOGLE_RECOVERY_NOT_REQUIRED") return new AuthError("google_recovery_not_required", 409);
750
+ if (status === 403 && code === "GOOGLE_RECOVERY_EMAIL_VERIFICATION_REQUIRED") return new AuthError("email_verification_required", 403);
751
+ if (status === 400 && code === "GOOGLE_RECOVERY_INVALID") return new AuthError("google_recovery_invalid", 400);
752
+ if (status === 410 && code === "GOOGLE_RECOVERY_EXPIRED") return new AuthError("google_recovery_expired", 410);
753
+ if (status === 403 && code === "GOOGLE_RECOVERY_ACCOUNT_MISMATCH") return new AuthError("google_recovery_account_mismatch", 403);
754
+ if (status === 401 && code === "GOOGLE_RECOVERY_FRESH_SIGN_IN_REQUIRED") return new AuthError("recent_sign_in_required", 401);
755
+ if (code === "GOOGLE_RECOVERY_UNAVAILABLE") return authorityUnavailable();
756
+ return fromAccountAuthorityError(value, status, retryAfter);
757
+ }
758
+ String.fromCharCode;
759
+ const HASH_RE = /#/g;
760
+ const AMPERSAND_RE = /&/g;
761
+ const SLASH_RE = /\//g;
762
+ const EQUAL_RE = /=/g;
763
+ const PLUS_RE = /\+/g;
764
+ const ENC_CARET_RE = /%5e/gi;
765
+ const ENC_BACKTICK_RE = /%60/gi;
766
+ const ENC_PIPE_RE = /%7c/gi;
767
+ const ENC_SPACE_RE = /%20/gi;
768
+ function encode$2(text) {
769
+ return encodeURI("" + text).replace(ENC_PIPE_RE, "|");
770
+ }
771
+ function encodeQueryValue(input) {
772
+ 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");
773
+ }
774
+ function encodeQueryKey(text) {
775
+ return encodeQueryValue(text).replace(EQUAL_RE, "%3D");
776
+ }
777
+ function decode$1(text = "") {
778
+ try {
779
+ return decodeURIComponent("" + text);
780
+ } catch {
781
+ return "" + text;
782
+ }
783
+ }
784
+ function decodeQueryKey(text) {
785
+ return decode$1(text.replace(PLUS_RE, " "));
786
+ }
787
+ function decodeQueryValue(text) {
788
+ return decode$1(text.replace(PLUS_RE, " "));
789
+ }
790
+ function parseQuery(parametersString = "") {
791
+ const object = Object.create(null);
792
+ if (parametersString[0] === "?") parametersString = parametersString.slice(1);
793
+ for (const parameter of parametersString.split("&")) {
794
+ const s = parameter.match(/([^=]+)=?(.*)/) || [];
795
+ if (s.length < 2) continue;
796
+ const key = decodeQueryKey(s[1]);
797
+ if (key === "__proto__" || key === "constructor") continue;
798
+ const value = decodeQueryValue(s[2] || "");
799
+ if (object[key] === void 0) object[key] = value;
800
+ else if (Array.isArray(object[key])) object[key].push(value);
801
+ else object[key] = [object[key], value];
802
+ }
803
+ return object;
804
+ }
805
+ function encodeQueryItem(key, value) {
806
+ if (typeof value === "number" || typeof value === "boolean") value = String(value);
807
+ if (!value) return encodeQueryKey(key);
808
+ if (Array.isArray(value)) return value.map((_value) => `${encodeQueryKey(key)}=${encodeQueryValue(_value)}`).join("&");
809
+ return `${encodeQueryKey(key)}=${encodeQueryValue(value)}`;
810
+ }
811
+ function stringifyQuery(query) {
812
+ return Object.keys(query).filter((k) => query[k] !== void 0).map((k) => encodeQueryItem(k, query[k])).filter(Boolean).join("&");
813
+ }
814
+ const PROTOCOL_STRICT_REGEX = /^[\s\w\0+.-]{2,}:([/\\]{1,2})/;
815
+ const PROTOCOL_REGEX = /^[\s\w\0+.-]{2,}:([/\\]{2})?/;
816
+ const PROTOCOL_RELATIVE_REGEX = /^([/\\]\s*){2,}[^/\\]/;
817
+ const TRAILING_SLASH_RE = /\/$|\/\?|\/#/;
818
+ const JOIN_LEADING_SLASH_RE = /^\.?\//;
819
+ function hasProtocol(inputString, opts = {}) {
820
+ if (typeof opts === "boolean") opts = { acceptRelative: opts };
821
+ if (opts.strict) return PROTOCOL_STRICT_REGEX.test(inputString);
822
+ return PROTOCOL_REGEX.test(inputString) || (opts.acceptRelative ? PROTOCOL_RELATIVE_REGEX.test(inputString) : false);
823
+ }
824
+ function hasTrailingSlash(input = "", respectQueryAndFragment) {
825
+ if (!respectQueryAndFragment) return input.endsWith("/");
826
+ return TRAILING_SLASH_RE.test(input);
827
+ }
828
+ function withoutTrailingSlash(input = "", respectQueryAndFragment) {
829
+ if (!respectQueryAndFragment) return (hasTrailingSlash(input) ? input.slice(0, -1) : input) || "/";
830
+ if (!hasTrailingSlash(input, true)) return input || "/";
831
+ let path = input;
832
+ let fragment = "";
833
+ const fragmentIndex = input.indexOf("#");
834
+ if (fragmentIndex !== -1) {
835
+ path = input.slice(0, fragmentIndex);
836
+ fragment = input.slice(fragmentIndex);
837
+ }
838
+ const [s0, ...s] = path.split("?");
839
+ return ((s0.endsWith("/") ? s0.slice(0, -1) : s0) || "/") + (s.length > 0 ? `?${s.join("?")}` : "") + fragment;
840
+ }
841
+ function withTrailingSlash(input = "", respectQueryAndFragment) {
842
+ if (!respectQueryAndFragment) return input.endsWith("/") ? input : input + "/";
843
+ if (hasTrailingSlash(input, true)) return input || "/";
844
+ let path = input;
845
+ let fragment = "";
846
+ const fragmentIndex = input.indexOf("#");
847
+ if (fragmentIndex !== -1) {
848
+ path = input.slice(0, fragmentIndex);
849
+ fragment = input.slice(fragmentIndex);
850
+ if (!path) return fragment;
851
+ }
852
+ const [s0, ...s] = path.split("?");
853
+ return s0 + "/" + (s.length > 0 ? `?${s.join("?")}` : "") + fragment;
854
+ }
855
+ function withBase(input, base) {
856
+ if (isEmptyURL(base) || hasProtocol(input)) return input;
857
+ const _base = withoutTrailingSlash(base);
858
+ if (input.startsWith(_base)) {
859
+ const nextChar = input[_base.length];
860
+ if (!nextChar || nextChar === "/" || nextChar === "?") return input;
861
+ }
862
+ return joinURL(_base, input);
863
+ }
864
+ function withQuery(input, query) {
865
+ const parsed = parseURL(input);
866
+ parsed.search = stringifyQuery({
867
+ ...parseQuery(parsed.search),
868
+ ...query
869
+ });
870
+ return stringifyParsedURL(parsed);
871
+ }
872
+ function isEmptyURL(url) {
873
+ return !url || url === "/";
874
+ }
875
+ function isNonEmptyURL(url) {
876
+ return url && url !== "/";
877
+ }
878
+ function joinURL(base, ...input) {
879
+ let url = base || "";
880
+ for (const segment of input.filter((url2) => isNonEmptyURL(url2))) if (url) {
881
+ const _segment = segment.replace(JOIN_LEADING_SLASH_RE, "");
882
+ url = withTrailingSlash(url) + _segment;
883
+ } else url = segment;
884
+ return url;
885
+ }
886
+ const protocolRelative = Symbol.for("ufo:protocolRelative");
887
+ function parseURL(input = "", defaultProto) {
888
+ const _specialProtoMatch = input.match(/^[\s\0]*(blob:|data:|javascript:|vbscript:)(.*)/i);
889
+ if (_specialProtoMatch) {
890
+ const [, _proto, _pathname = ""] = _specialProtoMatch;
891
+ return {
892
+ protocol: _proto.toLowerCase(),
893
+ pathname: _pathname,
894
+ href: _proto + _pathname,
895
+ auth: "",
896
+ host: "",
897
+ search: "",
898
+ hash: ""
899
+ };
900
+ }
901
+ if (!hasProtocol(input, { acceptRelative: true })) return defaultProto ? parseURL(defaultProto + input) : parsePath(input);
902
+ const [, protocol = "", auth, hostAndPath = ""] = input.replace(/\\/g, "/").match(/^[\s\0]*([\w+.-]{2,}:)?\/\/([^/@]+@)?(.*)/) || [];
903
+ let [, host = "", path = ""] = hostAndPath.match(/([^#/?]*)(.*)?/) || [];
904
+ if (protocol === "file:") path = path.replace(/\/(?=[A-Za-z]:)/, "");
905
+ const { pathname, search, hash } = parsePath(path);
906
+ return {
907
+ protocol: protocol.toLowerCase(),
908
+ auth: auth ? auth.slice(0, Math.max(0, auth.length - 1)) : "",
909
+ host,
910
+ pathname,
911
+ search,
912
+ hash,
913
+ [protocolRelative]: !protocol
914
+ };
915
+ }
916
+ function parsePath(input = "") {
917
+ const [pathname = "", search = "", hash = ""] = (input.match(/([^#?]*)(\?[^#]*)?(#.*)?/) || []).splice(1);
918
+ return {
919
+ pathname,
920
+ search,
921
+ hash
922
+ };
923
+ }
924
+ function stringifyParsedURL(parsed) {
925
+ const pathname = parsed.pathname || "";
926
+ const search = parsed.search ? (parsed.search.startsWith("?") ? "" : "?") + parsed.search : "";
927
+ const hash = parsed.hash || "";
928
+ const auth = parsed.auth ? parsed.auth + "@" : "";
929
+ const host = parsed.host || "";
930
+ return (parsed.protocol || parsed[protocolRelative] ? (parsed.protocol || "") + "//" : "") + auth + host + pathname + search + hash;
931
+ }
932
+ //#endregion
880
933
  //#region src/user-api/credential.ts
881
934
  function userApiApplication(input) {
882
935
  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");
@@ -3230,6 +3283,39 @@ function createServerAuth(options) {
3230
3283
  getReceivedInvitation(invitationId) {
3231
3284
  return organizationRead(`received-invitations/${normalizeIdInput(invitationId)}`, void 0, normalizeReceivedInvitation);
3232
3285
  },
3286
+ async startGoogleAccountRecovery(input) {
3287
+ if (authorization) throw new AuthError("state_conflict", 409);
3288
+ const body = googleRecoveryInput(input, false);
3289
+ return normalizeGoogleRecovery(await requestJson(joinURL(authOrigin, "api/v1/auth/google-account-recovery/start"), {
3290
+ fetch: fetchImpl,
3291
+ timeoutMs,
3292
+ method: "POST",
3293
+ credentials: "include",
3294
+ headers: {
3295
+ ...authHeaders(),
3296
+ "content-type": "application/json; charset=utf-8"
3297
+ },
3298
+ body,
3299
+ mapError: fromGoogleRecoveryError
3300
+ }), now());
3301
+ },
3302
+ async completeGoogleAccountRecovery(input) {
3303
+ if (authorization) throw new AuthError("state_conflict", 409);
3304
+ if (!cookie) throw new AuthError("authentication_required", 401);
3305
+ const body = googleRecoveryInput(input, true);
3306
+ return normalizeGoogleRecoveryCompletion(await requestJson(joinURL(authOrigin, "api/v1/auth/google-account-recovery/complete"), {
3307
+ fetch: fetchImpl,
3308
+ timeoutMs,
3309
+ method: "POST",
3310
+ credentials: "include",
3311
+ headers: {
3312
+ ...authHeaders(),
3313
+ "content-type": "application/json; charset=utf-8"
3314
+ },
3315
+ body,
3316
+ mapError: fromGoogleRecoveryError
3317
+ }));
3318
+ },
3233
3319
  async signInWithSocialIdToken(input) {
3234
3320
  if (authorization) throw new AuthError("state_conflict", 409);
3235
3321
  const body = socialIdTokenRequest(normalizeSocialIdTokenInput(input));
@@ -10,8 +10,8 @@ interface UserApiCredential {
10
10
  }
11
11
  //#endregion
12
12
  //#region src/errors.d.ts
13
- type AuthErrorCode = "invalid_credentials" | "invalid_auth_input" | "account_conflict" | "password_reset_invalid" | "authentication_required" | "request_origin_denied" | "invalid_request" | "invalid_invitation" | "invitation_unavailable" | "recipient_unavailable" | "invitation_recipient_mismatch" | "invitation_recovery_required" | "membership_removal_recovery_required" | "email_verification_required" | "invalid_workspace_selection" | "organization_context_too_large" | "credential_rate_limited" | "auth_request_rate_limited" | "state_conflict" | "access_denied" | "platform_target_unavailable" | "platform_quorum_unavailable" | "platform_recovery_required" | "identity_authority_unavailable" | "two_factor_required" | "two_factor_code_invalid" | "two_factor_challenge_expired" | "two_factor_locked" | "recent_sign_in_required" | "enterprise_recovery_required" | "recent_authentication_required" | "organization_closure_confirmation_mismatch" | "organization_closure_cancellation_ended" | "ceremony_return_refused" | "password_sign_in_required";
14
- type AuthErrorStatus = 400 | 401 | 403 | 404 | 405 | 409 | 413 | 415 | 422 | 429 | 503;
13
+ type AuthErrorCode = "invalid_credentials" | "invalid_auth_input" | "account_conflict" | "google_recovery_in_progress" | "google_recovery_not_required" | "google_recovery_invalid" | "google_recovery_expired" | "google_recovery_account_mismatch" | "password_reset_invalid" | "authentication_required" | "request_origin_denied" | "invalid_request" | "invalid_invitation" | "invitation_unavailable" | "recipient_unavailable" | "invitation_recipient_mismatch" | "invitation_recovery_required" | "membership_removal_recovery_required" | "email_verification_required" | "invalid_workspace_selection" | "organization_context_too_large" | "credential_rate_limited" | "auth_request_rate_limited" | "state_conflict" | "access_denied" | "platform_target_unavailable" | "platform_quorum_unavailable" | "platform_recovery_required" | "identity_authority_unavailable" | "two_factor_required" | "two_factor_code_invalid" | "two_factor_challenge_expired" | "two_factor_locked" | "recent_sign_in_required" | "enterprise_recovery_required" | "recent_authentication_required" | "organization_closure_confirmation_mismatch" | "organization_closure_cancellation_ended" | "ceremony_return_refused" | "password_sign_in_required";
14
+ type AuthErrorStatus = 400 | 401 | 403 | 404 | 405 | 409 | 410 | 413 | 415 | 422 | 429 | 503;
15
15
  declare class AuthError extends Error {
16
16
  readonly code: AuthErrorCode;
17
17
  readonly status: AuthErrorStatus;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@finueva/auth",
3
- "version": "0.19.0",
3
+ "version": "0.20.0",
4
4
  "description": "Public browser and server SDK for Finueva Auth",
5
5
  "type": "module",
6
6
  "sideEffects": false,