@hyper.authio/client 0.1.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { JWK, CryptoKey } from 'jose';
1
+ import { JWK, CryptoKey, JWTPayload, JWTVerifyGetKey } from 'jose';
2
2
 
3
3
  /**
4
4
  * Claim names Authio writes into its tokens.
@@ -20,6 +20,8 @@ declare const AuthioClaimTypes: {
20
20
  readonly AuthenticationMethods: "amr";
21
21
  readonly IdentityProvider: "idp";
22
22
  readonly Nonce: "nonce";
23
+ readonly AccessTokenHash: "at_hash";
24
+ readonly Events: "events";
23
25
  readonly OrganizationId: "org_id";
24
26
  readonly OrganizationAlias: "org_alias";
25
27
  readonly AccountId: "account_id";
@@ -39,6 +41,12 @@ declare const AuthioClaimTypes: {
39
41
  readonly ConsumerName: "consumer_name";
40
42
  readonly CredentialId: "credential_id";
41
43
  readonly CredentialType: "credential_type";
44
+ readonly CredentialName: "credential_name";
45
+ readonly CredentialRealm: "credential_realm";
46
+ readonly CredentialClient: "credential_client";
47
+ readonly ActorType: "actor_type";
48
+ readonly OwnerUserId: "owner_user_id";
49
+ readonly OwnerUsername: "owner_username";
42
50
  readonly UserResourceAccess: "user_resource_access";
43
51
  readonly RealmResourceAccess: "realm_resource_access";
44
52
  readonly ClientResourceAccess: "client_resource_access";
@@ -116,6 +124,12 @@ declare const AuthioOAuthErrors: {
116
124
  readonly ConnectionPolicyViolation: "connection_policy_violation";
117
125
  readonly ServerError: "server_error";
118
126
  readonly TemporarilyUnavailable: "temporarily_unavailable";
127
+ readonly LoginRequired: "login_required";
128
+ readonly InteractionRequired: "interaction_required";
129
+ readonly ConsentRequired: "consent_required";
130
+ readonly AccountSelectionRequired: "account_selection_required";
131
+ readonly InsufficientScope: "insufficient_scope";
132
+ readonly InsufficientUserAuthentication: "insufficient_user_authentication";
119
133
  };
120
134
  /**
121
135
  * Webhook event types.
@@ -135,6 +149,8 @@ declare const AuthioWebhookEventTypes: {
135
149
  readonly AdminResourceDeleted: "admin_resource_deleted";
136
150
  readonly UserSuspended: "user_suspended";
137
151
  readonly UserSuspensionEnded: "user_suspension_ended";
152
+ readonly AttackDetected: "attack_detected";
153
+ readonly CredentialCompromised: "credential_compromised";
138
154
  readonly Ping: "ping";
139
155
  };
140
156
  /**
@@ -145,6 +161,31 @@ declare const AuthioWebhookHeaders: {
145
161
  readonly Event: "X-Authio-Event";
146
162
  readonly EventId: "X-Authio-Event-Id";
147
163
  };
164
+ /**
165
+ * Who called an API, read from the access token (see `conformance/callers.json`).
166
+ *
167
+ * - `user`: a person signed in (the token carries `auth_time`).
168
+ * - `client`: a client authenticated as itself.
169
+ * - `consumer`: a machine consumer of a client (`credential_type` `client_consumer`).
170
+ * - `account_credential`: a credential of an Authio account (`credential_type` `account_secret`).
171
+ */
172
+ type AuthioCallerKind = "user" | "client" | "consumer" | "account_credential";
173
+ /**
174
+ * How a machine caller proved who it is.
175
+ */
176
+ type AuthioCredentialForm = "client_secret" | "personal_access_token" | "api_key" | "consumer_api_key";
177
+ /**
178
+ * The caller kinds.
179
+ */
180
+ declare const AuthioCallerKinds: readonly ["user", "client", "consumer", "account_credential"];
181
+ /**
182
+ * The values of `prompt` Authio honours.
183
+ */
184
+ declare const AuthioPrompts: readonly ["none", "login", "select_account", "consent"];
185
+ /**
186
+ * A value of `prompt`.
187
+ */
188
+ type AuthioPrompt = (typeof AuthioPrompts)[number];
148
189
  /**
149
190
  * Asymmetric signing algorithms Authio issues tokens with and accepts in client assertions.
150
191
  */
@@ -154,12 +195,23 @@ declare const AuthioAsymmetricAlgorithms: readonly ["RS256", "RS384", "RS512", "
154
195
  */
155
196
  declare const AuthioDefaults: {
156
197
  readonly DiscoveryPath: "/.well-known/openid-configuration";
198
+ readonly ProtectedResourceMetadataPath: "/.well-known/oauth-protected-resource";
157
199
  readonly RedactedValue: "[redacted]";
158
200
  readonly PlatformRealm: "authio";
159
201
  readonly PlatformClientId: "authio";
160
202
  readonly ApiKeyPrefix: "ak_";
161
203
  readonly ClientSecretPrefix: "cs_";
162
204
  readonly PersonalAccessTokenPrefix: "pat_";
205
+ /** The `client_id` an account credential's client secret is exchanged with: `cred_` and the credential id (format N). */
206
+ readonly CredentialClientIdPrefix: "cred_";
207
+ readonly ApiKeyHeader: "x-api-key";
208
+ readonly RequestIdHeader: "X-Request-Id";
209
+ /** The header `typ` of a back-channel logout token. */
210
+ readonly LogoutTokenType: "logout+jwt";
211
+ /** The event a back-channel logout token carries. */
212
+ readonly BackchannelLogoutEvent: "http://schemas.openid.net/event/backchannel-logout";
213
+ /** Seconds. */
214
+ readonly ClockSkew: 30;
163
215
  /** Seconds. */
164
216
  readonly ClientAssertionLifetime: 120;
165
217
  /** Seconds. */
@@ -220,6 +272,65 @@ declare class AuthioDiscoveryError extends AuthioError {
220
272
  */
221
273
  declare class AuthioConfigurationError extends AuthioError {
222
274
  }
275
+ /**
276
+ * Why a token was refused, with the outcome names of `conformance/tokens.json`.
277
+ */
278
+ type AuthioTokenFailure = "not_access_token" | "not_id_token" | "invalid_audience" | "invalid_issuer" | "expired" | "not_yet_valid" | "invalid_signature" | "invalid_algorithm" | "reference_token" | "malformed" | "decryption_failed" | "legacy_algorithm" | "invalid_nonce" | "invalid_at_hash" | "authentication_too_old" | "invalid_logout_token" | "signing_keys_unavailable";
279
+ /**
280
+ * A token (ID token, logout token, signed UserInfo, encrypted token) did not pass validation.
281
+ */
282
+ declare class AuthioTokenValidationError extends AuthioError {
283
+ /** Why, as a stable code. */
284
+ readonly reason: AuthioTokenFailure;
285
+ constructor(reason: AuthioTokenFailure, message: string, options?: {
286
+ cause?: unknown;
287
+ });
288
+ }
289
+ /**
290
+ * Why an authorization callback was refused before any code was exchanged.
291
+ */
292
+ type AuthioCallbackFailure = "state_mismatch" | "issuer_mismatch" | "missing_issuer" | "missing_code";
293
+ /**
294
+ * The authorization callback does not belong to the request this client made: `state` differs, the `iss` parameter
295
+ * (RFC 9207) names another issuer or is missing where Authio sends it, or there is no code.
296
+ */
297
+ declare class AuthioCallbackError extends AuthioError {
298
+ /** Why, as a stable code. */
299
+ readonly reason: AuthioCallbackFailure;
300
+ constructor(reason: AuthioCallbackFailure, message: string);
301
+ }
302
+ /**
303
+ * One message of an Admin API error, optionally tied to a field of the request.
304
+ */
305
+ interface AuthioAdminNotification {
306
+ readonly message: string;
307
+ readonly field?: string;
308
+ readonly code?: string;
309
+ }
310
+ /**
311
+ * The Admin API refused a request. `errorCode` is the envelope's top-level `errorCode`; the HTTP status is read from
312
+ * the response, never from the envelope's numeric `statusCode`.
313
+ */
314
+ declare class AuthioAdminError extends AuthioError {
315
+ /** The HTTP status. */
316
+ readonly status: number;
317
+ /** Authio's error code, such as `ValidationFailed` or `RealmNotFound`. */
318
+ readonly errorCode: string | undefined;
319
+ /** The messages, with the field each one is about. */
320
+ readonly notifications: readonly AuthioAdminNotification[];
321
+ /** The request id, from the envelope or the `X-Request-Id` header. */
322
+ readonly requestId: string | undefined;
323
+ /** Seconds to wait before retrying, from `Retry-After` (`429` and `503`). */
324
+ readonly retryAfterSeconds: number | undefined;
325
+ constructor(details: {
326
+ status: number;
327
+ errorCode?: string;
328
+ notifications?: readonly AuthioAdminNotification[];
329
+ requestId?: string;
330
+ retryAfterSeconds?: number;
331
+ cause?: unknown;
332
+ });
333
+ }
223
334
 
224
335
  /**
225
336
  * Time as the SDK sees it. Replace it in tests to control expiry, caching and device polling.
@@ -235,7 +346,7 @@ interface AuthioClock {
235
346
  */
236
347
  declare const systemClock: AuthioClock;
237
348
  /**
238
- * Where Authio is and how to reach it. Shared by the client, the API verifier and the BFF.
349
+ * Where Authio is and how to reach it. Shared by the client and the API verifier.
239
350
  */
240
351
  interface AuthioConnectionOptions {
241
352
  /**
@@ -387,14 +498,22 @@ type AuthioPrivateKeyInput = string | JWK | CryptoKey;
387
498
  */
388
499
  declare const AuthioClientAssertionAlgorithms: readonly ["RS256", "RS384", "RS512", "PS256", "PS384", "PS512", "ES256", "ES384", "ES512"];
389
500
 
501
+ /**
502
+ * The client secret, or a function returning the current one, called for every request so a rotated secret is used
503
+ * without a restart.
504
+ */
505
+ type AuthioSecretSource = string | (() => string | Promise<string>);
390
506
  /**
391
507
  * How the client proves who it is.
392
508
  */
393
509
  interface AuthioClientCredentialsSettings {
394
510
  /** The client id. */
395
511
  clientId: string;
396
- /** The client secret, for `client_secret_basic` and `client_secret_post`. */
397
- clientSecret?: string;
512
+ /**
513
+ * The client secret, for `client_secret_basic` and `client_secret_post`; or a function returning the current one,
514
+ * called for every request.
515
+ */
516
+ clientSecret?: AuthioSecretSource;
398
517
  /**
399
518
  * Defaults to `private_key_jwt` when only a private key is configured, else `client_secret_basic`. A public client
400
519
  * sets `none`.
@@ -421,18 +540,43 @@ declare function toBasicAuthorization(clientId: string, clientSecret: string): s
421
540
  * Authio hands over when it generates the pair (object or JSON text), or a PEM private key (PKCS#8 or PKCS#1 RSA).
422
541
  */
423
542
  type AuthioEncryptionKey = string | JWK;
543
+ /**
544
+ * Where the encryption key comes from: the key itself, or a function returning it (read again on every new
545
+ * algorithm, so a rotated key is picked up).
546
+ */
547
+ type AuthioEncryptionKeySource = AuthioEncryptionKey | (() => AuthioEncryptionKey | Promise<AuthioEncryptionKey>);
424
548
  /**
425
549
  * Opens a compact JWE and returns its plaintext; a token that is not a JWE comes back unchanged.
550
+ *
551
+ * @throws AuthioTokenValidationError with `legacy_algorithm` for RSA1_5 and `decryption_failed` when the key cannot
552
+ * open it.
426
553
  */
427
554
  type AuthioTokenDecrypter = (token: string) => Promise<string>;
428
555
  /**
429
- * The key management algorithms Authio encrypts with.
556
+ * The key management algorithms Authio encrypts with, and this SDK decrypts.
430
557
  */
431
558
  declare const AuthioKeyManagementAlgorithms: readonly ["RSA-OAEP", "RSA-OAEP-256"];
559
+ /**
560
+ * Key management algorithms Authio may still use for clients registered long ago. Node and WebCrypto cannot decrypt
561
+ * RSA1_5 (PKCS#1 v1.5), so this SDK refuses it even with `allowLegacyEncryptionAlgorithms`.
562
+ */
563
+ declare const AuthioLegacyKeyManagementAlgorithms: readonly ["RSA1_5"];
432
564
  /**
433
565
  * The content encryption algorithms Authio encrypts with.
434
566
  */
435
567
  declare const AuthioContentEncryptionAlgorithms: readonly ["A128CBC-HS256", "A192CBC-HS384", "A256CBC-HS512"];
568
+ /**
569
+ * Options of the decrypter.
570
+ */
571
+ interface AuthioTokenDecrypterOptions {
572
+ /** The setting the key came from, named in errors. Defaults to `clientEncryptionKey`. */
573
+ setting?: string;
574
+ /**
575
+ * Accepted for parity with the other Authio SDKs. RSA1_5 stays refused here, with an error saying so, because
576
+ * neither Node nor WebCrypto can decrypt PKCS#1 v1.5.
577
+ */
578
+ allowLegacyEncryptionAlgorithms?: boolean;
579
+ }
436
580
  /**
437
581
  * Whether a value is a compact JWE (five segments).
438
582
  */
@@ -440,10 +584,195 @@ declare function isAuthioTokenEncrypted(token: unknown): token is string;
440
584
  /**
441
585
  * Creates a decrypter for the client's own encryption key. Keys are imported once per algorithm.
442
586
  *
443
- * @param key The key, or `undefined` when none is configured: an encrypted token then throws.
444
- * @param setting The setting the key came from, named in errors.
587
+ * @param key The key, a function returning it, or `undefined` when none is configured: an encrypted token then throws.
588
+ * @param options The setting name for errors, and the legacy algorithm switch. A string is taken as the setting name.
589
+ */
590
+ declare function createAuthioTokenDecrypter(key: AuthioEncryptionKeySource | undefined, options?: AuthioTokenDecrypterOptions | string): AuthioTokenDecrypter;
591
+ /**
592
+ * Reads the client's encryption key from a PEM or JWK file (Node only), again whenever the file changes.
593
+ *
594
+ * @internal
595
+ */
596
+ declare function encryptionKeyFromFile(path: string, setting?: string): () => Promise<AuthioEncryptionKey>;
597
+
598
+ /**
599
+ * The claims of a validated ID token. Authio writes `typ` = `ID`, `sid`, `auth_time`, `acr`, `amr`, `nonce` and
600
+ * `at_hash`, besides the profile claims of the granted scopes.
601
+ */
602
+ interface AuthioIdTokenClaims extends JWTPayload {
603
+ sub: string;
604
+ sid?: string;
605
+ nonce?: string;
606
+ auth_time?: number;
607
+ acr?: string;
608
+ amr?: string[];
609
+ at_hash?: string;
610
+ [claim: string]: unknown;
611
+ }
612
+ /**
613
+ * A validated back-channel logout token: end the sessions of `subject`, or the one session `sessionId` names.
614
+ */
615
+ interface AuthioLogoutToken {
616
+ /** `sub`, when the token names the person. */
617
+ readonly subject: string | undefined;
618
+ /** `sid`, when the token names one session. */
619
+ readonly sessionId: string | undefined;
620
+ /** `jti`. */
621
+ readonly tokenId: string | undefined;
622
+ /** Every claim. */
623
+ readonly claims: Readonly<JWTPayload>;
624
+ }
625
+ /**
626
+ * The realm's signing keys, read from the discovery document's `jwks_uri` and cached; an unknown `kid` makes it read
627
+ * them again (at most once every 30 seconds).
628
+ *
629
+ * @internal
630
+ */
631
+ type AuthioSigningKeys = (signal?: AbortSignal) => Promise<JWTVerifyGetKey>;
632
+ /**
633
+ * What a JWT is checked against.
634
+ *
635
+ * @internal
636
+ */
637
+ interface AuthioJwtExpectations {
638
+ readonly issuer: string;
639
+ readonly audiences: readonly string[];
640
+ readonly algorithms?: readonly string[];
641
+ /** Seconds. */
642
+ readonly clockSkew?: number;
643
+ /** Milliseconds since the epoch. */
644
+ readonly now: number;
645
+ readonly requiredClaims?: readonly string[];
646
+ }
647
+ /**
648
+ * Creates the cached reader of the realm's signing keys.
649
+ *
650
+ * @internal
651
+ */
652
+ declare function createAuthioSigningKeys(connection: AuthioConnection, discovery: AuthioDiscoveryClient): AuthioSigningKeys;
653
+ /**
654
+ * Verifies a signed JWT: signature by a realm key with an accepted algorithm, `iss`, `aud`, `exp` (required) and
655
+ * `nbf` with the clock skew.
656
+ *
657
+ * @throws AuthioTokenValidationError naming why the token was refused.
658
+ * @internal
659
+ */
660
+ declare function verifyAuthioJwt(token: string, keys: JWTVerifyGetKey, expected: AuthioJwtExpectations): Promise<{
661
+ payload: JWTPayload;
662
+ header: Record<string, unknown>;
663
+ }>;
664
+ /**
665
+ * Turns a `jose` failure into the refusal it stands for, worded as ASP.NET Core's bearer handler words it.
666
+ *
667
+ * @internal
668
+ */
669
+ declare function toTokenValidationError(error: unknown, audiences: readonly string[], token: string): AuthioTokenValidationError;
670
+ /**
671
+ * The `at_hash` / `c_hash` of a value for a signing algorithm: the left half of its SHA-256, SHA-384 or SHA-512
672
+ * digest, base64url-encoded (OpenID Connect Core §3.1.3.6).
673
+ */
674
+ declare function computeAuthioTokenHash(value: string, algorithm: string): Promise<string>;
675
+
676
+ /**
677
+ * The PKCE method (RFC 7636). `S256` is the default; `plain` only when asked for, for a client that cannot hash.
678
+ */
679
+ type AuthioCodeChallengeMethod = "S256" | "plain";
680
+ /**
681
+ * A PKCE pair: send `codeChallenge` with the authorization request and `codeVerifier` with the code exchange.
682
+ */
683
+ interface AuthioPkcePair {
684
+ readonly codeVerifier: string;
685
+ readonly codeChallenge: string;
686
+ readonly codeChallengeMethod: AuthioCodeChallengeMethod;
687
+ }
688
+ /**
689
+ * What an authorization request asks Authio for. Every member is optional; `redirectUri` falls back to the client's.
690
+ */
691
+ interface AuthioAuthorizationRequest {
692
+ /** Where Authio sends the person back. Defaults to the client's `redirectUri`. */
693
+ redirectUri?: string;
694
+ /** Defaults to `openid`. */
695
+ scopes?: Iterable<string> | string;
696
+ /** The resource server the access token is for (RFC 8707). */
697
+ resource?: string;
698
+ /** The organization (its handle) the sign-in is for. Authoritative: the person cannot switch to another one. */
699
+ organization?: string;
700
+ /** `none` (silent), `login`, `select_account`, `consent`; several are joined with spaces. */
701
+ prompt?: AuthioPrompt | readonly AuthioPrompt[];
702
+ /** Seconds the person's sign-in may be old; Authio asks again past it, and the ID token's `auth_time` is checked. */
703
+ maxAge?: number;
704
+ /** Authentication context classes asked for: `1` one factor, `2` several, `3` one of them phishing-resistant. */
705
+ acrValues?: string | readonly string[];
706
+ /** Pre-fills the identifier on the sign-in screen. */
707
+ loginHint?: string;
708
+ /** A previously issued ID token, naming the person whose session is renewed. */
709
+ idTokenHint?: string;
710
+ /** Languages of the hosted screens, most preferred first. */
711
+ uiLocales?: string | readonly string[];
712
+ /** `page` (default) or `popup`, the layout of the hosted screens. */
713
+ display?: "page" | "popup";
714
+ /** `query` (default) or `web_message`, the popup's answer posted to the opener window. */
715
+ responseMode?: "query" | "web_message";
716
+ /** Shorthand for `display: "popup"` with `responseMode: "web_message"`. */
717
+ popup?: boolean;
718
+ /** The alias of the identity provider to go straight to, skipping Authio's sign-in screen. */
719
+ idpHint?: string;
720
+ /** Defaults to `S256`. */
721
+ codeChallengeMethod?: AuthioCodeChallengeMethod;
722
+ /** A `state` of your own; a random one otherwise. */
723
+ state?: string;
724
+ /** A `nonce` of your own; a random one otherwise. */
725
+ nonce?: string;
726
+ /** Further parameters, sent as given. */
727
+ extraParameters?: Record<string, string | undefined>;
728
+ }
729
+ /**
730
+ * What the application keeps between the authorization request and the callback (in its session, a cookie, …), to
731
+ * check the callback and redeem the code.
732
+ */
733
+ interface AuthioAuthorizationTransaction {
734
+ readonly state: string;
735
+ readonly nonce: string;
736
+ readonly codeVerifier: string;
737
+ readonly codeChallengeMethod: AuthioCodeChallengeMethod;
738
+ readonly redirectUri: string;
739
+ readonly resource?: string;
740
+ readonly maxAge?: number;
741
+ }
742
+ /**
743
+ * An authorization URL and the transaction to keep until the callback.
744
+ */
745
+ interface AuthioAuthorizationUrl {
746
+ readonly url: string;
747
+ readonly transaction: AuthioAuthorizationTransaction;
748
+ }
749
+ /**
750
+ * A `WWW-Authenticate` bearer challenge, as an API answers it (RFC 6750, RFC 9470, RFC 9728).
751
+ */
752
+ interface AuthioBearerChallenge {
753
+ readonly error: string | undefined;
754
+ readonly errorDescription: string | undefined;
755
+ /** `insufficient_scope`: the scopes required. */
756
+ readonly scope: string | undefined;
757
+ /** `insufficient_user_authentication`: the context classes to ask for. */
758
+ readonly acrValues: string | undefined;
759
+ /** `insufficient_user_authentication`: how old the sign-in may be, in seconds. */
760
+ readonly maxAge: number | undefined;
761
+ /** RFC 9728: where the API's protected resource metadata is. */
762
+ readonly resourceMetadata: string | undefined;
763
+ }
764
+ /**
765
+ * Creates a PKCE pair: a 256-bit random verifier and its S256 (or plain) challenge.
766
+ */
767
+ declare function createAuthioPkce(method?: AuthioCodeChallengeMethod): Promise<AuthioPkcePair>;
768
+ /**
769
+ * A random, URL-safe value of `bytes` random bytes, for `state` and `nonce`.
445
770
  */
446
- declare function createAuthioTokenDecrypter(key: AuthioEncryptionKey | undefined, setting?: string): AuthioTokenDecrypter;
771
+ declare function randomValue(bytes?: number): string;
772
+ /**
773
+ * Parses a `WWW-Authenticate` bearer challenge, or `undefined` when the header holds none.
774
+ */
775
+ declare function parseAuthioBearerChallenge(header: string | null | undefined): AuthioBearerChallenge | undefined;
447
776
 
448
777
  /**
449
778
  * A token endpoint answer, as Authio sends it.
@@ -529,9 +858,10 @@ interface AuthioClientCredentialsToken {
529
858
  * One of the person's connected accounts at a provider.
530
859
  */
531
860
  interface AuthioConnectionChoice {
532
- id: string;
533
- label?: string;
534
- external_login?: string;
861
+ readonly id: string;
862
+ readonly label?: string;
863
+ /** The account's login at the provider. */
864
+ readonly externalLogin?: string;
535
865
  }
536
866
  /**
537
867
  * The account at the provider a connection token belongs to.
@@ -540,6 +870,7 @@ interface AuthioExternalAccount {
540
870
  id?: string;
541
871
  login?: string;
542
872
  email?: string;
873
+ [member: string]: unknown;
543
874
  }
544
875
  /**
545
876
  * The outcome of exchanging a user's token for the token of one of their connected accounts.
@@ -551,15 +882,17 @@ type AuthioConnectionExchangeResult = AuthioConnectionGranted | AuthioConnection
551
882
  interface AuthioConnectionGranted {
552
883
  readonly status: "granted";
553
884
  readonly accessToken: string;
554
- readonly provider: string;
555
- readonly providerType?: string;
556
- readonly connectionId?: string;
557
- readonly tokenType?: string;
885
+ /** `urn:authio:params:oauth:token-type:connection-access-token`. */
558
886
  readonly issuedTokenType?: string;
559
- readonly scope?: string;
560
- readonly externalAccount?: AuthioExternalAccount;
887
+ readonly tokenType?: string;
561
888
  /** Seconds. */
562
889
  readonly expiresIn?: number;
890
+ readonly scope?: string;
891
+ readonly connectionId?: string;
892
+ readonly provider: string;
893
+ /** The kind of provider, such as `GitHubApp`. */
894
+ readonly providerType?: string;
895
+ readonly externalAccount?: AuthioExternalAccount;
563
896
  }
564
897
  /**
565
898
  * The person has not connected an account at the provider yet; send them to `connectUri`.
@@ -567,15 +900,19 @@ interface AuthioConnectionGranted {
567
900
  interface AuthioConnectionRequired {
568
901
  readonly status: "required";
569
902
  readonly connectUri?: string;
570
- readonly description: string;
903
+ readonly provider: string;
904
+ readonly errorCode?: string;
905
+ readonly errorDescription: string;
571
906
  }
572
907
  /**
573
908
  * The person has several accounts at the provider; ask again with one `connectionId`.
574
909
  */
575
910
  interface AuthioConnectionSelectionRequired {
576
911
  readonly status: "selection_required";
912
+ readonly provider: string;
577
913
  readonly connections: readonly AuthioConnectionChoice[];
578
- readonly description: string;
914
+ readonly errorCode?: string;
915
+ readonly errorDescription: string;
579
916
  }
580
917
  /**
581
918
  * Authio refused the exchange.
@@ -583,10 +920,20 @@ interface AuthioConnectionSelectionRequired {
583
920
  interface AuthioConnectionRefused {
584
921
  readonly status: "refused";
585
922
  readonly error: string;
586
- readonly code?: string;
587
- readonly description: string;
923
+ readonly errorCode?: string;
924
+ readonly errorDescription: string;
588
925
  readonly connectUri?: string;
589
926
  }
927
+ /**
928
+ * What one poll of the device flow's token endpoint means (RFC 8628 §3.5).
929
+ */
930
+ type AuthioDevicePollOutcome = {
931
+ readonly outcome: "keep_polling";
932
+ readonly intervalIncrease: number;
933
+ } | {
934
+ readonly outcome: "failed";
935
+ readonly error: string;
936
+ };
590
937
 
591
938
  /**
592
939
  * Everything the Authio client needs: where Authio is, and the client's credentials.
@@ -596,8 +943,50 @@ interface AuthioClientOptions extends AuthioConnectionOptions, AuthioClientCrede
596
943
  * Seconds before expiry a cached token is renewed (capped at half its lifetime). Defaults to 60.
597
944
  */
598
945
  tokenRefreshSkew?: number;
599
- /** The client's own encryption key, to read a UserInfo Authio answers encrypted. */
600
- clientEncryptionKey?: AuthioEncryptionKey;
946
+ /**
947
+ * The private half of the client's own encryption key, to read ID tokens, UserInfo and logout tokens Authio
948
+ * encrypts to the client (RSA-OAEP or RSA-OAEP-256); or a function returning it.
949
+ */
950
+ clientEncryptionKey?: AuthioEncryptionKeySource;
951
+ /** A PEM or JWK file holding `clientEncryptionKey` (Node only), read on first use. */
952
+ clientEncryptionKeyPath?: string;
953
+ /**
954
+ * Accepted for parity with the other Authio SDKs; RSA1_5 stays refused here, because Node and WebCrypto cannot
955
+ * decrypt it. Defaults to `false`.
956
+ */
957
+ allowLegacyEncryptionAlgorithms?: boolean;
958
+ /** Where Authio sends the person back after signing in, unless a request names another. */
959
+ redirectUri?: string;
960
+ /** Where Authio sends the person after signing out, unless a request names another. */
961
+ postLogoutRedirectUri?: string;
962
+ /** Seconds of clock skew tolerated on ID tokens, logout tokens and signed UserInfo. Defaults to 30. */
963
+ clockSkew?: number;
964
+ /** Algorithms ID tokens, logout tokens and signed UserInfo are accepted with. Defaults to RS*, PS*, ES*. */
965
+ validAlgorithms?: readonly string[];
966
+ }
967
+ /**
968
+ * What a completed sign-in yields.
969
+ */
970
+ interface AuthioAuthorizationResult {
971
+ /** The token endpoint's answer: access token, refresh token, ID token. */
972
+ readonly tokens: AuthioTokenResponse;
973
+ /** The validated ID token's claims, when Authio issued one (the `openid` scope). */
974
+ readonly idToken: AuthioIdTokenClaims | undefined;
975
+ }
976
+ /**
977
+ * What the end-session URL carries (OpenID Connect RP-Initiated Logout).
978
+ */
979
+ interface AuthioEndSessionRequest {
980
+ /** The ID token of the session to end. */
981
+ idTokenHint?: string;
982
+ /** Where to send the person afterwards; must be registered. Defaults to the client's `postLogoutRedirectUri`. */
983
+ postLogoutRedirectUri?: string;
984
+ /** Echoed back to `postLogoutRedirectUri`. */
985
+ state?: string;
986
+ /** The language of the signed-out screen. */
987
+ uiLocales?: string | readonly string[];
988
+ /** Sends the client id unless `false`, so Authio knows the client without an ID token. */
989
+ includeClientId?: boolean;
601
990
  }
602
991
  /**
603
992
  * Per-call options.
@@ -661,6 +1050,16 @@ interface AuthioTokenClient {
661
1050
  password: string;
662
1051
  scopes?: Iterable<string> | string;
663
1052
  } & AuthioCallOptions): Promise<AuthioTokenResponse>;
1053
+ /**
1054
+ * The `personal_access_token` grant: a `pat_` value presented as `client_secret`, with the consumer's client id for
1055
+ * a consumer's token or none for an account's token. The client's own credentials are not sent.
1056
+ */
1057
+ personalAccessToken(options: {
1058
+ token: string;
1059
+ clientId?: string;
1060
+ scopes?: Iterable<string> | string;
1061
+ resource?: string;
1062
+ } & AuthioCallOptions): Promise<AuthioTokenResponse>;
664
1063
  }
665
1064
  /**
666
1065
  * Client-credentials tokens, cached per scopes and resource.
@@ -721,6 +1120,49 @@ interface AuthioClient {
721
1120
  resource?: string;
722
1121
  fetch?: typeof fetch;
723
1122
  }): typeof fetch;
1123
+ /**
1124
+ * Builds the authorization URL (PKCE S256, `state`, `nonce` and Authio's parameters) and the transaction to keep
1125
+ * until the callback.
1126
+ */
1127
+ createAuthorizationUrl(request?: AuthioAuthorizationRequest & AuthioCallOptions): Promise<AuthioAuthorizationUrl>;
1128
+ /**
1129
+ * Completes a sign-in: checks `state` and the `iss` parameter (RFC 9207), throws the OAuth error Authio sent back,
1130
+ * redeems the code with the PKCE verifier, and validates the ID token (nonce, `at_hash`, `max_age`).
1131
+ *
1132
+ * @param callback The callback URL, its query, or its parameters (a `web_message` answer, a parsed query).
1133
+ * @param transaction What `createAuthorizationUrl` returned with the URL.
1134
+ * @throws AuthioCallbackError when the callback is not for this transaction.
1135
+ * @throws AuthioProtocolError for an OAuth error.
1136
+ * @throws AuthioTokenValidationError when the ID token does not validate.
1137
+ */
1138
+ handleAuthorizationCallback(callback: string | URL | URLSearchParams | Readonly<Record<string, unknown>>, transaction: AuthioAuthorizationTransaction, options?: AuthioCallOptions): Promise<AuthioAuthorizationResult>;
1139
+ /**
1140
+ * Validates an ID token: decrypted with `clientEncryptionKey` when it is a JWE, then signature (cached JWKS), `iss`,
1141
+ * `aud` = the client id, `exp` with the skew, payload `typ` = `ID`, and `nonce`, `at_hash` and `auth_time` when
1142
+ * given.
1143
+ *
1144
+ * @throws AuthioTokenValidationError naming why it was refused.
1145
+ */
1146
+ validateIdToken(idToken: string, expectations?: {
1147
+ nonce?: string;
1148
+ accessToken?: string;
1149
+ maxAge?: number;
1150
+ } & AuthioCallOptions): Promise<AuthioIdTokenClaims>;
1151
+ /**
1152
+ * Validates a back-channel logout token Authio posted as `logout_token`.
1153
+ *
1154
+ * @throws AuthioTokenValidationError naming why it was refused (`invalid_logout_token` for the logout-specific rules).
1155
+ */
1156
+ validateLogoutToken(logoutToken: string, options?: AuthioCallOptions): Promise<AuthioLogoutToken>;
1157
+ /** Builds the end-session URL (RP-Initiated Logout). */
1158
+ createEndSessionUrl(request?: AuthioEndSessionRequest & AuthioCallOptions): Promise<string>;
1159
+ /**
1160
+ * Builds an authorization URL that satisfies an API's `insufficient_user_authentication` challenge (RFC 9470): its
1161
+ * `acr_values` and `max_age`, with `prompt=login` when the challenge asks for a sign-in made just now (`max_age=0`).
1162
+ *
1163
+ * @param challenge The `WWW-Authenticate` header value, or the challenge already parsed.
1164
+ */
1165
+ createStepUpAuthorizationUrl(challenge: string | AuthioBearerChallenge, request?: AuthioAuthorizationRequest & AuthioCallOptions): Promise<AuthioAuthorizationUrl>;
724
1166
  }
725
1167
  /**
726
1168
  * Creates the Authio client.
@@ -733,6 +1175,102 @@ declare function createAuthioClient(options: AuthioClientOptions): AuthioClient;
733
1175
  * renewed `refreshSkewMs` before that, at most half its lifetime.
734
1176
  */
735
1177
  declare function toClientCredentialsToken(response: AuthioTokenResponse, issuedAt: number, refreshSkewMs: number): AuthioClientCredentialsToken;
1178
+ /**
1179
+ * Reads the answer of a connected-account token exchange (see `conformance/oauth-responses.json`).
1180
+ *
1181
+ * @internal
1182
+ */
1183
+ declare function toConnectionExchangeResult(body: string, status: number, provider: string): AuthioConnectionExchangeResult;
1184
+ /**
1185
+ * What a device-flow poll's OAuth error means: keep polling (5 seconds slower after `slow_down`), or stop with it.
1186
+ */
1187
+ declare function toDevicePollOutcome(error: string): AuthioDevicePollOutcome;
1188
+
1189
+ /**
1190
+ * A successful Admin API answer: the envelope's `data` (one object, or a listing's page `{ items, totalCount,
1191
+ * pageNumber, pageSize }`), nothing for `204`.
1192
+ */
1193
+ interface AuthioAdminSuccess<T = unknown> {
1194
+ readonly ok: true;
1195
+ readonly data?: T;
1196
+ }
1197
+ /**
1198
+ * A refused Admin API answer.
1199
+ */
1200
+ interface AuthioAdminFailure {
1201
+ readonly ok: false;
1202
+ readonly error: AuthioAdminError;
1203
+ }
1204
+ /**
1205
+ * An Admin API answer, read.
1206
+ */
1207
+ type AuthioAdminEnvelope<T = unknown> = AuthioAdminSuccess<T> | AuthioAdminFailure;
1208
+ /**
1209
+ * How an account credential is presented: `ak_` (API key), `cs_` (client secret, exchanged first) or `pat_`
1210
+ * (personal access token).
1211
+ */
1212
+ type AuthioAccountCredentialKind = "api_key" | "client_secret" | "personal_access_token";
1213
+ /**
1214
+ * Options of `createAuthioAccountCredential`.
1215
+ */
1216
+ interface AuthioAccountCredentialOptions extends Omit<AuthioConnectionOptions, "issuer" | "realm"> {
1217
+ /** Authio's base URL, such as `https://auth.example.com`. Required. */
1218
+ authority?: string;
1219
+ /** The credential's value: `ak_…`, `cs_…` or `pat_…`. */
1220
+ credential: string;
1221
+ /** The credential's id, needed to exchange a `cs_` secret (its `client_id` is `cred_` and the id without dashes). */
1222
+ credentialId?: string;
1223
+ /** How an `ak_` or `pat_` value is sent directly: `Authorization: Bearer` (default) or `x-api-key`. */
1224
+ presentAs?: "bearer" | "x-api-key";
1225
+ /** Exchanges a `pat_` value with the `personal_access_token` grant instead of sending it directly. */
1226
+ exchangePersonalAccessToken?: boolean;
1227
+ /** Narrows an exchanged token to these `admin:{permission}:{method}` scopes. */
1228
+ scopes?: Iterable<string> | string;
1229
+ /** Seconds before expiry an exchanged token is renewed (at most half its lifetime). Defaults to 60. */
1230
+ tokenRefreshSkew?: number;
1231
+ }
1232
+ /**
1233
+ * An account credential ready to call the Admin API with.
1234
+ */
1235
+ interface AuthioAccountCredential {
1236
+ /** How the credential is presented. */
1237
+ readonly kind: AuthioAccountCredentialKind;
1238
+ /** Whether it is exchanged at the `authio` realm's token endpoint before use. */
1239
+ readonly exchanged: boolean;
1240
+ /** The headers that authenticate a request: `Authorization` or `x-api-key`. */
1241
+ headers(signal?: AbortSignal): Promise<Record<string, string>>;
1242
+ /** Drops an exchanged token, so the next request exchanges again. */
1243
+ invalidate(): void;
1244
+ /**
1245
+ * A `fetch` that authenticates every request; on `401` with an exchanged token it exchanges again and retries once;
1246
+ * on `429` or `503` it waits `Retry-After` and retries an idempotent request (`GET`, `HEAD`, `PUT`, `DELETE`) once.
1247
+ */
1248
+ readonly fetch: typeof fetch;
1249
+ }
1250
+ /**
1251
+ * Reads an Admin API answer (see `conformance/admin-envelopes.json`). The status is the HTTP one, never the
1252
+ * envelope's numeric `statusCode`; `requestId` falls back to `X-Request-Id`, and `retryAfterSeconds` comes from
1253
+ * `Retry-After`.
1254
+ */
1255
+ declare function parseAuthioAdminEnvelope<T = unknown>(status: number, body: string | null | undefined, headers?: Headers | Readonly<Record<string, string | undefined>>): AuthioAdminEnvelope<T>;
1256
+ /**
1257
+ * Reads an Admin API response, throwing `AuthioAdminError` when it is not a success.
1258
+ */
1259
+ declare function readAuthioAdminResponse<T = unknown>(response: Response): Promise<AuthioAdminSuccess<T>>;
1260
+ /**
1261
+ * Prepares an account credential for the Admin API: `ak_` and `pat_` go directly as `Authorization: Bearer` (or
1262
+ * `x-api-key`); a `cs_` secret is exchanged at `{authority}/realms/authio` with `client_credentials` and the
1263
+ * `client_id` `cred_{id}`; a `pat_` may be exchanged with the `personal_access_token` grant instead. Exchanged tokens
1264
+ * are cached and renewed before expiry.
1265
+ *
1266
+ * @throws AuthioConfigurationError when the value has no known prefix or a `cs_` secret comes without its id.
1267
+ */
1268
+ declare function createAuthioAccountCredential(options: AuthioAccountCredentialOptions): AuthioAccountCredential;
1269
+ /**
1270
+ * The `client_id` an account credential's client secret is exchanged with: `cred_` and the id in format N (no dashes,
1271
+ * lower case). An id already starting with `cred_` is kept.
1272
+ */
1273
+ declare function toCredentialClientId(credentialId: string): string;
736
1274
 
737
1275
  /**
738
1276
  * One role read from a `*_resource_access` claim, with the permissions it grants.
@@ -811,109 +1349,152 @@ type AuthioWebhookVerificationResult = {
811
1349
  readonly timestamp?: Date;
812
1350
  };
813
1351
  /**
814
- * A webhook event. `data` holds the event-specific payload; read it typed with the `as…` helpers.
1352
+ * A webhook event. `data` holds the event-specific payload as delivered (snake_case); read it typed, in camelCase,
1353
+ * with the `as…` helpers.
815
1354
  */
816
1355
  interface AuthioWebhookEvent {
817
1356
  readonly id: string;
818
1357
  readonly type: string;
819
1358
  /** Seconds since the epoch. */
820
1359
  readonly created_at: number;
821
- readonly realm_id?: string;
822
- readonly client_id?: string;
1360
+ readonly realm_id?: string | null;
1361
+ readonly client_id?: string | null;
823
1362
  readonly data: unknown;
824
1363
  [member: string]: unknown;
825
1364
  }
826
- /** `user_created`, `user_updated`, `user_deleted`. */
1365
+ /** `user_created`, `user_updated`, `user_deleted`, as delivered. */
827
1366
  interface AuthioWebhookUserData {
828
1367
  id: string;
829
- username?: string;
830
- email?: string;
831
- first_name?: string;
832
- last_name?: string;
1368
+ username?: string | null;
1369
+ email?: string | null;
1370
+ first_name?: string | null;
1371
+ last_name?: string | null;
833
1372
  email_confirmed: boolean;
834
- status?: string;
835
- realm_id?: string;
836
- client_id?: string;
1373
+ status?: string | null;
1374
+ realm_id?: string | null;
1375
+ client_id?: string | null;
837
1376
  }
838
- /** `login_succeeded`, `login_failed`. */
1377
+ /** `login_succeeded`, `login_failed`, as delivered. */
839
1378
  interface AuthioWebhookLoginData {
840
- grant_type?: string;
841
- user_id?: string;
842
- username?: string;
843
- email?: string;
844
- ip_address?: string;
845
- user_agent?: string;
846
- session_id?: string;
847
- failure_reason?: string;
848
- resource?: string;
849
- scopes?: string;
1379
+ grant_type?: string | null;
1380
+ user_id?: string | null;
1381
+ username?: string | null;
1382
+ email?: string | null;
1383
+ ip_address?: string | null;
1384
+ user_agent?: string | null;
1385
+ session_id?: string | null;
1386
+ failure_reason?: string | null;
1387
+ resource?: string | null;
1388
+ scopes?: string[] | null;
1389
+ authentication_methods?: string[] | null;
1390
+ acr?: string | null;
1391
+ identity_provider?: string | null;
1392
+ consumer_id?: string | null;
1393
+ consumer_name?: string | null;
850
1394
  }
851
- /** `user_locked_out`. */
1395
+ /** `user_locked_out`, as delivered. */
852
1396
  interface AuthioWebhookUserLockedOutData {
853
1397
  user_id: string;
854
- username?: string;
855
- email?: string;
856
- lockout_end?: string;
1398
+ username?: string | null;
1399
+ email?: string | null;
1400
+ lockout_end?: string | null;
857
1401
  access_failed_count: number;
858
1402
  }
859
- /** `token_revoked`. */
1403
+ /** `token_revoked`, as delivered. */
860
1404
  interface AuthioWebhookTokenRevokedData {
861
- token_id?: string;
862
- subject?: string;
863
- session_id?: string;
864
- token_type_hint?: string;
1405
+ token_id?: string | null;
1406
+ subject?: string | null;
1407
+ session_id?: string | null;
1408
+ token_type_hint?: string | null;
865
1409
  }
866
- /** `keys_rotated`. */
1410
+ /**
1411
+ * `keys_rotated`, as delivered: `rotation_days` and `automatic` on a scheduled rotation, `revoked_keys_count` on a
1412
+ * manual one.
1413
+ */
867
1414
  interface AuthioWebhookKeysRotatedData {
868
- signing_key_id?: string;
869
- encryption_key_id?: string;
870
- revoked_keys_count?: number;
871
- rotation_days?: number;
872
- automatic?: boolean;
1415
+ signing_key_id?: string | null;
1416
+ encryption_key_id?: string | null;
1417
+ revoked_keys_count?: number | null;
1418
+ rotation_days?: number | null;
1419
+ automatic?: boolean | null;
873
1420
  }
874
- /** `token_reuse_detected`. */
1421
+ /** `token_reuse_detected`, as delivered. */
875
1422
  interface AuthioWebhookTokenReuseDetectedData {
876
- token_id?: string;
877
- subject?: string;
878
- session_id?: string;
879
- ip_address?: string;
880
- user_agent?: string;
1423
+ token_id?: string | null;
1424
+ subject?: string | null;
1425
+ session_id?: string | null;
1426
+ ip_address?: string | null;
1427
+ user_agent?: string | null;
881
1428
  }
882
- /** `admin_resource_created`, `admin_resource_updated`, `admin_resource_deleted`. */
1429
+ /** `admin_resource_created`, `admin_resource_updated`, `admin_resource_deleted`, as delivered. */
883
1430
  interface AuthioWebhookAdminResourceData {
884
- action?: string;
885
- resource_type?: string;
886
- resource_id?: string;
887
- realm_id?: string;
888
- client_id?: string;
889
- actor_user_id?: string;
890
- actor_username?: string;
891
- actor_email?: string;
892
- ip_address?: string;
893
- method?: string;
894
- path?: string;
895
- }
896
- /** `user_suspended`, `user_suspension_ended`. */
1431
+ action?: string | null;
1432
+ resource_type?: string | null;
1433
+ resource_id?: string | null;
1434
+ parent_id?: string | null;
1435
+ realm_id?: string | null;
1436
+ client_id?: string | null;
1437
+ /** `User` or `Credential`. */
1438
+ actor_type?: string | null;
1439
+ actor_user_id?: string | null;
1440
+ actor_username?: string | null;
1441
+ actor_email?: string | null;
1442
+ actor_credential_id?: string | null;
1443
+ actor_credential_name?: string | null;
1444
+ actor_platform_operator?: boolean | null;
1445
+ ip_address?: string | null;
1446
+ method?: string | null;
1447
+ path?: string | null;
1448
+ /** What changed, by resource type; kept as delivered. */
1449
+ details?: Record<string, unknown> | null;
1450
+ }
1451
+ /** `user_suspended`, `user_suspension_ended`, as delivered. */
897
1452
  interface AuthioWebhookUserSuspensionData {
898
1453
  id: string;
899
1454
  user_id: string;
900
- level?: string;
901
- status?: string;
902
- starts_at?: string;
903
- ends_at?: string;
1455
+ level?: string | null;
1456
+ status?: string | null;
1457
+ starts_at?: string | null;
1458
+ ends_at?: string | null;
904
1459
  restricted_scopes: string[];
905
1460
  revokes_every_role: boolean;
906
1461
  revoked_role_ids: string[];
907
- sessions_terminated_at?: string;
908
- lifted_at?: string;
1462
+ sessions_terminated_at?: string | null;
1463
+ lifted_at?: string | null;
909
1464
  }
910
- /** `ping`. */
1465
+ /** `attack_detected`, as delivered: an attack on the realm and the measure Authio took. */
1466
+ interface AuthioWebhookAttackDetectedData {
1467
+ incident_id: string;
1468
+ /** Such as `credential_stuffing`. */
1469
+ kind?: string | null;
1470
+ severity?: string | null;
1471
+ /** Such as `source_blocked`. */
1472
+ measure?: string | null;
1473
+ ip_address?: string | null;
1474
+ country?: string | null;
1475
+ asn?: number | null;
1476
+ network_operator?: string | null;
1477
+ user_id?: string | null;
1478
+ started_at?: string | null;
1479
+ }
1480
+ /** `credential_compromised`, as delivered: a person's password was used by an attacker. */
1481
+ interface AuthioWebhookCredentialCompromisedData {
1482
+ incident_id: string;
1483
+ user_id?: string | null;
1484
+ username?: string | null;
1485
+ ip_address?: string | null;
1486
+ country?: string | null;
1487
+ asn?: number | null;
1488
+ network_operator?: string | null;
1489
+ password_change_required?: boolean | null;
1490
+ }
1491
+ /** `ping`, as delivered. */
911
1492
  interface AuthioWebhookPingData {
912
- message?: string;
913
- subscription?: string;
1493
+ message?: string | null;
1494
+ subscription?: string | null;
914
1495
  }
915
1496
  /**
916
- * The data shape of each event type.
1497
+ * The data shape of each event type, as delivered (snake_case).
917
1498
  */
918
1499
  interface AuthioWebhookDataByType {
919
1500
  user_created: AuthioWebhookUserData;
@@ -930,10 +1511,44 @@ interface AuthioWebhookDataByType {
930
1511
  admin_resource_deleted: AuthioWebhookAdminResourceData;
931
1512
  user_suspended: AuthioWebhookUserSuspensionData;
932
1513
  user_suspension_ended: AuthioWebhookUserSuspensionData;
1514
+ attack_detected: AuthioWebhookAttackDetectedData;
1515
+ credential_compromised: AuthioWebhookCredentialCompromisedData;
933
1516
  ping: AuthioWebhookPingData;
934
1517
  }
935
1518
  /**
936
- * An event narrowed to one type, with its data typed.
1519
+ * A snake_case name in camelCase.
1520
+ */
1521
+ type AuthioCamelCase<S extends string> = S extends `${infer Head}_${infer Tail}` ? `${Head}${Capitalize<AuthioCamelCase<Tail>>}` : S;
1522
+ /**
1523
+ * An object whose top-level member names are turned into camelCase, values unchanged.
1524
+ */
1525
+ type AuthioCamelCased<T> = {
1526
+ [K in keyof T as K extends string ? AuthioCamelCase<K> : K]: T[K];
1527
+ };
1528
+ /** The data of a user event, as the typed accessor exposes it. */
1529
+ type AuthioWebhookUser = AuthioCamelCased<AuthioWebhookUserData>;
1530
+ /** The data of a login event, as the typed accessor exposes it. */
1531
+ type AuthioWebhookLogin = AuthioCamelCased<AuthioWebhookLoginData>;
1532
+ /** The data of a lockout event, as the typed accessor exposes it. */
1533
+ type AuthioWebhookUserLockedOut = AuthioCamelCased<AuthioWebhookUserLockedOutData>;
1534
+ /** The data of a revocation event, as the typed accessor exposes it. */
1535
+ type AuthioWebhookTokenRevoked = AuthioCamelCased<AuthioWebhookTokenRevokedData>;
1536
+ /** The data of a key rotation event, as the typed accessor exposes it. */
1537
+ type AuthioWebhookKeysRotated = AuthioCamelCased<AuthioWebhookKeysRotatedData>;
1538
+ /** The data of a refresh token reuse event, as the typed accessor exposes it. */
1539
+ type AuthioWebhookTokenReuseDetected = AuthioCamelCased<AuthioWebhookTokenReuseDetectedData>;
1540
+ /** The data of an admin resource event, as the typed accessor exposes it. */
1541
+ type AuthioWebhookAdminResource = AuthioCamelCased<AuthioWebhookAdminResourceData>;
1542
+ /** The data of a suspension event, as the typed accessor exposes it. */
1543
+ type AuthioWebhookUserSuspension = AuthioCamelCased<AuthioWebhookUserSuspensionData>;
1544
+ /** The data of an attack event, as the typed accessor exposes it. */
1545
+ type AuthioWebhookAttackDetected = AuthioCamelCased<AuthioWebhookAttackDetectedData>;
1546
+ /** The data of a compromised credential event, as the typed accessor exposes it. */
1547
+ type AuthioWebhookCredentialCompromised = AuthioCamelCased<AuthioWebhookCredentialCompromisedData>;
1548
+ /** The data of a ping, as the typed accessor exposes it. */
1549
+ type AuthioWebhookPing = AuthioCamelCased<AuthioWebhookPingData>;
1550
+ /**
1551
+ * An event narrowed to one type, with its data typed as delivered.
937
1552
  */
938
1553
  type AuthioTypedWebhookEvent<T extends keyof AuthioWebhookDataByType> = AuthioWebhookEvent & {
939
1554
  readonly type: T;
@@ -973,23 +1588,40 @@ declare function tryParseWebhookEvent(rawBody: string | Uint8Array | null | unde
973
1588
  * Whether the event is of one of the given types, narrowing its data.
974
1589
  */
975
1590
  declare function isWebhookEventOfType<T extends keyof AuthioWebhookDataByType>(event: AuthioWebhookEvent, ...types: T[]): event is AuthioTypedWebhookEvent<T>;
976
- /** The data of a user event, or `undefined` for any other type. */
977
- declare const asUserEvent: (event: AuthioWebhookEvent) => AuthioWebhookUserData | undefined;
978
- /** The data of a login event, or `undefined` for any other type. */
979
- declare const asLoginEvent: (event: AuthioWebhookEvent) => AuthioWebhookLoginData | undefined;
980
- /** The data of a lockout event, or `undefined` for any other type. */
981
- declare const asUserLockedOutEvent: (event: AuthioWebhookEvent) => AuthioWebhookUserLockedOutData | undefined;
982
- /** The data of a revocation event, or `undefined` for any other type. */
983
- declare const asTokenRevokedEvent: (event: AuthioWebhookEvent) => AuthioWebhookTokenRevokedData | undefined;
984
- /** The data of a key rotation event, or `undefined` for any other type. */
985
- declare const asKeysRotatedEvent: (event: AuthioWebhookEvent) => AuthioWebhookKeysRotatedData | undefined;
986
- /** The data of a refresh token reuse event, or `undefined` for any other type. */
987
- declare const asTokenReuseDetectedEvent: (event: AuthioWebhookEvent) => AuthioWebhookTokenReuseDetectedData | undefined;
988
- /** The data of an admin resource event, or `undefined` for any other type. */
989
- declare const asAdminResourceEvent: (event: AuthioWebhookEvent) => AuthioWebhookAdminResourceData | undefined;
990
- /** The data of a suspension event, or `undefined` for any other type. */
991
- declare const asUserSuspensionEvent: (event: AuthioWebhookEvent) => AuthioWebhookUserSuspensionData | undefined;
992
- /** The data of a ping, or `undefined` for any other type. */
993
- declare const asPingEvent: (event: AuthioWebhookEvent) => AuthioWebhookPingData | undefined;
1591
+ /** The data of a user event in camelCase, or `undefined` for any other type. */
1592
+ declare const asUserEvent: (event: AuthioWebhookEvent) => AuthioCamelCased<AuthioWebhookUserData> | undefined;
1593
+ /** The data of a login event in camelCase, or `undefined` for any other type. */
1594
+ declare const asLoginEvent: (event: AuthioWebhookEvent) => AuthioCamelCased<AuthioWebhookLoginData> | undefined;
1595
+ /** The data of a lockout event in camelCase, or `undefined` for any other type. */
1596
+ declare const asUserLockedOutEvent: (event: AuthioWebhookEvent) => AuthioCamelCased<AuthioWebhookUserLockedOutData> | undefined;
1597
+ /** The data of a revocation event in camelCase, or `undefined` for any other type. */
1598
+ declare const asTokenRevokedEvent: (event: AuthioWebhookEvent) => AuthioCamelCased<AuthioWebhookTokenRevokedData> | undefined;
1599
+ /** The data of a key rotation event in camelCase, or `undefined` for any other type. */
1600
+ declare const asKeysRotatedEvent: (event: AuthioWebhookEvent) => AuthioCamelCased<AuthioWebhookKeysRotatedData> | undefined;
1601
+ /** The data of a refresh token reuse event in camelCase, or `undefined` for any other type. */
1602
+ declare const asTokenReuseDetectedEvent: (event: AuthioWebhookEvent) => AuthioCamelCased<AuthioWebhookTokenReuseDetectedData> | undefined;
1603
+ /** The data of an admin resource event in camelCase, or `undefined` for any other type. */
1604
+ declare const asAdminResourceEvent: (event: AuthioWebhookEvent) => AuthioCamelCased<AuthioWebhookAdminResourceData> | undefined;
1605
+ /** The data of a suspension event in camelCase, or `undefined` for any other type. */
1606
+ declare const asUserSuspensionEvent: (event: AuthioWebhookEvent) => AuthioCamelCased<AuthioWebhookUserSuspensionData> | undefined;
1607
+ /** The data of an attack event in camelCase, or `undefined` for any other type. */
1608
+ declare const asAttackDetectedEvent: (event: AuthioWebhookEvent) => AuthioCamelCased<AuthioWebhookAttackDetectedData> | undefined;
1609
+ /** The data of a compromised credential event in camelCase, or `undefined` for any other type. */
1610
+ declare const asCredentialCompromisedEvent: (event: AuthioWebhookEvent) => AuthioCamelCased<AuthioWebhookCredentialCompromisedData> | undefined;
1611
+ /** The data of a ping in camelCase, or `undefined` for any other type. */
1612
+ declare const asPingEvent: (event: AuthioWebhookEvent) => AuthioCamelCased<AuthioWebhookPingData> | undefined;
1613
+ /**
1614
+ * Whether Authio documents the event type. An unknown type still parses; read its `data` as delivered.
1615
+ */
1616
+ declare function isKnownWebhookEventType(type: string): type is keyof AuthioWebhookDataByType;
1617
+ /**
1618
+ * The data of any known event in camelCase (what the typed accessor of its type returns), or `undefined` for an
1619
+ * unknown type.
1620
+ */
1621
+ declare function readWebhookEventData(event: AuthioWebhookEvent): Record<string, unknown> | undefined;
1622
+ /**
1623
+ * Turns the top-level member names of an object from snake_case into camelCase, leaving the values as they are.
1624
+ */
1625
+ declare function toCamelCasedMembers<T extends object>(value: T): AuthioCamelCased<T>;
994
1626
 
995
- export { AuthioAsymmetricAlgorithms, type AuthioCallOptions, AuthioClaimTypes, type AuthioClient, AuthioClientAssertionAlgorithms, type AuthioClientAuthentication, type AuthioClientCredentialsCache, type AuthioClientCredentialsSettings, type AuthioClientCredentialsToken, type AuthioClientOptions, type AuthioClock, AuthioConfigurationError, type AuthioConnection, type AuthioConnectionChoice, type AuthioConnectionExchangeResult, type AuthioConnectionGranted, type AuthioConnectionOptions, type AuthioConnectionRefused, type AuthioConnectionRequired, type AuthioConnectionSelectionRequired, AuthioContentEncryptionAlgorithms, AuthioDefaults, type AuthioDeviceAuthorization, type AuthioDiscoveryClient, type AuthioDiscoveryDocument, AuthioDiscoveryError, type AuthioEncryptionKey, AuthioError, type AuthioErrorResponse, type AuthioExternalAccount, AuthioGrantTypes, type AuthioIntrospectionResult, AuthioKeyManagementAlgorithms, AuthioOAuthErrors, type AuthioPrivateKeyInput, AuthioProtocolError, AuthioResourceAccess, AuthioResourceAccessClaims, type AuthioResourceAccessRole, type AuthioResourceAccessSource, AuthioScopes, type AuthioTokenClient, type AuthioTokenDecrypter, type AuthioTokenResponse, AuthioTokenTypes, type AuthioTypedWebhookEvent, type AuthioUserInfo, type AuthioWebhookAdminResourceData, type AuthioWebhookDataByType, type AuthioWebhookEvent, AuthioWebhookEventTypes, AuthioWebhookHeaders, type AuthioWebhookKeysRotatedData, type AuthioWebhookLoginData, type AuthioWebhookPingData, type AuthioWebhookTokenReuseDetectedData, type AuthioWebhookTokenRevokedData, type AuthioWebhookUserData, type AuthioWebhookUserLockedOutData, type AuthioWebhookUserSuspensionData, type AuthioWebhookVerificationFailure, type AuthioWebhookVerificationResult, asAdminResourceEvent, asKeysRotatedEvent, asLoginEvent, asPingEvent, asTokenReuseDetectedEvent, asTokenRevokedEvent, asUserEvent, asUserLockedOutEvent, asUserSuspensionEvent, computeWebhookSignatureHeader, createAuthioClient, createAuthioDiscoveryClient, createAuthioTokenDecrypter, escapeDataString, isAllowedUrl, isAuthioTokenEncrypted, isWebhookEventOfType, parseResourceAccess, parseResourceAccessClaim, parseWebhookEvent, resolveConnection, resolveIssuer, resourceAccessSourceOf, seconds, systemClock, toBasicAuthorization, toClientCredentialsToken, toScopeString, tryParseWebhookEvent, verifyWebhookSignature };
1627
+ export { type AuthioAccountCredential, type AuthioAccountCredentialKind, type AuthioAccountCredentialOptions, type AuthioAdminEnvelope, AuthioAdminError, type AuthioAdminFailure, type AuthioAdminNotification, type AuthioAdminSuccess, AuthioAsymmetricAlgorithms, type AuthioAuthorizationRequest, type AuthioAuthorizationResult, type AuthioAuthorizationTransaction, type AuthioAuthorizationUrl, type AuthioBearerChallenge, type AuthioCallOptions, AuthioCallbackError, type AuthioCallbackFailure, type AuthioCallerKind, AuthioCallerKinds, type AuthioCamelCase, type AuthioCamelCased, AuthioClaimTypes, type AuthioClient, AuthioClientAssertionAlgorithms, type AuthioClientAuthentication, type AuthioClientCredentialsCache, type AuthioClientCredentialsSettings, type AuthioClientCredentialsToken, type AuthioClientOptions, type AuthioClock, type AuthioCodeChallengeMethod, AuthioConfigurationError, type AuthioConnection, type AuthioConnectionChoice, type AuthioConnectionExchangeResult, type AuthioConnectionGranted, type AuthioConnectionOptions, type AuthioConnectionRefused, type AuthioConnectionRequired, type AuthioConnectionSelectionRequired, AuthioContentEncryptionAlgorithms, type AuthioCredentialForm, AuthioDefaults, type AuthioDeviceAuthorization, type AuthioDevicePollOutcome, type AuthioDiscoveryClient, type AuthioDiscoveryDocument, AuthioDiscoveryError, type AuthioEncryptionKey, type AuthioEncryptionKeySource, type AuthioEndSessionRequest, AuthioError, type AuthioErrorResponse, type AuthioExternalAccount, AuthioGrantTypes, type AuthioIdTokenClaims, type AuthioIntrospectionResult, type AuthioJwtExpectations, AuthioKeyManagementAlgorithms, AuthioLegacyKeyManagementAlgorithms, type AuthioLogoutToken, AuthioOAuthErrors, type AuthioPkcePair, type AuthioPrivateKeyInput, type AuthioPrompt, AuthioPrompts, AuthioProtocolError, AuthioResourceAccess, AuthioResourceAccessClaims, type AuthioResourceAccessRole, type AuthioResourceAccessSource, AuthioScopes, type AuthioSecretSource, type AuthioSigningKeys, type AuthioTokenClient, type AuthioTokenDecrypter, type AuthioTokenDecrypterOptions, type AuthioTokenFailure, type AuthioTokenResponse, AuthioTokenTypes, AuthioTokenValidationError, type AuthioTypedWebhookEvent, type AuthioUserInfo, type AuthioWebhookAdminResource, type AuthioWebhookAdminResourceData, type AuthioWebhookAttackDetected, type AuthioWebhookAttackDetectedData, type AuthioWebhookCredentialCompromised, type AuthioWebhookCredentialCompromisedData, type AuthioWebhookDataByType, type AuthioWebhookEvent, AuthioWebhookEventTypes, AuthioWebhookHeaders, type AuthioWebhookKeysRotated, type AuthioWebhookKeysRotatedData, type AuthioWebhookLogin, type AuthioWebhookLoginData, type AuthioWebhookPing, type AuthioWebhookPingData, type AuthioWebhookTokenReuseDetected, type AuthioWebhookTokenReuseDetectedData, type AuthioWebhookTokenRevoked, type AuthioWebhookTokenRevokedData, type AuthioWebhookUser, type AuthioWebhookUserData, type AuthioWebhookUserLockedOut, type AuthioWebhookUserLockedOutData, type AuthioWebhookUserSuspension, type AuthioWebhookUserSuspensionData, type AuthioWebhookVerificationFailure, type AuthioWebhookVerificationResult, asAdminResourceEvent, asAttackDetectedEvent, asCredentialCompromisedEvent, asKeysRotatedEvent, asLoginEvent, asPingEvent, asTokenReuseDetectedEvent, asTokenRevokedEvent, asUserEvent, asUserLockedOutEvent, asUserSuspensionEvent, computeAuthioTokenHash, computeWebhookSignatureHeader, createAuthioAccountCredential, createAuthioClient, createAuthioDiscoveryClient, createAuthioPkce, createAuthioSigningKeys, createAuthioTokenDecrypter, encryptionKeyFromFile, escapeDataString, isAllowedUrl, isAuthioTokenEncrypted, isKnownWebhookEventType, isWebhookEventOfType, parseAuthioAdminEnvelope, parseAuthioBearerChallenge, parseResourceAccess, parseResourceAccessClaim, parseWebhookEvent, randomValue, readAuthioAdminResponse, readWebhookEventData, resolveConnection, resolveIssuer, resourceAccessSourceOf, seconds, systemClock, toBasicAuthorization, toCamelCasedMembers, toClientCredentialsToken, toConnectionExchangeResult, toCredentialClientId, toDevicePollOutcome, toScopeString, toTokenValidationError, tryParseWebhookEvent, verifyAuthioJwt, verifyWebhookSignature };