@authyon/server 0.2.0-beta.11 → 0.2.0-beta.14
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 +49 -62
- package/dist/{authorization-CeP_GqT7.d.cts → authorization-B7ynKAud.d.cts} +1 -1
- package/dist/{authorization-D_A6L9Ie.d.ts → authorization-BF015NDJ.d.ts} +1 -1
- package/dist/{authyonServerClient-D-DxoL30.d.cts → authyonServerClient-DmNnjw4z.d.cts} +141 -115
- package/dist/{authyonServerClient-D-DxoL30.d.ts → authyonServerClient-DmNnjw4z.d.ts} +141 -115
- package/dist/bff.cjs +29 -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-TWUVXZOT.js} +29 -6
- package/dist/index.cjs +127 -147
- package/dist/index.d.cts +27 -9
- package/dist/index.d.ts +27 -9
- package/dist/index.js +84 -125
- package/dist/next.d.cts +2 -2
- package/dist/next.d.ts +2 -2
- package/package.json +1 -1
|
@@ -253,6 +253,8 @@ interface CreateUserInput {
|
|
|
253
253
|
email: string;
|
|
254
254
|
username: string;
|
|
255
255
|
password: string;
|
|
256
|
+
/** Values for custom user fields configured in the environment. */
|
|
257
|
+
customFields?: Record<string, unknown>;
|
|
256
258
|
emailConfirmed?: boolean;
|
|
257
259
|
roles?: string[];
|
|
258
260
|
/** Tenants (organizations) to add the user to on creation. */
|
|
@@ -399,14 +401,6 @@ type CreateCredentialInput = CredentialPermissionsInput & {
|
|
|
399
401
|
description?: string;
|
|
400
402
|
lifetimeDays?: number | null;
|
|
401
403
|
};
|
|
402
|
-
interface CredentialScope {
|
|
403
|
-
workspaceId: string;
|
|
404
|
-
environmentId: string;
|
|
405
|
-
tenantId?: string;
|
|
406
|
-
}
|
|
407
|
-
interface TenantManagementScope extends CredentialScope {
|
|
408
|
-
tenantId: string;
|
|
409
|
-
}
|
|
410
404
|
interface CredentialCreator {
|
|
411
405
|
id: string | null;
|
|
412
406
|
type: string;
|
|
@@ -422,64 +416,6 @@ interface CredentialDetail extends TenantCredentialSummary {
|
|
|
422
416
|
lifetimeSeconds: number | null;
|
|
423
417
|
accessTokenLifetimeSeconds: number;
|
|
424
418
|
}
|
|
425
|
-
type WorkspaceRole = "admin" | "auditor";
|
|
426
|
-
interface WorkspaceMember {
|
|
427
|
-
memberId: string | null;
|
|
428
|
-
userId: string;
|
|
429
|
-
email: string;
|
|
430
|
-
name: string;
|
|
431
|
-
role: string;
|
|
432
|
-
isOwner: boolean;
|
|
433
|
-
isSelf: boolean;
|
|
434
|
-
invitedByName: string | null;
|
|
435
|
-
joinedAt: string;
|
|
436
|
-
lastLoginAt: string | null;
|
|
437
|
-
}
|
|
438
|
-
interface WorkspaceInvite {
|
|
439
|
-
id: string;
|
|
440
|
-
email: string;
|
|
441
|
-
role: string;
|
|
442
|
-
invitedByName: string | null;
|
|
443
|
-
createdAt: string;
|
|
444
|
-
expiresAt: string;
|
|
445
|
-
}
|
|
446
|
-
interface WorkspaceTeam {
|
|
447
|
-
workspaceId: string;
|
|
448
|
-
workspaceName: string;
|
|
449
|
-
callerRole: string;
|
|
450
|
-
canManage: boolean;
|
|
451
|
-
members: WorkspaceMember[];
|
|
452
|
-
pendingInvites: WorkspaceInvite[];
|
|
453
|
-
}
|
|
454
|
-
interface InviteWorkspaceMemberInput {
|
|
455
|
-
email: string;
|
|
456
|
-
role: WorkspaceRole;
|
|
457
|
-
}
|
|
458
|
-
interface WorkspaceInviteIssued {
|
|
459
|
-
inviteId: string;
|
|
460
|
-
email: string;
|
|
461
|
-
role: string;
|
|
462
|
-
/** Sensitive bearer link returned at issuance. Do not log or persist in public storage. */
|
|
463
|
-
acceptUrl: string;
|
|
464
|
-
expiresAt: string;
|
|
465
|
-
}
|
|
466
|
-
interface WorkspaceInvitePreview {
|
|
467
|
-
workspaceName: string;
|
|
468
|
-
email: string;
|
|
469
|
-
role: string;
|
|
470
|
-
expiresAt: string;
|
|
471
|
-
requiresRegistration: boolean;
|
|
472
|
-
}
|
|
473
|
-
interface WorkspaceInviteAccepted {
|
|
474
|
-
workspaceId: string;
|
|
475
|
-
workspaceName: string;
|
|
476
|
-
role: string;
|
|
477
|
-
accountCreated: boolean;
|
|
478
|
-
}
|
|
479
|
-
interface AcceptWorkspaceInviteInput {
|
|
480
|
-
name?: string;
|
|
481
|
-
password?: string;
|
|
482
|
-
}
|
|
483
419
|
interface InviteTenantMemberInput {
|
|
484
420
|
email: string;
|
|
485
421
|
roles?: string[];
|
|
@@ -506,51 +442,107 @@ interface JsonRequestOptions {
|
|
|
506
442
|
|
|
507
443
|
type ManagementRequest = <T>(path: string, options?: JsonRequestOptions) => Promise<T>;
|
|
508
444
|
|
|
509
|
-
/**
|
|
510
|
-
|
|
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
|
-
|
|
445
|
+
/** Lifecycle of a transaction-bound financial authorization. */
|
|
446
|
+
type FinancialAuthorizationStatus = "pending" | "approved" | "denied" | "consumed" | "expired";
|
|
447
|
+
/**
|
|
448
|
+
* The transaction the customer approves. The API hashes a canonical form of
|
|
449
|
+
* these fields; `consume()` must resend exactly the same values (amount is
|
|
450
|
+
* normalized to four decimal places, metadata keys are sorted).
|
|
451
|
+
*/
|
|
452
|
+
interface FinancialTransaction {
|
|
453
|
+
/** Business action, e.g. `"pix.transfer"`. Max 100 characters. */
|
|
454
|
+
action: string;
|
|
455
|
+
/** Positive amount, up to 15 integer digits and 4 decimal places. */
|
|
456
|
+
amount: number;
|
|
457
|
+
/** ISO 4217 currency code, e.g. `"BRL"`. */
|
|
458
|
+
currency: string;
|
|
459
|
+
/** Human-readable beneficiary shown to the customer. Max 256 characters. */
|
|
460
|
+
beneficiary: string;
|
|
461
|
+
/** Optional JSON object bound into the hash (max 16 KiB). */
|
|
462
|
+
metadata?: Record<string, unknown>;
|
|
463
|
+
}
|
|
464
|
+
/** Evidence of how the customer proved their identity when approving. */
|
|
465
|
+
interface FinancialAssurance {
|
|
466
|
+
/** `urn:authyon:loa:3` (passkey) or `urn:authyon:loa:2` (authenticator code). */
|
|
467
|
+
acr: string;
|
|
468
|
+
/** Authentication methods, e.g. `["pwd", "otp"]` or `["pwd", "webauthn"]`. */
|
|
469
|
+
amr: string[];
|
|
470
|
+
/** When the second factor was verified (ISO 8601). */
|
|
471
|
+
authTime: string;
|
|
472
|
+
}
|
|
473
|
+
interface FinancialAuthorization {
|
|
474
|
+
id: string;
|
|
475
|
+
status: FinancialAuthorizationStatus;
|
|
476
|
+
subjectId: string;
|
|
477
|
+
tenantId?: string | null;
|
|
478
|
+
action: string;
|
|
479
|
+
amount: number;
|
|
480
|
+
currency: string;
|
|
481
|
+
beneficiary: string;
|
|
482
|
+
/** SHA-256 (hex) of the canonical transaction. */
|
|
483
|
+
transactionHash: string;
|
|
484
|
+
createdAt: string;
|
|
485
|
+
expiresAt: string;
|
|
486
|
+
decidedAt?: string | null;
|
|
487
|
+
consumedAt?: string | null;
|
|
488
|
+
/** Full canonical transaction — returned only to the customer (subject) view. */
|
|
489
|
+
transaction?: FinancialTransaction | null;
|
|
490
|
+
/** Present once approved. */
|
|
491
|
+
assurance?: FinancialAssurance | null;
|
|
492
|
+
}
|
|
493
|
+
/** Inline second factor sent with `confirm()`. */
|
|
494
|
+
type ConfirmFinancialAuthorizationInput = {
|
|
495
|
+
method: "authenticator";
|
|
496
|
+
/** Six-digit code from the customer's authenticator app. */
|
|
497
|
+
code: string;
|
|
498
|
+
} | {
|
|
499
|
+
method: "webauthn";
|
|
500
|
+
/** Assertion for the options returned by `webauthnOptions()`. */
|
|
501
|
+
webAuthn: {
|
|
502
|
+
ceremonyToken: string;
|
|
503
|
+
/** JSON-serialized `PublicKeyCredential` from `navigator.credentials.get()`. */
|
|
504
|
+
assertionJson: string;
|
|
547
505
|
};
|
|
506
|
+
};
|
|
507
|
+
/** Passkey assertion options for approving one authorization. */
|
|
508
|
+
interface FinancialWebAuthnOptions {
|
|
509
|
+
ceremonyToken: string;
|
|
510
|
+
/** JSON `PublicKeyCredentialRequestOptions` to pass to `navigator.credentials.get()`. */
|
|
511
|
+
optionsJson: string;
|
|
548
512
|
}
|
|
513
|
+
|
|
514
|
+
/** Sends a request already authenticated as the customer (end-user bearer). */
|
|
515
|
+
type SubjectRequest = <T>(path: string, options?: JsonRequestOptions) => Promise<T>;
|
|
516
|
+
/** Customer-side operations on a financial authorization (`/auth/authorizations`). */
|
|
517
|
+
declare function subjectFinancialAuthorizations(request: SubjectRequest): {
|
|
518
|
+
/** GET /auth/authorizations/{id} — the pending transaction, to show before asking for the code. */
|
|
519
|
+
get: (id: string) => Promise<FinancialAuthorization>;
|
|
520
|
+
/** POST /auth/authorizations/{id}/webauthn/options — passkey options for approving this authorization. */
|
|
521
|
+
webauthnOptions: (id: string) => Promise<FinancialWebAuthnOptions>;
|
|
522
|
+
/**
|
|
523
|
+
* POST /auth/authorizations/{id}/confirm — approves the transaction.
|
|
524
|
+
*
|
|
525
|
+
* Pass the authenticator code or passkey assertion to verify the second
|
|
526
|
+
* factor inline (recommended). Without `input`, the session itself must
|
|
527
|
+
* have used a passkey or authenticator code within the last 5 minutes,
|
|
528
|
+
* otherwise the API answers `step_up_required`.
|
|
529
|
+
*/
|
|
530
|
+
confirm: (id: string, input?: ConfirmFinancialAuthorizationInput) => Promise<FinancialAuthorization>;
|
|
531
|
+
/** POST /auth/authorizations/{id}/reject — the customer declines the transaction. */
|
|
532
|
+
reject: (id: string) => Promise<FinancialAuthorization>;
|
|
533
|
+
};
|
|
534
|
+
|
|
549
535
|
/** End-user operations require a user token and the environment publishable key. */
|
|
550
536
|
declare class UserScopedClient {
|
|
551
537
|
#private;
|
|
552
538
|
/** @hidden */
|
|
553
539
|
constructor(request: ManagementRequest, token: AccessTokenSource);
|
|
540
|
+
/**
|
|
541
|
+
* Customer-side approval of a financial authorization, for backends (BFF)
|
|
542
|
+
* that hold the customer's access token: `get`, `webauthnOptions`,
|
|
543
|
+
* `confirm`, `reject`.
|
|
544
|
+
*/
|
|
545
|
+
readonly financialAuthorizations: ReturnType<typeof subjectFinancialAuthorizations>;
|
|
554
546
|
readonly tenants: {
|
|
555
547
|
members: {
|
|
556
548
|
list: (tenantId: string, options?: PaginationOptions) => Promise<TenantMemberPage>;
|
|
@@ -560,13 +552,29 @@ declare class UserScopedClient {
|
|
|
560
552
|
};
|
|
561
553
|
};
|
|
562
554
|
}
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
/**
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
555
|
+
|
|
556
|
+
/** POST /env/authorizations — a transaction awaiting the customer's approval. */
|
|
557
|
+
interface CreateFinancialAuthorizationInput extends FinancialTransaction {
|
|
558
|
+
/** Environment user who must approve. */
|
|
559
|
+
subjectId: string;
|
|
560
|
+
/** Restrict approval to a session in this tenant. */
|
|
561
|
+
tenantId?: string;
|
|
562
|
+
/** Lifetime in seconds, clamped to 60–600. Default 300. */
|
|
563
|
+
expiresInSeconds?: number;
|
|
564
|
+
/**
|
|
565
|
+
* Sent as the `Idempotency-Key` header (max 128 chars). Retrying with the
|
|
566
|
+
* same key and transaction returns the same authorization; the same key
|
|
567
|
+
* with a different transaction fails with `idempotency_conflict`.
|
|
568
|
+
*/
|
|
569
|
+
idempotencyKey: string;
|
|
570
|
+
}
|
|
571
|
+
/** POST /env/authorizations/{id}/consume — single-use redemption result. */
|
|
572
|
+
interface ConsumedFinancialAuthorization {
|
|
573
|
+
id: string;
|
|
574
|
+
status: "consumed";
|
|
575
|
+
consumedAt: string;
|
|
576
|
+
transactionHash: string;
|
|
577
|
+
assurance: FinancialAssurance | null;
|
|
570
578
|
}
|
|
571
579
|
|
|
572
580
|
interface ClientRequestContext {
|
|
@@ -680,11 +688,8 @@ declare class AuthyonServerClient {
|
|
|
680
688
|
* "the token's tenant" rather than one you pass by id.
|
|
681
689
|
*/
|
|
682
690
|
tenant(credentials: ClientCredentials): TenantScopedClient;
|
|
683
|
-
/** Uses only the supplied platform-user access token. */
|
|
684
|
-
platform(token: AccessTokenSource): PlatformScopedClient;
|
|
685
691
|
/** Uses an end-user token; the configured environment key selects the environment. */
|
|
686
692
|
user(token: AccessTokenSource): UserScopedClient;
|
|
687
|
-
readonly workspaceInvites: WorkspaceInvitesClient;
|
|
688
693
|
readonly environment: {
|
|
689
694
|
users: {
|
|
690
695
|
/** GET /env/users — paginated list of users in the environment. */
|
|
@@ -814,6 +819,27 @@ declare class AuthyonServerClient {
|
|
|
814
819
|
/** GET /permissions/reserved — reserved permission names you can't redefine. */
|
|
815
820
|
reserved: () => Promise<ReservedPermissions>;
|
|
816
821
|
};
|
|
822
|
+
/**
|
|
823
|
+
* Transaction-bound step-up for financial operations. The environment
|
|
824
|
+
* credential needs the `authyon:financial:authorize` scope.
|
|
825
|
+
*
|
|
826
|
+
* 1. `create()` the authorization for the transaction and the customer.
|
|
827
|
+
* 2. The customer approves it with their authenticator code or passkey
|
|
828
|
+
* (`@authyon/auth` → `financialAuthorizations.confirm`).
|
|
829
|
+
* 3. `consume()` it with the same transaction right before executing it.
|
|
830
|
+
*/
|
|
831
|
+
financialAuthorizations: {
|
|
832
|
+
/** POST /env/authorizations — registers a transaction awaiting the customer's approval. */
|
|
833
|
+
create: (input: CreateFinancialAuthorizationInput) => Promise<FinancialAuthorization>;
|
|
834
|
+
/** GET /env/authorizations/{id} — current status and, once approved, the assurance evidence. */
|
|
835
|
+
get: (id: string) => Promise<FinancialAuthorization>;
|
|
836
|
+
/**
|
|
837
|
+
* POST /env/authorizations/{id}/consume — redeems an approved
|
|
838
|
+
* authorization exactly once. Resend the same transaction given to
|
|
839
|
+
* `create()`; any difference fails with `transaction_mismatch`.
|
|
840
|
+
*/
|
|
841
|
+
consume: (id: string, transaction: FinancialTransaction) => Promise<ConsumedFinancialAuthorization>;
|
|
842
|
+
};
|
|
817
843
|
audit: {
|
|
818
844
|
/** GET /env/audit — paginated list of the environment's audit events. */
|
|
819
845
|
list: (params?: PaginationOptions) => Promise<Paged<AuditEvent>>;
|
|
@@ -895,4 +921,4 @@ declare class TenantScopedClient {
|
|
|
895
921
|
/** Convenience factory: `const authyon = createClient({ clientId, clientSecret })`. */
|
|
896
922
|
declare function createClient(options?: AuthyonServerClientOptions): AuthyonServerClient;
|
|
897
923
|
|
|
898
|
-
export { type
|
|
924
|
+
export { type TenantCredentialIssued 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 Paged as P, type PaginationOptions as Q, type Permission as R, type PermissionsByRole as S, type ReservedPermissions as T, type Role as U, type RoleGrant as V, type RoleInput as W, type RoleList as X, type RolePermissions as Y, type SafeJwtAlgorithm as Z, type TenantClientValidationResult as _, type HttpLoggerOptions as a, type TenantCredentialSummary as a0, type TenantMember as a1, type TenantMemberPage as a2, type TenantMembership as a3, TenantScopedClient as a4, type TokenResult as a5, TokenVerificationError as a6, type TokenVerificationErrorCode as a7, type UpdateOrganizationInput as a8, type User as a9, UserScopedClient as aa, type ValidateResult as ab, type VerifiedAccessToken as ac, createClient as ad, normalizeClientIp as ae, type AccessTokenSource as b, type AuditEvent as c, type AuthyonJwksDiscoveryOptions as d, type AuthyonJwtClaims as e, type AuthyonServerClientOptions as f, type ClientRequestContext as g, type ConfirmFinancialAuthorizationInput as h, type ConsumedFinancialAuthorization as i, type CreateCredentialInput as j, type CreateFinancialAuthorizationInput as k, type CreateOrganizationInput as l, type CreatePermissionInput as m, type CreateTenantCredentialInput as n, type CreateUserInput as o, type CredentialCreator as p, type CredentialDetail as q, type CredentialListOptions as r, type CredentialPermissionsInput as s, type FinancialAssurance as t, type FinancialAuthorization as u, type FinancialAuthorizationStatus as v, type FinancialTransaction as w, type FinancialWebAuthnOptions as x, type HttpAdapterRequest as y, type HttpLogEvent as z };
|
package/dist/bff.cjs
CHANGED
|
@@ -51,16 +51,37 @@ 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
|
+
InvalidAuthorizationState: "invalid_authorization_state",
|
|
60
|
+
TransactionMismatch: "transaction_mismatch",
|
|
61
|
+
AuthorizationNotConsumable: "authorization_not_consumable",
|
|
62
|
+
IdempotencyConflict: "idempotency_conflict"
|
|
55
63
|
};
|
|
64
|
+
var STANDARD_ERROR_FIELDS = /* @__PURE__ */ new Set([
|
|
65
|
+
"type",
|
|
66
|
+
"status",
|
|
67
|
+
"title",
|
|
68
|
+
"detail",
|
|
69
|
+
"code",
|
|
70
|
+
"error",
|
|
71
|
+
"error_description"
|
|
72
|
+
]);
|
|
56
73
|
var AuthyonError = class extends Error {
|
|
57
74
|
constructor(status, body, options = {}) {
|
|
58
|
-
|
|
75
|
+
const detail = body.detail ?? body.error_description;
|
|
76
|
+
super(detail ?? body.title ?? `Authyon request failed with status ${status}`);
|
|
59
77
|
this.name = "AuthyonError";
|
|
60
78
|
this.status = status;
|
|
61
|
-
this.code = body.code ?? "unknown";
|
|
79
|
+
this.code = body.code ?? body.error ?? "unknown";
|
|
62
80
|
this.title = body.title ?? "Error";
|
|
63
|
-
this.detail =
|
|
81
|
+
this.detail = detail;
|
|
82
|
+
this.extensions = Object.fromEntries(
|
|
83
|
+
Object.entries(body).filter(([key]) => !STANDARD_ERROR_FIELDS.has(key))
|
|
84
|
+
);
|
|
64
85
|
this.requestId = options.requestId;
|
|
65
86
|
this.retryAfter = options.retryAfter;
|
|
66
87
|
this.cause = options.cause;
|
|
@@ -110,6 +131,7 @@ var AuthyonError = class extends Error {
|
|
|
110
131
|
};
|
|
111
132
|
function classifyError(status, code) {
|
|
112
133
|
if (code === ErrorCodes.NetworkError) return "network";
|
|
134
|
+
if (code === ErrorCodes.StepUpRequired) return "authentication";
|
|
113
135
|
if (code === ErrorCodes.Timeout || status === 408) return "timeout";
|
|
114
136
|
if (code === ErrorCodes.RateLimited || status === 429) return "rate_limit";
|
|
115
137
|
if (code === ErrorCodes.EmailTaken || status === 409) return "conflict";
|
|
@@ -778,7 +800,6 @@ function sanitizeUrl(value) {
|
|
|
778
800
|
url.username = "";
|
|
779
801
|
url.password = "";
|
|
780
802
|
url.hash = "";
|
|
781
|
-
url.pathname = url.pathname.replace(/(\/platform\/workspace-invites\/)[^/]+/u, "$1REDACTED");
|
|
782
803
|
const queryKeys = /* @__PURE__ */ new Set();
|
|
783
804
|
url.searchParams.forEach((_value, key) => queryKeys.add(key));
|
|
784
805
|
url.search = queryKeys.size > 0 ? [...queryKeys].map((key) => `${encodeURIComponent(key)}=REDACTED`).join("&") : "";
|
|
@@ -889,7 +910,9 @@ var JsonHttpClient = class {
|
|
|
889
910
|
if (!response.ok) {
|
|
890
911
|
let body = {};
|
|
891
912
|
try {
|
|
892
|
-
|
|
913
|
+
const parsed = await response.json();
|
|
914
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed))
|
|
915
|
+
body = parsed;
|
|
893
916
|
} catch {
|
|
894
917
|
}
|
|
895
918
|
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-DmNnjw4z.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-DmNnjw4z.js';
|
|
2
2
|
import 'jose';
|
|
3
3
|
|
|
4
4
|
interface BffLoginInput {
|
package/dist/bff.js
CHANGED
|
@@ -10,16 +10,37 @@ 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
|
+
InvalidAuthorizationState: "invalid_authorization_state",
|
|
19
|
+
TransactionMismatch: "transaction_mismatch",
|
|
20
|
+
AuthorizationNotConsumable: "authorization_not_consumable",
|
|
21
|
+
IdempotencyConflict: "idempotency_conflict"
|
|
14
22
|
};
|
|
23
|
+
var STANDARD_ERROR_FIELDS = /* @__PURE__ */ new Set([
|
|
24
|
+
"type",
|
|
25
|
+
"status",
|
|
26
|
+
"title",
|
|
27
|
+
"detail",
|
|
28
|
+
"code",
|
|
29
|
+
"error",
|
|
30
|
+
"error_description"
|
|
31
|
+
]);
|
|
15
32
|
var AuthyonError = class extends Error {
|
|
16
33
|
constructor(status, body, options = {}) {
|
|
17
|
-
|
|
34
|
+
const detail = body.detail ?? body.error_description;
|
|
35
|
+
super(detail ?? body.title ?? `Authyon request failed with status ${status}`);
|
|
18
36
|
this.name = "AuthyonError";
|
|
19
37
|
this.status = status;
|
|
20
|
-
this.code = body.code ?? "unknown";
|
|
38
|
+
this.code = body.code ?? body.error ?? "unknown";
|
|
21
39
|
this.title = body.title ?? "Error";
|
|
22
|
-
this.detail =
|
|
40
|
+
this.detail = detail;
|
|
41
|
+
this.extensions = Object.fromEntries(
|
|
42
|
+
Object.entries(body).filter(([key]) => !STANDARD_ERROR_FIELDS.has(key))
|
|
43
|
+
);
|
|
23
44
|
this.requestId = options.requestId;
|
|
24
45
|
this.retryAfter = options.retryAfter;
|
|
25
46
|
this.cause = options.cause;
|
|
@@ -69,6 +90,7 @@ var AuthyonError = class extends Error {
|
|
|
69
90
|
};
|
|
70
91
|
function classifyError(status, code) {
|
|
71
92
|
if (code === ErrorCodes.NetworkError) return "network";
|
|
93
|
+
if (code === ErrorCodes.StepUpRequired) return "authentication";
|
|
72
94
|
if (code === ErrorCodes.Timeout || status === 408) return "timeout";
|
|
73
95
|
if (code === ErrorCodes.RateLimited || status === 429) return "rate_limit";
|
|
74
96
|
if (code === ErrorCodes.EmailTaken || status === 409) return "conflict";
|
|
@@ -172,7 +194,6 @@ function sanitizeUrl(value) {
|
|
|
172
194
|
url.username = "";
|
|
173
195
|
url.password = "";
|
|
174
196
|
url.hash = "";
|
|
175
|
-
url.pathname = url.pathname.replace(/(\/platform\/workspace-invites\/)[^/]+/u, "$1REDACTED");
|
|
176
197
|
const queryKeys = /* @__PURE__ */ new Set();
|
|
177
198
|
url.searchParams.forEach((_value, key) => queryKeys.add(key));
|
|
178
199
|
url.search = queryKeys.size > 0 ? [...queryKeys].map((key) => `${encodeURIComponent(key)}=REDACTED`).join("&") : "";
|
|
@@ -298,7 +319,9 @@ var JsonHttpClient = class {
|
|
|
298
319
|
if (!response.ok) {
|
|
299
320
|
let body = {};
|
|
300
321
|
try {
|
|
301
|
-
|
|
322
|
+
const parsed = await response.json();
|
|
323
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed))
|
|
324
|
+
body = parsed;
|
|
302
325
|
} catch {
|
|
303
326
|
}
|
|
304
327
|
throw new AuthyonError(response.status, body, responseMetadata(response));
|