@finueva/auth 0.5.0 → 0.7.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 +50 -4
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/dist/device.d.ts +8 -2
- package/dist/device.js +616 -101
- package/dist/index.d.ts +2 -3
- package/dist/index.js +323 -102
- package/dist/server.d.ts +6 -3
- package/dist/server.js +127 -35
- package/dist/{types-HSdjQWMZ.d.ts → types-B1SZbs6Z.d.ts} +28 -1
- package/package.json +3 -2
- package/dist/errors-Crd93Rah.d.ts +0 -11
package/dist/server.js
CHANGED
|
@@ -173,6 +173,39 @@ function stringifyParsedURL(parsed) {
|
|
|
173
173
|
return (parsed.protocol || parsed[protocolRelative] ? (parsed.protocol || "") + "//" : "") + auth + host + pathname + search + hash;
|
|
174
174
|
}
|
|
175
175
|
//#endregion
|
|
176
|
+
//#region src/errors.ts
|
|
177
|
+
const messages = {
|
|
178
|
+
invalid_credentials: "The credentials are invalid.",
|
|
179
|
+
invalid_auth_input: "The authentication input is invalid.",
|
|
180
|
+
account_conflict: "The account is not available.",
|
|
181
|
+
password_reset_invalid: "The password reset request is invalid.",
|
|
182
|
+
authentication_required: "Authentication is required.",
|
|
183
|
+
request_origin_denied: "The request origin is not allowed.",
|
|
184
|
+
invalid_invitation: "The invitation is invalid.",
|
|
185
|
+
invitation_unavailable: "The invitation is not available.",
|
|
186
|
+
invitation_recipient_mismatch: "The invitation cannot be accepted by this account.",
|
|
187
|
+
email_verification_required: "Email verification is required.",
|
|
188
|
+
invalid_workspace_selection: "The workspace selection is invalid.",
|
|
189
|
+
organization_context_too_large: "The organization context is too large.",
|
|
190
|
+
credential_rate_limited: "Credential requests are temporarily limited.",
|
|
191
|
+
auth_request_rate_limited: "Authentication requests are temporarily limited.",
|
|
192
|
+
state_conflict: "The authentication state conflicts with the request.",
|
|
193
|
+
access_denied: "Access is denied.",
|
|
194
|
+
identity_authority_unavailable: "Authentication is temporarily unavailable."
|
|
195
|
+
};
|
|
196
|
+
var AuthError = class extends Error {
|
|
197
|
+
code;
|
|
198
|
+
status;
|
|
199
|
+
retryAfterSeconds;
|
|
200
|
+
constructor(code, status, retryAfterSeconds) {
|
|
201
|
+
super(messages[code]);
|
|
202
|
+
this.name = "AuthError";
|
|
203
|
+
this.code = code;
|
|
204
|
+
this.status = status;
|
|
205
|
+
this.retryAfterSeconds = retryAfterSeconds;
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
//#endregion
|
|
176
209
|
//#region ../../node_modules/.pnpm/destr@2.0.5/node_modules/destr/dist/index.mjs
|
|
177
210
|
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
211
|
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*:/;
|
|
@@ -436,38 +469,32 @@ function createFetch(globalOptions = {}) {
|
|
|
436
469
|
return $fetch;
|
|
437
470
|
}
|
|
438
471
|
//#endregion
|
|
439
|
-
//#region src/errors.ts
|
|
440
|
-
const messages = {
|
|
441
|
-
invalid_credentials: "The credentials are invalid.",
|
|
442
|
-
authentication_required: "Authentication is required.",
|
|
443
|
-
request_origin_denied: "The request origin is not allowed.",
|
|
444
|
-
invalid_invitation: "The invitation is invalid.",
|
|
445
|
-
invitation_unavailable: "The invitation is not available.",
|
|
446
|
-
invitation_recipient_mismatch: "The invitation cannot be accepted by this account.",
|
|
447
|
-
email_verification_required: "Email verification is required.",
|
|
448
|
-
invalid_workspace_selection: "The workspace selection is invalid.",
|
|
449
|
-
organization_context_too_large: "The organization context is too large.",
|
|
450
|
-
credential_rate_limited: "Credential requests are temporarily limited.",
|
|
451
|
-
state_conflict: "The authentication state conflicts with the request.",
|
|
452
|
-
access_denied: "Access is denied.",
|
|
453
|
-
identity_authority_unavailable: "Authentication is temporarily unavailable."
|
|
454
|
-
};
|
|
455
|
-
var AuthError = class extends Error {
|
|
456
|
-
code;
|
|
457
|
-
status;
|
|
458
|
-
retryAfterSeconds;
|
|
459
|
-
constructor(code, status, retryAfterSeconds) {
|
|
460
|
-
super(messages[code]);
|
|
461
|
-
this.name = "AuthError";
|
|
462
|
-
this.code = code;
|
|
463
|
-
this.status = status;
|
|
464
|
-
this.retryAfterSeconds = retryAfterSeconds;
|
|
465
|
-
}
|
|
466
|
-
};
|
|
467
|
-
//#endregion
|
|
468
472
|
//#region src/shared.ts
|
|
473
|
+
const DRIVE_CREDENTIAL_LIFETIME_SECONDS = 840;
|
|
469
474
|
const id = /^[A-Za-z0-9_-]{1,128}$/;
|
|
470
475
|
const email = /^[^\s@]+@[^\s@]+$/;
|
|
476
|
+
const MAX_SOCIAL_ID_TOKEN_BYTES = 16 * 1024;
|
|
477
|
+
function normalizeSocialIdTokenInput(value) {
|
|
478
|
+
if (!isObject(value)) throw new TypeError("social ID token input is invalid");
|
|
479
|
+
const keys = Object.keys(value);
|
|
480
|
+
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");
|
|
481
|
+
return {
|
|
482
|
+
provider: value.provider,
|
|
483
|
+
idToken: value.idToken,
|
|
484
|
+
...value.nonce === void 0 ? {} : { nonce: value.nonce },
|
|
485
|
+
signUp: value.signUp
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
function socialIdTokenRequest(value) {
|
|
489
|
+
return {
|
|
490
|
+
provider: value.provider,
|
|
491
|
+
idToken: {
|
|
492
|
+
token: value.idToken,
|
|
493
|
+
...value.nonce === void 0 ? {} : { nonce: value.nonce }
|
|
494
|
+
},
|
|
495
|
+
requestSignUp: value.signUp
|
|
496
|
+
};
|
|
497
|
+
}
|
|
471
498
|
function normalizeOrigin(value, name) {
|
|
472
499
|
if (value.length === 0 || value.length > 2048 || /[^\x20-\x7e]/.test(value)) throw new TypeError(`${name} must be an ASCII HTTP origin`);
|
|
473
500
|
let url;
|
|
@@ -504,7 +531,7 @@ function normalizeSession(value) {
|
|
|
504
531
|
};
|
|
505
532
|
}
|
|
506
533
|
function normalizeDriveCredential(value, now) {
|
|
507
|
-
if (!isObject(value) || value.tokenType !== "Bearer" || value.expiresIn !==
|
|
534
|
+
if (!isObject(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();
|
|
508
535
|
return {
|
|
509
536
|
tokenType: "Bearer",
|
|
510
537
|
token: value.token,
|
|
@@ -546,6 +573,26 @@ function fromAuthorityError(value, fallbackStatus, retryAfter) {
|
|
|
546
573
|
const mapped = mapError(isObject(value) && typeof value.code === "string" ? value.code : void 0, fallbackStatus);
|
|
547
574
|
return new AuthError(mapped.code, mapped.status, parseRetryAfter(retryAfter));
|
|
548
575
|
}
|
|
576
|
+
function fromAccountAuthorityError(value, status, retryAfter) {
|
|
577
|
+
const code = isObject(value) && typeof value.code === "string" ? value.code : void 0;
|
|
578
|
+
if (status === 403 && (code === "INVALID_ORIGIN" || code === "MISSING_OR_NULL_ORIGIN")) return new AuthError("request_origin_denied", 403);
|
|
579
|
+
if (code === "USER_ALREADY_EXISTS_USE_ANOTHER_EMAIL") return new AuthError("account_conflict", 409);
|
|
580
|
+
if (code === "INVALID_TOKEN") return new AuthError("password_reset_invalid", 422);
|
|
581
|
+
if (code === "INVALID_PASSWORD" || code === "INVALID_EMAIL_OR_PASSWORD") return new AuthError("invalid_credentials", 401);
|
|
582
|
+
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);
|
|
583
|
+
if (status === 401) return new AuthError("authentication_required", 401);
|
|
584
|
+
if (status === 403) return new AuthError("access_denied", 403);
|
|
585
|
+
if (status === 409) return new AuthError("state_conflict", 409);
|
|
586
|
+
if (status === 429) return new AuthError("auth_request_rate_limited", 429, parseRetryAfter(retryAfter));
|
|
587
|
+
if (status === 400 || status === 422) return new AuthError("invalid_auth_input", 422);
|
|
588
|
+
return authorityUnavailable();
|
|
589
|
+
}
|
|
590
|
+
function fromSocialIdTokenAuthorityError(value, status, retryAfter) {
|
|
591
|
+
const code = isObject(value) && typeof value.code === "string" ? value.code : void 0;
|
|
592
|
+
if (code === "INVALID_TOKEN" || code === "FAILED_TO_GET_USER_INFO" || code === "USER_EMAIL_NOT_FOUND") return new AuthError("invalid_credentials", 401);
|
|
593
|
+
if (code === "OAUTH_LINK_ERROR") return new AuthError("account_conflict", 409);
|
|
594
|
+
return fromAccountAuthorityError(value, status, retryAfter);
|
|
595
|
+
}
|
|
549
596
|
function authorityUnavailable() {
|
|
550
597
|
return new AuthError("identity_authority_unavailable", 503);
|
|
551
598
|
}
|
|
@@ -644,7 +691,7 @@ async function requestJsonResponse(url, options) {
|
|
|
644
691
|
method: options.method,
|
|
645
692
|
headers: options.headers,
|
|
646
693
|
body: options.body,
|
|
647
|
-
credentials: "include",
|
|
694
|
+
credentials: options.credentials ?? "include",
|
|
648
695
|
retry: 0,
|
|
649
696
|
timeout: options.timeoutMs,
|
|
650
697
|
redirect: "manual",
|
|
@@ -704,6 +751,7 @@ async function readJson(response) {
|
|
|
704
751
|
}
|
|
705
752
|
//#endregion
|
|
706
753
|
//#region src/server.ts
|
|
754
|
+
const MAX_AUTHORIZATION_BYTES = 16 * 1024;
|
|
707
755
|
function createServerAuth(options) {
|
|
708
756
|
const authOrigin = normalizeOrigin(options.authOrigin, "authOrigin");
|
|
709
757
|
const appOrigin = normalizeOrigin(options.appOrigin, "appOrigin");
|
|
@@ -711,10 +759,12 @@ function createServerAuth(options) {
|
|
|
711
759
|
if (typeof fetchImpl !== "function") throw new TypeError("fetch is required");
|
|
712
760
|
const now = options.now ?? Date.now;
|
|
713
761
|
const timeoutMs = normalizeTimeout(options.timeoutMs);
|
|
762
|
+
const authorization = authAuthorizationHeader(options.request.headers.get("authorization"));
|
|
714
763
|
const cookie = authCookieHeader(options.request.headers.get("cookie"));
|
|
715
|
-
const
|
|
716
|
-
|
|
717
|
-
|
|
764
|
+
const credentials = authorization ? "omit" : "include";
|
|
765
|
+
const authHeaders = (includeOrigin = true) => ({
|
|
766
|
+
...authorization ? { authorization } : { cookie },
|
|
767
|
+
...includeOrigin ? { origin: appOrigin } : {}
|
|
718
768
|
});
|
|
719
769
|
return {
|
|
720
770
|
async acceptInvitation(input) {
|
|
@@ -724,6 +774,7 @@ function createServerAuth(options) {
|
|
|
724
774
|
fetch: fetchImpl,
|
|
725
775
|
timeoutMs,
|
|
726
776
|
method: "POST",
|
|
777
|
+
credentials,
|
|
727
778
|
headers: {
|
|
728
779
|
...authHeaders(),
|
|
729
780
|
"content-type": "application/json; charset=utf-8"
|
|
@@ -748,7 +799,8 @@ function createServerAuth(options) {
|
|
|
748
799
|
fetch: fetchImpl,
|
|
749
800
|
timeoutMs,
|
|
750
801
|
method: "GET",
|
|
751
|
-
|
|
802
|
+
credentials,
|
|
803
|
+
headers: authHeaders(false)
|
|
752
804
|
}));
|
|
753
805
|
},
|
|
754
806
|
async listOrganizations() {
|
|
@@ -757,18 +809,52 @@ function createServerAuth(options) {
|
|
|
757
809
|
fetch: fetchImpl,
|
|
758
810
|
timeoutMs,
|
|
759
811
|
method: "GET",
|
|
812
|
+
credentials,
|
|
760
813
|
headers: authHeaders()
|
|
761
814
|
}));
|
|
762
815
|
} catch (error) {
|
|
763
816
|
throw fromOrganizationListError(error);
|
|
764
817
|
}
|
|
765
818
|
},
|
|
819
|
+
async signInWithSocialIdToken(input) {
|
|
820
|
+
if (authorization) throw new AuthError("state_conflict", 409);
|
|
821
|
+
const body = socialIdTokenRequest(normalizeSocialIdTokenInput(input));
|
|
822
|
+
const cookies = responseCookies((await requestJsonResponse(joinURL(authOrigin, "api/v1/auth/sign-in/social"), {
|
|
823
|
+
fetch: fetchImpl,
|
|
824
|
+
timeoutMs,
|
|
825
|
+
method: "POST",
|
|
826
|
+
credentials,
|
|
827
|
+
headers: {
|
|
828
|
+
...authHeaders(),
|
|
829
|
+
"content-type": "application/json; charset=utf-8"
|
|
830
|
+
},
|
|
831
|
+
body,
|
|
832
|
+
mapError: fromSocialIdTokenAuthorityError
|
|
833
|
+
})).headers);
|
|
834
|
+
const cookieHeader = authCookieHeader(cookies.map((value) => value.split(";", 1)[0]).join("; "));
|
|
835
|
+
if (!cookieHeader) throw authorityUnavailable();
|
|
836
|
+
const session = normalizeSession(await requestJson(joinURL(authOrigin, "api/v1/auth/get-session"), {
|
|
837
|
+
fetch: fetchImpl,
|
|
838
|
+
timeoutMs,
|
|
839
|
+
method: "GET",
|
|
840
|
+
credentials: "include",
|
|
841
|
+
headers: { cookie: cookieHeader }
|
|
842
|
+
}));
|
|
843
|
+
if (!session) throw new AuthError("authentication_required", 401);
|
|
844
|
+
return {
|
|
845
|
+
...session,
|
|
846
|
+
applyCookies(headers) {
|
|
847
|
+
applyCookies(cookies, headers);
|
|
848
|
+
}
|
|
849
|
+
};
|
|
850
|
+
},
|
|
766
851
|
async getDriveCredential(input) {
|
|
767
852
|
const workspace = normalizeWorkspaceSelection(input?.workspace);
|
|
768
853
|
return normalizeDriveCredential(await requestJson(joinURL(authOrigin, "api/v1/auth/drive-credential"), {
|
|
769
854
|
fetch: fetchImpl,
|
|
770
855
|
timeoutMs,
|
|
771
856
|
method: "POST",
|
|
857
|
+
credentials,
|
|
772
858
|
headers: {
|
|
773
859
|
...authHeaders(),
|
|
774
860
|
"content-type": "application/json; charset=utf-8"
|
|
@@ -781,6 +867,7 @@ function createServerAuth(options) {
|
|
|
781
867
|
try {
|
|
782
868
|
response = await fetchImpl(joinURL(authOrigin, "api/v1/auth/sign-out"), {
|
|
783
869
|
method: "POST",
|
|
870
|
+
credentials,
|
|
784
871
|
headers: authHeaders(),
|
|
785
872
|
redirect: "manual",
|
|
786
873
|
signal: AbortSignal.timeout(timeoutMs)
|
|
@@ -816,5 +903,10 @@ function authCookieHeader(value) {
|
|
|
816
903
|
return name.startsWith("better-auth.") || name.startsWith("__Secure-better-auth.");
|
|
817
904
|
}).join("; ");
|
|
818
905
|
}
|
|
906
|
+
function authAuthorizationHeader(value) {
|
|
907
|
+
if (value === null) return void 0;
|
|
908
|
+
if (new TextEncoder().encode(value).byteLength > MAX_AUTHORIZATION_BYTES || /[^\x20-\x7e]/.test(value) || !/^Bearer [^\s,]+$/i.test(value)) throw new AuthError("authentication_required", 401);
|
|
909
|
+
return value;
|
|
910
|
+
}
|
|
819
911
|
//#endregion
|
|
820
912
|
export { AuthError, createServerAuth };
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
//#region src/errors.d.ts
|
|
2
|
+
type AuthErrorCode = "invalid_credentials" | "invalid_auth_input" | "account_conflict" | "password_reset_invalid" | "authentication_required" | "request_origin_denied" | "invalid_invitation" | "invitation_unavailable" | "invitation_recipient_mismatch" | "email_verification_required" | "invalid_workspace_selection" | "organization_context_too_large" | "credential_rate_limited" | "auth_request_rate_limited" | "state_conflict" | "access_denied" | "identity_authority_unavailable";
|
|
3
|
+
type AuthErrorStatus = 401 | 403 | 409 | 422 | 429 | 503;
|
|
4
|
+
declare class AuthError extends Error {
|
|
5
|
+
readonly code: AuthErrorCode;
|
|
6
|
+
readonly status: AuthErrorStatus;
|
|
7
|
+
readonly retryAfterSeconds?: number;
|
|
8
|
+
constructor(code: AuthErrorCode, status: AuthErrorStatus, retryAfterSeconds?: number);
|
|
9
|
+
}
|
|
10
|
+
//#endregion
|
|
1
11
|
//#region src/types.d.ts
|
|
2
12
|
interface AuthUser {
|
|
3
13
|
id: string;
|
|
@@ -64,6 +74,17 @@ interface SignInInput {
|
|
|
64
74
|
email: string;
|
|
65
75
|
password: string;
|
|
66
76
|
}
|
|
77
|
+
type SocialIdTokenProvider = "google" | "apple";
|
|
78
|
+
interface SocialIdTokenInput {
|
|
79
|
+
provider: SocialIdTokenProvider;
|
|
80
|
+
idToken: string;
|
|
81
|
+
nonce?: string;
|
|
82
|
+
signUp: boolean;
|
|
83
|
+
}
|
|
84
|
+
interface UpdateProfileInput {
|
|
85
|
+
name?: string;
|
|
86
|
+
image?: string | null;
|
|
87
|
+
}
|
|
67
88
|
interface SendVerificationEmailInput {
|
|
68
89
|
email: string;
|
|
69
90
|
callbackURL?: string;
|
|
@@ -85,11 +106,17 @@ interface FinuevaAuthClient {
|
|
|
85
106
|
getSession(): Promise<AuthSession | null>;
|
|
86
107
|
listOrganizations(): Promise<AuthOrganization[]>;
|
|
87
108
|
sendVerificationEmail(input: SendVerificationEmailInput): Promise<void>;
|
|
109
|
+
signUp(email: string, password: string, name: string): Promise<AuthSession>;
|
|
88
110
|
signIn(input: SignInInput): Promise<AuthSession>;
|
|
111
|
+
signInWithSocialIdToken(input: SocialIdTokenInput): Promise<AuthSession>;
|
|
112
|
+
updateProfile(input: UpdateProfileInput): Promise<AuthSession>;
|
|
113
|
+
changePassword(currentPassword: string, newPassword: string, revokeOtherSessions?: boolean): Promise<AuthSession>;
|
|
114
|
+
requestPasswordReset(email: string, redirectTo: string): Promise<void>;
|
|
115
|
+
resetPassword(token: string, newPassword: string): Promise<void>;
|
|
89
116
|
signOut(): Promise<void>;
|
|
90
117
|
getDriveCredential(input: DriveCredentialInput): Promise<DriveCredential>;
|
|
91
118
|
onAuthStateChange(listener: (state: AuthState) => void): () => void;
|
|
92
119
|
onSessionChange(listener: (session: AuthSession | null) => void): () => void;
|
|
93
120
|
}
|
|
94
121
|
//#endregion
|
|
95
|
-
export {
|
|
122
|
+
export { AuthErrorStatus as C, AuthErrorCode as S, SocialIdTokenInput as _, AuthPersistenceDriver as a, WorkspaceSelection as b, AuthUser as c, FinuevaAuthClient as d, InvitationAcceptance as f, SignInInput as g, SendVerificationEmailInput as h, AuthPersistence as i, DriveCredential as l, PersonalWorkspaceSelection as m, AuthClientOptions as n, AuthSession as o, OrganizationWorkspaceSelection as p, AuthOrganization as r, AuthState as s, AcceptInvitationInput as t, DriveCredentialInput as u, SocialIdTokenProvider as v, AuthError as x, UpdateProfileInput as y };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@finueva/auth",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Public browser and server SDK for Finueva Auth",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
"build": "rolldown -c",
|
|
42
42
|
"coverage": "vitest run --coverage",
|
|
43
43
|
"lint": "oxlint . --deny-warnings",
|
|
44
|
+
"prepack": "pnpm build",
|
|
44
45
|
"test": "pnpm test:unit && pnpm build && pnpm test:package",
|
|
45
46
|
"test:composition": "node scripts/test-composition.mjs",
|
|
46
47
|
"test:package": "node scripts/test-package.mjs",
|
|
@@ -48,7 +49,7 @@
|
|
|
48
49
|
"typecheck": "tsc --noEmit"
|
|
49
50
|
},
|
|
50
51
|
"devDependencies": {
|
|
51
|
-
"@chiballc/utils": "2.
|
|
52
|
+
"@chiballc/utils": "2.5.0",
|
|
52
53
|
"@types/node": "24.13.3",
|
|
53
54
|
"@typescript/native": "npm:typescript@7.0.2",
|
|
54
55
|
"@vitest/coverage-v8": "4.1.10",
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
//#region src/errors.d.ts
|
|
2
|
-
type AuthErrorCode = "invalid_credentials" | "authentication_required" | "request_origin_denied" | "invalid_invitation" | "invitation_unavailable" | "invitation_recipient_mismatch" | "email_verification_required" | "invalid_workspace_selection" | "organization_context_too_large" | "credential_rate_limited" | "state_conflict" | "access_denied" | "identity_authority_unavailable";
|
|
3
|
-
type AuthErrorStatus = 401 | 403 | 409 | 422 | 429 | 503;
|
|
4
|
-
declare class AuthError extends Error {
|
|
5
|
-
readonly code: AuthErrorCode;
|
|
6
|
-
readonly status: AuthErrorStatus;
|
|
7
|
-
readonly retryAfterSeconds?: number;
|
|
8
|
-
constructor(code: AuthErrorCode, status: AuthErrorStatus, retryAfterSeconds?: number);
|
|
9
|
-
}
|
|
10
|
-
//#endregion
|
|
11
|
-
export { AuthErrorCode as n, AuthErrorStatus as r, AuthError as t };
|