@authyon/server 0.2.0-beta.14 → 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 CHANGED
@@ -120,7 +120,7 @@ await authyon.environment.audit.list({ take: 50 });
120
120
 
121
121
  Veja [`examples/organizationMembership.ts`](./examples/organizationMembership.ts) para o fluxo completo, incluindo as rotas de backend que o `@authyon/auth` chamaria.
122
122
 
123
- Namespaces disponíveis: `environment.users`, `environment.tenants` (com `.members` e `.roles` aninhados), `environment.roles`, `environment.permissions`, `environment.audit`, `environment.financialAuthorizations`.
123
+ Namespaces disponíveis: `environment.users`, `environment.tenants` (com `.members` e `.roles` aninhados), `environment.roles`, `environment.permissions`, `environment.audit`. OTP e aprovações ficam em `security` (veja abaixo).
124
124
 
125
125
  ## Autorização local
126
126
 
@@ -191,34 +191,36 @@ Chamadas server-side propagam `clientIp` em `X-Forwarded-For`. O middleware Expr
191
191
  await authyon.validate(token, { clientIp: "203.0.113.10" });
192
192
  ```
193
193
 
194
- ## Confirmação de transações financeiras
194
+ ## Segurança (`security.*`)
195
195
 
196
- Exige uma credencial de ambiente com o escopo `authyon:financial:authorize`. Guia
197
- completo, incluindo o lado do cliente: [`docs/financialStepUp.md`](../../docs/financialStepUp.md).
196
+ OTP e aprovações ficam agrupados em `authyon.security`. Exige uma credencial de ambiente
197
+ com o escopo `authyon:financial:authorize`. Guia completo:
198
+ [`docs/security-otp-approvals.md`](../../docs/security-otp-approvals.md).
198
199
 
199
200
  ```ts
200
- const transaction = {
201
- action: "pix.transfer",
202
- amount: 150.5,
203
- currency: "BRL",
204
- beneficiary: "Maria Silva",
205
- };
206
-
207
- // 1. Antes de executar, peça a aprovação do cliente.
208
- const { id } = await authyon.environment.financialAuthorizations.create({
209
- ...transaction,
201
+ // security.otp — só validar o código do app autenticador
202
+ const result = await authyon.security.otp.check(customerId, code);
203
+ if (!result.valid) console.log(result.attemptsRemaining, result.sessionsRevoked);
204
+
205
+ // security.approvals — aprovação presa a um payload livre e de uso único
206
+ const { id } = await authyon.security.approvals.create({
210
207
  subjectId: customerId,
211
- idempotencyKey: orderId,
208
+ payload: { type: "pix", amount: 150.5, to: "maria@example.com" },
212
209
  });
213
-
214
- // 2. O cliente confirma com o código (@authyon/auth → financialAuthorizations.confirm).
215
-
216
- // 3. Consuma com a mesma transação e só então execute.
217
- const { assurance } = await authyon.environment.financialAuthorizations.consume(id, transaction);
210
+ // ...cliente confirma com @authyon/auth → security.approvals.confirm
211
+ const { payload } = await authyon.security.approvals.consume(id);
218
212
  ```
219
213
 
220
- Se o seu servidor guarda o token do cliente (BFF), o lado do cliente também está em
221
- `authyon.user(accessToken).financialAuthorizations`.
214
+ | Método | Endpoint |
215
+ | ------------------------------------ | --------------------------------------- |
216
+ | `security.otp.check(userId, code)` | `POST /env/users/{userId}/otp/verify` |
217
+ | `security.approvals.create(input)` | `POST /env/authorizations` |
218
+ | `security.approvals.get(id)` | `GET /env/authorizations/{id}` |
219
+ | `security.approvals.consume(id, p?)` | `POST /env/authorizations/{id}/consume` |
220
+
221
+ Cada código vale uma vez; 3 erros seguidos deslogam o usuário de todos os dispositivos e
222
+ 5 bloqueiam a verificação por 15 minutos. Se o seu servidor guarda o token do cliente
223
+ (BFF), o lado do cliente está em `authyon.user(accessToken).security.approvals`.
222
224
 
223
225
  ## Administração por tenant (`tenant()`)
224
226
 
@@ -1,4 +1,4 @@
1
- import { G as JwksTokenVerifier, A as AuthyonServerClient } from './authyonServerClient-DmNnjw4z.cjs';
1
+ import { G as JwksTokenVerifier, A as AuthyonServerClient } from './authyonServerClient-DQzhfaja.cjs';
2
2
 
3
3
  type AbilitySubject = string | Record<string, unknown>;
4
4
  type AbilityConditions = Record<string, unknown>;
@@ -1,4 +1,4 @@
1
- import { G as JwksTokenVerifier, A as AuthyonServerClient } from './authyonServerClient-DmNnjw4z.js';
1
+ import { G as JwksTokenVerifier, A as AuthyonServerClient } from './authyonServerClient-DQzhfaja.js';
2
2
 
3
3
  type AbilitySubject = string | Record<string, unknown>;
4
4
  type AbilityConditions = Record<string, unknown>;
@@ -442,27 +442,16 @@ interface JsonRequestOptions {
442
442
 
443
443
  type ManagementRequest = <T>(path: string, options?: JsonRequestOptions) => Promise<T>;
444
444
 
445
- /** Lifecycle of a transaction-bound financial authorization. */
446
- type FinancialAuthorizationStatus = "pending" | "approved" | "denied" | "consumed" | "expired";
445
+ /** Lifecycle of an approval. */
446
+ type ApprovalStatus = "pending" | "approved" | "denied" | "consumed" | "expired";
447
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).
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
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
- }
452
+ type ApprovalPayload = Record<string, unknown>;
464
453
  /** Evidence of how the customer proved their identity when approving. */
465
- interface FinancialAssurance {
454
+ interface ApprovalAssurance {
466
455
  /** `urn:authyon:loa:3` (passkey) or `urn:authyon:loa:2` (authenticator code). */
467
456
  acr: string;
468
457
  /** Authentication methods, e.g. `["pwd", "otp"]` or `["pwd", "webauthn"]`. */
@@ -470,28 +459,25 @@ interface FinancialAssurance {
470
459
  /** When the second factor was verified (ISO 8601). */
471
460
  authTime: string;
472
461
  }
473
- interface FinancialAuthorization {
462
+ /** A request for the customer to approve something with a second factor. */
463
+ interface Approval {
474
464
  id: string;
475
- status: FinancialAuthorizationStatus;
465
+ status: ApprovalStatus;
476
466
  subjectId: string;
477
467
  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;
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;
484
472
  createdAt: string;
485
473
  expiresAt: string;
486
474
  decidedAt?: string | null;
487
475
  consumedAt?: string | null;
488
- /** Full canonical transaction — returned only to the customer (subject) view. */
489
- transaction?: FinancialTransaction | null;
490
476
  /** Present once approved. */
491
- assurance?: FinancialAssurance | null;
477
+ assurance?: ApprovalAssurance | null;
492
478
  }
493
- /** Inline second factor sent with `confirm()`. */
494
- type ConfirmFinancialAuthorizationInput = {
479
+ /** Second factor sent with `confirm()`. */
480
+ type ConfirmApprovalInput = {
495
481
  method: "authenticator";
496
482
  /** Six-digit code from the customer's authenticator app. */
497
483
  code: string;
@@ -504,33 +490,36 @@ type ConfirmFinancialAuthorizationInput = {
504
490
  assertionJson: string;
505
491
  };
506
492
  };
507
- /** Passkey assertion options for approving one authorization. */
508
- interface FinancialWebAuthnOptions {
493
+ /** Passkey assertion options for approving one approval. */
494
+ interface ApprovalWebAuthnOptions {
509
495
  ceremonyToken: string;
510
496
  /** JSON `PublicKeyCredentialRequestOptions` to pass to `navigator.credentials.get()`. */
511
497
  optionsJson: string;
512
498
  }
513
499
 
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>;
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>;
522
506
  /**
523
- * POST /auth/authorizations/{id}/confirm — approves the transaction.
507
+ * POST /auth/authorizations/{id}/confirm — approves it.
524
508
  *
525
509
  * Pass the authenticator code or passkey assertion to verify the second
526
510
  * factor inline (recommended). Without `input`, the session itself must
527
511
  * have used a passkey or authenticator code within the last 5 minutes,
528
512
  * otherwise the API answers `step_up_required`.
529
513
  */
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
- };
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;
522
+ }
534
523
 
535
524
  /** End-user operations require a user token and the environment publishable key. */
536
525
  declare class UserScopedClient {
@@ -538,11 +527,10 @@ declare class UserScopedClient {
538
527
  /** @hidden */
539
528
  constructor(request: ManagementRequest, token: AccessTokenSource);
540
529
  /**
541
- * Customer-side approval of a financial authorization, for backends (BFF)
542
- * that hold the customer's access token: `get`, `webauthnOptions`,
543
- * `confirm`, `reject`.
530
+ * The customer's side of `security.approvals`, for backends (BFF) that hold
531
+ * the customer's access token: `get`, `webauthnOptions`, `confirm`, `reject`.
544
532
  */
545
- readonly financialAuthorizations: ReturnType<typeof subjectFinancialAuthorizations>;
533
+ readonly security: SubjectSecurity;
546
534
  readonly tenants: {
547
535
  members: {
548
536
  list: (tenantId: string, options?: PaginationOptions) => Promise<TenantMemberPage>;
@@ -553,29 +541,54 @@ declare class UserScopedClient {
553
541
  };
554
542
  }
555
543
 
556
- /** POST /env/authorizations — a transaction awaiting the customer's approval. */
557
- interface CreateFinancialAuthorizationInput extends FinancialTransaction {
544
+ /** `security.approvals.create()` — something awaiting the customer's approval. */
545
+ interface CreateApprovalInput {
558
546
  /** Environment user who must approve. */
559
547
  subjectId: string;
548
+ /** Any JSON object (up to 16 KiB) describing what is being approved. Default `{}`. */
549
+ payload?: ApprovalPayload;
560
550
  /** Restrict approval to a session in this tenant. */
561
551
  tenantId?: string;
562
552
  /** Lifetime in seconds, clamped to 60–600. Default 300. */
563
553
  expiresInSeconds?: number;
564
554
  /**
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`.
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`.
568
558
  */
569
- idempotencyKey: string;
559
+ idempotencyKey?: string;
570
560
  }
571
- /** POST /env/authorizations/{id}/consume — single-use redemption result. */
572
- interface ConsumedFinancialAuthorization {
561
+ /** `security.approvals.consume()` — single-use redemption result. */
562
+ interface ConsumedApproval {
573
563
  id: string;
574
564
  status: "consumed";
575
565
  consumedAt: string;
576
- transactionHash: string;
577
- assurance: FinancialAssurance | null;
578
- }
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
+ };
579
592
 
580
593
  interface ClientRequestContext {
581
594
  /** Real end-user IP, resolved only from infrastructure trusted by the application. */
@@ -819,32 +832,43 @@ declare class AuthyonServerClient {
819
832
  /** GET /permissions/reserved — reserved permission names you can't redefine. */
820
833
  reserved: () => Promise<ReservedPermissions>;
821
834
  };
835
+ audit: {
836
+ /** GET /env/audit — paginated list of the environment's audit events. */
837
+ list: (params?: PaginationOptions) => Promise<Paged<AuditEvent>>;
838
+ /** GET /env/audit/login-activity — paginated login activity in the environment. */
839
+ loginActivity: (params?: PaginationOptions) => Promise<Paged<LoginActivity>>;
840
+ };
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
+ };
822
853
  /**
823
- * Transaction-bound step-up for financial operations. The environment
824
- * credential needs the `authyon:financial:authorize` scope.
854
+ * The customer approves a payload with their authenticator code or
855
+ * passkey, once.
825
856
  *
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.
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.
830
860
  */
831
- financialAuthorizations: {
832
- /** POST /env/authorizations — registers a transaction awaiting the customer's approval. */
833
- create: (input: CreateFinancialAuthorizationInput) => Promise<FinancialAuthorization>;
861
+ approvals: {
862
+ /** POST /env/authorizations — registers a payload awaiting the customer's approval. */
863
+ create: (input: CreateApprovalInput) => Promise<Approval>;
834
864
  /** GET /env/authorizations/{id} — current status and, once approved, the assurance evidence. */
835
- get: (id: string) => Promise<FinancialAuthorization>;
865
+ get: (id: string) => Promise<Approval>;
836
866
  /**
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`.
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).
840
870
  */
841
- consume: (id: string, transaction: FinancialTransaction) => Promise<ConsumedFinancialAuthorization>;
842
- };
843
- audit: {
844
- /** GET /env/audit — paginated list of the environment's audit events. */
845
- list: (params?: PaginationOptions) => Promise<Paged<AuditEvent>>;
846
- /** GET /env/audit/login-activity — paginated login activity in the environment. */
847
- loginActivity: (params?: PaginationOptions) => Promise<Paged<LoginActivity>>;
871
+ consume: (id: string, payload?: ApprovalPayload) => Promise<ConsumedApproval>;
848
872
  };
849
873
  };
850
874
  readonly permissions: {
@@ -921,4 +945,4 @@ declare class TenantScopedClient {
921
945
  /** Convenience factory: `const authyon = createClient({ clientId, clientSecret })`. */
922
946
  declare function createClient(options?: AuthyonServerClientOptions): AuthyonServerClient;
923
947
 
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 };
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 };
@@ -442,27 +442,16 @@ interface JsonRequestOptions {
442
442
 
443
443
  type ManagementRequest = <T>(path: string, options?: JsonRequestOptions) => Promise<T>;
444
444
 
445
- /** Lifecycle of a transaction-bound financial authorization. */
446
- type FinancialAuthorizationStatus = "pending" | "approved" | "denied" | "consumed" | "expired";
445
+ /** Lifecycle of an approval. */
446
+ type ApprovalStatus = "pending" | "approved" | "denied" | "consumed" | "expired";
447
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).
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
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
- }
452
+ type ApprovalPayload = Record<string, unknown>;
464
453
  /** Evidence of how the customer proved their identity when approving. */
465
- interface FinancialAssurance {
454
+ interface ApprovalAssurance {
466
455
  /** `urn:authyon:loa:3` (passkey) or `urn:authyon:loa:2` (authenticator code). */
467
456
  acr: string;
468
457
  /** Authentication methods, e.g. `["pwd", "otp"]` or `["pwd", "webauthn"]`. */
@@ -470,28 +459,25 @@ interface FinancialAssurance {
470
459
  /** When the second factor was verified (ISO 8601). */
471
460
  authTime: string;
472
461
  }
473
- interface FinancialAuthorization {
462
+ /** A request for the customer to approve something with a second factor. */
463
+ interface Approval {
474
464
  id: string;
475
- status: FinancialAuthorizationStatus;
465
+ status: ApprovalStatus;
476
466
  subjectId: string;
477
467
  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;
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;
484
472
  createdAt: string;
485
473
  expiresAt: string;
486
474
  decidedAt?: string | null;
487
475
  consumedAt?: string | null;
488
- /** Full canonical transaction — returned only to the customer (subject) view. */
489
- transaction?: FinancialTransaction | null;
490
476
  /** Present once approved. */
491
- assurance?: FinancialAssurance | null;
477
+ assurance?: ApprovalAssurance | null;
492
478
  }
493
- /** Inline second factor sent with `confirm()`. */
494
- type ConfirmFinancialAuthorizationInput = {
479
+ /** Second factor sent with `confirm()`. */
480
+ type ConfirmApprovalInput = {
495
481
  method: "authenticator";
496
482
  /** Six-digit code from the customer's authenticator app. */
497
483
  code: string;
@@ -504,33 +490,36 @@ type ConfirmFinancialAuthorizationInput = {
504
490
  assertionJson: string;
505
491
  };
506
492
  };
507
- /** Passkey assertion options for approving one authorization. */
508
- interface FinancialWebAuthnOptions {
493
+ /** Passkey assertion options for approving one approval. */
494
+ interface ApprovalWebAuthnOptions {
509
495
  ceremonyToken: string;
510
496
  /** JSON `PublicKeyCredentialRequestOptions` to pass to `navigator.credentials.get()`. */
511
497
  optionsJson: string;
512
498
  }
513
499
 
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>;
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>;
522
506
  /**
523
- * POST /auth/authorizations/{id}/confirm — approves the transaction.
507
+ * POST /auth/authorizations/{id}/confirm — approves it.
524
508
  *
525
509
  * Pass the authenticator code or passkey assertion to verify the second
526
510
  * factor inline (recommended). Without `input`, the session itself must
527
511
  * have used a passkey or authenticator code within the last 5 minutes,
528
512
  * otherwise the API answers `step_up_required`.
529
513
  */
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
- };
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;
522
+ }
534
523
 
535
524
  /** End-user operations require a user token and the environment publishable key. */
536
525
  declare class UserScopedClient {
@@ -538,11 +527,10 @@ declare class UserScopedClient {
538
527
  /** @hidden */
539
528
  constructor(request: ManagementRequest, token: AccessTokenSource);
540
529
  /**
541
- * Customer-side approval of a financial authorization, for backends (BFF)
542
- * that hold the customer's access token: `get`, `webauthnOptions`,
543
- * `confirm`, `reject`.
530
+ * The customer's side of `security.approvals`, for backends (BFF) that hold
531
+ * the customer's access token: `get`, `webauthnOptions`, `confirm`, `reject`.
544
532
  */
545
- readonly financialAuthorizations: ReturnType<typeof subjectFinancialAuthorizations>;
533
+ readonly security: SubjectSecurity;
546
534
  readonly tenants: {
547
535
  members: {
548
536
  list: (tenantId: string, options?: PaginationOptions) => Promise<TenantMemberPage>;
@@ -553,29 +541,54 @@ declare class UserScopedClient {
553
541
  };
554
542
  }
555
543
 
556
- /** POST /env/authorizations — a transaction awaiting the customer's approval. */
557
- interface CreateFinancialAuthorizationInput extends FinancialTransaction {
544
+ /** `security.approvals.create()` — something awaiting the customer's approval. */
545
+ interface CreateApprovalInput {
558
546
  /** Environment user who must approve. */
559
547
  subjectId: string;
548
+ /** Any JSON object (up to 16 KiB) describing what is being approved. Default `{}`. */
549
+ payload?: ApprovalPayload;
560
550
  /** Restrict approval to a session in this tenant. */
561
551
  tenantId?: string;
562
552
  /** Lifetime in seconds, clamped to 60–600. Default 300. */
563
553
  expiresInSeconds?: number;
564
554
  /**
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`.
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`.
568
558
  */
569
- idempotencyKey: string;
559
+ idempotencyKey?: string;
570
560
  }
571
- /** POST /env/authorizations/{id}/consume — single-use redemption result. */
572
- interface ConsumedFinancialAuthorization {
561
+ /** `security.approvals.consume()` — single-use redemption result. */
562
+ interface ConsumedApproval {
573
563
  id: string;
574
564
  status: "consumed";
575
565
  consumedAt: string;
576
- transactionHash: string;
577
- assurance: FinancialAssurance | null;
578
- }
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
+ };
579
592
 
580
593
  interface ClientRequestContext {
581
594
  /** Real end-user IP, resolved only from infrastructure trusted by the application. */
@@ -819,32 +832,43 @@ declare class AuthyonServerClient {
819
832
  /** GET /permissions/reserved — reserved permission names you can't redefine. */
820
833
  reserved: () => Promise<ReservedPermissions>;
821
834
  };
835
+ audit: {
836
+ /** GET /env/audit — paginated list of the environment's audit events. */
837
+ list: (params?: PaginationOptions) => Promise<Paged<AuditEvent>>;
838
+ /** GET /env/audit/login-activity — paginated login activity in the environment. */
839
+ loginActivity: (params?: PaginationOptions) => Promise<Paged<LoginActivity>>;
840
+ };
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
+ };
822
853
  /**
823
- * Transaction-bound step-up for financial operations. The environment
824
- * credential needs the `authyon:financial:authorize` scope.
854
+ * The customer approves a payload with their authenticator code or
855
+ * passkey, once.
825
856
  *
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.
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.
830
860
  */
831
- financialAuthorizations: {
832
- /** POST /env/authorizations — registers a transaction awaiting the customer's approval. */
833
- create: (input: CreateFinancialAuthorizationInput) => Promise<FinancialAuthorization>;
861
+ approvals: {
862
+ /** POST /env/authorizations — registers a payload awaiting the customer's approval. */
863
+ create: (input: CreateApprovalInput) => Promise<Approval>;
834
864
  /** GET /env/authorizations/{id} — current status and, once approved, the assurance evidence. */
835
- get: (id: string) => Promise<FinancialAuthorization>;
865
+ get: (id: string) => Promise<Approval>;
836
866
  /**
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`.
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).
840
870
  */
841
- consume: (id: string, transaction: FinancialTransaction) => Promise<ConsumedFinancialAuthorization>;
842
- };
843
- audit: {
844
- /** GET /env/audit — paginated list of the environment's audit events. */
845
- list: (params?: PaginationOptions) => Promise<Paged<AuditEvent>>;
846
- /** GET /env/audit/login-activity — paginated login activity in the environment. */
847
- loginActivity: (params?: PaginationOptions) => Promise<Paged<LoginActivity>>;
871
+ consume: (id: string, payload?: ApprovalPayload) => Promise<ConsumedApproval>;
848
872
  };
849
873
  };
850
874
  readonly permissions: {
@@ -921,4 +945,4 @@ declare class TenantScopedClient {
921
945
  /** Convenience factory: `const authyon = createClient({ clientId, clientSecret })`. */
922
946
  declare function createClient(options?: AuthyonServerClientOptions): AuthyonServerClient;
923
947
 
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 };
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
@@ -56,10 +56,17 @@ var ErrorCodes = {
56
56
  InvalidSecondFactorCode: "invalid_code",
57
57
  VerificationAttemptsExhausted: "verification_attempts_exhausted",
58
58
  MethodNotEnrolled: "method_not_enrolled",
59
- InvalidAuthorizationState: "invalid_authorization_state",
60
- TransactionMismatch: "transaction_mismatch",
61
- AuthorizationNotConsumable: "authorization_not_consumable",
62
- IdempotencyConflict: "idempotency_conflict"
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"
63
70
  };
64
71
  var STANDARD_ERROR_FIELDS = /* @__PURE__ */ new Set([
65
72
  "type",
package/dist/bff.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { H as HttpAdapter, a as HttpLoggerOptions, A as AuthyonServerClient } from './authyonServerClient-DmNnjw4z.cjs';
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-DmNnjw4z.js';
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
@@ -3,7 +3,7 @@ import {
3
3
  DEFAULT_BASE_URL,
4
4
  JsonHttpClient,
5
5
  createSharedTransport
6
- } from "./chunk-TWUVXZOT.js";
6
+ } from "./chunk-WPPEV5BA.js";
7
7
  import "./chunk-77J4NURK.js";
8
8
 
9
9
  // src/bff/contracts.ts
@@ -15,10 +15,17 @@ var ErrorCodes = {
15
15
  InvalidSecondFactorCode: "invalid_code",
16
16
  VerificationAttemptsExhausted: "verification_attempts_exhausted",
17
17
  MethodNotEnrolled: "method_not_enrolled",
18
- InvalidAuthorizationState: "invalid_authorization_state",
19
- TransactionMismatch: "transaction_mismatch",
20
- AuthorizationNotConsumable: "authorization_not_consumable",
21
- IdempotencyConflict: "idempotency_conflict"
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"
22
29
  };
23
30
  var STANDARD_ERROR_FIELDS = /* @__PURE__ */ new Set([
24
31
  "type",
package/dist/index.cjs CHANGED
@@ -168,29 +168,20 @@ async function allCredentials(request, path2) {
168
168
  throw new Error("Authyon: use listPage for more than 1000 credential pages.");
169
169
  }
170
170
 
171
- // ../../internal/core/financial/subjectFinancialAuthorizations.ts
171
+ // ../../internal/core/security/approvals.ts
172
172
  function path(id, suffix = "") {
173
173
  if (typeof id !== "string" || !id.trim())
174
- throw new TypeError("Authyon: a financial authorization id is required.");
174
+ throw new TypeError("Authyon: an approval id is required.");
175
175
  return `/auth/authorizations/${encodeURIComponent(id)}${suffix}`;
176
176
  }
177
- function subjectFinancialAuthorizations(request) {
177
+ function subjectSecurity(request) {
178
178
  return {
179
- /** GET /auth/authorizations/{id} — the pending transaction, to show before asking for the code. */
180
- get: (id) => request(path(id)),
181
- /** POST /auth/authorizations/{id}/webauthn/options — passkey options for approving this authorization. */
182
- webauthnOptions: (id) => request(path(id, "/webauthn/options"), { method: "POST" }),
183
- /**
184
- * POST /auth/authorizations/{id}/confirm — approves the transaction.
185
- *
186
- * Pass the authenticator code or passkey assertion to verify the second
187
- * factor inline (recommended). Without `input`, the session itself must
188
- * have used a passkey or authenticator code within the last 5 minutes,
189
- * otherwise the API answers `step_up_required`.
190
- */
191
- confirm: (id, input) => request(path(id, "/confirm"), { method: "POST", body: input }),
192
- /** POST /auth/authorizations/{id}/reject — the customer declines the transaction. */
193
- reject: (id) => request(path(id, "/reject"), { method: "POST" })
179
+ approvals: {
180
+ get: (id) => request(path(id)),
181
+ webauthnOptions: (id) => request(path(id, "/webauthn/options"), { method: "POST" }),
182
+ confirm: (id, input) => request(path(id, "/confirm"), { method: "POST", body: input }),
183
+ reject: (id) => request(path(id, "/reject"), { method: "POST" })
184
+ }
194
185
  };
195
186
  }
196
187
 
@@ -225,7 +216,7 @@ var UserScopedClient = class {
225
216
  }
226
217
  };
227
218
  __privateSet(this, _request, scopedRequest(request, token));
228
- this.financialAuthorizations = subjectFinancialAuthorizations(__privateGet(this, _request));
219
+ this.security = subjectSecurity(__privateGet(this, _request));
229
220
  }
230
221
  };
231
222
  _request = new WeakMap();
@@ -280,10 +271,17 @@ var ErrorCodes = {
280
271
  InvalidSecondFactorCode: "invalid_code",
281
272
  VerificationAttemptsExhausted: "verification_attempts_exhausted",
282
273
  MethodNotEnrolled: "method_not_enrolled",
283
- InvalidAuthorizationState: "invalid_authorization_state",
284
- TransactionMismatch: "transaction_mismatch",
285
- AuthorizationNotConsumable: "authorization_not_consumable",
286
- IdempotencyConflict: "idempotency_conflict"
274
+ InvalidApprovalState: "invalid_authorization_state",
275
+ PayloadMismatch: "payload_mismatch",
276
+ ApprovalNotConsumable: "authorization_not_consumable",
277
+ IdempotencyConflict: "idempotency_conflict",
278
+ UserDisabled: "user_disabled",
279
+ UserNotFound: "user_not_found",
280
+ TemporarilyUnavailable: "temporarily_unavailable",
281
+ InsufficientScope: "insufficient_scope",
282
+ ApprovalNotFound: "authorization_not_found",
283
+ SessionRevoked: "session_revoked",
284
+ TwoFactorTooManyFailures: "user.2fa.too_many_failures"
287
285
  };
288
286
  var STANDARD_ERROR_FIELDS = /* @__PURE__ */ new Set([
289
287
  "type",
@@ -1070,46 +1068,63 @@ var AuthyonServerClient = class {
1070
1068
  /** GET /permissions/reserved — reserved permission names you can't redefine. */
1071
1069
  reserved: () => this.request("/permissions/reserved", { envBearer: true })
1072
1070
  },
1071
+ audit: {
1072
+ /** GET /env/audit — paginated list of the environment's audit events. */
1073
+ list: (params = {}) => this.request("/env/audit", { envBearer: true, query: params }),
1074
+ /** GET /env/audit/login-activity — paginated login activity in the environment. */
1075
+ loginActivity: (params = {}) => this.request("/env/audit/login-activity", { envBearer: true, query: params })
1076
+ }
1077
+ };
1078
+ // ── Security: one-time codes and approvals ───────────────────────────────
1079
+ //
1080
+ // Everything here runs with the environment credential, which needs the
1081
+ // `authyon:financial:authorize` scope. Keep that credential on the server.
1082
+ this.security = {
1083
+ otp: {
1084
+ /**
1085
+ * POST /env/users/{userId}/otp/verify — checks the user's authenticator
1086
+ * app (TOTP) code. A wrong code returns `{ valid: false }` instead of
1087
+ * throwing. Each code is accepted once; 3 wrong codes in a row sign the
1088
+ * user out everywhere (`sessionsRevoked: true`); 5 lock the check for 15
1089
+ * minutes (`rate_limited`).
1090
+ */
1091
+ check: (userId, code) => this.request(`/env/users/${segment(userId)}/otp/verify`, {
1092
+ method: "POST",
1093
+ envBearer: true,
1094
+ body: { code }
1095
+ })
1096
+ },
1073
1097
  /**
1074
- * Transaction-bound step-up for financial operations. The environment
1075
- * credential needs the `authyon:financial:authorize` scope.
1098
+ * The customer approves a payload with their authenticator code or
1099
+ * passkey, once.
1076
1100
  *
1077
- * 1. `create()` the authorization for the transaction and the customer.
1078
- * 2. The customer approves it with their authenticator code or passkey
1079
- * (`@authyon/auth` → `financialAuthorizations.confirm`).
1080
- * 3. `consume()` it with the same transaction right before executing it.
1101
+ * 1. `create()` the approval with the payload and the customer.
1102
+ * 2. The customer confirms it (`@authyon/auth` → `security.approvals.confirm`).
1103
+ * 3. `consume()` it right before executing, and execute the returned payload.
1081
1104
  */
1082
- financialAuthorizations: {
1083
- /** POST /env/authorizations — registers a transaction awaiting the customer's approval. */
1105
+ approvals: {
1106
+ /** POST /env/authorizations — registers a payload awaiting the customer's approval. */
1084
1107
  create: (input) => {
1085
1108
  const { idempotencyKey, ...body } = input;
1086
- if (typeof idempotencyKey !== "string" || !idempotencyKey.trim())
1087
- throw new TypeError("Authyon: `idempotencyKey` is required.");
1088
1109
  return this.request("/env/authorizations", {
1089
1110
  method: "POST",
1090
1111
  envBearer: true,
1091
- headers: { "Idempotency-Key": idempotencyKey },
1112
+ headers: idempotencyKey ? { "Idempotency-Key": idempotencyKey } : void 0,
1092
1113
  body
1093
1114
  });
1094
1115
  },
1095
1116
  /** GET /env/authorizations/{id} — current status and, once approved, the assurance evidence. */
1096
1117
  get: (id) => this.request(`/env/authorizations/${segment(id)}`, { envBearer: true }),
1097
1118
  /**
1098
- * POST /env/authorizations/{id}/consume — redeems an approved
1099
- * authorization exactly once. Resend the same transaction given to
1100
- * `create()`; any difference fails with `transaction_mismatch`.
1119
+ * POST /env/authorizations/{id}/consume — redeems an approved approval
1120
+ * exactly once and returns the approved payload. Pass `payload` to have
1121
+ * the API check it matches (`payload_mismatch` otherwise).
1101
1122
  */
1102
- consume: (id, transaction) => this.request(`/env/authorizations/${segment(id)}/consume`, {
1123
+ consume: (id, payload) => this.request(`/env/authorizations/${segment(id)}/consume`, {
1103
1124
  method: "POST",
1104
1125
  envBearer: true,
1105
- body: transaction
1126
+ body: payload === void 0 ? void 0 : { payload }
1106
1127
  })
1107
- },
1108
- audit: {
1109
- /** GET /env/audit — paginated list of the environment's audit events. */
1110
- list: (params = {}) => this.request("/env/audit", { envBearer: true, query: params }),
1111
- /** GET /env/audit/login-activity — paginated login activity in the environment. */
1112
- loginActivity: (params = {}) => this.request("/env/audit/login-activity", { envBearer: true, query: params })
1113
1128
  }
1114
1129
  };
1115
1130
  // ── Generic permission grants ─────────────────────────────────────────────
package/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
- import { H as HttpAdapter, a as HttpLoggerOptions, A as AuthyonServerClient } from './authyonServerClient-DmNnjw4z.cjs';
2
- export { b as AccessTokenSource, c as AuditEvent, d as AuthyonJwksDiscoveryOptions, e as AuthyonJwtClaims, f as AuthyonServerClientOptions, C as ClientCredentials, g as ClientRequestContext, h as ConfirmFinancialAuthorizationInput, i as ConsumedFinancialAuthorization, j as CreateCredentialInput, k as CreateFinancialAuthorizationInput, l as CreateOrganizationInput, m as CreatePermissionInput, n as CreateTenantCredentialInput, o as CreateUserInput, p as CredentialCreator, q as CredentialDetail, r as CredentialListOptions, s as CredentialPermissionsInput, E as EnvironmentUser, F as FetchHttpAdapter, t as FinancialAssurance, u as FinancialAuthorization, v as FinancialAuthorizationStatus, w as FinancialTransaction, x as FinancialWebAuthnOptions, y as HttpAdapterRequest, z as HttpLogEvent, B as HttpLogger, I as IntrospectResult, D as InviteTenantMemberInput, J as JsonWebKeySet, G as JwksTokenVerifier, K as JwksTokenVerifierOptions, L as LoggingHttpAdapter, M as LoginActivity, O as OpenIdConfiguration, N as Organization, P as Paged, Q as PaginationOptions, R as Permission, S as PermissionsByRole, T as ReservedPermissions, U as Role, V as RoleGrant, W as RoleInput, X as RoleList, Y as RolePermissions, Z as SafeJwtAlgorithm, _ as TenantClientValidationResult, $ as TenantCredentialIssued, a0 as TenantCredentialSummary, a1 as TenantMember, a2 as TenantMemberPage, a3 as TenantMembership, a4 as TenantScopedClient, a5 as TokenResult, a6 as TokenVerificationError, a7 as TokenVerificationErrorCode, a8 as UpdateOrganizationInput, a9 as User, aa as UserScopedClient, ab as ValidateResult, ac as VerifiedAccessToken, ad as createClient, ae as normalizeClientIp } from './authyonServerClient-DmNnjw4z.cjs';
3
- export { b as AbilityConditions, c as AbilityEvent, d as AbilityListener, e as AbilityRequirement, f as AbilityRule, A as AbilitySubject, g as AuthorizationContext, a as AuthorizationError, h as AuthorizationOptions, i as AuthyonAbility, j as AuthyonAbilityBuilder, k as AuthyonAbilityOptions, l as AuthyonPermissionSource, E as ExpressAuthorizationMiddlewareOptions, m as ExpressNext, n as ExpressRequestLike, o as ExpressResponseLike, P as PermissionGroup, R as RequestAuthorizationOptions, p as authorizeRequest, q as authorizeToken, r as createAuthorizationErrorResponse, s as createAuthyonAbility, t as createAuthyonRules, u as createExpressAuthorizationMiddleware, v as hasPermission, w as hasPermissionGroup } from './authorization-B7ynKAud.cjs';
1
+ import { H as HttpAdapter, a as HttpLoggerOptions, A as AuthyonServerClient } from './authyonServerClient-DQzhfaja.cjs';
2
+ export { b as AccessTokenSource, c as Approval, d as ApprovalAssurance, e as ApprovalPayload, f as ApprovalStatus, g as ApprovalWebAuthnOptions, h as AuditEvent, i as AuthyonJwksDiscoveryOptions, j as AuthyonJwtClaims, k as AuthyonServerClientOptions, C as ClientCredentials, l as ClientRequestContext, m as ConfirmApprovalInput, n as ConsumedApproval, o as CreateApprovalInput, p as CreateCredentialInput, q as CreateOrganizationInput, r as CreatePermissionInput, s as CreateTenantCredentialInput, t as CreateUserInput, u as CredentialCreator, v as CredentialDetail, w as CredentialListOptions, x as CredentialPermissionsInput, E as EnvironmentUser, F as FetchHttpAdapter, y as HttpAdapterRequest, z as HttpLogEvent, B as HttpLogger, I as IntrospectResult, D as InviteTenantMemberInput, J as JsonWebKeySet, G as JwksTokenVerifier, K as JwksTokenVerifierOptions, L as LoggingHttpAdapter, M as LoginActivity, O as OpenIdConfiguration, N as Organization, P as OtpCheckResult, Q as Paged, R as PaginationOptions, S as Permission, T as PermissionsByRole, U as ReservedPermissions, V as Role, W as RoleGrant, X as RoleInput, Y as RoleList, Z as RolePermissions, _ as SafeJwtAlgorithm, $ as SubjectApprovals, a0 as SubjectSecurity, a1 as TenantClientValidationResult, a2 as TenantCredentialIssued, a3 as TenantCredentialSummary, a4 as TenantMember, a5 as TenantMemberPage, a6 as TenantMembership, a7 as TenantScopedClient, a8 as TokenResult, a9 as TokenVerificationError, aa as TokenVerificationErrorCode, ab as UpdateOrganizationInput, ac as User, ad as UserScopedClient, ae as ValidateResult, af as VerifiedAccessToken, ag as createClient, ah as normalizeClientIp } from './authyonServerClient-DQzhfaja.cjs';
3
+ export { b as AbilityConditions, c as AbilityEvent, d as AbilityListener, e as AbilityRequirement, f as AbilityRule, A as AbilitySubject, g as AuthorizationContext, a as AuthorizationError, h as AuthorizationOptions, i as AuthyonAbility, j as AuthyonAbilityBuilder, k as AuthyonAbilityOptions, l as AuthyonPermissionSource, E as ExpressAuthorizationMiddlewareOptions, m as ExpressNext, n as ExpressRequestLike, o as ExpressResponseLike, P as PermissionGroup, R as RequestAuthorizationOptions, p as authorizeRequest, q as authorizeToken, r as createAuthorizationErrorResponse, s as createAuthyonAbility, t as createAuthyonRules, u as createExpressAuthorizationMiddleware, v as hasPermission, w as hasPermissionGroup } from './authorization-B82XXf3B.cjs';
4
4
  import 'jose';
5
5
 
6
6
  declare const ErrorCodes: {
@@ -19,10 +19,17 @@ declare const ErrorCodes: {
19
19
  readonly InvalidSecondFactorCode: "invalid_code";
20
20
  readonly VerificationAttemptsExhausted: "verification_attempts_exhausted";
21
21
  readonly MethodNotEnrolled: "method_not_enrolled";
22
- readonly InvalidAuthorizationState: "invalid_authorization_state";
23
- readonly TransactionMismatch: "transaction_mismatch";
24
- readonly AuthorizationNotConsumable: "authorization_not_consumable";
22
+ readonly InvalidApprovalState: "invalid_authorization_state";
23
+ readonly PayloadMismatch: "payload_mismatch";
24
+ readonly ApprovalNotConsumable: "authorization_not_consumable";
25
25
  readonly IdempotencyConflict: "idempotency_conflict";
26
+ readonly UserDisabled: "user_disabled";
27
+ readonly UserNotFound: "user_not_found";
28
+ readonly TemporarilyUnavailable: "temporarily_unavailable";
29
+ readonly InsufficientScope: "insufficient_scope";
30
+ readonly ApprovalNotFound: "authorization_not_found";
31
+ readonly SessionRevoked: "session_revoked";
32
+ readonly TwoFactorTooManyFailures: "user.2fa.too_many_failures";
26
33
  };
27
34
  type KnownErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];
28
35
  type AuthyonErrorCategory = "network" | "timeout" | "authentication" | "authorization" | "validation" | "not_found" | "conflict" | "rate_limit" | "server" | "unknown";
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { H as HttpAdapter, a as HttpLoggerOptions, A as AuthyonServerClient } from './authyonServerClient-DmNnjw4z.js';
2
- export { b as AccessTokenSource, c as AuditEvent, d as AuthyonJwksDiscoveryOptions, e as AuthyonJwtClaims, f as AuthyonServerClientOptions, C as ClientCredentials, g as ClientRequestContext, h as ConfirmFinancialAuthorizationInput, i as ConsumedFinancialAuthorization, j as CreateCredentialInput, k as CreateFinancialAuthorizationInput, l as CreateOrganizationInput, m as CreatePermissionInput, n as CreateTenantCredentialInput, o as CreateUserInput, p as CredentialCreator, q as CredentialDetail, r as CredentialListOptions, s as CredentialPermissionsInput, E as EnvironmentUser, F as FetchHttpAdapter, t as FinancialAssurance, u as FinancialAuthorization, v as FinancialAuthorizationStatus, w as FinancialTransaction, x as FinancialWebAuthnOptions, y as HttpAdapterRequest, z as HttpLogEvent, B as HttpLogger, I as IntrospectResult, D as InviteTenantMemberInput, J as JsonWebKeySet, G as JwksTokenVerifier, K as JwksTokenVerifierOptions, L as LoggingHttpAdapter, M as LoginActivity, O as OpenIdConfiguration, N as Organization, P as Paged, Q as PaginationOptions, R as Permission, S as PermissionsByRole, T as ReservedPermissions, U as Role, V as RoleGrant, W as RoleInput, X as RoleList, Y as RolePermissions, Z as SafeJwtAlgorithm, _ as TenantClientValidationResult, $ as TenantCredentialIssued, a0 as TenantCredentialSummary, a1 as TenantMember, a2 as TenantMemberPage, a3 as TenantMembership, a4 as TenantScopedClient, a5 as TokenResult, a6 as TokenVerificationError, a7 as TokenVerificationErrorCode, a8 as UpdateOrganizationInput, a9 as User, aa as UserScopedClient, ab as ValidateResult, ac as VerifiedAccessToken, ad as createClient, ae as normalizeClientIp } from './authyonServerClient-DmNnjw4z.js';
3
- export { b as AbilityConditions, c as AbilityEvent, d as AbilityListener, e as AbilityRequirement, f as AbilityRule, A as AbilitySubject, g as AuthorizationContext, a as AuthorizationError, h as AuthorizationOptions, i as AuthyonAbility, j as AuthyonAbilityBuilder, k as AuthyonAbilityOptions, l as AuthyonPermissionSource, E as ExpressAuthorizationMiddlewareOptions, m as ExpressNext, n as ExpressRequestLike, o as ExpressResponseLike, P as PermissionGroup, R as RequestAuthorizationOptions, p as authorizeRequest, q as authorizeToken, r as createAuthorizationErrorResponse, s as createAuthyonAbility, t as createAuthyonRules, u as createExpressAuthorizationMiddleware, v as hasPermission, w as hasPermissionGroup } from './authorization-BF015NDJ.js';
1
+ import { H as HttpAdapter, a as HttpLoggerOptions, A as AuthyonServerClient } from './authyonServerClient-DQzhfaja.js';
2
+ export { b as AccessTokenSource, c as Approval, d as ApprovalAssurance, e as ApprovalPayload, f as ApprovalStatus, g as ApprovalWebAuthnOptions, h as AuditEvent, i as AuthyonJwksDiscoveryOptions, j as AuthyonJwtClaims, k as AuthyonServerClientOptions, C as ClientCredentials, l as ClientRequestContext, m as ConfirmApprovalInput, n as ConsumedApproval, o as CreateApprovalInput, p as CreateCredentialInput, q as CreateOrganizationInput, r as CreatePermissionInput, s as CreateTenantCredentialInput, t as CreateUserInput, u as CredentialCreator, v as CredentialDetail, w as CredentialListOptions, x as CredentialPermissionsInput, E as EnvironmentUser, F as FetchHttpAdapter, y as HttpAdapterRequest, z as HttpLogEvent, B as HttpLogger, I as IntrospectResult, D as InviteTenantMemberInput, J as JsonWebKeySet, G as JwksTokenVerifier, K as JwksTokenVerifierOptions, L as LoggingHttpAdapter, M as LoginActivity, O as OpenIdConfiguration, N as Organization, P as OtpCheckResult, Q as Paged, R as PaginationOptions, S as Permission, T as PermissionsByRole, U as ReservedPermissions, V as Role, W as RoleGrant, X as RoleInput, Y as RoleList, Z as RolePermissions, _ as SafeJwtAlgorithm, $ as SubjectApprovals, a0 as SubjectSecurity, a1 as TenantClientValidationResult, a2 as TenantCredentialIssued, a3 as TenantCredentialSummary, a4 as TenantMember, a5 as TenantMemberPage, a6 as TenantMembership, a7 as TenantScopedClient, a8 as TokenResult, a9 as TokenVerificationError, aa as TokenVerificationErrorCode, ab as UpdateOrganizationInput, ac as User, ad as UserScopedClient, ae as ValidateResult, af as VerifiedAccessToken, ag as createClient, ah as normalizeClientIp } from './authyonServerClient-DQzhfaja.js';
3
+ export { b as AbilityConditions, c as AbilityEvent, d as AbilityListener, e as AbilityRequirement, f as AbilityRule, A as AbilitySubject, g as AuthorizationContext, a as AuthorizationError, h as AuthorizationOptions, i as AuthyonAbility, j as AuthyonAbilityBuilder, k as AuthyonAbilityOptions, l as AuthyonPermissionSource, E as ExpressAuthorizationMiddlewareOptions, m as ExpressNext, n as ExpressRequestLike, o as ExpressResponseLike, P as PermissionGroup, R as RequestAuthorizationOptions, p as authorizeRequest, q as authorizeToken, r as createAuthorizationErrorResponse, s as createAuthyonAbility, t as createAuthyonRules, u as createExpressAuthorizationMiddleware, v as hasPermission, w as hasPermissionGroup } from './authorization-WlwcTBwG.js';
4
4
  import 'jose';
5
5
 
6
6
  declare const ErrorCodes: {
@@ -19,10 +19,17 @@ declare const ErrorCodes: {
19
19
  readonly InvalidSecondFactorCode: "invalid_code";
20
20
  readonly VerificationAttemptsExhausted: "verification_attempts_exhausted";
21
21
  readonly MethodNotEnrolled: "method_not_enrolled";
22
- readonly InvalidAuthorizationState: "invalid_authorization_state";
23
- readonly TransactionMismatch: "transaction_mismatch";
24
- readonly AuthorizationNotConsumable: "authorization_not_consumable";
22
+ readonly InvalidApprovalState: "invalid_authorization_state";
23
+ readonly PayloadMismatch: "payload_mismatch";
24
+ readonly ApprovalNotConsumable: "authorization_not_consumable";
25
25
  readonly IdempotencyConflict: "idempotency_conflict";
26
+ readonly UserDisabled: "user_disabled";
27
+ readonly UserNotFound: "user_not_found";
28
+ readonly TemporarilyUnavailable: "temporarily_unavailable";
29
+ readonly InsufficientScope: "insufficient_scope";
30
+ readonly ApprovalNotFound: "authorization_not_found";
31
+ readonly SessionRevoked: "session_revoked";
32
+ readonly TwoFactorTooManyFailures: "user.2fa.too_many_failures";
26
33
  };
27
34
  type KnownErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];
28
35
  type AuthyonErrorCategory = "network" | "timeout" | "authentication" | "authorization" | "validation" | "not_found" | "conflict" | "rate_limit" | "server" | "unknown";
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  JsonHttpClient,
8
8
  LoggingHttpAdapter,
9
9
  createSharedTransport
10
- } from "./chunk-TWUVXZOT.js";
10
+ } from "./chunk-WPPEV5BA.js";
11
11
  import {
12
12
  AuthorizationError,
13
13
  AuthyonAbility,
@@ -146,29 +146,20 @@ async function allCredentials(request, path2) {
146
146
  throw new Error("Authyon: use listPage for more than 1000 credential pages.");
147
147
  }
148
148
 
149
- // ../../internal/core/financial/subjectFinancialAuthorizations.ts
149
+ // ../../internal/core/security/approvals.ts
150
150
  function path(id, suffix = "") {
151
151
  if (typeof id !== "string" || !id.trim())
152
- throw new TypeError("Authyon: a financial authorization id is required.");
152
+ throw new TypeError("Authyon: an approval id is required.");
153
153
  return `/auth/authorizations/${encodeURIComponent(id)}${suffix}`;
154
154
  }
155
- function subjectFinancialAuthorizations(request) {
155
+ function subjectSecurity(request) {
156
156
  return {
157
- /** GET /auth/authorizations/{id} — the pending transaction, to show before asking for the code. */
158
- get: (id) => request(path(id)),
159
- /** POST /auth/authorizations/{id}/webauthn/options — passkey options for approving this authorization. */
160
- webauthnOptions: (id) => request(path(id, "/webauthn/options"), { method: "POST" }),
161
- /**
162
- * POST /auth/authorizations/{id}/confirm — approves the transaction.
163
- *
164
- * Pass the authenticator code or passkey assertion to verify the second
165
- * factor inline (recommended). Without `input`, the session itself must
166
- * have used a passkey or authenticator code within the last 5 minutes,
167
- * otherwise the API answers `step_up_required`.
168
- */
169
- confirm: (id, input) => request(path(id, "/confirm"), { method: "POST", body: input }),
170
- /** POST /auth/authorizations/{id}/reject — the customer declines the transaction. */
171
- reject: (id) => request(path(id, "/reject"), { method: "POST" })
157
+ approvals: {
158
+ get: (id) => request(path(id)),
159
+ webauthnOptions: (id) => request(path(id, "/webauthn/options"), { method: "POST" }),
160
+ confirm: (id, input) => request(path(id, "/confirm"), { method: "POST", body: input }),
161
+ reject: (id) => request(path(id, "/reject"), { method: "POST" })
162
+ }
172
163
  };
173
164
  }
174
165
 
@@ -203,7 +194,7 @@ var UserScopedClient = class {
203
194
  }
204
195
  };
205
196
  __privateSet(this, _request, scopedRequest(request, token));
206
- this.financialAuthorizations = subjectFinancialAuthorizations(__privateGet(this, _request));
197
+ this.security = subjectSecurity(__privateGet(this, _request));
207
198
  }
208
199
  };
209
200
  _request = new WeakMap();
@@ -555,46 +546,63 @@ var AuthyonServerClient = class {
555
546
  /** GET /permissions/reserved — reserved permission names you can't redefine. */
556
547
  reserved: () => this.request("/permissions/reserved", { envBearer: true })
557
548
  },
549
+ audit: {
550
+ /** GET /env/audit — paginated list of the environment's audit events. */
551
+ list: (params = {}) => this.request("/env/audit", { envBearer: true, query: params }),
552
+ /** GET /env/audit/login-activity — paginated login activity in the environment. */
553
+ loginActivity: (params = {}) => this.request("/env/audit/login-activity", { envBearer: true, query: params })
554
+ }
555
+ };
556
+ // ── Security: one-time codes and approvals ───────────────────────────────
557
+ //
558
+ // Everything here runs with the environment credential, which needs the
559
+ // `authyon:financial:authorize` scope. Keep that credential on the server.
560
+ this.security = {
561
+ otp: {
562
+ /**
563
+ * POST /env/users/{userId}/otp/verify — checks the user's authenticator
564
+ * app (TOTP) code. A wrong code returns `{ valid: false }` instead of
565
+ * throwing. Each code is accepted once; 3 wrong codes in a row sign the
566
+ * user out everywhere (`sessionsRevoked: true`); 5 lock the check for 15
567
+ * minutes (`rate_limited`).
568
+ */
569
+ check: (userId, code) => this.request(`/env/users/${segment(userId)}/otp/verify`, {
570
+ method: "POST",
571
+ envBearer: true,
572
+ body: { code }
573
+ })
574
+ },
558
575
  /**
559
- * Transaction-bound step-up for financial operations. The environment
560
- * credential needs the `authyon:financial:authorize` scope.
576
+ * The customer approves a payload with their authenticator code or
577
+ * passkey, once.
561
578
  *
562
- * 1. `create()` the authorization for the transaction and the customer.
563
- * 2. The customer approves it with their authenticator code or passkey
564
- * (`@authyon/auth` → `financialAuthorizations.confirm`).
565
- * 3. `consume()` it with the same transaction right before executing it.
579
+ * 1. `create()` the approval with the payload and the customer.
580
+ * 2. The customer confirms it (`@authyon/auth` → `security.approvals.confirm`).
581
+ * 3. `consume()` it right before executing, and execute the returned payload.
566
582
  */
567
- financialAuthorizations: {
568
- /** POST /env/authorizations — registers a transaction awaiting the customer's approval. */
583
+ approvals: {
584
+ /** POST /env/authorizations — registers a payload awaiting the customer's approval. */
569
585
  create: (input) => {
570
586
  const { idempotencyKey, ...body } = input;
571
- if (typeof idempotencyKey !== "string" || !idempotencyKey.trim())
572
- throw new TypeError("Authyon: `idempotencyKey` is required.");
573
587
  return this.request("/env/authorizations", {
574
588
  method: "POST",
575
589
  envBearer: true,
576
- headers: { "Idempotency-Key": idempotencyKey },
590
+ headers: idempotencyKey ? { "Idempotency-Key": idempotencyKey } : void 0,
577
591
  body
578
592
  });
579
593
  },
580
594
  /** GET /env/authorizations/{id} — current status and, once approved, the assurance evidence. */
581
595
  get: (id) => this.request(`/env/authorizations/${segment(id)}`, { envBearer: true }),
582
596
  /**
583
- * POST /env/authorizations/{id}/consume — redeems an approved
584
- * authorization exactly once. Resend the same transaction given to
585
- * `create()`; any difference fails with `transaction_mismatch`.
597
+ * POST /env/authorizations/{id}/consume — redeems an approved approval
598
+ * exactly once and returns the approved payload. Pass `payload` to have
599
+ * the API check it matches (`payload_mismatch` otherwise).
586
600
  */
587
- consume: (id, transaction) => this.request(`/env/authorizations/${segment(id)}/consume`, {
601
+ consume: (id, payload) => this.request(`/env/authorizations/${segment(id)}/consume`, {
588
602
  method: "POST",
589
603
  envBearer: true,
590
- body: transaction
604
+ body: payload === void 0 ? void 0 : { payload }
591
605
  })
592
- },
593
- audit: {
594
- /** GET /env/audit — paginated list of the environment's audit events. */
595
- list: (params = {}) => this.request("/env/audit", { envBearer: true, query: params }),
596
- /** GET /env/audit/login-activity — paginated login activity in the environment. */
597
- loginActivity: (params = {}) => this.request("/env/audit/login-activity", { envBearer: true, query: params })
598
606
  }
599
607
  };
600
608
  // ── Generic permission grants ─────────────────────────────────────────────
package/dist/next.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { ReactNode } from 'react';
2
- import { R as RequestAuthorizationOptions, A as AbilitySubject, a as AuthorizationError } from './authorization-B7ynKAud.cjs';
3
- import { A as AuthyonServerClient } from './authyonServerClient-DmNnjw4z.cjs';
2
+ import { R as RequestAuthorizationOptions, A as AbilitySubject, a as AuthorizationError } from './authorization-B82XXf3B.cjs';
3
+ import { A as AuthyonServerClient } from './authyonServerClient-DQzhfaja.cjs';
4
4
  import 'jose';
5
5
 
6
6
  interface ServerPermissionGuardFallbackContext {
package/dist/next.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { ReactNode } from 'react';
2
- import { R as RequestAuthorizationOptions, A as AbilitySubject, a as AuthorizationError } from './authorization-BF015NDJ.js';
3
- import { A as AuthyonServerClient } from './authyonServerClient-DmNnjw4z.js';
2
+ import { R as RequestAuthorizationOptions, A as AbilitySubject, a as AuthorizationError } from './authorization-WlwcTBwG.js';
3
+ import { A as AuthyonServerClient } from './authyonServerClient-DQzhfaja.js';
4
4
  import 'jose';
5
5
 
6
6
  interface ServerPermissionGuardFallbackContext {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@authyon/server",
3
- "version": "0.2.0-beta.14",
3
+ "version": "0.2.0-beta.15",
4
4
  "description": "Authyon SDK for backends — server-to-server organization/member management and access-token verification.",
5
5
  "license": "MIT",
6
6
  "type": "module",