@spfn/auth 0.3.0-beta.4 → 0.3.0-beta.6
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 +101 -0
- package/dist/{authenticate-Ctul07Sc.d.ts → authenticate-98lBIMxP.d.ts} +115 -1
- package/dist/config.d.ts +60 -0
- package/dist/config.js +27 -0
- package/dist/config.js.map +1 -1
- package/dist/errors.d.ts +39 -2
- package/dist/errors.js +24 -0
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +29 -2
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -1
- package/dist/nextjs/api.js +58 -1
- package/dist/nextjs/api.js.map +1 -1
- package/dist/nextjs/server.js +4 -0
- package/dist/nextjs/server.js.map +1 -1
- package/dist/server.d.ts +442 -7
- package/dist/server.js +933 -383
- package/dist/server.js.map +1 -1
- package/migrations/20260810112144_colorful_tomorrow_man/migration.sql +18 -0
- package/migrations/20260810112144_colorful_tomorrow_man/snapshot.json +3576 -0
- package/package.json +2 -2
package/dist/server.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as AuthInitOptions,
|
|
2
|
-
export {
|
|
1
|
+
import { A as AuthInitOptions, n as OAuthProvider, k as VerificationPurpose, i as PermissionCategory, o as AuthContext } from './authenticate-98lBIMxP.js';
|
|
2
|
+
export { p as AuthProfileOutcome, q as AuthProfileVerifier, r as ChangePasswordParams, s as CompleteSignupParams, t as ConfirmSignupLinkParams, C as ConfirmSignupLinkResult, D as DeviceNameSchema, E as EmailSchema, I as IssueOneTimeTokenResult, u as KEY_FINGERPRINT_PREFIX_LENGTH, K as KeySummary, v as LoginParams, L as LoginResult, w as LogoutParams, N as NativeVerifyOptions, x as NormalizedIdentity, y as OAuthCallbackParams, z as OAuthCallbackResult, B as OAuthCodeExchangeOptions, F as OAuthNativeParams, e as OAuthNativeResult, G as OAuthStartParams, O as OAuthStartResult, H as OAuthTokens, J as PasswordSchema, M as PhoneSchema, Q as PlatformSchema, T as RegisterParams, W as RegisterPublicKeyParams, a as RegisterResult, X as RequestSignupLinkParams, b as RequestSignupLinkResult, Y as RevokeAllKeysParams, d as RevokeAllKeysResult, Z as RevokeKeyParams, _ as RotateKeyParams, c as RotateKeyResult, $ as SendVerificationCodeParams, S as SendVerificationCodeResult, a0 as TargetTypeSchema, a1 as UnlinkNotification, a2 as UnlinkNotifyRejection, a3 as UnlinkNotifyRequest, a4 as UnlinkNotifyResult, V as VERIFICATION_PURPOSES, j as VERIFICATION_TARGET_TYPES, a5 as VerificationPurposeSchema, l as VerificationTargetType, a6 as VerifyCodeParams, a7 as VerifyCodeResult, m as authRouter, a8 as authenticate, a9 as buildOAuthErrorUrl, aa as changePasswordService, ab as completeSignupService, ac as confirmSignupLinkService, ad as getEnabledOAuthProviders, ae as getGoogleAccessToken, af as getOAuthProvider, ag as getRegisteredProviders, ah as isOAuthProviderEnabled, ai as isSafeReturnPath, aj as issueOneTimeTokenService, ak as listKeysService, al as loginService, am as logoutService, an as oauthCallbackService, ao as oauthNativeService, ap as oauthStartService, aq as oauthUnlinkNotifyService, ar as optionalAuth, as as registerOAuthProvider, at as registerPublicKeyService, au as registerService, av as requestSignupLinkService, aw as requireEnabledProvider, ax as resolveAuthenticatedUser, ay as revokeAllKeysService, az as revokeKeyService, aA as rotateKeyService, aB as runAuthProfile, aC as selectAuthProfile, aD as sendVerificationCodeService, aE as verifyCodeService, aF as verifyOneTimeTokenService } from './authenticate-98lBIMxP.js';
|
|
3
3
|
import * as drizzle_orm_pg_core from 'drizzle-orm/pg-core';
|
|
4
4
|
import { K as KeyAlgorithmType, d as InvitationStatus, j as SocialProvider, 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';
|
|
@@ -431,6 +431,42 @@ declare function updateUsernameService(userId: string | number | bigint, usernam
|
|
|
431
431
|
*/
|
|
432
432
|
declare function initializeAuth(options?: AuthInitOptions): Promise<void>;
|
|
433
433
|
|
|
434
|
+
/**
|
|
435
|
+
* @spfn/auth - Stored email normalization
|
|
436
|
+
*
|
|
437
|
+
* Brings existing rows into the canonical form the repository now writes and
|
|
438
|
+
* reads. Without it, normalizing the code alone would lock out every account
|
|
439
|
+
* whose address was stored with any capitalization: the lookup folds the typed
|
|
440
|
+
* address to lower case, the stored one stays mixed, and they stop matching.
|
|
441
|
+
*
|
|
442
|
+
* Runs once at startup and records that it ran, so a healthy install pays one
|
|
443
|
+
* small metadata read per boot rather than a scan of the users table.
|
|
444
|
+
*
|
|
445
|
+
* The work itself stays in the database — one query to find the addresses two
|
|
446
|
+
* rows would share, one statement to fold the rest. Nothing proportional to the
|
|
447
|
+
* table is carried through the application, which is what keeps a legacy
|
|
448
|
+
* install's first boot from turning into a row-at-a-time migration.
|
|
449
|
+
*/
|
|
450
|
+
interface EmailNormalizationResult {
|
|
451
|
+
/** Rows rewritten to canonical form. */
|
|
452
|
+
normalized: number;
|
|
453
|
+
/** User id groups that share an address once folded, left untouched. */
|
|
454
|
+
conflicts: number[][];
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* Rewrite stored addresses to canonical form, skipping anything that would
|
|
458
|
+
* collide.
|
|
459
|
+
*
|
|
460
|
+
* A collision means two accounts differ only by capitalization. Which of them is
|
|
461
|
+
* the real one, and what happens to the other's data, is not a question this can
|
|
462
|
+
* answer — so every row in the group is left exactly as it is and all of their
|
|
463
|
+
* ids are reported. The alternative, merging or deleting one, destroys an
|
|
464
|
+
* account on a guess.
|
|
465
|
+
*
|
|
466
|
+
* @returns what was rewritten and what was left for an operator
|
|
467
|
+
*/
|
|
468
|
+
declare function normalizeStoredEmails(): Promise<EmailNormalizationResult>;
|
|
469
|
+
|
|
434
470
|
/**
|
|
435
471
|
* @spfn/auth - Permission Service
|
|
436
472
|
*
|
|
@@ -3057,6 +3093,209 @@ declare const verificationCodes: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
3057
3093
|
type VerificationCode = typeof verificationCodes.$inferSelect;
|
|
3058
3094
|
type NewVerificationCode = typeof verificationCodes.$inferInsert;
|
|
3059
3095
|
|
|
3096
|
+
/**
|
|
3097
|
+
* @spfn/auth - Signup Link Tokens Entity
|
|
3098
|
+
*
|
|
3099
|
+
* Backs the verified-email signup flow: a one-time confirmation link is emailed,
|
|
3100
|
+
* opening it mints a short-lived setup session, and setting a password on that
|
|
3101
|
+
* session creates the account.
|
|
3102
|
+
*
|
|
3103
|
+
* A separate table from `verification_codes` on purpose. That table stores its
|
|
3104
|
+
* six-digit code in plaintext, which is acceptable for a short-lived numeric code
|
|
3105
|
+
* bounded by an attempt counter, but a link token is a bearer credential sitting
|
|
3106
|
+
* in someone's mailbox and must only ever be stored as a hash. Sharing one table
|
|
3107
|
+
* would make "plaintext or hash" a per-row property that nothing enforces.
|
|
3108
|
+
*/
|
|
3109
|
+
declare const signupLinkTokens: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
3110
|
+
name: "signup_link_tokens";
|
|
3111
|
+
schema: string;
|
|
3112
|
+
columns: {
|
|
3113
|
+
createdAt: drizzle_orm_pg_core.PgBuildColumn<"signup_link_tokens", drizzle_orm_pg_core.SetNotNull<drizzle_orm_pg_core.SetHasDefault<drizzle_orm_pg_core.PgTimestampBuilder>>, {
|
|
3114
|
+
name: string;
|
|
3115
|
+
tableName: "signup_link_tokens";
|
|
3116
|
+
dataType: "object date";
|
|
3117
|
+
data: Date;
|
|
3118
|
+
driverParam: string;
|
|
3119
|
+
notNull: true;
|
|
3120
|
+
hasDefault: true;
|
|
3121
|
+
isPrimaryKey: false;
|
|
3122
|
+
isAutoincrement: false;
|
|
3123
|
+
hasRuntimeDefault: false;
|
|
3124
|
+
enumValues: undefined;
|
|
3125
|
+
identity: undefined;
|
|
3126
|
+
generated: undefined;
|
|
3127
|
+
}>;
|
|
3128
|
+
updatedAt: drizzle_orm_pg_core.PgBuildColumn<"signup_link_tokens", drizzle_orm_pg_core.SetHasDefault<drizzle_orm_pg_core.SetNotNull<drizzle_orm_pg_core.SetHasDefault<drizzle_orm_pg_core.PgTimestampBuilder>>>, {
|
|
3129
|
+
name: string;
|
|
3130
|
+
tableName: "signup_link_tokens";
|
|
3131
|
+
dataType: "object date";
|
|
3132
|
+
data: Date;
|
|
3133
|
+
driverParam: string;
|
|
3134
|
+
notNull: true;
|
|
3135
|
+
hasDefault: true;
|
|
3136
|
+
isPrimaryKey: false;
|
|
3137
|
+
isAutoincrement: false;
|
|
3138
|
+
hasRuntimeDefault: false;
|
|
3139
|
+
enumValues: undefined;
|
|
3140
|
+
identity: undefined;
|
|
3141
|
+
generated: undefined;
|
|
3142
|
+
}>;
|
|
3143
|
+
id: drizzle_orm_pg_core.PgBuildColumn<"signup_link_tokens", drizzle_orm_pg_core.SetIsPrimaryKey<drizzle_orm_pg_core.PgBigSerial53Builder>, {
|
|
3144
|
+
name: string;
|
|
3145
|
+
tableName: "signup_link_tokens";
|
|
3146
|
+
dataType: "number int53";
|
|
3147
|
+
data: number;
|
|
3148
|
+
driverParam: number;
|
|
3149
|
+
notNull: true;
|
|
3150
|
+
hasDefault: true;
|
|
3151
|
+
isPrimaryKey: false;
|
|
3152
|
+
isAutoincrement: false;
|
|
3153
|
+
hasRuntimeDefault: false;
|
|
3154
|
+
enumValues: undefined;
|
|
3155
|
+
identity: undefined;
|
|
3156
|
+
generated: undefined;
|
|
3157
|
+
}>;
|
|
3158
|
+
email: drizzle_orm_pg_core.PgBuildColumn<"signup_link_tokens", drizzle_orm_pg_core.SetNotNull<drizzle_orm_pg_core.PgTextBuilder<[string, ...string[]]>>, {
|
|
3159
|
+
name: string;
|
|
3160
|
+
tableName: "signup_link_tokens";
|
|
3161
|
+
dataType: "string";
|
|
3162
|
+
data: string;
|
|
3163
|
+
driverParam: string;
|
|
3164
|
+
notNull: true;
|
|
3165
|
+
hasDefault: false;
|
|
3166
|
+
isPrimaryKey: false;
|
|
3167
|
+
isAutoincrement: false;
|
|
3168
|
+
hasRuntimeDefault: false;
|
|
3169
|
+
enumValues: undefined;
|
|
3170
|
+
identity: undefined;
|
|
3171
|
+
generated: undefined;
|
|
3172
|
+
}>;
|
|
3173
|
+
tokenHash: drizzle_orm_pg_core.PgBuildColumn<"signup_link_tokens", drizzle_orm_pg_core.SetNotNull<drizzle_orm_pg_core.PgTextBuilder<[string, ...string[]]>>, {
|
|
3174
|
+
name: string;
|
|
3175
|
+
tableName: "signup_link_tokens";
|
|
3176
|
+
dataType: "string";
|
|
3177
|
+
data: string;
|
|
3178
|
+
driverParam: string;
|
|
3179
|
+
notNull: true;
|
|
3180
|
+
hasDefault: false;
|
|
3181
|
+
isPrimaryKey: false;
|
|
3182
|
+
isAutoincrement: false;
|
|
3183
|
+
hasRuntimeDefault: false;
|
|
3184
|
+
enumValues: undefined;
|
|
3185
|
+
identity: undefined;
|
|
3186
|
+
generated: undefined;
|
|
3187
|
+
}>;
|
|
3188
|
+
returnPath: drizzle_orm_pg_core.PgBuildColumn<"signup_link_tokens", drizzle_orm_pg_core.PgTextBuilder<[string, ...string[]]>, {
|
|
3189
|
+
name: string;
|
|
3190
|
+
tableName: "signup_link_tokens";
|
|
3191
|
+
dataType: "string";
|
|
3192
|
+
data: string;
|
|
3193
|
+
driverParam: string;
|
|
3194
|
+
notNull: false;
|
|
3195
|
+
hasDefault: false;
|
|
3196
|
+
isPrimaryKey: false;
|
|
3197
|
+
isAutoincrement: false;
|
|
3198
|
+
hasRuntimeDefault: false;
|
|
3199
|
+
enumValues: undefined;
|
|
3200
|
+
identity: undefined;
|
|
3201
|
+
generated: undefined;
|
|
3202
|
+
}>;
|
|
3203
|
+
expiresAt: drizzle_orm_pg_core.PgBuildColumn<"signup_link_tokens", drizzle_orm_pg_core.SetNotNull<drizzle_orm_pg_core.PgTimestampBuilder>, {
|
|
3204
|
+
name: string;
|
|
3205
|
+
tableName: "signup_link_tokens";
|
|
3206
|
+
dataType: "object date";
|
|
3207
|
+
data: Date;
|
|
3208
|
+
driverParam: string;
|
|
3209
|
+
notNull: true;
|
|
3210
|
+
hasDefault: false;
|
|
3211
|
+
isPrimaryKey: false;
|
|
3212
|
+
isAutoincrement: false;
|
|
3213
|
+
hasRuntimeDefault: false;
|
|
3214
|
+
enumValues: undefined;
|
|
3215
|
+
identity: undefined;
|
|
3216
|
+
generated: undefined;
|
|
3217
|
+
}>;
|
|
3218
|
+
consumedAt: drizzle_orm_pg_core.PgBuildColumn<"signup_link_tokens", drizzle_orm_pg_core.PgTimestampBuilder, {
|
|
3219
|
+
name: string;
|
|
3220
|
+
tableName: "signup_link_tokens";
|
|
3221
|
+
dataType: "object date";
|
|
3222
|
+
data: Date;
|
|
3223
|
+
driverParam: string;
|
|
3224
|
+
notNull: false;
|
|
3225
|
+
hasDefault: false;
|
|
3226
|
+
isPrimaryKey: false;
|
|
3227
|
+
isAutoincrement: false;
|
|
3228
|
+
hasRuntimeDefault: false;
|
|
3229
|
+
enumValues: undefined;
|
|
3230
|
+
identity: undefined;
|
|
3231
|
+
generated: undefined;
|
|
3232
|
+
}>;
|
|
3233
|
+
supersededAt: drizzle_orm_pg_core.PgBuildColumn<"signup_link_tokens", drizzle_orm_pg_core.PgTimestampBuilder, {
|
|
3234
|
+
name: string;
|
|
3235
|
+
tableName: "signup_link_tokens";
|
|
3236
|
+
dataType: "object date";
|
|
3237
|
+
data: Date;
|
|
3238
|
+
driverParam: string;
|
|
3239
|
+
notNull: false;
|
|
3240
|
+
hasDefault: false;
|
|
3241
|
+
isPrimaryKey: false;
|
|
3242
|
+
isAutoincrement: false;
|
|
3243
|
+
hasRuntimeDefault: false;
|
|
3244
|
+
enumValues: undefined;
|
|
3245
|
+
identity: undefined;
|
|
3246
|
+
generated: undefined;
|
|
3247
|
+
}>;
|
|
3248
|
+
setupSecretHash: drizzle_orm_pg_core.PgBuildColumn<"signup_link_tokens", drizzle_orm_pg_core.PgTextBuilder<[string, ...string[]]>, {
|
|
3249
|
+
name: string;
|
|
3250
|
+
tableName: "signup_link_tokens";
|
|
3251
|
+
dataType: "string";
|
|
3252
|
+
data: string;
|
|
3253
|
+
driverParam: string;
|
|
3254
|
+
notNull: false;
|
|
3255
|
+
hasDefault: false;
|
|
3256
|
+
isPrimaryKey: false;
|
|
3257
|
+
isAutoincrement: false;
|
|
3258
|
+
hasRuntimeDefault: false;
|
|
3259
|
+
enumValues: undefined;
|
|
3260
|
+
identity: undefined;
|
|
3261
|
+
generated: undefined;
|
|
3262
|
+
}>;
|
|
3263
|
+
setupExpiresAt: drizzle_orm_pg_core.PgBuildColumn<"signup_link_tokens", drizzle_orm_pg_core.PgTimestampBuilder, {
|
|
3264
|
+
name: string;
|
|
3265
|
+
tableName: "signup_link_tokens";
|
|
3266
|
+
dataType: "object date";
|
|
3267
|
+
data: Date;
|
|
3268
|
+
driverParam: string;
|
|
3269
|
+
notNull: false;
|
|
3270
|
+
hasDefault: false;
|
|
3271
|
+
isPrimaryKey: false;
|
|
3272
|
+
isAutoincrement: false;
|
|
3273
|
+
hasRuntimeDefault: false;
|
|
3274
|
+
enumValues: undefined;
|
|
3275
|
+
identity: undefined;
|
|
3276
|
+
generated: undefined;
|
|
3277
|
+
}>;
|
|
3278
|
+
completedAt: drizzle_orm_pg_core.PgBuildColumn<"signup_link_tokens", drizzle_orm_pg_core.PgTimestampBuilder, {
|
|
3279
|
+
name: string;
|
|
3280
|
+
tableName: "signup_link_tokens";
|
|
3281
|
+
dataType: "object date";
|
|
3282
|
+
data: Date;
|
|
3283
|
+
driverParam: string;
|
|
3284
|
+
notNull: false;
|
|
3285
|
+
hasDefault: false;
|
|
3286
|
+
isPrimaryKey: false;
|
|
3287
|
+
isAutoincrement: false;
|
|
3288
|
+
hasRuntimeDefault: false;
|
|
3289
|
+
enumValues: undefined;
|
|
3290
|
+
identity: undefined;
|
|
3291
|
+
generated: undefined;
|
|
3292
|
+
}>;
|
|
3293
|
+
};
|
|
3294
|
+
dialect: "pg";
|
|
3295
|
+
}>;
|
|
3296
|
+
type SignupLinkToken = typeof signupLinkTokens.$inferSelect;
|
|
3297
|
+
type NewSignupLinkToken = typeof signupLinkTokens.$inferInsert;
|
|
3298
|
+
|
|
3060
3299
|
/**
|
|
3061
3300
|
* @spfn/auth - Permissions Entity
|
|
3062
3301
|
*
|
|
@@ -3629,6 +3868,38 @@ declare class UsersRepository extends BaseRepository {
|
|
|
3629
3868
|
phoneVerifiedAt: Date | null;
|
|
3630
3869
|
lastLoginAt: Date | null;
|
|
3631
3870
|
}>;
|
|
3871
|
+
/**
|
|
3872
|
+
* 이메일로 사용자 조회 — 저장된 형태와 무관하게 찾는다.
|
|
3873
|
+
*
|
|
3874
|
+
* `findByEmail` asks whether a row holds this exact address; this asks
|
|
3875
|
+
* whether any row *is* this address, whatever form it was written in. The
|
|
3876
|
+
* difference matters to a caller that answers "no" by creating an account:
|
|
3877
|
+
* a lookup that misses a row stored in another form would make a second
|
|
3878
|
+
* account for a person who already has one, and the unique constraint
|
|
3879
|
+
* cannot object because the two stored strings differ.
|
|
3880
|
+
*
|
|
3881
|
+
* Folding in the predicate means no index on `email` applies, so this is for
|
|
3882
|
+
* the few addresses a caller decides about — admin seeding — not for a
|
|
3883
|
+
* request path. Write primary: the answer decides whether to insert.
|
|
3884
|
+
*/
|
|
3885
|
+
findByEmailInAnyStoredForm(email: string): Promise<{
|
|
3886
|
+
deletedAt: Date | null;
|
|
3887
|
+
deletedBy: string | null;
|
|
3888
|
+
createdAt: Date;
|
|
3889
|
+
updatedAt: Date;
|
|
3890
|
+
id: number;
|
|
3891
|
+
publicId: string;
|
|
3892
|
+
email: string | null;
|
|
3893
|
+
phone: string | null;
|
|
3894
|
+
username: string | null;
|
|
3895
|
+
passwordHash: string | null;
|
|
3896
|
+
passwordChangeRequired: boolean;
|
|
3897
|
+
roleId: number;
|
|
3898
|
+
status: "active" | "inactive" | "suspended" | "pending_deletion" | "deleted";
|
|
3899
|
+
emailVerifiedAt: Date | null;
|
|
3900
|
+
phoneVerifiedAt: Date | null;
|
|
3901
|
+
lastLoginAt: Date | null;
|
|
3902
|
+
}>;
|
|
3632
3903
|
/**
|
|
3633
3904
|
* 전화번호로 사용자 조회
|
|
3634
3905
|
* Read replica 사용
|
|
@@ -3770,6 +4041,51 @@ declare class UsersRepository extends BaseRepository {
|
|
|
3770
4041
|
deletedAt: Date | null;
|
|
3771
4042
|
deletedBy: string | null;
|
|
3772
4043
|
}>;
|
|
4044
|
+
/**
|
|
4045
|
+
* User ids grouped by an address two or more rows share once folded.
|
|
4046
|
+
*
|
|
4047
|
+
* The whole comparison happens in the database and only the colliding groups
|
|
4048
|
+
* come back, so the size of the answer is the size of the problem rather
|
|
4049
|
+
* than the size of the table. `users.email` is unique, so a group of more
|
|
4050
|
+
* than one can only be rows that differ by capitalization or padding —
|
|
4051
|
+
* exactly the ones a rewrite cannot decide between.
|
|
4052
|
+
*
|
|
4053
|
+
* Every member id is returned, including a row already holding the
|
|
4054
|
+
* canonical form, because the operator has to compare the accounts against
|
|
4055
|
+
* each other to settle which is real.
|
|
4056
|
+
*
|
|
4057
|
+
* Write primary: the caller is about to rewrite rows and a replica could
|
|
4058
|
+
* still be showing the pre-fix state.
|
|
4059
|
+
*/
|
|
4060
|
+
findEmailConflictGroups(): Promise<number[][]>;
|
|
4061
|
+
/**
|
|
4062
|
+
* Fold every stored address to canonical form, leaving the given ids alone.
|
|
4063
|
+
*
|
|
4064
|
+
* One statement rather than a row at a time: the rewrite is the same
|
|
4065
|
+
* expression the detection uses, so the database can do it in place. A
|
|
4066
|
+
* legacy install with a large users table therefore pays one update instead
|
|
4067
|
+
* of a round trip per row on the boot path, and no list of addresses is ever
|
|
4068
|
+
* carried through the application.
|
|
4069
|
+
*
|
|
4070
|
+
* The excluded ids travel as a single array parameter, so the count of
|
|
4071
|
+
* conflicts cannot run into the protocol's limit on bind parameters.
|
|
4072
|
+
*
|
|
4073
|
+
* One statement also means all or nothing. `users.email` is unique, so if an
|
|
4074
|
+
* instance still running the old code registers a canonical address in the
|
|
4075
|
+
* moment between the conflict query and this update, the update aborts and
|
|
4076
|
+
* nothing is folded on this boot. The next boot sees that pair as a conflict
|
|
4077
|
+
* and folds everything else, so the repair is deferred rather than lost.
|
|
4078
|
+
*
|
|
4079
|
+
* `lower(btrim(...))` is the SQL spelling of `normalizeEmail`. The two agree
|
|
4080
|
+
* on every address this package's validation accepts (ASCII, no interior
|
|
4081
|
+
* whitespace); an address outside that set — reachable only by an app
|
|
4082
|
+
* writing to the repository directly — may fold differently in a database
|
|
4083
|
+
* whose collation lower-cases non-ASCII letters.
|
|
4084
|
+
*
|
|
4085
|
+
* @param excludedIds - Rows to leave untouched, normally the conflict groups
|
|
4086
|
+
* @returns How many rows were rewritten
|
|
4087
|
+
*/
|
|
4088
|
+
normalizeEmailsExcept(excludedIds: number[]): Promise<number>;
|
|
3773
4089
|
/**
|
|
3774
4090
|
* 사용자 정보 업데이트
|
|
3775
4091
|
* Write primary 사용
|
|
@@ -4428,6 +4744,75 @@ declare class VerificationCodesRepository extends BaseRepository {
|
|
|
4428
4744
|
}
|
|
4429
4745
|
declare const verificationCodesRepository: VerificationCodesRepository;
|
|
4430
4746
|
|
|
4747
|
+
/**
|
|
4748
|
+
* Signup Link Tokens Repository
|
|
4749
|
+
*
|
|
4750
|
+
* Data access for the verified-email signup flow. Extends BaseRepository for
|
|
4751
|
+
* transaction-context detection and read/write splitting.
|
|
4752
|
+
*
|
|
4753
|
+
* The two claim methods (`claimLink`, `claimSetupSession`) update conditionally
|
|
4754
|
+
* and return the row only if THIS call was the one that moved it. Two concurrent
|
|
4755
|
+
* confirms — or two concurrent password submits — therefore produce one winner
|
|
4756
|
+
* and one refusal, rather than both proceeding on a row they each read as
|
|
4757
|
+
* unclaimed. Read-then-write would lose that race.
|
|
4758
|
+
*/
|
|
4759
|
+
|
|
4760
|
+
declare class SignupLinkTokensRepository extends BaseRepository {
|
|
4761
|
+
/**
|
|
4762
|
+
* Create a signup link row.
|
|
4763
|
+
* Write primary.
|
|
4764
|
+
*/
|
|
4765
|
+
create(data: NewSignupLinkToken): Promise<SignupLinkToken>;
|
|
4766
|
+
/**
|
|
4767
|
+
* Find a row by the hash of an emailed token, in any state.
|
|
4768
|
+
*
|
|
4769
|
+
* Deliberately unfiltered: the caller decides why a link is refused, and a
|
|
4770
|
+
* row filtered out here would be indistinguishable from an unknown token in
|
|
4771
|
+
* the logs.
|
|
4772
|
+
*
|
|
4773
|
+
* Read replica.
|
|
4774
|
+
*/
|
|
4775
|
+
findByTokenHash(tokenHash: string): Promise<SignupLinkToken | null>;
|
|
4776
|
+
/**
|
|
4777
|
+
* Find a row by the hash of a setup session secret, in any state.
|
|
4778
|
+
* Read replica.
|
|
4779
|
+
*/
|
|
4780
|
+
findBySetupSecretHash(setupSecretHash: string): Promise<SignupLinkToken | null>;
|
|
4781
|
+
/**
|
|
4782
|
+
* Consume a link and open a setup session on it, but only if it is still
|
|
4783
|
+
* unconsumed and not superseded.
|
|
4784
|
+
*
|
|
4785
|
+
* @returns the updated row, or null if another request claimed it first
|
|
4786
|
+
*/
|
|
4787
|
+
claimLink(id: number, setupSecretHash: string, setupExpiresAt: Date): Promise<SignupLinkToken | null>;
|
|
4788
|
+
/**
|
|
4789
|
+
* Mark a setup session as completed, but only if it has not completed
|
|
4790
|
+
* already.
|
|
4791
|
+
*
|
|
4792
|
+
* @returns the updated row, or null if another request completed it first
|
|
4793
|
+
*/
|
|
4794
|
+
claimSetupSession(id: number): Promise<SignupLinkToken | null>;
|
|
4795
|
+
/**
|
|
4796
|
+
* Supersede every live link for an address, so requesting a new one
|
|
4797
|
+
* invalidates the previous one and any setup session opened from it.
|
|
4798
|
+
*
|
|
4799
|
+
* Write primary.
|
|
4800
|
+
*
|
|
4801
|
+
* @returns number of rows superseded
|
|
4802
|
+
*/
|
|
4803
|
+
supersedeLiveForEmail(email: string): Promise<number>;
|
|
4804
|
+
/**
|
|
4805
|
+
* Delete every signup link row for an address (account destruction).
|
|
4806
|
+
*
|
|
4807
|
+
* Rows key on the email text and carry no user FK, so destruction has to
|
|
4808
|
+
* clean them up by address the way verification codes are cleaned up.
|
|
4809
|
+
*
|
|
4810
|
+
* Write primary.
|
|
4811
|
+
*/
|
|
4812
|
+
deleteByEmail(email: string): Promise<number>;
|
|
4813
|
+
}
|
|
4814
|
+
declare const signupLinkTokensRepository: SignupLinkTokensRepository;
|
|
4815
|
+
|
|
4431
4816
|
/**
|
|
4432
4817
|
* Roles Repository
|
|
4433
4818
|
*
|
|
@@ -5145,12 +5530,12 @@ declare class InvitationsRepository extends BaseRepository {
|
|
|
5145
5530
|
create(data: NewInvitation): Promise<{
|
|
5146
5531
|
email: string;
|
|
5147
5532
|
metadata: Record<string, any> | null;
|
|
5533
|
+
token: string;
|
|
5148
5534
|
id: number;
|
|
5149
5535
|
roleId: number;
|
|
5150
5536
|
createdAt: Date;
|
|
5151
5537
|
updatedAt: Date;
|
|
5152
5538
|
status: "pending" | "accepted" | "expired" | "cancelled";
|
|
5153
|
-
token: string;
|
|
5154
5539
|
invitedBy: number;
|
|
5155
5540
|
expiresAt: Date;
|
|
5156
5541
|
acceptedAt: Date | null;
|
|
@@ -5179,12 +5564,12 @@ declare class InvitationsRepository extends BaseRepository {
|
|
|
5179
5564
|
deleteById(id: number): Promise<{
|
|
5180
5565
|
email: string;
|
|
5181
5566
|
metadata: Record<string, any> | null;
|
|
5567
|
+
token: string;
|
|
5182
5568
|
id: number;
|
|
5183
5569
|
roleId: number;
|
|
5184
5570
|
createdAt: Date;
|
|
5185
5571
|
updatedAt: Date;
|
|
5186
5572
|
status: "pending" | "accepted" | "expired" | "cancelled";
|
|
5187
|
-
token: string;
|
|
5188
5573
|
invitedBy: number;
|
|
5189
5574
|
expiresAt: Date;
|
|
5190
5575
|
acceptedAt: Date | null;
|
|
@@ -5581,10 +5966,10 @@ declare class AccountDeletionRequestsRepository extends BaseRepository {
|
|
|
5581
5966
|
reason: string | null;
|
|
5582
5967
|
purgeScheduledAt: Date;
|
|
5583
5968
|
cancelledAt: Date | null;
|
|
5969
|
+
completedAt: Date | null;
|
|
5584
5970
|
userPublicId: string;
|
|
5585
5971
|
requestedAt: Date;
|
|
5586
5972
|
requestedBy: "admin" | "self";
|
|
5587
|
-
completedAt: Date | null;
|
|
5588
5973
|
purgeStrategy: "anonymize" | "hard-delete" | null;
|
|
5589
5974
|
}>;
|
|
5590
5975
|
/**
|
|
@@ -5669,6 +6054,43 @@ declare class OpsTokensRepository extends BaseRepository {
|
|
|
5669
6054
|
}
|
|
5670
6055
|
declare const opsTokensRepository: OpsTokensRepository;
|
|
5671
6056
|
|
|
6057
|
+
/**
|
|
6058
|
+
* @spfn/auth - Email address normalization
|
|
6059
|
+
*
|
|
6060
|
+
* One canonical form for an address, applied on the way in AND on the way out,
|
|
6061
|
+
* so `Foo@Example.com` and `foo@example.com` are the same account everywhere.
|
|
6062
|
+
*
|
|
6063
|
+
* Both sides have to agree or normalization makes things worse rather than
|
|
6064
|
+
* better: normalizing only the lookup means an address stored in mixed case can
|
|
6065
|
+
* no longer be found, and normalizing only the write means an old row stays
|
|
6066
|
+
* unreachable. `UsersRepository` therefore applies this to every read and every
|
|
6067
|
+
* write of `users.email`, which is what keeps a call site from forgetting.
|
|
6068
|
+
*/
|
|
6069
|
+
/**
|
|
6070
|
+
* Trim and lower-case an address.
|
|
6071
|
+
*
|
|
6072
|
+
* Nothing else. Two normalizations that look tempting are deliberately absent:
|
|
6073
|
+
* stripping dots and cutting at `+` are Gmail delivery rules, not internet ones,
|
|
6074
|
+
* and applying them would merge addresses that other providers treat as
|
|
6075
|
+
* genuinely different people.
|
|
6076
|
+
*
|
|
6077
|
+
* The local part is technically case-sensitive per RFC 5321, but no mail
|
|
6078
|
+
* provider in practice treats it that way, while users routinely retype their
|
|
6079
|
+
* address with different capitalization. Matching the practice avoids duplicate
|
|
6080
|
+
* accounts; honouring the RFC creates them.
|
|
6081
|
+
*
|
|
6082
|
+
* @param email - Address as supplied
|
|
6083
|
+
* @returns The canonical form used for storage and lookup
|
|
6084
|
+
*/
|
|
6085
|
+
declare function normalizeEmail(email: string): string;
|
|
6086
|
+
/**
|
|
6087
|
+
* Normalize when there is an address, pass null/undefined through untouched.
|
|
6088
|
+
*
|
|
6089
|
+
* Accounts registered by phone have no email, and `null` is meaningfully
|
|
6090
|
+
* different from `''` in that column.
|
|
6091
|
+
*/
|
|
6092
|
+
declare function normalizeOptionalEmail<T extends string | null | undefined>(email: T): T;
|
|
6093
|
+
|
|
5672
6094
|
/**
|
|
5673
6095
|
* @spfn/auth - Password Helpers
|
|
5674
6096
|
*
|
|
@@ -6227,6 +6649,8 @@ declare const COOKIE_NAMES: {
|
|
|
6227
6649
|
readonly OAUTH_PENDING: string;
|
|
6228
6650
|
/** OAuth CSRF nonce — double-submit against the (encrypted) state.nonce at callback */
|
|
6229
6651
|
readonly OAUTH_CSRF: string;
|
|
6652
|
+
/** Password-setup session for verified-email signup — temporary, single-purpose */
|
|
6653
|
+
readonly SIGNUP_SETUP: string;
|
|
6230
6654
|
};
|
|
6231
6655
|
/**
|
|
6232
6656
|
* OAuth CSRF 쿠키를 PORT 접미사와 무관하게 전부 수집한다.
|
|
@@ -6270,6 +6694,12 @@ interface BeforeRegisterContext {
|
|
|
6270
6694
|
channel: RegisterChannel;
|
|
6271
6695
|
/** Social provider — only set when channel is 'oauth' */
|
|
6272
6696
|
provider?: SocialProvider;
|
|
6697
|
+
/**
|
|
6698
|
+
* Canonical form of the address — trimmed and lower-cased, the same form
|
|
6699
|
+
* the account is stored under. A policy keyed on the address (a denylist, a
|
|
6700
|
+
* domain allowlist) therefore matches whatever capitalization the person
|
|
6701
|
+
* typed, instead of being walked past by `Blocked@Example.com`.
|
|
6702
|
+
*/
|
|
6273
6703
|
email?: string;
|
|
6274
6704
|
/**
|
|
6275
6705
|
* Whether the email is verified — only set when channel is 'oauth'.
|
|
@@ -6349,6 +6779,11 @@ declare function getAuthConfig(): AuthConfig;
|
|
|
6349
6779
|
* Single entry point for every registration channel so a new channel cannot
|
|
6350
6780
|
* forget the configured-check. Callers invoke this right before creating the
|
|
6351
6781
|
* user row.
|
|
6782
|
+
*
|
|
6783
|
+
* The address is folded here rather than at each call site, for the same reason
|
|
6784
|
+
* the check itself lives here: three channels supply it, and a policy that sees
|
|
6785
|
+
* a different spelling depending on which one the person came through is a
|
|
6786
|
+
* policy that can be walked past.
|
|
6352
6787
|
*/
|
|
6353
6788
|
declare function runBeforeRegister(context: BeforeRegisterContext): Promise<void>;
|
|
6354
6789
|
/**
|
|
@@ -6808,8 +7243,8 @@ declare const invitationCreatedEvent: _spfn_core_event.EventDef<{
|
|
|
6808
7243
|
[x: string]: unknown;
|
|
6809
7244
|
} | undefined;
|
|
6810
7245
|
email: string;
|
|
6811
|
-
roleId: number;
|
|
6812
7246
|
token: string;
|
|
7247
|
+
roleId: number;
|
|
6813
7248
|
invitedBy: string;
|
|
6814
7249
|
expiresAt: string;
|
|
6815
7250
|
invitationId: string;
|
|
@@ -6915,4 +7350,4 @@ type AuthDeletionCancelledPayload = typeof authDeletionCancelledEvent._payload;
|
|
|
6915
7350
|
type AuthDeletionCompletedPayload = typeof authDeletionCompletedEvent._payload;
|
|
6916
7351
|
type OAuthUnlinkedPayload = typeof oauthUnlinkedEvent._payload;
|
|
6917
7352
|
|
|
6918
|
-
export { type AccountDeletionPurgeUser, type AccountDeletionRequest, AccountDeletionRequestedBy, AccountDeletionRequestsRepository, type AuthConfig, AuthContext, type AuthDeletionCancelledPayload, type AuthDeletionCompletedPayload, type AuthDeletionConfig, type AuthDeletionRequestedPayload, type AuthLifecycleConfig, type AuthLifecycleOptions, type AuthLoginPayload, type AuthMetadataEntity, AuthMetadataRepository, AuthProviderSchema, type AuthRegisterPayload, type BeforeRegisterContext, COOKIE_NAMES, type CancelAccountDeletionParams, type CancelAccountDeletionResult, type CreateOAuthStateParams, DEFAULT_DELETION_ALLOW_SELF_IMMEDIATE, DEFAULT_DELETION_GRACE_PERIOD_DAYS, DEFAULT_DELETION_PURGE_CRON, DEFAULT_DELETION_PURGE_STRATEGY, DEFAULT_DELETION_SEND_NOTIFICATIONS, type DecryptedOAuthToken, EnvironmentKeyringTokenCipher, type GoogleTokenResponse, type GoogleUserInfo, type Invitation, type InvitationAcceptedPayload, type InvitationCreatedPayload, InvitationStatus, InvitationsRepository, type IssuedOpsToken, KeyAlgorithmType, KeysRepository, type NewAccountDeletionRequest, type NewAuthMetadataEntity, type NewInvitation, type NewOpsToken, type NewPermission, type NewPermissionEntity, type NewRole, type NewRoleEntity, type NewRolePermission, type NewUser, type NewUserPermission, type NewUserProfile, type NewUserPublicKey, type NewUserSocialAccount, type NewVerificationCode, OAuthProvider, type OAuthState, type OAuthTokenCipher, type OAuthTokenContext, type OAuthTokenType, type OAuthUnlinkedPayload, type OpsToken, OpsTokensRepository, type PendingDeletionInfo, type Permission, type PermissionEntity, PermissionsRepository, PurgeStrategy, type PurgeUserResult, type RegisterChannel, type RequestAccountDeletionParams, type RequestAccountDeletionResult, type Role, type RoleEntity, type RoleGuardOptions, type RolePermission, RolePermissionsRepository, RolesRepository, type SessionPayload, SocialAccountsRepository, SocialProvider, type SweepDuePurgesResult, type TokenPayload, type UpdateProfileParams, type User, type UserPermission, UserPermissionsRepository, type UserProfile, UserProfilesRepository, type UserPublicKey, type UserSocialAccount, UsersRepository, type VerificationCode, VerificationCodesRepository, VerificationPurpose, type VerifiedOpsToken, type VerifyIdTokenParams, acceptInvitation, accountDeletionRequests, accountDeletionRequestsRepository, addPermissionToRole, appleProvider, assertCanAssignRole, authDeletionCancelledEvent, authDeletionCompletedEvent, authDeletionRequestedEvent, authJobRouter, authLogger, authLoginEvent, authMetadata, authMetadataRepository, authRegisterEvent, authSchema, cancelAccountDeletionService, cancelInvitation, checkUsernameAvailableService, configureAuth, configureDeletion, configureOAuthTokenCipher, createAuthDeletionJobRouter, createAuthDeletionPurgeJob, createAuthLifecycle, createInvitation, createOAuthState, createRole, decodeToken, decryptToken, deleteInvitation, deleteRole, encryptToken, exchangeCodeForTokens, expireOldInvitations, generateOAuthNonce, generateToken, getAllRoles, getAuth, getAuthConfig, getAuthSessionService, getDeletionConfig, getDummyPasswordHash, getGoogleAuthUrl, getGoogleOAuthConfig, getGoogleUserInfo, getInvitationByToken, getInvitationWithDetails, getKeyId, getLocale, getOneTimeTokenManager, getOpsToken, getOptionalAuth, getPendingDeletionInfo, getRole, getRoleByName, getRolePermissions, getSessionTtl, getUser, getUserByEmailService, getUserByIdService, getUserByPhoneService, getUserId, getUserPermissions, getUserProfileService, getUserRole, githubProvider, googleProvider, hasAllPermissions, hasAnyPermission, hasAnyRole, hasPermission, hasRole, hashPassword, initOneTimeTokenManager, initializeAuth, invitationAcceptedEvent, invitationCreatedEvent, invitationsRepository, isEncrypted, isGoogleOAuthEnabled, issueOpsTokenService, kakaoProvider, keysRepository, listInvitations, listOpsTokensService, matchOAuthCsrfCookies, naverProvider, oauthUnlinkedEvent, oneTimeTokenAuth, opsTokenAuth, opsTokens, opsTokensRepository, parseDuration, permissions, permissionsRepository, purgeUserService, refreshAccessToken, removePermissionFromRole, requestAccountDeletionService, requireAnyPermission, requireOpsScope, requirePermissions, requireRole, resendInvitation, revokeOpsTokenService, roleGuard, rolePermissions, rolePermissionsRepository, roles, rolesRepository, runBeforeRegister, setRolePermissions, socialAccountsRepository, sweepDuePurges, updateLastLoginService, updateLocaleService, updateRole, updateUserProfileService, updateUserService, updateUsernameService, userInvitations, userPermissions, userPermissionsRepository, userProfiles, userProfilesRepository, userPublicKeys, userSocialAccounts, users, usersRepository, validateInvitation, validatePasswordStrength, verificationCodes, verificationCodesRepository, verifyClientToken, verifyIdToken, verifyKeyFingerprint, verifyOAuthState, verifyOpsTokenService, verifyPassword, verifyToken };
|
|
7353
|
+
export { type AccountDeletionPurgeUser, type AccountDeletionRequest, AccountDeletionRequestedBy, AccountDeletionRequestsRepository, type AuthConfig, AuthContext, type AuthDeletionCancelledPayload, type AuthDeletionCompletedPayload, type AuthDeletionConfig, type AuthDeletionRequestedPayload, type AuthLifecycleConfig, type AuthLifecycleOptions, type AuthLoginPayload, type AuthMetadataEntity, AuthMetadataRepository, AuthProviderSchema, type AuthRegisterPayload, type BeforeRegisterContext, COOKIE_NAMES, type CancelAccountDeletionParams, type CancelAccountDeletionResult, type CreateOAuthStateParams, DEFAULT_DELETION_ALLOW_SELF_IMMEDIATE, DEFAULT_DELETION_GRACE_PERIOD_DAYS, DEFAULT_DELETION_PURGE_CRON, DEFAULT_DELETION_PURGE_STRATEGY, DEFAULT_DELETION_SEND_NOTIFICATIONS, type DecryptedOAuthToken, type EmailNormalizationResult, EnvironmentKeyringTokenCipher, type GoogleTokenResponse, type GoogleUserInfo, type Invitation, type InvitationAcceptedPayload, type InvitationCreatedPayload, InvitationStatus, InvitationsRepository, type IssuedOpsToken, KeyAlgorithmType, KeysRepository, type NewAccountDeletionRequest, type NewAuthMetadataEntity, type NewInvitation, type NewOpsToken, type NewPermission, type NewPermissionEntity, type NewRole, type NewRoleEntity, type NewRolePermission, type NewSignupLinkToken, type NewUser, type NewUserPermission, type NewUserProfile, type NewUserPublicKey, type NewUserSocialAccount, type NewVerificationCode, OAuthProvider, type OAuthState, type OAuthTokenCipher, type OAuthTokenContext, type OAuthTokenType, type OAuthUnlinkedPayload, type OpsToken, OpsTokensRepository, type PendingDeletionInfo, type Permission, type PermissionEntity, PermissionsRepository, PurgeStrategy, type PurgeUserResult, type RegisterChannel, type RequestAccountDeletionParams, type RequestAccountDeletionResult, type Role, type RoleEntity, type RoleGuardOptions, type RolePermission, RolePermissionsRepository, RolesRepository, type SessionPayload, type SignupLinkToken, SignupLinkTokensRepository, SocialAccountsRepository, SocialProvider, type SweepDuePurgesResult, type TokenPayload, type UpdateProfileParams, type User, type UserPermission, UserPermissionsRepository, type UserProfile, UserProfilesRepository, type UserPublicKey, type UserSocialAccount, UsersRepository, type VerificationCode, VerificationCodesRepository, VerificationPurpose, type VerifiedOpsToken, type VerifyIdTokenParams, acceptInvitation, accountDeletionRequests, accountDeletionRequestsRepository, addPermissionToRole, appleProvider, assertCanAssignRole, authDeletionCancelledEvent, authDeletionCompletedEvent, authDeletionRequestedEvent, authJobRouter, authLogger, authLoginEvent, authMetadata, authMetadataRepository, authRegisterEvent, authSchema, cancelAccountDeletionService, cancelInvitation, checkUsernameAvailableService, configureAuth, configureDeletion, configureOAuthTokenCipher, createAuthDeletionJobRouter, createAuthDeletionPurgeJob, createAuthLifecycle, createInvitation, createOAuthState, createRole, decodeToken, decryptToken, deleteInvitation, deleteRole, encryptToken, exchangeCodeForTokens, expireOldInvitations, generateOAuthNonce, generateToken, getAllRoles, getAuth, getAuthConfig, getAuthSessionService, getDeletionConfig, getDummyPasswordHash, getGoogleAuthUrl, getGoogleOAuthConfig, getGoogleUserInfo, getInvitationByToken, getInvitationWithDetails, getKeyId, getLocale, getOneTimeTokenManager, getOpsToken, getOptionalAuth, getPendingDeletionInfo, getRole, getRoleByName, getRolePermissions, getSessionTtl, getUser, getUserByEmailService, getUserByIdService, getUserByPhoneService, getUserId, getUserPermissions, getUserProfileService, getUserRole, githubProvider, googleProvider, hasAllPermissions, hasAnyPermission, hasAnyRole, hasPermission, hasRole, hashPassword, initOneTimeTokenManager, initializeAuth, invitationAcceptedEvent, invitationCreatedEvent, invitationsRepository, isEncrypted, isGoogleOAuthEnabled, issueOpsTokenService, kakaoProvider, keysRepository, listInvitations, listOpsTokensService, matchOAuthCsrfCookies, naverProvider, normalizeEmail, normalizeOptionalEmail, normalizeStoredEmails, oauthUnlinkedEvent, oneTimeTokenAuth, opsTokenAuth, opsTokens, opsTokensRepository, parseDuration, permissions, permissionsRepository, purgeUserService, refreshAccessToken, removePermissionFromRole, requestAccountDeletionService, requireAnyPermission, requireOpsScope, requirePermissions, requireRole, resendInvitation, revokeOpsTokenService, roleGuard, rolePermissions, rolePermissionsRepository, roles, rolesRepository, runBeforeRegister, setRolePermissions, signupLinkTokens, signupLinkTokensRepository, socialAccountsRepository, sweepDuePurges, updateLastLoginService, updateLocaleService, updateRole, updateUserProfileService, updateUserService, updateUsernameService, userInvitations, userPermissions, userPermissionsRepository, userProfiles, userProfilesRepository, userPublicKeys, userSocialAccounts, users, usersRepository, validateInvitation, validatePasswordStrength, verificationCodes, verificationCodesRepository, verifyClientToken, verifyIdToken, verifyKeyFingerprint, verifyOAuthState, verifyOpsTokenService, verifyPassword, verifyToken };
|