@factiii/auth 0.5.4 → 0.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +76 -20
- package/dist/index.d.ts +76 -20
- package/dist/index.js +93 -53
- package/dist/index.mjs +91 -53
- package/package.json +20 -33
package/dist/index.d.mts
CHANGED
|
@@ -6,6 +6,7 @@ import * as zod from 'zod';
|
|
|
6
6
|
import { CreateHTTPContextOptions } from '@trpc/server/adapters/standalone';
|
|
7
7
|
import { S as SchemaExtensions, A as AuthHooks } from './hooks-yHGJ7C6_.mjs';
|
|
8
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';
|
|
9
|
+
import { AnyPgTable, PgColumn, PgDatabase, PgQueryResultHKT } from 'drizzle-orm/pg-core';
|
|
9
10
|
|
|
10
11
|
//# sourceMappingURL=TRPCError.d.ts.map
|
|
11
12
|
//#endregion
|
|
@@ -294,35 +295,42 @@ interface DatabaseAdapter {
|
|
|
294
295
|
};
|
|
295
296
|
}
|
|
296
297
|
|
|
297
|
-
type PrismaClient = any;
|
|
298
298
|
/**
|
|
299
299
|
* Creates a DatabaseAdapter backed by Prisma.
|
|
300
|
-
*
|
|
300
|
+
* Pass your generated PrismaClient instance — its full types are preserved at the call site.
|
|
301
301
|
*/
|
|
302
|
-
declare function createPrismaAdapter(prisma:
|
|
302
|
+
declare function createPrismaAdapter(prisma: unknown): DatabaseAdapter;
|
|
303
303
|
|
|
304
|
+
/**
|
|
305
|
+
* A Postgres Drizzle table with column properties accessible by name.
|
|
306
|
+
* `AnyPgTable` is Drizzle's base Postgres table type; intersecting with
|
|
307
|
+
* `Record<string, Column>` exposes the column descriptors for index access.
|
|
308
|
+
*/
|
|
309
|
+
type DrizzleTable = AnyPgTable & Record<string, PgColumn>;
|
|
304
310
|
/**
|
|
305
311
|
* Drizzle table references required by the adapter.
|
|
306
|
-
* Consumers pass their Drizzle table objects so the adapter
|
|
312
|
+
* Consumers pass their Drizzle Postgres table objects so the adapter
|
|
307
313
|
* can build queries without knowing the schema file location.
|
|
314
|
+
*
|
|
315
|
+
* **Note:** This adapter only supports PostgreSQL via `drizzle-orm/pg-core`.
|
|
308
316
|
*/
|
|
309
317
|
interface DrizzleAdapterTables {
|
|
310
|
-
users:
|
|
311
|
-
sessions:
|
|
312
|
-
otps:
|
|
313
|
-
passwordResets:
|
|
314
|
-
devices:
|
|
315
|
-
admins:
|
|
318
|
+
users: DrizzleTable;
|
|
319
|
+
sessions: DrizzleTable;
|
|
320
|
+
otps: DrizzleTable;
|
|
321
|
+
passwordResets: DrizzleTable;
|
|
322
|
+
devices: DrizzleTable;
|
|
323
|
+
admins: DrizzleTable;
|
|
316
324
|
/** Join table for many-to-many device↔user relation (if applicable). */
|
|
317
|
-
devicesToUsers?:
|
|
325
|
+
devicesToUsers?: DrizzleTable;
|
|
318
326
|
/** Join table for many-to-many device↔session relation (if applicable). */
|
|
319
|
-
devicesToSessions?:
|
|
327
|
+
devicesToSessions?: DrizzleTable;
|
|
320
328
|
}
|
|
321
329
|
/**
|
|
322
|
-
* Any
|
|
323
|
-
*
|
|
330
|
+
* Any `PgDatabase` instance, regardless of the underlying driver
|
|
331
|
+
* (node-postgres, postgres.js, Neon, PGLite, etc.).
|
|
324
332
|
*/
|
|
325
|
-
type
|
|
333
|
+
type AnyPgDatabase = PgDatabase<PgQueryResultHKT, Record<string, unknown>>;
|
|
326
334
|
/**
|
|
327
335
|
* Creates a DatabaseAdapter backed by Drizzle ORM.
|
|
328
336
|
*
|
|
@@ -347,7 +355,7 @@ type DrizzleDB = any;
|
|
|
347
355
|
* for joins and `db.insert/update/delete` for mutations. Make sure your Drizzle
|
|
348
356
|
* instance is created with `{ schema }` so relational queries work.
|
|
349
357
|
*/
|
|
350
|
-
declare function createDrizzleAdapter(db:
|
|
358
|
+
declare function createDrizzleAdapter(db: AnyPgDatabase, tables: DrizzleAdapterTables): DatabaseAdapter;
|
|
351
359
|
|
|
352
360
|
/**
|
|
353
361
|
* JWT payload structure
|
|
@@ -505,9 +513,9 @@ declare function createAuthGuard(config: AuthConfig, t: TrpcBuilder): _trpc_serv
|
|
|
505
513
|
userId: number;
|
|
506
514
|
socketId: string | null;
|
|
507
515
|
sessionId: number;
|
|
516
|
+
ip: string | undefined;
|
|
508
517
|
headers: http.IncomingHttpHeaders;
|
|
509
518
|
res: http.ServerResponse<http.IncomingMessage>;
|
|
510
|
-
ip: string | undefined;
|
|
511
519
|
}, unknown>;
|
|
512
520
|
|
|
513
521
|
/**
|
|
@@ -1081,17 +1089,17 @@ declare function createAuthRouter<TExtensions extends SchemaExtensions = {}>(con
|
|
|
1081
1089
|
sessionId: number;
|
|
1082
1090
|
userId: number;
|
|
1083
1091
|
socketId: string | null;
|
|
1092
|
+
ip: string | undefined;
|
|
1084
1093
|
headers: http.IncomingHttpHeaders;
|
|
1085
1094
|
res: http.ServerResponse<http.IncomingMessage>;
|
|
1086
|
-
ip: string | undefined;
|
|
1087
1095
|
}, _trpc_server.TRPCUnsetMarker, _trpc_server.TRPCUnsetMarker, _trpc_server.TRPCUnsetMarker, _trpc_server.TRPCUnsetMarker, false>;
|
|
1088
1096
|
authProcedure: _trpc_server.TRPCProcedureBuilder<TrpcContext, Meta, {
|
|
1089
1097
|
sessionId: number;
|
|
1090
1098
|
userId: number;
|
|
1091
1099
|
socketId: string | null;
|
|
1100
|
+
ip: string | undefined;
|
|
1092
1101
|
headers: http.IncomingHttpHeaders;
|
|
1093
1102
|
res: http.ServerResponse<http.IncomingMessage>;
|
|
1094
|
-
ip: string | undefined;
|
|
1095
1103
|
}, _trpc_server.TRPCUnsetMarker, _trpc_server.TRPCUnsetMarker, _trpc_server.TRPCUnsetMarker, _trpc_server.TRPCUnsetMarker, false>;
|
|
1096
1104
|
createContext: ({ req, res }: CreateHTTPContextOptions) => TrpcContext;
|
|
1097
1105
|
};
|
|
@@ -1222,6 +1230,54 @@ declare function validatePasswordStrength(password: string, minLength?: number):
|
|
|
1222
1230
|
error?: string;
|
|
1223
1231
|
};
|
|
1224
1232
|
|
|
1233
|
+
/**
|
|
1234
|
+
* Parameters for creating a session with a signed JWT token.
|
|
1235
|
+
*/
|
|
1236
|
+
interface CreateSessionWithTokenParams {
|
|
1237
|
+
/** User ID to create the session for */
|
|
1238
|
+
userId: number;
|
|
1239
|
+
/** Browser name (from user-agent) */
|
|
1240
|
+
browserName: string;
|
|
1241
|
+
/** Socket ID for real-time connections */
|
|
1242
|
+
socketId: string | null;
|
|
1243
|
+
/** Device ID for push notifications */
|
|
1244
|
+
deviceId?: number;
|
|
1245
|
+
/** Extra fields to include in the session record (e.g., instanceId) */
|
|
1246
|
+
extraSessionData?: Record<string, unknown>;
|
|
1247
|
+
}
|
|
1248
|
+
/**
|
|
1249
|
+
* Result of creating a session with a token.
|
|
1250
|
+
*/
|
|
1251
|
+
interface SessionWithTokenResult {
|
|
1252
|
+
/** Signed JWT access token */
|
|
1253
|
+
accessToken: string;
|
|
1254
|
+
/** Created session ID */
|
|
1255
|
+
sessionId: number;
|
|
1256
|
+
}
|
|
1257
|
+
/**
|
|
1258
|
+
* Create a session and sign a JWT token.
|
|
1259
|
+
*
|
|
1260
|
+
* Use this for programmatic auth flows (magic links, auto-login, test helpers)
|
|
1261
|
+
* where you need a token without going through the full login procedure.
|
|
1262
|
+
*
|
|
1263
|
+
* @param config - Resolved auth config (from createAuthConfig)
|
|
1264
|
+
* @param params - Session creation parameters
|
|
1265
|
+
* @returns Signed JWT and session ID
|
|
1266
|
+
*/
|
|
1267
|
+
declare function createSessionWithToken(config: ResolvedAuthConfig, params: CreateSessionWithTokenParams): Promise<SessionWithTokenResult>;
|
|
1268
|
+
/**
|
|
1269
|
+
* Create a session, sign a JWT token, and set the auth cookie on the response.
|
|
1270
|
+
*
|
|
1271
|
+
* Convenience wrapper around {@link createSessionWithToken} for HTTP handlers
|
|
1272
|
+
* that need to set the cookie immediately.
|
|
1273
|
+
*
|
|
1274
|
+
* @param config - Resolved auth config (from createAuthConfig)
|
|
1275
|
+
* @param params - Session creation parameters
|
|
1276
|
+
* @param res - HTTP response to set the cookie on
|
|
1277
|
+
* @returns Signed JWT and session ID
|
|
1278
|
+
*/
|
|
1279
|
+
declare function createSessionWithTokenAndCookie(config: ResolvedAuthConfig, params: CreateSessionWithTokenParams, res: CreateHTTPContextOptions['res']): Promise<SessionWithTokenResult>;
|
|
1280
|
+
|
|
1225
1281
|
/**
|
|
1226
1282
|
* Generate a random TOTP secret
|
|
1227
1283
|
* @param length - Length of the secret (default: 16)
|
|
@@ -1256,4 +1312,4 @@ declare function verifyTotp(code: string, secret: string): Promise<boolean>;
|
|
|
1256
1312
|
*/
|
|
1257
1313
|
declare function generateOtp(min?: number, max?: number): number;
|
|
1258
1314
|
|
|
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 };
|
|
1315
|
+
export { type AuthConfig, type AuthFeatures, AuthHooks, type AuthOTP, type AuthPasswordReset, type AuthRouter, type AuthSession, type AuthUser, type CreateSessionData, type CreateSessionWithTokenParams, type CreateUserData, DEFAULT_STORAGE_KEYS, type DatabaseAdapter, type DrizzleAdapterTables, type EmailAdapter, type OAuthKeys, type OAuthProvider, type OAuthResult, OAuthVerificationError, type ResolvedAuthConfig, SchemaExtensions, type SessionWithDevice, type SessionWithTokenResult, type SessionWithUser, type TokenSettings, type TrpcContext, cleanBase32String, clearAuthCookie, comparePassword, createAuthConfig, createAuthGuard, createAuthRouter, createAuthToken, createConsoleEmailAdapter, createDrizzleAdapter, createNoopEmailAdapter, createOAuthVerifier, createPrismaAdapter, createSessionWithToken, createSessionWithTokenAndCookie, 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
|
@@ -6,6 +6,7 @@ import * as zod from 'zod';
|
|
|
6
6
|
import { CreateHTTPContextOptions } from '@trpc/server/adapters/standalone';
|
|
7
7
|
import { S as SchemaExtensions, A as AuthHooks } from './hooks-yHGJ7C6_.js';
|
|
8
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';
|
|
9
|
+
import { AnyPgTable, PgColumn, PgDatabase, PgQueryResultHKT } from 'drizzle-orm/pg-core';
|
|
9
10
|
|
|
10
11
|
//# sourceMappingURL=TRPCError.d.ts.map
|
|
11
12
|
//#endregion
|
|
@@ -294,35 +295,42 @@ interface DatabaseAdapter {
|
|
|
294
295
|
};
|
|
295
296
|
}
|
|
296
297
|
|
|
297
|
-
type PrismaClient = any;
|
|
298
298
|
/**
|
|
299
299
|
* Creates a DatabaseAdapter backed by Prisma.
|
|
300
|
-
*
|
|
300
|
+
* Pass your generated PrismaClient instance — its full types are preserved at the call site.
|
|
301
301
|
*/
|
|
302
|
-
declare function createPrismaAdapter(prisma:
|
|
302
|
+
declare function createPrismaAdapter(prisma: unknown): DatabaseAdapter;
|
|
303
303
|
|
|
304
|
+
/**
|
|
305
|
+
* A Postgres Drizzle table with column properties accessible by name.
|
|
306
|
+
* `AnyPgTable` is Drizzle's base Postgres table type; intersecting with
|
|
307
|
+
* `Record<string, Column>` exposes the column descriptors for index access.
|
|
308
|
+
*/
|
|
309
|
+
type DrizzleTable = AnyPgTable & Record<string, PgColumn>;
|
|
304
310
|
/**
|
|
305
311
|
* Drizzle table references required by the adapter.
|
|
306
|
-
* Consumers pass their Drizzle table objects so the adapter
|
|
312
|
+
* Consumers pass their Drizzle Postgres table objects so the adapter
|
|
307
313
|
* can build queries without knowing the schema file location.
|
|
314
|
+
*
|
|
315
|
+
* **Note:** This adapter only supports PostgreSQL via `drizzle-orm/pg-core`.
|
|
308
316
|
*/
|
|
309
317
|
interface DrizzleAdapterTables {
|
|
310
|
-
users:
|
|
311
|
-
sessions:
|
|
312
|
-
otps:
|
|
313
|
-
passwordResets:
|
|
314
|
-
devices:
|
|
315
|
-
admins:
|
|
318
|
+
users: DrizzleTable;
|
|
319
|
+
sessions: DrizzleTable;
|
|
320
|
+
otps: DrizzleTable;
|
|
321
|
+
passwordResets: DrizzleTable;
|
|
322
|
+
devices: DrizzleTable;
|
|
323
|
+
admins: DrizzleTable;
|
|
316
324
|
/** Join table for many-to-many device↔user relation (if applicable). */
|
|
317
|
-
devicesToUsers?:
|
|
325
|
+
devicesToUsers?: DrizzleTable;
|
|
318
326
|
/** Join table for many-to-many device↔session relation (if applicable). */
|
|
319
|
-
devicesToSessions?:
|
|
327
|
+
devicesToSessions?: DrizzleTable;
|
|
320
328
|
}
|
|
321
329
|
/**
|
|
322
|
-
* Any
|
|
323
|
-
*
|
|
330
|
+
* Any `PgDatabase` instance, regardless of the underlying driver
|
|
331
|
+
* (node-postgres, postgres.js, Neon, PGLite, etc.).
|
|
324
332
|
*/
|
|
325
|
-
type
|
|
333
|
+
type AnyPgDatabase = PgDatabase<PgQueryResultHKT, Record<string, unknown>>;
|
|
326
334
|
/**
|
|
327
335
|
* Creates a DatabaseAdapter backed by Drizzle ORM.
|
|
328
336
|
*
|
|
@@ -347,7 +355,7 @@ type DrizzleDB = any;
|
|
|
347
355
|
* for joins and `db.insert/update/delete` for mutations. Make sure your Drizzle
|
|
348
356
|
* instance is created with `{ schema }` so relational queries work.
|
|
349
357
|
*/
|
|
350
|
-
declare function createDrizzleAdapter(db:
|
|
358
|
+
declare function createDrizzleAdapter(db: AnyPgDatabase, tables: DrizzleAdapterTables): DatabaseAdapter;
|
|
351
359
|
|
|
352
360
|
/**
|
|
353
361
|
* JWT payload structure
|
|
@@ -505,9 +513,9 @@ declare function createAuthGuard(config: AuthConfig, t: TrpcBuilder): _trpc_serv
|
|
|
505
513
|
userId: number;
|
|
506
514
|
socketId: string | null;
|
|
507
515
|
sessionId: number;
|
|
516
|
+
ip: string | undefined;
|
|
508
517
|
headers: http.IncomingHttpHeaders;
|
|
509
518
|
res: http.ServerResponse<http.IncomingMessage>;
|
|
510
|
-
ip: string | undefined;
|
|
511
519
|
}, unknown>;
|
|
512
520
|
|
|
513
521
|
/**
|
|
@@ -1081,17 +1089,17 @@ declare function createAuthRouter<TExtensions extends SchemaExtensions = {}>(con
|
|
|
1081
1089
|
sessionId: number;
|
|
1082
1090
|
userId: number;
|
|
1083
1091
|
socketId: string | null;
|
|
1092
|
+
ip: string | undefined;
|
|
1084
1093
|
headers: http.IncomingHttpHeaders;
|
|
1085
1094
|
res: http.ServerResponse<http.IncomingMessage>;
|
|
1086
|
-
ip: string | undefined;
|
|
1087
1095
|
}, _trpc_server.TRPCUnsetMarker, _trpc_server.TRPCUnsetMarker, _trpc_server.TRPCUnsetMarker, _trpc_server.TRPCUnsetMarker, false>;
|
|
1088
1096
|
authProcedure: _trpc_server.TRPCProcedureBuilder<TrpcContext, Meta, {
|
|
1089
1097
|
sessionId: number;
|
|
1090
1098
|
userId: number;
|
|
1091
1099
|
socketId: string | null;
|
|
1100
|
+
ip: string | undefined;
|
|
1092
1101
|
headers: http.IncomingHttpHeaders;
|
|
1093
1102
|
res: http.ServerResponse<http.IncomingMessage>;
|
|
1094
|
-
ip: string | undefined;
|
|
1095
1103
|
}, _trpc_server.TRPCUnsetMarker, _trpc_server.TRPCUnsetMarker, _trpc_server.TRPCUnsetMarker, _trpc_server.TRPCUnsetMarker, false>;
|
|
1096
1104
|
createContext: ({ req, res }: CreateHTTPContextOptions) => TrpcContext;
|
|
1097
1105
|
};
|
|
@@ -1222,6 +1230,54 @@ declare function validatePasswordStrength(password: string, minLength?: number):
|
|
|
1222
1230
|
error?: string;
|
|
1223
1231
|
};
|
|
1224
1232
|
|
|
1233
|
+
/**
|
|
1234
|
+
* Parameters for creating a session with a signed JWT token.
|
|
1235
|
+
*/
|
|
1236
|
+
interface CreateSessionWithTokenParams {
|
|
1237
|
+
/** User ID to create the session for */
|
|
1238
|
+
userId: number;
|
|
1239
|
+
/** Browser name (from user-agent) */
|
|
1240
|
+
browserName: string;
|
|
1241
|
+
/** Socket ID for real-time connections */
|
|
1242
|
+
socketId: string | null;
|
|
1243
|
+
/** Device ID for push notifications */
|
|
1244
|
+
deviceId?: number;
|
|
1245
|
+
/** Extra fields to include in the session record (e.g., instanceId) */
|
|
1246
|
+
extraSessionData?: Record<string, unknown>;
|
|
1247
|
+
}
|
|
1248
|
+
/**
|
|
1249
|
+
* Result of creating a session with a token.
|
|
1250
|
+
*/
|
|
1251
|
+
interface SessionWithTokenResult {
|
|
1252
|
+
/** Signed JWT access token */
|
|
1253
|
+
accessToken: string;
|
|
1254
|
+
/** Created session ID */
|
|
1255
|
+
sessionId: number;
|
|
1256
|
+
}
|
|
1257
|
+
/**
|
|
1258
|
+
* Create a session and sign a JWT token.
|
|
1259
|
+
*
|
|
1260
|
+
* Use this for programmatic auth flows (magic links, auto-login, test helpers)
|
|
1261
|
+
* where you need a token without going through the full login procedure.
|
|
1262
|
+
*
|
|
1263
|
+
* @param config - Resolved auth config (from createAuthConfig)
|
|
1264
|
+
* @param params - Session creation parameters
|
|
1265
|
+
* @returns Signed JWT and session ID
|
|
1266
|
+
*/
|
|
1267
|
+
declare function createSessionWithToken(config: ResolvedAuthConfig, params: CreateSessionWithTokenParams): Promise<SessionWithTokenResult>;
|
|
1268
|
+
/**
|
|
1269
|
+
* Create a session, sign a JWT token, and set the auth cookie on the response.
|
|
1270
|
+
*
|
|
1271
|
+
* Convenience wrapper around {@link createSessionWithToken} for HTTP handlers
|
|
1272
|
+
* that need to set the cookie immediately.
|
|
1273
|
+
*
|
|
1274
|
+
* @param config - Resolved auth config (from createAuthConfig)
|
|
1275
|
+
* @param params - Session creation parameters
|
|
1276
|
+
* @param res - HTTP response to set the cookie on
|
|
1277
|
+
* @returns Signed JWT and session ID
|
|
1278
|
+
*/
|
|
1279
|
+
declare function createSessionWithTokenAndCookie(config: ResolvedAuthConfig, params: CreateSessionWithTokenParams, res: CreateHTTPContextOptions['res']): Promise<SessionWithTokenResult>;
|
|
1280
|
+
|
|
1225
1281
|
/**
|
|
1226
1282
|
* Generate a random TOTP secret
|
|
1227
1283
|
* @param length - Length of the secret (default: 16)
|
|
@@ -1256,4 +1312,4 @@ declare function verifyTotp(code: string, secret: string): Promise<boolean>;
|
|
|
1256
1312
|
*/
|
|
1257
1313
|
declare function generateOtp(min?: number, max?: number): number;
|
|
1258
1314
|
|
|
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 };
|
|
1315
|
+
export { type AuthConfig, type AuthFeatures, AuthHooks, type AuthOTP, type AuthPasswordReset, type AuthRouter, type AuthSession, type AuthUser, type CreateSessionData, type CreateSessionWithTokenParams, type CreateUserData, DEFAULT_STORAGE_KEYS, type DatabaseAdapter, type DrizzleAdapterTables, type EmailAdapter, type OAuthKeys, type OAuthProvider, type OAuthResult, OAuthVerificationError, type ResolvedAuthConfig, SchemaExtensions, type SessionWithDevice, type SessionWithTokenResult, type SessionWithUser, type TokenSettings, type TrpcContext, cleanBase32String, clearAuthCookie, comparePassword, createAuthConfig, createAuthGuard, createAuthRouter, createAuthToken, createConsoleEmailAdapter, createDrizzleAdapter, createNoopEmailAdapter, createOAuthVerifier, createPrismaAdapter, createSessionWithToken, createSessionWithTokenAndCookie, decodeToken, defaultAuthConfig, defaultCookieSettings, defaultStorageKeys, defaultTokenSettings, detectBrowser, generateOtp, generateTotpCode, generateTotpSecret, hashPassword, isMobileDevice, isNativeApp, isTokenExpiredError, isTokenInvalidError, parseAuthCookie, setAuthCookie, validatePasswordStrength, verifyAuthToken, verifyTotp };
|
package/dist/index.js
CHANGED
|
@@ -46,6 +46,8 @@ __export(index_exports, {
|
|
|
46
46
|
createNoopEmailAdapter: () => createNoopEmailAdapter,
|
|
47
47
|
createOAuthVerifier: () => createOAuthVerifier,
|
|
48
48
|
createPrismaAdapter: () => createPrismaAdapter,
|
|
49
|
+
createSessionWithToken: () => createSessionWithToken,
|
|
50
|
+
createSessionWithTokenAndCookie: () => createSessionWithTokenAndCookie,
|
|
49
51
|
decodeToken: () => decodeToken,
|
|
50
52
|
defaultAuthConfig: () => defaultAuthConfig,
|
|
51
53
|
defaultCookieSettings: () => defaultCookieSettings,
|
|
@@ -82,20 +84,21 @@ var import_server = require("@trpc/server");
|
|
|
82
84
|
|
|
83
85
|
// src/adapters/prismaAdapter.ts
|
|
84
86
|
function createPrismaAdapter(prisma) {
|
|
87
|
+
const db = prisma;
|
|
85
88
|
return {
|
|
86
89
|
user: {
|
|
87
90
|
async findByEmailInsensitive(email) {
|
|
88
|
-
return
|
|
91
|
+
return db.user.findFirst({
|
|
89
92
|
where: { email: { equals: email, mode: "insensitive" } }
|
|
90
93
|
});
|
|
91
94
|
},
|
|
92
95
|
async findByUsernameInsensitive(username) {
|
|
93
|
-
return
|
|
96
|
+
return db.user.findFirst({
|
|
94
97
|
where: { username: { equals: username, mode: "insensitive" } }
|
|
95
98
|
});
|
|
96
99
|
},
|
|
97
100
|
async findByEmailOrUsernameInsensitive(identifier) {
|
|
98
|
-
return
|
|
101
|
+
return db.user.findFirst({
|
|
99
102
|
where: {
|
|
100
103
|
OR: [
|
|
101
104
|
{ email: { equals: identifier, mode: "insensitive" } },
|
|
@@ -105,7 +108,7 @@ function createPrismaAdapter(prisma) {
|
|
|
105
108
|
});
|
|
106
109
|
},
|
|
107
110
|
async findByEmailOrOAuthId(email, oauthId) {
|
|
108
|
-
return
|
|
111
|
+
return db.user.findFirst({
|
|
109
112
|
where: {
|
|
110
113
|
OR: [
|
|
111
114
|
{ email: { equals: email, mode: "insensitive" } },
|
|
@@ -115,23 +118,23 @@ function createPrismaAdapter(prisma) {
|
|
|
115
118
|
});
|
|
116
119
|
},
|
|
117
120
|
async findById(id) {
|
|
118
|
-
return
|
|
121
|
+
return db.user.findUnique({ where: { id } });
|
|
119
122
|
},
|
|
120
123
|
async findActiveById(id) {
|
|
121
|
-
return
|
|
124
|
+
return db.user.findUnique({
|
|
122
125
|
where: { id, status: "ACTIVE" }
|
|
123
126
|
});
|
|
124
127
|
},
|
|
125
128
|
async create(data) {
|
|
126
|
-
return
|
|
129
|
+
return db.user.create({ data });
|
|
127
130
|
},
|
|
128
131
|
async update(id, data) {
|
|
129
|
-
return
|
|
132
|
+
return db.user.update({ where: { id }, data });
|
|
130
133
|
}
|
|
131
134
|
},
|
|
132
135
|
session: {
|
|
133
136
|
async findById(id) {
|
|
134
|
-
const session = await
|
|
137
|
+
const session = await db.session.findUnique({
|
|
135
138
|
where: { id },
|
|
136
139
|
select: {
|
|
137
140
|
id: true,
|
|
@@ -149,13 +152,13 @@ function createPrismaAdapter(prisma) {
|
|
|
149
152
|
return session;
|
|
150
153
|
},
|
|
151
154
|
async create(data) {
|
|
152
|
-
return
|
|
155
|
+
return db.session.create({ data });
|
|
153
156
|
},
|
|
154
157
|
async update(id, data) {
|
|
155
|
-
return
|
|
158
|
+
return db.session.update({ where: { id }, data });
|
|
156
159
|
},
|
|
157
160
|
async updateLastUsed(id) {
|
|
158
|
-
const session = await
|
|
161
|
+
const session = await db.session.update({
|
|
159
162
|
where: { id },
|
|
160
163
|
data: { lastUsed: /* @__PURE__ */ new Date() },
|
|
161
164
|
select: {
|
|
@@ -174,13 +177,13 @@ function createPrismaAdapter(prisma) {
|
|
|
174
177
|
return session;
|
|
175
178
|
},
|
|
176
179
|
async revoke(id) {
|
|
177
|
-
await
|
|
180
|
+
await db.session.update({
|
|
178
181
|
where: { id },
|
|
179
182
|
data: { revokedAt: /* @__PURE__ */ new Date() }
|
|
180
183
|
});
|
|
181
184
|
},
|
|
182
185
|
async findActiveByUserId(userId, excludeSessionId) {
|
|
183
|
-
return
|
|
186
|
+
return db.session.findMany({
|
|
184
187
|
where: {
|
|
185
188
|
userId,
|
|
186
189
|
revokedAt: null,
|
|
@@ -190,7 +193,7 @@ function createPrismaAdapter(prisma) {
|
|
|
190
193
|
});
|
|
191
194
|
},
|
|
192
195
|
async revokeAllByUserId(userId, excludeSessionId) {
|
|
193
|
-
await
|
|
196
|
+
await db.session.updateMany({
|
|
194
197
|
where: {
|
|
195
198
|
userId,
|
|
196
199
|
revokedAt: null,
|
|
@@ -200,13 +203,13 @@ function createPrismaAdapter(prisma) {
|
|
|
200
203
|
});
|
|
201
204
|
},
|
|
202
205
|
async findTwoFaSecretsByUserId(userId) {
|
|
203
|
-
return
|
|
206
|
+
return db.session.findMany({
|
|
204
207
|
where: { userId, twoFaSecret: { not: null } },
|
|
205
208
|
select: { twoFaSecret: true }
|
|
206
209
|
});
|
|
207
210
|
},
|
|
208
211
|
async clearTwoFaSecrets(userId, excludeSessionId) {
|
|
209
|
-
await
|
|
212
|
+
await db.session.updateMany({
|
|
210
213
|
where: {
|
|
211
214
|
userId,
|
|
212
215
|
...excludeSessionId ? { NOT: { id: excludeSessionId } } : {}
|
|
@@ -215,7 +218,7 @@ function createPrismaAdapter(prisma) {
|
|
|
215
218
|
});
|
|
216
219
|
},
|
|
217
220
|
async findByIdWithDevice(id, userId) {
|
|
218
|
-
const session = await
|
|
221
|
+
const session = await db.session.findUnique({
|
|
219
222
|
where: { id, userId },
|
|
220
223
|
select: {
|
|
221
224
|
twoFaSecret: true,
|
|
@@ -226,7 +229,7 @@ function createPrismaAdapter(prisma) {
|
|
|
226
229
|
return session;
|
|
227
230
|
},
|
|
228
231
|
async revokeByDevicePushToken(userId, pushToken, excludeSessionId) {
|
|
229
|
-
await
|
|
232
|
+
await db.session.updateMany({
|
|
230
233
|
where: {
|
|
231
234
|
userId,
|
|
232
235
|
id: { not: excludeSessionId },
|
|
@@ -237,7 +240,7 @@ function createPrismaAdapter(prisma) {
|
|
|
237
240
|
});
|
|
238
241
|
},
|
|
239
242
|
async clearDeviceId(userId, deviceId) {
|
|
240
|
-
await
|
|
243
|
+
await db.session.updateMany({
|
|
241
244
|
where: { userId, deviceId },
|
|
242
245
|
data: { deviceId: null }
|
|
243
246
|
});
|
|
@@ -245,39 +248,39 @@ function createPrismaAdapter(prisma) {
|
|
|
245
248
|
},
|
|
246
249
|
otp: {
|
|
247
250
|
async findValidByUserAndCode(userId, code) {
|
|
248
|
-
return
|
|
251
|
+
return db.oTP.findFirst({
|
|
249
252
|
where: { userId, code, expiresAt: { gte: /* @__PURE__ */ new Date() } }
|
|
250
253
|
});
|
|
251
254
|
},
|
|
252
255
|
async create(data) {
|
|
253
|
-
return
|
|
256
|
+
return db.oTP.create({ data });
|
|
254
257
|
},
|
|
255
258
|
async delete(id) {
|
|
256
|
-
await
|
|
259
|
+
await db.oTP.delete({ where: { id } });
|
|
257
260
|
}
|
|
258
261
|
},
|
|
259
262
|
passwordReset: {
|
|
260
263
|
async findById(id) {
|
|
261
|
-
return
|
|
264
|
+
return db.passwordReset.findUnique({
|
|
262
265
|
where: { id },
|
|
263
266
|
select: { id: true, createdAt: true, userId: true }
|
|
264
267
|
});
|
|
265
268
|
},
|
|
266
269
|
async create(userId) {
|
|
267
|
-
return
|
|
270
|
+
return db.passwordReset.create({
|
|
268
271
|
data: { userId }
|
|
269
272
|
});
|
|
270
273
|
},
|
|
271
274
|
async delete(id) {
|
|
272
|
-
await
|
|
275
|
+
await db.passwordReset.delete({ where: { id } });
|
|
273
276
|
},
|
|
274
277
|
async deleteAllByUserId(userId) {
|
|
275
|
-
await
|
|
278
|
+
await db.passwordReset.deleteMany({ where: { userId } });
|
|
276
279
|
}
|
|
277
280
|
},
|
|
278
281
|
device: {
|
|
279
282
|
async findByTokenSessionAndUser(pushToken, sessionId, userId) {
|
|
280
|
-
return
|
|
283
|
+
return db.device.findFirst({
|
|
281
284
|
where: {
|
|
282
285
|
pushToken,
|
|
283
286
|
sessions: { some: { id: sessionId } },
|
|
@@ -287,7 +290,7 @@ function createPrismaAdapter(prisma) {
|
|
|
287
290
|
});
|
|
288
291
|
},
|
|
289
292
|
async upsertByPushToken(pushToken, sessionId, userId) {
|
|
290
|
-
await
|
|
293
|
+
await db.device.upsert({
|
|
291
294
|
where: { pushToken },
|
|
292
295
|
create: {
|
|
293
296
|
pushToken,
|
|
@@ -301,31 +304,31 @@ function createPrismaAdapter(prisma) {
|
|
|
301
304
|
});
|
|
302
305
|
},
|
|
303
306
|
async findByUserAndToken(userId, pushToken) {
|
|
304
|
-
return
|
|
307
|
+
return db.device.findFirst({
|
|
305
308
|
where: { users: { some: { id: userId } }, pushToken },
|
|
306
309
|
select: { id: true }
|
|
307
310
|
});
|
|
308
311
|
},
|
|
309
312
|
async disconnectUser(deviceId, userId) {
|
|
310
|
-
await
|
|
313
|
+
await db.device.update({
|
|
311
314
|
where: { id: deviceId },
|
|
312
315
|
data: { users: { disconnect: { id: userId } } }
|
|
313
316
|
});
|
|
314
317
|
},
|
|
315
318
|
async hasRemainingUsers(deviceId) {
|
|
316
|
-
const result = await
|
|
319
|
+
const result = await db.device.findUnique({
|
|
317
320
|
where: { id: deviceId },
|
|
318
321
|
select: { users: { select: { id: true }, take: 1 } }
|
|
319
322
|
});
|
|
320
323
|
return (result?.users.length ?? 0) > 0;
|
|
321
324
|
},
|
|
322
325
|
async delete(id) {
|
|
323
|
-
await
|
|
326
|
+
await db.device.delete({ where: { id } });
|
|
324
327
|
}
|
|
325
328
|
},
|
|
326
329
|
admin: {
|
|
327
330
|
async findByUserId(userId) {
|
|
328
|
-
return
|
|
331
|
+
return db.admin.findFirst({
|
|
329
332
|
where: { userId },
|
|
330
333
|
select: { ip: true }
|
|
331
334
|
});
|
|
@@ -498,11 +501,12 @@ function createDrizzleAdapter(db, tables) {
|
|
|
498
501
|
if (excludeSessionId !== void 0) {
|
|
499
502
|
conditions.push(ne(sessions.id, excludeSessionId));
|
|
500
503
|
}
|
|
501
|
-
|
|
504
|
+
const activeRows = await db.select({
|
|
502
505
|
id: sessions.id,
|
|
503
506
|
socketId: sessions.socketId,
|
|
504
507
|
userId: sessions.userId
|
|
505
508
|
}).from(sessions).where(and(...conditions));
|
|
509
|
+
return activeRows;
|
|
506
510
|
},
|
|
507
511
|
async revokeAllByUserId(userId, excludeSessionId) {
|
|
508
512
|
const conditions = [eq(sessions.userId, userId), isNull(sessions.revokedAt)];
|
|
@@ -512,7 +516,8 @@ function createDrizzleAdapter(db, tables) {
|
|
|
512
516
|
await db.update(sessions).set({ revokedAt: /* @__PURE__ */ new Date() }).where(and(...conditions));
|
|
513
517
|
},
|
|
514
518
|
async findTwoFaSecretsByUserId(userId) {
|
|
515
|
-
|
|
519
|
+
const secretRows = await db.select({ twoFaSecret: sessions.twoFaSecret }).from(sessions).where(and(eq(sessions.userId, userId), isNotNull(sessions.twoFaSecret)));
|
|
520
|
+
return secretRows;
|
|
516
521
|
},
|
|
517
522
|
async clearTwoFaSecrets(userId, excludeSessionId) {
|
|
518
523
|
const conditions = [eq(sessions.userId, userId)];
|
|
@@ -531,10 +536,11 @@ function createDrizzleAdapter(db, tables) {
|
|
|
531
536
|
}).from(sessions).leftJoin(devices, eq(sessions.deviceId, devices.id)).where(and(eq(sessions.id, id), eq(sessions.userId, userId))).limit(1);
|
|
532
537
|
if (!rows[0]) return null;
|
|
533
538
|
const row = rows[0];
|
|
539
|
+
const device = row.device;
|
|
534
540
|
return {
|
|
535
541
|
twoFaSecret: row.twoFaSecret,
|
|
536
542
|
deviceId: row.deviceId,
|
|
537
|
-
device:
|
|
543
|
+
device: device?.pushToken ? { pushToken: device.pushToken } : null
|
|
538
544
|
};
|
|
539
545
|
},
|
|
540
546
|
async revokeByDevicePushToken(userId, pushToken, excludeSessionId) {
|
|
@@ -615,8 +621,8 @@ function createDrizzleAdapter(db, tables) {
|
|
|
615
621
|
if (existing[0]) {
|
|
616
622
|
deviceId = existing[0].id;
|
|
617
623
|
} else {
|
|
618
|
-
const
|
|
619
|
-
deviceId =
|
|
624
|
+
const insertedRows = await db.insert(devices).values({ pushToken }).returning({ id: devices.id });
|
|
625
|
+
deviceId = insertedRows[0].id;
|
|
620
626
|
}
|
|
621
627
|
if (tables.devicesToSessions) {
|
|
622
628
|
await db.insert(tables.devicesToSessions).values({ deviceId, sessionId }).onConflictDoNothing();
|
|
@@ -628,7 +634,7 @@ function createDrizzleAdapter(db, tables) {
|
|
|
628
634
|
},
|
|
629
635
|
async findByUserAndToken(userId, pushToken) {
|
|
630
636
|
if (tables.devicesToUsers) {
|
|
631
|
-
const
|
|
637
|
+
const joinRows = await db.select({ id: devices.id }).from(devices).innerJoin(
|
|
632
638
|
tables.devicesToUsers,
|
|
633
639
|
eq(devices.id, tables.devicesToUsers.deviceId)
|
|
634
640
|
).where(
|
|
@@ -637,7 +643,7 @@ function createDrizzleAdapter(db, tables) {
|
|
|
637
643
|
eq(tables.devicesToUsers.userId, userId)
|
|
638
644
|
)
|
|
639
645
|
).limit(1);
|
|
640
|
-
return
|
|
646
|
+
return joinRows[0] ? { id: joinRows[0].id } : null;
|
|
641
647
|
}
|
|
642
648
|
const rows = await db.select({ id: devices.id }).from(devices).where(eq(devices.pushToken, pushToken)).limit(1);
|
|
643
649
|
return rows[0] ? { id: rows[0].id } : null;
|
|
@@ -654,8 +660,8 @@ function createDrizzleAdapter(db, tables) {
|
|
|
654
660
|
},
|
|
655
661
|
async hasRemainingUsers(deviceId) {
|
|
656
662
|
if (tables.devicesToUsers) {
|
|
657
|
-
const
|
|
658
|
-
return
|
|
663
|
+
const remainingRows = await db.select({ userId: tables.devicesToUsers.userId }).from(tables.devicesToUsers).where(eq(tables.devicesToUsers.deviceId, deviceId)).limit(1);
|
|
664
|
+
return remainingRows.length > 0;
|
|
659
665
|
}
|
|
660
666
|
return false;
|
|
661
667
|
},
|
|
@@ -1137,6 +1143,36 @@ function validatePasswordStrength(password, minLength = 6) {
|
|
|
1137
1143
|
return { valid: true };
|
|
1138
1144
|
}
|
|
1139
1145
|
|
|
1146
|
+
// src/utilities/session.ts
|
|
1147
|
+
async function createSessionWithToken(config, params) {
|
|
1148
|
+
const { userId, browserName, socketId, deviceId, extraSessionData } = params;
|
|
1149
|
+
const session = await config.database.session.create({
|
|
1150
|
+
userId,
|
|
1151
|
+
browserName,
|
|
1152
|
+
socketId,
|
|
1153
|
+
...deviceId != null ? { deviceId } : {},
|
|
1154
|
+
...extraSessionData
|
|
1155
|
+
});
|
|
1156
|
+
const user = await config.database.user.findById(userId);
|
|
1157
|
+
const accessToken = createAuthToken(
|
|
1158
|
+
{
|
|
1159
|
+
id: session.id,
|
|
1160
|
+
userId: session.userId,
|
|
1161
|
+
verifiedHumanAt: user?.verifiedHumanAt ?? null
|
|
1162
|
+
},
|
|
1163
|
+
{
|
|
1164
|
+
secret: config.secrets.jwt,
|
|
1165
|
+
expiresIn: config.tokenSettings.jwtExpiry
|
|
1166
|
+
}
|
|
1167
|
+
);
|
|
1168
|
+
return { accessToken, sessionId: session.id };
|
|
1169
|
+
}
|
|
1170
|
+
async function createSessionWithTokenAndCookie(config, params, res) {
|
|
1171
|
+
const result = await createSessionWithToken(config, params);
|
|
1172
|
+
setAuthCookie(res, result.accessToken, config.cookieSettings, config.storageKeys);
|
|
1173
|
+
return result;
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1140
1176
|
// src/utilities/totp.ts
|
|
1141
1177
|
var import_crypto = __toESM(require("crypto"));
|
|
1142
1178
|
var import_totp_generator = require("totp-generator");
|
|
@@ -2098,13 +2134,15 @@ var TwoFaProcedureFactory = class {
|
|
|
2098
2134
|
var import_server7 = require("@trpc/server");
|
|
2099
2135
|
var import_superjson = __toESM(require("superjson"));
|
|
2100
2136
|
var import_zod2 = require("zod");
|
|
2137
|
+
function hasStringProp(obj, key) {
|
|
2138
|
+
return typeof obj === "object" && obj !== null && key in obj && typeof obj[key] === "string";
|
|
2139
|
+
}
|
|
2101
2140
|
function isPrismaConnectionError(error) {
|
|
2102
2141
|
if (!error || typeof error !== "object") {
|
|
2103
2142
|
return false;
|
|
2104
2143
|
}
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
const codeMatch = errorCode.match(/^P(\d+)$/);
|
|
2144
|
+
if (hasStringProp(error, "code")) {
|
|
2145
|
+
const codeMatch = error.code.match(/^P(\d+)$/);
|
|
2108
2146
|
if (codeMatch) {
|
|
2109
2147
|
const codeNum = parseInt(codeMatch[1], 10);
|
|
2110
2148
|
if (codeNum >= 1e3 && codeNum <= 1003) {
|
|
@@ -2114,14 +2152,13 @@ function isPrismaConnectionError(error) {
|
|
|
2114
2152
|
}
|
|
2115
2153
|
const constructorName = error.constructor?.name || "";
|
|
2116
2154
|
if (constructorName.includes("Prisma")) {
|
|
2117
|
-
const errorMessage = error.message
|
|
2155
|
+
const errorMessage = hasStringProp(error, "message") ? error.message.toLowerCase() : "";
|
|
2118
2156
|
if (errorMessage.includes("can't reach database") || errorMessage.includes("authentication failed") || errorMessage.includes("database server") || errorMessage.includes("timeout") || errorMessage.includes("connection")) {
|
|
2119
2157
|
return true;
|
|
2120
2158
|
}
|
|
2121
2159
|
}
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
return isPrismaConnectionError(cause);
|
|
2160
|
+
if ("cause" in error) {
|
|
2161
|
+
return isPrismaConnectionError(error.cause);
|
|
2125
2162
|
}
|
|
2126
2163
|
return false;
|
|
2127
2164
|
}
|
|
@@ -2167,8 +2204,9 @@ function createBaseProcedure(t, authGuard) {
|
|
|
2167
2204
|
}
|
|
2168
2205
|
function getClientIp(req) {
|
|
2169
2206
|
const forwarded = req.headers["x-forwarded-for"];
|
|
2170
|
-
|
|
2171
|
-
|
|
2207
|
+
const forwardedStr = Array.isArray(forwarded) ? forwarded[0] : forwarded;
|
|
2208
|
+
if (forwardedStr) {
|
|
2209
|
+
return forwardedStr.split(",")[0]?.trim();
|
|
2172
2210
|
}
|
|
2173
2211
|
return req.socket.remoteAddress || void 0;
|
|
2174
2212
|
}
|
|
@@ -2186,7 +2224,7 @@ var AuthRouterFactory = class {
|
|
|
2186
2224
|
constructor(userConfig) {
|
|
2187
2225
|
this.userConfig = userConfig;
|
|
2188
2226
|
this.config = createAuthConfig(this.userConfig);
|
|
2189
|
-
this.schemas = createSchemas(this.
|
|
2227
|
+
this.schemas = createSchemas(this.userConfig.schemaExtensions);
|
|
2190
2228
|
this.t = createTrpcBuilder(this.config);
|
|
2191
2229
|
this.authGuard = createAuthGuard(this.config, this.t);
|
|
2192
2230
|
this.procedure = createBaseProcedure(this.t, this.authGuard);
|
|
@@ -2248,6 +2286,8 @@ function createAuthRouter(config) {
|
|
|
2248
2286
|
createNoopEmailAdapter,
|
|
2249
2287
|
createOAuthVerifier,
|
|
2250
2288
|
createPrismaAdapter,
|
|
2289
|
+
createSessionWithToken,
|
|
2290
|
+
createSessionWithTokenAndCookie,
|
|
2251
2291
|
decodeToken,
|
|
2252
2292
|
defaultAuthConfig,
|
|
2253
2293
|
defaultCookieSettings,
|
package/dist/index.mjs
CHANGED
|
@@ -25,20 +25,21 @@ import { TRPCError } from "@trpc/server";
|
|
|
25
25
|
|
|
26
26
|
// src/adapters/prismaAdapter.ts
|
|
27
27
|
function createPrismaAdapter(prisma) {
|
|
28
|
+
const db = prisma;
|
|
28
29
|
return {
|
|
29
30
|
user: {
|
|
30
31
|
async findByEmailInsensitive(email) {
|
|
31
|
-
return
|
|
32
|
+
return db.user.findFirst({
|
|
32
33
|
where: { email: { equals: email, mode: "insensitive" } }
|
|
33
34
|
});
|
|
34
35
|
},
|
|
35
36
|
async findByUsernameInsensitive(username) {
|
|
36
|
-
return
|
|
37
|
+
return db.user.findFirst({
|
|
37
38
|
where: { username: { equals: username, mode: "insensitive" } }
|
|
38
39
|
});
|
|
39
40
|
},
|
|
40
41
|
async findByEmailOrUsernameInsensitive(identifier) {
|
|
41
|
-
return
|
|
42
|
+
return db.user.findFirst({
|
|
42
43
|
where: {
|
|
43
44
|
OR: [
|
|
44
45
|
{ email: { equals: identifier, mode: "insensitive" } },
|
|
@@ -48,7 +49,7 @@ function createPrismaAdapter(prisma) {
|
|
|
48
49
|
});
|
|
49
50
|
},
|
|
50
51
|
async findByEmailOrOAuthId(email, oauthId) {
|
|
51
|
-
return
|
|
52
|
+
return db.user.findFirst({
|
|
52
53
|
where: {
|
|
53
54
|
OR: [
|
|
54
55
|
{ email: { equals: email, mode: "insensitive" } },
|
|
@@ -58,23 +59,23 @@ function createPrismaAdapter(prisma) {
|
|
|
58
59
|
});
|
|
59
60
|
},
|
|
60
61
|
async findById(id) {
|
|
61
|
-
return
|
|
62
|
+
return db.user.findUnique({ where: { id } });
|
|
62
63
|
},
|
|
63
64
|
async findActiveById(id) {
|
|
64
|
-
return
|
|
65
|
+
return db.user.findUnique({
|
|
65
66
|
where: { id, status: "ACTIVE" }
|
|
66
67
|
});
|
|
67
68
|
},
|
|
68
69
|
async create(data) {
|
|
69
|
-
return
|
|
70
|
+
return db.user.create({ data });
|
|
70
71
|
},
|
|
71
72
|
async update(id, data) {
|
|
72
|
-
return
|
|
73
|
+
return db.user.update({ where: { id }, data });
|
|
73
74
|
}
|
|
74
75
|
},
|
|
75
76
|
session: {
|
|
76
77
|
async findById(id) {
|
|
77
|
-
const session = await
|
|
78
|
+
const session = await db.session.findUnique({
|
|
78
79
|
where: { id },
|
|
79
80
|
select: {
|
|
80
81
|
id: true,
|
|
@@ -92,13 +93,13 @@ function createPrismaAdapter(prisma) {
|
|
|
92
93
|
return session;
|
|
93
94
|
},
|
|
94
95
|
async create(data) {
|
|
95
|
-
return
|
|
96
|
+
return db.session.create({ data });
|
|
96
97
|
},
|
|
97
98
|
async update(id, data) {
|
|
98
|
-
return
|
|
99
|
+
return db.session.update({ where: { id }, data });
|
|
99
100
|
},
|
|
100
101
|
async updateLastUsed(id) {
|
|
101
|
-
const session = await
|
|
102
|
+
const session = await db.session.update({
|
|
102
103
|
where: { id },
|
|
103
104
|
data: { lastUsed: /* @__PURE__ */ new Date() },
|
|
104
105
|
select: {
|
|
@@ -117,13 +118,13 @@ function createPrismaAdapter(prisma) {
|
|
|
117
118
|
return session;
|
|
118
119
|
},
|
|
119
120
|
async revoke(id) {
|
|
120
|
-
await
|
|
121
|
+
await db.session.update({
|
|
121
122
|
where: { id },
|
|
122
123
|
data: { revokedAt: /* @__PURE__ */ new Date() }
|
|
123
124
|
});
|
|
124
125
|
},
|
|
125
126
|
async findActiveByUserId(userId, excludeSessionId) {
|
|
126
|
-
return
|
|
127
|
+
return db.session.findMany({
|
|
127
128
|
where: {
|
|
128
129
|
userId,
|
|
129
130
|
revokedAt: null,
|
|
@@ -133,7 +134,7 @@ function createPrismaAdapter(prisma) {
|
|
|
133
134
|
});
|
|
134
135
|
},
|
|
135
136
|
async revokeAllByUserId(userId, excludeSessionId) {
|
|
136
|
-
await
|
|
137
|
+
await db.session.updateMany({
|
|
137
138
|
where: {
|
|
138
139
|
userId,
|
|
139
140
|
revokedAt: null,
|
|
@@ -143,13 +144,13 @@ function createPrismaAdapter(prisma) {
|
|
|
143
144
|
});
|
|
144
145
|
},
|
|
145
146
|
async findTwoFaSecretsByUserId(userId) {
|
|
146
|
-
return
|
|
147
|
+
return db.session.findMany({
|
|
147
148
|
where: { userId, twoFaSecret: { not: null } },
|
|
148
149
|
select: { twoFaSecret: true }
|
|
149
150
|
});
|
|
150
151
|
},
|
|
151
152
|
async clearTwoFaSecrets(userId, excludeSessionId) {
|
|
152
|
-
await
|
|
153
|
+
await db.session.updateMany({
|
|
153
154
|
where: {
|
|
154
155
|
userId,
|
|
155
156
|
...excludeSessionId ? { NOT: { id: excludeSessionId } } : {}
|
|
@@ -158,7 +159,7 @@ function createPrismaAdapter(prisma) {
|
|
|
158
159
|
});
|
|
159
160
|
},
|
|
160
161
|
async findByIdWithDevice(id, userId) {
|
|
161
|
-
const session = await
|
|
162
|
+
const session = await db.session.findUnique({
|
|
162
163
|
where: { id, userId },
|
|
163
164
|
select: {
|
|
164
165
|
twoFaSecret: true,
|
|
@@ -169,7 +170,7 @@ function createPrismaAdapter(prisma) {
|
|
|
169
170
|
return session;
|
|
170
171
|
},
|
|
171
172
|
async revokeByDevicePushToken(userId, pushToken, excludeSessionId) {
|
|
172
|
-
await
|
|
173
|
+
await db.session.updateMany({
|
|
173
174
|
where: {
|
|
174
175
|
userId,
|
|
175
176
|
id: { not: excludeSessionId },
|
|
@@ -180,7 +181,7 @@ function createPrismaAdapter(prisma) {
|
|
|
180
181
|
});
|
|
181
182
|
},
|
|
182
183
|
async clearDeviceId(userId, deviceId) {
|
|
183
|
-
await
|
|
184
|
+
await db.session.updateMany({
|
|
184
185
|
where: { userId, deviceId },
|
|
185
186
|
data: { deviceId: null }
|
|
186
187
|
});
|
|
@@ -188,39 +189,39 @@ function createPrismaAdapter(prisma) {
|
|
|
188
189
|
},
|
|
189
190
|
otp: {
|
|
190
191
|
async findValidByUserAndCode(userId, code) {
|
|
191
|
-
return
|
|
192
|
+
return db.oTP.findFirst({
|
|
192
193
|
where: { userId, code, expiresAt: { gte: /* @__PURE__ */ new Date() } }
|
|
193
194
|
});
|
|
194
195
|
},
|
|
195
196
|
async create(data) {
|
|
196
|
-
return
|
|
197
|
+
return db.oTP.create({ data });
|
|
197
198
|
},
|
|
198
199
|
async delete(id) {
|
|
199
|
-
await
|
|
200
|
+
await db.oTP.delete({ where: { id } });
|
|
200
201
|
}
|
|
201
202
|
},
|
|
202
203
|
passwordReset: {
|
|
203
204
|
async findById(id) {
|
|
204
|
-
return
|
|
205
|
+
return db.passwordReset.findUnique({
|
|
205
206
|
where: { id },
|
|
206
207
|
select: { id: true, createdAt: true, userId: true }
|
|
207
208
|
});
|
|
208
209
|
},
|
|
209
210
|
async create(userId) {
|
|
210
|
-
return
|
|
211
|
+
return db.passwordReset.create({
|
|
211
212
|
data: { userId }
|
|
212
213
|
});
|
|
213
214
|
},
|
|
214
215
|
async delete(id) {
|
|
215
|
-
await
|
|
216
|
+
await db.passwordReset.delete({ where: { id } });
|
|
216
217
|
},
|
|
217
218
|
async deleteAllByUserId(userId) {
|
|
218
|
-
await
|
|
219
|
+
await db.passwordReset.deleteMany({ where: { userId } });
|
|
219
220
|
}
|
|
220
221
|
},
|
|
221
222
|
device: {
|
|
222
223
|
async findByTokenSessionAndUser(pushToken, sessionId, userId) {
|
|
223
|
-
return
|
|
224
|
+
return db.device.findFirst({
|
|
224
225
|
where: {
|
|
225
226
|
pushToken,
|
|
226
227
|
sessions: { some: { id: sessionId } },
|
|
@@ -230,7 +231,7 @@ function createPrismaAdapter(prisma) {
|
|
|
230
231
|
});
|
|
231
232
|
},
|
|
232
233
|
async upsertByPushToken(pushToken, sessionId, userId) {
|
|
233
|
-
await
|
|
234
|
+
await db.device.upsert({
|
|
234
235
|
where: { pushToken },
|
|
235
236
|
create: {
|
|
236
237
|
pushToken,
|
|
@@ -244,31 +245,31 @@ function createPrismaAdapter(prisma) {
|
|
|
244
245
|
});
|
|
245
246
|
},
|
|
246
247
|
async findByUserAndToken(userId, pushToken) {
|
|
247
|
-
return
|
|
248
|
+
return db.device.findFirst({
|
|
248
249
|
where: { users: { some: { id: userId } }, pushToken },
|
|
249
250
|
select: { id: true }
|
|
250
251
|
});
|
|
251
252
|
},
|
|
252
253
|
async disconnectUser(deviceId, userId) {
|
|
253
|
-
await
|
|
254
|
+
await db.device.update({
|
|
254
255
|
where: { id: deviceId },
|
|
255
256
|
data: { users: { disconnect: { id: userId } } }
|
|
256
257
|
});
|
|
257
258
|
},
|
|
258
259
|
async hasRemainingUsers(deviceId) {
|
|
259
|
-
const result = await
|
|
260
|
+
const result = await db.device.findUnique({
|
|
260
261
|
where: { id: deviceId },
|
|
261
262
|
select: { users: { select: { id: true }, take: 1 } }
|
|
262
263
|
});
|
|
263
264
|
return (result?.users.length ?? 0) > 0;
|
|
264
265
|
},
|
|
265
266
|
async delete(id) {
|
|
266
|
-
await
|
|
267
|
+
await db.device.delete({ where: { id } });
|
|
267
268
|
}
|
|
268
269
|
},
|
|
269
270
|
admin: {
|
|
270
271
|
async findByUserId(userId) {
|
|
271
|
-
return
|
|
272
|
+
return db.admin.findFirst({
|
|
272
273
|
where: { userId },
|
|
273
274
|
select: { ip: true }
|
|
274
275
|
});
|
|
@@ -441,11 +442,12 @@ function createDrizzleAdapter(db, tables) {
|
|
|
441
442
|
if (excludeSessionId !== void 0) {
|
|
442
443
|
conditions.push(ne(sessions.id, excludeSessionId));
|
|
443
444
|
}
|
|
444
|
-
|
|
445
|
+
const activeRows = await db.select({
|
|
445
446
|
id: sessions.id,
|
|
446
447
|
socketId: sessions.socketId,
|
|
447
448
|
userId: sessions.userId
|
|
448
449
|
}).from(sessions).where(and(...conditions));
|
|
450
|
+
return activeRows;
|
|
449
451
|
},
|
|
450
452
|
async revokeAllByUserId(userId, excludeSessionId) {
|
|
451
453
|
const conditions = [eq(sessions.userId, userId), isNull(sessions.revokedAt)];
|
|
@@ -455,7 +457,8 @@ function createDrizzleAdapter(db, tables) {
|
|
|
455
457
|
await db.update(sessions).set({ revokedAt: /* @__PURE__ */ new Date() }).where(and(...conditions));
|
|
456
458
|
},
|
|
457
459
|
async findTwoFaSecretsByUserId(userId) {
|
|
458
|
-
|
|
460
|
+
const secretRows = await db.select({ twoFaSecret: sessions.twoFaSecret }).from(sessions).where(and(eq(sessions.userId, userId), isNotNull(sessions.twoFaSecret)));
|
|
461
|
+
return secretRows;
|
|
459
462
|
},
|
|
460
463
|
async clearTwoFaSecrets(userId, excludeSessionId) {
|
|
461
464
|
const conditions = [eq(sessions.userId, userId)];
|
|
@@ -474,10 +477,11 @@ function createDrizzleAdapter(db, tables) {
|
|
|
474
477
|
}).from(sessions).leftJoin(devices, eq(sessions.deviceId, devices.id)).where(and(eq(sessions.id, id), eq(sessions.userId, userId))).limit(1);
|
|
475
478
|
if (!rows[0]) return null;
|
|
476
479
|
const row = rows[0];
|
|
480
|
+
const device = row.device;
|
|
477
481
|
return {
|
|
478
482
|
twoFaSecret: row.twoFaSecret,
|
|
479
483
|
deviceId: row.deviceId,
|
|
480
|
-
device:
|
|
484
|
+
device: device?.pushToken ? { pushToken: device.pushToken } : null
|
|
481
485
|
};
|
|
482
486
|
},
|
|
483
487
|
async revokeByDevicePushToken(userId, pushToken, excludeSessionId) {
|
|
@@ -558,8 +562,8 @@ function createDrizzleAdapter(db, tables) {
|
|
|
558
562
|
if (existing[0]) {
|
|
559
563
|
deviceId = existing[0].id;
|
|
560
564
|
} else {
|
|
561
|
-
const
|
|
562
|
-
deviceId =
|
|
565
|
+
const insertedRows = await db.insert(devices).values({ pushToken }).returning({ id: devices.id });
|
|
566
|
+
deviceId = insertedRows[0].id;
|
|
563
567
|
}
|
|
564
568
|
if (tables.devicesToSessions) {
|
|
565
569
|
await db.insert(tables.devicesToSessions).values({ deviceId, sessionId }).onConflictDoNothing();
|
|
@@ -571,7 +575,7 @@ function createDrizzleAdapter(db, tables) {
|
|
|
571
575
|
},
|
|
572
576
|
async findByUserAndToken(userId, pushToken) {
|
|
573
577
|
if (tables.devicesToUsers) {
|
|
574
|
-
const
|
|
578
|
+
const joinRows = await db.select({ id: devices.id }).from(devices).innerJoin(
|
|
575
579
|
tables.devicesToUsers,
|
|
576
580
|
eq(devices.id, tables.devicesToUsers.deviceId)
|
|
577
581
|
).where(
|
|
@@ -580,7 +584,7 @@ function createDrizzleAdapter(db, tables) {
|
|
|
580
584
|
eq(tables.devicesToUsers.userId, userId)
|
|
581
585
|
)
|
|
582
586
|
).limit(1);
|
|
583
|
-
return
|
|
587
|
+
return joinRows[0] ? { id: joinRows[0].id } : null;
|
|
584
588
|
}
|
|
585
589
|
const rows = await db.select({ id: devices.id }).from(devices).where(eq(devices.pushToken, pushToken)).limit(1);
|
|
586
590
|
return rows[0] ? { id: rows[0].id } : null;
|
|
@@ -597,8 +601,8 @@ function createDrizzleAdapter(db, tables) {
|
|
|
597
601
|
},
|
|
598
602
|
async hasRemainingUsers(deviceId) {
|
|
599
603
|
if (tables.devicesToUsers) {
|
|
600
|
-
const
|
|
601
|
-
return
|
|
604
|
+
const remainingRows = await db.select({ userId: tables.devicesToUsers.userId }).from(tables.devicesToUsers).where(eq(tables.devicesToUsers.deviceId, deviceId)).limit(1);
|
|
605
|
+
return remainingRows.length > 0;
|
|
602
606
|
}
|
|
603
607
|
return false;
|
|
604
608
|
},
|
|
@@ -1080,6 +1084,36 @@ function validatePasswordStrength(password, minLength = 6) {
|
|
|
1080
1084
|
return { valid: true };
|
|
1081
1085
|
}
|
|
1082
1086
|
|
|
1087
|
+
// src/utilities/session.ts
|
|
1088
|
+
async function createSessionWithToken(config, params) {
|
|
1089
|
+
const { userId, browserName, socketId, deviceId, extraSessionData } = params;
|
|
1090
|
+
const session = await config.database.session.create({
|
|
1091
|
+
userId,
|
|
1092
|
+
browserName,
|
|
1093
|
+
socketId,
|
|
1094
|
+
...deviceId != null ? { deviceId } : {},
|
|
1095
|
+
...extraSessionData
|
|
1096
|
+
});
|
|
1097
|
+
const user = await config.database.user.findById(userId);
|
|
1098
|
+
const accessToken = createAuthToken(
|
|
1099
|
+
{
|
|
1100
|
+
id: session.id,
|
|
1101
|
+
userId: session.userId,
|
|
1102
|
+
verifiedHumanAt: user?.verifiedHumanAt ?? null
|
|
1103
|
+
},
|
|
1104
|
+
{
|
|
1105
|
+
secret: config.secrets.jwt,
|
|
1106
|
+
expiresIn: config.tokenSettings.jwtExpiry
|
|
1107
|
+
}
|
|
1108
|
+
);
|
|
1109
|
+
return { accessToken, sessionId: session.id };
|
|
1110
|
+
}
|
|
1111
|
+
async function createSessionWithTokenAndCookie(config, params, res) {
|
|
1112
|
+
const result = await createSessionWithToken(config, params);
|
|
1113
|
+
setAuthCookie(res, result.accessToken, config.cookieSettings, config.storageKeys);
|
|
1114
|
+
return result;
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1083
1117
|
// src/utilities/totp.ts
|
|
1084
1118
|
import crypto from "crypto";
|
|
1085
1119
|
import { TOTP } from "totp-generator";
|
|
@@ -1963,13 +1997,15 @@ var TwoFaProcedureFactory = class {
|
|
|
1963
1997
|
import { initTRPC } from "@trpc/server";
|
|
1964
1998
|
import SuperJSON from "superjson";
|
|
1965
1999
|
import { ZodError } from "zod";
|
|
2000
|
+
function hasStringProp(obj, key) {
|
|
2001
|
+
return typeof obj === "object" && obj !== null && key in obj && typeof obj[key] === "string";
|
|
2002
|
+
}
|
|
1966
2003
|
function isPrismaConnectionError(error) {
|
|
1967
2004
|
if (!error || typeof error !== "object") {
|
|
1968
2005
|
return false;
|
|
1969
2006
|
}
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
const codeMatch = errorCode.match(/^P(\d+)$/);
|
|
2007
|
+
if (hasStringProp(error, "code")) {
|
|
2008
|
+
const codeMatch = error.code.match(/^P(\d+)$/);
|
|
1973
2009
|
if (codeMatch) {
|
|
1974
2010
|
const codeNum = parseInt(codeMatch[1], 10);
|
|
1975
2011
|
if (codeNum >= 1e3 && codeNum <= 1003) {
|
|
@@ -1979,14 +2015,13 @@ function isPrismaConnectionError(error) {
|
|
|
1979
2015
|
}
|
|
1980
2016
|
const constructorName = error.constructor?.name || "";
|
|
1981
2017
|
if (constructorName.includes("Prisma")) {
|
|
1982
|
-
const errorMessage = error.message
|
|
2018
|
+
const errorMessage = hasStringProp(error, "message") ? error.message.toLowerCase() : "";
|
|
1983
2019
|
if (errorMessage.includes("can't reach database") || errorMessage.includes("authentication failed") || errorMessage.includes("database server") || errorMessage.includes("timeout") || errorMessage.includes("connection")) {
|
|
1984
2020
|
return true;
|
|
1985
2021
|
}
|
|
1986
2022
|
}
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
return isPrismaConnectionError(cause);
|
|
2023
|
+
if ("cause" in error) {
|
|
2024
|
+
return isPrismaConnectionError(error.cause);
|
|
1990
2025
|
}
|
|
1991
2026
|
return false;
|
|
1992
2027
|
}
|
|
@@ -2032,8 +2067,9 @@ function createBaseProcedure(t, authGuard) {
|
|
|
2032
2067
|
}
|
|
2033
2068
|
function getClientIp(req) {
|
|
2034
2069
|
const forwarded = req.headers["x-forwarded-for"];
|
|
2035
|
-
|
|
2036
|
-
|
|
2070
|
+
const forwardedStr = Array.isArray(forwarded) ? forwarded[0] : forwarded;
|
|
2071
|
+
if (forwardedStr) {
|
|
2072
|
+
return forwardedStr.split(",")[0]?.trim();
|
|
2037
2073
|
}
|
|
2038
2074
|
return req.socket.remoteAddress || void 0;
|
|
2039
2075
|
}
|
|
@@ -2051,7 +2087,7 @@ var AuthRouterFactory = class {
|
|
|
2051
2087
|
constructor(userConfig) {
|
|
2052
2088
|
this.userConfig = userConfig;
|
|
2053
2089
|
this.config = createAuthConfig(this.userConfig);
|
|
2054
|
-
this.schemas = createSchemas(this.
|
|
2090
|
+
this.schemas = createSchemas(this.userConfig.schemaExtensions);
|
|
2055
2091
|
this.t = createTrpcBuilder(this.config);
|
|
2056
2092
|
this.authGuard = createAuthGuard(this.config, this.t);
|
|
2057
2093
|
this.procedure = createBaseProcedure(this.t, this.authGuard);
|
|
@@ -2112,6 +2148,8 @@ export {
|
|
|
2112
2148
|
createNoopEmailAdapter,
|
|
2113
2149
|
createOAuthVerifier,
|
|
2114
2150
|
createPrismaAdapter,
|
|
2151
|
+
createSessionWithToken,
|
|
2152
|
+
createSessionWithTokenAndCookie,
|
|
2115
2153
|
decodeToken,
|
|
2116
2154
|
defaultAuthConfig,
|
|
2117
2155
|
defaultCookieSettings,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@factiii/auth",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.5",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -50,26 +50,8 @@
|
|
|
50
50
|
"prisma",
|
|
51
51
|
"README.md"
|
|
52
52
|
],
|
|
53
|
-
"scripts": {
|
|
54
|
-
"build": "tsup",
|
|
55
|
-
"dev": "tsup --watch",
|
|
56
|
-
"check-types": "tsc --noEmit",
|
|
57
|
-
"lint": "eslint src",
|
|
58
|
-
"lint:fix": "eslint src --fix",
|
|
59
|
-
"format": "prettier --check src",
|
|
60
|
-
"format:fix": "prettier --write src",
|
|
61
|
-
"test": "vitest run",
|
|
62
|
-
"test:watch": "vitest",
|
|
63
|
-
"seed": "tsx e2e/seed.ts",
|
|
64
|
-
"clean": "rm -rf dist node_modules/.cache .turbo",
|
|
65
|
-
"prepublishOnly": "npm run build",
|
|
66
|
-
"e2e": "pnpm e2e:db:up && playwright test --reporter=list; pnpm e2e:db:down",
|
|
67
|
-
"e2e:ui": "pnpm e2e:db:up && playwright test --ui",
|
|
68
|
-
"e2e:db:up": "docker compose -f e2e/docker-compose.yml up -d --wait && prisma generate --schema=e2e/server/schema.prisma --config=e2e/server/prisma.config.ts && prisma migrate reset --schema=e2e/server/schema.prisma --config=e2e/server/prisma.config.ts --force",
|
|
69
|
-
"e2e:db:down": "docker compose -f e2e/docker-compose.yml down"
|
|
70
|
-
},
|
|
71
53
|
"dependencies": {
|
|
72
|
-
"@trpc/server": "11.8.0",
|
|
54
|
+
"@trpc/server": "^11.8.0",
|
|
73
55
|
"apple-signin-auth": "^2.0.0",
|
|
74
56
|
"bcryptjs": "^2.4.3",
|
|
75
57
|
"google-auth-library": "^10.5.0",
|
|
@@ -102,7 +84,7 @@
|
|
|
102
84
|
"@prisma/adapter-pg": "^7.3.0",
|
|
103
85
|
"@prisma/client": "^7.1.0",
|
|
104
86
|
"@trpc/client": "^11.8.0",
|
|
105
|
-
"@trpc/server": "11.8.0",
|
|
87
|
+
"@trpc/server": "^11.8.0",
|
|
106
88
|
"@types/bcryptjs": "^2.4.6",
|
|
107
89
|
"@types/better-sqlite3": "^7.6.13",
|
|
108
90
|
"@types/jsonwebtoken": "^9.0.9",
|
|
@@ -133,16 +115,21 @@
|
|
|
133
115
|
"engines": {
|
|
134
116
|
"node": ">=18.0.0"
|
|
135
117
|
},
|
|
136
|
-
"
|
|
137
|
-
|
|
138
|
-
"
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
118
|
+
"scripts": {
|
|
119
|
+
"build": "tsup",
|
|
120
|
+
"dev": "tsup --watch",
|
|
121
|
+
"check-types": "tsc --noEmit",
|
|
122
|
+
"lint": "eslint src",
|
|
123
|
+
"lint:fix": "eslint src --fix",
|
|
124
|
+
"format": "prettier --check src",
|
|
125
|
+
"format:fix": "prettier --write src",
|
|
126
|
+
"test": "vitest run",
|
|
127
|
+
"test:watch": "vitest",
|
|
128
|
+
"seed": "tsx e2e/seed.ts",
|
|
129
|
+
"clean": "rm -rf dist node_modules/.cache .turbo",
|
|
130
|
+
"e2e": "pnpm e2e:db:up && playwright test --reporter=list; pnpm e2e:db:down",
|
|
131
|
+
"e2e:ui": "pnpm e2e:db:up && playwright test --ui",
|
|
132
|
+
"e2e:db:up": "docker compose -f e2e/docker-compose.yml up -d --wait && prisma generate --schema=e2e/server/schema.prisma --config=e2e/server/prisma.config.ts && prisma migrate reset --schema=e2e/server/schema.prisma --config=e2e/server/prisma.config.ts --force",
|
|
133
|
+
"e2e:db:down": "docker compose -f e2e/docker-compose.yml down"
|
|
147
134
|
}
|
|
148
|
-
}
|
|
135
|
+
}
|