@spfn/auth 0.3.0-beta.20 → 0.3.0-beta.21

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/server.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { A as AuthInitOptions, u as OAuthProvider, s as VerificationPurpose, N as NewPasskey, v as Passkey, q as PermissionCategory, w as AuthContext } from './machine-principals-BD4tnASp.js';
2
- export { x as ApproveDeviceAuthParams, y as AuthProfileOutcome, z as AuthProfileVerifier, B as ChangePasswordParams, E as CompletePasswordResetParams, G as CompleteSignupParams, H as ConfirmPasswordResetParams, d as ConfirmPasswordResetResult, J as ConfirmSignupLinkParams, C as ConfirmSignupLinkResult, M as DenyDeviceAuthParams, Q as DeviceAuthApprovedResult, T as DeviceAuthInfoParams, D as DeviceAuthInfoResult, W as DeviceAuthPendingResult, X as DeviceAuthPollResponseSchema, Y as DeviceNameSchema, Z as EmailSchema, _ as FingerprintSchema, $ as FinishPasskeyEnrollmentParams, F as FinishPasskeyEnrollmentResult, a0 as FinishPasskeyLoginParams, I as IssueOneTimeTokenResult, a1 as KEY_FINGERPRINT_PREFIX_LENGTH, a2 as KeyIdSchema, K as KeySummary, a3 as LoginParams, L as LoginResult, a4 as LogoutParams, a5 as MachinePrincipal, a6 as MachineVerifierRegistration, a7 as NativeVerifyOptions, a8 as NormalizedIdentity, l as OAuth2AuthorizationCodeIssued, a9 as OAuth2AuthorizeParams, k as OAuth2ConsentView, n as OAuth2GrantSummary, aa as OAuth2ScopeDescription, ab as OAuthCallbackParams, ac as OAuthCallbackResult, ad as OAuthCodeExchangeOptions, ae as OAuthNativeParams, i as OAuthNativeResult, af as OAuthStartParams, O as OAuthStartResult, ag as OAuthTokens, ah as PASSKEY_DEVICE_TYPES, ai as PASSKEY_LABEL_MAX_LENGTH, aj as PasskeyDeviceType, f as PasskeySummary, ak as PasswordSchema, al as PhoneSchema, am as PlatformSchema, an as PollDeviceAuthParams, ao as PollDeviceAuthResult, ap as PublicKeySchema, aq as RecentAuthenticationParams, ar as RegisterParams, as as RegisterPublicKeyParams, a as RegisterResult, at as RenamePasskeyParams, au as RequestPasswordResetParams, c as RequestPasswordResetResult, av as RequestSignupLinkParams, b as RequestSignupLinkResult, aw as RevokeAllKeysParams, h as RevokeAllKeysResult, ax as RevokeKeyParams, ay as RevokePasskeyParams, az as RotateKeyParams, g as RotateKeyResult, aA as SendVerificationCodeParams, S as SendVerificationCodeResult, aB as StartDeviceAuthParams, e as StartDeviceAuthResult, aC as StartPasskeyEnrollmentParams, aD as TargetTypeSchema, aE as UnlinkNotification, aF as UnlinkNotifyRejection, aG as UnlinkNotifyRequest, aH as UnlinkNotifyResult, aI as UserCodeSchema, V as VERIFICATION_PURPOSES, r as VERIFICATION_TARGET_TYPES, aJ as VerificationPurposeSchema, t as VerificationTargetType, aK as VerifyCodeParams, aL as VerifyCodeResult, aM as approveDeviceAuthService, aN as approveOAuth2AuthorizeService, aO as assertNotLastRecoveryCredential, aP as assertRecentAuthentication, m as authRouter, aQ as authenticate, aR as buildOAuthErrorUrl, aS as changePasswordService, aT as completePasswordResetService, aU as completeSignupService, aV as confirmPasswordResetService, aW as confirmSignupLinkService, aX as denyDeviceAuthService, aY as denyOAuth2AuthorizeService, aZ as describeOAuth2AuthorizeRequestService, a_ as finishPasskeyEnrollmentService, a$ as finishPasskeyLoginService, b0 as getDeviceAuthInfoService, b1 as getEnabledOAuthProviders, b2 as getGoogleAccessToken, b3 as getMachinePrincipal, b4 as getOAuthProvider, b5 as getRegisteredProviders, b6 as isOAuthProviderEnabled, b7 as issueOneTimeTokenService, b8 as listKeysService, b9 as listOAuth2GrantsService, ba as listPasskeysService, bb as loginService, bc as logoutService, bd as machineAuth, be as oauthCallbackService, bf as oauthNativeService, bg as oauthStartService, bh as oauthUnlinkNotifyService, bi as optionalAuth, bj as passkeys, bk as pollDeviceAuthService, bl as registerAuthProfile, bm as registerMachineVerifier, bn as registerOAuthProvider, bo as registerPublicKeyService, bp as registerService, bq as renamePasskeyService, br as requestPasswordResetService, bs as requestSignupLinkService, bt as requireEnabledProvider, bu as requireMachineScope, bv as resolveAuthenticatedUser, bw as revokeAllKeysService, bx as revokeAllOAuth2GrantsForUser, by as revokeKeyService, bz as revokeOAuth2GrantService, bA as revokePasskeyService, bB as rotateKeyService, bC as runAuthProfile, bD as selectAuthProfile, bE as sendVerificationCodeService, bF as startDeviceAuthService, bG as startPasskeyEnrollmentService, bH as startPasskeyLoginService, bI as verifyCodeService, bJ as verifyOneTimeTokenService } from './machine-principals-BD4tnASp.js';
1
+ import { A as AuthInitOptions, u as OAuthProvider, s as VerificationPurpose, N as NewPasskey, v as Passkey, q as PermissionCategory, w as AuthContext } from './machine-principals-B7N8gux0.js';
2
+ export { x as ApproveDeviceAuthParams, y as AuthDeletionCancelledPayload, z as AuthDeletionCompletedPayload, B as AuthDeletionRequestedPayload, E as AuthDeviceRegisteredPayload, G as AuthLoginPayload, H as AuthPasswordResetPayload, J as AuthProfileOutcome, M as AuthProfileVerifier, Q as AuthProviderSchema, T as AuthRegisterPayload, W as ChangePasswordParams, X as CompletePasswordResetParams, Y as CompleteSignupParams, Z as ConfirmPasswordResetParams, d as ConfirmPasswordResetResult, _ as ConfirmSignupLinkParams, C as ConfirmSignupLinkResult, $ as DenyDeviceAuthParams, a0 as DeviceAuthApprovedResult, a1 as DeviceAuthInfoParams, D as DeviceAuthInfoResult, a2 as DeviceAuthPendingResult, a3 as DeviceAuthPollResponseSchema, a4 as DeviceNameSchema, a5 as DeviceRegistrationChannel, a6 as EmailSchema, a7 as FingerprintSchema, a8 as FinishPasskeyEnrollmentParams, F as FinishPasskeyEnrollmentResult, a9 as FinishPasskeyLoginParams, aa as InvitationAcceptedPayload, ab as InvitationCreatedPayload, I as IssueOneTimeTokenResult, ac as KEY_FINGERPRINT_PREFIX_LENGTH, ad as KeyIdSchema, K as KeySummary, ae as LoginParams, L as LoginResult, af as LogoutParams, ag as MachinePrincipal, ah as MachineVerifierRegistration, ai as NativeVerifyOptions, aj as NormalizedIdentity, l as OAuth2AuthorizationCodeIssued, ak as OAuth2AuthorizeParams, k as OAuth2ConsentView, n as OAuth2GrantSummary, al as OAuth2ScopeDescription, am as OAuthCallbackParams, an as OAuthCallbackResult, ao as OAuthCodeExchangeOptions, ap as OAuthNativeParams, i as OAuthNativeResult, aq as OAuthStartParams, O as OAuthStartResult, ar as OAuthTokens, as as OAuthUnlinkedPayload, at as PASSKEY_DEVICE_TYPES, au as PASSKEY_LABEL_MAX_LENGTH, av as PasskeyDeviceType, f as PasskeySummary, aw as PasswordSchema, ax as PhoneSchema, ay as PlatformSchema, az as PollDeviceAuthParams, aA as PollDeviceAuthResult, aB as PublicKeySchema, aC as RecentAuthenticationParams, aD as RegisterParams, aE as RegisterPublicKeyParams, a as RegisterResult, aF as RenamePasskeyParams, aG as RequestPasswordResetParams, c as RequestPasswordResetResult, aH as RequestSignupLinkParams, b as RequestSignupLinkResult, aI as RevokeAllKeysParams, h as RevokeAllKeysResult, aJ as RevokeKeyParams, aK as RevokePasskeyParams, aL as RotateKeyParams, g as RotateKeyResult, aM as SendVerificationCodeParams, S as SendVerificationCodeResult, aN as StartDeviceAuthParams, e as StartDeviceAuthResult, aO as StartPasskeyEnrollmentParams, aP as TargetTypeSchema, aQ as UnlinkNotification, aR as UnlinkNotifyRejection, aS as UnlinkNotifyRequest, aT as UnlinkNotifyResult, aU as UserCodeSchema, V as VERIFICATION_PURPOSES, r as VERIFICATION_TARGET_TYPES, aV as VerificationPurposeSchema, t as VerificationTargetType, aW as VerifyCodeParams, aX as VerifyCodeResult, aY as approveDeviceAuthService, aZ as approveOAuth2AuthorizeService, a_ as assertNotLastRecoveryCredential, a$ as assertRecentAuthentication, b0 as authDeletionCancelledEvent, b1 as authDeletionCompletedEvent, b2 as authDeletionRequestedEvent, b3 as authDeviceRegisteredEvent, b4 as authLoginEvent, b5 as authPasswordResetEvent, b6 as authRegisterEvent, m as authRouter, b7 as authenticate, b8 as buildOAuthErrorUrl, b9 as changePasswordService, ba as completePasswordResetService, bb as completeSignupService, bc as confirmPasswordResetService, bd as confirmSignupLinkService, be as denyDeviceAuthService, bf as denyOAuth2AuthorizeService, bg as describeOAuth2AuthorizeRequestService, bh as finishPasskeyEnrollmentService, bi as finishPasskeyLoginService, bj as getDeviceAuthInfoService, bk as getEnabledOAuthProviders, bl as getGoogleAccessToken, bm as getMachinePrincipal, bn as getOAuthProvider, bo as getRegisteredProviders, bp as invitationAcceptedEvent, bq as invitationCreatedEvent, br as isOAuthProviderEnabled, bs as issueOneTimeTokenService, bt as listKeysService, bu as listOAuth2GrantsService, bv as listPasskeysService, bw as loginService, bx as logoutService, by as machineAuth, bz as oauthCallbackService, bA as oauthNativeService, bB as oauthStartService, bC as oauthUnlinkNotifyService, bD as oauthUnlinkedEvent, bE as optionalAuth, bF as passkeys, bG as pollDeviceAuthService, bH as registerAuthProfile, bI as registerMachineVerifier, bJ as registerOAuthProvider, bK as registerPublicKeyService, bL as registerService, bM as renamePasskeyService, bN as requestPasswordResetService, bO as requestSignupLinkService, bP as requireEnabledProvider, bQ as requireMachineScope, bR as resolveAuthenticatedUser, bS as revokeAllKeysService, bT as revokeAllOAuth2GrantsForUser, bU as revokeKeyService, bV as revokeOAuth2GrantService, bW as revokePasskeyService, bX as rotateKeyService, bY as runAuthProfile, bZ as selectAuthProfile, b_ as sendVerificationCodeService, b$ as startDeviceAuthService, c0 as startPasskeyEnrollmentService, c1 as startPasskeyLoginService, c2 as verifyCodeService, c3 as verifyOneTimeTokenService } from './machine-principals-B7N8gux0.js';
3
3
  import * as drizzle_orm_pg_core from 'drizzle-orm/pg-core';
4
4
  import { j as SocialProvider, K as KeyAlgorithmType, d as InvitationStatus, c as AccountDeletionRequestedBy, i as PurgeStrategy } from './types-DYyhze28.js';
5
5
  export { A as ACCOUNT_DELETION_REQUESTED_BY, a as ACCOUNT_DELETION_REQUEST_STATUSES, b as AccountDeletionRequestStatus, I as INVITATION_STATUSES, e as KEY_ALGORITHM, f as KEY_DEVICE_NAME_MAX_LENGTH, g as KEY_PLATFORM, h as KeyPlatformType, P as PURGE_STRATEGIES, S as SOCIAL_PROVIDERS, U as USER_STATUSES, k as UserStatus } from './types-DYyhze28.js';
@@ -15,12 +15,101 @@ import { JWTPayload } from 'jose';
15
15
  import { SSETokenManager, SSETokenStore } from '@spfn/core/event/sse';
16
16
  import * as _spfn_core_logger from '@spfn/core/logger';
17
17
  import * as _spfn_core_job from '@spfn/core/job';
18
- import * as _spfn_core_event from '@spfn/core/event';
19
- import * as _sinclair_typebox from '@sinclair/typebox';
20
18
  import '@simplewebauthn/server';
19
+ import '@sinclair/typebox';
20
+ import '@spfn/core/event';
21
21
  import '@spfn/auth/server';
22
22
  import 'jsonwebtoken';
23
23
 
24
+ /**
25
+ * @spfn/auth - Signed Sign-Out-Everywhere Link
26
+ *
27
+ * A link an app mails to an account's proven address, which signs every device
28
+ * of that account out without a session. It exists for the case the rest of the
29
+ * key surface cannot serve: the owner suspects a device they do not recognise,
30
+ * and the device they would have to sign in on to do something about it is the
31
+ * one they no longer trust.
32
+ *
33
+ * Three calls, and each is deliberately not the other two. `createRevokeAllLink`
34
+ * mints the capability and hands the app a URL. `describeRevokeAllLink` says
35
+ * whether that URL still works and changes nothing, so a mail scanner opening
36
+ * the page costs nothing. `consumeRevokeAllLink` is the only one that revokes,
37
+ * and it takes the owner pressing the button.
38
+ *
39
+ * The caller's obligation, which this package cannot enforce: the URL
40
+ * `createRevokeAllLink` returns carries the plaintext token, because the package
41
+ * sends no mail here. Do not log it, do not persist it, do not put it in a job
42
+ * payload — hand it to the mail template and let it go. Every other link in this
43
+ * package is minted inside the worker that sends it precisely so that no caller
44
+ * ever holds one; this one cannot be, and the obligation moves to the app.
45
+ */
46
+ interface CreateRevokeAllLinkOptions {
47
+ /**
48
+ * Minutes the link stays valid. Defaults to
49
+ * `SPFN_AUTH_REVOKE_ALL_LINK_TTL_MINUTES`, itself 30.
50
+ */
51
+ ttlMinutes?: number;
52
+ }
53
+ interface RevokeAllLink {
54
+ /** Absolute URL of the app page, token in its query string. Never log it. */
55
+ url: string;
56
+ expiresAt: Date;
57
+ }
58
+ /** What the describe call tells the page, so it can say what pressing the button does. */
59
+ interface RevokeAllLinkDescription {
60
+ expiresAt: Date;
61
+ activeKeyCount: number;
62
+ }
63
+ /**
64
+ * Mint a sign-out-everywhere link for an account.
65
+ *
66
+ * Issuing supersedes every live link the account already has, the rule the
67
+ * password-reset flow follows: an owner who asks twice must not leave the first
68
+ * capability working in their mailbox after using the second.
69
+ *
70
+ * The row records the account's key generation, so the link dies the moment any
71
+ * other path signs every device out — a password reset, a password change, a
72
+ * deletion request, or the ordinary revoke-all route.
73
+ *
74
+ * Send it beside a password reset link. It ends the sessions; it does not change
75
+ * the password that let them start.
76
+ *
77
+ * @param userId - The account to issue for
78
+ * @throws ValidationError `ttlMinutes` that is not a positive integer — no row is written
79
+ * @throws NotFoundError no such account, rather than a foreign-key failure at the insert
80
+ */
81
+ declare function createRevokeAllLink(userId: string | number, options?: CreateRevokeAllLinkOptions): Promise<RevokeAllLink>;
82
+ /**
83
+ * Say whether a presented link still works, and what pressing the button would
84
+ * do. Changes nothing — a mail scanner that opens the page has done nothing.
85
+ *
86
+ * @throws RevokeAllLinkError every refusal, in one shape
87
+ */
88
+ declare function describeRevokeAllLink(token: string): Promise<RevokeAllLinkDescription>;
89
+ /**
90
+ * Spend a link and sign every device of the account out.
91
+ *
92
+ * The claim is one statement, so of two requests carrying the same token exactly
93
+ * one revokes and the other is refused as if the token were unknown — which by
94
+ * then it is. `includeCurrent` is true because there is no current device here:
95
+ * the caller holds a mailbox, not a session, and sparing something would mean
96
+ * sparing whatever the owner is trying to cut off.
97
+ *
98
+ * @returns how many device keys were revoked; zero is a success, not a refusal
99
+ * @throws RevokeAllLinkError every refusal, in the same shape `describe` uses
100
+ */
101
+ declare function consumeRevokeAllLink(token: string): Promise<{
102
+ revokedCount: number;
103
+ }>;
104
+ /**
105
+ * Delete link rows that can no longer answer anything.
106
+ *
107
+ * @returns number of rows deleted
108
+ */
109
+ declare function purgeRevokeAllTokensService(): Promise<{
110
+ deleted: number;
111
+ }>;
112
+
24
113
  /**
25
114
  * @spfn/auth - Global Configuration
26
115
  *
@@ -553,6 +642,21 @@ declare const users: drizzle_orm_pg_core.PgTableWithColumns<{
553
642
  identity: undefined;
554
643
  generated: undefined;
555
644
  }>;
645
+ keyEpoch: drizzle_orm_pg_core.PgBuildColumn<"users", drizzle_orm_pg_core.SetHasDefault<drizzle_orm_pg_core.SetNotNull<drizzle_orm_pg_core.PgIntegerBuilder>>, {
646
+ name: string;
647
+ tableName: "users";
648
+ dataType: "number int32";
649
+ data: number;
650
+ driverParam: string | number;
651
+ notNull: true;
652
+ hasDefault: true;
653
+ isPrimaryKey: false;
654
+ isAutoincrement: false;
655
+ hasRuntimeDefault: false;
656
+ enumValues: undefined;
657
+ identity: undefined;
658
+ generated: undefined;
659
+ }>;
556
660
  lastLoginAt: drizzle_orm_pg_core.PgBuildColumn<"users", drizzle_orm_pg_core.PgTimestampBuilder, {
557
661
  name: string;
558
662
  tableName: "users";
@@ -599,6 +703,7 @@ declare function getUserByIdService(userId: number): Promise<{
599
703
  status: "active" | "inactive" | "suspended" | "pending_deletion" | "deleted";
600
704
  emailVerifiedAt: Date | null;
601
705
  phoneVerifiedAt: Date | null;
706
+ keyEpoch: number;
602
707
  lastLoginAt: Date | null;
603
708
  }>;
604
709
  /**
@@ -620,6 +725,7 @@ declare function getUserByEmailService(email: string): Promise<{
620
725
  status: "active" | "inactive" | "suspended" | "pending_deletion" | "deleted";
621
726
  emailVerifiedAt: Date | null;
622
727
  phoneVerifiedAt: Date | null;
728
+ keyEpoch: number;
623
729
  lastLoginAt: Date | null;
624
730
  }>;
625
731
  /**
@@ -641,6 +747,7 @@ declare function getUserByPhoneService(phone: string): Promise<{
641
747
  status: "active" | "inactive" | "suspended" | "pending_deletion" | "deleted";
642
748
  emailVerifiedAt: Date | null;
643
749
  phoneVerifiedAt: Date | null;
750
+ keyEpoch: number;
644
751
  lastLoginAt: Date | null;
645
752
  }>;
646
753
  /**
@@ -681,6 +788,7 @@ declare function updateUsernameService(userId: string | number | bigint, usernam
681
788
  status: "active" | "inactive" | "suspended" | "pending_deletion" | "deleted";
682
789
  emailVerifiedAt: Date | null;
683
790
  phoneVerifiedAt: Date | null;
791
+ keyEpoch: number;
684
792
  lastLoginAt: Date | null;
685
793
  }>;
686
794
 
@@ -1514,6 +1622,10 @@ declare function acceptInvitation(params: {
1514
1622
  keyId: string;
1515
1623
  fingerprint: string;
1516
1624
  algorithm: KeyAlgorithmType;
1625
+ /** Client address of the request, from `deviceProvenance` at the route. */
1626
+ ip?: string;
1627
+ /** `user-agent` of the request, already truncated at the route. */
1628
+ userAgent?: string;
1517
1629
  }): Promise<{
1518
1630
  userId: number;
1519
1631
  email: string;
@@ -3136,6 +3248,36 @@ declare const userPublicKeys: drizzle_orm_pg_core.PgTableWithColumns<{
3136
3248
  identity: undefined;
3137
3249
  generated: undefined;
3138
3250
  }>;
3251
+ registeredIp: drizzle_orm_pg_core.PgBuildColumn<"user_public_keys", drizzle_orm_pg_core.PgTextBuilder<[string, ...string[]]>, {
3252
+ name: string;
3253
+ tableName: "user_public_keys";
3254
+ dataType: "string";
3255
+ data: string;
3256
+ driverParam: string;
3257
+ notNull: false;
3258
+ hasDefault: false;
3259
+ isPrimaryKey: false;
3260
+ isAutoincrement: false;
3261
+ hasRuntimeDefault: false;
3262
+ enumValues: undefined;
3263
+ identity: undefined;
3264
+ generated: undefined;
3265
+ }>;
3266
+ registeredUserAgent: drizzle_orm_pg_core.PgBuildColumn<"user_public_keys", drizzle_orm_pg_core.PgTextBuilder<[string, ...string[]]>, {
3267
+ name: string;
3268
+ tableName: "user_public_keys";
3269
+ dataType: "string";
3270
+ data: string;
3271
+ driverParam: string;
3272
+ notNull: false;
3273
+ hasDefault: false;
3274
+ isPrimaryKey: false;
3275
+ isAutoincrement: false;
3276
+ hasRuntimeDefault: false;
3277
+ enumValues: undefined;
3278
+ identity: undefined;
3279
+ generated: undefined;
3280
+ }>;
3139
3281
  clientKind: drizzle_orm_pg_core.PgBuildColumn<"user_public_keys", drizzle_orm_pg_core.PgTextBuilder<["web", "ios", "android"] & [string, ...string[]]>, {
3140
3282
  name: string;
3141
3283
  tableName: "user_public_keys";
@@ -4050,6 +4192,169 @@ declare const passwordResetTokens: drizzle_orm_pg_core.PgTableWithColumns<{
4050
4192
  type PasswordResetToken = typeof passwordResetTokens.$inferSelect;
4051
4193
  type NewPasswordResetToken = typeof passwordResetTokens.$inferInsert;
4052
4194
 
4195
+ /**
4196
+ * @spfn/auth - Revoke-All Link Tokens Entity
4197
+ *
4198
+ * Backs the signed sign-out-everywhere link: a one-time token an app mails to
4199
+ * an account's proven address, which revokes every device key of that account
4200
+ * without a session. It is the action an owner can take from a mailbox when the
4201
+ * device they would otherwise have to sign in on is the one they no longer
4202
+ * trust.
4203
+ *
4204
+ * `key_epoch` is what makes the link dead rather than merely spent. It records
4205
+ * the account's key generation at issue time, and the consume statement joins it
4206
+ * against `users.key_epoch` — so a password reset, a password change, a deletion
4207
+ * request or an earlier revoke-all, every one of which moves the counter, leaves
4208
+ * the outstanding link answering the same 404 an unknown token gets.
4209
+ *
4210
+ * The token is a bearer credential, so only its SHA-256 hash is stored, the same
4211
+ * way the signup and reset links store theirs.
4212
+ */
4213
+ declare const keyRevokeAllTokens: drizzle_orm_pg_core.PgTableWithColumns<{
4214
+ name: "key_revoke_all_tokens";
4215
+ schema: string;
4216
+ columns: {
4217
+ createdAt: drizzle_orm_pg_core.PgBuildColumn<"key_revoke_all_tokens", drizzle_orm_pg_core.SetNotNull<drizzle_orm_pg_core.SetHasDefault<drizzle_orm_pg_core.PgTimestampBuilder>>, {
4218
+ name: string;
4219
+ tableName: "key_revoke_all_tokens";
4220
+ dataType: "object date";
4221
+ data: Date;
4222
+ driverParam: string;
4223
+ notNull: true;
4224
+ hasDefault: true;
4225
+ isPrimaryKey: false;
4226
+ isAutoincrement: false;
4227
+ hasRuntimeDefault: false;
4228
+ enumValues: undefined;
4229
+ identity: undefined;
4230
+ generated: undefined;
4231
+ }>;
4232
+ updatedAt: drizzle_orm_pg_core.PgBuildColumn<"key_revoke_all_tokens", drizzle_orm_pg_core.SetHasDefault<drizzle_orm_pg_core.SetNotNull<drizzle_orm_pg_core.SetHasDefault<drizzle_orm_pg_core.PgTimestampBuilder>>>, {
4233
+ name: string;
4234
+ tableName: "key_revoke_all_tokens";
4235
+ dataType: "object date";
4236
+ data: Date;
4237
+ driverParam: string;
4238
+ notNull: true;
4239
+ hasDefault: true;
4240
+ isPrimaryKey: false;
4241
+ isAutoincrement: false;
4242
+ hasRuntimeDefault: false;
4243
+ enumValues: undefined;
4244
+ identity: undefined;
4245
+ generated: undefined;
4246
+ }>;
4247
+ id: drizzle_orm_pg_core.PgBuildColumn<"key_revoke_all_tokens", drizzle_orm_pg_core.SetIsPrimaryKey<drizzle_orm_pg_core.PgBigSerial53Builder>, {
4248
+ name: string;
4249
+ tableName: "key_revoke_all_tokens";
4250
+ dataType: "number int53";
4251
+ data: number;
4252
+ driverParam: number;
4253
+ notNull: true;
4254
+ hasDefault: true;
4255
+ isPrimaryKey: false;
4256
+ isAutoincrement: false;
4257
+ hasRuntimeDefault: false;
4258
+ enumValues: undefined;
4259
+ identity: undefined;
4260
+ generated: undefined;
4261
+ }>;
4262
+ userId: drizzle_orm_pg_core.PgBuildColumn<"key_revoke_all_tokens", drizzle_orm_pg_core.SetNotNull<drizzle_orm_pg_core.PgBigInt53Builder>, {
4263
+ name: string;
4264
+ tableName: "key_revoke_all_tokens";
4265
+ dataType: "number int53";
4266
+ data: number;
4267
+ driverParam: string | number;
4268
+ notNull: true;
4269
+ hasDefault: false;
4270
+ isPrimaryKey: false;
4271
+ isAutoincrement: false;
4272
+ hasRuntimeDefault: false;
4273
+ enumValues: undefined;
4274
+ identity: undefined;
4275
+ generated: undefined;
4276
+ }>;
4277
+ tokenHash: drizzle_orm_pg_core.PgBuildColumn<"key_revoke_all_tokens", drizzle_orm_pg_core.SetNotNull<drizzle_orm_pg_core.PgTextBuilder<[string, ...string[]]>>, {
4278
+ name: string;
4279
+ tableName: "key_revoke_all_tokens";
4280
+ dataType: "string";
4281
+ data: string;
4282
+ driverParam: string;
4283
+ notNull: true;
4284
+ hasDefault: false;
4285
+ isPrimaryKey: false;
4286
+ isAutoincrement: false;
4287
+ hasRuntimeDefault: false;
4288
+ enumValues: undefined;
4289
+ identity: undefined;
4290
+ generated: undefined;
4291
+ }>;
4292
+ keyEpoch: drizzle_orm_pg_core.PgBuildColumn<"key_revoke_all_tokens", drizzle_orm_pg_core.SetNotNull<drizzle_orm_pg_core.PgIntegerBuilder>, {
4293
+ name: string;
4294
+ tableName: "key_revoke_all_tokens";
4295
+ dataType: "number int32";
4296
+ data: number;
4297
+ driverParam: string | number;
4298
+ notNull: true;
4299
+ hasDefault: false;
4300
+ isPrimaryKey: false;
4301
+ isAutoincrement: false;
4302
+ hasRuntimeDefault: false;
4303
+ enumValues: undefined;
4304
+ identity: undefined;
4305
+ generated: undefined;
4306
+ }>;
4307
+ expiresAt: drizzle_orm_pg_core.PgBuildColumn<"key_revoke_all_tokens", drizzle_orm_pg_core.SetNotNull<drizzle_orm_pg_core.PgTimestampBuilder>, {
4308
+ name: string;
4309
+ tableName: "key_revoke_all_tokens";
4310
+ dataType: "object date";
4311
+ data: Date;
4312
+ driverParam: string;
4313
+ notNull: true;
4314
+ hasDefault: false;
4315
+ isPrimaryKey: false;
4316
+ isAutoincrement: false;
4317
+ hasRuntimeDefault: false;
4318
+ enumValues: undefined;
4319
+ identity: undefined;
4320
+ generated: undefined;
4321
+ }>;
4322
+ consumedAt: drizzle_orm_pg_core.PgBuildColumn<"key_revoke_all_tokens", drizzle_orm_pg_core.PgTimestampBuilder, {
4323
+ name: string;
4324
+ tableName: "key_revoke_all_tokens";
4325
+ dataType: "object date";
4326
+ data: Date;
4327
+ driverParam: string;
4328
+ notNull: false;
4329
+ hasDefault: false;
4330
+ isPrimaryKey: false;
4331
+ isAutoincrement: false;
4332
+ hasRuntimeDefault: false;
4333
+ enumValues: undefined;
4334
+ identity: undefined;
4335
+ generated: undefined;
4336
+ }>;
4337
+ supersededAt: drizzle_orm_pg_core.PgBuildColumn<"key_revoke_all_tokens", drizzle_orm_pg_core.PgTimestampBuilder, {
4338
+ name: string;
4339
+ tableName: "key_revoke_all_tokens";
4340
+ dataType: "object date";
4341
+ data: Date;
4342
+ driverParam: string;
4343
+ notNull: false;
4344
+ hasDefault: false;
4345
+ isPrimaryKey: false;
4346
+ isAutoincrement: false;
4347
+ hasRuntimeDefault: false;
4348
+ enumValues: undefined;
4349
+ identity: undefined;
4350
+ generated: undefined;
4351
+ }>;
4352
+ };
4353
+ dialect: "pg";
4354
+ }>;
4355
+ type KeyRevokeAllToken = typeof keyRevokeAllTokens.$inferSelect;
4356
+ type NewKeyRevokeAllToken = typeof keyRevokeAllTokens.$inferInsert;
4357
+
4053
4358
  /**
4054
4359
  * @spfn/auth - WebAuthn Challenges Entity
4055
4360
  *
@@ -5657,6 +5962,7 @@ declare class UsersRepository extends BaseRepository {
5657
5962
  status: "active" | "inactive" | "suspended" | "pending_deletion" | "deleted";
5658
5963
  emailVerifiedAt: Date | null;
5659
5964
  phoneVerifiedAt: Date | null;
5965
+ keyEpoch: number;
5660
5966
  lastLoginAt: Date | null;
5661
5967
  }>;
5662
5968
  /**
@@ -5682,6 +5988,7 @@ declare class UsersRepository extends BaseRepository {
5682
5988
  status: "active" | "inactive" | "suspended" | "pending_deletion" | "deleted";
5683
5989
  emailVerifiedAt: Date | null;
5684
5990
  phoneVerifiedAt: Date | null;
5991
+ keyEpoch: number;
5685
5992
  lastLoginAt: Date | null;
5686
5993
  }>;
5687
5994
  /**
@@ -5718,6 +6025,7 @@ declare class UsersRepository extends BaseRepository {
5718
6025
  status: "active" | "inactive" | "suspended" | "pending_deletion" | "deleted";
5719
6026
  emailVerifiedAt: Date | null;
5720
6027
  phoneVerifiedAt: Date | null;
6028
+ keyEpoch: number;
5721
6029
  lastLoginAt: Date | null;
5722
6030
  }>;
5723
6031
  /**
@@ -5750,6 +6058,7 @@ declare class UsersRepository extends BaseRepository {
5750
6058
  status: "active" | "inactive" | "suspended" | "pending_deletion" | "deleted";
5751
6059
  emailVerifiedAt: Date | null;
5752
6060
  phoneVerifiedAt: Date | null;
6061
+ keyEpoch: number;
5753
6062
  lastLoginAt: Date | null;
5754
6063
  }>;
5755
6064
  /**
@@ -5772,6 +6081,7 @@ declare class UsersRepository extends BaseRepository {
5772
6081
  status: "active" | "inactive" | "suspended" | "pending_deletion" | "deleted";
5773
6082
  emailVerifiedAt: Date | null;
5774
6083
  phoneVerifiedAt: Date | null;
6084
+ keyEpoch: number;
5775
6085
  lastLoginAt: Date | null;
5776
6086
  }>;
5777
6087
  /**
@@ -5794,6 +6104,7 @@ declare class UsersRepository extends BaseRepository {
5794
6104
  status: "active" | "inactive" | "suspended" | "pending_deletion" | "deleted";
5795
6105
  emailVerifiedAt: Date | null;
5796
6106
  phoneVerifiedAt: Date | null;
6107
+ keyEpoch: number;
5797
6108
  lastLoginAt: Date | null;
5798
6109
  }>;
5799
6110
  /**
@@ -5816,6 +6127,7 @@ declare class UsersRepository extends BaseRepository {
5816
6127
  status: "active" | "inactive" | "suspended" | "pending_deletion" | "deleted";
5817
6128
  emailVerifiedAt: Date | null;
5818
6129
  phoneVerifiedAt: Date | null;
6130
+ keyEpoch: number;
5819
6131
  lastLoginAt: Date | null;
5820
6132
  }>;
5821
6133
  /**
@@ -5838,6 +6150,7 @@ declare class UsersRepository extends BaseRepository {
5838
6150
  status: "active" | "inactive" | "suspended" | "pending_deletion" | "deleted";
5839
6151
  emailVerifiedAt: Date | null;
5840
6152
  phoneVerifiedAt: Date | null;
6153
+ keyEpoch: number;
5841
6154
  lastLoginAt: Date | null;
5842
6155
  } | null>;
5843
6156
  /**
@@ -5863,6 +6176,7 @@ declare class UsersRepository extends BaseRepository {
5863
6176
  status: "active" | "inactive" | "suspended" | "pending_deletion" | "deleted";
5864
6177
  emailVerifiedAt: Date | null;
5865
6178
  phoneVerifiedAt: Date | null;
6179
+ keyEpoch: number;
5866
6180
  lastLoginAt: Date | null;
5867
6181
  };
5868
6182
  role: {
@@ -5889,6 +6203,7 @@ declare class UsersRepository extends BaseRepository {
5889
6203
  updatedAt: Date;
5890
6204
  emailVerifiedAt: Date | null;
5891
6205
  phoneVerifiedAt: Date | null;
6206
+ keyEpoch: number;
5892
6207
  lastLoginAt: Date | null;
5893
6208
  deletedAt: Date | null;
5894
6209
  deletedBy: string | null;
@@ -5958,6 +6273,7 @@ declare class UsersRepository extends BaseRepository {
5958
6273
  status: "active" | "inactive" | "suspended" | "pending_deletion" | "deleted";
5959
6274
  emailVerifiedAt: Date | null;
5960
6275
  phoneVerifiedAt: Date | null;
6276
+ keyEpoch: number;
5961
6277
  lastLoginAt: Date | null;
5962
6278
  }>;
5963
6279
  /**
@@ -5985,6 +6301,7 @@ declare class UsersRepository extends BaseRepository {
5985
6301
  status: "active" | "inactive" | "suspended" | "pending_deletion" | "deleted";
5986
6302
  emailVerifiedAt: Date | null;
5987
6303
  phoneVerifiedAt: Date | null;
6304
+ keyEpoch: number;
5988
6305
  lastLoginAt: Date | null;
5989
6306
  }>;
5990
6307
  /**
@@ -6007,6 +6324,7 @@ declare class UsersRepository extends BaseRepository {
6007
6324
  status: "active" | "inactive" | "suspended" | "pending_deletion" | "deleted";
6008
6325
  emailVerifiedAt: Date | null;
6009
6326
  phoneVerifiedAt: Date | null;
6327
+ keyEpoch: number;
6010
6328
  lastLoginAt: Date | null;
6011
6329
  }>;
6012
6330
  /**
@@ -6029,6 +6347,7 @@ declare class UsersRepository extends BaseRepository {
6029
6347
  status: "active" | "inactive" | "suspended" | "pending_deletion" | "deleted";
6030
6348
  emailVerifiedAt: Date | null;
6031
6349
  phoneVerifiedAt: Date | null;
6350
+ keyEpoch: number;
6032
6351
  lastLoginAt: Date | null;
6033
6352
  }>;
6034
6353
  /**
@@ -6049,6 +6368,7 @@ declare class UsersRepository extends BaseRepository {
6049
6368
  updatedAt: Date;
6050
6369
  emailVerifiedAt: Date | null;
6051
6370
  phoneVerifiedAt: Date | null;
6371
+ keyEpoch: number;
6052
6372
  lastLoginAt: Date | null;
6053
6373
  deletedAt: Date | null;
6054
6374
  deletedBy: string | null;
@@ -6118,6 +6438,16 @@ declare const usersRepository: UsersRepository;
6118
6438
  * BaseRepository를 상속받아 자동 트랜잭션 컨텍스트 지원 및 Read/Write 분리
6119
6439
  */
6120
6440
 
6441
+ /**
6442
+ * What a global revocation answers with.
6443
+ *
6444
+ * The key id and nothing else: every caller counts the rows or names them, and
6445
+ * the statement that produces them revokes keys and moves the account's key
6446
+ * generation at once, which a typed Drizzle update cannot express.
6447
+ */
6448
+ interface RevokedKey {
6449
+ keyId: string;
6450
+ }
6121
6451
  /**
6122
6452
  * User Public Keys Repository 클래스
6123
6453
  *
@@ -6140,6 +6470,8 @@ declare class KeysRepository extends BaseRepository {
6140
6470
  fingerprint: string;
6141
6471
  deviceName: string | null;
6142
6472
  platform: "ios" | "android" | "web" | "desktop" | null;
6473
+ registeredIp: string | null;
6474
+ registeredUserAgent: string | null;
6143
6475
  clientKind: "ios" | "android" | "web" | null;
6144
6476
  clientVersion: string | null;
6145
6477
  clientContractVersion: string | null;
@@ -6164,6 +6496,8 @@ declare class KeysRepository extends BaseRepository {
6164
6496
  fingerprint: string;
6165
6497
  deviceName: string | null;
6166
6498
  platform: "ios" | "android" | "web" | "desktop" | null;
6499
+ registeredIp: string | null;
6500
+ registeredUserAgent: string | null;
6167
6501
  clientKind: "ios" | "android" | "web" | null;
6168
6502
  clientVersion: string | null;
6169
6503
  clientContractVersion: string | null;
@@ -6188,6 +6522,8 @@ declare class KeysRepository extends BaseRepository {
6188
6522
  fingerprint: string;
6189
6523
  deviceName: string | null;
6190
6524
  platform: "ios" | "android" | "web" | "desktop" | null;
6525
+ registeredIp: string | null;
6526
+ registeredUserAgent: string | null;
6191
6527
  clientKind: "ios" | "android" | "web" | null;
6192
6528
  clientVersion: string | null;
6193
6529
  clientContractVersion: string | null;
@@ -6220,6 +6556,8 @@ declare class KeysRepository extends BaseRepository {
6220
6556
  lastUsedAt: Date | null;
6221
6557
  expiresAt: Date | null;
6222
6558
  revokedAt: Date | null;
6559
+ registeredIp: string | null;
6560
+ registeredUserAgent: string | null;
6223
6561
  }[]>;
6224
6562
  /**
6225
6563
  * 공개키 생성
@@ -6233,12 +6571,14 @@ declare class KeysRepository extends BaseRepository {
6233
6571
  deviceName: string | null;
6234
6572
  platform: "ios" | "android" | "web" | "desktop" | null;
6235
6573
  userId: number;
6574
+ expiresAt: Date | null;
6236
6575
  id: number;
6237
6576
  isActive: boolean;
6238
6577
  createdAt: Date;
6239
- expiresAt: Date | null;
6240
6578
  revokedAt: Date | null;
6241
6579
  lastUsedAt: Date | null;
6580
+ registeredIp: string | null;
6581
+ registeredUserAgent: string | null;
6242
6582
  clientKind: "ios" | "android" | "web" | null;
6243
6583
  clientVersion: string | null;
6244
6584
  clientContractVersion: string | null;
@@ -6246,7 +6586,13 @@ declare class KeysRepository extends BaseRepository {
6246
6586
  revokedReason: string | null;
6247
6587
  }>;
6248
6588
  /**
6249
- * 공개키 revoke (비활성화)
6589
+ * 공개키 revoke (비활성화) — 아직 살아 있는 키만
6590
+ *
6591
+ * `isActive`가 조건에 있어야 반환값이 "이 호출이 무언가를 폐기했는가"를 뜻한다.
6592
+ * 없으면 이미 폐기된 키를 다시 지목해도 행이 하나 돌아와, 호출자는 폐기가
6593
+ * 일어났다고 읽는다. 로그인 경로가 그 값으로 "기기 교체인가 새 기기인가"를
6594
+ * 가르므로, 죽은 키를 들이밀어 새 기기 알림을 끄는 길이 된다.
6595
+ * 폐기 시각·사유도 덮어쓰지 않는다 — 처음 끊긴 순간이 답이다.
6250
6596
  * Write primary 사용
6251
6597
  */
6252
6598
  revokeByKeyIdAndUserId(keyId: string, userId: number, reason: string): Promise<{
@@ -6258,6 +6604,8 @@ declare class KeysRepository extends BaseRepository {
6258
6604
  fingerprint: string;
6259
6605
  deviceName: string | null;
6260
6606
  platform: "ios" | "android" | "web" | "desktop" | null;
6607
+ registeredIp: string | null;
6608
+ registeredUserAgent: string | null;
6261
6609
  clientKind: "ios" | "android" | "web" | null;
6262
6610
  clientVersion: string | null;
6263
6611
  clientContractVersion: string | null;
@@ -6270,59 +6618,37 @@ declare class KeysRepository extends BaseRepository {
6270
6618
  revokedReason: string | null;
6271
6619
  }>;
6272
6620
  /**
6273
- * 사용자의 모든 활성 공개키 revoke (비활성화)
6621
+ * 사용자의 모든 활성 공개키 revoke (비활성화) — 그리고 같은 문장에서 key_epoch +1
6274
6622
  *
6275
6623
  * 비번 변경 시 전체 세션 로그아웃에 사용. authenticate는 활성 키만 검증하므로,
6276
6624
  * revoke된 키로 서명한 기존 세션의 요청은 즉시 401이 된다.
6277
6625
  * Write primary 사용
6278
6626
  */
6279
- revokeAllActiveByUserId(userId: number, reason: string): Promise<{
6280
- id: number;
6281
- userId: number;
6282
- keyId: string;
6283
- publicKey: string;
6284
- algorithm: "ES256" | "RS256";
6285
- fingerprint: string;
6286
- deviceName: string | null;
6287
- platform: "ios" | "android" | "web" | "desktop" | null;
6288
- clientKind: "ios" | "android" | "web" | null;
6289
- clientVersion: string | null;
6290
- clientContractVersion: string | null;
6291
- clientSeenAt: Date | null;
6292
- isActive: boolean;
6293
- createdAt: Date;
6294
- lastUsedAt: Date | null;
6295
- expiresAt: Date | null;
6296
- revokedAt: Date | null;
6297
- revokedReason: string | null;
6298
- }[]>;
6627
+ revokeAllActiveByUserId(userId: number, reason: string): Promise<RevokedKey[]>;
6299
6628
  /**
6300
- * 지정한 키 하나만 남기고 사용자의 활성 공개키를 전부 revoke
6629
+ * 지정한 키 하나만 남기고 사용자의 활성 공개키를 전부 revoke — key_epoch도 +1
6301
6630
  *
6302
6631
  * "다른 기기 전부 로그아웃" — 요청을 보낸 기기는 살려 둔다. 남길 키를 별도 조회로
6303
6632
  * 확인하지 않고 조건에 담아, 그 사이에 다른 요청이 키를 바꾸는 경쟁을 만들지 않는다.
6633
+ *
6634
+ * 한 기기를 남기더라도 epoch는 오른다. 미소비 revoke-all 링크가 죽는 쪽이 보수적이고,
6635
+ * 사용자가 "나머지 전부 로그아웃"을 이미 눌렀다면 메일함의 링크는 목적을 다했다.
6304
6636
  * Write primary 사용
6305
6637
  */
6306
- revokeAllActiveByUserIdExcept(userId: number, keepKeyId: string, reason: string): Promise<{
6307
- id: number;
6308
- userId: number;
6309
- keyId: string;
6310
- publicKey: string;
6311
- algorithm: "ES256" | "RS256";
6312
- fingerprint: string;
6313
- deviceName: string | null;
6314
- platform: "ios" | "android" | "web" | "desktop" | null;
6315
- clientKind: "ios" | "android" | "web" | null;
6316
- clientVersion: string | null;
6317
- clientContractVersion: string | null;
6318
- clientSeenAt: Date | null;
6319
- isActive: boolean;
6320
- createdAt: Date;
6321
- lastUsedAt: Date | null;
6322
- expiresAt: Date | null;
6323
- revokedAt: Date | null;
6324
- revokedReason: string | null;
6325
- }[]>;
6638
+ revokeAllActiveByUserIdExcept(userId: number, keepKeyId: string, reason: string): Promise<RevokedKey[]>;
6639
+ /**
6640
+ * The one statement behind both global revocations.
6641
+ *
6642
+ * The epoch bump is a data-modifying CTE on the same statement rather than a
6643
+ * second call, so that no caller can revoke every key and forget to move the
6644
+ * counter — and three of the four callers are services that never see the
6645
+ * counter at all. It runs whether or not any key matched: an account with no
6646
+ * active keys still had its generation ended, and an outstanding
6647
+ * sign-out-everywhere link must die with it.
6648
+ *
6649
+ * Write primary 사용
6650
+ */
6651
+ private revokeActive;
6326
6652
  /**
6327
6653
  * 공개키 삭제
6328
6654
  * Write primary 사용
@@ -6335,12 +6661,14 @@ declare class KeysRepository extends BaseRepository {
6335
6661
  deviceName: string | null;
6336
6662
  platform: "ios" | "android" | "web" | "desktop" | null;
6337
6663
  userId: number;
6664
+ expiresAt: Date | null;
6338
6665
  id: number;
6339
6666
  isActive: boolean;
6340
6667
  createdAt: Date;
6341
- expiresAt: Date | null;
6342
6668
  revokedAt: Date | null;
6343
6669
  lastUsedAt: Date | null;
6670
+ registeredIp: string | null;
6671
+ registeredUserAgent: string | null;
6344
6672
  clientKind: "ios" | "android" | "web" | null;
6345
6673
  clientVersion: string | null;
6346
6674
  clientContractVersion: string | null;
@@ -6368,6 +6696,8 @@ declare class KeysRepository extends BaseRepository {
6368
6696
  fingerprint: string;
6369
6697
  deviceName: string | null;
6370
6698
  platform: "ios" | "android" | "web" | "desktop" | null;
6699
+ registeredIp: string | null;
6700
+ registeredUserAgent: string | null;
6371
6701
  clientKind: "ios" | "android" | "web" | null;
6372
6702
  clientVersion: string | null;
6373
6703
  clientContractVersion: string | null;
@@ -6392,6 +6722,8 @@ declare class KeysRepository extends BaseRepository {
6392
6722
  fingerprint: string;
6393
6723
  deviceName: string | null;
6394
6724
  platform: "ios" | "android" | "web" | "desktop" | null;
6725
+ registeredIp: string | null;
6726
+ registeredUserAgent: string | null;
6395
6727
  clientKind: "ios" | "android" | "web" | null;
6396
6728
  clientVersion: string | null;
6397
6729
  clientContractVersion: string | null;
@@ -6419,6 +6751,8 @@ declare class KeysRepository extends BaseRepository {
6419
6751
  fingerprint: string;
6420
6752
  deviceName: string | null;
6421
6753
  platform: "ios" | "android" | "web" | "desktop" | null;
6754
+ registeredIp: string | null;
6755
+ registeredUserAgent: string | null;
6422
6756
  clientKind: "ios" | "android" | "web" | null;
6423
6757
  clientVersion: string | null;
6424
6758
  clientContractVersion: string | null;
@@ -6443,6 +6777,8 @@ declare class KeysRepository extends BaseRepository {
6443
6777
  fingerprint: string;
6444
6778
  deviceName: string | null;
6445
6779
  platform: "ios" | "android" | "web" | "desktop" | null;
6780
+ registeredIp: string | null;
6781
+ registeredUserAgent: string | null;
6446
6782
  clientKind: "ios" | "android" | "web" | null;
6447
6783
  clientVersion: string | null;
6448
6784
  clientContractVersion: string | null;
@@ -6536,10 +6872,10 @@ declare class VerificationCodesRepository extends BaseRepository {
6536
6872
  targetType: "email" | "phone";
6537
6873
  purpose: "registration" | "login" | "password_reset" | "email_change" | "phone_change" | "account_deletion";
6538
6874
  code: string;
6875
+ expiresAt: Date;
6539
6876
  id: number;
6540
6877
  createdAt: Date;
6541
6878
  updatedAt: Date;
6542
- expiresAt: Date;
6543
6879
  usedAt: Date | null;
6544
6880
  attempts: number;
6545
6881
  }>;
@@ -6778,6 +7114,86 @@ declare class PasswordResetTokensRepository extends BaseRepository {
6778
7114
  }
6779
7115
  declare const passwordResetTokensRepository: PasswordResetTokensRepository;
6780
7116
 
7117
+ /**
7118
+ * Revoke-All Link Tokens Repository
7119
+ *
7120
+ * Data access for the signed sign-out-everywhere link. Extends BaseRepository
7121
+ * for transaction-context detection and read/write splitting.
7122
+ *
7123
+ * `consume` is one statement and returns the account only if THIS call was the
7124
+ * one that spent the link. Two requests arriving with the same token therefore
7125
+ * produce one revocation and one refusal, rather than both reading an unspent
7126
+ * row and both proceeding — a read-then-write would lose that race, and the
7127
+ * race is the interesting one for a credential sitting in a mailbox.
7128
+ *
7129
+ * Every lookup filters to a usable row rather than returning whatever it finds.
7130
+ * Unknown, expired, spent, superseded, out of generation and not-an-active-
7131
+ * account are one refusal to the caller, so there is nothing to learn from
7132
+ * telling them apart — and a filter in the statement cannot be forgotten the
7133
+ * way a state check can.
7134
+ */
7135
+
7136
+ /** What a live link says about itself, for the describe call that changes nothing. */
7137
+ interface LiveRevokeAllLink {
7138
+ userId: number;
7139
+ expiresAt: Date;
7140
+ }
7141
+ declare class KeyRevokeAllTokensRepository extends BaseRepository {
7142
+ /**
7143
+ * Write an issued link row.
7144
+ * Write primary.
7145
+ */
7146
+ create(data: NewKeyRevokeAllToken): Promise<KeyRevokeAllToken>;
7147
+ /**
7148
+ * Supersede every live link for an account, so issuing a new one retires the
7149
+ * previous one rather than leaving two capabilities in a mailbox.
7150
+ *
7151
+ * Write primary.
7152
+ *
7153
+ * @returns number of rows superseded
7154
+ */
7155
+ supersedeAllLiveByUserId(userId: number): Promise<number>;
7156
+ /**
7157
+ * Find a link that could still be spent right now, without spending it.
7158
+ *
7159
+ * Joined to the account on both the generation and an active status, so the
7160
+ * describe call answers exactly what consume would: a link issued before a
7161
+ * password reset, or for an account since suspended or anonymized, is not
7162
+ * live here either.
7163
+ *
7164
+ * Read replica.
7165
+ */
7166
+ findLiveByTokenHash(tokenHash: string): Promise<LiveRevokeAllLink | null>;
7167
+ /**
7168
+ * Spend a link, and answer with the account it belonged to.
7169
+ *
7170
+ * One UPDATE with every condition in it and `RETURNING`, rather than a read
7171
+ * and a write: the row is claimed by whichever request the database serves
7172
+ * first, and the other matches nothing. Nothing opens a transaction around
7173
+ * it, so the claim is not held open across the revocation that follows.
7174
+ *
7175
+ * Write primary.
7176
+ *
7177
+ * @returns the account id, or null if the link was not spendable by this call
7178
+ */
7179
+ consume(tokenHash: string): Promise<number | null>;
7180
+ /**
7181
+ * Delete rows nothing can be learned from any more.
7182
+ *
7183
+ * Two ages, because the two states stop mattering at different times. An
7184
+ * expired row is kept a week so a support question about a link that was
7185
+ * mailed can still be answered; a spent or superseded one is kept a day,
7186
+ * since the refusal it produces is already indistinguishable from the one an
7187
+ * unknown token gets and the row is only bookkeeping after that.
7188
+ *
7189
+ * Write primary.
7190
+ *
7191
+ * @returns number of rows deleted
7192
+ */
7193
+ purge(expiredBefore: Date, settledBefore: Date): Promise<number>;
7194
+ }
7195
+ declare const keyRevokeAllTokensRepository: KeyRevokeAllTokensRepository;
7196
+
6781
7197
  /**
6782
7198
  * Passkeys Repository
6783
7199
  *
@@ -7352,12 +7768,12 @@ declare class UserPermissionsRepository extends BaseRepository {
7352
7768
  */
7353
7769
  create(data: NewUserPermission): Promise<{
7354
7770
  userId: number;
7771
+ expiresAt: Date | null;
7355
7772
  id: number;
7356
7773
  createdAt: Date;
7357
7774
  updatedAt: Date;
7358
7775
  permissionId: number;
7359
7776
  reason: string | null;
7360
- expiresAt: Date | null;
7361
7777
  granted: boolean;
7362
7778
  }>;
7363
7779
  /**
@@ -7378,12 +7794,12 @@ declare class UserPermissionsRepository extends BaseRepository {
7378
7794
  */
7379
7795
  deleteByUserIdAndPermissionId(userId: number, permissionId: number): Promise<{
7380
7796
  userId: number;
7797
+ expiresAt: Date | null;
7381
7798
  id: number;
7382
7799
  createdAt: Date;
7383
7800
  updatedAt: Date;
7384
7801
  permissionId: number;
7385
7802
  reason: string | null;
7386
- expiresAt: Date | null;
7387
7803
  granted: boolean;
7388
7804
  }>;
7389
7805
  /**
@@ -7728,12 +8144,12 @@ declare class InvitationsRepository extends BaseRepository {
7728
8144
  metadata: Record<string, any> | null;
7729
8145
  token: string;
7730
8146
  status: "pending" | "accepted" | "expired" | "cancelled";
8147
+ expiresAt: Date;
7731
8148
  id: number;
7732
8149
  roleId: number;
7733
8150
  createdAt: Date;
7734
8151
  updatedAt: Date;
7735
8152
  invitedBy: number;
7736
- expiresAt: Date;
7737
8153
  acceptedAt: Date | null;
7738
8154
  cancelledAt: Date | null;
7739
8155
  }>;
@@ -7762,12 +8178,12 @@ declare class InvitationsRepository extends BaseRepository {
7762
8178
  metadata: Record<string, any> | null;
7763
8179
  token: string;
7764
8180
  status: "pending" | "accepted" | "expired" | "cancelled";
8181
+ expiresAt: Date;
7765
8182
  id: number;
7766
8183
  roleId: number;
7767
8184
  createdAt: Date;
7768
8185
  updatedAt: Date;
7769
8186
  invitedBy: number;
7770
- expiresAt: Date;
7771
8187
  acceptedAt: Date | null;
7772
8188
  cancelledAt: Date | null;
7773
8189
  }>;
@@ -9092,6 +9508,7 @@ declare function getUser(c: Context | {
9092
9508
  updatedAt: Date;
9093
9509
  emailVerifiedAt: Date | null;
9094
9510
  phoneVerifiedAt: Date | null;
9511
+ keyEpoch: number;
9095
9512
  lastLoginAt: Date | null;
9096
9513
  deletedAt: Date | null;
9097
9514
  deletedBy: string | null;
@@ -9973,6 +10390,34 @@ declare function createAuthLifecycle(options?: AuthLifecycleOptions): AuthLifecy
9973
10390
  */
9974
10391
  declare function createAuthDeletionPurgeJob(cronExpression?: string): _spfn_core_job.JobDef<void, void>;
9975
10392
 
10393
+ /**
10394
+ * @spfn/auth - Revoke-All Link Token Purge Job
10395
+ *
10396
+ * `key_revoke_all_tokens` gains a row every time an app issues a
10397
+ * sign-out-everywhere link, and a row that can no longer answer anything is
10398
+ * only storage. This sweep deletes them.
10399
+ *
10400
+ * Two ages, because the two states stop mattering at different times. An expired
10401
+ * row is kept a week, so a support question about a link that was mailed can
10402
+ * still be answered from the table. A spent or superseded one is kept a day: the
10403
+ * refusal it produces is already indistinguishable from the one an unknown token
10404
+ * gets, so after that it is bookkeeping.
10405
+ *
10406
+ * Registration is NOT automatic, for the reason `deletion-purge.ts` sets out at
10407
+ * length: `createAuthLifecycle()`'s `afterInfrastructure` hook runs before
10408
+ * `registerJobs` in `@spfn/core`'s startup, so the lifecycle cannot register a
10409
+ * job itself. Applications register `authJobRouter`, which carries this one
10410
+ * beside the deletion purge, the stale-client sweep and the link mailer.
10411
+ */
10412
+ /** Daily at 06:00, an hour after the stale-client sweep so the three do not overlap. */
10413
+ declare const DEFAULT_REVOKE_ALL_TOKEN_PURGE_CRON = "0 6 * * *";
10414
+ /**
10415
+ * Build the `auth.revoke-all-token-purge` job with a given cron schedule.
10416
+ *
10417
+ * @param cronExpression - Defaults to daily at 06:00
10418
+ */
10419
+ declare function createRevokeAllTokenPurgeJob(cronExpression?: string): _spfn_core_job.JobDef<void, void>;
10420
+
9976
10421
  /**
9977
10422
  * Send the mail one request deferred.
9978
10423
  *
@@ -9994,7 +10439,8 @@ declare const linkMailJob: _spfn_core_job.JobDef<{
9994
10439
 
9995
10440
  /**
9996
10441
  * Build the auth job router: the account-deletion purge sweep, the OAuth 2.1
9997
- * stale-client sweep, and the link-mail sender.
10442
+ * stale-client sweep, the sign-out-everywhere link sweep, and the link-mail
10443
+ * sender.
9998
10444
  *
9999
10445
  * The cron is a parameter because `job(...).cron(expression)` bakes the string in
10000
10446
  * at module-import time, which always happens before `createAuthLifecycle()` runs
@@ -10004,13 +10450,16 @@ declare const linkMailJob: _spfn_core_job.JobDef<{
10004
10450
  *
10005
10451
  * @param options.purgeCron - Deletion purge schedule; defaults to daily at 04:00
10006
10452
  * @param options.oauth2ClientPurgeCron - Stale OAuth client sweep; defaults to daily at 05:00
10453
+ * @param options.revokeAllTokenPurgeCron - Sign-out-everywhere link sweep; defaults to daily at 06:00
10007
10454
  */
10008
10455
  declare function createAuthJobRouter(options?: {
10009
10456
  purgeCron?: string;
10010
10457
  oauth2ClientPurgeCron?: string;
10458
+ revokeAllTokenPurgeCron?: string;
10011
10459
  }): _spfn_core_job.JobRouter<{
10012
10460
  deletionPurge: _spfn_core_job.JobDef<void, void>;
10013
10461
  oauth2ClientPurge: _spfn_core_job.JobDef<void, void>;
10462
+ revokeAllTokenPurge: _spfn_core_job.JobDef<void, void>;
10014
10463
  linkMail: _spfn_core_job.JobDef<{
10015
10464
  kind: "signup-link";
10016
10465
  rowId: number;
@@ -10030,6 +10479,7 @@ declare function createAuthJobRouter(options?: {
10030
10479
  declare const authJobRouter: _spfn_core_job.JobRouter<{
10031
10480
  deletionPurge: _spfn_core_job.JobDef<void, void>;
10032
10481
  oauth2ClientPurge: _spfn_core_job.JobDef<void, void>;
10482
+ revokeAllTokenPurge: _spfn_core_job.JobDef<void, void>;
10033
10483
  linkMail: _spfn_core_job.JobDef<{
10034
10484
  kind: "signup-link";
10035
10485
  rowId: number;
@@ -10049,216 +10499,4 @@ declare const authJobRouter: _spfn_core_job.JobRouter<{
10049
10499
  */
10050
10500
  declare const createAuthDeletionJobRouter: typeof createAuthJobRouter;
10051
10501
 
10052
- /**
10053
- * @spfn/auth - Auth Events
10054
- *
10055
- * 인증 관련 이벤트 정의
10056
- * - auth.login: 로그인 성공 시 (기존 사용자만)
10057
- * - auth.register: 회원가입 성공 시 (OAuth 신규 가입 포함)
10058
- */
10059
- /**
10060
- * Auth provider type
10061
- *
10062
- * 직접 인증(email/phone) + 등록 가능한 모든 소셜 provider(SOCIAL_PROVIDERS).
10063
- */
10064
- declare const AuthProviderSchema: _sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"email">, _sinclair_typebox.TLiteral<"phone">, ..._sinclair_typebox.TLiteral<"google" | "apple" | "github" | "kakao" | "naver" | "superself">[]]>;
10065
- /**
10066
- * auth.login - 로그인 성공 이벤트
10067
- *
10068
- * 발행 시점:
10069
- * - 이메일/전화 로그인 성공 시
10070
- * - OAuth 기존 사용자 로그인 시
10071
- * - 기기 코드 승인이 소비되어 새 기기 키가 등록될 때 (provider: 'device')
10072
- *
10073
- * @example
10074
- * ```typescript
10075
- * authLoginEvent.subscribe(async (payload) => {
10076
- * await analytics.trackLogin(payload.userId, payload.provider);
10077
- * });
10078
- * ```
10079
- */
10080
- declare const authLoginEvent: _spfn_core_event.EventDef<{
10081
- email?: string | undefined;
10082
- phone?: string | undefined;
10083
- userId: string;
10084
- provider: "email" | "phone" | "google" | "apple" | "github" | "kakao" | "naver" | "superself" | "device" | "passkey";
10085
- }>;
10086
- /**
10087
- * auth.register - 회원가입 성공 이벤트
10088
- *
10089
- * 발행 시점:
10090
- * - 이메일/전화 회원가입 성공 시
10091
- * - OAuth 신규 사용자 가입 시
10092
- *
10093
- * @example
10094
- * ```typescript
10095
- * authRegisterEvent.subscribe(async (payload) => {
10096
- * await emailService.sendWelcome(payload.email);
10097
- * });
10098
- * ```
10099
- */
10100
- declare const authRegisterEvent: _spfn_core_event.EventDef<{
10101
- email?: string | undefined;
10102
- phone?: string | undefined;
10103
- metadata?: {
10104
- [x: string]: unknown;
10105
- } | undefined;
10106
- userId: string;
10107
- provider: "email" | "phone" | "google" | "apple" | "github" | "kakao" | "naver" | "superself";
10108
- }>;
10109
- /**
10110
- * auth.invitation.created - 초대 생성 이벤트
10111
- *
10112
- * 발행 시점:
10113
- * - createInvitation() 성공 시
10114
- * - resendInvitation() 성공 시
10115
- *
10116
- * @example
10117
- * ```typescript
10118
- * invitationCreatedEvent.subscribe(async (payload) => {
10119
- * const inviteUrl = `${APP_URL}/invite/${payload.token}`;
10120
- * await notificationService.send({
10121
- * channel: 'email',
10122
- * to: payload.email,
10123
- * subject: 'You are invited!',
10124
- * html: renderInviteEmail({ inviteUrl, ...payload.metadata }),
10125
- * });
10126
- * });
10127
- * ```
10128
- */
10129
- declare const invitationCreatedEvent: _spfn_core_event.EventDef<{
10130
- metadata?: {
10131
- [x: string]: unknown;
10132
- } | undefined;
10133
- email: string;
10134
- token: string;
10135
- roleId: number;
10136
- invitedBy: string;
10137
- expiresAt: string;
10138
- invitationId: string;
10139
- isResend: boolean;
10140
- }>;
10141
- /**
10142
- * auth.invitation.accepted - 초대 수락 이벤트
10143
- *
10144
- * 발행 시점:
10145
- * - acceptInvitation() 성공 시
10146
- *
10147
- * @example
10148
- * ```typescript
10149
- * invitationAcceptedEvent.subscribe(async (payload) => {
10150
- * await onboardingService.start(payload.userId);
10151
- * });
10152
- * ```
10153
- */
10154
- declare const invitationAcceptedEvent: _spfn_core_event.EventDef<{
10155
- metadata?: {
10156
- [x: string]: unknown;
10157
- } | undefined;
10158
- email: string;
10159
- userId: string;
10160
- roleId: number;
10161
- invitedBy: string;
10162
- invitationId: string;
10163
- }>;
10164
- /**
10165
- * auth.deletion.requested - 계정 탈퇴 요청 이벤트
10166
- *
10167
- * 발행 시점:
10168
- * - requestAccountDeletionService() 성공 시 (self/admin 공통)
10169
- *
10170
- * @example
10171
- * ```typescript
10172
- * authDeletionRequestedEvent.subscribe(async (payload) => {
10173
- * await analytics.trackChurnRisk(payload.userId);
10174
- * });
10175
- * ```
10176
- */
10177
- declare const authDeletionRequestedEvent: _spfn_core_event.EventDef<{
10178
- userId: string;
10179
- purgeScheduledAt: string;
10180
- userPublicId: string;
10181
- requestedBy: "admin" | "self";
10182
- }>;
10183
- /**
10184
- * auth.deletion.cancelled - 계정 탈퇴 복구 이벤트
10185
- *
10186
- * 발행 시점:
10187
- * - cancelAccountDeletionService() 성공 시 (유예 기간 내 복구)
10188
- */
10189
- declare const authDeletionCancelledEvent: _spfn_core_event.EventDef<{
10190
- userId: string;
10191
- userPublicId: string;
10192
- }>;
10193
- /**
10194
- * auth.deletion.completed - 계정 파기 완료 이벤트
10195
- *
10196
- * 발행 시점:
10197
- * - purge job(또는 즉시 파기 경로)이 유저를 파기한 직후
10198
- *
10199
- * PII를 담지 않는다 — userId(내부 순번)/email/phone 없이 userPublicId만 실어
10200
- * 파기 완료 이후에도 구독자가 식별 정보를 다시 축적하지 않도록 한다.
10201
- */
10202
- declare const authDeletionCompletedEvent: _spfn_core_event.EventDef<{
10203
- userPublicId: string;
10204
- purgeStrategy: "anonymize" | "hard-delete";
10205
- }>;
10206
- /**
10207
- * auth.oauth.unlinked - provider발 연동 해제 이벤트
10208
- *
10209
- * 발행 시점:
10210
- * - provider(카카오·네이버 등)가 unlink-notify 웹훅으로 연동 해제를 알려와
10211
- * 소셜 계정 연결과 저장 토큰이 삭제된 직후
10212
- *
10213
- * 연결 삭제까지는 프레임워크가 수행하고, 그 이후(계정 탈퇴로 이어갈지 등)는
10214
- * 앱 정책이므로 이 이벤트를 구독해 처리한다.
10215
- *
10216
- * @example
10217
- * ```typescript
10218
- * oauthUnlinkedEvent.subscribe(async (payload) => {
10219
- * await requestAccountDeletionService({ userId: payload.userId, requestedBy: 'self' });
10220
- * });
10221
- * ```
10222
- */
10223
- declare const oauthUnlinkedEvent: _spfn_core_event.EventDef<{
10224
- reason?: string | undefined;
10225
- userId: string;
10226
- provider: "email" | "phone" | "google" | "apple" | "github" | "kakao" | "naver" | "superself";
10227
- providerUserId: string;
10228
- }>;
10229
- /**
10230
- * auth.password.reset — an account's password was replaced through a reset link
10231
- *
10232
- * 발행 시점:
10233
- * - completePasswordResetService()가 커밋된 직후
10234
- *
10235
- * Distinct from a password *change*, which is made from a session that already
10236
- * proved itself. This one is made by whoever opened a link in a mailbox, so it
10237
- * is the event an app hangs a "your password was reset" notice on — and the
10238
- * signal to look at, if the owner says they did not ask for it.
10239
- *
10240
- * @example
10241
- * ```typescript
10242
- * authPasswordResetEvent.subscribe(async (payload) => {
10243
- * await notifyOwner(payload.userId, 'Your password was reset');
10244
- * });
10245
- * ```
10246
- */
10247
- declare const authPasswordResetEvent: _spfn_core_event.EventDef<{
10248
- email: string;
10249
- userId: string;
10250
- }>;
10251
- /**
10252
- * Auth event payload types
10253
- */
10254
- type AuthLoginPayload = typeof authLoginEvent._payload;
10255
- type AuthRegisterPayload = typeof authRegisterEvent._payload;
10256
- type AuthPasswordResetPayload = typeof authPasswordResetEvent._payload;
10257
- type InvitationCreatedPayload = typeof invitationCreatedEvent._payload;
10258
- type InvitationAcceptedPayload = typeof invitationAcceptedEvent._payload;
10259
- type AuthDeletionRequestedPayload = typeof authDeletionRequestedEvent._payload;
10260
- type AuthDeletionCancelledPayload = typeof authDeletionCancelledEvent._payload;
10261
- type AuthDeletionCompletedPayload = typeof authDeletionCompletedEvent._payload;
10262
- type OAuthUnlinkedPayload = typeof oauthUnlinkedEvent._payload;
10263
-
10264
- export { AUTHORIZE_PATH, type AccountDeletionPurgeUser, type AccountDeletionRequest, AccountDeletionRequestedBy, AccountDeletionRequestsRepository, type AuthConfig, AuthContext, type AuthCsrfConfig, type AuthDeletionCancelledPayload, type AuthDeletionCompletedPayload, type AuthDeletionConfig, type AuthDeletionRequestedPayload, type AuthDeviceAuthConfig, type AuthLifecycleConfig, type AuthLifecycleOptions, type AuthLoginPayload, type AuthMetadataEntity, AuthMetadataRepository, type AuthPasswordResetPayload, AuthProviderSchema, type AuthRegisterPayload, type AuthorizationServerConfig, type AuthorizationServerOptions, type BeforeRegisterContext, COOKIE_NAMES, CSRF_HEADER, type CancelAccountDeletionParams, type CancelAccountDeletionResult, type CreateOAuthStateParams, type CsrfMode, DEFAULT_ACCESS_TOKEN_TTL_MS, DEFAULT_CODE_TTL_MS, DEFAULT_DELETION_ALLOW_SELF_IMMEDIATE, DEFAULT_DELETION_GRACE_PERIOD_DAYS, DEFAULT_DELETION_PURGE_CRON, DEFAULT_DELETION_PURGE_STRATEGY, DEFAULT_DELETION_SEND_NOTIFICATIONS, DEFAULT_DEVICE_AUTH_INTERVAL_MS, DEFAULT_DEVICE_AUTH_TTL_MS, DEFAULT_REFRESH_TOKEN_TTL_MS, DEVICE_AUTH_STATUSES, type DecryptedOAuthToken, type DeviceAuthStatus, type DeviceAuthorization, DeviceAuthorizationsRepository, type EmailNormalizationResult, EnvironmentKeyringTokenCipher, type GoogleTokenResponse, type GoogleUserInfo, type Invitation, type InvitationAcceptedPayload, type InvitationCreatedPayload, InvitationStatus, InvitationsRepository, type IssuedOpsToken, KeyAlgorithmType, KeysRepository, MAX_UNGRANTED_CLIENTS_PER_IP, type NewAccountDeletionRequest, type NewAuthMetadataEntity, type NewDeviceAuthorization, type NewInvitation, type NewOAuth2AuthorizationCode, type NewOAuth2Client, type NewOAuth2Grant, type NewOAuth2Token, type NewOpsToken, NewPasskey, type NewPasswordResetToken, type NewPermission, type NewPermissionEntity, type NewRole, type NewRoleEntity, type NewRolePermission, type NewSignupLinkToken, type NewUser, type NewUserPermission, type NewUserProfile, type NewUserPublicKey, type NewUserSocialAccount, type NewVerificationCode, type NewWebAuthnChallenge, OAUTH2_ACCESS_TOKEN_PREFIX, OAUTH2_REFRESH_TOKEN_PREFIX, OAUTH2_TOKEN_KINDS, type OAuth2AuthorizationCode, OAuth2AuthorizationCodesRepository, type OAuth2Client, OAuth2ClientsRepository, type OAuth2Grant, type OAuth2GrantWithClient, OAuth2GrantsRepository, type OAuth2RegisterRefusal, type OAuth2RegisterRequest, type OAuth2RegisterResult, type OAuth2RegisteredClient, type OAuth2Token, type OAuth2TokenKind, type OAuth2TokenRefusal, type OAuth2TokenRequest, type OAuth2TokenResponse, type OAuth2TokenResult, OAuth2TokensRepository, OAuthProvider, type OAuthState, type OAuthTokenCipher, type OAuthTokenContext, type OAuthTokenType, type OAuthUnlinkedPayload, OPS_TOKEN_PREFIX, type OpsOrUserConfig, type OpsToken, OpsTokensRepository, Passkey, type PasskeyConfig, type PasskeyUserVerification, PasskeysRepository, type PasswordResetToken, PasswordResetTokensRepository, type PendingDeletionInfo, type Permission, type PermissionEntity, PermissionsRepository, PurgeStrategy, type PurgeUserResult, type RedirectUriRefusal, type RegisterChannel, type RequestAccountDeletionParams, type RequestAccountDeletionResult, type Role, type RoleEntity, type RoleGuardOptions, type RolePermission, RolePermissionsRepository, RolesRepository, STALE_CLIENT_MAX_AGE_MS, SUPPORTED_GRANT_TYPES, SUPPORTED_RESPONSE_TYPES, type SessionPayload, type SignupLinkToken, SignupLinkTokensRepository, SocialAccountsRepository, SocialProvider, type SweepDuePurgesResult, type TokenPayload, USER_CODE_ALPHABET, USER_CODE_LENGTH, type UpdateProfileParams, type User, type UserPermission, UserPermissionsRepository, type UserProfile, UserProfilesRepository, type UserPublicKey, type UserSocialAccount, UsersRepository, type VerificationCode, VerificationCodesRepository, VerificationPurpose, type VerifiedOAuth2AccessToken, type VerifiedOpsToken, type VerifyIdTokenParams, WEBAUTHN_CHALLENGE_KINDS, type WebAuthnChallenge, type WebAuthnChallengeKind, WebAuthnChallengesRepository, acceptInvitation, accountDeletionRequests, accountDeletionRequestsRepository, addPermissionToRole, appleProvider, assertAuthorizationServerIssuer, assertCanAssignRole, assertKeyMatchesAlgorithm, assertPasskeyConfig, authDeletionCancelledEvent, authDeletionCompletedEvent, authDeletionRequestedEvent, authJobRouter, authLogger, authLoginEvent, authMetadata, authMetadataRepository, authPasswordResetEvent, authRegisterEvent, authSchema, cancelAccountDeletionService, cancelInvitation, checkUsernameAvailableService, configureAuth, configureAuthorizationServer, configureDeletion, configureDeviceAuth, configureOAuthTokenCipher, createAuthDeletionJobRouter, createAuthDeletionPurgeJob, createAuthJobRouter, createAuthLifecycle, createInvitation, createOAuthState, createRole, decodeToken, decryptToken, deleteInvitation, deleteRole, deriveCsrfToken, deviceAuthorizations, deviceAuthorizationsRepository, encryptToken, exchangeCodeForTokens, expireOldInvitations, formatUserCode, generateAccessToken, generateAuthorizationCode, generateDeviceCode, generateOAuthNonce, generateRefreshToken, generateToken, generateUserCode, getAllRoles, getAuth, getAuthConfig, getAuthSessionService, getAuthorizationServerConfig, getCsrfExemptPaths, getCsrfMode, getDeletionConfig, getDeviceAuthConfig, getDummyPasswordHash, getGoogleAuthUrl, getGoogleOAuthConfig, getGoogleUserInfo, getInvitationByToken, getInvitationWithDetails, getKeyId, getLocale, getOneTimeTokenManager, getOpsToken, getOptionalAuth, getPasskeyConfig, getPendingDeletionInfo, getRole, getRoleByName, getRolePermissions, getSessionTtl, getUser, getUserByEmailService, getUserByIdService, getUserByPhoneService, getUserId, getUserPermissions, getUserProfileService, getUserRole, githubProvider, googleProvider, hasAllPermissions, hasAnyPermission, hasAnyRole, hasPermission, hasRole, hashDeviceCode, hashOAuth2Secret, hashPassword, initOneTimeTokenManager, initializeAuth, invitationAcceptedEvent, invitationCreatedEvent, invitationsRepository, isAccessTokenShaped, isEncrypted, isGoogleOAuthEnabled, isLoopbackHostname, isOpsToken, isPkceS256ChallengeShaped, isPkceVerifierShaped, issueOpsTokenService, kakaoProvider, keysRepository, linkMailJob, listInvitations, listOpsTokensService, matchOAuthCsrfCookies, matchesCsrfToken, matchesRegisteredRedirectUri, naverProvider, normalizeEmail, normalizeOptionalEmail, normalizeResource, normalizeStoredEmails, normalizeUserCode, oauth2AuthorizationCodes, oauth2AuthorizationCodesRepository, oauth2Clients, oauth2ClientsRepository, oauth2Grants, oauth2GrantsRepository, oauth2TokenService, oauth2Tokens, oauth2TokensRepository, oauthUnlinkedEvent, oneTimeTokenAuth, opsOrUser, opsTokenAuth, opsTokens, opsTokensRepository, parseDuration, passkeysRepository, passwordResetTokens, passwordResetTokensRepository, permissions, permissionsRepository, pkceChallengeFor, purgeStaleOAuth2ClientsService, purgeUserService, redirectHostOf, refreshAccessToken, refuseRedirectUriRegistration, registerOAuth2ClientService, removePermissionFromRole, requestAccountDeletionService, requireAnyPermission, requireOpsScope, requirePermissions, requireRole, resendInvitation, resolveIssuerSource, revokeOAuth2TokenService, revokeOpsTokenService, roleGuard, rolePermissions, rolePermissionsRepository, roles, rolesRepository, runBeforeRegister, sameOAuth2Hash, sameResource, secondsUntil, setRolePermissions, signupLinkTokens, signupLinkTokensRepository, socialAccountsRepository, sweepDuePurges, toEpochSeconds, updateLastLoginService, updateLocaleService, updateRole, updateUserProfileService, updateUserService, updateUsernameService, userInvitations, userPermissions, userPermissionsRepository, userProfiles, userProfilesRepository, userPublicKeys, userSocialAccounts, users, usersRepository, validateInvitation, validatePasswordStrength, verificationCodes, verificationCodesRepository, verifyAccessToken, verifyClientToken, verifyIdToken, verifyKeyFingerprint, verifyOAuthState, verifyOpsTokenService, verifyPassword, verifyToken, webauthnChallenges, webauthnChallengesRepository };
10502
+ export { AUTHORIZE_PATH, type AccountDeletionPurgeUser, type AccountDeletionRequest, AccountDeletionRequestedBy, AccountDeletionRequestsRepository, type AuthConfig, AuthContext, type AuthCsrfConfig, type AuthDeletionConfig, type AuthDeviceAuthConfig, type AuthLifecycleConfig, type AuthLifecycleOptions, type AuthMetadataEntity, AuthMetadataRepository, type AuthorizationServerConfig, type AuthorizationServerOptions, type BeforeRegisterContext, COOKIE_NAMES, CSRF_HEADER, type CancelAccountDeletionParams, type CancelAccountDeletionResult, type CreateOAuthStateParams, type CreateRevokeAllLinkOptions, type CsrfMode, DEFAULT_ACCESS_TOKEN_TTL_MS, DEFAULT_CODE_TTL_MS, DEFAULT_DELETION_ALLOW_SELF_IMMEDIATE, DEFAULT_DELETION_GRACE_PERIOD_DAYS, DEFAULT_DELETION_PURGE_CRON, DEFAULT_DELETION_PURGE_STRATEGY, DEFAULT_DELETION_SEND_NOTIFICATIONS, DEFAULT_DEVICE_AUTH_INTERVAL_MS, DEFAULT_DEVICE_AUTH_TTL_MS, DEFAULT_REFRESH_TOKEN_TTL_MS, DEFAULT_REVOKE_ALL_TOKEN_PURGE_CRON, DEVICE_AUTH_STATUSES, type DecryptedOAuthToken, type DeviceAuthStatus, type DeviceAuthorization, DeviceAuthorizationsRepository, type EmailNormalizationResult, EnvironmentKeyringTokenCipher, type GoogleTokenResponse, type GoogleUserInfo, type Invitation, InvitationStatus, InvitationsRepository, type IssuedOpsToken, KeyAlgorithmType, type KeyRevokeAllToken, KeyRevokeAllTokensRepository, KeysRepository, type LiveRevokeAllLink, MAX_UNGRANTED_CLIENTS_PER_IP, type NewAccountDeletionRequest, type NewAuthMetadataEntity, type NewDeviceAuthorization, type NewInvitation, type NewKeyRevokeAllToken, type NewOAuth2AuthorizationCode, type NewOAuth2Client, type NewOAuth2Grant, type NewOAuth2Token, type NewOpsToken, NewPasskey, type NewPasswordResetToken, type NewPermission, type NewPermissionEntity, type NewRole, type NewRoleEntity, type NewRolePermission, type NewSignupLinkToken, type NewUser, type NewUserPermission, type NewUserProfile, type NewUserPublicKey, type NewUserSocialAccount, type NewVerificationCode, type NewWebAuthnChallenge, OAUTH2_ACCESS_TOKEN_PREFIX, OAUTH2_REFRESH_TOKEN_PREFIX, OAUTH2_TOKEN_KINDS, type OAuth2AuthorizationCode, OAuth2AuthorizationCodesRepository, type OAuth2Client, OAuth2ClientsRepository, type OAuth2Grant, type OAuth2GrantWithClient, OAuth2GrantsRepository, type OAuth2RegisterRefusal, type OAuth2RegisterRequest, type OAuth2RegisterResult, type OAuth2RegisteredClient, type OAuth2Token, type OAuth2TokenKind, type OAuth2TokenRefusal, type OAuth2TokenRequest, type OAuth2TokenResponse, type OAuth2TokenResult, OAuth2TokensRepository, OAuthProvider, type OAuthState, type OAuthTokenCipher, type OAuthTokenContext, type OAuthTokenType, OPS_TOKEN_PREFIX, type OpsOrUserConfig, type OpsToken, OpsTokensRepository, Passkey, type PasskeyConfig, type PasskeyUserVerification, PasskeysRepository, type PasswordResetToken, PasswordResetTokensRepository, type PendingDeletionInfo, type Permission, type PermissionEntity, PermissionsRepository, PurgeStrategy, type PurgeUserResult, type RedirectUriRefusal, type RegisterChannel, type RequestAccountDeletionParams, type RequestAccountDeletionResult, type RevokeAllLink, type RevokeAllLinkDescription, type RevokedKey, type Role, type RoleEntity, type RoleGuardOptions, type RolePermission, RolePermissionsRepository, RolesRepository, STALE_CLIENT_MAX_AGE_MS, SUPPORTED_GRANT_TYPES, SUPPORTED_RESPONSE_TYPES, type SessionPayload, type SignupLinkToken, SignupLinkTokensRepository, SocialAccountsRepository, SocialProvider, type SweepDuePurgesResult, type TokenPayload, USER_CODE_ALPHABET, USER_CODE_LENGTH, type UpdateProfileParams, type User, type UserPermission, UserPermissionsRepository, type UserProfile, UserProfilesRepository, type UserPublicKey, type UserSocialAccount, UsersRepository, type VerificationCode, VerificationCodesRepository, VerificationPurpose, type VerifiedOAuth2AccessToken, type VerifiedOpsToken, type VerifyIdTokenParams, WEBAUTHN_CHALLENGE_KINDS, type WebAuthnChallenge, type WebAuthnChallengeKind, WebAuthnChallengesRepository, acceptInvitation, accountDeletionRequests, accountDeletionRequestsRepository, addPermissionToRole, appleProvider, assertAuthorizationServerIssuer, assertCanAssignRole, assertKeyMatchesAlgorithm, assertPasskeyConfig, authJobRouter, authLogger, authMetadata, authMetadataRepository, authSchema, cancelAccountDeletionService, cancelInvitation, checkUsernameAvailableService, configureAuth, configureAuthorizationServer, configureDeletion, configureDeviceAuth, configureOAuthTokenCipher, consumeRevokeAllLink, createAuthDeletionJobRouter, createAuthDeletionPurgeJob, createAuthJobRouter, createAuthLifecycle, createInvitation, createOAuthState, createRevokeAllLink, createRevokeAllTokenPurgeJob, createRole, decodeToken, decryptToken, deleteInvitation, deleteRole, deriveCsrfToken, describeRevokeAllLink, deviceAuthorizations, deviceAuthorizationsRepository, encryptToken, exchangeCodeForTokens, expireOldInvitations, formatUserCode, generateAccessToken, generateAuthorizationCode, generateDeviceCode, generateOAuthNonce, generateRefreshToken, generateToken, generateUserCode, getAllRoles, getAuth, getAuthConfig, getAuthSessionService, getAuthorizationServerConfig, getCsrfExemptPaths, getCsrfMode, getDeletionConfig, getDeviceAuthConfig, getDummyPasswordHash, getGoogleAuthUrl, getGoogleOAuthConfig, getGoogleUserInfo, getInvitationByToken, getInvitationWithDetails, getKeyId, getLocale, getOneTimeTokenManager, getOpsToken, getOptionalAuth, getPasskeyConfig, getPendingDeletionInfo, getRole, getRoleByName, getRolePermissions, getSessionTtl, getUser, getUserByEmailService, getUserByIdService, getUserByPhoneService, getUserId, getUserPermissions, getUserProfileService, getUserRole, githubProvider, googleProvider, hasAllPermissions, hasAnyPermission, hasAnyRole, hasPermission, hasRole, hashDeviceCode, hashOAuth2Secret, hashPassword, initOneTimeTokenManager, initializeAuth, invitationsRepository, isAccessTokenShaped, isEncrypted, isGoogleOAuthEnabled, isLoopbackHostname, isOpsToken, isPkceS256ChallengeShaped, isPkceVerifierShaped, issueOpsTokenService, kakaoProvider, keyRevokeAllTokens, keyRevokeAllTokensRepository, keysRepository, linkMailJob, listInvitations, listOpsTokensService, matchOAuthCsrfCookies, matchesCsrfToken, matchesRegisteredRedirectUri, naverProvider, normalizeEmail, normalizeOptionalEmail, normalizeResource, normalizeStoredEmails, normalizeUserCode, oauth2AuthorizationCodes, oauth2AuthorizationCodesRepository, oauth2Clients, oauth2ClientsRepository, oauth2Grants, oauth2GrantsRepository, oauth2TokenService, oauth2Tokens, oauth2TokensRepository, oneTimeTokenAuth, opsOrUser, opsTokenAuth, opsTokens, opsTokensRepository, parseDuration, passkeysRepository, passwordResetTokens, passwordResetTokensRepository, permissions, permissionsRepository, pkceChallengeFor, purgeRevokeAllTokensService, purgeStaleOAuth2ClientsService, purgeUserService, redirectHostOf, refreshAccessToken, refuseRedirectUriRegistration, registerOAuth2ClientService, removePermissionFromRole, requestAccountDeletionService, requireAnyPermission, requireOpsScope, requirePermissions, requireRole, resendInvitation, resolveIssuerSource, revokeOAuth2TokenService, revokeOpsTokenService, roleGuard, rolePermissions, rolePermissionsRepository, roles, rolesRepository, runBeforeRegister, sameOAuth2Hash, sameResource, secondsUntil, setRolePermissions, signupLinkTokens, signupLinkTokensRepository, socialAccountsRepository, sweepDuePurges, toEpochSeconds, updateLastLoginService, updateLocaleService, updateRole, updateUserProfileService, updateUserService, updateUsernameService, userInvitations, userPermissions, userPermissionsRepository, userProfiles, userProfilesRepository, userPublicKeys, userSocialAccounts, users, usersRepository, validateInvitation, validatePasswordStrength, verificationCodes, verificationCodesRepository, verifyAccessToken, verifyClientToken, verifyIdToken, verifyKeyFingerprint, verifyOAuthState, verifyOpsTokenService, verifyPassword, verifyToken, webauthnChallenges, webauthnChallengesRepository };