@authyon/server 0.2.0-beta.12 → 0.2.0-beta.15
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 +51 -62
- package/dist/{authorization-DWlLfYQJ.d.cts → authorization-B82XXf3B.d.cts} +1 -1
- package/dist/{authorization-wrZ5ull7.d.ts → authorization-WlwcTBwG.d.ts} +1 -1
- package/dist/{authyonServerClient-t82mwTws.d.cts → authyonServerClient-DQzhfaja.d.cts} +163 -115
- package/dist/{authyonServerClient-t82mwTws.d.ts → authyonServerClient-DQzhfaja.d.ts} +163 -115
- package/dist/bff.cjs +36 -6
- package/dist/bff.d.cts +1 -1
- package/dist/bff.d.ts +1 -1
- package/dist/bff.js +1 -1
- package/dist/{chunk-56H66KLG.js → chunk-WPPEV5BA.js} +36 -6
- package/dist/index.cjs +142 -147
- package/dist/index.d.cts +34 -9
- package/dist/index.d.ts +34 -9
- package/dist/index.js +92 -125
- package/dist/next.d.cts +2 -2
- package/dist/next.d.ts +2 -2
- package/package.json +1 -1
|
@@ -401,14 +401,6 @@ type CreateCredentialInput = CredentialPermissionsInput & {
|
|
|
401
401
|
description?: string;
|
|
402
402
|
lifetimeDays?: number | null;
|
|
403
403
|
};
|
|
404
|
-
interface CredentialScope {
|
|
405
|
-
workspaceId: string;
|
|
406
|
-
environmentId: string;
|
|
407
|
-
tenantId?: string;
|
|
408
|
-
}
|
|
409
|
-
interface TenantManagementScope extends CredentialScope {
|
|
410
|
-
tenantId: string;
|
|
411
|
-
}
|
|
412
404
|
interface CredentialCreator {
|
|
413
405
|
id: string | null;
|
|
414
406
|
type: string;
|
|
@@ -424,64 +416,6 @@ interface CredentialDetail extends TenantCredentialSummary {
|
|
|
424
416
|
lifetimeSeconds: number | null;
|
|
425
417
|
accessTokenLifetimeSeconds: number;
|
|
426
418
|
}
|
|
427
|
-
type WorkspaceRole = "admin" | "auditor";
|
|
428
|
-
interface WorkspaceMember {
|
|
429
|
-
memberId: string | null;
|
|
430
|
-
userId: string;
|
|
431
|
-
email: string;
|
|
432
|
-
name: string;
|
|
433
|
-
role: string;
|
|
434
|
-
isOwner: boolean;
|
|
435
|
-
isSelf: boolean;
|
|
436
|
-
invitedByName: string | null;
|
|
437
|
-
joinedAt: string;
|
|
438
|
-
lastLoginAt: string | null;
|
|
439
|
-
}
|
|
440
|
-
interface WorkspaceInvite {
|
|
441
|
-
id: string;
|
|
442
|
-
email: string;
|
|
443
|
-
role: string;
|
|
444
|
-
invitedByName: string | null;
|
|
445
|
-
createdAt: string;
|
|
446
|
-
expiresAt: string;
|
|
447
|
-
}
|
|
448
|
-
interface WorkspaceTeam {
|
|
449
|
-
workspaceId: string;
|
|
450
|
-
workspaceName: string;
|
|
451
|
-
callerRole: string;
|
|
452
|
-
canManage: boolean;
|
|
453
|
-
members: WorkspaceMember[];
|
|
454
|
-
pendingInvites: WorkspaceInvite[];
|
|
455
|
-
}
|
|
456
|
-
interface InviteWorkspaceMemberInput {
|
|
457
|
-
email: string;
|
|
458
|
-
role: WorkspaceRole;
|
|
459
|
-
}
|
|
460
|
-
interface WorkspaceInviteIssued {
|
|
461
|
-
inviteId: string;
|
|
462
|
-
email: string;
|
|
463
|
-
role: string;
|
|
464
|
-
/** Sensitive bearer link returned at issuance. Do not log or persist in public storage. */
|
|
465
|
-
acceptUrl: string;
|
|
466
|
-
expiresAt: string;
|
|
467
|
-
}
|
|
468
|
-
interface WorkspaceInvitePreview {
|
|
469
|
-
workspaceName: string;
|
|
470
|
-
email: string;
|
|
471
|
-
role: string;
|
|
472
|
-
expiresAt: string;
|
|
473
|
-
requiresRegistration: boolean;
|
|
474
|
-
}
|
|
475
|
-
interface WorkspaceInviteAccepted {
|
|
476
|
-
workspaceId: string;
|
|
477
|
-
workspaceName: string;
|
|
478
|
-
role: string;
|
|
479
|
-
accountCreated: boolean;
|
|
480
|
-
}
|
|
481
|
-
interface AcceptWorkspaceInviteInput {
|
|
482
|
-
name?: string;
|
|
483
|
-
password?: string;
|
|
484
|
-
}
|
|
485
419
|
interface InviteTenantMemberInput {
|
|
486
420
|
email: string;
|
|
487
421
|
roles?: string[];
|
|
@@ -508,51 +442,95 @@ interface JsonRequestOptions {
|
|
|
508
442
|
|
|
509
443
|
type ManagementRequest = <T>(path: string, options?: JsonRequestOptions) => Promise<T>;
|
|
510
444
|
|
|
511
|
-
/**
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
445
|
+
/** Lifecycle of an approval. */
|
|
446
|
+
type ApprovalStatus = "pending" | "approved" | "denied" | "consumed" | "expired";
|
|
447
|
+
/**
|
|
448
|
+
* Free-form JSON object describing what the customer approves (up to 16 KiB).
|
|
449
|
+
* The API stores it, shows it back to the customer and binds its canonical
|
|
450
|
+
* hash (keys sorted) to the approval.
|
|
451
|
+
*/
|
|
452
|
+
type ApprovalPayload = Record<string, unknown>;
|
|
453
|
+
/** Evidence of how the customer proved their identity when approving. */
|
|
454
|
+
interface ApprovalAssurance {
|
|
455
|
+
/** `urn:authyon:loa:3` (passkey) or `urn:authyon:loa:2` (authenticator code). */
|
|
456
|
+
acr: string;
|
|
457
|
+
/** Authentication methods, e.g. `["pwd", "otp"]` or `["pwd", "webauthn"]`. */
|
|
458
|
+
amr: string[];
|
|
459
|
+
/** When the second factor was verified (ISO 8601). */
|
|
460
|
+
authTime: string;
|
|
461
|
+
}
|
|
462
|
+
/** A request for the customer to approve something with a second factor. */
|
|
463
|
+
interface Approval {
|
|
464
|
+
id: string;
|
|
465
|
+
status: ApprovalStatus;
|
|
466
|
+
subjectId: string;
|
|
467
|
+
tenantId?: string | null;
|
|
468
|
+
/** The payload given to `create()`, with keys in canonical order. */
|
|
469
|
+
payload: ApprovalPayload;
|
|
470
|
+
/** SHA-256 (hex) of the canonical payload. */
|
|
471
|
+
payloadHash: string;
|
|
472
|
+
createdAt: string;
|
|
473
|
+
expiresAt: string;
|
|
474
|
+
decidedAt?: string | null;
|
|
475
|
+
consumedAt?: string | null;
|
|
476
|
+
/** Present once approved. */
|
|
477
|
+
assurance?: ApprovalAssurance | null;
|
|
478
|
+
}
|
|
479
|
+
/** Second factor sent with `confirm()`. */
|
|
480
|
+
type ConfirmApprovalInput = {
|
|
481
|
+
method: "authenticator";
|
|
482
|
+
/** Six-digit code from the customer's authenticator app. */
|
|
483
|
+
code: string;
|
|
484
|
+
} | {
|
|
485
|
+
method: "webauthn";
|
|
486
|
+
/** Assertion for the options returned by `webauthnOptions()`. */
|
|
487
|
+
webAuthn: {
|
|
488
|
+
ceremonyToken: string;
|
|
489
|
+
/** JSON-serialized `PublicKeyCredential` from `navigator.credentials.get()`. */
|
|
490
|
+
assertionJson: string;
|
|
549
491
|
};
|
|
492
|
+
};
|
|
493
|
+
/** Passkey assertion options for approving one approval. */
|
|
494
|
+
interface ApprovalWebAuthnOptions {
|
|
495
|
+
ceremonyToken: string;
|
|
496
|
+
/** JSON `PublicKeyCredentialRequestOptions` to pass to `navigator.credentials.get()`. */
|
|
497
|
+
optionsJson: string;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
/** Customer-side operations on an approval (`/auth/authorizations`). */
|
|
501
|
+
interface SubjectApprovals {
|
|
502
|
+
/** GET /auth/authorizations/{id} — the pending payload, to show before asking for the code. */
|
|
503
|
+
get(id: string): Promise<Approval>;
|
|
504
|
+
/** POST /auth/authorizations/{id}/webauthn/options — passkey options for approving it. */
|
|
505
|
+
webauthnOptions(id: string): Promise<ApprovalWebAuthnOptions>;
|
|
506
|
+
/**
|
|
507
|
+
* POST /auth/authorizations/{id}/confirm — approves it.
|
|
508
|
+
*
|
|
509
|
+
* Pass the authenticator code or passkey assertion to verify the second
|
|
510
|
+
* factor inline (recommended). Without `input`, the session itself must
|
|
511
|
+
* have used a passkey or authenticator code within the last 5 minutes,
|
|
512
|
+
* otherwise the API answers `step_up_required`.
|
|
513
|
+
*/
|
|
514
|
+
confirm(id: string, input?: ConfirmApprovalInput): Promise<Approval>;
|
|
515
|
+
/** POST /auth/authorizations/{id}/reject — the customer declines it. */
|
|
516
|
+
reject(id: string): Promise<Approval>;
|
|
517
|
+
}
|
|
518
|
+
/** The `security` namespace an end-user client exposes. */
|
|
519
|
+
interface SubjectSecurity {
|
|
520
|
+
/** Approve or reject what your backend asked the customer to confirm. */
|
|
521
|
+
readonly approvals: SubjectApprovals;
|
|
550
522
|
}
|
|
523
|
+
|
|
551
524
|
/** End-user operations require a user token and the environment publishable key. */
|
|
552
525
|
declare class UserScopedClient {
|
|
553
526
|
#private;
|
|
554
527
|
/** @hidden */
|
|
555
528
|
constructor(request: ManagementRequest, token: AccessTokenSource);
|
|
529
|
+
/**
|
|
530
|
+
* The customer's side of `security.approvals`, for backends (BFF) that hold
|
|
531
|
+
* the customer's access token: `get`, `webauthnOptions`, `confirm`, `reject`.
|
|
532
|
+
*/
|
|
533
|
+
readonly security: SubjectSecurity;
|
|
556
534
|
readonly tenants: {
|
|
557
535
|
members: {
|
|
558
536
|
list: (tenantId: string, options?: PaginationOptions) => Promise<TenantMemberPage>;
|
|
@@ -562,14 +540,55 @@ declare class UserScopedClient {
|
|
|
562
540
|
};
|
|
563
541
|
};
|
|
564
542
|
}
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
/**
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
543
|
+
|
|
544
|
+
/** `security.approvals.create()` — something awaiting the customer's approval. */
|
|
545
|
+
interface CreateApprovalInput {
|
|
546
|
+
/** Environment user who must approve. */
|
|
547
|
+
subjectId: string;
|
|
548
|
+
/** Any JSON object (up to 16 KiB) describing what is being approved. Default `{}`. */
|
|
549
|
+
payload?: ApprovalPayload;
|
|
550
|
+
/** Restrict approval to a session in this tenant. */
|
|
551
|
+
tenantId?: string;
|
|
552
|
+
/** Lifetime in seconds, clamped to 60–600. Default 300. */
|
|
553
|
+
expiresInSeconds?: number;
|
|
554
|
+
/**
|
|
555
|
+
* Optional. Sent as the `Idempotency-Key` header (max 128 chars): retrying
|
|
556
|
+
* with the same key and payload returns the same approval; the same key
|
|
557
|
+
* with a different payload fails with `idempotency_conflict`.
|
|
558
|
+
*/
|
|
559
|
+
idempotencyKey?: string;
|
|
572
560
|
}
|
|
561
|
+
/** `security.approvals.consume()` — single-use redemption result. */
|
|
562
|
+
interface ConsumedApproval {
|
|
563
|
+
id: string;
|
|
564
|
+
status: "consumed";
|
|
565
|
+
consumedAt: string;
|
|
566
|
+
/** The approved payload — execute exactly this. */
|
|
567
|
+
payload: ApprovalPayload;
|
|
568
|
+
payloadHash: string;
|
|
569
|
+
assurance: ApprovalAssurance | null;
|
|
570
|
+
}
|
|
571
|
+
/** `security.otp.check()` result. */
|
|
572
|
+
type OtpCheckResult = {
|
|
573
|
+
valid: true;
|
|
574
|
+
userId: string;
|
|
575
|
+
/** Always `"otp"` (authenticator app). */
|
|
576
|
+
method: string;
|
|
577
|
+
verifiedAt: string;
|
|
578
|
+
} | {
|
|
579
|
+
valid: false;
|
|
580
|
+
/**
|
|
581
|
+
* Wrong codes left before the first consequence: the sign-out (3 in a
|
|
582
|
+
* row) or the 15-minute lock (5). `0` when the user was just signed out.
|
|
583
|
+
*/
|
|
584
|
+
attemptsRemaining: number;
|
|
585
|
+
/**
|
|
586
|
+
* True when this was the 3rd wrong code in a row (counted across login
|
|
587
|
+
* 2FA, `security.otp.check` and `security.approvals.confirm`): every
|
|
588
|
+
* session of the user was ended and they must sign in again.
|
|
589
|
+
*/
|
|
590
|
+
sessionsRevoked?: boolean;
|
|
591
|
+
};
|
|
573
592
|
|
|
574
593
|
interface ClientRequestContext {
|
|
575
594
|
/** Real end-user IP, resolved only from infrastructure trusted by the application. */
|
|
@@ -682,11 +701,8 @@ declare class AuthyonServerClient {
|
|
|
682
701
|
* "the token's tenant" rather than one you pass by id.
|
|
683
702
|
*/
|
|
684
703
|
tenant(credentials: ClientCredentials): TenantScopedClient;
|
|
685
|
-
/** Uses only the supplied platform-user access token. */
|
|
686
|
-
platform(token: AccessTokenSource): PlatformScopedClient;
|
|
687
704
|
/** Uses an end-user token; the configured environment key selects the environment. */
|
|
688
705
|
user(token: AccessTokenSource): UserScopedClient;
|
|
689
|
-
readonly workspaceInvites: WorkspaceInvitesClient;
|
|
690
706
|
readonly environment: {
|
|
691
707
|
users: {
|
|
692
708
|
/** GET /env/users — paginated list of users in the environment. */
|
|
@@ -823,6 +839,38 @@ declare class AuthyonServerClient {
|
|
|
823
839
|
loginActivity: (params?: PaginationOptions) => Promise<Paged<LoginActivity>>;
|
|
824
840
|
};
|
|
825
841
|
};
|
|
842
|
+
readonly security: {
|
|
843
|
+
otp: {
|
|
844
|
+
/**
|
|
845
|
+
* POST /env/users/{userId}/otp/verify — checks the user's authenticator
|
|
846
|
+
* app (TOTP) code. A wrong code returns `{ valid: false }` instead of
|
|
847
|
+
* throwing. Each code is accepted once; 3 wrong codes in a row sign the
|
|
848
|
+
* user out everywhere (`sessionsRevoked: true`); 5 lock the check for 15
|
|
849
|
+
* minutes (`rate_limited`).
|
|
850
|
+
*/
|
|
851
|
+
check: (userId: string, code: string) => Promise<OtpCheckResult>;
|
|
852
|
+
};
|
|
853
|
+
/**
|
|
854
|
+
* The customer approves a payload with their authenticator code or
|
|
855
|
+
* passkey, once.
|
|
856
|
+
*
|
|
857
|
+
* 1. `create()` the approval with the payload and the customer.
|
|
858
|
+
* 2. The customer confirms it (`@authyon/auth` → `security.approvals.confirm`).
|
|
859
|
+
* 3. `consume()` it right before executing, and execute the returned payload.
|
|
860
|
+
*/
|
|
861
|
+
approvals: {
|
|
862
|
+
/** POST /env/authorizations — registers a payload awaiting the customer's approval. */
|
|
863
|
+
create: (input: CreateApprovalInput) => Promise<Approval>;
|
|
864
|
+
/** GET /env/authorizations/{id} — current status and, once approved, the assurance evidence. */
|
|
865
|
+
get: (id: string) => Promise<Approval>;
|
|
866
|
+
/**
|
|
867
|
+
* POST /env/authorizations/{id}/consume — redeems an approved approval
|
|
868
|
+
* exactly once and returns the approved payload. Pass `payload` to have
|
|
869
|
+
* the API check it matches (`payload_mismatch` otherwise).
|
|
870
|
+
*/
|
|
871
|
+
consume: (id: string, payload?: ApprovalPayload) => Promise<ConsumedApproval>;
|
|
872
|
+
};
|
|
873
|
+
};
|
|
826
874
|
readonly permissions: {
|
|
827
875
|
/** POST /users/{userId}/permissions — grant a permission directly to a user. */
|
|
828
876
|
grant: (userId: string, permission: string) => Promise<void>;
|
|
@@ -897,4 +945,4 @@ declare class TenantScopedClient {
|
|
|
897
945
|
/** Convenience factory: `const authyon = createClient({ clientId, clientSecret })`. */
|
|
898
946
|
declare function createClient(options?: AuthyonServerClientOptions): AuthyonServerClient;
|
|
899
947
|
|
|
900
|
-
export { type
|
|
948
|
+
export { type SubjectApprovals as $, AuthyonServerClient as A, type HttpLogger as B, type ClientCredentials as C, type InviteTenantMemberInput as D, type EnvironmentUser as E, FetchHttpAdapter as F, JwksTokenVerifier as G, type HttpAdapter as H, type IntrospectResult as I, type JsonWebKeySet as J, type JwksTokenVerifierOptions as K, LoggingHttpAdapter as L, type LoginActivity as M, type Organization as N, type OpenIdConfiguration as O, type OtpCheckResult as P, type Paged as Q, type PaginationOptions as R, type Permission as S, type PermissionsByRole as T, type ReservedPermissions as U, type Role as V, type RoleGrant as W, type RoleInput as X, type RoleList as Y, type RolePermissions as Z, type SafeJwtAlgorithm as _, type HttpLoggerOptions as a, type SubjectSecurity as a0, type TenantClientValidationResult as a1, type TenantCredentialIssued as a2, type TenantCredentialSummary as a3, type TenantMember as a4, type TenantMemberPage as a5, type TenantMembership as a6, TenantScopedClient as a7, type TokenResult as a8, TokenVerificationError as a9, type TokenVerificationErrorCode as aa, type UpdateOrganizationInput as ab, type User as ac, UserScopedClient as ad, type ValidateResult as ae, type VerifiedAccessToken as af, createClient as ag, normalizeClientIp as ah, type AccessTokenSource as b, type Approval as c, type ApprovalAssurance as d, type ApprovalPayload as e, type ApprovalStatus as f, type ApprovalWebAuthnOptions as g, type AuditEvent as h, type AuthyonJwksDiscoveryOptions as i, type AuthyonJwtClaims as j, type AuthyonServerClientOptions as k, type ClientRequestContext as l, type ConfirmApprovalInput as m, type ConsumedApproval as n, type CreateApprovalInput as o, type CreateCredentialInput as p, type CreateOrganizationInput as q, type CreatePermissionInput as r, type CreateTenantCredentialInput as s, type CreateUserInput as t, type CredentialCreator as u, type CredentialDetail as v, type CredentialListOptions as w, type CredentialPermissionsInput as x, type HttpAdapterRequest as y, type HttpLogEvent as z };
|
package/dist/bff.cjs
CHANGED
|
@@ -51,16 +51,44 @@ var ErrorCodes = {
|
|
|
51
51
|
EmailTaken: "user.email_taken",
|
|
52
52
|
PasswordWeak: "user.password_weak",
|
|
53
53
|
PasswordPwned: "user.password_pwned",
|
|
54
|
-
RateLimited: "rate_limited"
|
|
54
|
+
RateLimited: "rate_limited",
|
|
55
|
+
StepUpRequired: "step_up_required",
|
|
56
|
+
InvalidSecondFactorCode: "invalid_code",
|
|
57
|
+
VerificationAttemptsExhausted: "verification_attempts_exhausted",
|
|
58
|
+
MethodNotEnrolled: "method_not_enrolled",
|
|
59
|
+
InvalidApprovalState: "invalid_authorization_state",
|
|
60
|
+
PayloadMismatch: "payload_mismatch",
|
|
61
|
+
ApprovalNotConsumable: "authorization_not_consumable",
|
|
62
|
+
IdempotencyConflict: "idempotency_conflict",
|
|
63
|
+
UserDisabled: "user_disabled",
|
|
64
|
+
UserNotFound: "user_not_found",
|
|
65
|
+
TemporarilyUnavailable: "temporarily_unavailable",
|
|
66
|
+
InsufficientScope: "insufficient_scope",
|
|
67
|
+
ApprovalNotFound: "authorization_not_found",
|
|
68
|
+
SessionRevoked: "session_revoked",
|
|
69
|
+
TwoFactorTooManyFailures: "user.2fa.too_many_failures"
|
|
55
70
|
};
|
|
71
|
+
var STANDARD_ERROR_FIELDS = /* @__PURE__ */ new Set([
|
|
72
|
+
"type",
|
|
73
|
+
"status",
|
|
74
|
+
"title",
|
|
75
|
+
"detail",
|
|
76
|
+
"code",
|
|
77
|
+
"error",
|
|
78
|
+
"error_description"
|
|
79
|
+
]);
|
|
56
80
|
var AuthyonError = class extends Error {
|
|
57
81
|
constructor(status, body, options = {}) {
|
|
58
|
-
|
|
82
|
+
const detail = body.detail ?? body.error_description;
|
|
83
|
+
super(detail ?? body.title ?? `Authyon request failed with status ${status}`);
|
|
59
84
|
this.name = "AuthyonError";
|
|
60
85
|
this.status = status;
|
|
61
|
-
this.code = body.code ?? "unknown";
|
|
86
|
+
this.code = body.code ?? body.error ?? "unknown";
|
|
62
87
|
this.title = body.title ?? "Error";
|
|
63
|
-
this.detail =
|
|
88
|
+
this.detail = detail;
|
|
89
|
+
this.extensions = Object.fromEntries(
|
|
90
|
+
Object.entries(body).filter(([key]) => !STANDARD_ERROR_FIELDS.has(key))
|
|
91
|
+
);
|
|
64
92
|
this.requestId = options.requestId;
|
|
65
93
|
this.retryAfter = options.retryAfter;
|
|
66
94
|
this.cause = options.cause;
|
|
@@ -110,6 +138,7 @@ var AuthyonError = class extends Error {
|
|
|
110
138
|
};
|
|
111
139
|
function classifyError(status, code) {
|
|
112
140
|
if (code === ErrorCodes.NetworkError) return "network";
|
|
141
|
+
if (code === ErrorCodes.StepUpRequired) return "authentication";
|
|
113
142
|
if (code === ErrorCodes.Timeout || status === 408) return "timeout";
|
|
114
143
|
if (code === ErrorCodes.RateLimited || status === 429) return "rate_limit";
|
|
115
144
|
if (code === ErrorCodes.EmailTaken || status === 409) return "conflict";
|
|
@@ -778,7 +807,6 @@ function sanitizeUrl(value) {
|
|
|
778
807
|
url.username = "";
|
|
779
808
|
url.password = "";
|
|
780
809
|
url.hash = "";
|
|
781
|
-
url.pathname = url.pathname.replace(/(\/platform\/workspace-invites\/)[^/]+/u, "$1REDACTED");
|
|
782
810
|
const queryKeys = /* @__PURE__ */ new Set();
|
|
783
811
|
url.searchParams.forEach((_value, key) => queryKeys.add(key));
|
|
784
812
|
url.search = queryKeys.size > 0 ? [...queryKeys].map((key) => `${encodeURIComponent(key)}=REDACTED`).join("&") : "";
|
|
@@ -889,7 +917,9 @@ var JsonHttpClient = class {
|
|
|
889
917
|
if (!response.ok) {
|
|
890
918
|
let body = {};
|
|
891
919
|
try {
|
|
892
|
-
|
|
920
|
+
const parsed = await response.json();
|
|
921
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed))
|
|
922
|
+
body = parsed;
|
|
893
923
|
} catch {
|
|
894
924
|
}
|
|
895
925
|
throw new AuthyonError(response.status, body, responseMetadata(response));
|
package/dist/bff.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { H as HttpAdapter, a as HttpLoggerOptions, A as AuthyonServerClient } from './authyonServerClient-
|
|
1
|
+
import { H as HttpAdapter, a as HttpLoggerOptions, A as AuthyonServerClient } from './authyonServerClient-DQzhfaja.cjs';
|
|
2
2
|
import 'jose';
|
|
3
3
|
|
|
4
4
|
interface BffLoginInput {
|
package/dist/bff.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { H as HttpAdapter, a as HttpLoggerOptions, A as AuthyonServerClient } from './authyonServerClient-
|
|
1
|
+
import { H as HttpAdapter, a as HttpLoggerOptions, A as AuthyonServerClient } from './authyonServerClient-DQzhfaja.js';
|
|
2
2
|
import 'jose';
|
|
3
3
|
|
|
4
4
|
interface BffLoginInput {
|
package/dist/bff.js
CHANGED
|
@@ -10,16 +10,44 @@ var ErrorCodes = {
|
|
|
10
10
|
EmailTaken: "user.email_taken",
|
|
11
11
|
PasswordWeak: "user.password_weak",
|
|
12
12
|
PasswordPwned: "user.password_pwned",
|
|
13
|
-
RateLimited: "rate_limited"
|
|
13
|
+
RateLimited: "rate_limited",
|
|
14
|
+
StepUpRequired: "step_up_required",
|
|
15
|
+
InvalidSecondFactorCode: "invalid_code",
|
|
16
|
+
VerificationAttemptsExhausted: "verification_attempts_exhausted",
|
|
17
|
+
MethodNotEnrolled: "method_not_enrolled",
|
|
18
|
+
InvalidApprovalState: "invalid_authorization_state",
|
|
19
|
+
PayloadMismatch: "payload_mismatch",
|
|
20
|
+
ApprovalNotConsumable: "authorization_not_consumable",
|
|
21
|
+
IdempotencyConflict: "idempotency_conflict",
|
|
22
|
+
UserDisabled: "user_disabled",
|
|
23
|
+
UserNotFound: "user_not_found",
|
|
24
|
+
TemporarilyUnavailable: "temporarily_unavailable",
|
|
25
|
+
InsufficientScope: "insufficient_scope",
|
|
26
|
+
ApprovalNotFound: "authorization_not_found",
|
|
27
|
+
SessionRevoked: "session_revoked",
|
|
28
|
+
TwoFactorTooManyFailures: "user.2fa.too_many_failures"
|
|
14
29
|
};
|
|
30
|
+
var STANDARD_ERROR_FIELDS = /* @__PURE__ */ new Set([
|
|
31
|
+
"type",
|
|
32
|
+
"status",
|
|
33
|
+
"title",
|
|
34
|
+
"detail",
|
|
35
|
+
"code",
|
|
36
|
+
"error",
|
|
37
|
+
"error_description"
|
|
38
|
+
]);
|
|
15
39
|
var AuthyonError = class extends Error {
|
|
16
40
|
constructor(status, body, options = {}) {
|
|
17
|
-
|
|
41
|
+
const detail = body.detail ?? body.error_description;
|
|
42
|
+
super(detail ?? body.title ?? `Authyon request failed with status ${status}`);
|
|
18
43
|
this.name = "AuthyonError";
|
|
19
44
|
this.status = status;
|
|
20
|
-
this.code = body.code ?? "unknown";
|
|
45
|
+
this.code = body.code ?? body.error ?? "unknown";
|
|
21
46
|
this.title = body.title ?? "Error";
|
|
22
|
-
this.detail =
|
|
47
|
+
this.detail = detail;
|
|
48
|
+
this.extensions = Object.fromEntries(
|
|
49
|
+
Object.entries(body).filter(([key]) => !STANDARD_ERROR_FIELDS.has(key))
|
|
50
|
+
);
|
|
23
51
|
this.requestId = options.requestId;
|
|
24
52
|
this.retryAfter = options.retryAfter;
|
|
25
53
|
this.cause = options.cause;
|
|
@@ -69,6 +97,7 @@ var AuthyonError = class extends Error {
|
|
|
69
97
|
};
|
|
70
98
|
function classifyError(status, code) {
|
|
71
99
|
if (code === ErrorCodes.NetworkError) return "network";
|
|
100
|
+
if (code === ErrorCodes.StepUpRequired) return "authentication";
|
|
72
101
|
if (code === ErrorCodes.Timeout || status === 408) return "timeout";
|
|
73
102
|
if (code === ErrorCodes.RateLimited || status === 429) return "rate_limit";
|
|
74
103
|
if (code === ErrorCodes.EmailTaken || status === 409) return "conflict";
|
|
@@ -172,7 +201,6 @@ function sanitizeUrl(value) {
|
|
|
172
201
|
url.username = "";
|
|
173
202
|
url.password = "";
|
|
174
203
|
url.hash = "";
|
|
175
|
-
url.pathname = url.pathname.replace(/(\/platform\/workspace-invites\/)[^/]+/u, "$1REDACTED");
|
|
176
204
|
const queryKeys = /* @__PURE__ */ new Set();
|
|
177
205
|
url.searchParams.forEach((_value, key) => queryKeys.add(key));
|
|
178
206
|
url.search = queryKeys.size > 0 ? [...queryKeys].map((key) => `${encodeURIComponent(key)}=REDACTED`).join("&") : "";
|
|
@@ -298,7 +326,9 @@ var JsonHttpClient = class {
|
|
|
298
326
|
if (!response.ok) {
|
|
299
327
|
let body = {};
|
|
300
328
|
try {
|
|
301
|
-
|
|
329
|
+
const parsed = await response.json();
|
|
330
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed))
|
|
331
|
+
body = parsed;
|
|
302
332
|
} catch {
|
|
303
333
|
}
|
|
304
334
|
throw new AuthyonError(response.status, body, responseMetadata(response));
|