@factiii/auth 0.5.2 → 0.5.4
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/bin/init.mjs +449 -64
- package/dist/{chunk-EHI4P63M.mjs → chunk-KUYH4DBN.mjs} +8 -0
- package/dist/index.d.mts +228 -16
- package/dist/index.d.ts +228 -16
- package/dist/index.js +678 -381
- package/dist/index.mjs +678 -382
- package/dist/validators.d.mts +1 -1
- package/dist/validators.d.ts +1 -1
- package/dist/validators.mjs +1 -1
- package/package.json +24 -3
- package/dist/{hooks-BXNxNK4S.d.mts → hooks-yHGJ7C6_.d.mts} +2 -2
- package/dist/{hooks-BXNxNK4S.d.ts → hooks-yHGJ7C6_.d.ts} +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import * as http from 'http';
|
|
2
2
|
import * as SuperJSON from 'superjson';
|
|
3
3
|
import SuperJSON__default from 'superjson';
|
|
4
|
-
import * as _prisma_client from '@prisma/client';
|
|
5
|
-
import { PrismaClient } from '@prisma/client';
|
|
6
4
|
import * as _trpc_server from '@trpc/server';
|
|
7
5
|
import * as zod from 'zod';
|
|
8
6
|
import { CreateHTTPContextOptions } from '@trpc/server/adapters/standalone';
|
|
9
|
-
import { S as SchemaExtensions, A as AuthHooks } from './hooks-
|
|
10
|
-
export { C as ChangePasswordInput, L as LoginInput, O as OAuthLoginInput, R as ResetPasswordInput, a as SignupInput, T as TwoFaVerifyInput, V as VerifyEmailInput, b as biometricVerifySchema, c as changePasswordSchema, e as endAllSessionsSchema, l as loginSchema, o as oAuthLoginSchema, r as requestPasswordResetSchema, d as resetPasswordSchema, s as signupSchema, t as twoFaResetSchema, f as twoFaVerifySchema, v as verifyEmailSchema } from './hooks-
|
|
7
|
+
import { S as SchemaExtensions, A as AuthHooks } from './hooks-yHGJ7C6_.mjs';
|
|
8
|
+
export { C as ChangePasswordInput, L as LoginInput, O as OAuthLoginInput, R as ResetPasswordInput, a as SignupInput, T as TwoFaVerifyInput, V as VerifyEmailInput, b as biometricVerifySchema, c as changePasswordSchema, e as endAllSessionsSchema, l as loginSchema, o as oAuthLoginSchema, r as requestPasswordResetSchema, d as resetPasswordSchema, s as signupSchema, t as twoFaResetSchema, f as twoFaVerifySchema, v as verifyEmailSchema } from './hooks-yHGJ7C6_.mjs';
|
|
11
9
|
|
|
12
10
|
//# sourceMappingURL=TRPCError.d.ts.map
|
|
13
11
|
//#endregion
|
|
@@ -149,6 +147,208 @@ declare function createNoopEmailAdapter(): EmailAdapter;
|
|
|
149
147
|
*/
|
|
150
148
|
declare function createConsoleEmailAdapter(): EmailAdapter;
|
|
151
149
|
|
|
150
|
+
/**
|
|
151
|
+
* ORM-agnostic database adapter interface for @factiii/auth.
|
|
152
|
+
* Implement this interface to use any database/ORM with the auth library.
|
|
153
|
+
*/
|
|
154
|
+
interface AuthUser {
|
|
155
|
+
id: number;
|
|
156
|
+
status: string;
|
|
157
|
+
email: string;
|
|
158
|
+
username: string;
|
|
159
|
+
password: string | null;
|
|
160
|
+
twoFaEnabled: boolean;
|
|
161
|
+
oauthProvider: string | null;
|
|
162
|
+
oauthId: string | null;
|
|
163
|
+
tag: string;
|
|
164
|
+
verifiedHumanAt: Date | null;
|
|
165
|
+
emailVerificationStatus: string;
|
|
166
|
+
otpForEmailVerification: string | null;
|
|
167
|
+
isActive: boolean;
|
|
168
|
+
}
|
|
169
|
+
interface AuthSession {
|
|
170
|
+
id: number;
|
|
171
|
+
userId: number;
|
|
172
|
+
socketId: string | null;
|
|
173
|
+
twoFaSecret: string | null;
|
|
174
|
+
browserName: string;
|
|
175
|
+
issuedAt: Date;
|
|
176
|
+
lastUsed: Date;
|
|
177
|
+
revokedAt: Date | null;
|
|
178
|
+
deviceId: number | null;
|
|
179
|
+
}
|
|
180
|
+
interface AuthOTP {
|
|
181
|
+
id: number;
|
|
182
|
+
code: number;
|
|
183
|
+
expiresAt: Date;
|
|
184
|
+
userId: number;
|
|
185
|
+
}
|
|
186
|
+
interface AuthPasswordReset {
|
|
187
|
+
id: string;
|
|
188
|
+
createdAt: Date;
|
|
189
|
+
userId: number;
|
|
190
|
+
}
|
|
191
|
+
interface CreateUserData {
|
|
192
|
+
username: string;
|
|
193
|
+
email: string;
|
|
194
|
+
password: string | null;
|
|
195
|
+
status: string;
|
|
196
|
+
tag: string;
|
|
197
|
+
twoFaEnabled: boolean;
|
|
198
|
+
emailVerificationStatus: string;
|
|
199
|
+
verifiedHumanAt: Date | null;
|
|
200
|
+
oauthProvider?: string;
|
|
201
|
+
oauthId?: string;
|
|
202
|
+
}
|
|
203
|
+
interface CreateSessionData {
|
|
204
|
+
userId: number;
|
|
205
|
+
browserName: string;
|
|
206
|
+
socketId: string | null;
|
|
207
|
+
[key: string]: unknown;
|
|
208
|
+
}
|
|
209
|
+
type SessionWithUser = AuthSession & {
|
|
210
|
+
user: {
|
|
211
|
+
status: string;
|
|
212
|
+
verifiedHumanAt: Date | null;
|
|
213
|
+
};
|
|
214
|
+
};
|
|
215
|
+
type SessionWithDevice = {
|
|
216
|
+
twoFaSecret: string | null;
|
|
217
|
+
deviceId: number | null;
|
|
218
|
+
device: {
|
|
219
|
+
pushToken: string;
|
|
220
|
+
} | null;
|
|
221
|
+
};
|
|
222
|
+
interface DatabaseAdapter {
|
|
223
|
+
user: {
|
|
224
|
+
findByEmailInsensitive(email: string): Promise<AuthUser | null>;
|
|
225
|
+
findByUsernameInsensitive(username: string): Promise<AuthUser | null>;
|
|
226
|
+
findByEmailOrUsernameInsensitive(identifier: string): Promise<AuthUser | null>;
|
|
227
|
+
findByEmailOrOAuthId(email: string, oauthId: string): Promise<AuthUser | null>;
|
|
228
|
+
findById(id: number): Promise<AuthUser | null>;
|
|
229
|
+
findActiveById(id: number): Promise<AuthUser | null>;
|
|
230
|
+
create(data: CreateUserData): Promise<AuthUser>;
|
|
231
|
+
update(id: number, data: Partial<Omit<AuthUser, 'id'>>): Promise<AuthUser>;
|
|
232
|
+
};
|
|
233
|
+
session: {
|
|
234
|
+
/** Find session by ID with user status and verifiedHumanAt joined. */
|
|
235
|
+
findById(id: number): Promise<SessionWithUser | null>;
|
|
236
|
+
create(data: CreateSessionData): Promise<AuthSession>;
|
|
237
|
+
update(id: number, data: Partial<Pick<AuthSession, 'revokedAt' | 'lastUsed' | 'twoFaSecret' | 'deviceId'>>): Promise<AuthSession>;
|
|
238
|
+
/** Update lastUsed and return session with user's verifiedHumanAt. */
|
|
239
|
+
updateLastUsed(id: number): Promise<AuthSession & {
|
|
240
|
+
user: {
|
|
241
|
+
verifiedHumanAt: Date | null;
|
|
242
|
+
};
|
|
243
|
+
}>;
|
|
244
|
+
/** Set revokedAt on a single session. */
|
|
245
|
+
revoke(id: number): Promise<void>;
|
|
246
|
+
/** Find active (non-revoked) sessions for a user, optionally excluding one. */
|
|
247
|
+
findActiveByUserId(userId: number, excludeSessionId?: number): Promise<Pick<AuthSession, 'id' | 'socketId' | 'userId'>[]>;
|
|
248
|
+
/** Revoke all active sessions for a user, optionally excluding one. */
|
|
249
|
+
revokeAllByUserId(userId: number, excludeSessionId?: number): Promise<void>;
|
|
250
|
+
/** Get twoFaSecret from all sessions that have one for a user. */
|
|
251
|
+
findTwoFaSecretsByUserId(userId: number): Promise<{
|
|
252
|
+
twoFaSecret: string | null;
|
|
253
|
+
}[]>;
|
|
254
|
+
/** Clear twoFaSecret on sessions for a user, optionally excluding one. */
|
|
255
|
+
clearTwoFaSecrets(userId: number, excludeSessionId?: number): Promise<void>;
|
|
256
|
+
/** Find session with device relation for TOTP verification. */
|
|
257
|
+
findByIdWithDevice(id: number, userId: number): Promise<SessionWithDevice | null>;
|
|
258
|
+
/** Revoke other sessions that share a device push token. */
|
|
259
|
+
revokeByDevicePushToken(userId: number, pushToken: string, excludeSessionId: number): Promise<void>;
|
|
260
|
+
/** Clear deviceId on all sessions for a user+device pair. */
|
|
261
|
+
clearDeviceId(userId: number, deviceId: number): Promise<void>;
|
|
262
|
+
};
|
|
263
|
+
otp: {
|
|
264
|
+
findValidByUserAndCode(userId: number, code: number): Promise<AuthOTP | null>;
|
|
265
|
+
create(data: {
|
|
266
|
+
userId: number;
|
|
267
|
+
code: number;
|
|
268
|
+
expiresAt: Date;
|
|
269
|
+
}): Promise<AuthOTP>;
|
|
270
|
+
delete(id: number): Promise<void>;
|
|
271
|
+
};
|
|
272
|
+
passwordReset: {
|
|
273
|
+
findById(id: string): Promise<AuthPasswordReset | null>;
|
|
274
|
+
create(userId: number): Promise<AuthPasswordReset>;
|
|
275
|
+
delete(id: string): Promise<void>;
|
|
276
|
+
deleteAllByUserId(userId: number): Promise<void>;
|
|
277
|
+
};
|
|
278
|
+
device: {
|
|
279
|
+
findByTokenSessionAndUser(pushToken: string, sessionId: number, userId: number): Promise<{
|
|
280
|
+
id: number;
|
|
281
|
+
} | null>;
|
|
282
|
+
upsertByPushToken(pushToken: string, sessionId: number, userId: number): Promise<void>;
|
|
283
|
+
findByUserAndToken(userId: number, pushToken: string): Promise<{
|
|
284
|
+
id: number;
|
|
285
|
+
} | null>;
|
|
286
|
+
disconnectUser(deviceId: number, userId: number): Promise<void>;
|
|
287
|
+
hasRemainingUsers(deviceId: number): Promise<boolean>;
|
|
288
|
+
delete(id: number): Promise<void>;
|
|
289
|
+
};
|
|
290
|
+
admin: {
|
|
291
|
+
findByUserId(userId: number): Promise<{
|
|
292
|
+
ip: string;
|
|
293
|
+
} | null>;
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
type PrismaClient = any;
|
|
298
|
+
/**
|
|
299
|
+
* Creates a DatabaseAdapter backed by Prisma.
|
|
300
|
+
* Each method is a direct extraction of existing Prisma calls from the procedures.
|
|
301
|
+
*/
|
|
302
|
+
declare function createPrismaAdapter(prisma: PrismaClient): DatabaseAdapter;
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Drizzle table references required by the adapter.
|
|
306
|
+
* Consumers pass their Drizzle table objects so the adapter
|
|
307
|
+
* can build queries without knowing the schema file location.
|
|
308
|
+
*/
|
|
309
|
+
interface DrizzleAdapterTables {
|
|
310
|
+
users: any;
|
|
311
|
+
sessions: any;
|
|
312
|
+
otps: any;
|
|
313
|
+
passwordResets: any;
|
|
314
|
+
devices: any;
|
|
315
|
+
admins: any;
|
|
316
|
+
/** Join table for many-to-many device↔user relation (if applicable). */
|
|
317
|
+
devicesToUsers?: any;
|
|
318
|
+
/** Join table for many-to-many device↔session relation (if applicable). */
|
|
319
|
+
devicesToSessions?: any;
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Any Drizzle database instance (pg, mysql, better-sqlite3, etc.).
|
|
323
|
+
* We keep this generic so consumers aren't locked into a specific driver.
|
|
324
|
+
*/
|
|
325
|
+
type DrizzleDB = any;
|
|
326
|
+
/**
|
|
327
|
+
* Creates a DatabaseAdapter backed by Drizzle ORM.
|
|
328
|
+
*
|
|
329
|
+
* Usage:
|
|
330
|
+
* ```ts
|
|
331
|
+
* import { drizzle } from 'drizzle-orm/node-postgres';
|
|
332
|
+
* import { createDrizzleAdapter } from '@factiii/auth';
|
|
333
|
+
* import * as schema from './schema';
|
|
334
|
+
*
|
|
335
|
+
* const db = drizzle(pool, { schema });
|
|
336
|
+
* const adapter = createDrizzleAdapter(db, {
|
|
337
|
+
* users: schema.users,
|
|
338
|
+
* sessions: schema.sessions,
|
|
339
|
+
* otps: schema.otps,
|
|
340
|
+
* passwordResets: schema.passwordResets,
|
|
341
|
+
* devices: schema.devices,
|
|
342
|
+
* admins: schema.admins,
|
|
343
|
+
* });
|
|
344
|
+
* ```
|
|
345
|
+
*
|
|
346
|
+
* **Important:** This adapter uses Drizzle's relational query API (`db.query.*`)
|
|
347
|
+
* for joins and `db.insert/update/delete` for mutations. Make sure your Drizzle
|
|
348
|
+
* instance is created with `{ schema }` so relational queries work.
|
|
349
|
+
*/
|
|
350
|
+
declare function createDrizzleAdapter(db: DrizzleDB, tables: DrizzleAdapterTables): DatabaseAdapter;
|
|
351
|
+
|
|
152
352
|
/**
|
|
153
353
|
* JWT payload structure
|
|
154
354
|
*/
|
|
@@ -241,9 +441,15 @@ interface AuthFeatures {
|
|
|
241
441
|
}
|
|
242
442
|
interface AuthConfig<TExtensions extends SchemaExtensions = {}> {
|
|
243
443
|
/**
|
|
244
|
-
*
|
|
444
|
+
* Database adapter (use createPrismaAdapter or implement your own).
|
|
445
|
+
* If omitted but `prisma` is provided, a PrismaAdapter is created automatically.
|
|
245
446
|
*/
|
|
246
|
-
|
|
447
|
+
database?: DatabaseAdapter;
|
|
448
|
+
/**
|
|
449
|
+
* @deprecated Use `database` with createPrismaAdapter() instead.
|
|
450
|
+
* Prisma client instance — kept for backwards compatibility.
|
|
451
|
+
*/
|
|
452
|
+
prisma?: unknown;
|
|
247
453
|
/**
|
|
248
454
|
* Secret keys for JWT signing
|
|
249
455
|
*/
|
|
@@ -318,13 +524,17 @@ declare const defaultCookieSettings: CookieSettings;
|
|
|
318
524
|
declare const defaultStorageKeys: {
|
|
319
525
|
authToken: string;
|
|
320
526
|
};
|
|
527
|
+
/** Resolved config type with database adapter guaranteed. */
|
|
528
|
+
type ResolvedAuthConfig = Required<Omit<AuthConfig, 'hooks' | 'oauthKeys' | 'schemaExtensions' | 'prisma'>> & AuthConfig & {
|
|
529
|
+
database: DatabaseAdapter;
|
|
530
|
+
};
|
|
321
531
|
/**
|
|
322
|
-
* Create a fully resolved auth config with defaults applied
|
|
532
|
+
* Create a fully resolved auth config with defaults applied.
|
|
533
|
+
* Accepts either `database` (adapter) or `prisma` (auto-wrapped).
|
|
323
534
|
*/
|
|
324
|
-
declare function createAuthConfig(config: AuthConfig):
|
|
325
|
-
type ResolvedAuthConfig = ReturnType<typeof createAuthConfig>;
|
|
535
|
+
declare function createAuthConfig(config: AuthConfig): ResolvedAuthConfig;
|
|
326
536
|
/**
|
|
327
|
-
* Default auth config (requires prisma and secrets to be provided)
|
|
537
|
+
* Default auth config (requires database/prisma and secrets to be provided)
|
|
328
538
|
*/
|
|
329
539
|
declare const defaultAuthConfig: {
|
|
330
540
|
features: AuthFeatures;
|
|
@@ -438,7 +648,7 @@ declare function createAuthRouter<TExtensions extends SchemaExtensions = {}>(con
|
|
|
438
648
|
input: void;
|
|
439
649
|
output: {
|
|
440
650
|
email: string;
|
|
441
|
-
status:
|
|
651
|
+
status: string;
|
|
442
652
|
isVerified: boolean;
|
|
443
653
|
};
|
|
444
654
|
meta: Meta;
|
|
@@ -659,12 +869,12 @@ declare function createAuthRouter<TExtensions extends SchemaExtensions = {}>(con
|
|
|
659
869
|
email: zod.ZodString;
|
|
660
870
|
password: zod.ZodEffects<zod.ZodString, string, string>;
|
|
661
871
|
}, "strip", zod.ZodTypeAny, {
|
|
662
|
-
email: string;
|
|
663
872
|
username: string;
|
|
873
|
+
email: string;
|
|
664
874
|
password: string;
|
|
665
875
|
}, {
|
|
666
|
-
email: string;
|
|
667
876
|
username: string;
|
|
877
|
+
email: string;
|
|
668
878
|
password: string;
|
|
669
879
|
}>>["in"] extends infer T_7 ? T_7 extends inferParser<[TExtensions["signup"]] extends [zod.AnyZodObject] ? zod.ZodObject<{
|
|
670
880
|
username: zod.ZodString;
|
|
@@ -683,12 +893,12 @@ declare function createAuthRouter<TExtensions extends SchemaExtensions = {}>(con
|
|
|
683
893
|
email: zod.ZodString;
|
|
684
894
|
password: zod.ZodEffects<zod.ZodString, string, string>;
|
|
685
895
|
}, "strip", zod.ZodTypeAny, {
|
|
686
|
-
email: string;
|
|
687
896
|
username: string;
|
|
897
|
+
email: string;
|
|
688
898
|
password: string;
|
|
689
899
|
}, {
|
|
690
|
-
email: string;
|
|
691
900
|
username: string;
|
|
901
|
+
email: string;
|
|
692
902
|
password: string;
|
|
693
903
|
}>>["in"] ? T_7 extends _trpc_server.TRPCUnsetMarker ? void : T_7 : never : never;
|
|
694
904
|
output: {
|
|
@@ -754,6 +964,7 @@ declare function createAuthRouter<TExtensions extends SchemaExtensions = {}>(con
|
|
|
754
964
|
output: {
|
|
755
965
|
success: boolean;
|
|
756
966
|
requires2FA: boolean;
|
|
967
|
+
userId: number;
|
|
757
968
|
user?: undefined;
|
|
758
969
|
} | {
|
|
759
970
|
success: boolean;
|
|
@@ -763,6 +974,7 @@ declare function createAuthRouter<TExtensions extends SchemaExtensions = {}>(con
|
|
|
763
974
|
username: string;
|
|
764
975
|
};
|
|
765
976
|
requires2FA?: undefined;
|
|
977
|
+
userId?: undefined;
|
|
766
978
|
};
|
|
767
979
|
meta: Meta;
|
|
768
980
|
}>;
|
|
@@ -1044,4 +1256,4 @@ declare function verifyTotp(code: string, secret: string): Promise<boolean>;
|
|
|
1044
1256
|
*/
|
|
1045
1257
|
declare function generateOtp(min?: number, max?: number): number;
|
|
1046
1258
|
|
|
1047
|
-
export { type AuthConfig, type AuthFeatures, AuthHooks, type AuthRouter, DEFAULT_STORAGE_KEYS, type EmailAdapter, type OAuthKeys, type OAuthProvider, type OAuthResult, OAuthVerificationError, SchemaExtensions, type TokenSettings, type TrpcContext, cleanBase32String, clearAuthCookie, comparePassword, createAuthConfig, createAuthGuard, createAuthRouter, createAuthToken, createConsoleEmailAdapter, createNoopEmailAdapter, createOAuthVerifier, decodeToken, defaultAuthConfig, defaultCookieSettings, defaultStorageKeys, defaultTokenSettings, detectBrowser, generateOtp, generateTotpCode, generateTotpSecret, hashPassword, isMobileDevice, isNativeApp, isTokenExpiredError, isTokenInvalidError, parseAuthCookie, setAuthCookie, validatePasswordStrength, verifyAuthToken, verifyTotp };
|
|
1259
|
+
export { type AuthConfig, type AuthFeatures, AuthHooks, type AuthOTP, type AuthPasswordReset, type AuthRouter, type AuthSession, type AuthUser, type CreateSessionData, type CreateUserData, DEFAULT_STORAGE_KEYS, type DatabaseAdapter, type DrizzleAdapterTables, type EmailAdapter, type OAuthKeys, type OAuthProvider, type OAuthResult, OAuthVerificationError, SchemaExtensions, type SessionWithDevice, type SessionWithUser, type TokenSettings, type TrpcContext, cleanBase32String, clearAuthCookie, comparePassword, createAuthConfig, createAuthGuard, createAuthRouter, createAuthToken, createConsoleEmailAdapter, createDrizzleAdapter, createNoopEmailAdapter, createOAuthVerifier, createPrismaAdapter, decodeToken, defaultAuthConfig, defaultCookieSettings, defaultStorageKeys, defaultTokenSettings, detectBrowser, generateOtp, generateTotpCode, generateTotpSecret, hashPassword, isMobileDevice, isNativeApp, isTokenExpiredError, isTokenInvalidError, parseAuthCookie, setAuthCookie, validatePasswordStrength, verifyAuthToken, verifyTotp };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import * as http from 'http';
|
|
2
2
|
import * as SuperJSON from 'superjson';
|
|
3
3
|
import SuperJSON__default from 'superjson';
|
|
4
|
-
import * as _prisma_client from '@prisma/client';
|
|
5
|
-
import { PrismaClient } from '@prisma/client';
|
|
6
4
|
import * as _trpc_server from '@trpc/server';
|
|
7
5
|
import * as zod from 'zod';
|
|
8
6
|
import { CreateHTTPContextOptions } from '@trpc/server/adapters/standalone';
|
|
9
|
-
import { S as SchemaExtensions, A as AuthHooks } from './hooks-
|
|
10
|
-
export { C as ChangePasswordInput, L as LoginInput, O as OAuthLoginInput, R as ResetPasswordInput, a as SignupInput, T as TwoFaVerifyInput, V as VerifyEmailInput, b as biometricVerifySchema, c as changePasswordSchema, e as endAllSessionsSchema, l as loginSchema, o as oAuthLoginSchema, r as requestPasswordResetSchema, d as resetPasswordSchema, s as signupSchema, t as twoFaResetSchema, f as twoFaVerifySchema, v as verifyEmailSchema } from './hooks-
|
|
7
|
+
import { S as SchemaExtensions, A as AuthHooks } from './hooks-yHGJ7C6_.js';
|
|
8
|
+
export { C as ChangePasswordInput, L as LoginInput, O as OAuthLoginInput, R as ResetPasswordInput, a as SignupInput, T as TwoFaVerifyInput, V as VerifyEmailInput, b as biometricVerifySchema, c as changePasswordSchema, e as endAllSessionsSchema, l as loginSchema, o as oAuthLoginSchema, r as requestPasswordResetSchema, d as resetPasswordSchema, s as signupSchema, t as twoFaResetSchema, f as twoFaVerifySchema, v as verifyEmailSchema } from './hooks-yHGJ7C6_.js';
|
|
11
9
|
|
|
12
10
|
//# sourceMappingURL=TRPCError.d.ts.map
|
|
13
11
|
//#endregion
|
|
@@ -149,6 +147,208 @@ declare function createNoopEmailAdapter(): EmailAdapter;
|
|
|
149
147
|
*/
|
|
150
148
|
declare function createConsoleEmailAdapter(): EmailAdapter;
|
|
151
149
|
|
|
150
|
+
/**
|
|
151
|
+
* ORM-agnostic database adapter interface for @factiii/auth.
|
|
152
|
+
* Implement this interface to use any database/ORM with the auth library.
|
|
153
|
+
*/
|
|
154
|
+
interface AuthUser {
|
|
155
|
+
id: number;
|
|
156
|
+
status: string;
|
|
157
|
+
email: string;
|
|
158
|
+
username: string;
|
|
159
|
+
password: string | null;
|
|
160
|
+
twoFaEnabled: boolean;
|
|
161
|
+
oauthProvider: string | null;
|
|
162
|
+
oauthId: string | null;
|
|
163
|
+
tag: string;
|
|
164
|
+
verifiedHumanAt: Date | null;
|
|
165
|
+
emailVerificationStatus: string;
|
|
166
|
+
otpForEmailVerification: string | null;
|
|
167
|
+
isActive: boolean;
|
|
168
|
+
}
|
|
169
|
+
interface AuthSession {
|
|
170
|
+
id: number;
|
|
171
|
+
userId: number;
|
|
172
|
+
socketId: string | null;
|
|
173
|
+
twoFaSecret: string | null;
|
|
174
|
+
browserName: string;
|
|
175
|
+
issuedAt: Date;
|
|
176
|
+
lastUsed: Date;
|
|
177
|
+
revokedAt: Date | null;
|
|
178
|
+
deviceId: number | null;
|
|
179
|
+
}
|
|
180
|
+
interface AuthOTP {
|
|
181
|
+
id: number;
|
|
182
|
+
code: number;
|
|
183
|
+
expiresAt: Date;
|
|
184
|
+
userId: number;
|
|
185
|
+
}
|
|
186
|
+
interface AuthPasswordReset {
|
|
187
|
+
id: string;
|
|
188
|
+
createdAt: Date;
|
|
189
|
+
userId: number;
|
|
190
|
+
}
|
|
191
|
+
interface CreateUserData {
|
|
192
|
+
username: string;
|
|
193
|
+
email: string;
|
|
194
|
+
password: string | null;
|
|
195
|
+
status: string;
|
|
196
|
+
tag: string;
|
|
197
|
+
twoFaEnabled: boolean;
|
|
198
|
+
emailVerificationStatus: string;
|
|
199
|
+
verifiedHumanAt: Date | null;
|
|
200
|
+
oauthProvider?: string;
|
|
201
|
+
oauthId?: string;
|
|
202
|
+
}
|
|
203
|
+
interface CreateSessionData {
|
|
204
|
+
userId: number;
|
|
205
|
+
browserName: string;
|
|
206
|
+
socketId: string | null;
|
|
207
|
+
[key: string]: unknown;
|
|
208
|
+
}
|
|
209
|
+
type SessionWithUser = AuthSession & {
|
|
210
|
+
user: {
|
|
211
|
+
status: string;
|
|
212
|
+
verifiedHumanAt: Date | null;
|
|
213
|
+
};
|
|
214
|
+
};
|
|
215
|
+
type SessionWithDevice = {
|
|
216
|
+
twoFaSecret: string | null;
|
|
217
|
+
deviceId: number | null;
|
|
218
|
+
device: {
|
|
219
|
+
pushToken: string;
|
|
220
|
+
} | null;
|
|
221
|
+
};
|
|
222
|
+
interface DatabaseAdapter {
|
|
223
|
+
user: {
|
|
224
|
+
findByEmailInsensitive(email: string): Promise<AuthUser | null>;
|
|
225
|
+
findByUsernameInsensitive(username: string): Promise<AuthUser | null>;
|
|
226
|
+
findByEmailOrUsernameInsensitive(identifier: string): Promise<AuthUser | null>;
|
|
227
|
+
findByEmailOrOAuthId(email: string, oauthId: string): Promise<AuthUser | null>;
|
|
228
|
+
findById(id: number): Promise<AuthUser | null>;
|
|
229
|
+
findActiveById(id: number): Promise<AuthUser | null>;
|
|
230
|
+
create(data: CreateUserData): Promise<AuthUser>;
|
|
231
|
+
update(id: number, data: Partial<Omit<AuthUser, 'id'>>): Promise<AuthUser>;
|
|
232
|
+
};
|
|
233
|
+
session: {
|
|
234
|
+
/** Find session by ID with user status and verifiedHumanAt joined. */
|
|
235
|
+
findById(id: number): Promise<SessionWithUser | null>;
|
|
236
|
+
create(data: CreateSessionData): Promise<AuthSession>;
|
|
237
|
+
update(id: number, data: Partial<Pick<AuthSession, 'revokedAt' | 'lastUsed' | 'twoFaSecret' | 'deviceId'>>): Promise<AuthSession>;
|
|
238
|
+
/** Update lastUsed and return session with user's verifiedHumanAt. */
|
|
239
|
+
updateLastUsed(id: number): Promise<AuthSession & {
|
|
240
|
+
user: {
|
|
241
|
+
verifiedHumanAt: Date | null;
|
|
242
|
+
};
|
|
243
|
+
}>;
|
|
244
|
+
/** Set revokedAt on a single session. */
|
|
245
|
+
revoke(id: number): Promise<void>;
|
|
246
|
+
/** Find active (non-revoked) sessions for a user, optionally excluding one. */
|
|
247
|
+
findActiveByUserId(userId: number, excludeSessionId?: number): Promise<Pick<AuthSession, 'id' | 'socketId' | 'userId'>[]>;
|
|
248
|
+
/** Revoke all active sessions for a user, optionally excluding one. */
|
|
249
|
+
revokeAllByUserId(userId: number, excludeSessionId?: number): Promise<void>;
|
|
250
|
+
/** Get twoFaSecret from all sessions that have one for a user. */
|
|
251
|
+
findTwoFaSecretsByUserId(userId: number): Promise<{
|
|
252
|
+
twoFaSecret: string | null;
|
|
253
|
+
}[]>;
|
|
254
|
+
/** Clear twoFaSecret on sessions for a user, optionally excluding one. */
|
|
255
|
+
clearTwoFaSecrets(userId: number, excludeSessionId?: number): Promise<void>;
|
|
256
|
+
/** Find session with device relation for TOTP verification. */
|
|
257
|
+
findByIdWithDevice(id: number, userId: number): Promise<SessionWithDevice | null>;
|
|
258
|
+
/** Revoke other sessions that share a device push token. */
|
|
259
|
+
revokeByDevicePushToken(userId: number, pushToken: string, excludeSessionId: number): Promise<void>;
|
|
260
|
+
/** Clear deviceId on all sessions for a user+device pair. */
|
|
261
|
+
clearDeviceId(userId: number, deviceId: number): Promise<void>;
|
|
262
|
+
};
|
|
263
|
+
otp: {
|
|
264
|
+
findValidByUserAndCode(userId: number, code: number): Promise<AuthOTP | null>;
|
|
265
|
+
create(data: {
|
|
266
|
+
userId: number;
|
|
267
|
+
code: number;
|
|
268
|
+
expiresAt: Date;
|
|
269
|
+
}): Promise<AuthOTP>;
|
|
270
|
+
delete(id: number): Promise<void>;
|
|
271
|
+
};
|
|
272
|
+
passwordReset: {
|
|
273
|
+
findById(id: string): Promise<AuthPasswordReset | null>;
|
|
274
|
+
create(userId: number): Promise<AuthPasswordReset>;
|
|
275
|
+
delete(id: string): Promise<void>;
|
|
276
|
+
deleteAllByUserId(userId: number): Promise<void>;
|
|
277
|
+
};
|
|
278
|
+
device: {
|
|
279
|
+
findByTokenSessionAndUser(pushToken: string, sessionId: number, userId: number): Promise<{
|
|
280
|
+
id: number;
|
|
281
|
+
} | null>;
|
|
282
|
+
upsertByPushToken(pushToken: string, sessionId: number, userId: number): Promise<void>;
|
|
283
|
+
findByUserAndToken(userId: number, pushToken: string): Promise<{
|
|
284
|
+
id: number;
|
|
285
|
+
} | null>;
|
|
286
|
+
disconnectUser(deviceId: number, userId: number): Promise<void>;
|
|
287
|
+
hasRemainingUsers(deviceId: number): Promise<boolean>;
|
|
288
|
+
delete(id: number): Promise<void>;
|
|
289
|
+
};
|
|
290
|
+
admin: {
|
|
291
|
+
findByUserId(userId: number): Promise<{
|
|
292
|
+
ip: string;
|
|
293
|
+
} | null>;
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
type PrismaClient = any;
|
|
298
|
+
/**
|
|
299
|
+
* Creates a DatabaseAdapter backed by Prisma.
|
|
300
|
+
* Each method is a direct extraction of existing Prisma calls from the procedures.
|
|
301
|
+
*/
|
|
302
|
+
declare function createPrismaAdapter(prisma: PrismaClient): DatabaseAdapter;
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Drizzle table references required by the adapter.
|
|
306
|
+
* Consumers pass their Drizzle table objects so the adapter
|
|
307
|
+
* can build queries without knowing the schema file location.
|
|
308
|
+
*/
|
|
309
|
+
interface DrizzleAdapterTables {
|
|
310
|
+
users: any;
|
|
311
|
+
sessions: any;
|
|
312
|
+
otps: any;
|
|
313
|
+
passwordResets: any;
|
|
314
|
+
devices: any;
|
|
315
|
+
admins: any;
|
|
316
|
+
/** Join table for many-to-many device↔user relation (if applicable). */
|
|
317
|
+
devicesToUsers?: any;
|
|
318
|
+
/** Join table for many-to-many device↔session relation (if applicable). */
|
|
319
|
+
devicesToSessions?: any;
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Any Drizzle database instance (pg, mysql, better-sqlite3, etc.).
|
|
323
|
+
* We keep this generic so consumers aren't locked into a specific driver.
|
|
324
|
+
*/
|
|
325
|
+
type DrizzleDB = any;
|
|
326
|
+
/**
|
|
327
|
+
* Creates a DatabaseAdapter backed by Drizzle ORM.
|
|
328
|
+
*
|
|
329
|
+
* Usage:
|
|
330
|
+
* ```ts
|
|
331
|
+
* import { drizzle } from 'drizzle-orm/node-postgres';
|
|
332
|
+
* import { createDrizzleAdapter } from '@factiii/auth';
|
|
333
|
+
* import * as schema from './schema';
|
|
334
|
+
*
|
|
335
|
+
* const db = drizzle(pool, { schema });
|
|
336
|
+
* const adapter = createDrizzleAdapter(db, {
|
|
337
|
+
* users: schema.users,
|
|
338
|
+
* sessions: schema.sessions,
|
|
339
|
+
* otps: schema.otps,
|
|
340
|
+
* passwordResets: schema.passwordResets,
|
|
341
|
+
* devices: schema.devices,
|
|
342
|
+
* admins: schema.admins,
|
|
343
|
+
* });
|
|
344
|
+
* ```
|
|
345
|
+
*
|
|
346
|
+
* **Important:** This adapter uses Drizzle's relational query API (`db.query.*`)
|
|
347
|
+
* for joins and `db.insert/update/delete` for mutations. Make sure your Drizzle
|
|
348
|
+
* instance is created with `{ schema }` so relational queries work.
|
|
349
|
+
*/
|
|
350
|
+
declare function createDrizzleAdapter(db: DrizzleDB, tables: DrizzleAdapterTables): DatabaseAdapter;
|
|
351
|
+
|
|
152
352
|
/**
|
|
153
353
|
* JWT payload structure
|
|
154
354
|
*/
|
|
@@ -241,9 +441,15 @@ interface AuthFeatures {
|
|
|
241
441
|
}
|
|
242
442
|
interface AuthConfig<TExtensions extends SchemaExtensions = {}> {
|
|
243
443
|
/**
|
|
244
|
-
*
|
|
444
|
+
* Database adapter (use createPrismaAdapter or implement your own).
|
|
445
|
+
* If omitted but `prisma` is provided, a PrismaAdapter is created automatically.
|
|
245
446
|
*/
|
|
246
|
-
|
|
447
|
+
database?: DatabaseAdapter;
|
|
448
|
+
/**
|
|
449
|
+
* @deprecated Use `database` with createPrismaAdapter() instead.
|
|
450
|
+
* Prisma client instance — kept for backwards compatibility.
|
|
451
|
+
*/
|
|
452
|
+
prisma?: unknown;
|
|
247
453
|
/**
|
|
248
454
|
* Secret keys for JWT signing
|
|
249
455
|
*/
|
|
@@ -318,13 +524,17 @@ declare const defaultCookieSettings: CookieSettings;
|
|
|
318
524
|
declare const defaultStorageKeys: {
|
|
319
525
|
authToken: string;
|
|
320
526
|
};
|
|
527
|
+
/** Resolved config type with database adapter guaranteed. */
|
|
528
|
+
type ResolvedAuthConfig = Required<Omit<AuthConfig, 'hooks' | 'oauthKeys' | 'schemaExtensions' | 'prisma'>> & AuthConfig & {
|
|
529
|
+
database: DatabaseAdapter;
|
|
530
|
+
};
|
|
321
531
|
/**
|
|
322
|
-
* Create a fully resolved auth config with defaults applied
|
|
532
|
+
* Create a fully resolved auth config with defaults applied.
|
|
533
|
+
* Accepts either `database` (adapter) or `prisma` (auto-wrapped).
|
|
323
534
|
*/
|
|
324
|
-
declare function createAuthConfig(config: AuthConfig):
|
|
325
|
-
type ResolvedAuthConfig = ReturnType<typeof createAuthConfig>;
|
|
535
|
+
declare function createAuthConfig(config: AuthConfig): ResolvedAuthConfig;
|
|
326
536
|
/**
|
|
327
|
-
* Default auth config (requires prisma and secrets to be provided)
|
|
537
|
+
* Default auth config (requires database/prisma and secrets to be provided)
|
|
328
538
|
*/
|
|
329
539
|
declare const defaultAuthConfig: {
|
|
330
540
|
features: AuthFeatures;
|
|
@@ -438,7 +648,7 @@ declare function createAuthRouter<TExtensions extends SchemaExtensions = {}>(con
|
|
|
438
648
|
input: void;
|
|
439
649
|
output: {
|
|
440
650
|
email: string;
|
|
441
|
-
status:
|
|
651
|
+
status: string;
|
|
442
652
|
isVerified: boolean;
|
|
443
653
|
};
|
|
444
654
|
meta: Meta;
|
|
@@ -659,12 +869,12 @@ declare function createAuthRouter<TExtensions extends SchemaExtensions = {}>(con
|
|
|
659
869
|
email: zod.ZodString;
|
|
660
870
|
password: zod.ZodEffects<zod.ZodString, string, string>;
|
|
661
871
|
}, "strip", zod.ZodTypeAny, {
|
|
662
|
-
email: string;
|
|
663
872
|
username: string;
|
|
873
|
+
email: string;
|
|
664
874
|
password: string;
|
|
665
875
|
}, {
|
|
666
|
-
email: string;
|
|
667
876
|
username: string;
|
|
877
|
+
email: string;
|
|
668
878
|
password: string;
|
|
669
879
|
}>>["in"] extends infer T_7 ? T_7 extends inferParser<[TExtensions["signup"]] extends [zod.AnyZodObject] ? zod.ZodObject<{
|
|
670
880
|
username: zod.ZodString;
|
|
@@ -683,12 +893,12 @@ declare function createAuthRouter<TExtensions extends SchemaExtensions = {}>(con
|
|
|
683
893
|
email: zod.ZodString;
|
|
684
894
|
password: zod.ZodEffects<zod.ZodString, string, string>;
|
|
685
895
|
}, "strip", zod.ZodTypeAny, {
|
|
686
|
-
email: string;
|
|
687
896
|
username: string;
|
|
897
|
+
email: string;
|
|
688
898
|
password: string;
|
|
689
899
|
}, {
|
|
690
|
-
email: string;
|
|
691
900
|
username: string;
|
|
901
|
+
email: string;
|
|
692
902
|
password: string;
|
|
693
903
|
}>>["in"] ? T_7 extends _trpc_server.TRPCUnsetMarker ? void : T_7 : never : never;
|
|
694
904
|
output: {
|
|
@@ -754,6 +964,7 @@ declare function createAuthRouter<TExtensions extends SchemaExtensions = {}>(con
|
|
|
754
964
|
output: {
|
|
755
965
|
success: boolean;
|
|
756
966
|
requires2FA: boolean;
|
|
967
|
+
userId: number;
|
|
757
968
|
user?: undefined;
|
|
758
969
|
} | {
|
|
759
970
|
success: boolean;
|
|
@@ -763,6 +974,7 @@ declare function createAuthRouter<TExtensions extends SchemaExtensions = {}>(con
|
|
|
763
974
|
username: string;
|
|
764
975
|
};
|
|
765
976
|
requires2FA?: undefined;
|
|
977
|
+
userId?: undefined;
|
|
766
978
|
};
|
|
767
979
|
meta: Meta;
|
|
768
980
|
}>;
|
|
@@ -1044,4 +1256,4 @@ declare function verifyTotp(code: string, secret: string): Promise<boolean>;
|
|
|
1044
1256
|
*/
|
|
1045
1257
|
declare function generateOtp(min?: number, max?: number): number;
|
|
1046
1258
|
|
|
1047
|
-
export { type AuthConfig, type AuthFeatures, AuthHooks, type AuthRouter, DEFAULT_STORAGE_KEYS, type EmailAdapter, type OAuthKeys, type OAuthProvider, type OAuthResult, OAuthVerificationError, SchemaExtensions, type TokenSettings, type TrpcContext, cleanBase32String, clearAuthCookie, comparePassword, createAuthConfig, createAuthGuard, createAuthRouter, createAuthToken, createConsoleEmailAdapter, createNoopEmailAdapter, createOAuthVerifier, decodeToken, defaultAuthConfig, defaultCookieSettings, defaultStorageKeys, defaultTokenSettings, detectBrowser, generateOtp, generateTotpCode, generateTotpSecret, hashPassword, isMobileDevice, isNativeApp, isTokenExpiredError, isTokenInvalidError, parseAuthCookie, setAuthCookie, validatePasswordStrength, verifyAuthToken, verifyTotp };
|
|
1259
|
+
export { type AuthConfig, type AuthFeatures, AuthHooks, type AuthOTP, type AuthPasswordReset, type AuthRouter, type AuthSession, type AuthUser, type CreateSessionData, type CreateUserData, DEFAULT_STORAGE_KEYS, type DatabaseAdapter, type DrizzleAdapterTables, type EmailAdapter, type OAuthKeys, type OAuthProvider, type OAuthResult, OAuthVerificationError, SchemaExtensions, type SessionWithDevice, type SessionWithUser, type TokenSettings, type TrpcContext, cleanBase32String, clearAuthCookie, comparePassword, createAuthConfig, createAuthGuard, createAuthRouter, createAuthToken, createConsoleEmailAdapter, createDrizzleAdapter, createNoopEmailAdapter, createOAuthVerifier, createPrismaAdapter, decodeToken, defaultAuthConfig, defaultCookieSettings, defaultStorageKeys, defaultTokenSettings, detectBrowser, generateOtp, generateTotpCode, generateTotpSecret, hashPassword, isMobileDevice, isNativeApp, isTokenExpiredError, isTokenInvalidError, parseAuthCookie, setAuthCookie, validatePasswordStrength, verifyAuthToken, verifyTotp };
|