@spfn/auth 0.3.0-beta.23 → 0.3.0-beta.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +328 -7
- package/dist/client-proof.d.ts +10 -1
- package/dist/client-proof.js +136 -11
- package/dist/client-proof.js.map +1 -1
- package/dist/client.d.ts +101 -1
- package/dist/client.js +65 -0
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +122 -0
- package/dist/config.js +53 -0
- package/dist/config.js.map +1 -1
- package/dist/crypto.d.ts +1 -1
- package/dist/errors.d.ts +159 -3
- package/dist/errors.js +95 -2
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +52 -12
- package/dist/index.js +104 -3
- package/dist/index.js.map +1 -1
- package/dist/{machine-principals-CaEFq61K.d.ts → machine-principals-CdEgxOB1.d.ts} +2049 -771
- package/dist/nextjs/api.js +329 -37
- package/dist/nextjs/api.js.map +1 -1
- package/dist/nextjs/server.d.ts +59 -24
- package/dist/nextjs/server.js +105 -11
- package/dist/nextjs/server.js.map +1 -1
- package/dist/server.d.ts +415 -332
- package/dist/server.js +2933 -1545
- package/dist/server.js.map +1 -1
- package/dist/{session-Dfwu5g2W.d.ts → session-BbhAGZtA.d.ts} +57 -1
- package/dist/{types-DYyhze28.d.ts → types-CTdoTOxM.d.ts} +24 -1
- package/migrations/20260918184037_happy_mordo/migration.sql +4 -0
- package/migrations/20260918184037_happy_mordo/snapshot.json +6000 -0
- package/migrations/20260918184152_dear_rictor/migration.sql +3 -0
- package/migrations/20260918184152_dear_rictor/snapshot.json +6039 -0
- package/migrations/20260919023107_even_mikhail_rasputin/migration.sql +20 -0
- package/migrations/20260919023107_even_mikhail_rasputin/snapshot.json +6300 -0
- package/package.json +1 -1
package/dist/server.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { A as AuthInitOptions,
|
|
2
|
-
export {
|
|
1
|
+
import { A as AuthInitOptions, z as OAuthProvider, N as NewUserPublicKey, x as VerificationPurpose, B as NewPasskey, E as Passkey, G as MfaVerification, H as MfaVerificationMethod, J as NewMfaChallenge, Q as MfaChallenge, u as PermissionCategory, W as UserPublicKey, X as AuthContext } from './machine-principals-CdEgxOB1.js';
|
|
2
|
+
export { Y as ApproveDeviceAuthParams, Z as AssertStepUpParams, _ as AuthDeletionCancelledPayload, $ as AuthDeletionCompletedPayload, a0 as AuthDeletionRequestedPayload, a1 as AuthDeviceRegisteredPayload, a2 as AuthLoginPayload, a3 as AuthPasswordResetPayload, a4 as AuthProfileOutcome, a5 as AuthProfileVerifier, a6 as AuthProviderSchema, a7 as AuthRegisterPayload, a8 as BearerOutcome, a9 as BearerRefusal, aa as ChangePasswordParams, ab as CompletePasswordResetParams, ac as CompleteSignupParams, ad as ConfirmPasswordResetParams, d as ConfirmPasswordResetResult, ae as ConfirmSignupLinkParams, C as ConfirmSignupLinkResult, af as ConfirmTotpParams, g as ConfirmTotpResult, ag as DeferredLoginEvent, ah as DenyDeviceAuthParams, ai as DeviceAuthApprovedResult, aj as DeviceAuthInfoParams, D as DeviceAuthInfoResult, ak as DeviceAuthPendingResult, al as DeviceAuthPollResponseSchema, am as DeviceNameSchema, an as DeviceRegistrationChannel, ao as DisableSessionBindingParams, ap as EmailSchema, aq as FingerprintSchema, ar as FinishPasskeyEnrollmentParams, F as FinishPasskeyEnrollmentResult, as as FinishPasskeyLoginParams, at as FinishSessionRenewParams, au as InvitationAcceptedPayload, av as InvitationCreatedPayload, I as IssueOneTimeTokenResult, aw as KEY_FINGERPRINT_PREFIX_LENGTH, ax as KeyIdSchema, K as KeySummary, ay as LoginParams, L as LoginResult, az as LogoutParams, aA as MFA_CHALLENGE_ATTEMPT_LIMIT, aB as MFA_CHALLENGE_CHANNELS, aC as MFA_VERIFICATION_METHODS, aD as MachinePrincipal, aE as MachineVerifierRegistration, aF as MarkPasskeyParams, aG as MfaChallengeChannel, aH as MfaChallengeHandle, M as MfaStatus, aI as NativeVerifyOptions, aJ as NewMfaVerification, aK as NormalizedIdentity, q as OAuth2AuthorizationCodeIssued, aL as OAuth2AuthorizeParams, p as OAuth2ConsentView, r as OAuth2GrantSummary, aM as OAuth2ScopeDescription, aN as OAuthCallbackParams, aO as OAuthCallbackResult, aP as OAuthCodeExchangeOptions, aQ as OAuthNativeParams, n as OAuthNativeResult, aR as OAuthStartParams, O as OAuthStartResult, aS as OAuthTokens, aT as OAuthUnlinkedPayload, aU as OpenStepUpChallengeParams, aV as PASSKEY_DEVICE_TYPES, aW as PASSKEY_LABEL_MAX_LENGTH, aX as PasskeyDeviceType, f as PasskeySummary, aY as PasswordSchema, aZ as PhoneSchema, a_ as PlatformSchema, a$ as PollDeviceAuthParams, b0 as PollDeviceAuthResult, b1 as PublicKeySchema, b2 as RecentAuthenticationParams, b3 as RegisterParams, b4 as RegisterPublicKeyParams, b5 as RegisterPublicKeyResult, a as RegisterResult, b6 as RenamePasskeyParams, b7 as RequestPasswordResetParams, c as RequestPasswordResetResult, b8 as RequestSignupLinkParams, b as RequestSignupLinkResult, b9 as RevokeAllKeysParams, i as RevokeAllKeysResult, ba as RevokeKeyParams, bb as RevokePasskeyParams, bc as RotateKeyParams, h as RotateKeyResult, bd as SendVerificationCodeParams, S as SendVerificationCodeResult, be as SessionBindingParams, j as SessionBindingResult, bf as StartDeviceAuthParams, e as StartDeviceAuthResult, bg as StartPasskeyEnrollmentParams, bh as StartSessionRenewParams, bi as StepUpParams, bj as TargetTypeSchema, T as TotpEnrolmentResult, bk as UnlinkNotification, bl as UnlinkNotifyRejection, bm as UnlinkNotifyRequest, bn as UnlinkNotifyResult, bo as UserCodeSchema, v as VERIFICATION_PURPOSES, w as VERIFICATION_TARGET_TYPES, bp as VerificationPurposeSchema, y as VerificationTargetType, bq as VerifyCodeParams, br as VerifyCodeResult, bs as VerifyMfaChallengeParams, V as VerifyMfaChallengeResult, bt as admitBearerKey, bu as approveDeviceAuthService, bv as approveOAuth2AuthorizeService, bw as assertNotLastRecoveryCredential, bx as assertRecentAuthentication, by as assertStepUp, bz as attemptSecondFactor, bA as authDeletionCancelledEvent, bB as authDeletionCompletedEvent, bC as authDeletionRequestedEvent, bD as authDeviceRegisteredEvent, bE as authLoginEvent, bF as authPasswordResetEvent, bG as authRegisterEvent, m as authRouter, bH as authenticate, bI as bearerAuthContext, bJ as buildOAuthErrorUrl, bK as carryStepUpVerification, bL as changePasswordService, bM as completePasswordResetService, bN as completeSignupService, bO as confirmPasswordResetService, bP as confirmSignupLinkService, bQ as confirmTotpEnrolmentService, bR as denyDeviceAuthService, bS as denyOAuth2AuthorizeService, bT as describeOAuth2AuthorizeRequestService, bU as disableMfaService, bV as disableSessionBindingService, bW as enableSessionBindingService, bX as finishPasskeyEnrollmentService, bY as finishPasskeyLoginService, bZ as finishSessionRenewService, b_ as getDeviceAuthInfoService, b$ as getEnabledOAuthProviders, c0 as getGoogleAccessToken, c1 as getMachinePrincipal, c2 as getOAuthProvider, c3 as getRegisteredProviders, c4 as getSessionBindingService, c5 as invitationAcceptedEvent, c6 as invitationCreatedEvent, c7 as isOAuthProviderEnabled, c8 as issueOneTimeTokenService, c9 as keySessionBindingService, ca as listKeysService, cb as listOAuth2GrantsService, cc as listPasskeysService, cd as loginService, ce as logoutService, cf as machineAuth, cg as markPasskeySecondFactorService, ch as mfaChallenges, ci as mfaEnrolledForUser, cj as mfaStatusService, ck as mfaVerifications, cl as oauthCallbackService, cm as oauthNativeService, cn as oauthStartService, co as oauthUnlinkNotifyService, cp as oauthUnlinkedEvent, cq as openStepUpChallengeService, cr as optionalAuth, cs as passkeys, ct as pollDeviceAuthService, cu as regenerateRecoveryCodesService, cv as registerAuthProfile, cw as registerMachineVerifier, cx as registerOAuthProvider, cy as registerPublicKeyService, cz as registerService, cA as registeredBinding, cB as renamePasskeyService, cC as requestPasswordResetService, cD as requestSignupLinkService, cE as requireEnabledProvider, cF as requireMachineScope, cG as resolveAuthenticatedUser, cH as resumeStepUpChallengeService, cI as revokeAllKeysService, cJ as revokeAllOAuth2GrantsForUser, cK as revokeKeyService, cL as revokeOAuth2GrantService, cM as revokePasskeyService, cN as rotateKeyService, cO as runAuthProfile, cP as selectAuthProfile, cQ as sendVerificationCodeService, cR as startDeviceAuthService, cS as startMfaChallengeAssertionService, cT as startPasskeyEnrollmentService, cU as startPasskeyLoginService, cV as startSessionBindingDisableService, cW as startSessionRenewService, cX as startStepUpService, cY as startTotpEnrolmentService, cZ as stepUpService, c_ as sweepMfaChallengesService, c$ as sweepUnconfirmedMfaService, d0 as userPublicKeys, d1 as verifyCodeService, d2 as verifyMfaChallengeService, d3 as verifyOneTimeTokenService, d4 as verifySecondFactor } from './machine-principals-CdEgxOB1.js';
|
|
3
3
|
import * as drizzle_orm_pg_core from 'drizzle-orm/pg-core';
|
|
4
|
-
import {
|
|
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,
|
|
4
|
+
import { l as SocialProvider, K as KeyAlgorithmType, d as InvitationStatus, c as AccountDeletionRequestedBy, i as PurgeStrategy } from './types-CTdoTOxM.js';
|
|
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, j as SESSION_BINDINGS, k as SOCIAL_PROVIDERS, S as SessionBindingType, U as USER_STATUSES, m as UserStatus } from './types-CTdoTOxM.js';
|
|
6
6
|
import { UserProfile as UserProfile$1, ProfileInfo } from '@spfn/auth';
|
|
7
7
|
import { BaseRepository } from '@spfn/core/db';
|
|
8
8
|
import { c as ClientIdentity } from './wire-version-CtzMKvBB.js';
|
|
@@ -10,7 +10,7 @@ import { Context } from 'hono';
|
|
|
10
10
|
import * as _spfn_core_route from '@spfn/core/route';
|
|
11
11
|
import { NamedMiddleware } from '@spfn/core/route';
|
|
12
12
|
export { KeyPair, generateClientToken, generateKeyPair, generateKeyPairES256, generateKeyPairRS256, getKeySize, shouldRotateKey } from './crypto.js';
|
|
13
|
-
export { S as SessionData, g as getSessionInfo, i as isSafeReturnPath, s as sealSession, a as shouldRefreshSession, u as unsealSession } from './session-
|
|
13
|
+
export { S as SessionData, g as getSessionInfo, i as isSafeReturnPath, s as sealSession, a as shouldRefreshSession, u as unsealSession } from './session-BbhAGZtA.js';
|
|
14
14
|
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';
|
|
@@ -129,6 +129,16 @@ declare const COOKIE_NAMES: {
|
|
|
129
129
|
readonly SESSION_KEY_ID: string;
|
|
130
130
|
/** Pending OAuth session (privateKey, keyId, algorithm) - temporary during OAuth flow */
|
|
131
131
|
readonly OAUTH_PENDING: string;
|
|
132
|
+
/**
|
|
133
|
+
* Pending second-factor session (privateKey, keyId, challengeHash) (#95)
|
|
134
|
+
*
|
|
135
|
+
* Its own name and its own audience, separate from OAUTH_PENDING. The two
|
|
136
|
+
* coexist: a person who starts a social login in one tab while a password
|
|
137
|
+
* step-up is outstanding in another has both flows live, and one name would
|
|
138
|
+
* mean the second overwrote the first — sealing a session with a private key
|
|
139
|
+
* that does not match the key being activated.
|
|
140
|
+
*/
|
|
141
|
+
readonly MFA_PENDING: string;
|
|
132
142
|
/** OAuth CSRF nonce — double-submit against the (encrypted) state.nonce at callback */
|
|
133
143
|
readonly OAUTH_CSRF: string;
|
|
134
144
|
/** Password-setup session for verified-email signup — temporary, single-purpose */
|
|
@@ -341,6 +351,27 @@ declare function getCsrfMode(): CsrfMode;
|
|
|
341
351
|
* Get the paths exempted from the CSRF check (exact match, backend route paths)
|
|
342
352
|
*/
|
|
343
353
|
declare function getCsrfExemptPaths(): string[];
|
|
354
|
+
/**
|
|
355
|
+
* How long a key bound to a passkey lives, in milliseconds.
|
|
356
|
+
*
|
|
357
|
+
* A positive override is honoured; anything else falls back to the policy
|
|
358
|
+
* constant. Nothing refuses boot over it — unlike the passkey relying party, a
|
|
359
|
+
* nonsensical value here does not make every ceremony fail, it just means the
|
|
360
|
+
* default applies.
|
|
361
|
+
*/
|
|
362
|
+
declare function getBoundKeyTtlMs(): number;
|
|
363
|
+
/** How long past expiry a bound key may still be renewed, in milliseconds. */
|
|
364
|
+
declare function getBoundKeyRenewGraceMs(): number;
|
|
365
|
+
/** How close two sightings from two addresses must be to count as concurrent. */
|
|
366
|
+
declare function getConcurrentUseWindowMs(): number;
|
|
367
|
+
/**
|
|
368
|
+
* The page a bound session whose key expired is sent to.
|
|
369
|
+
*
|
|
370
|
+
* `RequireAuth` redirects here instead of to the sign-in page; the app renders a
|
|
371
|
+
* client component there that calls `renewSession(api)` and returns the person to
|
|
372
|
+
* where they were.
|
|
373
|
+
*/
|
|
374
|
+
declare function getSessionRenewPath(): string;
|
|
344
375
|
/**
|
|
345
376
|
* The relying party this deployment presents to authenticators, resolved.
|
|
346
377
|
*
|
|
@@ -405,6 +436,15 @@ interface MfaConfig {
|
|
|
405
436
|
issuer: string;
|
|
406
437
|
/** How long a device's step-up stays good for a sensitive change. */
|
|
407
438
|
stepUpWindowMs: number;
|
|
439
|
+
/**
|
|
440
|
+
* How long a new-device step-up challenge stays spendable.
|
|
441
|
+
*
|
|
442
|
+
* The window a person has to reach for their authenticator, and the window
|
|
443
|
+
* an attacker who has the password has to get past the second factor. Ten
|
|
444
|
+
* minutes is the same number the OAuth pending cookie and the link flows
|
|
445
|
+
* use, and the proxy's pending cookie is sealed for exactly this long.
|
|
446
|
+
*/
|
|
447
|
+
challengeTtlMs: number;
|
|
408
448
|
}
|
|
409
449
|
/**
|
|
410
450
|
* Resolve the second-factor configuration.
|
|
@@ -678,6 +718,36 @@ declare const users: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
678
718
|
identity: undefined;
|
|
679
719
|
generated: undefined;
|
|
680
720
|
}>;
|
|
721
|
+
sessionBinding: drizzle_orm_pg_core.PgBuildColumn<"users", drizzle_orm_pg_core.SetHasDefault<drizzle_orm_pg_core.SetNotNull<drizzle_orm_pg_core.PgTextBuilder<["none", "passkey"] & [string, ...string[]]>>>, {
|
|
722
|
+
name: string;
|
|
723
|
+
tableName: "users";
|
|
724
|
+
dataType: "string enum";
|
|
725
|
+
data: "none" | "passkey";
|
|
726
|
+
driverParam: string;
|
|
727
|
+
notNull: true;
|
|
728
|
+
hasDefault: true;
|
|
729
|
+
isPrimaryKey: false;
|
|
730
|
+
isAutoincrement: false;
|
|
731
|
+
hasRuntimeDefault: false;
|
|
732
|
+
enumValues: ["none", "passkey"] & [string, ...string[]];
|
|
733
|
+
identity: undefined;
|
|
734
|
+
generated: undefined;
|
|
735
|
+
}>;
|
|
736
|
+
sessionBindingChangedAt: drizzle_orm_pg_core.PgBuildColumn<"users", drizzle_orm_pg_core.PgTimestampBuilder, {
|
|
737
|
+
name: string;
|
|
738
|
+
tableName: "users";
|
|
739
|
+
dataType: "object date";
|
|
740
|
+
data: Date;
|
|
741
|
+
driverParam: string;
|
|
742
|
+
notNull: false;
|
|
743
|
+
hasDefault: false;
|
|
744
|
+
isPrimaryKey: false;
|
|
745
|
+
isAutoincrement: false;
|
|
746
|
+
hasRuntimeDefault: false;
|
|
747
|
+
enumValues: undefined;
|
|
748
|
+
identity: undefined;
|
|
749
|
+
generated: undefined;
|
|
750
|
+
}>;
|
|
681
751
|
lastLoginAt: drizzle_orm_pg_core.PgBuildColumn<"users", drizzle_orm_pg_core.PgTimestampBuilder, {
|
|
682
752
|
name: string;
|
|
683
753
|
tableName: "users";
|
|
@@ -725,6 +795,8 @@ declare function getUserByIdService(userId: number): Promise<{
|
|
|
725
795
|
emailVerifiedAt: Date | null;
|
|
726
796
|
phoneVerifiedAt: Date | null;
|
|
727
797
|
keyEpoch: number;
|
|
798
|
+
sessionBinding: "none" | "passkey";
|
|
799
|
+
sessionBindingChangedAt: Date | null;
|
|
728
800
|
lastLoginAt: Date | null;
|
|
729
801
|
}>;
|
|
730
802
|
/**
|
|
@@ -747,6 +819,8 @@ declare function getUserByEmailService(email: string): Promise<{
|
|
|
747
819
|
emailVerifiedAt: Date | null;
|
|
748
820
|
phoneVerifiedAt: Date | null;
|
|
749
821
|
keyEpoch: number;
|
|
822
|
+
sessionBinding: "none" | "passkey";
|
|
823
|
+
sessionBindingChangedAt: Date | null;
|
|
750
824
|
lastLoginAt: Date | null;
|
|
751
825
|
}>;
|
|
752
826
|
/**
|
|
@@ -769,6 +843,8 @@ declare function getUserByPhoneService(phone: string): Promise<{
|
|
|
769
843
|
emailVerifiedAt: Date | null;
|
|
770
844
|
phoneVerifiedAt: Date | null;
|
|
771
845
|
keyEpoch: number;
|
|
846
|
+
sessionBinding: "none" | "passkey";
|
|
847
|
+
sessionBindingChangedAt: Date | null;
|
|
772
848
|
lastLoginAt: Date | null;
|
|
773
849
|
}>;
|
|
774
850
|
/**
|
|
@@ -810,6 +886,8 @@ declare function updateUsernameService(userId: string | number | bigint, usernam
|
|
|
810
886
|
emailVerifiedAt: Date | null;
|
|
811
887
|
phoneVerifiedAt: Date | null;
|
|
812
888
|
keyEpoch: number;
|
|
889
|
+
sessionBinding: "none" | "passkey";
|
|
890
|
+
sessionBindingChangedAt: Date | null;
|
|
813
891
|
lastLoginAt: Date | null;
|
|
814
892
|
}>;
|
|
815
893
|
|
|
@@ -3158,326 +3236,6 @@ declare const userProfiles: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
3158
3236
|
type UserProfile = typeof userProfiles.$inferSelect;
|
|
3159
3237
|
type NewUserProfile = typeof userProfiles.$inferInsert;
|
|
3160
3238
|
|
|
3161
|
-
/**
|
|
3162
|
-
* @spfn/auth - User Public Keys Entity
|
|
3163
|
-
*
|
|
3164
|
-
* Stores client-generated public keys for JWT verification
|
|
3165
|
-
* Supports key rotation and multi-key management per user
|
|
3166
|
-
*/
|
|
3167
|
-
/**
|
|
3168
|
-
* User Public Keys Table
|
|
3169
|
-
* Each user can have multiple public keys (for rotation)
|
|
3170
|
-
*/
|
|
3171
|
-
declare const userPublicKeys: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
3172
|
-
name: "user_public_keys";
|
|
3173
|
-
schema: string;
|
|
3174
|
-
columns: {
|
|
3175
|
-
id: drizzle_orm_pg_core.PgBuildColumn<"user_public_keys", drizzle_orm_pg_core.SetIsPrimaryKey<drizzle_orm_pg_core.PgBigSerial53Builder>, {
|
|
3176
|
-
name: string;
|
|
3177
|
-
tableName: "user_public_keys";
|
|
3178
|
-
dataType: "number int53";
|
|
3179
|
-
data: number;
|
|
3180
|
-
driverParam: number;
|
|
3181
|
-
notNull: true;
|
|
3182
|
-
hasDefault: true;
|
|
3183
|
-
isPrimaryKey: false;
|
|
3184
|
-
isAutoincrement: false;
|
|
3185
|
-
hasRuntimeDefault: false;
|
|
3186
|
-
enumValues: undefined;
|
|
3187
|
-
identity: undefined;
|
|
3188
|
-
generated: undefined;
|
|
3189
|
-
}>;
|
|
3190
|
-
userId: drizzle_orm_pg_core.PgBuildColumn<"user_public_keys", drizzle_orm_pg_core.SetNotNull<drizzle_orm_pg_core.PgBigInt53Builder>, {
|
|
3191
|
-
name: string;
|
|
3192
|
-
tableName: "user_public_keys";
|
|
3193
|
-
dataType: "number int53";
|
|
3194
|
-
data: number;
|
|
3195
|
-
driverParam: string | number;
|
|
3196
|
-
notNull: true;
|
|
3197
|
-
hasDefault: false;
|
|
3198
|
-
isPrimaryKey: false;
|
|
3199
|
-
isAutoincrement: false;
|
|
3200
|
-
hasRuntimeDefault: false;
|
|
3201
|
-
enumValues: undefined;
|
|
3202
|
-
identity: undefined;
|
|
3203
|
-
generated: undefined;
|
|
3204
|
-
}>;
|
|
3205
|
-
keyId: drizzle_orm_pg_core.PgBuildColumn<"user_public_keys", drizzle_orm_pg_core.SetNotNull<drizzle_orm_pg_core.PgTextBuilder<[string, ...string[]]>>, {
|
|
3206
|
-
name: string;
|
|
3207
|
-
tableName: "user_public_keys";
|
|
3208
|
-
dataType: "string";
|
|
3209
|
-
data: string;
|
|
3210
|
-
driverParam: string;
|
|
3211
|
-
notNull: true;
|
|
3212
|
-
hasDefault: false;
|
|
3213
|
-
isPrimaryKey: false;
|
|
3214
|
-
isAutoincrement: false;
|
|
3215
|
-
hasRuntimeDefault: false;
|
|
3216
|
-
enumValues: undefined;
|
|
3217
|
-
identity: undefined;
|
|
3218
|
-
generated: undefined;
|
|
3219
|
-
}>;
|
|
3220
|
-
publicKey: drizzle_orm_pg_core.PgBuildColumn<"user_public_keys", drizzle_orm_pg_core.SetNotNull<drizzle_orm_pg_core.PgTextBuilder<[string, ...string[]]>>, {
|
|
3221
|
-
name: string;
|
|
3222
|
-
tableName: "user_public_keys";
|
|
3223
|
-
dataType: "string";
|
|
3224
|
-
data: string;
|
|
3225
|
-
driverParam: string;
|
|
3226
|
-
notNull: true;
|
|
3227
|
-
hasDefault: false;
|
|
3228
|
-
isPrimaryKey: false;
|
|
3229
|
-
isAutoincrement: false;
|
|
3230
|
-
hasRuntimeDefault: false;
|
|
3231
|
-
enumValues: undefined;
|
|
3232
|
-
identity: undefined;
|
|
3233
|
-
generated: undefined;
|
|
3234
|
-
}>;
|
|
3235
|
-
algorithm: drizzle_orm_pg_core.PgBuildColumn<"user_public_keys", drizzle_orm_pg_core.SetHasDefault<drizzle_orm_pg_core.SetNotNull<drizzle_orm_pg_core.PgTextBuilder<["ES256", "RS256"] & [string, ...string[]]>>>, {
|
|
3236
|
-
name: string;
|
|
3237
|
-
tableName: "user_public_keys";
|
|
3238
|
-
dataType: "string enum";
|
|
3239
|
-
data: "ES256" | "RS256";
|
|
3240
|
-
driverParam: string;
|
|
3241
|
-
notNull: true;
|
|
3242
|
-
hasDefault: true;
|
|
3243
|
-
isPrimaryKey: false;
|
|
3244
|
-
isAutoincrement: false;
|
|
3245
|
-
hasRuntimeDefault: false;
|
|
3246
|
-
enumValues: ["ES256", "RS256"] & [string, ...string[]];
|
|
3247
|
-
identity: undefined;
|
|
3248
|
-
generated: undefined;
|
|
3249
|
-
}>;
|
|
3250
|
-
fingerprint: drizzle_orm_pg_core.PgBuildColumn<"user_public_keys", drizzle_orm_pg_core.SetNotNull<drizzle_orm_pg_core.PgTextBuilder<[string, ...string[]]>>, {
|
|
3251
|
-
name: string;
|
|
3252
|
-
tableName: "user_public_keys";
|
|
3253
|
-
dataType: "string";
|
|
3254
|
-
data: string;
|
|
3255
|
-
driverParam: string;
|
|
3256
|
-
notNull: true;
|
|
3257
|
-
hasDefault: false;
|
|
3258
|
-
isPrimaryKey: false;
|
|
3259
|
-
isAutoincrement: false;
|
|
3260
|
-
hasRuntimeDefault: false;
|
|
3261
|
-
enumValues: undefined;
|
|
3262
|
-
identity: undefined;
|
|
3263
|
-
generated: undefined;
|
|
3264
|
-
}>;
|
|
3265
|
-
deviceName: drizzle_orm_pg_core.PgBuildColumn<"user_public_keys", drizzle_orm_pg_core.PgTextBuilder<[string, ...string[]]>, {
|
|
3266
|
-
name: string;
|
|
3267
|
-
tableName: "user_public_keys";
|
|
3268
|
-
dataType: "string";
|
|
3269
|
-
data: string;
|
|
3270
|
-
driverParam: string;
|
|
3271
|
-
notNull: false;
|
|
3272
|
-
hasDefault: false;
|
|
3273
|
-
isPrimaryKey: false;
|
|
3274
|
-
isAutoincrement: false;
|
|
3275
|
-
hasRuntimeDefault: false;
|
|
3276
|
-
enumValues: undefined;
|
|
3277
|
-
identity: undefined;
|
|
3278
|
-
generated: undefined;
|
|
3279
|
-
}>;
|
|
3280
|
-
platform: drizzle_orm_pg_core.PgBuildColumn<"user_public_keys", drizzle_orm_pg_core.PgTextBuilder<["ios", "android", "web", "desktop"] & [string, ...string[]]>, {
|
|
3281
|
-
name: string;
|
|
3282
|
-
tableName: "user_public_keys";
|
|
3283
|
-
dataType: "string enum";
|
|
3284
|
-
data: "ios" | "android" | "web" | "desktop";
|
|
3285
|
-
driverParam: string;
|
|
3286
|
-
notNull: false;
|
|
3287
|
-
hasDefault: false;
|
|
3288
|
-
isPrimaryKey: false;
|
|
3289
|
-
isAutoincrement: false;
|
|
3290
|
-
hasRuntimeDefault: false;
|
|
3291
|
-
enumValues: ["ios", "android", "web", "desktop"] & [string, ...string[]];
|
|
3292
|
-
identity: undefined;
|
|
3293
|
-
generated: undefined;
|
|
3294
|
-
}>;
|
|
3295
|
-
registeredIp: drizzle_orm_pg_core.PgBuildColumn<"user_public_keys", drizzle_orm_pg_core.PgTextBuilder<[string, ...string[]]>, {
|
|
3296
|
-
name: string;
|
|
3297
|
-
tableName: "user_public_keys";
|
|
3298
|
-
dataType: "string";
|
|
3299
|
-
data: string;
|
|
3300
|
-
driverParam: string;
|
|
3301
|
-
notNull: false;
|
|
3302
|
-
hasDefault: false;
|
|
3303
|
-
isPrimaryKey: false;
|
|
3304
|
-
isAutoincrement: false;
|
|
3305
|
-
hasRuntimeDefault: false;
|
|
3306
|
-
enumValues: undefined;
|
|
3307
|
-
identity: undefined;
|
|
3308
|
-
generated: undefined;
|
|
3309
|
-
}>;
|
|
3310
|
-
registeredUserAgent: drizzle_orm_pg_core.PgBuildColumn<"user_public_keys", drizzle_orm_pg_core.PgTextBuilder<[string, ...string[]]>, {
|
|
3311
|
-
name: string;
|
|
3312
|
-
tableName: "user_public_keys";
|
|
3313
|
-
dataType: "string";
|
|
3314
|
-
data: string;
|
|
3315
|
-
driverParam: string;
|
|
3316
|
-
notNull: false;
|
|
3317
|
-
hasDefault: false;
|
|
3318
|
-
isPrimaryKey: false;
|
|
3319
|
-
isAutoincrement: false;
|
|
3320
|
-
hasRuntimeDefault: false;
|
|
3321
|
-
enumValues: undefined;
|
|
3322
|
-
identity: undefined;
|
|
3323
|
-
generated: undefined;
|
|
3324
|
-
}>;
|
|
3325
|
-
clientKind: drizzle_orm_pg_core.PgBuildColumn<"user_public_keys", drizzle_orm_pg_core.PgTextBuilder<["web", "ios", "android"] & [string, ...string[]]>, {
|
|
3326
|
-
name: string;
|
|
3327
|
-
tableName: "user_public_keys";
|
|
3328
|
-
dataType: "string enum";
|
|
3329
|
-
data: "ios" | "android" | "web";
|
|
3330
|
-
driverParam: string;
|
|
3331
|
-
notNull: false;
|
|
3332
|
-
hasDefault: false;
|
|
3333
|
-
isPrimaryKey: false;
|
|
3334
|
-
isAutoincrement: false;
|
|
3335
|
-
hasRuntimeDefault: false;
|
|
3336
|
-
enumValues: ["web", "ios", "android"] & [string, ...string[]];
|
|
3337
|
-
identity: undefined;
|
|
3338
|
-
generated: undefined;
|
|
3339
|
-
}>;
|
|
3340
|
-
clientVersion: drizzle_orm_pg_core.PgBuildColumn<"user_public_keys", drizzle_orm_pg_core.PgTextBuilder<[string, ...string[]]>, {
|
|
3341
|
-
name: string;
|
|
3342
|
-
tableName: "user_public_keys";
|
|
3343
|
-
dataType: "string";
|
|
3344
|
-
data: string;
|
|
3345
|
-
driverParam: string;
|
|
3346
|
-
notNull: false;
|
|
3347
|
-
hasDefault: false;
|
|
3348
|
-
isPrimaryKey: false;
|
|
3349
|
-
isAutoincrement: false;
|
|
3350
|
-
hasRuntimeDefault: false;
|
|
3351
|
-
enumValues: undefined;
|
|
3352
|
-
identity: undefined;
|
|
3353
|
-
generated: undefined;
|
|
3354
|
-
}>;
|
|
3355
|
-
clientContractVersion: drizzle_orm_pg_core.PgBuildColumn<"user_public_keys", drizzle_orm_pg_core.PgTextBuilder<[string, ...string[]]>, {
|
|
3356
|
-
name: string;
|
|
3357
|
-
tableName: "user_public_keys";
|
|
3358
|
-
dataType: "string";
|
|
3359
|
-
data: string;
|
|
3360
|
-
driverParam: string;
|
|
3361
|
-
notNull: false;
|
|
3362
|
-
hasDefault: false;
|
|
3363
|
-
isPrimaryKey: false;
|
|
3364
|
-
isAutoincrement: false;
|
|
3365
|
-
hasRuntimeDefault: false;
|
|
3366
|
-
enumValues: undefined;
|
|
3367
|
-
identity: undefined;
|
|
3368
|
-
generated: undefined;
|
|
3369
|
-
}>;
|
|
3370
|
-
clientSeenAt: drizzle_orm_pg_core.PgBuildColumn<"user_public_keys", drizzle_orm_pg_core.PgTimestampBuilder, {
|
|
3371
|
-
name: string;
|
|
3372
|
-
tableName: "user_public_keys";
|
|
3373
|
-
dataType: "object date";
|
|
3374
|
-
data: Date;
|
|
3375
|
-
driverParam: string;
|
|
3376
|
-
notNull: false;
|
|
3377
|
-
hasDefault: false;
|
|
3378
|
-
isPrimaryKey: false;
|
|
3379
|
-
isAutoincrement: false;
|
|
3380
|
-
hasRuntimeDefault: false;
|
|
3381
|
-
enumValues: undefined;
|
|
3382
|
-
identity: undefined;
|
|
3383
|
-
generated: undefined;
|
|
3384
|
-
}>;
|
|
3385
|
-
isActive: drizzle_orm_pg_core.PgBuildColumn<"user_public_keys", drizzle_orm_pg_core.SetHasDefault<drizzle_orm_pg_core.SetNotNull<drizzle_orm_pg_core.PgBooleanBuilder>>, {
|
|
3386
|
-
name: string;
|
|
3387
|
-
tableName: "user_public_keys";
|
|
3388
|
-
dataType: "boolean";
|
|
3389
|
-
data: boolean;
|
|
3390
|
-
driverParam: boolean;
|
|
3391
|
-
notNull: true;
|
|
3392
|
-
hasDefault: true;
|
|
3393
|
-
isPrimaryKey: false;
|
|
3394
|
-
isAutoincrement: false;
|
|
3395
|
-
hasRuntimeDefault: false;
|
|
3396
|
-
enumValues: undefined;
|
|
3397
|
-
identity: undefined;
|
|
3398
|
-
generated: undefined;
|
|
3399
|
-
}>;
|
|
3400
|
-
createdAt: drizzle_orm_pg_core.PgBuildColumn<"user_public_keys", drizzle_orm_pg_core.SetHasDefault<drizzle_orm_pg_core.SetNotNull<drizzle_orm_pg_core.PgTimestampBuilder>>, {
|
|
3401
|
-
name: string;
|
|
3402
|
-
tableName: "user_public_keys";
|
|
3403
|
-
dataType: "object date";
|
|
3404
|
-
data: Date;
|
|
3405
|
-
driverParam: string;
|
|
3406
|
-
notNull: true;
|
|
3407
|
-
hasDefault: true;
|
|
3408
|
-
isPrimaryKey: false;
|
|
3409
|
-
isAutoincrement: false;
|
|
3410
|
-
hasRuntimeDefault: false;
|
|
3411
|
-
enumValues: undefined;
|
|
3412
|
-
identity: undefined;
|
|
3413
|
-
generated: undefined;
|
|
3414
|
-
}>;
|
|
3415
|
-
lastUsedAt: drizzle_orm_pg_core.PgBuildColumn<"user_public_keys", drizzle_orm_pg_core.PgTimestampBuilder, {
|
|
3416
|
-
name: string;
|
|
3417
|
-
tableName: "user_public_keys";
|
|
3418
|
-
dataType: "object date";
|
|
3419
|
-
data: Date;
|
|
3420
|
-
driverParam: string;
|
|
3421
|
-
notNull: false;
|
|
3422
|
-
hasDefault: false;
|
|
3423
|
-
isPrimaryKey: false;
|
|
3424
|
-
isAutoincrement: false;
|
|
3425
|
-
hasRuntimeDefault: false;
|
|
3426
|
-
enumValues: undefined;
|
|
3427
|
-
identity: undefined;
|
|
3428
|
-
generated: undefined;
|
|
3429
|
-
}>;
|
|
3430
|
-
expiresAt: drizzle_orm_pg_core.PgBuildColumn<"user_public_keys", drizzle_orm_pg_core.PgTimestampBuilder, {
|
|
3431
|
-
name: string;
|
|
3432
|
-
tableName: "user_public_keys";
|
|
3433
|
-
dataType: "object date";
|
|
3434
|
-
data: Date;
|
|
3435
|
-
driverParam: string;
|
|
3436
|
-
notNull: false;
|
|
3437
|
-
hasDefault: false;
|
|
3438
|
-
isPrimaryKey: false;
|
|
3439
|
-
isAutoincrement: false;
|
|
3440
|
-
hasRuntimeDefault: false;
|
|
3441
|
-
enumValues: undefined;
|
|
3442
|
-
identity: undefined;
|
|
3443
|
-
generated: undefined;
|
|
3444
|
-
}>;
|
|
3445
|
-
revokedAt: drizzle_orm_pg_core.PgBuildColumn<"user_public_keys", drizzle_orm_pg_core.PgTimestampBuilder, {
|
|
3446
|
-
name: string;
|
|
3447
|
-
tableName: "user_public_keys";
|
|
3448
|
-
dataType: "object date";
|
|
3449
|
-
data: Date;
|
|
3450
|
-
driverParam: string;
|
|
3451
|
-
notNull: false;
|
|
3452
|
-
hasDefault: false;
|
|
3453
|
-
isPrimaryKey: false;
|
|
3454
|
-
isAutoincrement: false;
|
|
3455
|
-
hasRuntimeDefault: false;
|
|
3456
|
-
enumValues: undefined;
|
|
3457
|
-
identity: undefined;
|
|
3458
|
-
generated: undefined;
|
|
3459
|
-
}>;
|
|
3460
|
-
revokedReason: drizzle_orm_pg_core.PgBuildColumn<"user_public_keys", drizzle_orm_pg_core.PgTextBuilder<[string, ...string[]]>, {
|
|
3461
|
-
name: string;
|
|
3462
|
-
tableName: "user_public_keys";
|
|
3463
|
-
dataType: "string";
|
|
3464
|
-
data: string;
|
|
3465
|
-
driverParam: string;
|
|
3466
|
-
notNull: false;
|
|
3467
|
-
hasDefault: false;
|
|
3468
|
-
isPrimaryKey: false;
|
|
3469
|
-
isAutoincrement: false;
|
|
3470
|
-
hasRuntimeDefault: false;
|
|
3471
|
-
enumValues: undefined;
|
|
3472
|
-
identity: undefined;
|
|
3473
|
-
generated: undefined;
|
|
3474
|
-
}>;
|
|
3475
|
-
};
|
|
3476
|
-
dialect: "pg";
|
|
3477
|
-
}>;
|
|
3478
|
-
type UserPublicKey = typeof userPublicKeys.$inferSelect;
|
|
3479
|
-
type NewUserPublicKey = typeof userPublicKeys.$inferInsert;
|
|
3480
|
-
|
|
3481
3239
|
/**
|
|
3482
3240
|
* @spfn/auth - User Social Accounts Entity
|
|
3483
3241
|
*
|
|
@@ -4429,8 +4187,15 @@ type NewKeyRevokeAllToken = typeof keyRevokeAllTokens.$inferInsert;
|
|
|
4429
4187
|
* direction that matters most — an assertion collected as a second factor is
|
|
4430
4188
|
* not a sign-in, and `passkeys/login/verify` refuses it for exactly the reason
|
|
4431
4189
|
* the column exists.
|
|
4190
|
+
*
|
|
4191
|
+
* `'renewal'` is the fourth: the assertion that renews a bound session key, and
|
|
4192
|
+
* the one that lets an account leave `session_binding: 'passkey'`. It is its own
|
|
4193
|
+
* kind rather than a reused `'authentication'` because that kind's challenge is
|
|
4194
|
+
* minted for nobody in particular — a discoverable sign-in names no account —
|
|
4195
|
+
* while a renewal challenge is bound to the account it was issued for, and
|
|
4196
|
+
* spending one where the other was expected would cross those two rules.
|
|
4432
4197
|
*/
|
|
4433
|
-
declare const WEBAUTHN_CHALLENGE_KINDS: readonly ["registration", "authentication", "mfa"];
|
|
4198
|
+
declare const WEBAUTHN_CHALLENGE_KINDS: readonly ["registration", "authentication", "mfa", "renewal"];
|
|
4434
4199
|
type WebAuthnChallengeKind = typeof WEBAUTHN_CHALLENGE_KINDS[number];
|
|
4435
4200
|
declare const webauthnChallenges: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
4436
4201
|
name: "webauthn_challenges";
|
|
@@ -4466,18 +4231,18 @@ declare const webauthnChallenges: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
4466
4231
|
identity: undefined;
|
|
4467
4232
|
generated: undefined;
|
|
4468
4233
|
}>;
|
|
4469
|
-
kind: drizzle_orm_pg_core.PgBuildColumn<"webauthn_challenges", drizzle_orm_pg_core.SetNotNull<drizzle_orm_pg_core.PgTextBuilder<["registration", "authentication", "mfa"] & [string, ...string[]]>>, {
|
|
4234
|
+
kind: drizzle_orm_pg_core.PgBuildColumn<"webauthn_challenges", drizzle_orm_pg_core.SetNotNull<drizzle_orm_pg_core.PgTextBuilder<["registration", "authentication", "mfa", "renewal"] & [string, ...string[]]>>, {
|
|
4470
4235
|
name: string;
|
|
4471
4236
|
tableName: "webauthn_challenges";
|
|
4472
4237
|
dataType: "string enum";
|
|
4473
|
-
data: "registration" | "authentication" | "mfa";
|
|
4238
|
+
data: "registration" | "authentication" | "mfa" | "renewal";
|
|
4474
4239
|
driverParam: string;
|
|
4475
4240
|
notNull: true;
|
|
4476
4241
|
hasDefault: false;
|
|
4477
4242
|
isPrimaryKey: false;
|
|
4478
4243
|
isAutoincrement: false;
|
|
4479
4244
|
hasRuntimeDefault: false;
|
|
4480
|
-
enumValues: ["registration", "authentication", "mfa"] & [string, ...string[]];
|
|
4245
|
+
enumValues: ["registration", "authentication", "mfa", "renewal"] & [string, ...string[]];
|
|
4481
4246
|
identity: undefined;
|
|
4482
4247
|
generated: undefined;
|
|
4483
4248
|
}>;
|
|
@@ -6273,6 +6038,17 @@ type NewAuthMetadataEntity = typeof authMetadata.$inferInsert;
|
|
|
6273
6038
|
* - 타입 안전성
|
|
6274
6039
|
*/
|
|
6275
6040
|
declare class UsersRepository extends BaseRepository {
|
|
6041
|
+
/**
|
|
6042
|
+
* The account's current key generation.
|
|
6043
|
+
*
|
|
6044
|
+
* Read from the primary, and this is the one place that matters: the value
|
|
6045
|
+
* is stamped onto a second-factor challenge that must die with the
|
|
6046
|
+
* generation it was minted in, and a replica lagging behind a revoke-all
|
|
6047
|
+
* would stamp the generation that has just ended.
|
|
6048
|
+
*
|
|
6049
|
+
* Write primary 사용
|
|
6050
|
+
*/
|
|
6051
|
+
currentKeyEpoch(id: number): Promise<number>;
|
|
6276
6052
|
/**
|
|
6277
6053
|
* ID로 사용자 조회
|
|
6278
6054
|
* Read replica 사용
|
|
@@ -6294,6 +6070,8 @@ declare class UsersRepository extends BaseRepository {
|
|
|
6294
6070
|
emailVerifiedAt: Date | null;
|
|
6295
6071
|
phoneVerifiedAt: Date | null;
|
|
6296
6072
|
keyEpoch: number;
|
|
6073
|
+
sessionBinding: "none" | "passkey";
|
|
6074
|
+
sessionBindingChangedAt: Date | null;
|
|
6297
6075
|
lastLoginAt: Date | null;
|
|
6298
6076
|
}>;
|
|
6299
6077
|
/**
|
|
@@ -6320,6 +6098,8 @@ declare class UsersRepository extends BaseRepository {
|
|
|
6320
6098
|
emailVerifiedAt: Date | null;
|
|
6321
6099
|
phoneVerifiedAt: Date | null;
|
|
6322
6100
|
keyEpoch: number;
|
|
6101
|
+
sessionBinding: "none" | "passkey";
|
|
6102
|
+
sessionBindingChangedAt: Date | null;
|
|
6323
6103
|
lastLoginAt: Date | null;
|
|
6324
6104
|
}>;
|
|
6325
6105
|
/**
|
|
@@ -6357,6 +6137,8 @@ declare class UsersRepository extends BaseRepository {
|
|
|
6357
6137
|
emailVerifiedAt: Date | null;
|
|
6358
6138
|
phoneVerifiedAt: Date | null;
|
|
6359
6139
|
keyEpoch: number;
|
|
6140
|
+
sessionBinding: "none" | "passkey";
|
|
6141
|
+
sessionBindingChangedAt: Date | null;
|
|
6360
6142
|
lastLoginAt: Date | null;
|
|
6361
6143
|
}>;
|
|
6362
6144
|
/**
|
|
@@ -6390,6 +6172,8 @@ declare class UsersRepository extends BaseRepository {
|
|
|
6390
6172
|
emailVerifiedAt: Date | null;
|
|
6391
6173
|
phoneVerifiedAt: Date | null;
|
|
6392
6174
|
keyEpoch: number;
|
|
6175
|
+
sessionBinding: "none" | "passkey";
|
|
6176
|
+
sessionBindingChangedAt: Date | null;
|
|
6393
6177
|
lastLoginAt: Date | null;
|
|
6394
6178
|
}>;
|
|
6395
6179
|
/**
|
|
@@ -6413,6 +6197,8 @@ declare class UsersRepository extends BaseRepository {
|
|
|
6413
6197
|
emailVerifiedAt: Date | null;
|
|
6414
6198
|
phoneVerifiedAt: Date | null;
|
|
6415
6199
|
keyEpoch: number;
|
|
6200
|
+
sessionBinding: "none" | "passkey";
|
|
6201
|
+
sessionBindingChangedAt: Date | null;
|
|
6416
6202
|
lastLoginAt: Date | null;
|
|
6417
6203
|
}>;
|
|
6418
6204
|
/**
|
|
@@ -6436,6 +6222,8 @@ declare class UsersRepository extends BaseRepository {
|
|
|
6436
6222
|
emailVerifiedAt: Date | null;
|
|
6437
6223
|
phoneVerifiedAt: Date | null;
|
|
6438
6224
|
keyEpoch: number;
|
|
6225
|
+
sessionBinding: "none" | "passkey";
|
|
6226
|
+
sessionBindingChangedAt: Date | null;
|
|
6439
6227
|
lastLoginAt: Date | null;
|
|
6440
6228
|
}>;
|
|
6441
6229
|
/**
|
|
@@ -6459,6 +6247,8 @@ declare class UsersRepository extends BaseRepository {
|
|
|
6459
6247
|
emailVerifiedAt: Date | null;
|
|
6460
6248
|
phoneVerifiedAt: Date | null;
|
|
6461
6249
|
keyEpoch: number;
|
|
6250
|
+
sessionBinding: "none" | "passkey";
|
|
6251
|
+
sessionBindingChangedAt: Date | null;
|
|
6462
6252
|
lastLoginAt: Date | null;
|
|
6463
6253
|
}>;
|
|
6464
6254
|
/**
|
|
@@ -6482,6 +6272,8 @@ declare class UsersRepository extends BaseRepository {
|
|
|
6482
6272
|
emailVerifiedAt: Date | null;
|
|
6483
6273
|
phoneVerifiedAt: Date | null;
|
|
6484
6274
|
keyEpoch: number;
|
|
6275
|
+
sessionBinding: "none" | "passkey";
|
|
6276
|
+
sessionBindingChangedAt: Date | null;
|
|
6485
6277
|
lastLoginAt: Date | null;
|
|
6486
6278
|
} | null>;
|
|
6487
6279
|
/**
|
|
@@ -6508,6 +6300,8 @@ declare class UsersRepository extends BaseRepository {
|
|
|
6508
6300
|
emailVerifiedAt: Date | null;
|
|
6509
6301
|
phoneVerifiedAt: Date | null;
|
|
6510
6302
|
keyEpoch: number;
|
|
6303
|
+
sessionBinding: "none" | "passkey";
|
|
6304
|
+
sessionBindingChangedAt: Date | null;
|
|
6511
6305
|
lastLoginAt: Date | null;
|
|
6512
6306
|
};
|
|
6513
6307
|
role: {
|
|
@@ -6526,6 +6320,7 @@ declare class UsersRepository extends BaseRepository {
|
|
|
6526
6320
|
status: "active" | "inactive" | "suspended" | "pending_deletion" | "deleted";
|
|
6527
6321
|
publicId: string;
|
|
6528
6322
|
passwordChangeRequired: boolean;
|
|
6323
|
+
sessionBinding: "none" | "passkey";
|
|
6529
6324
|
id: number;
|
|
6530
6325
|
username: string | null;
|
|
6531
6326
|
passwordHash: string | null;
|
|
@@ -6535,6 +6330,7 @@ declare class UsersRepository extends BaseRepository {
|
|
|
6535
6330
|
emailVerifiedAt: Date | null;
|
|
6536
6331
|
phoneVerifiedAt: Date | null;
|
|
6537
6332
|
keyEpoch: number;
|
|
6333
|
+
sessionBindingChangedAt: Date | null;
|
|
6538
6334
|
lastLoginAt: Date | null;
|
|
6539
6335
|
deletedAt: Date | null;
|
|
6540
6336
|
deletedBy: string | null;
|
|
@@ -6605,6 +6401,8 @@ declare class UsersRepository extends BaseRepository {
|
|
|
6605
6401
|
emailVerifiedAt: Date | null;
|
|
6606
6402
|
phoneVerifiedAt: Date | null;
|
|
6607
6403
|
keyEpoch: number;
|
|
6404
|
+
sessionBinding: "none" | "passkey";
|
|
6405
|
+
sessionBindingChangedAt: Date | null;
|
|
6608
6406
|
lastLoginAt: Date | null;
|
|
6609
6407
|
}>;
|
|
6610
6408
|
/**
|
|
@@ -6633,6 +6431,8 @@ declare class UsersRepository extends BaseRepository {
|
|
|
6633
6431
|
emailVerifiedAt: Date | null;
|
|
6634
6432
|
phoneVerifiedAt: Date | null;
|
|
6635
6433
|
keyEpoch: number;
|
|
6434
|
+
sessionBinding: "none" | "passkey";
|
|
6435
|
+
sessionBindingChangedAt: Date | null;
|
|
6636
6436
|
lastLoginAt: Date | null;
|
|
6637
6437
|
}>;
|
|
6638
6438
|
/**
|
|
@@ -6656,6 +6456,8 @@ declare class UsersRepository extends BaseRepository {
|
|
|
6656
6456
|
emailVerifiedAt: Date | null;
|
|
6657
6457
|
phoneVerifiedAt: Date | null;
|
|
6658
6458
|
keyEpoch: number;
|
|
6459
|
+
sessionBinding: "none" | "passkey";
|
|
6460
|
+
sessionBindingChangedAt: Date | null;
|
|
6659
6461
|
lastLoginAt: Date | null;
|
|
6660
6462
|
}>;
|
|
6661
6463
|
/**
|
|
@@ -6679,6 +6481,8 @@ declare class UsersRepository extends BaseRepository {
|
|
|
6679
6481
|
emailVerifiedAt: Date | null;
|
|
6680
6482
|
phoneVerifiedAt: Date | null;
|
|
6681
6483
|
keyEpoch: number;
|
|
6484
|
+
sessionBinding: "none" | "passkey";
|
|
6485
|
+
sessionBindingChangedAt: Date | null;
|
|
6682
6486
|
lastLoginAt: Date | null;
|
|
6683
6487
|
}>;
|
|
6684
6488
|
/**
|
|
@@ -6691,6 +6495,7 @@ declare class UsersRepository extends BaseRepository {
|
|
|
6691
6495
|
status: "active" | "inactive" | "suspended" | "pending_deletion" | "deleted";
|
|
6692
6496
|
publicId: string;
|
|
6693
6497
|
passwordChangeRequired: boolean;
|
|
6498
|
+
sessionBinding: "none" | "passkey";
|
|
6694
6499
|
id: number;
|
|
6695
6500
|
username: string | null;
|
|
6696
6501
|
passwordHash: string | null;
|
|
@@ -6700,6 +6505,7 @@ declare class UsersRepository extends BaseRepository {
|
|
|
6700
6505
|
emailVerifiedAt: Date | null;
|
|
6701
6506
|
phoneVerifiedAt: Date | null;
|
|
6702
6507
|
keyEpoch: number;
|
|
6508
|
+
sessionBindingChangedAt: Date | null;
|
|
6703
6509
|
lastLoginAt: Date | null;
|
|
6704
6510
|
deletedAt: Date | null;
|
|
6705
6511
|
deletedBy: string | null;
|
|
@@ -6803,11 +6609,17 @@ declare class KeysRepository extends BaseRepository {
|
|
|
6803
6609
|
platform: "ios" | "android" | "web" | "desktop" | null;
|
|
6804
6610
|
registeredIp: string | null;
|
|
6805
6611
|
registeredUserAgent: string | null;
|
|
6612
|
+
registeredUaFamily: string | null;
|
|
6613
|
+
lastSeenIp: string | null;
|
|
6614
|
+
lastSeenAt: Date | null;
|
|
6615
|
+
concurrentUseAt: Date | null;
|
|
6616
|
+
binding: "none" | "passkey";
|
|
6806
6617
|
clientKind: "ios" | "android" | "web" | null;
|
|
6807
6618
|
clientVersion: string | null;
|
|
6808
6619
|
clientContractVersion: string | null;
|
|
6809
6620
|
clientSeenAt: Date | null;
|
|
6810
6621
|
isActive: boolean;
|
|
6622
|
+
pendingMfaChallengeId: number | null;
|
|
6811
6623
|
createdAt: Date;
|
|
6812
6624
|
lastUsedAt: Date | null;
|
|
6813
6625
|
expiresAt: Date | null;
|
|
@@ -6829,11 +6641,17 @@ declare class KeysRepository extends BaseRepository {
|
|
|
6829
6641
|
platform: "ios" | "android" | "web" | "desktop" | null;
|
|
6830
6642
|
registeredIp: string | null;
|
|
6831
6643
|
registeredUserAgent: string | null;
|
|
6644
|
+
registeredUaFamily: string | null;
|
|
6645
|
+
lastSeenIp: string | null;
|
|
6646
|
+
lastSeenAt: Date | null;
|
|
6647
|
+
concurrentUseAt: Date | null;
|
|
6648
|
+
binding: "none" | "passkey";
|
|
6832
6649
|
clientKind: "ios" | "android" | "web" | null;
|
|
6833
6650
|
clientVersion: string | null;
|
|
6834
6651
|
clientContractVersion: string | null;
|
|
6835
6652
|
clientSeenAt: Date | null;
|
|
6836
6653
|
isActive: boolean;
|
|
6654
|
+
pendingMfaChallengeId: number | null;
|
|
6837
6655
|
createdAt: Date;
|
|
6838
6656
|
lastUsedAt: Date | null;
|
|
6839
6657
|
expiresAt: Date | null;
|
|
@@ -6855,11 +6673,17 @@ declare class KeysRepository extends BaseRepository {
|
|
|
6855
6673
|
platform: "ios" | "android" | "web" | "desktop" | null;
|
|
6856
6674
|
registeredIp: string | null;
|
|
6857
6675
|
registeredUserAgent: string | null;
|
|
6676
|
+
registeredUaFamily: string | null;
|
|
6677
|
+
lastSeenIp: string | null;
|
|
6678
|
+
lastSeenAt: Date | null;
|
|
6679
|
+
concurrentUseAt: Date | null;
|
|
6680
|
+
binding: "none" | "passkey";
|
|
6858
6681
|
clientKind: "ios" | "android" | "web" | null;
|
|
6859
6682
|
clientVersion: string | null;
|
|
6860
6683
|
clientContractVersion: string | null;
|
|
6861
6684
|
clientSeenAt: Date | null;
|
|
6862
6685
|
isActive: boolean;
|
|
6686
|
+
pendingMfaChallengeId: number | null;
|
|
6863
6687
|
createdAt: Date;
|
|
6864
6688
|
lastUsedAt: Date | null;
|
|
6865
6689
|
expiresAt: Date | null;
|
|
@@ -6874,6 +6698,16 @@ declare class KeysRepository extends BaseRepository {
|
|
|
6874
6698
|
*
|
|
6875
6699
|
* `includeRevoked`는 이미 끊은 기기까지 보여준다 — "내가 언제 무엇을 끊었나"를
|
|
6876
6700
|
* 확인하는 용도라, 폐기 시각과 사유를 함께 고른다.
|
|
6701
|
+
*
|
|
6702
|
+
* `lastSeenIp` is not selected, deliberately. The concurrent-use moment is
|
|
6703
|
+
* what the owner acts on; the trail of addresses behind it is stored PII the
|
|
6704
|
+
* account surface has no use for.
|
|
6705
|
+
*
|
|
6706
|
+
* A key still waiting on a second factor is excluded in **both** modes
|
|
6707
|
+
* (#95). It is not a device that can sign, so it does not belong in the
|
|
6708
|
+
* default list; and it is not a device the owner signed out either, so it
|
|
6709
|
+
* does not belong in the revoked one — where it would read exactly like a
|
|
6710
|
+
* revoked key with no revocation time, which is a different thing entirely.
|
|
6877
6711
|
* Read replica 사용
|
|
6878
6712
|
*/
|
|
6879
6713
|
listForUser(userId: number, includeRevoked?: boolean): Promise<{
|
|
@@ -6889,6 +6723,8 @@ declare class KeysRepository extends BaseRepository {
|
|
|
6889
6723
|
revokedAt: Date | null;
|
|
6890
6724
|
registeredIp: string | null;
|
|
6891
6725
|
registeredUserAgent: string | null;
|
|
6726
|
+
binding: "none" | "passkey";
|
|
6727
|
+
concurrentUseAt: Date | null;
|
|
6892
6728
|
}[]>;
|
|
6893
6729
|
/**
|
|
6894
6730
|
* 공개키 생성
|
|
@@ -6910,10 +6746,16 @@ declare class KeysRepository extends BaseRepository {
|
|
|
6910
6746
|
lastUsedAt: Date | null;
|
|
6911
6747
|
registeredIp: string | null;
|
|
6912
6748
|
registeredUserAgent: string | null;
|
|
6749
|
+
registeredUaFamily: string | null;
|
|
6750
|
+
lastSeenIp: string | null;
|
|
6751
|
+
lastSeenAt: Date | null;
|
|
6752
|
+
concurrentUseAt: Date | null;
|
|
6753
|
+
binding: "none" | "passkey";
|
|
6913
6754
|
clientKind: "ios" | "android" | "web" | null;
|
|
6914
6755
|
clientVersion: string | null;
|
|
6915
6756
|
clientContractVersion: string | null;
|
|
6916
6757
|
clientSeenAt: Date | null;
|
|
6758
|
+
pendingMfaChallengeId: number | null;
|
|
6917
6759
|
revokedReason: string | null;
|
|
6918
6760
|
}>;
|
|
6919
6761
|
/**
|
|
@@ -6937,11 +6779,17 @@ declare class KeysRepository extends BaseRepository {
|
|
|
6937
6779
|
platform: "ios" | "android" | "web" | "desktop" | null;
|
|
6938
6780
|
registeredIp: string | null;
|
|
6939
6781
|
registeredUserAgent: string | null;
|
|
6782
|
+
registeredUaFamily: string | null;
|
|
6783
|
+
lastSeenIp: string | null;
|
|
6784
|
+
lastSeenAt: Date | null;
|
|
6785
|
+
concurrentUseAt: Date | null;
|
|
6786
|
+
binding: "none" | "passkey";
|
|
6940
6787
|
clientKind: "ios" | "android" | "web" | null;
|
|
6941
6788
|
clientVersion: string | null;
|
|
6942
6789
|
clientContractVersion: string | null;
|
|
6943
6790
|
clientSeenAt: Date | null;
|
|
6944
6791
|
isActive: boolean;
|
|
6792
|
+
pendingMfaChallengeId: number | null;
|
|
6945
6793
|
createdAt: Date;
|
|
6946
6794
|
lastUsedAt: Date | null;
|
|
6947
6795
|
expiresAt: Date | null;
|
|
@@ -6977,6 +6825,17 @@ declare class KeysRepository extends BaseRepository {
|
|
|
6977
6825
|
* active keys still had its generation ended, and an outstanding
|
|
6978
6826
|
* sign-out-everywhere link must die with it.
|
|
6979
6827
|
*
|
|
6828
|
+
* The two second-factor CTEs are here for the same "no caller can forget"
|
|
6829
|
+
* reason (#95). A pending key is `is_active = false`, so the UPDATE below
|
|
6830
|
+
* does not touch it and neither would anything else: the owner who sees an
|
|
6831
|
+
* unexpected second-factor prompt and does exactly what the notice says —
|
|
6832
|
+
* change the password, sign out everywhere, open the revoke-all link, run a
|
|
6833
|
+
* reset — would otherwise leave the attacker's pending key and its live
|
|
6834
|
+
* challenge untouched. Deleting the key cascades onto its challenge; the
|
|
6835
|
+
* expiry beside it catches a challenge whose key is already gone. A pending
|
|
6836
|
+
* row and an active row are disjoint sets, so the two statements never
|
|
6837
|
+
* contend for the same row.
|
|
6838
|
+
*
|
|
6980
6839
|
* Write primary 사용
|
|
6981
6840
|
*/
|
|
6982
6841
|
private revokeActive;
|
|
@@ -7000,10 +6859,16 @@ declare class KeysRepository extends BaseRepository {
|
|
|
7000
6859
|
lastUsedAt: Date | null;
|
|
7001
6860
|
registeredIp: string | null;
|
|
7002
6861
|
registeredUserAgent: string | null;
|
|
6862
|
+
registeredUaFamily: string | null;
|
|
6863
|
+
lastSeenIp: string | null;
|
|
6864
|
+
lastSeenAt: Date | null;
|
|
6865
|
+
concurrentUseAt: Date | null;
|
|
6866
|
+
binding: "none" | "passkey";
|
|
7003
6867
|
clientKind: "ios" | "android" | "web" | null;
|
|
7004
6868
|
clientVersion: string | null;
|
|
7005
6869
|
clientContractVersion: string | null;
|
|
7006
6870
|
clientSeenAt: Date | null;
|
|
6871
|
+
pendingMfaChallengeId: number | null;
|
|
7007
6872
|
revokedReason: string | null;
|
|
7008
6873
|
}>;
|
|
7009
6874
|
/**
|
|
@@ -7029,11 +6894,17 @@ declare class KeysRepository extends BaseRepository {
|
|
|
7029
6894
|
platform: "ios" | "android" | "web" | "desktop" | null;
|
|
7030
6895
|
registeredIp: string | null;
|
|
7031
6896
|
registeredUserAgent: string | null;
|
|
6897
|
+
registeredUaFamily: string | null;
|
|
6898
|
+
lastSeenIp: string | null;
|
|
6899
|
+
lastSeenAt: Date | null;
|
|
6900
|
+
concurrentUseAt: Date | null;
|
|
6901
|
+
binding: "none" | "passkey";
|
|
7032
6902
|
clientKind: "ios" | "android" | "web" | null;
|
|
7033
6903
|
clientVersion: string | null;
|
|
7034
6904
|
clientContractVersion: string | null;
|
|
7035
6905
|
clientSeenAt: Date | null;
|
|
7036
6906
|
isActive: boolean;
|
|
6907
|
+
pendingMfaChallengeId: number | null;
|
|
7037
6908
|
createdAt: Date;
|
|
7038
6909
|
lastUsedAt: Date | null;
|
|
7039
6910
|
expiresAt: Date | null;
|
|
@@ -7055,17 +6926,68 @@ declare class KeysRepository extends BaseRepository {
|
|
|
7055
6926
|
platform: "ios" | "android" | "web" | "desktop" | null;
|
|
7056
6927
|
registeredIp: string | null;
|
|
7057
6928
|
registeredUserAgent: string | null;
|
|
6929
|
+
registeredUaFamily: string | null;
|
|
6930
|
+
lastSeenIp: string | null;
|
|
6931
|
+
lastSeenAt: Date | null;
|
|
6932
|
+
concurrentUseAt: Date | null;
|
|
6933
|
+
binding: "none" | "passkey";
|
|
6934
|
+
clientKind: "ios" | "android" | "web" | null;
|
|
6935
|
+
clientVersion: string | null;
|
|
6936
|
+
clientContractVersion: string | null;
|
|
6937
|
+
clientSeenAt: Date | null;
|
|
6938
|
+
isActive: boolean;
|
|
6939
|
+
pendingMfaChallengeId: number | null;
|
|
6940
|
+
createdAt: Date;
|
|
6941
|
+
lastUsedAt: Date | null;
|
|
6942
|
+
expiresAt: Date | null;
|
|
6943
|
+
revokedAt: Date | null;
|
|
6944
|
+
revokedReason: string | null;
|
|
6945
|
+
}>;
|
|
6946
|
+
/**
|
|
6947
|
+
* Bind one live key to the account's passkey, and give it the short life
|
|
6948
|
+
* that goes with it.
|
|
6949
|
+
*
|
|
6950
|
+
* Scoped by user and by `isActive`, like every other targeted update here, so
|
|
6951
|
+
* the answer is "this call bound something" rather than "a row exists".
|
|
6952
|
+
* Write primary 사용
|
|
6953
|
+
*/
|
|
6954
|
+
bindByKeyIdAndUserId(keyId: string, userId: number, expiresAt: Date): Promise<{
|
|
6955
|
+
id: number;
|
|
6956
|
+
userId: number;
|
|
6957
|
+
keyId: string;
|
|
6958
|
+
publicKey: string;
|
|
6959
|
+
algorithm: "ES256" | "RS256";
|
|
6960
|
+
fingerprint: string;
|
|
6961
|
+
deviceName: string | null;
|
|
6962
|
+
platform: "ios" | "android" | "web" | "desktop" | null;
|
|
6963
|
+
registeredIp: string | null;
|
|
6964
|
+
registeredUserAgent: string | null;
|
|
6965
|
+
registeredUaFamily: string | null;
|
|
6966
|
+
lastSeenIp: string | null;
|
|
6967
|
+
lastSeenAt: Date | null;
|
|
6968
|
+
concurrentUseAt: Date | null;
|
|
6969
|
+
binding: "none" | "passkey";
|
|
7058
6970
|
clientKind: "ios" | "android" | "web" | null;
|
|
7059
6971
|
clientVersion: string | null;
|
|
7060
6972
|
clientContractVersion: string | null;
|
|
7061
6973
|
clientSeenAt: Date | null;
|
|
7062
6974
|
isActive: boolean;
|
|
6975
|
+
pendingMfaChallengeId: number | null;
|
|
7063
6976
|
createdAt: Date;
|
|
7064
6977
|
lastUsedAt: Date | null;
|
|
7065
6978
|
expiresAt: Date | null;
|
|
7066
6979
|
revokedAt: Date | null;
|
|
7067
6980
|
revokedReason: string | null;
|
|
7068
6981
|
}>;
|
|
6982
|
+
/**
|
|
6983
|
+
* Return every one of a user's bound keys to an ordinary long-lived key.
|
|
6984
|
+
*
|
|
6985
|
+
* One statement, because turning the setting off has to leave no key behind:
|
|
6986
|
+
* a row still marked `'passkey'` would keep expiring in hours with nothing
|
|
6987
|
+
* left to renew it, and its owner has just said they do not want that.
|
|
6988
|
+
* Write primary 사용
|
|
6989
|
+
*/
|
|
6990
|
+
unbindActiveByUserId(userId: number, expiresAt: Date): Promise<number>;
|
|
7069
6991
|
/**
|
|
7070
6992
|
* Key ID로 공개키 조회 — 활성 여부 무관 (clientProofV1 admission의 revocation 판정용)
|
|
7071
6993
|
*
|
|
@@ -7084,11 +7006,17 @@ declare class KeysRepository extends BaseRepository {
|
|
|
7084
7006
|
platform: "ios" | "android" | "web" | "desktop" | null;
|
|
7085
7007
|
registeredIp: string | null;
|
|
7086
7008
|
registeredUserAgent: string | null;
|
|
7009
|
+
registeredUaFamily: string | null;
|
|
7010
|
+
lastSeenIp: string | null;
|
|
7011
|
+
lastSeenAt: Date | null;
|
|
7012
|
+
concurrentUseAt: Date | null;
|
|
7013
|
+
binding: "none" | "passkey";
|
|
7087
7014
|
clientKind: "ios" | "android" | "web" | null;
|
|
7088
7015
|
clientVersion: string | null;
|
|
7089
7016
|
clientContractVersion: string | null;
|
|
7090
7017
|
clientSeenAt: Date | null;
|
|
7091
7018
|
isActive: boolean;
|
|
7019
|
+
pendingMfaChallengeId: number | null;
|
|
7092
7020
|
createdAt: Date;
|
|
7093
7021
|
lastUsedAt: Date | null;
|
|
7094
7022
|
expiresAt: Date | null;
|
|
@@ -7110,11 +7038,17 @@ declare class KeysRepository extends BaseRepository {
|
|
|
7110
7038
|
platform: "ios" | "android" | "web" | "desktop" | null;
|
|
7111
7039
|
registeredIp: string | null;
|
|
7112
7040
|
registeredUserAgent: string | null;
|
|
7041
|
+
registeredUaFamily: string | null;
|
|
7042
|
+
lastSeenIp: string | null;
|
|
7043
|
+
lastSeenAt: Date | null;
|
|
7044
|
+
concurrentUseAt: Date | null;
|
|
7045
|
+
binding: "none" | "passkey";
|
|
7113
7046
|
clientKind: "ios" | "android" | "web" | null;
|
|
7114
7047
|
clientVersion: string | null;
|
|
7115
7048
|
clientContractVersion: string | null;
|
|
7116
7049
|
clientSeenAt: Date | null;
|
|
7117
7050
|
isActive: boolean;
|
|
7051
|
+
pendingMfaChallengeId: number | null;
|
|
7118
7052
|
createdAt: Date;
|
|
7119
7053
|
lastUsedAt: Date | null;
|
|
7120
7054
|
expiresAt: Date | null;
|
|
@@ -7140,8 +7074,28 @@ declare class KeysRepository extends BaseRepository {
|
|
|
7140
7074
|
* `clientSeenAt` moves only when one of the three values differs from what is
|
|
7141
7075
|
* stored, so it answers "since when has this device been on this release"
|
|
7142
7076
|
* rather than "when was it last seen", which lastUsedAt already answers.
|
|
7077
|
+
*
|
|
7078
|
+
* `ip` is the client address this request resolved to, or null when none did.
|
|
7079
|
+
* It joins this statement rather than getting one of its own: the rule the
|
|
7080
|
+
* concurrent-use signal needs — write the address, and move
|
|
7081
|
+
* `concurrentUseAt` when it differs from the stored one inside the window —
|
|
7082
|
+
* is the rule already implemented here, and a second fire-and-forget write
|
|
7083
|
+
* beside it would double the per-request write on the authenticated path. It
|
|
7084
|
+
* is also why the comparison is a `CASE` over the stored value rather than a
|
|
7085
|
+
* read followed by a write: the row comes off the read replica, and a
|
|
7086
|
+
* replica-lagged address compared in application code both misses real
|
|
7087
|
+
* switches and invents ones that did not happen.
|
|
7088
|
+
*/
|
|
7089
|
+
updateLastUsedById(id: number, identity?: ClientIdentity | null, ip?: string | null): Promise<void>;
|
|
7090
|
+
/**
|
|
7091
|
+
* The boundary a previous sighting has to be newer than to count as concurrent.
|
|
7092
|
+
*
|
|
7093
|
+
* Computed here rather than written as `now() - interval` so that the moment
|
|
7094
|
+
* the row is stamped with and the moment the window is measured from are the
|
|
7095
|
+
* same one — a statement that used the database clock for the boundary and
|
|
7096
|
+
* ours for the value would disagree with itself by the round trip.
|
|
7143
7097
|
*/
|
|
7144
|
-
|
|
7098
|
+
private concurrentUseSince;
|
|
7145
7099
|
}
|
|
7146
7100
|
declare const keysRepository: KeysRepository;
|
|
7147
7101
|
|
|
@@ -7791,6 +7745,108 @@ declare class MfaVerificationsRepository extends BaseRepository {
|
|
|
7791
7745
|
}
|
|
7792
7746
|
declare const mfaVerificationsRepository: MfaVerificationsRepository;
|
|
7793
7747
|
|
|
7748
|
+
/**
|
|
7749
|
+
* MFA Challenges Repository
|
|
7750
|
+
*
|
|
7751
|
+
* Data access for the row that stands between a registered-but-inactive key and
|
|
7752
|
+
* a session. Extends BaseRepository for transaction-context detection and
|
|
7753
|
+
* read/write splitting.
|
|
7754
|
+
*
|
|
7755
|
+
* Every lookup here is by `challenge_hash` and never by id. The secret is what
|
|
7756
|
+
* the caller holds; the hash is what this table has, so a row can only be found
|
|
7757
|
+
* by someone who already had the secret — a guess reaches no row at all, which
|
|
7758
|
+
* is what keeps a guess from touching another challenge's `attempts`.
|
|
7759
|
+
*/
|
|
7760
|
+
|
|
7761
|
+
declare class MfaChallengesRepository extends BaseRepository {
|
|
7762
|
+
/** Park a fresh challenge. The caller has already written the pending key. */
|
|
7763
|
+
create(data: NewMfaChallenge): Promise<MfaChallenge>;
|
|
7764
|
+
/**
|
|
7765
|
+
* The challenge this secret names, whatever state it is in.
|
|
7766
|
+
*
|
|
7767
|
+
* Reads the primary rather than the replica: `verify` decides whether a key
|
|
7768
|
+
* becomes usable, and a replica lagging behind the 202 that created the row
|
|
7769
|
+
* would refuse a challenge the caller was handed a moment ago.
|
|
7770
|
+
*/
|
|
7771
|
+
findByHash(challengeHash: string): Promise<MfaChallenge | null>;
|
|
7772
|
+
/**
|
|
7773
|
+
* The live challenge already outstanding for this key, if there is one.
|
|
7774
|
+
*
|
|
7775
|
+
* What makes a retried registration resume rather than collide: a native
|
|
7776
|
+
* client reusing its keyId, or an OAuth state replayed from the back button,
|
|
7777
|
+
* gets the challenge it was already given instead of a 409 about a key it
|
|
7778
|
+
* does own.
|
|
7779
|
+
*/
|
|
7780
|
+
findLiveByKeyId(userId: number, keyId: string): Promise<MfaChallenge | null>;
|
|
7781
|
+
/**
|
|
7782
|
+
* Spend the challenge, or answer false because somebody else already did.
|
|
7783
|
+
*
|
|
7784
|
+
* A conditional UPDATE and not a read followed by a write: two verifies
|
|
7785
|
+
* arriving together would both pass a read, and a challenge is single use.
|
|
7786
|
+
* Every condition the caller checked is restated here, so the row that is
|
|
7787
|
+
* marked is a row that was still spendable at the moment it was marked.
|
|
7788
|
+
*/
|
|
7789
|
+
markVerified(id: number, keyEpoch: number): Promise<boolean>;
|
|
7790
|
+
/**
|
|
7791
|
+
* Count a wrong proof, and say whether that was the last one allowed.
|
|
7792
|
+
*
|
|
7793
|
+
* The increment is on the row the presented secret actually hashed to, which
|
|
7794
|
+
* is the whole reason lookup is by hash: there is no id for a caller to name,
|
|
7795
|
+
* so no counter but their own can be moved.
|
|
7796
|
+
*/
|
|
7797
|
+
countFailure(id: number): Promise<boolean>;
|
|
7798
|
+
/**
|
|
7799
|
+
* Point an inactive key at the challenge that gates it.
|
|
7800
|
+
*
|
|
7801
|
+
* A second statement rather than a column on the insert, because the
|
|
7802
|
+
* challenge references the key: the key row has to exist before the
|
|
7803
|
+
* challenge can, so the back-reference is written once both do. Both run
|
|
7804
|
+
* inside the registering route's transaction.
|
|
7805
|
+
*/
|
|
7806
|
+
markKeyPending(keyId: string, challengeId: number): Promise<void>;
|
|
7807
|
+
/**
|
|
7808
|
+
* Give a live challenge a fresh secret, leaving everything else alone.
|
|
7809
|
+
*
|
|
7810
|
+
* What a retried registration gets. The row keeps its id, its expiry and its
|
|
7811
|
+
* spent attempts, so retrying is not a way to reset the counter or buy
|
|
7812
|
+
* another ten minutes; only the secret is new, because the old one was never
|
|
7813
|
+
* stored and cannot be handed out twice.
|
|
7814
|
+
*/
|
|
7815
|
+
resecret(id: number, challengeHash: string): Promise<boolean>;
|
|
7816
|
+
/**
|
|
7817
|
+
* Delete the pending key a challenge was gating, which takes the challenge
|
|
7818
|
+
* with it through the cascade.
|
|
7819
|
+
*
|
|
7820
|
+
* Scoped to `pending_mfa_challenge_id`, so a key that has since been
|
|
7821
|
+
* activated is never deleted by a late failure or a sweep.
|
|
7822
|
+
*/
|
|
7823
|
+
dropPendingKey(keyId: string, challengeId: number): Promise<void>;
|
|
7824
|
+
/**
|
|
7825
|
+
* Mark a key active and no longer pending — what a verified challenge buys.
|
|
7826
|
+
*
|
|
7827
|
+
* Conditioned on the challenge id, so this can only activate the key that
|
|
7828
|
+
* challenge was minted for.
|
|
7829
|
+
*/
|
|
7830
|
+
activateKey(keyId: string, challengeId: number): Promise<void>;
|
|
7831
|
+
/**
|
|
7832
|
+
* Clear out challenges nobody finished, and the keys they were gating.
|
|
7833
|
+
*
|
|
7834
|
+
* Counted from the read rather than from either delete, because the two
|
|
7835
|
+
* overlap: deleting a pending key cascades onto its challenge, so the second
|
|
7836
|
+
* statement finds only the challenges whose key had already gone some other
|
|
7837
|
+
* way — and a count taken there would report a sweep that did nothing.
|
|
7838
|
+
*
|
|
7839
|
+
* A spent challenge is kept for the same span as an expired one, so a replay
|
|
7840
|
+
* inside the window meets "already verified" from a row rather than
|
|
7841
|
+
* "unknown" from an absence. The 401 is the same either way; the record is
|
|
7842
|
+
* not.
|
|
7843
|
+
*
|
|
7844
|
+
* @returns how many challenge rows are gone
|
|
7845
|
+
*/
|
|
7846
|
+
sweepFinished(cutoff: Date): Promise<number>;
|
|
7847
|
+
}
|
|
7848
|
+
declare const mfaChallengesRepository: MfaChallengesRepository;
|
|
7849
|
+
|
|
7794
7850
|
/**
|
|
7795
7851
|
* MFA Enrolment Repository
|
|
7796
7852
|
*
|
|
@@ -9088,9 +9144,9 @@ declare class AccountDeletionRequestsRepository extends BaseRepository {
|
|
|
9088
9144
|
cancelledAt: Date | null;
|
|
9089
9145
|
completedAt: Date | null;
|
|
9090
9146
|
userPublicId: string;
|
|
9091
|
-
requestedAt: Date;
|
|
9092
9147
|
requestedBy: "admin" | "self";
|
|
9093
9148
|
purgeStrategy: "anonymize" | "hard-delete" | null;
|
|
9149
|
+
requestedAt: Date;
|
|
9094
9150
|
}>;
|
|
9095
9151
|
/**
|
|
9096
9152
|
* 요청 취소 (복구)
|
|
@@ -9661,6 +9717,31 @@ declare function verifyKeyFingerprint(publicKeyB64: string, expectedFingerprint:
|
|
|
9661
9717
|
*/
|
|
9662
9718
|
declare function assertKeyMatchesAlgorithm(publicKeyB64: string, algorithm: KeyAlgorithmType): void;
|
|
9663
9719
|
|
|
9720
|
+
/**
|
|
9721
|
+
* Whether a key may sign a renewal — the one clause that differs from `authenticate`.
|
|
9722
|
+
*
|
|
9723
|
+
* Bound, and within its grace. Early renewal is allowed, because a browser that
|
|
9724
|
+
* asks a minute before its key runs out should not have to wait for the failure
|
|
9725
|
+
* first; late renewal is allowed for the grace window, so a laptop closed over a
|
|
9726
|
+
* long weekend comes back to one prompt instead of a sign-in. Past it there is
|
|
9727
|
+
* nothing to continue, and an unbound key was never in this ceremony at all.
|
|
9728
|
+
*/
|
|
9729
|
+
declare function admitsForRenewal(key: UserPublicKey): boolean;
|
|
9730
|
+
/**
|
|
9731
|
+
* Renewal authentication middleware
|
|
9732
|
+
*
|
|
9733
|
+
* Auto-skips the global `auth` middleware, the way `optionalAuth` does: a route
|
|
9734
|
+
* that carries this one must not also be asked for a live key.
|
|
9735
|
+
*
|
|
9736
|
+
* @example
|
|
9737
|
+
* ```typescript
|
|
9738
|
+
* export const sessionRenewOptions = route.post('/_auth/session/renew/options')
|
|
9739
|
+
* .use([authenticateForRenewal])
|
|
9740
|
+
* .handler(async (c) => startSessionRenewService({ expiredKeyId: getAuth(c).keyId }));
|
|
9741
|
+
* ```
|
|
9742
|
+
*/
|
|
9743
|
+
declare const authenticateForRenewal: _spfn_core_route.NamedMiddleware<"authForRenewal">;
|
|
9744
|
+
|
|
9664
9745
|
/**
|
|
9665
9746
|
* @spfn/auth - Permission Middleware
|
|
9666
9747
|
*
|
|
@@ -10008,6 +10089,7 @@ declare function getUser(c: Context | {
|
|
|
10008
10089
|
status: "active" | "inactive" | "suspended" | "pending_deletion" | "deleted";
|
|
10009
10090
|
publicId: string;
|
|
10010
10091
|
passwordChangeRequired: boolean;
|
|
10092
|
+
sessionBinding: "none" | "passkey";
|
|
10011
10093
|
id: number;
|
|
10012
10094
|
username: string | null;
|
|
10013
10095
|
passwordHash: string | null;
|
|
@@ -10017,6 +10099,7 @@ declare function getUser(c: Context | {
|
|
|
10017
10099
|
emailVerifiedAt: Date | null;
|
|
10018
10100
|
phoneVerifiedAt: Date | null;
|
|
10019
10101
|
keyEpoch: number;
|
|
10102
|
+
sessionBindingChangedAt: Date | null;
|
|
10020
10103
|
lastLoginAt: Date | null;
|
|
10021
10104
|
deletedAt: Date | null;
|
|
10022
10105
|
deletedBy: string | null;
|
|
@@ -11011,4 +11094,4 @@ declare const authJobRouter: _spfn_core_job.JobRouter<{
|
|
|
11011
11094
|
*/
|
|
11012
11095
|
declare const createAuthDeletionJobRouter: typeof createAuthJobRouter;
|
|
11013
11096
|
|
|
11014
|
-
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, MFA_CONFIRM_ATTEMPT_LIMIT, type MfaConfig, MfaEnrolmentRepository, type MfaRecoveryCode, MfaRecoveryCodesRepository, type MfaTotp, MfaTotpRepository, MfaVerification, MfaVerificationMethod, MfaVerificationsRepository, type NewAccountDeletionRequest, type NewAuthMetadataEntity, type NewDeviceAuthorization, type NewInvitation, type NewKeyRevokeAllToken, type NewMfaRecoveryCode, type NewMfaTotp, 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,
|
|
11097
|
+
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, MFA_CONFIRM_ATTEMPT_LIMIT, MfaChallenge, MfaChallengesRepository, type MfaConfig, MfaEnrolmentRepository, type MfaRecoveryCode, MfaRecoveryCodesRepository, type MfaTotp, MfaTotpRepository, MfaVerification, MfaVerificationMethod, MfaVerificationsRepository, type NewAccountDeletionRequest, type NewAuthMetadataEntity, type NewDeviceAuthorization, type NewInvitation, type NewKeyRevokeAllToken, NewMfaChallenge, type NewMfaRecoveryCode, type NewMfaTotp, 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, 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 TokenEncryptionKey, type TokenPayload, USER_CODE_ALPHABET, USER_CODE_LENGTH, type UpdateProfileParams, type User, type UserPermission, UserPermissionsRepository, type UserProfile, UserProfilesRepository, UserPublicKey, type UserSocialAccount, UsersRepository, V2_PREFIX, type VerificationCode, VerificationCodesRepository, VerificationPurpose, type VerifiedOAuth2AccessToken, type VerifiedOpsToken, type VerifyIdTokenParams, WEBAUTHN_CHALLENGE_KINDS, type WebAuthnChallenge, type WebAuthnChallengeKind, WebAuthnChallengesRepository, acceptInvitation, accountDeletionRequests, accountDeletionRequestsRepository, addPermissionToRole, admitsForRenewal, appleProvider, assertAuthorizationServerIssuer, assertCanAssignRole, assertKeyMatchesAlgorithm, assertPasskeyConfig, authJobRouter, authLogger, authMetadata, authMetadataRepository, authSchema, authenticateForRenewal, 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, getBoundKeyRenewGraceMs, getBoundKeyTtlMs, getConcurrentUseWindowMs, getCsrfExemptPaths, getCsrfMode, getDeletionConfig, getDeviceAuthConfig, getDummyPasswordHash, getEncryptionKeyring, getGoogleAuthUrl, getGoogleOAuthConfig, getGoogleUserInfo, getInvitationByToken, getInvitationWithDetails, getKeyId, getLocale, getMfaConfig, getOneTimeTokenManager, getOpsToken, getOptionalAuth, getPasskeyConfig, getPendingDeletionInfo, getRole, getRoleByName, getRolePermissions, getSessionRenewPath, 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, mfaChallengesRepository, mfaEnrolmentRepository, mfaRecoveryCodes, mfaRecoveryCodesRepository, mfaTotp, mfaTotpRepository, mfaVerificationsRepository, 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, userSocialAccounts, users, usersRepository, validateInvitation, validatePasswordStrength, verificationCodes, verificationCodesRepository, verifyAccessToken, verifyClientToken, verifyIdToken, verifyKeyFingerprint, verifyOAuthState, verifyOpsTokenService, verifyPassword, verifyToken, webauthnChallenges, webauthnChallengesRepository };
|