@factiii/auth 0.1.0 → 0.1.1

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.
@@ -115,4 +115,3 @@ export {
115
115
  otpLoginVerifySchema,
116
116
  createSchemas
117
117
  };
118
- //# sourceMappingURL=chunk-CLHDX2R2.mjs.map
package/dist/index.d.mts CHANGED
@@ -6,8 +6,8 @@ import { PrismaClient } from '@prisma/client';
6
6
  import * as _trpc_server from '@trpc/server';
7
7
  import * as zod from 'zod';
8
8
  import { CreateHTTPContextOptions } from '@trpc/server/adapters/standalone';
9
- import { S as SchemaExtensions, A as AuthHooks } from './hooks-B4Kl294A.mjs';
10
- export { C as ChangePasswordInput, L as LoginInput, a as LogoutInput, O as OAuthLoginInput, R as ResetPasswordInput, b as SignupInput, T as TwoFaVerifyInput, V as VerifyEmailInput, c as biometricVerifySchema, d as changePasswordSchema, e as endAllSessionsSchema, l as loginSchema, f as logoutSchema, o as oAuthLoginSchema, g as otpLoginRequestSchema, h as otpLoginVerifySchema, r as requestPasswordResetSchema, i as resetPasswordSchema, s as signupSchema, t as twoFaResetSchema, j as twoFaSetupSchema, k as twoFaVerifySchema, v as verifyEmailSchema } from './hooks-B4Kl294A.mjs';
9
+ import { S as SchemaExtensions, A as AuthHooks } from './hooks-CK4f4PHo.mjs';
10
+ export { C as ChangePasswordInput, L as LoginInput, a as LogoutInput, O as OAuthLoginInput, R as ResetPasswordInput, b as SignupInput, T as TwoFaVerifyInput, V as VerifyEmailInput, c as biometricVerifySchema, d as changePasswordSchema, e as endAllSessionsSchema, l as loginSchema, f as logoutSchema, o as oAuthLoginSchema, g as otpLoginRequestSchema, h as otpLoginVerifySchema, r as requestPasswordResetSchema, i as resetPasswordSchema, s as signupSchema, t as twoFaResetSchema, j as twoFaSetupSchema, k as twoFaVerifySchema, v as verifyEmailSchema } from './hooks-CK4f4PHo.mjs';
11
11
  import { SignOptions } from 'jsonwebtoken';
12
12
 
13
13
  //# sourceMappingURL=TRPCError.d.ts.map
@@ -671,12 +671,12 @@ declare function createAuthRouter<TExtensions extends SchemaExtensions = {}>(con
671
671
  email: zod.ZodString;
672
672
  password: zod.ZodString;
673
673
  }, "strip", zod.ZodTypeAny, {
674
- username: string;
675
674
  email: string;
675
+ username: string;
676
676
  password: string;
677
677
  }, {
678
- username: string;
679
678
  email: string;
679
+ username: string;
680
680
  password: string;
681
681
  }>>["in"] extends infer T_7 ? T_7 extends inferParser<[TExtensions["signup"]] extends [zod.AnyZodObject] ? zod.ZodObject<{
682
682
  username: zod.ZodString;
@@ -695,12 +695,12 @@ declare function createAuthRouter<TExtensions extends SchemaExtensions = {}>(con
695
695
  email: zod.ZodString;
696
696
  password: zod.ZodString;
697
697
  }, "strip", zod.ZodTypeAny, {
698
- username: string;
699
698
  email: string;
699
+ username: string;
700
700
  password: string;
701
701
  }, {
702
- username: string;
703
702
  email: string;
703
+ username: string;
704
704
  password: string;
705
705
  }>>["in"] ? T_7 extends _trpc_server.TRPCUnsetMarker ? void : T_7 : never : never;
706
706
  output: {
package/dist/index.d.ts CHANGED
@@ -6,8 +6,8 @@ import { PrismaClient } from '@prisma/client';
6
6
  import * as _trpc_server from '@trpc/server';
7
7
  import * as zod from 'zod';
8
8
  import { CreateHTTPContextOptions } from '@trpc/server/adapters/standalone';
9
- import { S as SchemaExtensions, A as AuthHooks } from './hooks-B4Kl294A.js';
10
- export { C as ChangePasswordInput, L as LoginInput, a as LogoutInput, O as OAuthLoginInput, R as ResetPasswordInput, b as SignupInput, T as TwoFaVerifyInput, V as VerifyEmailInput, c as biometricVerifySchema, d as changePasswordSchema, e as endAllSessionsSchema, l as loginSchema, f as logoutSchema, o as oAuthLoginSchema, g as otpLoginRequestSchema, h as otpLoginVerifySchema, r as requestPasswordResetSchema, i as resetPasswordSchema, s as signupSchema, t as twoFaResetSchema, j as twoFaSetupSchema, k as twoFaVerifySchema, v as verifyEmailSchema } from './hooks-B4Kl294A.js';
9
+ import { S as SchemaExtensions, A as AuthHooks } from './hooks-CK4f4PHo.js';
10
+ export { C as ChangePasswordInput, L as LoginInput, a as LogoutInput, O as OAuthLoginInput, R as ResetPasswordInput, b as SignupInput, T as TwoFaVerifyInput, V as VerifyEmailInput, c as biometricVerifySchema, d as changePasswordSchema, e as endAllSessionsSchema, l as loginSchema, f as logoutSchema, o as oAuthLoginSchema, g as otpLoginRequestSchema, h as otpLoginVerifySchema, r as requestPasswordResetSchema, i as resetPasswordSchema, s as signupSchema, t as twoFaResetSchema, j as twoFaSetupSchema, k as twoFaVerifySchema, v as verifyEmailSchema } from './hooks-CK4f4PHo.js';
11
11
  import { SignOptions } from 'jsonwebtoken';
12
12
 
13
13
  //# sourceMappingURL=TRPCError.d.ts.map
@@ -671,12 +671,12 @@ declare function createAuthRouter<TExtensions extends SchemaExtensions = {}>(con
671
671
  email: zod.ZodString;
672
672
  password: zod.ZodString;
673
673
  }, "strip", zod.ZodTypeAny, {
674
- username: string;
675
674
  email: string;
675
+ username: string;
676
676
  password: string;
677
677
  }, {
678
- username: string;
679
678
  email: string;
679
+ username: string;
680
680
  password: string;
681
681
  }>>["in"] extends infer T_7 ? T_7 extends inferParser<[TExtensions["signup"]] extends [zod.AnyZodObject] ? zod.ZodObject<{
682
682
  username: zod.ZodString;
@@ -695,12 +695,12 @@ declare function createAuthRouter<TExtensions extends SchemaExtensions = {}>(con
695
695
  email: zod.ZodString;
696
696
  password: zod.ZodString;
697
697
  }, "strip", zod.ZodTypeAny, {
698
- username: string;
699
698
  email: string;
699
+ username: string;
700
700
  password: string;
701
701
  }, {
702
- username: string;
703
702
  email: string;
703
+ username: string;
704
704
  password: string;
705
705
  }>>["in"] ? T_7 extends _trpc_server.TRPCUnsetMarker ? void : T_7 : never : never;
706
706
  output: {
package/dist/index.js CHANGED
@@ -2093,4 +2093,3 @@ function createAuthRouter(config) {
2093
2093
  verifyEmailSchema,
2094
2094
  verifyTotp
2095
2095
  });
2096
- //# sourceMappingURL=index.js.map
package/dist/index.mjs CHANGED
@@ -21,7 +21,7 @@ import {
21
21
  twoFaSetupSchema,
22
22
  twoFaVerifySchema,
23
23
  verifyEmailSchema
24
- } from "./chunk-CLHDX2R2.mjs";
24
+ } from "./chunk-2DOUP275.mjs";
25
25
 
26
26
  // src/middleware/authGuard.ts
27
27
  import { TRPCError } from "@trpc/server";
@@ -1944,4 +1944,3 @@ export {
1944
1944
  verifyEmailSchema,
1945
1945
  verifyTotp
1946
1946
  };
1947
- //# sourceMappingURL=index.mjs.map
@@ -1,2 +1,2 @@
1
1
  import 'zod';
2
- export { m as AuthSchemas, C as ChangePasswordInput, n as CreatedSchemas, L as LoginInput, p as LoginSchemaInput, a as LogoutInput, O as OAuthLoginInput, q as OAuthSchemaInput, R as ResetPasswordInput, b as SignupInput, u as SignupSchemaInput, T as TwoFaVerifyInput, V as VerifyEmailInput, c as biometricVerifySchema, d as changePasswordSchema, w as checkPasswordResetSchema, x as createSchemas, y as deregisterPushTokenSchema, z as disableTwofaSchema, e as endAllSessionsSchema, B as getTwofaSecretSchema, l as loginSchema, f as logoutSchema, o as oAuthLoginSchema, g as otpLoginRequestSchema, h as otpLoginVerifySchema, D as registerPushTokenSchema, r as requestPasswordResetSchema, E as resendVerificationSchema, i as resetPasswordSchema, s as signupSchema, t as twoFaResetSchema, F as twoFaResetVerifySchema, j as twoFaSetupSchema, k as twoFaVerifySchema, v as verifyEmailSchema } from './hooks-B4Kl294A.mjs';
2
+ export { m as AuthSchemas, C as ChangePasswordInput, n as CreatedSchemas, L as LoginInput, p as LoginSchemaInput, a as LogoutInput, O as OAuthLoginInput, q as OAuthSchemaInput, R as ResetPasswordInput, b as SignupInput, u as SignupSchemaInput, T as TwoFaVerifyInput, V as VerifyEmailInput, c as biometricVerifySchema, d as changePasswordSchema, w as checkPasswordResetSchema, x as createSchemas, y as deregisterPushTokenSchema, z as disableTwofaSchema, e as endAllSessionsSchema, B as getTwofaSecretSchema, l as loginSchema, f as logoutSchema, o as oAuthLoginSchema, g as otpLoginRequestSchema, h as otpLoginVerifySchema, D as registerPushTokenSchema, r as requestPasswordResetSchema, E as resendVerificationSchema, i as resetPasswordSchema, s as signupSchema, t as twoFaResetSchema, F as twoFaResetVerifySchema, j as twoFaSetupSchema, k as twoFaVerifySchema, v as verifyEmailSchema } from './hooks-CK4f4PHo.mjs';
@@ -1,2 +1,2 @@
1
1
  import 'zod';
2
- export { m as AuthSchemas, C as ChangePasswordInput, n as CreatedSchemas, L as LoginInput, p as LoginSchemaInput, a as LogoutInput, O as OAuthLoginInput, q as OAuthSchemaInput, R as ResetPasswordInput, b as SignupInput, u as SignupSchemaInput, T as TwoFaVerifyInput, V as VerifyEmailInput, c as biometricVerifySchema, d as changePasswordSchema, w as checkPasswordResetSchema, x as createSchemas, y as deregisterPushTokenSchema, z as disableTwofaSchema, e as endAllSessionsSchema, B as getTwofaSecretSchema, l as loginSchema, f as logoutSchema, o as oAuthLoginSchema, g as otpLoginRequestSchema, h as otpLoginVerifySchema, D as registerPushTokenSchema, r as requestPasswordResetSchema, E as resendVerificationSchema, i as resetPasswordSchema, s as signupSchema, t as twoFaResetSchema, F as twoFaResetVerifySchema, j as twoFaSetupSchema, k as twoFaVerifySchema, v as verifyEmailSchema } from './hooks-B4Kl294A.js';
2
+ export { m as AuthSchemas, C as ChangePasswordInput, n as CreatedSchemas, L as LoginInput, p as LoginSchemaInput, a as LogoutInput, O as OAuthLoginInput, q as OAuthSchemaInput, R as ResetPasswordInput, b as SignupInput, u as SignupSchemaInput, T as TwoFaVerifyInput, V as VerifyEmailInput, c as biometricVerifySchema, d as changePasswordSchema, w as checkPasswordResetSchema, x as createSchemas, y as deregisterPushTokenSchema, z as disableTwofaSchema, e as endAllSessionsSchema, B as getTwofaSecretSchema, l as loginSchema, f as logoutSchema, o as oAuthLoginSchema, g as otpLoginRequestSchema, h as otpLoginVerifySchema, D as registerPushTokenSchema, r as requestPasswordResetSchema, E as resendVerificationSchema, i as resetPasswordSchema, s as signupSchema, t as twoFaResetSchema, F as twoFaResetVerifySchema, j as twoFaSetupSchema, k as twoFaVerifySchema, v as verifyEmailSchema } from './hooks-CK4f4PHo.js';
@@ -161,4 +161,3 @@ function createSchemas(extensions) {
161
161
  twoFaVerifySchema,
162
162
  verifyEmailSchema
163
163
  });
164
- //# sourceMappingURL=validators.js.map
@@ -22,7 +22,7 @@ import {
22
22
  twoFaSetupSchema,
23
23
  twoFaVerifySchema,
24
24
  verifyEmailSchema
25
- } from "./chunk-CLHDX2R2.mjs";
25
+ } from "./chunk-2DOUP275.mjs";
26
26
  export {
27
27
  biometricVerifySchema,
28
28
  changePasswordSchema,
@@ -48,4 +48,3 @@ export {
48
48
  twoFaVerifySchema,
49
49
  verifyEmailSchema
50
50
  };
51
- //# sourceMappingURL=validators.mjs.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@factiii/auth",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/validators.ts"],"sourcesContent":["import { z, type AnyZodObject } from 'zod';\n\nimport type { SchemaExtensions } from './types/hooks';\n\n/**\n * Username validation regex - allows letters, numbers, and underscores\n */\nconst usernameValidationRegex = /^[a-zA-Z0-9_]+$/;\n\n/**\n * Schema for user registration\n */\nexport const signupSchema = z.object({\n username: z\n .string()\n .min(1, { message: 'Username is required' })\n .max(30, { message: 'Username must be 30 characters or less' })\n .regex(usernameValidationRegex, {\n message: 'Username can only contain letters, numbers, and underscores'\n }),\n email: z.string().email({ message: 'Invalid email address' }),\n password: z\n .string()\n .min(6, { message: 'Password must contain at least 6 characters' })\n});\n\n/**\n * Schema for user login\n */\nexport const loginSchema = z.object({\n username: z.string().min(1, { message: 'Username or email is required' }),\n password: z.string().min(1, { message: 'Password is required' }),\n code: z.string().optional() // 2FA code\n});\n\n/**\n * Schema for OAuth login\n */\nexport const oAuthLoginSchema = z.object({\n idToken: z.string(),\n user: z\n .object({\n email: z.string().email().optional()\n })\n .optional(),\n provider: z.enum(['GOOGLE', 'APPLE'])\n});\n\n/**\n * Schema for password reset request\n */\nexport const requestPasswordResetSchema = z.object({\n email: z.string().email({ message: 'Invalid email address' })\n});\n\n/**\n * Schema for password reset confirmation\n */\nexport const resetPasswordSchema = z.object({\n token: z.string().min(1, { message: 'Reset token is required' }),\n password: z\n .string()\n .min(6, { message: 'Password must contain at least 6 characters' })\n});\n\n/**\n * Schema for checking password reset token\n */\nexport const checkPasswordResetSchema = z.object({\n token: z.string().min(1, { message: 'Reset token is required' })\n});\n\n/**\n * Schema for changing password (authenticated)\n */\nexport const changePasswordSchema = z.object({\n currentPassword: z\n .string()\n .min(1, { message: 'Current password is required' }),\n newPassword: z\n .string()\n .min(6, { message: 'New password must contain at least 6 characters' })\n});\n\n/**\n * Schema for 2FA verification\n */\nexport const twoFaVerifySchema = z.object({\n code: z.string().min(6, { message: 'Verification code is required' }),\n sessionId: z.number().optional()\n});\n\n/**\n * Schema for 2FA setup\n */\nexport const twoFaSetupSchema = z.object({\n code: z.string().min(6, { message: 'Verification code is required' })\n});\n\n/**\n * Schema for 2FA reset request\n */\nexport const twoFaResetSchema = z.object({\n username: z.string().min(1),\n password: z.string().min(1)\n});\n\n/**\n * Schema for 2FA reset verification\n */\nexport const twoFaResetVerifySchema = z.object({\n code: z.number().min(100000).max(999999),\n username: z.string().min(1)\n});\n\n/**\n * Schema for email verification\n */\nexport const verifyEmailSchema = z.object({\n code: z.string().min(1, { message: 'Verification code is required' })\n});\n\n/**\n * Schema for resending verification email\n */\nexport const resendVerificationSchema = z.object({\n email: z.string().email().optional()\n});\n\n/**\n * Schema for biometric verification\n */\nexport const biometricVerifySchema = z.object({});\n\n/**\n * Schema for push token registration\n */\nexport const registerPushTokenSchema = z.object({\n pushToken: z.string().min(1, { message: 'Push token is required' })\n});\n\n/**\n * Schema for push token deregistration\n */\nexport const deregisterPushTokenSchema = z.object({\n pushToken: z.string().min(1, { message: 'Push token is required' })\n});\n\n/**\n * Schema for getting 2FA secret\n */\nexport const getTwofaSecretSchema = z.object({\n pushCode: z.string().min(6, { message: 'Push code is required' })\n});\n\n/**\n * Schema for disabling 2FA\n */\nexport const disableTwofaSchema = z.object({\n password: z.string().min(1, { message: 'Password is required' })\n});\n\n/**\n * Schema for logout\n */\nexport const logoutSchema = z.object({\n allDevices: z.boolean().optional().default(false)\n});\n\n/**\n * Schema for ending all sessions\n */\nexport const endAllSessionsSchema = z.object({\n skipCurrentSession: z.boolean().optional().default(true)\n});\n\n/**\n * Schema for OTP-based login request\n */\nexport const otpLoginRequestSchema = z.object({\n email: z.string().email({ message: 'Invalid email address' })\n});\n\n/**\n * Schema for OTP-based login verification\n */\nexport const otpLoginVerifySchema = z.object({\n email: z.string().email(),\n code: z.number().min(100000).max(999999)\n});\n\nexport type SignupInput = z.infer<typeof signupSchema>;\nexport type LoginInput = z.infer<typeof loginSchema>;\nexport type OAuthLoginInput = z.infer<typeof oAuthLoginSchema>;\nexport type ResetPasswordInput = z.infer<typeof resetPasswordSchema>;\nexport type ChangePasswordInput = z.infer<typeof changePasswordSchema>;\nexport type TwoFaVerifyInput = z.infer<typeof twoFaVerifySchema>;\nexport type VerifyEmailInput = z.infer<typeof verifyEmailSchema>;\nexport type LogoutInput = z.infer<typeof logoutSchema>;\n\n/** Schemas used by auth procedures */\nexport interface AuthSchemas {\n signup: AnyZodObject;\n login: AnyZodObject;\n oauth: AnyZodObject;\n}\n\n\n/**\n * Compute merged ZodObject type.\n * When TExt is defined, produces a schema with both base and extension shapes.\n * When TExt is undefined, produces the base schema.\n */\ntype MergedSchema<TBase extends AnyZodObject, TExt extends AnyZodObject | undefined> =\n [TExt] extends [AnyZodObject]\n ? z.ZodObject<TBase['shape'] & TExt['shape'], 'strip', z.ZodTypeAny>\n : TBase;\n\n/** Result type from createSchemas - preserves concrete schema types */\nexport type CreatedSchemas<TExtensions extends SchemaExtensions = {}> = {\n signup: MergedSchema<typeof signupSchema, TExtensions['signup']>;\n login: MergedSchema<typeof loginSchema, TExtensions['login']>;\n oauth: MergedSchema<typeof oAuthLoginSchema, TExtensions['oauth']>;\n};\n\nexport type SignupSchemaInput<TExtensions extends SchemaExtensions = {}> =\n SignupInput & (TExtensions['signup'] extends AnyZodObject ? z.infer<TExtensions['signup']> : {});\n\nexport type LoginSchemaInput<TExtensions extends SchemaExtensions = {}> =\n LoginInput & (TExtensions['login'] extends AnyZodObject ? z.infer<TExtensions['login']> : {});\n\nexport type OAuthSchemaInput<TExtensions extends SchemaExtensions = {}> =\n OAuthLoginInput & (TExtensions['oauth'] extends AnyZodObject ? z.infer<TExtensions['oauth']> : {});\n\n/** Create schemas with optional extensions merged in */\nexport function createSchemas<TExtensions extends SchemaExtensions = {}>(\n extensions?: TExtensions\n): CreatedSchemas<TExtensions> {\n return {\n signup: extensions?.signup\n ? signupSchema.merge(extensions.signup)\n : signupSchema,\n login: extensions?.login\n ? loginSchema.merge(extensions.login)\n : loginSchema,\n oauth: extensions?.oauth\n ? oAuthLoginSchema.merge(extensions.oauth)\n : oAuthLoginSchema\n } as CreatedSchemas<TExtensions>;\n}\n"],"mappings":";AAAA,SAAS,SAA4B;AAOrC,IAAM,0BAA0B;AAKzB,IAAM,eAAe,EAAE,OAAO;AAAA,EACnC,UAAU,EACP,OAAO,EACP,IAAI,GAAG,EAAE,SAAS,uBAAuB,CAAC,EAC1C,IAAI,IAAI,EAAE,SAAS,yCAAyC,CAAC,EAC7D,MAAM,yBAAyB;AAAA,IAC9B,SAAS;AAAA,EACX,CAAC;AAAA,EACH,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,wBAAwB,CAAC;AAAA,EAC5D,UAAU,EACP,OAAO,EACP,IAAI,GAAG,EAAE,SAAS,8CAA8C,CAAC;AACtE,CAAC;AAKM,IAAM,cAAc,EAAE,OAAO;AAAA,EAClC,UAAU,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,gCAAgC,CAAC;AAAA,EACxE,UAAU,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,uBAAuB,CAAC;AAAA,EAC/D,MAAM,EAAE,OAAO,EAAE,SAAS;AAAA;AAC5B,CAAC;AAKM,IAAM,mBAAmB,EAAE,OAAO;AAAA,EACvC,SAAS,EAAE,OAAO;AAAA,EAClB,MAAM,EACH,OAAO;AAAA,IACN,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS;AAAA,EACrC,CAAC,EACA,SAAS;AAAA,EACZ,UAAU,EAAE,KAAK,CAAC,UAAU,OAAO,CAAC;AACtC,CAAC;AAKM,IAAM,6BAA6B,EAAE,OAAO;AAAA,EACjD,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,wBAAwB,CAAC;AAC9D,CAAC;AAKM,IAAM,sBAAsB,EAAE,OAAO;AAAA,EAC1C,OAAO,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,0BAA0B,CAAC;AAAA,EAC/D,UAAU,EACP,OAAO,EACP,IAAI,GAAG,EAAE,SAAS,8CAA8C,CAAC;AACtE,CAAC;AAKM,IAAM,2BAA2B,EAAE,OAAO;AAAA,EAC/C,OAAO,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,0BAA0B,CAAC;AACjE,CAAC;AAKM,IAAM,uBAAuB,EAAE,OAAO;AAAA,EAC3C,iBAAiB,EACd,OAAO,EACP,IAAI,GAAG,EAAE,SAAS,+BAA+B,CAAC;AAAA,EACrD,aAAa,EACV,OAAO,EACP,IAAI,GAAG,EAAE,SAAS,kDAAkD,CAAC;AAC1E,CAAC;AAKM,IAAM,oBAAoB,EAAE,OAAO;AAAA,EACxC,MAAM,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,gCAAgC,CAAC;AAAA,EACpE,WAAW,EAAE,OAAO,EAAE,SAAS;AACjC,CAAC;AAKM,IAAM,mBAAmB,EAAE,OAAO;AAAA,EACvC,MAAM,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,gCAAgC,CAAC;AACtE,CAAC;AAKM,IAAM,mBAAmB,EAAE,OAAO;AAAA,EACvC,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC1B,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC;AAC5B,CAAC;AAKM,IAAM,yBAAyB,EAAE,OAAO;AAAA,EAC7C,MAAM,EAAE,OAAO,EAAE,IAAI,GAAM,EAAE,IAAI,MAAM;AAAA,EACvC,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC;AAC5B,CAAC;AAKM,IAAM,oBAAoB,EAAE,OAAO;AAAA,EACxC,MAAM,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,gCAAgC,CAAC;AACtE,CAAC;AAKM,IAAM,2BAA2B,EAAE,OAAO;AAAA,EAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS;AACrC,CAAC;AAKM,IAAM,wBAAwB,EAAE,OAAO,CAAC,CAAC;AAKzC,IAAM,0BAA0B,EAAE,OAAO;AAAA,EAC9C,WAAW,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,yBAAyB,CAAC;AACpE,CAAC;AAKM,IAAM,4BAA4B,EAAE,OAAO;AAAA,EAChD,WAAW,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,yBAAyB,CAAC;AACpE,CAAC;AAKM,IAAM,uBAAuB,EAAE,OAAO;AAAA,EAC3C,UAAU,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,wBAAwB,CAAC;AAClE,CAAC;AAKM,IAAM,qBAAqB,EAAE,OAAO;AAAA,EACzC,UAAU,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,uBAAuB,CAAC;AACjE,CAAC;AAKM,IAAM,eAAe,EAAE,OAAO;AAAA,EACnC,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,KAAK;AAClD,CAAC;AAKM,IAAM,uBAAuB,EAAE,OAAO;AAAA,EAC3C,oBAAoB,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,IAAI;AACzD,CAAC;AAKM,IAAM,wBAAwB,EAAE,OAAO;AAAA,EAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,wBAAwB,CAAC;AAC9D,CAAC;AAKM,IAAM,uBAAuB,EAAE,OAAO;AAAA,EAC3C,OAAO,EAAE,OAAO,EAAE,MAAM;AAAA,EACxB,MAAM,EAAE,OAAO,EAAE,IAAI,GAAM,EAAE,IAAI,MAAM;AACzC,CAAC;AA8CM,SAAS,cACd,YAC6B;AAC7B,SAAO;AAAA,IACL,QAAQ,YAAY,SAChB,aAAa,MAAM,WAAW,MAAM,IACpC;AAAA,IACJ,OAAO,YAAY,QACf,YAAY,MAAM,WAAW,KAAK,IAClC;AAAA,IACJ,OAAO,YAAY,QACf,iBAAiB,MAAM,WAAW,KAAK,IACvC;AAAA,EACN;AACF;","names":[]}
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/index.ts","../src/middleware/authGuard.ts","../src/adapters/email.ts","../src/utilities/config.ts","../src/utilities/cookies.ts","../src/utilities/jwt.ts","../src/procedures/base.ts","../src/utilities/browser.ts","../src/utilities/oauth.ts","../src/utilities/password.ts","../src/utilities/totp.ts","../src/validators.ts","../src/procedures/biometric.ts","../src/procedures/emailVerification.ts","../src/procedures/oauth.ts","../src/procedures/twoFa.ts","../src/utilities/trpc.ts","../src/router.ts"],"sourcesContent":["export type { AuthRouter } from './router';\nexport { createAuthRouter } from './router';\nexport type {\n AuthConfig,\n AuthFeatures,\n SchemaExtensions,\n TokenSettings\n} from './types/config';\nexport type { AuthHooks } from './types/hooks';\nexport type { TrpcContext } from './types/trpc';\nexport {\n createAuthConfig,\n defaultAuthConfig,\n defaultCookieSettings,\n defaultStorageKeys,\n defaultTokenSettings\n} from './utilities/config';\n\nexport type { OAuthKeys, OAuthProvider, OAuthResult } from './utilities/oauth';\nexport { createOAuthVerifier, OAuthVerificationError } from './utilities/oauth';\n\nexport { createAuthGuard } from './middleware/authGuard';\n\nexport type { EmailAdapter } from './adapters/email';\nexport {\n createConsoleEmailAdapter,\n createNoopEmailAdapter\n} from './adapters/email';\n\nexport {\n detectBrowser,\n isMobileDevice,\n isNativeApp\n} from './utilities/browser';\nexport {\n clearAuthCookies,\n DEFAULT_STORAGE_KEYS,\n parseAuthCookies,\n setAuthCookies\n} from './utilities/cookies';\nexport {\n createAccessToken,\n decodeToken,\n isTokenExpiredError,\n isTokenInvalidError,\n verifyAccessToken\n} from './utilities/jwt';\nexport {\n comparePassword,\n hashPassword,\n validatePasswordStrength\n} from './utilities/password';\nexport {\n cleanBase32String,\n generateOtp,\n generateTotpCode,\n generateTotpSecret,\n verifyTotp\n} from './utilities/totp';\n\nexport type {\n ChangePasswordInput,\n LoginInput,\n LogoutInput,\n OAuthLoginInput,\n ResetPasswordInput,\n SignupInput,\n TwoFaVerifyInput,\n VerifyEmailInput\n} from './validators';\nexport {\n biometricVerifySchema,\n changePasswordSchema,\n endAllSessionsSchema,\n loginSchema,\n logoutSchema,\n oAuthLoginSchema,\n otpLoginRequestSchema,\n otpLoginVerifySchema,\n requestPasswordResetSchema,\n resetPasswordSchema,\n signupSchema,\n twoFaResetSchema,\n twoFaSetupSchema,\n twoFaVerifySchema,\n verifyEmailSchema\n} from './validators';\n","import { TRPCError } from '@trpc/server';\n\nimport { type AuthConfig } from '../types/config';\nimport { type TrpcBuilder, type TrpcContext } from '../types/trpc';\nimport { defaultCookieSettings, defaultStorageKeys } from '../utilities/config';\nimport { clearAuthCookies, parseAuthCookies } from '../utilities/cookies';\nimport {\n isTokenExpiredError,\n isTokenInvalidError,\n verifyAccessToken\n} from '../utilities/jwt';\n\nexport function createAuthGuard(config: AuthConfig, t: TrpcBuilder) {\n const storageKeys = config.storageKeys ?? defaultStorageKeys;\n const cookieSettings = { ...defaultCookieSettings, ...config.cookieSettings };\n\n const revokeSession = async (\n ctx: TrpcContext,\n sessionId: number | null,\n description: string,\n errorStack?: string | null,\n path?: string\n ) => {\n clearAuthCookies(ctx.res, cookieSettings, storageKeys);\n\n // Log session revocations for security auditing\n // This helps track when and why sessions are revoked to detect accidental deauths\n if (config.hooks?.logError) {\n try {\n const contextInfo = {\n reason: description,\n sessionId,\n userId: ctx.userId,\n ip: ctx.ip,\n userAgent: ctx.headers['user-agent'],\n ...(path ? { path } : {}),\n timestamp: new Date().toISOString()\n };\n\n const combinedStack = [\n errorStack ? `Error Stack:\\n${errorStack}` : null,\n 'Context:',\n JSON.stringify(contextInfo, null, 2)\n ]\n .filter(Boolean)\n .join('\\n\\n');\n\n await config.hooks.logError({\n type: 'SECURITY',\n description: `Session revoked: ${description}`,\n stack: combinedStack,\n ip: ctx.ip,\n userId: ctx.userId ?? null\n });\n } catch {\n // Silently fail - don't let error logging prevent session revocation\n }\n }\n\n if (sessionId) {\n try {\n await config.prisma.session.update({\n where: { id: sessionId },\n data: { revokedAt: new Date() }\n });\n\n if (config.hooks?.onSessionRevoked) {\n const session = await config.prisma.session.findUnique({\n where: { id: sessionId },\n select: { id: true, userId: true, socketId: true }\n });\n if (session) {\n await config.hooks.onSessionRevoked(\n session.userId,\n session.socketId,\n description\n );\n }\n }\n } catch {\n // Session may already be revoked or deleted\n }\n }\n };\n\n const authGuard = t.middleware(async ({ ctx, meta, next, path }) => {\n const cookies = parseAuthCookies(ctx.headers.cookie, storageKeys);\n const authToken = cookies.accessToken;\n const refreshToken = cookies.refreshToken;\n const userAgent = ctx.headers['user-agent'];\n\n if (!userAgent) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'User agent is required'\n });\n }\n\n // If auth token is present, validate it\n if (authToken) {\n try {\n const decodedToken = verifyAccessToken(authToken, {\n secret: config.secrets.jwt,\n ignoreExpiration: meta?.ignoreExpiration ?? false\n });\n\n // For refresh endpoint, require refresh token\n if (path === 'auth.refresh' && !refreshToken) {\n await revokeSession(\n ctx,\n decodedToken.id,\n 'Session revoked: No refresh token',\n undefined,\n path\n );\n throw new TRPCError({\n message: 'Unauthorized',\n code: 'UNAUTHORIZED'\n });\n }\n\n // Find session in database\n const session = await config.prisma.session.findUnique({\n where: {\n id: decodedToken.id,\n ...(path === 'auth.refresh' ? { refreshToken } : {})\n },\n select: {\n userId: true,\n user: {\n select: {\n status: true,\n verifiedHumanAt: true\n }\n },\n revokedAt: true,\n socketId: true,\n id: true\n }\n });\n\n if (!session) {\n await revokeSession(\n ctx,\n decodedToken.id,\n 'Session revoked: Session not found',\n undefined,\n path\n );\n throw new TRPCError({\n message: 'Unauthorized',\n code: 'UNAUTHORIZED'\n });\n }\n\n // Check user status\n if (session.user.status === 'BANNED') {\n await revokeSession(\n ctx,\n session.id,\n 'Session revoked: User banned',\n undefined,\n path\n );\n throw new TRPCError({\n message: 'Unauthorized',\n code: 'UNAUTHORIZED'\n });\n }\n\n // Check biometric verification if enabled\n if (config.features?.biometric && config.hooks?.getBiometricTimeout) {\n const timeoutMs = await config.hooks.getBiometricTimeout();\n\n if (\n timeoutMs !== null &&\n !['auth.refresh', 'auth.verifyBiometric', 'auth.logout'].includes(\n path\n )\n ) {\n if (!session.user.verifiedHumanAt) {\n throw new TRPCError({\n message:\n 'Biometric verification not completed. Please verify again.',\n code: 'FORBIDDEN'\n });\n }\n\n const now = new Date();\n const verificationExpiry = new Date(\n session.user.verifiedHumanAt.getTime() + timeoutMs\n );\n\n if (now > verificationExpiry) {\n throw new TRPCError({\n message: 'Biometric verification expired. Please verify again.',\n code: 'FORBIDDEN'\n });\n }\n }\n }\n\n // Check if session is revoked\n if (session.revokedAt) {\n await revokeSession(\n ctx,\n session.id,\n 'Session revoked: Session already revoked',\n undefined,\n path\n );\n throw new TRPCError({\n message: 'Unauthorized',\n code: 'UNAUTHORIZED'\n });\n }\n\n // Check admin authorization if required\n if (meta?.adminRequired) {\n const admin = await config.prisma.admin.findFirst({\n where: { userId: session.userId },\n select: { ip: true }\n });\n\n if (!admin || admin.ip !== ctx.ip) {\n await revokeSession(\n ctx,\n session.id,\n 'Session revoked: Admin not found or IP mismatch',\n undefined,\n path\n );\n throw new TRPCError({\n message: 'Unauthorized',\n code: 'UNAUTHORIZED'\n });\n }\n }\n\n // Session is valid, proceed with authenticated context\n return next({\n ctx: {\n ...ctx,\n userId: session.userId,\n socketId: session.socketId,\n sessionId: session.id,\n refreshToken\n }\n });\n } catch (err: unknown) {\n if (err instanceof TRPCError && err.code === 'FORBIDDEN') {\n throw err;\n }\n\n // If auth is not required, continue with unauthenticated context\n if (!meta?.authRequired) {\n return next({ ctx: { ...ctx, userId: 0 } });\n }\n\n const errorStack = err instanceof Error ? err.stack : undefined;\n\n if (isTokenExpiredError(err) || isTokenInvalidError(err)) {\n await revokeSession(\n ctx,\n null,\n isTokenInvalidError(err)\n ? 'Session revoked: Token invalid'\n : 'Session revoked: Token expired',\n errorStack,\n path\n );\n throw new TRPCError({\n message: isTokenInvalidError(err)\n ? 'Token invalid'\n : 'Token expired',\n code: 'UNAUTHORIZED'\n });\n }\n\n if (err instanceof TRPCError && err.code === 'UNAUTHORIZED') {\n await revokeSession(\n ctx,\n null,\n 'Session revoked: Unauthorized',\n errorStack,\n path\n );\n throw new TRPCError({\n message: 'Unauthorized',\n code: 'UNAUTHORIZED'\n });\n }\n\n throw err;\n }\n } else {\n // No auth token present\n if (!meta?.authRequired) {\n return next({ ctx: { ...ctx, userId: 0 } });\n }\n\n await revokeSession(\n ctx,\n null,\n 'Session revoked: No token sent',\n undefined,\n path\n );\n throw new TRPCError({ message: 'Unauthorized', code: 'UNAUTHORIZED' });\n }\n });\n\n return authGuard;\n}\n","/**\n * Email service adapter interface\n * Implement this interface to integrate your email service\n */\nexport interface EmailAdapter {\n /**\n * Send email verification email with OTP code\n */\n sendVerificationEmail(email: string, code: string): Promise<void>;\n\n /**\n * Send password reset email with token/link\n */\n sendPasswordResetEmail(email: string, token: string): Promise<void>;\n\n /**\n * Send OTP for passwordless login or 2FA reset\n */\n sendOTPEmail(email: string, otp: number): Promise<void>;\n\n /**\n * Send login notification to existing devices\n */\n sendLoginNotification?(\n email: string,\n browserName: string,\n ip?: string\n ): Promise<void>;\n}\n\n/**\n * No-op email adapter as default\n */\nexport function createNoopEmailAdapter(): EmailAdapter {\n return {\n async sendVerificationEmail(email: string, code: string) {\n console.log(\n `[NoopEmailAdapter] Would send verification email to ${email} with code ${code}`\n );\n },\n async sendPasswordResetEmail(email: string, token: string) {\n console.log(\n `[NoopEmailAdapter] Would send password reset email to ${email} with token ${token}`\n );\n },\n async sendOTPEmail(email: string, otp: number) {\n console.log(\n `[NoopEmailAdapter] Would send OTP email to ${email} with code ${otp}`\n );\n },\n async sendLoginNotification(\n email: string,\n browserName: string,\n ip?: string\n ) {\n console.log(\n `[NoopEmailAdapter] Would send login notification to ${email} from ${browserName} (${ip})`\n );\n }\n };\n}\n\n/**\n * Console email adapter for development - logs emails to console\n */\nexport function createConsoleEmailAdapter(): EmailAdapter {\n return {\n async sendVerificationEmail(email: string, code: string) {\n console.log('\\n=== EMAIL: Verification ===');\n console.log(`To: ${email}`);\n console.log(`Code: ${code}`);\n console.log('===========================\\n');\n },\n async sendPasswordResetEmail(email: string, token: string) {\n console.log('\\n=== EMAIL: Password Reset ===');\n console.log(`To: ${email}`);\n console.log(`Token: ${token}`);\n console.log('=============================\\n');\n },\n async sendOTPEmail(email: string, otp: number) {\n console.log('\\n=== EMAIL: OTP Login ===');\n console.log(`To: ${email}`);\n console.log(`OTP: ${otp}`);\n console.log('========================\\n');\n },\n async sendLoginNotification(\n email: string,\n browserName: string,\n ip?: string\n ) {\n console.log('\\n=== EMAIL: Login Notification ===');\n console.log(`To: ${email}`);\n console.log(`Browser: ${browserName}`);\n console.log(`IP: ${ip || 'Unknown'}`);\n console.log('=================================\\n');\n }\n };\n}\n","import { createNoopEmailAdapter } from '../adapters';\nimport type { CookieSettings } from '../types';\nimport type { AuthConfig, AuthFeatures, TokenSettings } from '../types/config';\n\nexport type { AuthConfig, AuthFeatures, TokenSettings } from '../types/config';\nexport type { OAuthKeys } from './oauth';\n\n/**\n * Default token settings\n */\nexport const defaultTokenSettings: TokenSettings = {\n accessTokenExpiry: '5m',\n passwordResetExpiryMs: 60 * 60 * 1000, // 1 hour\n otpValidityMs: 15 * 60 * 1000 // 15 minutes\n};\n\n/**\n * Default cookie settings\n */\nexport const defaultCookieSettings: CookieSettings = {\n secure: true,\n sameSite: 'Strict',\n httpOnly: true,\n accessTokenPath: '/',\n refreshTokenPath: '/api/trpc/auth.refresh',\n maxAge: 365 * 24 * 60 * 60 // 1 year in seconds\n};\n\n/**\n * Default storage keys\n */\nexport const defaultStorageKeys = {\n accessToken: 'auth-at',\n refreshToken: 'auth-rt'\n};\n\n/**\n * Default feature flags (all optional features disabled)\n */\nexport const defaultFeatures: AuthFeatures = {\n twoFa: true,\n oauth: { google: true, apple: true },\n biometric: false,\n emailVerification: true,\n passwordReset: true,\n otpLogin: true\n};\n\n/**\n * Create a fully resolved auth config with defaults applied\n */\nexport function createAuthConfig(\n config: AuthConfig\n): Required<Omit<AuthConfig, 'hooks' | 'oauthKeys' | 'schemaExtensions'>> &\n AuthConfig {\n const emailService = config.emailService ?? createNoopEmailAdapter();\n return {\n ...config,\n features: { ...defaultFeatures, ...config.features },\n tokenSettings: { ...defaultTokenSettings, ...config.tokenSettings },\n cookieSettings: { ...defaultCookieSettings, ...config.cookieSettings },\n storageKeys: { ...defaultStorageKeys, ...config.storageKeys },\n generateUsername: config.generateUsername ?? (() => `user_${Date.now()}`),\n emailService\n };\n}\n\nexport type ResolvedAuthConfig = ReturnType<typeof createAuthConfig>;\n\n/**\n * Default auth config (requires prisma and secrets to be provided)\n */\nexport const defaultAuthConfig = {\n features: defaultFeatures,\n tokenSettings: defaultTokenSettings,\n cookieSettings: defaultCookieSettings,\n storageKeys: defaultStorageKeys\n};\n","import type { CreateHTTPContextOptions } from '@trpc/server/adapters/standalone';\n\nimport { type AuthCredentials, type CookieSettings } from '../types';\n\n/**\n * Default storage keys for auth cookies\n */\nexport const DEFAULT_STORAGE_KEYS = {\n ACCESS_TOKEN: 'auth-at',\n REFRESH_TOKEN: 'auth-rt'\n};\n\n/**\n * Parse auth tokens from cookie header\n * @param cookieHeader - Raw cookie header string\n * @param storageKeys - Custom storage keys (optional)\n * @returns Parsed tokens\n */\nexport function parseAuthCookies(\n cookieHeader: string | undefined,\n storageKeys: { accessToken: string; refreshToken: string } = {\n accessToken: DEFAULT_STORAGE_KEYS.ACCESS_TOKEN,\n refreshToken: DEFAULT_STORAGE_KEYS.REFRESH_TOKEN\n }\n): { accessToken?: string; refreshToken?: string } {\n if (!cookieHeader) {\n return {};\n }\n const accessToken = cookieHeader\n .split(`${storageKeys.accessToken}=`)[1]\n ?.split(';')[0];\n const refreshToken = cookieHeader\n .split(`${storageKeys.refreshToken}=`)[1]\n ?.split(';')[0];\n\n return {\n accessToken: accessToken || undefined,\n refreshToken: refreshToken || undefined\n };\n}\n\n/**\n * Extract domain from request headers\n * Tries origin header first (for POST/PUT/DELETE), then referer (for GET), then host\n * @param req - HTTP request object\n * @returns Domain hostname or undefined\n */\nfunction extractDomain(\n req: CreateHTTPContextOptions['res']['req']\n): string | undefined {\n // Try origin header first (available for POST/PUT/DELETE requests)\n const origin = req.headers.origin;\n if (origin) {\n try {\n return new URL(origin).hostname;\n } catch {\n // Invalid URL, continue to next option\n }\n }\n\n // Try referer header (available for GET requests)\n const referer = req.headers.referer;\n if (referer) {\n try {\n return new URL(referer).hostname;\n } catch {\n // Invalid URL, continue to next option\n }\n }\n\n // Fall back to host header (always available, but may include port)\n const host = req.headers.host;\n if (host) {\n // Remove port if present (e.g., \"example.com:3000\" -> \"example.com\")\n return host.split(':')[0];\n }\n\n return undefined;\n}\n\n/**\n * Set auth cookies on response\n * @param res - HTTP response object\n * @param credentials - Access and refresh tokens\n * @param settings - Cookie settings\n * @param storageKeys - Storage key names\n */\nexport function setAuthCookies(\n res: CreateHTTPContextOptions['res'],\n credentials: Partial<AuthCredentials>,\n settings: Partial<CookieSettings>,\n storageKeys: { accessToken: string; refreshToken: string } = {\n accessToken: DEFAULT_STORAGE_KEYS.ACCESS_TOKEN,\n refreshToken: DEFAULT_STORAGE_KEYS.REFRESH_TOKEN\n }\n): void {\n const cookies: string[] = [];\n const domain = settings.domain ?? extractDomain(res.req);\n\n const expiresDate = settings.maxAge\n ? new Date(Date.now() + settings.maxAge * 1000).toUTCString()\n : undefined;\n\n if (credentials.refreshToken) {\n const refreshCookie = [\n `${storageKeys.refreshToken}=${credentials.refreshToken}`,\n 'HttpOnly',\n settings.secure ? 'Secure=true' : '',\n `SameSite=${settings.sameSite}`,\n `Path=${settings.refreshTokenPath}`,\n domain ? `Domain=${domain}` : '',\n `Expires=${expiresDate}`\n ]\n .filter(Boolean)\n .join('; ');\n\n cookies.push(refreshCookie);\n }\n\n if (credentials.accessToken) {\n const accessCookie = [\n `${storageKeys.accessToken}=${credentials.accessToken}`,\n settings.secure ? 'Secure=true' : '',\n `SameSite=${settings.sameSite}`,\n `Path=${settings.accessTokenPath}`,\n domain ? `Domain=${domain}` : '',\n `Expires=${expiresDate}`\n ]\n .filter(Boolean)\n .join('; ');\n\n cookies.push(accessCookie);\n }\n\n if (cookies.length > 0) {\n res.setHeader('Set-Cookie', cookies);\n }\n}\n\n/**\n * Clear auth cookies (for logout)\n * @param res - HTTP response object\n * @param settings - Cookie settings\n * @param storageKeys - Storage key names\n */\nexport function clearAuthCookies(\n res: CreateHTTPContextOptions['res'],\n settings: Partial<CookieSettings>,\n storageKeys: { accessToken: string; refreshToken: string } = {\n accessToken: DEFAULT_STORAGE_KEYS.ACCESS_TOKEN,\n refreshToken: DEFAULT_STORAGE_KEYS.REFRESH_TOKEN\n }\n): void {\n const domain = extractDomain(res.req);\n const expiredDate = new Date(0).toUTCString();\n\n const cookies = [\n [\n `${storageKeys.refreshToken}=destroy`,\n 'HttpOnly',\n settings.secure ? 'Secure=true' : '',\n `SameSite=${settings.sameSite}`,\n `Path=${settings.refreshTokenPath}`,\n domain ? `Domain=${domain}` : '',\n `Expires=${expiredDate}`\n ]\n .filter(Boolean)\n .join('; '),\n [\n `${storageKeys.accessToken}=destroy`,\n settings.secure ? 'Secure=true' : '',\n `SameSite=${settings.sameSite}`,\n `Path=${settings.accessTokenPath}`,\n domain ? `Domain=${domain}` : '',\n `Expires=${expiredDate}`\n ]\n .filter(Boolean)\n .join('; ')\n ];\n\n res.setHeader('Set-Cookie', cookies);\n}\n","import jwt, { type SignOptions } from 'jsonwebtoken';\n\nimport type { JwtPayload } from '../types';\n\n/**\n * Options for creating access tokens\n */\nexport interface CreateTokenOptions {\n secret: string;\n expiresIn: SignOptions['expiresIn'];\n}\n\n/**\n * Options for verifying access tokens\n */\nexport interface VerifyTokenOptions {\n secret: string;\n ignoreExpiration?: boolean;\n}\n\n/**\n * Create a JWT access token\n * @param payload - Token payload containing session and user info\n * @param options - Token creation options\n * @returns Signed JWT token\n */\nexport function createAccessToken(\n payload: Omit<JwtPayload, 'exp' | 'iat'>,\n options: CreateTokenOptions\n): string {\n return jwt.sign(payload, options.secret, {\n expiresIn: options.expiresIn\n });\n}\n\n/**\n * Verify and decode a JWT access token\n * @param token - JWT token to verify\n * @param options - Verification options\n * @returns Decoded token payload\n * @throws Error if token is invalid or expired\n */\nexport function verifyAccessToken(\n token: string,\n options: VerifyTokenOptions\n): JwtPayload {\n return jwt.verify(token, options.secret, {\n ignoreExpiration: options.ignoreExpiration ?? false\n }) as JwtPayload;\n}\n\n/**\n * Decode a JWT token without verification\n * @param token - JWT token to decode\n * @returns Decoded payload or null if invalid\n */\nexport function decodeToken(token: string): JwtPayload | null {\n try {\n return jwt.decode(token) as JwtPayload | null;\n } catch {\n return null;\n }\n}\n\n/**\n * JWT error interface\n */\ninterface JwtError extends Error {\n name: 'TokenExpiredError' | 'JsonWebTokenError' | 'NotBeforeError';\n}\n\n/**\n * Check if an error is a JWT error\n */\nfunction isJwtError(error: unknown): error is JwtError {\n return (\n error instanceof Error &&\n ['TokenExpiredError', 'JsonWebTokenError', 'NotBeforeError'].includes(\n error.name\n )\n );\n}\n\n/**\n * Check if a token error is an expiration error\n */\nexport function isTokenExpiredError(error: unknown): boolean {\n return isJwtError(error) && error.name === 'TokenExpiredError';\n}\n\n/**\n * Check if a token error is a validation error\n */\nexport function isTokenInvalidError(error: unknown): boolean {\n return isJwtError(error) && error.name === 'JsonWebTokenError';\n}\n","import { randomUUID } from 'node:crypto';\n\nimport { TRPCError } from '@trpc/server';\nimport { type SignOptions } from 'jsonwebtoken';\n\nimport { type AuthProcedure, type BaseProcedure } from '../types/trpc';\nimport { cleanBase32String, verifyTotp } from '../utilities';\nimport { detectBrowser } from '../utilities/browser';\nimport type { ResolvedAuthConfig } from '../utilities/config';\nimport { clearAuthCookies, setAuthCookies } from '../utilities/cookies';\nimport { createAccessToken } from '../utilities/jwt';\nimport { comparePassword, hashPassword } from '../utilities/password';\nimport type { SchemaExtensions } from '../types/hooks';\nimport {\n changePasswordSchema,\n checkPasswordResetSchema,\n endAllSessionsSchema,\n requestPasswordResetSchema,\n resetPasswordSchema,\n type CreatedSchemas,\n type SignupSchemaInput,\n type LoginSchemaInput\n} from '../validators';\n\n/**\n * Factory for core authentication procedures: register, login, logout,\n * token refresh, session management, and password reset flows.\n */\nexport class BaseProcedureFactory<TExtensions extends SchemaExtensions = {}> {\n constructor(\n private config: ResolvedAuthConfig,\n private procedure: BaseProcedure,\n private authProcedure: AuthProcedure\n ) {}\n\n\n /** Returns all base auth procedures to be merged into the router. */\n createBaseProcedures(schemas: CreatedSchemas<TExtensions>) {\n return {\n register: this.register(schemas.signup),\n login: this.login(schemas.login),\n logout: this.logout(),\n refresh: this.refresh(),\n endAllSessions: this.endAllSessions(),\n changePassword: this.changePassword(),\n sendPasswordResetEmail: this.sendPasswordResetEmail(),\n checkPasswordReset: this.checkPasswordReset(),\n resetPassword: this.resetPassword()\n };\n }\n\n private register(schema: CreatedSchemas<TExtensions>['signup']) {\n return this.procedure\n .input(schema)\n .mutation(async ({ ctx, input }) => {\n const typedInput = input as SignupSchemaInput<TExtensions>;\n const { username, email, password } = typedInput;\n const userAgent = ctx.headers['user-agent'];\n\n if (!userAgent) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'User agent not found'\n });\n }\n\n if (this.config.hooks?.beforeRegister) {\n await this.config.hooks.beforeRegister(typedInput);\n }\n\n const usernameCheck = await this.config.prisma.user.findFirst({\n where: { username: { equals: username, mode: 'insensitive' } }\n });\n\n if (usernameCheck) {\n throw new TRPCError({\n code: 'CONFLICT',\n message: 'An account already exists with that username.'\n });\n }\n\n const emailCheck = await this.config.prisma.user.findFirst({\n where: { email: { equals: email, mode: 'insensitive' } },\n select: { id: true }\n });\n\n if (emailCheck) {\n throw new TRPCError({\n code: 'CONFLICT',\n message: 'An account already exists with that email.'\n });\n }\n\n const hashedPassword = await hashPassword(password);\n\n const user = await this.config.prisma.user.create({\n data: {\n username,\n email,\n password: hashedPassword,\n status: 'ACTIVE',\n tag: this.config.features.biometric ? 'BOT' : 'HUMAN',\n twoFaEnabled: false,\n emailVerificationStatus: 'UNVERIFIED',\n verifiedHumanAt: null\n }\n });\n\n if (this.config.hooks?.onUserCreated) {\n await this.config.hooks.onUserCreated(user.id, typedInput);\n }\n\n const refreshToken = randomUUID();\n const extraSessionData = this.config.hooks?.getSessionData\n ? await this.config.hooks.getSessionData(typedInput)\n : {};\n\n const session = await this.config.prisma.session.create({\n data: {\n userId: user.id,\n browserName: detectBrowser(userAgent),\n socketId: null,\n refreshToken,\n ...extraSessionData\n },\n select: { id: true, refreshToken: true, userId: true }\n });\n\n if (this.config.hooks?.onSessionCreated) {\n await this.config.hooks.onSessionCreated(session.id, typedInput);\n }\n\n const accessToken = createAccessToken(\n { id: session.id, userId: session.userId, verifiedHumanAt: null },\n {\n secret: this.config.secrets.jwt,\n expiresIn: this.config.tokenSettings.accessTokenExpiry as SignOptions['expiresIn']\n }\n );\n\n setAuthCookies(\n ctx.res,\n { accessToken, refreshToken: session.refreshToken! },\n this.config.cookieSettings,\n this.config.storageKeys\n );\n\n return {\n success: true,\n user: { id: user.id, email: user.email, username: user.username }\n };\n });\n }\n\n private login(schema: CreatedSchemas<TExtensions>['login']) {\n return this.procedure\n .input(schema)\n .mutation(async ({ ctx, input }) => {\n const typedInput = input as LoginSchemaInput<TExtensions>;\n const { username, password, code } = typedInput;\n const userAgent = ctx.headers['user-agent'];\n\n if (!userAgent) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'User agent not found'\n });\n }\n\n if (this.config.hooks?.beforeLogin) {\n await this.config.hooks.beforeLogin(typedInput);\n }\n\n const user = await this.config.prisma.user.findFirst({\n where: {\n OR: [\n { email: { equals: username, mode: 'insensitive' } },\n { username: { equals: username, mode: 'insensitive' } }\n ]\n },\n select: {\n id: true,\n status: true,\n password: true,\n twoFaEnabled: true,\n email: true,\n username: true,\n oauthProvider: true,\n verifiedHumanAt: true\n }\n });\n\n if (!user) {\n throw new TRPCError({\n code: 'FORBIDDEN',\n message: 'Invalid credentials.'\n });\n }\n\n if (user.status === 'DEACTIVATED') {\n throw new TRPCError({\n code: 'FORBIDDEN',\n message: 'Your account has been deactivated.'\n });\n }\n\n if (user.status === 'BANNED') {\n throw new TRPCError({\n code: 'FORBIDDEN',\n message: 'Your account has been banned.'\n });\n }\n\n if (!user.password) {\n throw new TRPCError({\n code: 'FORBIDDEN',\n message: `This account uses ${user.oauthProvider?.toLowerCase() || 'social login'}. Please use that method.`\n });\n }\n\n const isMatch = await comparePassword(password, user.password);\n if (!isMatch) {\n throw new TRPCError({\n code: 'FORBIDDEN',\n message: 'Invalid credentials.'\n });\n }\n\n if (user.twoFaEnabled && this.config.features?.twoFa) {\n if (!code) {\n throw new TRPCError({\n code: 'FORBIDDEN',\n message: '2FA code required.'\n });\n }\n\n let validCode = false;\n\n const secrets = await this.config.prisma.session.findMany({\n where: { userId: user.id, twoFaSecret: { not: null } },\n select: { twoFaSecret: true }\n });\n\n for (const s of secrets) {\n if (s.twoFaSecret && (await verifyTotp(code, cleanBase32String(s.twoFaSecret)))) {\n validCode = true;\n break;\n }\n }\n\n if (!validCode) {\n const checkOTP = await this.config.prisma.oTPBasedLogin.findFirst({\n where: {\n code: Number(code),\n userId: user.id,\n disabled: false,\n createdAt: { gte: new Date(Date.now() - this.config.tokenSettings.otpValidityMs) }\n }\n });\n\n if (checkOTP) {\n validCode = true;\n await this.config.prisma.oTPBasedLogin.updateMany({\n where: { code: Number(code) },\n data: { disabled: true }\n });\n }\n }\n\n if (!validCode) {\n throw new TRPCError({\n code: 'FORBIDDEN',\n message: 'Invalid 2FA code.'\n });\n }\n }\n\n const refreshToken = randomUUID();\n const extraSessionData = this.config.hooks?.getSessionData\n ? await this.config.hooks.getSessionData(typedInput)\n : {};\n\n const session = await this.config.prisma.session.create({\n data: {\n userId: user.id,\n browserName: detectBrowser(userAgent),\n socketId: null,\n refreshToken,\n ...extraSessionData\n },\n select: {\n id: true,\n refreshToken: true,\n userId: true,\n socketId: true,\n browserName: true,\n issuedAt: true,\n lastUsed: true,\n revokedAt: true,\n deviceId: true,\n twoFaSecret: true\n }\n });\n\n if (this.config.hooks?.onUserLogin) {\n await this.config.hooks.onUserLogin(user.id, session.id);\n }\n\n if (this.config.hooks?.onSessionCreated) {\n await this.config.hooks.onSessionCreated(session.id, typedInput);\n }\n\n const accessToken = createAccessToken(\n { id: session.id, userId: session.userId, verifiedHumanAt: user.verifiedHumanAt },\n {\n secret: this.config.secrets.jwt,\n expiresIn: this.config.tokenSettings.accessTokenExpiry as SignOptions['expiresIn']\n }\n );\n\n setAuthCookies(\n ctx.res,\n { accessToken, refreshToken: session.refreshToken! },\n this.config.cookieSettings,\n this.config.storageKeys\n );\n\n return {\n success: true,\n user: { id: user.id, email: user.email, username: user.username }\n };\n });\n }\n\n private logout() {\n return this.procedure.mutation(async ({ ctx }) => {\n const { userId, sessionId } = ctx;\n\n if (sessionId) {\n await this.config.prisma.session.update({\n where: { id: sessionId },\n data: { revokedAt: new Date() }\n });\n\n if (userId) {\n await this.config.prisma.user.update({\n where: { id: userId },\n data: { isActive: false }\n });\n }\n\n if (this.config.hooks?.afterLogout) {\n await this.config.hooks.afterLogout(userId, sessionId, ctx.socketId);\n }\n }\n\n clearAuthCookies(ctx.res, this.config.cookieSettings, this.config.storageKeys);\n\n return { success: true };\n });\n }\n\n private refresh() {\n return this.authProcedure\n .meta({ ignoreExpiration: true })\n .query(async ({ ctx }) => {\n const session = await this.config.prisma.session.update({\n where: { id: ctx.sessionId },\n data: { refreshToken: randomUUID(), lastUsed: new Date() },\n select: {\n id: true,\n refreshToken: true,\n userId: true,\n user: { select: { verifiedHumanAt: true } }\n }\n });\n\n if (this.config.hooks?.onRefresh) {\n this.config.hooks.onRefresh(session.userId).catch(() => {});\n }\n\n const accessToken = createAccessToken(\n { id: session.id, userId: session.userId, verifiedHumanAt: session.user.verifiedHumanAt },\n {\n secret: this.config.secrets.jwt,\n expiresIn: this.config.tokenSettings.accessTokenExpiry as SignOptions['expiresIn']\n }\n );\n\n setAuthCookies(\n ctx.res,\n { accessToken, refreshToken: session.refreshToken! },\n this.config.cookieSettings,\n this.config.storageKeys\n );\n\n return { success: true };\n });\n }\n\n private endAllSessions() {\n return this.authProcedure\n .input(endAllSessionsSchema)\n .mutation(async ({ ctx, input }) => {\n const { skipCurrentSession } = input;\n const { userId, sessionId } = ctx;\n\n const sessionsToRevoke = await this.config.prisma.session.findMany({\n where: {\n userId,\n revokedAt: null,\n ...(skipCurrentSession ? { NOT: { id: sessionId } } : {})\n },\n select: { socketId: true, id: true, userId: true }\n });\n\n await this.config.prisma.session.updateMany({\n where: {\n userId,\n revokedAt: null,\n ...(skipCurrentSession ? { NOT: { id: sessionId } } : {})\n },\n data: { revokedAt: new Date() }\n });\n\n for (const session of sessionsToRevoke) {\n if (this.config.hooks?.onSessionRevoked) {\n await this.config.hooks.onSessionRevoked(session.id, session.socketId, 'End all sessions');\n }\n }\n\n if (!skipCurrentSession) {\n await this.config.prisma.user.update({\n where: { id: userId },\n data: { isActive: false }\n });\n }\n\n return { success: true, revokedCount: sessionsToRevoke.length };\n });\n }\n\n private changePassword() {\n return this.authProcedure\n .input(changePasswordSchema)\n .mutation(async ({ ctx, input }) => {\n const { userId, sessionId } = ctx;\n const { currentPassword, newPassword } = input;\n\n if (currentPassword === newPassword) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'New password cannot be the same as current password'\n });\n }\n\n const user = await this.config.prisma.user.findUnique({\n where: { id: userId },\n select: { password: true }\n });\n\n if (!user) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'User not found' });\n }\n\n if (!user.password) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'This account uses social login and cannot change password.'\n });\n }\n\n const isMatch = await comparePassword(currentPassword, user.password);\n if (!isMatch) {\n throw new TRPCError({\n code: 'FORBIDDEN',\n message: 'Current password is incorrect'\n });\n }\n\n const hashedPassword = await hashPassword(newPassword);\n\n await this.config.prisma.user.update({\n where: { id: userId },\n data: { password: hashedPassword }\n });\n\n await this.config.prisma.session.updateMany({\n where: { userId, revokedAt: null, NOT: { id: sessionId } },\n data: { revokedAt: new Date() }\n });\n\n if (this.config.hooks?.onPasswordChanged) {\n await this.config.hooks.onPasswordChanged(userId);\n }\n\n return {\n success: true,\n message: 'Password changed. You will need to re-login on other devices.'\n };\n });\n }\n\n private sendPasswordResetEmail() {\n return this.procedure\n .input(requestPasswordResetSchema)\n .mutation(async ({ input }) => {\n const { email } = input;\n\n const user = await this.config.prisma.user.findFirst({\n where: { email: { equals: email, mode: 'insensitive' }, status: 'ACTIVE' },\n select: { id: true, password: true, email: true }\n });\n\n if (!user) {\n return { message: 'If an account exists with that email, a reset link has been sent.' };\n }\n\n if (!user.password) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'This account uses social login. Please use that method.'\n });\n }\n\n await this.config.prisma.passwordReset.deleteMany({ where: { userId: user.id } });\n\n const passwordReset = await this.config.prisma.passwordReset.create({\n data: { userId: user.id }\n });\n\n if (this.config.emailService) {\n await this.config.emailService.sendPasswordResetEmail(user.email, String(passwordReset.id));\n }\n\n return { message: 'Password reset email sent.' };\n });\n }\n\n private checkPasswordReset() {\n return this.procedure\n .input(checkPasswordResetSchema)\n .query(async ({ input }) => {\n const { token } = input;\n\n const passwordReset = await this.config.prisma.passwordReset.findUnique({\n where: { id: token },\n select: { id: true, createdAt: true, userId: true }\n });\n\n if (!passwordReset) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Invalid reset token.' });\n }\n\n if (passwordReset.createdAt.getTime() + this.config.tokenSettings.passwordResetExpiryMs < Date.now()) {\n await this.config.prisma.passwordReset.delete({ where: { id: token } });\n throw new TRPCError({ code: 'FORBIDDEN', message: 'Reset token expired.' });\n }\n\n return { valid: true };\n });\n }\n\n private resetPassword() {\n return this.procedure\n .input(resetPasswordSchema)\n .mutation(async ({ input }) => {\n const { token, password } = input;\n\n const passwordReset = await this.config.prisma.passwordReset.findFirst({\n where: { id: token },\n select: { id: true, createdAt: true, userId: true }\n });\n\n if (!passwordReset) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Invalid reset token.' });\n }\n\n if (passwordReset.createdAt.getTime() + this.config.tokenSettings.passwordResetExpiryMs < Date.now()) {\n await this.config.prisma.passwordReset.delete({ where: { id: token } });\n throw new TRPCError({ code: 'FORBIDDEN', message: 'Reset token expired.' });\n }\n\n const hashedPassword = await hashPassword(password);\n\n await this.config.prisma.user.update({\n where: { id: passwordReset.userId },\n data: { password: hashedPassword }\n });\n\n await this.config.prisma.passwordReset.delete({ where: { id: token } });\n\n await this.config.prisma.session.updateMany({\n where: { userId: passwordReset.userId },\n data: { revokedAt: new Date() }\n });\n\n return { message: 'Password updated. Please log in with your new password.' };\n });\n }\n}\n","/**\n * Detect browser/platform from user agent string\n * @param userAgent - User agent string from request headers\n * @returns Detected browser name\n */\nexport function detectBrowser(userAgent: string): string {\n // Check if it's an iOS app by looking for specific app-related terms\n if (/cfnetwork|darwin/i.test(userAgent)) return 'iOS App';\n\n // Check for iOS browsers\n if (\n /iphone|ipad|ipod/i.test(userAgent) &&\n /safari/i.test(userAgent) &&\n !/crios|fxios|edg\\//i.test(userAgent)\n ) {\n return 'iOS Browser (Safari)';\n }\n if (/iphone|ipad|ipod/i.test(userAgent) && /crios/i.test(userAgent))\n return 'iOS Browser (Chrome)';\n if (/iphone|ipad|ipod/i.test(userAgent) && /fxios/i.test(userAgent))\n return 'iOS Browser (Firefox)';\n if (/iphone|ipad|ipod/i.test(userAgent) && /edg\\//i.test(userAgent))\n return 'iOS Browser (Edge)';\n\n // Check if it's an Android app\n if (\n /android/i.test(userAgent) &&\n !/chrome|firefox|samsungbrowser|opr\\/|edg\\//i.test(userAgent)\n ) {\n return 'Android App';\n }\n\n // Check for Android browsers\n if (/android/i.test(userAgent) && /chrome/i.test(userAgent))\n return 'Android Browser (Chrome)';\n if (/android/i.test(userAgent) && /firefox/i.test(userAgent))\n return 'Android Browser (Firefox)';\n if (/android/i.test(userAgent) && /samsungbrowser/i.test(userAgent))\n return 'Android Browser (Samsung)';\n if (/android/i.test(userAgent) && /opr\\//i.test(userAgent))\n return 'Android Browser (Opera)';\n if (/android/i.test(userAgent) && /edg\\//i.test(userAgent))\n return 'Android Browser (Edge)';\n\n // Check for common desktop browsers\n if (/chrome|chromium/i.test(userAgent)) return 'Chrome';\n if (/firefox/i.test(userAgent)) return 'Firefox';\n if (/safari/i.test(userAgent) && !/chrome|chromium|crios/i.test(userAgent))\n return 'Safari';\n if (/opr\\//i.test(userAgent)) return 'Opera';\n if (/edg\\//i.test(userAgent)) return 'Edge';\n\n return 'Unknown';\n}\n\n/**\n * Check if the user agent indicates a mobile device\n * @param userAgent - User agent string\n * @returns True if mobile device\n */\nexport function isMobileDevice(userAgent: string): boolean {\n return /android|iphone|ipad|ipod|mobile/i.test(userAgent);\n}\n\n/**\n * Check if the user agent indicates a native app\n * @param userAgent - User agent string\n * @returns True if native app\n */\nexport function isNativeApp(userAgent: string): boolean {\n const browser = detectBrowser(userAgent);\n return browser === 'iOS App' || browser === 'Android App';\n}\n","import appleSignin from 'apple-signin-auth';\nimport { OAuth2Client } from 'google-auth-library';\n\nexport type OAuthProvider = 'GOOGLE' | 'APPLE';\n\nexport interface OAuthResult {\n email: string;\n oauthId: string;\n}\n\n/**\n * OAuth keys configuration for Google and Apple providers\n */\nexport interface OAuthKeys {\n google?: {\n clientId: string;\n clientSecret?: string;\n iosClientId?: string;\n };\n apple?: {\n clientId: string;\n iosClientId?: string;\n };\n}\n\n/**\n * OAuth verification error\n */\nexport class OAuthVerificationError extends Error {\n constructor(\n message: string,\n public readonly statusCode = 401\n ) {\n super(message);\n this.name = 'OAuthVerificationError';\n }\n}\n\n/**\n * Creates an OAuth token verifier with the provided keys\n * @param keys OAuth provider keys configuration\n * @returns A function to verify OAuth tokens\n */\nexport function createOAuthVerifier(keys: OAuthKeys) {\n let googleClient: OAuth2Client | null = null;\n if (keys.google?.clientId) {\n googleClient = new OAuth2Client({\n clientId: keys.google.clientId,\n clientSecret: keys.google.clientSecret\n });\n }\n\n return async function verifyOAuthToken(\n provider: OAuthProvider,\n token: string,\n extra?: { email?: string }\n ): Promise<OAuthResult> {\n if (provider === 'GOOGLE') {\n if (!keys.google?.clientId) {\n throw new OAuthVerificationError(\n 'Google OAuth configuration missing',\n 500\n );\n }\n\n if (!googleClient) {\n throw new OAuthVerificationError(\n 'Google OAuth client not initialized',\n 500\n );\n }\n\n const audience = [keys.google.clientId];\n if (keys.google.iosClientId) {\n audience.push(keys.google.iosClientId);\n }\n\n const ticket = await googleClient.verifyIdToken({\n idToken: token,\n audience\n });\n\n const payload = ticket.getPayload();\n if (!payload?.sub || !payload.email) {\n throw new OAuthVerificationError('Invalid Google token', 401);\n }\n\n return {\n oauthId: payload.sub,\n email: payload.email\n };\n }\n\n if (provider === 'APPLE') {\n if (!keys.apple?.clientId) {\n throw new OAuthVerificationError(\n 'Apple OAuth configuration missing',\n 500\n );\n }\n\n const audience = [keys.apple.clientId];\n if (keys.apple.iosClientId) {\n audience.push(keys.apple.iosClientId);\n }\n\n const { sub, email } = await appleSignin.verifyIdToken(token, {\n audience,\n ignoreExpiration: false\n });\n\n const finalEmail = email || extra?.email;\n if (!finalEmail || !sub) {\n throw new OAuthVerificationError('Invalid Apple token', 401);\n }\n\n return {\n oauthId: sub,\n email: finalEmail\n };\n }\n\n throw new OAuthVerificationError('Unsupported OAuth provider', 400);\n };\n}\n","import bcrypt from 'bcryptjs';\n\n/**\n * Default salt rounds for password hashing\n */\nconst DEFAULT_SALT_ROUNDS = 10;\n\n/**\n * Hash a plain text password\n * @param password - Plain text password\n * @param saltRounds - Number of salt rounds (default: 10)\n * @returns Hashed password\n */\nexport async function hashPassword(\n password: string,\n saltRounds: number = DEFAULT_SALT_ROUNDS\n): Promise<string> {\n const salt = await bcrypt.genSalt(saltRounds);\n return bcrypt.hash(password, salt);\n}\n\n/**\n * Compare a plain text password with a hashed password\n * @param password - Plain text password\n * @param hashedPassword - Hashed password to compare against\n * @returns True if passwords match\n */\nexport async function comparePassword(\n password: string,\n hashedPassword: string\n): Promise<boolean> {\n return bcrypt.compare(password, hashedPassword);\n}\n\n/**\n * Check if a password meets minimum requirements\n * @param password - Password to validate\n * @param minLength - Minimum length (default: 6)\n * @returns Validation result with error message if invalid\n */\nexport function validatePasswordStrength(\n password: string,\n minLength = 6\n): { valid: boolean; error?: string } {\n if (password.length < minLength) {\n return {\n valid: false,\n error: `Password must be at least ${minLength} characters`\n };\n }\n return { valid: true };\n}\n","import crypto from 'crypto';\nimport { TOTP } from 'totp-generator';\n\n/**\n * Base32 character set for TOTP secret generation\n */\nconst BASE32_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';\n\n/**\n * Generate a random TOTP secret\n * @param length - Length of the secret (default: 16)\n * @returns Base32 encoded secret\n */\nexport function generateTotpSecret(length = 16): string {\n let secret = '';\n for (let i = 0; i < length; i++) {\n const randIndex = Math.floor(Math.random() * BASE32_CHARS.length);\n secret += BASE32_CHARS[randIndex];\n }\n return secret;\n}\n\n/**\n * Clean a Base32 string by removing invalid characters\n * @param input - Input string to clean\n * @returns Cleaned Base32 string\n */\nexport function cleanBase32String(input: string): string {\n return input.replace(/[^A-Z2-7]/gi, '').toUpperCase();\n}\n\n/**\n * Generate a TOTP code from a secret\n * @param secret - Base32 encoded secret\n * @returns Current TOTP code\n */\nexport async function generateTotpCode(secret: string) {\n const cleanSecret = cleanBase32String(secret);\n const { otp } = await TOTP.generate(cleanSecret);\n return otp;\n}\n\n/**\n * Verify a TOTP code against a secret\n * @param code - TOTP code to verify\n * @param secret - Base32 encoded secret\n * @param window - Number of time steps to check before/after current (default: 1)\n * @returns True if code is valid\n */\nexport async function verifyTotp(code: string, secret: string) {\n const cleanSecret = cleanBase32String(secret);\n const normalizedCode = code.replace(/\\s/g, '');\n const { otp } = await TOTP.generate(cleanSecret);\n return otp === normalizedCode;\n}\n\n/**\n * Generate a random OTP code (for email-based verification)\n * @param min - Minimum value (default: 100000)\n * @param max - Maximum value (default: 999999)\n * @returns Random 6-digit OTP\n */\nexport function generateOtp(min = 100000, max = 999999): number {\n return Math.floor(crypto.randomInt(min, max + 1));\n}\n","import { z, type AnyZodObject } from 'zod';\n\nimport type { SchemaExtensions } from './types/hooks';\n\n/**\n * Username validation regex - allows letters, numbers, and underscores\n */\nconst usernameValidationRegex = /^[a-zA-Z0-9_]+$/;\n\n/**\n * Schema for user registration\n */\nexport const signupSchema = z.object({\n username: z\n .string()\n .min(1, { message: 'Username is required' })\n .max(30, { message: 'Username must be 30 characters or less' })\n .regex(usernameValidationRegex, {\n message: 'Username can only contain letters, numbers, and underscores'\n }),\n email: z.string().email({ message: 'Invalid email address' }),\n password: z\n .string()\n .min(6, { message: 'Password must contain at least 6 characters' })\n});\n\n/**\n * Schema for user login\n */\nexport const loginSchema = z.object({\n username: z.string().min(1, { message: 'Username or email is required' }),\n password: z.string().min(1, { message: 'Password is required' }),\n code: z.string().optional() // 2FA code\n});\n\n/**\n * Schema for OAuth login\n */\nexport const oAuthLoginSchema = z.object({\n idToken: z.string(),\n user: z\n .object({\n email: z.string().email().optional()\n })\n .optional(),\n provider: z.enum(['GOOGLE', 'APPLE'])\n});\n\n/**\n * Schema for password reset request\n */\nexport const requestPasswordResetSchema = z.object({\n email: z.string().email({ message: 'Invalid email address' })\n});\n\n/**\n * Schema for password reset confirmation\n */\nexport const resetPasswordSchema = z.object({\n token: z.string().min(1, { message: 'Reset token is required' }),\n password: z\n .string()\n .min(6, { message: 'Password must contain at least 6 characters' })\n});\n\n/**\n * Schema for checking password reset token\n */\nexport const checkPasswordResetSchema = z.object({\n token: z.string().min(1, { message: 'Reset token is required' })\n});\n\n/**\n * Schema for changing password (authenticated)\n */\nexport const changePasswordSchema = z.object({\n currentPassword: z\n .string()\n .min(1, { message: 'Current password is required' }),\n newPassword: z\n .string()\n .min(6, { message: 'New password must contain at least 6 characters' })\n});\n\n/**\n * Schema for 2FA verification\n */\nexport const twoFaVerifySchema = z.object({\n code: z.string().min(6, { message: 'Verification code is required' }),\n sessionId: z.number().optional()\n});\n\n/**\n * Schema for 2FA setup\n */\nexport const twoFaSetupSchema = z.object({\n code: z.string().min(6, { message: 'Verification code is required' })\n});\n\n/**\n * Schema for 2FA reset request\n */\nexport const twoFaResetSchema = z.object({\n username: z.string().min(1),\n password: z.string().min(1)\n});\n\n/**\n * Schema for 2FA reset verification\n */\nexport const twoFaResetVerifySchema = z.object({\n code: z.number().min(100000).max(999999),\n username: z.string().min(1)\n});\n\n/**\n * Schema for email verification\n */\nexport const verifyEmailSchema = z.object({\n code: z.string().min(1, { message: 'Verification code is required' })\n});\n\n/**\n * Schema for resending verification email\n */\nexport const resendVerificationSchema = z.object({\n email: z.string().email().optional()\n});\n\n/**\n * Schema for biometric verification\n */\nexport const biometricVerifySchema = z.object({});\n\n/**\n * Schema for push token registration\n */\nexport const registerPushTokenSchema = z.object({\n pushToken: z.string().min(1, { message: 'Push token is required' })\n});\n\n/**\n * Schema for push token deregistration\n */\nexport const deregisterPushTokenSchema = z.object({\n pushToken: z.string().min(1, { message: 'Push token is required' })\n});\n\n/**\n * Schema for getting 2FA secret\n */\nexport const getTwofaSecretSchema = z.object({\n pushCode: z.string().min(6, { message: 'Push code is required' })\n});\n\n/**\n * Schema for disabling 2FA\n */\nexport const disableTwofaSchema = z.object({\n password: z.string().min(1, { message: 'Password is required' })\n});\n\n/**\n * Schema for logout\n */\nexport const logoutSchema = z.object({\n allDevices: z.boolean().optional().default(false)\n});\n\n/**\n * Schema for ending all sessions\n */\nexport const endAllSessionsSchema = z.object({\n skipCurrentSession: z.boolean().optional().default(true)\n});\n\n/**\n * Schema for OTP-based login request\n */\nexport const otpLoginRequestSchema = z.object({\n email: z.string().email({ message: 'Invalid email address' })\n});\n\n/**\n * Schema for OTP-based login verification\n */\nexport const otpLoginVerifySchema = z.object({\n email: z.string().email(),\n code: z.number().min(100000).max(999999)\n});\n\nexport type SignupInput = z.infer<typeof signupSchema>;\nexport type LoginInput = z.infer<typeof loginSchema>;\nexport type OAuthLoginInput = z.infer<typeof oAuthLoginSchema>;\nexport type ResetPasswordInput = z.infer<typeof resetPasswordSchema>;\nexport type ChangePasswordInput = z.infer<typeof changePasswordSchema>;\nexport type TwoFaVerifyInput = z.infer<typeof twoFaVerifySchema>;\nexport type VerifyEmailInput = z.infer<typeof verifyEmailSchema>;\nexport type LogoutInput = z.infer<typeof logoutSchema>;\n\n/** Schemas used by auth procedures */\nexport interface AuthSchemas {\n signup: AnyZodObject;\n login: AnyZodObject;\n oauth: AnyZodObject;\n}\n\n\n/**\n * Compute merged ZodObject type.\n * When TExt is defined, produces a schema with both base and extension shapes.\n * When TExt is undefined, produces the base schema.\n */\ntype MergedSchema<TBase extends AnyZodObject, TExt extends AnyZodObject | undefined> =\n [TExt] extends [AnyZodObject]\n ? z.ZodObject<TBase['shape'] & TExt['shape'], 'strip', z.ZodTypeAny>\n : TBase;\n\n/** Result type from createSchemas - preserves concrete schema types */\nexport type CreatedSchemas<TExtensions extends SchemaExtensions = {}> = {\n signup: MergedSchema<typeof signupSchema, TExtensions['signup']>;\n login: MergedSchema<typeof loginSchema, TExtensions['login']>;\n oauth: MergedSchema<typeof oAuthLoginSchema, TExtensions['oauth']>;\n};\n\nexport type SignupSchemaInput<TExtensions extends SchemaExtensions = {}> =\n SignupInput & (TExtensions['signup'] extends AnyZodObject ? z.infer<TExtensions['signup']> : {});\n\nexport type LoginSchemaInput<TExtensions extends SchemaExtensions = {}> =\n LoginInput & (TExtensions['login'] extends AnyZodObject ? z.infer<TExtensions['login']> : {});\n\nexport type OAuthSchemaInput<TExtensions extends SchemaExtensions = {}> =\n OAuthLoginInput & (TExtensions['oauth'] extends AnyZodObject ? z.infer<TExtensions['oauth']> : {});\n\n/** Create schemas with optional extensions merged in */\nexport function createSchemas<TExtensions extends SchemaExtensions = {}>(\n extensions?: TExtensions\n): CreatedSchemas<TExtensions> {\n return {\n signup: extensions?.signup\n ? signupSchema.merge(extensions.signup)\n : signupSchema,\n login: extensions?.login\n ? loginSchema.merge(extensions.login)\n : loginSchema,\n oauth: extensions?.oauth\n ? oAuthLoginSchema.merge(extensions.oauth)\n : oAuthLoginSchema\n } as CreatedSchemas<TExtensions>;\n}\n","import { TRPCError } from '@trpc/server';\n\nimport { type AuthProcedure } from '../types/trpc';\nimport type { ResolvedAuthConfig } from '../utilities/config';\nimport { biometricVerifySchema } from '../validators';\n\n/** Factory for biometric verification procedures. */\nexport class BiometricProcedureFactory {\n constructor(\n private config: ResolvedAuthConfig,\n private authProcedure: AuthProcedure\n ) {}\n\n createBiometricProcedures() {\n return {\n verifyBiometric: this.verifyBiometric(),\n getBiometricStatus: this.getBiometricStatus()\n };\n }\n\n private checkConfig() {\n if (!this.config.features.biometric) {\n throw new TRPCError({ code: 'NOT_FOUND' });\n }\n }\n\n private verifyBiometric() {\n return this.authProcedure\n .input(biometricVerifySchema)\n .mutation(async ({ ctx }) => {\n this.checkConfig();\n const { userId } = ctx;\n\n await this.config.prisma.user.update({\n where: { id: userId },\n data: { verifiedHumanAt: new Date(), tag: 'HUMAN' }\n });\n\n if (this.config.hooks?.onBiometricVerified) {\n await this.config.hooks.onBiometricVerified(userId);\n }\n\n return { success: true, verifiedAt: new Date() };\n });\n }\n\n private getBiometricStatus() {\n return this.authProcedure.query(async ({ ctx }) => {\n this.checkConfig();\n const { userId } = ctx;\n\n const user = await this.config.prisma.user.findUnique({\n where: { id: userId },\n select: { verifiedHumanAt: true }\n });\n\n if (!user) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'User not found' });\n }\n\n let timeoutMs: number | null = null;\n if (this.config.hooks?.getBiometricTimeout) {\n timeoutMs = await this.config.hooks.getBiometricTimeout();\n }\n\n let isExpired = false;\n if (user.verifiedHumanAt && timeoutMs !== null) {\n const expiresAt = new Date(user.verifiedHumanAt.getTime() + timeoutMs);\n isExpired = new Date() > expiresAt;\n }\n\n return {\n verifiedHumanAt: user.verifiedHumanAt,\n isVerified: !!user.verifiedHumanAt && !isExpired,\n isExpired,\n requiresVerification: timeoutMs !== null\n };\n });\n }\n}\n","import { randomUUID } from 'node:crypto';\n\nimport { TRPCError } from '@trpc/server';\n\nimport { type AuthProcedure } from '../types/trpc';\nimport type { ResolvedAuthConfig } from '../utilities/config';\nimport { verifyEmailSchema } from '../validators';\n\n/** Factory for email verification procedures. */\nexport class EmailVerificationProcedureFactory {\n constructor(\n private config: ResolvedAuthConfig,\n private authProcedure: AuthProcedure\n ) {}\n\n createEmailVerificationProcedures() {\n return {\n sendVerificationEmail: this.sendVerificationEmail(),\n verifyEmail: this.verifyEmail(),\n getVerificationStatus: this.getVerificationStatus()\n };\n }\n\n private checkConfig() {\n if (!this.config.features.emailVerification) {\n throw new TRPCError({ code: 'NOT_FOUND' });\n }\n }\n\n private sendVerificationEmail() {\n return this.authProcedure.mutation(async ({ ctx }) => {\n this.checkConfig();\n const { userId } = ctx;\n\n const user = await this.config.prisma.user.findUnique({\n where: { id: userId, status: 'ACTIVE' },\n select: { id: true, email: true, emailVerificationStatus: true }\n });\n\n if (!user) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'User not found' });\n }\n\n if (user.emailVerificationStatus === 'VERIFIED') {\n return { message: 'Email is already verified', emailSent: false };\n }\n\n const otp = randomUUID();\n\n await this.config.prisma.user.update({\n where: { id: userId },\n data: { emailVerificationStatus: 'PENDING', otpForEmailVerification: otp }\n });\n\n if (this.config.emailService) {\n try {\n await this.config.emailService.sendVerificationEmail(user.email, otp);\n return { message: 'Verification email sent', emailSent: true };\n } catch {\n return { message: 'Failed to send email', emailSent: false };\n }\n }\n\n return { message: 'Email service not configured', emailSent: false };\n });\n }\n\n private verifyEmail() {\n return this.authProcedure\n .input(verifyEmailSchema)\n .mutation(async ({ ctx, input }) => {\n this.checkConfig();\n const { userId } = ctx;\n const { code } = input;\n\n const user = await this.config.prisma.user.findUnique({\n where: { id: userId, status: 'ACTIVE' },\n select: { id: true, emailVerificationStatus: true, otpForEmailVerification: true }\n });\n\n if (!user) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'User not found' });\n }\n\n if (user.emailVerificationStatus === 'VERIFIED') {\n return { success: true, message: 'Email is already verified' };\n }\n\n if (code !== user.otpForEmailVerification) {\n throw new TRPCError({ code: 'BAD_REQUEST', message: 'Invalid verification code' });\n }\n\n await this.config.prisma.user.update({\n where: { id: userId },\n data: { emailVerificationStatus: 'VERIFIED', otpForEmailVerification: null }\n });\n\n if (this.config.hooks?.onEmailVerified) {\n await this.config.hooks.onEmailVerified(userId);\n }\n\n return { success: true, message: 'Email verified' };\n });\n }\n\n private getVerificationStatus() {\n return this.authProcedure.query(async ({ ctx }) => {\n this.checkConfig();\n const { userId } = ctx;\n\n const user = await this.config.prisma.user.findUnique({\n where: { id: userId },\n select: { emailVerificationStatus: true, email: true }\n });\n\n if (!user) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'User not found' });\n }\n\n return {\n email: user.email,\n status: user.emailVerificationStatus,\n isVerified: user.emailVerificationStatus === 'VERIFIED'\n };\n });\n }\n}\n","import { randomUUID } from 'node:crypto';\n\nimport { TRPCError } from '@trpc/server';\nimport { type SignOptions } from 'jsonwebtoken';\n\nimport type { SchemaExtensions } from '../types/hooks';\nimport { type BaseProcedure } from '../types/trpc';\nimport { createAccessToken, detectBrowser, setAuthCookies } from '../utilities';\nimport type { ResolvedAuthConfig } from '../utilities/config';\nimport {\n createOAuthVerifier,\n type OAuthProvider,\n type OAuthResult\n} from '../utilities/oauth';\nimport { type CreatedSchemas, type OAuthSchemaInput } from '../validators';\n\n/** Factory for OAuth login procedures (Google, Apple). */\nexport class OAuthLoginProcedureFactory<TExtensions extends SchemaExtensions = {}> {\n private verifyOAuthToken:\n | ((provider: OAuthProvider, token: string, extra?: { email?: string }) => Promise<OAuthResult>)\n | null = null;\n\n constructor(\n private config: ResolvedAuthConfig,\n private procedure: BaseProcedure\n ) {\n if (config.oauthKeys) {\n this.verifyOAuthToken = createOAuthVerifier(config.oauthKeys);\n }\n }\n\n createOAuthLoginProcedures(schemas: CreatedSchemas<TExtensions>) {\n return { oAuthLogin: this.oAuthLogin(schemas.oauth) };\n }\n\n private checkConfig() {\n if (!this.config.features.oauth?.google && !this.config.features.oauth?.apple) {\n throw new TRPCError({ code: 'NOT_FOUND' });\n }\n }\n\n private oAuthLogin(schema: CreatedSchemas<TExtensions>['oauth']) {\n return this.procedure\n .input(schema)\n .mutation(async ({ ctx, input }) => {\n this.checkConfig();\n\n const typedInput = input as OAuthSchemaInput<TExtensions>;\n const { idToken, user: appleUser, provider } = typedInput;\n const userAgent = ctx.headers['user-agent'];\n\n if (!userAgent) {\n throw new TRPCError({ code: 'BAD_REQUEST', message: 'User agent not found' });\n }\n\n if (!this.verifyOAuthToken) {\n throw new TRPCError({\n code: 'INTERNAL_SERVER_ERROR',\n message: 'OAuth not configured. Provide oauthKeys in config.'\n });\n }\n\n const { email, oauthId } = await this.verifyOAuthToken(provider, idToken, appleUser);\n\n if (!email) {\n throw new TRPCError({ code: 'BAD_REQUEST', message: 'Email not provided by OAuth provider' });\n }\n\n let user = await this.config.prisma.user.findFirst({\n where: {\n OR: [\n { email: { equals: email, mode: 'insensitive' } },\n { oauthId: { equals: oauthId } }\n ]\n },\n select: {\n id: true,\n status: true,\n email: true,\n username: true,\n password: true,\n oauthProvider: true,\n oauthId: true,\n twoFaEnabled: true,\n verifiedHumanAt: true,\n emailVerificationStatus: true\n }\n });\n\n if (user?.oauthProvider && user.oauthProvider !== provider) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: `This email uses ${user.oauthProvider.toLowerCase()} sign-in.`\n });\n }\n\n if (user && !user.oauthProvider && user.password) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'This email uses password login. Please use email/password.'\n });\n }\n\n if (!user) {\n const generateUsername = this.config.generateUsername ?? (() => `user_${Date.now()}`);\n\n user = await this.config.prisma.user.create({\n data: {\n username: generateUsername(),\n email,\n password: null,\n emailVerificationStatus: 'VERIFIED',\n oauthProvider: provider,\n oauthId,\n status: 'ACTIVE',\n tag: this.config.features.biometric ? 'BOT' : 'HUMAN',\n twoFaEnabled: false,\n verifiedHumanAt: null\n }\n });\n\n if (this.config.hooks?.onUserCreated) {\n await this.config.hooks.onUserCreated(user.id, typedInput);\n }\n\n if (this.config.hooks?.onOAuthLinked) {\n await this.config.hooks.onOAuthLinked(user.id, provider);\n }\n }\n\n if (user.status === 'DEACTIVATED') {\n throw new TRPCError({ code: 'FORBIDDEN', message: 'Your account has been deactivated.' });\n }\n\n if (user.status === 'BANNED') {\n throw new TRPCError({ code: 'FORBIDDEN', message: 'Your account has been banned.' });\n }\n\n const refreshToken = randomUUID();\n const extraSessionData = this.config.hooks?.getSessionData\n ? await this.config.hooks.getSessionData(typedInput)\n : {};\n\n const session = await this.config.prisma.session.create({\n data: {\n userId: user.id,\n browserName: detectBrowser(userAgent),\n socketId: null,\n refreshToken,\n ...extraSessionData\n },\n select: {\n id: true,\n refreshToken: true,\n userId: true,\n socketId: true,\n browserName: true,\n issuedAt: true,\n lastUsed: true,\n revokedAt: true,\n deviceId: true,\n twoFaSecret: true\n }\n });\n\n if (this.config.hooks?.onUserLogin) {\n await this.config.hooks.onUserLogin(user.id, session.id);\n }\n\n if (this.config.hooks?.onSessionCreated) {\n await this.config.hooks.onSessionCreated(session.id, typedInput);\n }\n\n const accessToken = createAccessToken(\n { id: session.id, userId: session.userId, verifiedHumanAt: user.verifiedHumanAt ?? null },\n {\n secret: this.config.secrets.jwt,\n expiresIn: this.config.tokenSettings.accessTokenExpiry as SignOptions['expiresIn']\n }\n );\n\n setAuthCookies(\n ctx.res,\n { accessToken, refreshToken: session.refreshToken! },\n this.config.cookieSettings,\n this.config.storageKeys\n );\n\n return {\n success: true,\n user: { id: user.id, email: user.email, username: user.username }\n };\n });\n }\n}\n","import { TRPCError } from '@trpc/server';\n\nimport { type AuthProcedure, type BaseProcedure } from '../types/trpc';\nimport type { ResolvedAuthConfig } from '../utilities/config';\nimport { comparePassword } from '../utilities/password';\nimport {\n cleanBase32String,\n generateOtp,\n generateTotpSecret,\n verifyTotp\n} from '../utilities/totp';\nimport {\n deregisterPushTokenSchema,\n disableTwofaSchema,\n getTwofaSecretSchema,\n registerPushTokenSchema,\n twoFaResetSchema,\n twoFaResetVerifySchema\n} from '../validators';\n\n/** Factory for 2FA procedures: enable/disable, TOTP secrets, and reset flows. */\nexport class TwoFaProcedureFactory {\n constructor(\n private config: ResolvedAuthConfig,\n private procedure: BaseProcedure,\n private authProcedure: AuthProcedure\n ) {}\n\n createTwoFaProcedures() {\n return {\n enableTwofa: this.enableTwofa(),\n disableTwofa: this.disableTwofa(),\n getTwofaSecret: this.getTwofaSecret(),\n twoFaReset: this.twoFaReset(),\n twoFaResetVerify: this.twoFaResetVerify(),\n registerPushToken: this.registerPushToken(),\n deregisterPushToken: this.deregisterPushToken()\n };\n }\n\n private checkConfig() {\n if (!this.config.features.twoFa) {\n throw new TRPCError({ code: 'NOT_FOUND' });\n }\n }\n\n private enableTwofa() {\n return this.authProcedure.mutation(async ({ ctx }) => {\n this.checkConfig();\n const { userId, sessionId } = ctx;\n\n const user = await this.config.prisma.user.findFirst({\n where: { id: userId },\n select: { twoFaEnabled: true, oauthProvider: true, password: true }\n });\n\n if (!user) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'User not found.' });\n }\n\n if (user.oauthProvider) {\n throw new TRPCError({\n code: 'FORBIDDEN',\n message: '2FA is not available for social login accounts.'\n });\n }\n\n if (user.twoFaEnabled) {\n throw new TRPCError({ code: 'BAD_REQUEST', message: '2FA already enabled.' });\n }\n\n const checkSession = await this.config.prisma.session.findFirst({\n where: { userId, id: sessionId },\n select: { deviceId: true }\n });\n\n if (!checkSession?.deviceId) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'You must be logged in on mobile to enable 2FA.'\n });\n }\n\n await this.config.prisma.session.updateMany({\n where: { userId, revokedAt: null, NOT: { id: sessionId } },\n data: { revokedAt: new Date() }\n });\n\n await this.config.prisma.session.updateMany({\n where: { userId, NOT: { id: sessionId } },\n data: { twoFaSecret: null }\n });\n\n const secret = generateTotpSecret();\n\n await this.config.prisma.user.update({\n where: { id: userId },\n data: { twoFaEnabled: true }\n });\n\n await this.config.prisma.session.update({\n where: { id: sessionId },\n data: { twoFaSecret: secret }\n });\n\n if (this.config.hooks?.onTwoFaStatusChanged) {\n await this.config.hooks.onTwoFaStatusChanged(userId, true);\n }\n\n return { secret };\n });\n }\n\n private disableTwofa() {\n return this.authProcedure\n .input(disableTwofaSchema)\n .mutation(async ({ ctx, input }) => {\n this.checkConfig();\n const { userId, sessionId } = ctx;\n const { password } = input;\n\n const user = await this.config.prisma.user.findFirst({\n where: { id: userId },\n select: { password: true, status: true, oauthProvider: true }\n });\n\n if (!user) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'User not found.' });\n }\n\n if (user.status !== 'ACTIVE') {\n throw new TRPCError({ code: 'FORBIDDEN', message: 'Account deactivated.' });\n }\n\n if (user.oauthProvider) {\n throw new TRPCError({\n code: 'FORBIDDEN',\n message: '2FA is not available for social login accounts.'\n });\n }\n\n if (!user.password) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'Cannot verify password for social login account.'\n });\n }\n\n const isMatch = await comparePassword(password, user.password);\n if (!isMatch) {\n throw new TRPCError({ code: 'FORBIDDEN', message: 'Incorrect password.' });\n }\n\n await this.config.prisma.user.update({\n where: { id: userId },\n data: { twoFaEnabled: false }\n });\n\n await this.config.prisma.session.update({\n where: { id: sessionId },\n data: { twoFaSecret: null }\n });\n\n if (this.config.hooks?.onTwoFaStatusChanged) {\n await this.config.hooks.onTwoFaStatusChanged(userId, false);\n }\n\n return { disabled: true };\n });\n }\n\n private getTwofaSecret() {\n return this.authProcedure\n .input(getTwofaSecretSchema)\n .query(async ({ ctx, input }) => {\n this.checkConfig();\n const { userId, sessionId } = ctx;\n const { pushCode } = input;\n\n const user = await this.config.prisma.user.findFirst({\n where: { id: userId },\n select: { twoFaEnabled: true, oauthProvider: true }\n });\n\n if (user?.oauthProvider) {\n throw new TRPCError({\n code: 'FORBIDDEN',\n message: '2FA is not available for social login accounts.'\n });\n }\n\n if (!user?.twoFaEnabled) {\n throw new TRPCError({ code: 'BAD_REQUEST', message: '2FA not enabled.' });\n }\n\n const session = await this.config.prisma.session.findUnique({\n where: { id: sessionId, userId },\n select: { twoFaSecret: true, device: { select: { pushToken: true } } }\n });\n\n if (!session?.device) {\n throw new TRPCError({ code: 'BAD_REQUEST', message: 'Invalid request' });\n }\n\n const expectedCode = await verifyTotp(pushCode, cleanBase32String(session.device.pushToken));\n if (!expectedCode) {\n throw new TRPCError({ code: 'BAD_REQUEST', message: 'Invalid request' });\n }\n\n if (session.twoFaSecret) {\n return { secret: session.twoFaSecret };\n }\n\n const secret = generateTotpSecret();\n await this.config.prisma.session.update({\n where: { id: sessionId },\n data: { twoFaSecret: secret }\n });\n return { secret };\n });\n }\n\n private twoFaReset() {\n return this.procedure\n .input(twoFaResetSchema)\n .mutation(async ({ input }) => {\n this.checkConfig();\n const { username, password } = input;\n\n const user = await this.config.prisma.user.findFirst({\n where: { username: { equals: username, mode: 'insensitive' }, twoFaEnabled: true },\n select: { id: true, password: true, email: true }\n });\n\n if (!user) {\n throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Invalid credentials.' });\n }\n\n if (!user.password) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'Social login accounts cannot use 2FA reset.'\n });\n }\n\n const isMatch = await comparePassword(password, user.password);\n if (!isMatch) {\n throw new TRPCError({ code: 'FORBIDDEN', message: 'Invalid credentials.' });\n }\n\n const otp = generateOtp();\n await this.config.prisma.oTPBasedLogin.create({\n data: { userId: user.id, code: otp }\n });\n\n if (this.config.emailService) {\n await this.config.emailService.sendOTPEmail(user.email, otp);\n }\n\n return { success: true };\n });\n }\n\n private twoFaResetVerify() {\n return this.procedure\n .input(twoFaResetVerifySchema)\n .mutation(async ({ input }) => {\n this.checkConfig();\n const { code, username } = input;\n\n const user = await this.config.prisma.user.findFirst({\n where: { username: { equals: username, mode: 'insensitive' } },\n select: { id: true }\n });\n\n if (!user) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'User not found' });\n }\n\n const otp = await this.config.prisma.oTPBasedLogin.findFirst({\n where: {\n userId: user.id,\n code,\n disabled: false,\n createdAt: { gte: new Date(Date.now() - this.config.tokenSettings.otpValidityMs) }\n }\n });\n\n if (!otp) {\n throw new TRPCError({ code: 'FORBIDDEN', message: 'Invalid or expired OTP' });\n }\n\n await this.config.prisma.oTPBasedLogin.update({\n where: { id: otp.id },\n data: { disabled: true }\n });\n\n await this.config.prisma.user.update({\n where: { id: user.id },\n data: { twoFaEnabled: false }\n });\n\n await this.config.prisma.session.updateMany({\n where: { userId: user.id },\n data: { twoFaSecret: null }\n });\n\n return { success: true, message: '2FA has been reset.' };\n });\n }\n\n private registerPushToken() {\n return this.authProcedure\n .input(registerPushTokenSchema)\n .mutation(async ({ ctx, input }) => {\n this.checkConfig();\n const { userId, sessionId } = ctx;\n const { pushToken } = input;\n\n await this.config.prisma.session.updateMany({\n where: {\n userId,\n id: { not: sessionId },\n revokedAt: null,\n device: { pushToken }\n },\n data: { revokedAt: new Date() }\n });\n\n const checkDevice = await this.config.prisma.device.findFirst({\n where: {\n pushToken,\n sessions: { some: { id: sessionId } },\n users: { some: { id: userId } }\n },\n select: { id: true }\n });\n\n if (!checkDevice) {\n await this.config.prisma.device.upsert({\n where: { pushToken },\n create: {\n pushToken,\n sessions: { connect: { id: sessionId } },\n users: { connect: { id: userId } }\n },\n update: {\n sessions: { connect: { id: sessionId } },\n users: { connect: { id: userId } }\n }\n });\n }\n\n return { registered: true };\n });\n }\n\n private deregisterPushToken() {\n return this.authProcedure\n .meta({ ignoreExpiration: true })\n .input(deregisterPushTokenSchema)\n .mutation(async ({ ctx, input }) => {\n this.checkConfig();\n const { userId } = ctx;\n const { pushToken } = input;\n\n const device = await this.config.prisma.device.findFirst({\n where: {\n ...(userId !== 0 && { users: { some: { id: userId } } }),\n pushToken\n },\n select: { id: true }\n });\n\n if (device) {\n await this.config.prisma.device.delete({\n where: { id: device.id }\n });\n }\n\n return { deregistered: true };\n });\n }\n}\n","import { initTRPC } from '@trpc/server';\nimport { type IncomingMessage } from 'http';\nimport SuperJSON from 'superjson';\nimport { ZodError } from 'zod';\n\nimport { type createAuthGuard } from '../middleware/authGuard';\nimport { type Meta, type TrpcBuilder, type TrpcContext } from '../types/trpc';\nimport { type ResolvedAuthConfig } from './config';\n\n/**\n * Checks if an error is a Prisma connection error (infrastructure issue).\n * Connection errors are P1000-P1003:\n * - P1000: Authentication failed\n * - P1001: Can't reach database server\n * - P1002: Database server timeout\n * - P1003: Database does not exist\n */\nfunction isPrismaConnectionError(error: unknown): boolean {\n if (!error || typeof error !== 'object') {\n return false;\n }\n\n // Check for Prisma error code\n const errorCode = (error as { code?: string }).code;\n if (errorCode && typeof errorCode === 'string') {\n const codeMatch = errorCode.match(/^P(\\d+)$/);\n if (codeMatch) {\n const codeNum = parseInt(codeMatch[1], 10);\n if (codeNum >= 1000 && codeNum <= 1003) {\n return true;\n }\n }\n }\n\n // Check error constructor name for Prisma connection errors\n const constructorName = error.constructor?.name || '';\n if (constructorName.includes('Prisma')) {\n const errorMessage =\n (error as { message?: string }).message?.toLowerCase() || '';\n if (\n errorMessage.includes(\"can't reach database\") ||\n errorMessage.includes('authentication failed') ||\n errorMessage.includes('database server') ||\n errorMessage.includes('timeout') ||\n errorMessage.includes('connection')\n ) {\n return true;\n }\n }\n\n // Check error.cause recursively\n const cause = (error as { cause?: unknown }).cause;\n if (cause) {\n return isPrismaConnectionError(cause);\n }\n\n return false;\n}\n\nexport function createTrpcBuilder(config: ResolvedAuthConfig) {\n return initTRPC\n .context<TrpcContext>()\n .meta<Meta>()\n .create({\n transformer: SuperJSON,\n errorFormatter: (opts) => {\n const { shape, error } = opts;\n\n const { stack: _stack, ...safeData } = shape.data;\n\n // Handle 500 errors\n if (error.code === 'INTERNAL_SERVER_ERROR') {\n if (config.hooks?.logError) {\n const errorType =\n isPrismaConnectionError(error) ||\n isPrismaConnectionError(error.cause)\n ? 'DATABASE_ERROR'\n : 'SERVER_ERROR';\n\n config.hooks\n .logError({\n type: errorType,\n description: error.message,\n stack: error.stack || 'No stack trace',\n ip: opts.ctx?.ip,\n userId: opts.ctx?.userId ?? null\n })\n .catch(() => {\n // Silently fail - error logging should never throw\n });\n }\n\n // Customize the error message for users\n return {\n ...shape,\n message: 'An unexpected error occurred. Please try again later.',\n data: {\n ...safeData,\n zodError:\n error.cause instanceof ZodError ? error.cause.flatten() : null\n }\n };\n }\n\n return {\n ...shape,\n data: {\n ...safeData,\n zodError:\n error.cause instanceof ZodError ? error.cause.flatten() : null\n }\n };\n }\n });\n}\n\nexport function createBaseProcedure(\n t: TrpcBuilder,\n authGuard: ReturnType<typeof createAuthGuard>\n) {\n return t.procedure.use(authGuard);\n}\n\nexport function getClientIp(req: IncomingMessage): string | undefined {\n // Check for the X-Forwarded-For header\n const forwarded = req.headers['x-forwarded-for'] as string | undefined;\n\n if (forwarded) {\n return forwarded.split(',')[0]?.trim();\n }\n\n // Fallback to the connection's remote address\n return req.socket.remoteAddress || undefined;\n}\n","import { type CreateHTTPContextOptions } from '@trpc/server/adapters/standalone';\n\nimport { createAuthGuard } from './middleware/authGuard';\nimport { BaseProcedureFactory } from './procedures/base';\nimport { BiometricProcedureFactory } from './procedures/biometric';\nimport { EmailVerificationProcedureFactory } from './procedures/emailVerification';\nimport { OAuthLoginProcedureFactory } from './procedures/oauth';\nimport { TwoFaProcedureFactory } from './procedures/twoFa';\nimport type { SchemaExtensions } from './types/hooks';\nimport {\n type AuthProcedure,\n type BaseProcedure,\n type TrpcContext\n} from './types/trpc';\nimport type { AuthConfig, ResolvedAuthConfig } from './utilities/config';\nimport { createAuthConfig } from './utilities/config';\nimport {\n createBaseProcedure,\n createTrpcBuilder,\n getClientIp\n} from './utilities/trpc';\nimport { createSchemas, type CreatedSchemas } from './validators';\n\nexport const createContext = ({\n req,\n res\n}: CreateHTTPContextOptions): TrpcContext => ({\n headers: req.headers,\n userId: null,\n sessionId: null,\n refreshToken: null,\n socketId: null,\n ip: getClientIp(req),\n res\n});\n\nclass AuthRouterFactory<TExtensions extends SchemaExtensions = {}> {\n private config: ResolvedAuthConfig;\n private schemas: CreatedSchemas<TExtensions>;\n t: ReturnType<typeof createTrpcBuilder>;\n private authGuard: ReturnType<typeof createAuthGuard>;\n procedure: BaseProcedure;\n authProcedure: AuthProcedure;\n constructor(private userConfig: AuthConfig<TExtensions>) {\n this.config = createAuthConfig(this.userConfig);\n this.schemas = createSchemas<TExtensions>(\n this.config.schemaExtensions as TExtensions\n );\n this.t = createTrpcBuilder(this.config);\n this.authGuard = createAuthGuard(this.config, this.t);\n this.procedure = createBaseProcedure(this.t, this.authGuard);\n this.authProcedure = this.procedure.meta({ authRequired: true });\n }\n\n createRouter() {\n const baseRoutes = new BaseProcedureFactory<TExtensions>(\n this.config,\n this.procedure,\n this.authProcedure\n );\n const biometricRoutes = new BiometricProcedureFactory(\n this.config,\n this.authProcedure\n );\n const emailVerificationRoutes = new EmailVerificationProcedureFactory(\n this.config,\n this.authProcedure\n );\n const oAuthLoginRoutes = new OAuthLoginProcedureFactory<TExtensions>(\n this.config,\n this.procedure\n );\n const twoFaRoutes = new TwoFaProcedureFactory(\n this.config,\n this.procedure,\n this.authProcedure\n );\n\n return this.t.router({\n ...baseRoutes.createBaseProcedures(this.schemas),\n ...oAuthLoginRoutes.createOAuthLoginProcedures(this.schemas),\n ...twoFaRoutes.createTwoFaProcedures(),\n ...biometricRoutes.createBiometricProcedures(),\n ...emailVerificationRoutes.createEmailVerificationProcedures()\n });\n }\n}\n\nexport function createAuthRouter<TExtensions extends SchemaExtensions = {}>(\n config: AuthConfig<TExtensions>\n) {\n const factory = new AuthRouterFactory<TExtensions>(config);\n const router = factory.t.router({\n auth: factory.createRouter()\n });\n return {\n router: router,\n t: factory.t,\n procedure: factory.procedure,\n authProcedure: factory.authProcedure,\n createContext: createContext\n };\n}\n\nexport type AuthRouter<TExtensions extends SchemaExtensions = {}> = ReturnType<\n typeof createAuthRouter<TExtensions>\n>;\n"],"mappings":"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","names":["jwt","import_server","appleSignin","bcrypt","crypto","import_server","import_node_crypto","import_server","import_node_crypto","import_server","import_server","import_server","import_zod","SuperJSON"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/middleware/authGuard.ts","../src/adapters/email.ts","../src/utilities/config.ts","../src/utilities/cookies.ts","../src/utilities/jwt.ts","../src/procedures/base.ts","../src/utilities/browser.ts","../src/utilities/oauth.ts","../src/utilities/password.ts","../src/utilities/totp.ts","../src/procedures/biometric.ts","../src/procedures/emailVerification.ts","../src/procedures/oauth.ts","../src/procedures/twoFa.ts","../src/utilities/trpc.ts","../src/router.ts"],"sourcesContent":["import { TRPCError } from '@trpc/server';\n\nimport { type AuthConfig } from '../types/config';\nimport { type TrpcBuilder, type TrpcContext } from '../types/trpc';\nimport { defaultCookieSettings, defaultStorageKeys } from '../utilities/config';\nimport { clearAuthCookies, parseAuthCookies } from '../utilities/cookies';\nimport {\n isTokenExpiredError,\n isTokenInvalidError,\n verifyAccessToken\n} from '../utilities/jwt';\n\nexport function createAuthGuard(config: AuthConfig, t: TrpcBuilder) {\n const storageKeys = config.storageKeys ?? defaultStorageKeys;\n const cookieSettings = { ...defaultCookieSettings, ...config.cookieSettings };\n\n const revokeSession = async (\n ctx: TrpcContext,\n sessionId: number | null,\n description: string,\n errorStack?: string | null,\n path?: string\n ) => {\n clearAuthCookies(ctx.res, cookieSettings, storageKeys);\n\n // Log session revocations for security auditing\n // This helps track when and why sessions are revoked to detect accidental deauths\n if (config.hooks?.logError) {\n try {\n const contextInfo = {\n reason: description,\n sessionId,\n userId: ctx.userId,\n ip: ctx.ip,\n userAgent: ctx.headers['user-agent'],\n ...(path ? { path } : {}),\n timestamp: new Date().toISOString()\n };\n\n const combinedStack = [\n errorStack ? `Error Stack:\\n${errorStack}` : null,\n 'Context:',\n JSON.stringify(contextInfo, null, 2)\n ]\n .filter(Boolean)\n .join('\\n\\n');\n\n await config.hooks.logError({\n type: 'SECURITY',\n description: `Session revoked: ${description}`,\n stack: combinedStack,\n ip: ctx.ip,\n userId: ctx.userId ?? null\n });\n } catch {\n // Silently fail - don't let error logging prevent session revocation\n }\n }\n\n if (sessionId) {\n try {\n await config.prisma.session.update({\n where: { id: sessionId },\n data: { revokedAt: new Date() }\n });\n\n if (config.hooks?.onSessionRevoked) {\n const session = await config.prisma.session.findUnique({\n where: { id: sessionId },\n select: { id: true, userId: true, socketId: true }\n });\n if (session) {\n await config.hooks.onSessionRevoked(\n session.userId,\n session.socketId,\n description\n );\n }\n }\n } catch {\n // Session may already be revoked or deleted\n }\n }\n };\n\n const authGuard = t.middleware(async ({ ctx, meta, next, path }) => {\n const cookies = parseAuthCookies(ctx.headers.cookie, storageKeys);\n const authToken = cookies.accessToken;\n const refreshToken = cookies.refreshToken;\n const userAgent = ctx.headers['user-agent'];\n\n if (!userAgent) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'User agent is required'\n });\n }\n\n // If auth token is present, validate it\n if (authToken) {\n try {\n const decodedToken = verifyAccessToken(authToken, {\n secret: config.secrets.jwt,\n ignoreExpiration: meta?.ignoreExpiration ?? false\n });\n\n // For refresh endpoint, require refresh token\n if (path === 'auth.refresh' && !refreshToken) {\n await revokeSession(\n ctx,\n decodedToken.id,\n 'Session revoked: No refresh token',\n undefined,\n path\n );\n throw new TRPCError({\n message: 'Unauthorized',\n code: 'UNAUTHORIZED'\n });\n }\n\n // Find session in database\n const session = await config.prisma.session.findUnique({\n where: {\n id: decodedToken.id,\n ...(path === 'auth.refresh' ? { refreshToken } : {})\n },\n select: {\n userId: true,\n user: {\n select: {\n status: true,\n verifiedHumanAt: true\n }\n },\n revokedAt: true,\n socketId: true,\n id: true\n }\n });\n\n if (!session) {\n await revokeSession(\n ctx,\n decodedToken.id,\n 'Session revoked: Session not found',\n undefined,\n path\n );\n throw new TRPCError({\n message: 'Unauthorized',\n code: 'UNAUTHORIZED'\n });\n }\n\n // Check user status\n if (session.user.status === 'BANNED') {\n await revokeSession(\n ctx,\n session.id,\n 'Session revoked: User banned',\n undefined,\n path\n );\n throw new TRPCError({\n message: 'Unauthorized',\n code: 'UNAUTHORIZED'\n });\n }\n\n // Check biometric verification if enabled\n if (config.features?.biometric && config.hooks?.getBiometricTimeout) {\n const timeoutMs = await config.hooks.getBiometricTimeout();\n\n if (\n timeoutMs !== null &&\n !['auth.refresh', 'auth.verifyBiometric', 'auth.logout'].includes(\n path\n )\n ) {\n if (!session.user.verifiedHumanAt) {\n throw new TRPCError({\n message:\n 'Biometric verification not completed. Please verify again.',\n code: 'FORBIDDEN'\n });\n }\n\n const now = new Date();\n const verificationExpiry = new Date(\n session.user.verifiedHumanAt.getTime() + timeoutMs\n );\n\n if (now > verificationExpiry) {\n throw new TRPCError({\n message: 'Biometric verification expired. Please verify again.',\n code: 'FORBIDDEN'\n });\n }\n }\n }\n\n // Check if session is revoked\n if (session.revokedAt) {\n await revokeSession(\n ctx,\n session.id,\n 'Session revoked: Session already revoked',\n undefined,\n path\n );\n throw new TRPCError({\n message: 'Unauthorized',\n code: 'UNAUTHORIZED'\n });\n }\n\n // Check admin authorization if required\n if (meta?.adminRequired) {\n const admin = await config.prisma.admin.findFirst({\n where: { userId: session.userId },\n select: { ip: true }\n });\n\n if (!admin || admin.ip !== ctx.ip) {\n await revokeSession(\n ctx,\n session.id,\n 'Session revoked: Admin not found or IP mismatch',\n undefined,\n path\n );\n throw new TRPCError({\n message: 'Unauthorized',\n code: 'UNAUTHORIZED'\n });\n }\n }\n\n // Session is valid, proceed with authenticated context\n return next({\n ctx: {\n ...ctx,\n userId: session.userId,\n socketId: session.socketId,\n sessionId: session.id,\n refreshToken\n }\n });\n } catch (err: unknown) {\n if (err instanceof TRPCError && err.code === 'FORBIDDEN') {\n throw err;\n }\n\n // If auth is not required, continue with unauthenticated context\n if (!meta?.authRequired) {\n return next({ ctx: { ...ctx, userId: 0 } });\n }\n\n const errorStack = err instanceof Error ? err.stack : undefined;\n\n if (isTokenExpiredError(err) || isTokenInvalidError(err)) {\n await revokeSession(\n ctx,\n null,\n isTokenInvalidError(err)\n ? 'Session revoked: Token invalid'\n : 'Session revoked: Token expired',\n errorStack,\n path\n );\n throw new TRPCError({\n message: isTokenInvalidError(err)\n ? 'Token invalid'\n : 'Token expired',\n code: 'UNAUTHORIZED'\n });\n }\n\n if (err instanceof TRPCError && err.code === 'UNAUTHORIZED') {\n await revokeSession(\n ctx,\n null,\n 'Session revoked: Unauthorized',\n errorStack,\n path\n );\n throw new TRPCError({\n message: 'Unauthorized',\n code: 'UNAUTHORIZED'\n });\n }\n\n throw err;\n }\n } else {\n // No auth token present\n if (!meta?.authRequired) {\n return next({ ctx: { ...ctx, userId: 0 } });\n }\n\n await revokeSession(\n ctx,\n null,\n 'Session revoked: No token sent',\n undefined,\n path\n );\n throw new TRPCError({ message: 'Unauthorized', code: 'UNAUTHORIZED' });\n }\n });\n\n return authGuard;\n}\n","/**\n * Email service adapter interface\n * Implement this interface to integrate your email service\n */\nexport interface EmailAdapter {\n /**\n * Send email verification email with OTP code\n */\n sendVerificationEmail(email: string, code: string): Promise<void>;\n\n /**\n * Send password reset email with token/link\n */\n sendPasswordResetEmail(email: string, token: string): Promise<void>;\n\n /**\n * Send OTP for passwordless login or 2FA reset\n */\n sendOTPEmail(email: string, otp: number): Promise<void>;\n\n /**\n * Send login notification to existing devices\n */\n sendLoginNotification?(\n email: string,\n browserName: string,\n ip?: string\n ): Promise<void>;\n}\n\n/**\n * No-op email adapter as default\n */\nexport function createNoopEmailAdapter(): EmailAdapter {\n return {\n async sendVerificationEmail(email: string, code: string) {\n console.log(\n `[NoopEmailAdapter] Would send verification email to ${email} with code ${code}`\n );\n },\n async sendPasswordResetEmail(email: string, token: string) {\n console.log(\n `[NoopEmailAdapter] Would send password reset email to ${email} with token ${token}`\n );\n },\n async sendOTPEmail(email: string, otp: number) {\n console.log(\n `[NoopEmailAdapter] Would send OTP email to ${email} with code ${otp}`\n );\n },\n async sendLoginNotification(\n email: string,\n browserName: string,\n ip?: string\n ) {\n console.log(\n `[NoopEmailAdapter] Would send login notification to ${email} from ${browserName} (${ip})`\n );\n }\n };\n}\n\n/**\n * Console email adapter for development - logs emails to console\n */\nexport function createConsoleEmailAdapter(): EmailAdapter {\n return {\n async sendVerificationEmail(email: string, code: string) {\n console.log('\\n=== EMAIL: Verification ===');\n console.log(`To: ${email}`);\n console.log(`Code: ${code}`);\n console.log('===========================\\n');\n },\n async sendPasswordResetEmail(email: string, token: string) {\n console.log('\\n=== EMAIL: Password Reset ===');\n console.log(`To: ${email}`);\n console.log(`Token: ${token}`);\n console.log('=============================\\n');\n },\n async sendOTPEmail(email: string, otp: number) {\n console.log('\\n=== EMAIL: OTP Login ===');\n console.log(`To: ${email}`);\n console.log(`OTP: ${otp}`);\n console.log('========================\\n');\n },\n async sendLoginNotification(\n email: string,\n browserName: string,\n ip?: string\n ) {\n console.log('\\n=== EMAIL: Login Notification ===');\n console.log(`To: ${email}`);\n console.log(`Browser: ${browserName}`);\n console.log(`IP: ${ip || 'Unknown'}`);\n console.log('=================================\\n');\n }\n };\n}\n","import { createNoopEmailAdapter } from '../adapters';\nimport type { CookieSettings } from '../types';\nimport type { AuthConfig, AuthFeatures, TokenSettings } from '../types/config';\n\nexport type { AuthConfig, AuthFeatures, TokenSettings } from '../types/config';\nexport type { OAuthKeys } from './oauth';\n\n/**\n * Default token settings\n */\nexport const defaultTokenSettings: TokenSettings = {\n accessTokenExpiry: '5m',\n passwordResetExpiryMs: 60 * 60 * 1000, // 1 hour\n otpValidityMs: 15 * 60 * 1000 // 15 minutes\n};\n\n/**\n * Default cookie settings\n */\nexport const defaultCookieSettings: CookieSettings = {\n secure: true,\n sameSite: 'Strict',\n httpOnly: true,\n accessTokenPath: '/',\n refreshTokenPath: '/api/trpc/auth.refresh',\n maxAge: 365 * 24 * 60 * 60 // 1 year in seconds\n};\n\n/**\n * Default storage keys\n */\nexport const defaultStorageKeys = {\n accessToken: 'auth-at',\n refreshToken: 'auth-rt'\n};\n\n/**\n * Default feature flags (all optional features disabled)\n */\nexport const defaultFeatures: AuthFeatures = {\n twoFa: true,\n oauth: { google: true, apple: true },\n biometric: false,\n emailVerification: true,\n passwordReset: true,\n otpLogin: true\n};\n\n/**\n * Create a fully resolved auth config with defaults applied\n */\nexport function createAuthConfig(\n config: AuthConfig\n): Required<Omit<AuthConfig, 'hooks' | 'oauthKeys' | 'schemaExtensions'>> &\n AuthConfig {\n const emailService = config.emailService ?? createNoopEmailAdapter();\n return {\n ...config,\n features: { ...defaultFeatures, ...config.features },\n tokenSettings: { ...defaultTokenSettings, ...config.tokenSettings },\n cookieSettings: { ...defaultCookieSettings, ...config.cookieSettings },\n storageKeys: { ...defaultStorageKeys, ...config.storageKeys },\n generateUsername: config.generateUsername ?? (() => `user_${Date.now()}`),\n emailService\n };\n}\n\nexport type ResolvedAuthConfig = ReturnType<typeof createAuthConfig>;\n\n/**\n * Default auth config (requires prisma and secrets to be provided)\n */\nexport const defaultAuthConfig = {\n features: defaultFeatures,\n tokenSettings: defaultTokenSettings,\n cookieSettings: defaultCookieSettings,\n storageKeys: defaultStorageKeys\n};\n","import type { CreateHTTPContextOptions } from '@trpc/server/adapters/standalone';\n\nimport { type AuthCredentials, type CookieSettings } from '../types';\n\n/**\n * Default storage keys for auth cookies\n */\nexport const DEFAULT_STORAGE_KEYS = {\n ACCESS_TOKEN: 'auth-at',\n REFRESH_TOKEN: 'auth-rt'\n};\n\n/**\n * Parse auth tokens from cookie header\n * @param cookieHeader - Raw cookie header string\n * @param storageKeys - Custom storage keys (optional)\n * @returns Parsed tokens\n */\nexport function parseAuthCookies(\n cookieHeader: string | undefined,\n storageKeys: { accessToken: string; refreshToken: string } = {\n accessToken: DEFAULT_STORAGE_KEYS.ACCESS_TOKEN,\n refreshToken: DEFAULT_STORAGE_KEYS.REFRESH_TOKEN\n }\n): { accessToken?: string; refreshToken?: string } {\n if (!cookieHeader) {\n return {};\n }\n const accessToken = cookieHeader\n .split(`${storageKeys.accessToken}=`)[1]\n ?.split(';')[0];\n const refreshToken = cookieHeader\n .split(`${storageKeys.refreshToken}=`)[1]\n ?.split(';')[0];\n\n return {\n accessToken: accessToken || undefined,\n refreshToken: refreshToken || undefined\n };\n}\n\n/**\n * Extract domain from request headers\n * Tries origin header first (for POST/PUT/DELETE), then referer (for GET), then host\n * @param req - HTTP request object\n * @returns Domain hostname or undefined\n */\nfunction extractDomain(\n req: CreateHTTPContextOptions['res']['req']\n): string | undefined {\n // Try origin header first (available for POST/PUT/DELETE requests)\n const origin = req.headers.origin;\n if (origin) {\n try {\n return new URL(origin).hostname;\n } catch {\n // Invalid URL, continue to next option\n }\n }\n\n // Try referer header (available for GET requests)\n const referer = req.headers.referer;\n if (referer) {\n try {\n return new URL(referer).hostname;\n } catch {\n // Invalid URL, continue to next option\n }\n }\n\n // Fall back to host header (always available, but may include port)\n const host = req.headers.host;\n if (host) {\n // Remove port if present (e.g., \"example.com:3000\" -> \"example.com\")\n return host.split(':')[0];\n }\n\n return undefined;\n}\n\n/**\n * Set auth cookies on response\n * @param res - HTTP response object\n * @param credentials - Access and refresh tokens\n * @param settings - Cookie settings\n * @param storageKeys - Storage key names\n */\nexport function setAuthCookies(\n res: CreateHTTPContextOptions['res'],\n credentials: Partial<AuthCredentials>,\n settings: Partial<CookieSettings>,\n storageKeys: { accessToken: string; refreshToken: string } = {\n accessToken: DEFAULT_STORAGE_KEYS.ACCESS_TOKEN,\n refreshToken: DEFAULT_STORAGE_KEYS.REFRESH_TOKEN\n }\n): void {\n const cookies: string[] = [];\n const domain = settings.domain ?? extractDomain(res.req);\n\n const expiresDate = settings.maxAge\n ? new Date(Date.now() + settings.maxAge * 1000).toUTCString()\n : undefined;\n\n if (credentials.refreshToken) {\n const refreshCookie = [\n `${storageKeys.refreshToken}=${credentials.refreshToken}`,\n 'HttpOnly',\n settings.secure ? 'Secure=true' : '',\n `SameSite=${settings.sameSite}`,\n `Path=${settings.refreshTokenPath}`,\n domain ? `Domain=${domain}` : '',\n `Expires=${expiresDate}`\n ]\n .filter(Boolean)\n .join('; ');\n\n cookies.push(refreshCookie);\n }\n\n if (credentials.accessToken) {\n const accessCookie = [\n `${storageKeys.accessToken}=${credentials.accessToken}`,\n settings.secure ? 'Secure=true' : '',\n `SameSite=${settings.sameSite}`,\n `Path=${settings.accessTokenPath}`,\n domain ? `Domain=${domain}` : '',\n `Expires=${expiresDate}`\n ]\n .filter(Boolean)\n .join('; ');\n\n cookies.push(accessCookie);\n }\n\n if (cookies.length > 0) {\n res.setHeader('Set-Cookie', cookies);\n }\n}\n\n/**\n * Clear auth cookies (for logout)\n * @param res - HTTP response object\n * @param settings - Cookie settings\n * @param storageKeys - Storage key names\n */\nexport function clearAuthCookies(\n res: CreateHTTPContextOptions['res'],\n settings: Partial<CookieSettings>,\n storageKeys: { accessToken: string; refreshToken: string } = {\n accessToken: DEFAULT_STORAGE_KEYS.ACCESS_TOKEN,\n refreshToken: DEFAULT_STORAGE_KEYS.REFRESH_TOKEN\n }\n): void {\n const domain = extractDomain(res.req);\n const expiredDate = new Date(0).toUTCString();\n\n const cookies = [\n [\n `${storageKeys.refreshToken}=destroy`,\n 'HttpOnly',\n settings.secure ? 'Secure=true' : '',\n `SameSite=${settings.sameSite}`,\n `Path=${settings.refreshTokenPath}`,\n domain ? `Domain=${domain}` : '',\n `Expires=${expiredDate}`\n ]\n .filter(Boolean)\n .join('; '),\n [\n `${storageKeys.accessToken}=destroy`,\n settings.secure ? 'Secure=true' : '',\n `SameSite=${settings.sameSite}`,\n `Path=${settings.accessTokenPath}`,\n domain ? `Domain=${domain}` : '',\n `Expires=${expiredDate}`\n ]\n .filter(Boolean)\n .join('; ')\n ];\n\n res.setHeader('Set-Cookie', cookies);\n}\n","import jwt, { type SignOptions } from 'jsonwebtoken';\n\nimport type { JwtPayload } from '../types';\n\n/**\n * Options for creating access tokens\n */\nexport interface CreateTokenOptions {\n secret: string;\n expiresIn: SignOptions['expiresIn'];\n}\n\n/**\n * Options for verifying access tokens\n */\nexport interface VerifyTokenOptions {\n secret: string;\n ignoreExpiration?: boolean;\n}\n\n/**\n * Create a JWT access token\n * @param payload - Token payload containing session and user info\n * @param options - Token creation options\n * @returns Signed JWT token\n */\nexport function createAccessToken(\n payload: Omit<JwtPayload, 'exp' | 'iat'>,\n options: CreateTokenOptions\n): string {\n return jwt.sign(payload, options.secret, {\n expiresIn: options.expiresIn\n });\n}\n\n/**\n * Verify and decode a JWT access token\n * @param token - JWT token to verify\n * @param options - Verification options\n * @returns Decoded token payload\n * @throws Error if token is invalid or expired\n */\nexport function verifyAccessToken(\n token: string,\n options: VerifyTokenOptions\n): JwtPayload {\n return jwt.verify(token, options.secret, {\n ignoreExpiration: options.ignoreExpiration ?? false\n }) as JwtPayload;\n}\n\n/**\n * Decode a JWT token without verification\n * @param token - JWT token to decode\n * @returns Decoded payload or null if invalid\n */\nexport function decodeToken(token: string): JwtPayload | null {\n try {\n return jwt.decode(token) as JwtPayload | null;\n } catch {\n return null;\n }\n}\n\n/**\n * JWT error interface\n */\ninterface JwtError extends Error {\n name: 'TokenExpiredError' | 'JsonWebTokenError' | 'NotBeforeError';\n}\n\n/**\n * Check if an error is a JWT error\n */\nfunction isJwtError(error: unknown): error is JwtError {\n return (\n error instanceof Error &&\n ['TokenExpiredError', 'JsonWebTokenError', 'NotBeforeError'].includes(\n error.name\n )\n );\n}\n\n/**\n * Check if a token error is an expiration error\n */\nexport function isTokenExpiredError(error: unknown): boolean {\n return isJwtError(error) && error.name === 'TokenExpiredError';\n}\n\n/**\n * Check if a token error is a validation error\n */\nexport function isTokenInvalidError(error: unknown): boolean {\n return isJwtError(error) && error.name === 'JsonWebTokenError';\n}\n","import { randomUUID } from 'node:crypto';\n\nimport { TRPCError } from '@trpc/server';\nimport { type SignOptions } from 'jsonwebtoken';\n\nimport { type AuthProcedure, type BaseProcedure } from '../types/trpc';\nimport { cleanBase32String, verifyTotp } from '../utilities';\nimport { detectBrowser } from '../utilities/browser';\nimport type { ResolvedAuthConfig } from '../utilities/config';\nimport { clearAuthCookies, setAuthCookies } from '../utilities/cookies';\nimport { createAccessToken } from '../utilities/jwt';\nimport { comparePassword, hashPassword } from '../utilities/password';\nimport type { SchemaExtensions } from '../types/hooks';\nimport {\n changePasswordSchema,\n checkPasswordResetSchema,\n endAllSessionsSchema,\n requestPasswordResetSchema,\n resetPasswordSchema,\n type CreatedSchemas,\n type SignupSchemaInput,\n type LoginSchemaInput\n} from '../validators';\n\n/**\n * Factory for core authentication procedures: register, login, logout,\n * token refresh, session management, and password reset flows.\n */\nexport class BaseProcedureFactory<TExtensions extends SchemaExtensions = {}> {\n constructor(\n private config: ResolvedAuthConfig,\n private procedure: BaseProcedure,\n private authProcedure: AuthProcedure\n ) {}\n\n\n /** Returns all base auth procedures to be merged into the router. */\n createBaseProcedures(schemas: CreatedSchemas<TExtensions>) {\n return {\n register: this.register(schemas.signup),\n login: this.login(schemas.login),\n logout: this.logout(),\n refresh: this.refresh(),\n endAllSessions: this.endAllSessions(),\n changePassword: this.changePassword(),\n sendPasswordResetEmail: this.sendPasswordResetEmail(),\n checkPasswordReset: this.checkPasswordReset(),\n resetPassword: this.resetPassword()\n };\n }\n\n private register(schema: CreatedSchemas<TExtensions>['signup']) {\n return this.procedure\n .input(schema)\n .mutation(async ({ ctx, input }) => {\n const typedInput = input as SignupSchemaInput<TExtensions>;\n const { username, email, password } = typedInput;\n const userAgent = ctx.headers['user-agent'];\n\n if (!userAgent) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'User agent not found'\n });\n }\n\n if (this.config.hooks?.beforeRegister) {\n await this.config.hooks.beforeRegister(typedInput);\n }\n\n const usernameCheck = await this.config.prisma.user.findFirst({\n where: { username: { equals: username, mode: 'insensitive' } }\n });\n\n if (usernameCheck) {\n throw new TRPCError({\n code: 'CONFLICT',\n message: 'An account already exists with that username.'\n });\n }\n\n const emailCheck = await this.config.prisma.user.findFirst({\n where: { email: { equals: email, mode: 'insensitive' } },\n select: { id: true }\n });\n\n if (emailCheck) {\n throw new TRPCError({\n code: 'CONFLICT',\n message: 'An account already exists with that email.'\n });\n }\n\n const hashedPassword = await hashPassword(password);\n\n const user = await this.config.prisma.user.create({\n data: {\n username,\n email,\n password: hashedPassword,\n status: 'ACTIVE',\n tag: this.config.features.biometric ? 'BOT' : 'HUMAN',\n twoFaEnabled: false,\n emailVerificationStatus: 'UNVERIFIED',\n verifiedHumanAt: null\n }\n });\n\n if (this.config.hooks?.onUserCreated) {\n await this.config.hooks.onUserCreated(user.id, typedInput);\n }\n\n const refreshToken = randomUUID();\n const extraSessionData = this.config.hooks?.getSessionData\n ? await this.config.hooks.getSessionData(typedInput)\n : {};\n\n const session = await this.config.prisma.session.create({\n data: {\n userId: user.id,\n browserName: detectBrowser(userAgent),\n socketId: null,\n refreshToken,\n ...extraSessionData\n },\n select: { id: true, refreshToken: true, userId: true }\n });\n\n if (this.config.hooks?.onSessionCreated) {\n await this.config.hooks.onSessionCreated(session.id, typedInput);\n }\n\n const accessToken = createAccessToken(\n { id: session.id, userId: session.userId, verifiedHumanAt: null },\n {\n secret: this.config.secrets.jwt,\n expiresIn: this.config.tokenSettings.accessTokenExpiry as SignOptions['expiresIn']\n }\n );\n\n setAuthCookies(\n ctx.res,\n { accessToken, refreshToken: session.refreshToken! },\n this.config.cookieSettings,\n this.config.storageKeys\n );\n\n return {\n success: true,\n user: { id: user.id, email: user.email, username: user.username }\n };\n });\n }\n\n private login(schema: CreatedSchemas<TExtensions>['login']) {\n return this.procedure\n .input(schema)\n .mutation(async ({ ctx, input }) => {\n const typedInput = input as LoginSchemaInput<TExtensions>;\n const { username, password, code } = typedInput;\n const userAgent = ctx.headers['user-agent'];\n\n if (!userAgent) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'User agent not found'\n });\n }\n\n if (this.config.hooks?.beforeLogin) {\n await this.config.hooks.beforeLogin(typedInput);\n }\n\n const user = await this.config.prisma.user.findFirst({\n where: {\n OR: [\n { email: { equals: username, mode: 'insensitive' } },\n { username: { equals: username, mode: 'insensitive' } }\n ]\n },\n select: {\n id: true,\n status: true,\n password: true,\n twoFaEnabled: true,\n email: true,\n username: true,\n oauthProvider: true,\n verifiedHumanAt: true\n }\n });\n\n if (!user) {\n throw new TRPCError({\n code: 'FORBIDDEN',\n message: 'Invalid credentials.'\n });\n }\n\n if (user.status === 'DEACTIVATED') {\n throw new TRPCError({\n code: 'FORBIDDEN',\n message: 'Your account has been deactivated.'\n });\n }\n\n if (user.status === 'BANNED') {\n throw new TRPCError({\n code: 'FORBIDDEN',\n message: 'Your account has been banned.'\n });\n }\n\n if (!user.password) {\n throw new TRPCError({\n code: 'FORBIDDEN',\n message: `This account uses ${user.oauthProvider?.toLowerCase() || 'social login'}. Please use that method.`\n });\n }\n\n const isMatch = await comparePassword(password, user.password);\n if (!isMatch) {\n throw new TRPCError({\n code: 'FORBIDDEN',\n message: 'Invalid credentials.'\n });\n }\n\n if (user.twoFaEnabled && this.config.features?.twoFa) {\n if (!code) {\n throw new TRPCError({\n code: 'FORBIDDEN',\n message: '2FA code required.'\n });\n }\n\n let validCode = false;\n\n const secrets = await this.config.prisma.session.findMany({\n where: { userId: user.id, twoFaSecret: { not: null } },\n select: { twoFaSecret: true }\n });\n\n for (const s of secrets) {\n if (s.twoFaSecret && (await verifyTotp(code, cleanBase32String(s.twoFaSecret)))) {\n validCode = true;\n break;\n }\n }\n\n if (!validCode) {\n const checkOTP = await this.config.prisma.oTPBasedLogin.findFirst({\n where: {\n code: Number(code),\n userId: user.id,\n disabled: false,\n createdAt: { gte: new Date(Date.now() - this.config.tokenSettings.otpValidityMs) }\n }\n });\n\n if (checkOTP) {\n validCode = true;\n await this.config.prisma.oTPBasedLogin.updateMany({\n where: { code: Number(code) },\n data: { disabled: true }\n });\n }\n }\n\n if (!validCode) {\n throw new TRPCError({\n code: 'FORBIDDEN',\n message: 'Invalid 2FA code.'\n });\n }\n }\n\n const refreshToken = randomUUID();\n const extraSessionData = this.config.hooks?.getSessionData\n ? await this.config.hooks.getSessionData(typedInput)\n : {};\n\n const session = await this.config.prisma.session.create({\n data: {\n userId: user.id,\n browserName: detectBrowser(userAgent),\n socketId: null,\n refreshToken,\n ...extraSessionData\n },\n select: {\n id: true,\n refreshToken: true,\n userId: true,\n socketId: true,\n browserName: true,\n issuedAt: true,\n lastUsed: true,\n revokedAt: true,\n deviceId: true,\n twoFaSecret: true\n }\n });\n\n if (this.config.hooks?.onUserLogin) {\n await this.config.hooks.onUserLogin(user.id, session.id);\n }\n\n if (this.config.hooks?.onSessionCreated) {\n await this.config.hooks.onSessionCreated(session.id, typedInput);\n }\n\n const accessToken = createAccessToken(\n { id: session.id, userId: session.userId, verifiedHumanAt: user.verifiedHumanAt },\n {\n secret: this.config.secrets.jwt,\n expiresIn: this.config.tokenSettings.accessTokenExpiry as SignOptions['expiresIn']\n }\n );\n\n setAuthCookies(\n ctx.res,\n { accessToken, refreshToken: session.refreshToken! },\n this.config.cookieSettings,\n this.config.storageKeys\n );\n\n return {\n success: true,\n user: { id: user.id, email: user.email, username: user.username }\n };\n });\n }\n\n private logout() {\n return this.procedure.mutation(async ({ ctx }) => {\n const { userId, sessionId } = ctx;\n\n if (sessionId) {\n await this.config.prisma.session.update({\n where: { id: sessionId },\n data: { revokedAt: new Date() }\n });\n\n if (userId) {\n await this.config.prisma.user.update({\n where: { id: userId },\n data: { isActive: false }\n });\n }\n\n if (this.config.hooks?.afterLogout) {\n await this.config.hooks.afterLogout(userId, sessionId, ctx.socketId);\n }\n }\n\n clearAuthCookies(ctx.res, this.config.cookieSettings, this.config.storageKeys);\n\n return { success: true };\n });\n }\n\n private refresh() {\n return this.authProcedure\n .meta({ ignoreExpiration: true })\n .query(async ({ ctx }) => {\n const session = await this.config.prisma.session.update({\n where: { id: ctx.sessionId },\n data: { refreshToken: randomUUID(), lastUsed: new Date() },\n select: {\n id: true,\n refreshToken: true,\n userId: true,\n user: { select: { verifiedHumanAt: true } }\n }\n });\n\n if (this.config.hooks?.onRefresh) {\n this.config.hooks.onRefresh(session.userId).catch(() => {});\n }\n\n const accessToken = createAccessToken(\n { id: session.id, userId: session.userId, verifiedHumanAt: session.user.verifiedHumanAt },\n {\n secret: this.config.secrets.jwt,\n expiresIn: this.config.tokenSettings.accessTokenExpiry as SignOptions['expiresIn']\n }\n );\n\n setAuthCookies(\n ctx.res,\n { accessToken, refreshToken: session.refreshToken! },\n this.config.cookieSettings,\n this.config.storageKeys\n );\n\n return { success: true };\n });\n }\n\n private endAllSessions() {\n return this.authProcedure\n .input(endAllSessionsSchema)\n .mutation(async ({ ctx, input }) => {\n const { skipCurrentSession } = input;\n const { userId, sessionId } = ctx;\n\n const sessionsToRevoke = await this.config.prisma.session.findMany({\n where: {\n userId,\n revokedAt: null,\n ...(skipCurrentSession ? { NOT: { id: sessionId } } : {})\n },\n select: { socketId: true, id: true, userId: true }\n });\n\n await this.config.prisma.session.updateMany({\n where: {\n userId,\n revokedAt: null,\n ...(skipCurrentSession ? { NOT: { id: sessionId } } : {})\n },\n data: { revokedAt: new Date() }\n });\n\n for (const session of sessionsToRevoke) {\n if (this.config.hooks?.onSessionRevoked) {\n await this.config.hooks.onSessionRevoked(session.id, session.socketId, 'End all sessions');\n }\n }\n\n if (!skipCurrentSession) {\n await this.config.prisma.user.update({\n where: { id: userId },\n data: { isActive: false }\n });\n }\n\n return { success: true, revokedCount: sessionsToRevoke.length };\n });\n }\n\n private changePassword() {\n return this.authProcedure\n .input(changePasswordSchema)\n .mutation(async ({ ctx, input }) => {\n const { userId, sessionId } = ctx;\n const { currentPassword, newPassword } = input;\n\n if (currentPassword === newPassword) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'New password cannot be the same as current password'\n });\n }\n\n const user = await this.config.prisma.user.findUnique({\n where: { id: userId },\n select: { password: true }\n });\n\n if (!user) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'User not found' });\n }\n\n if (!user.password) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'This account uses social login and cannot change password.'\n });\n }\n\n const isMatch = await comparePassword(currentPassword, user.password);\n if (!isMatch) {\n throw new TRPCError({\n code: 'FORBIDDEN',\n message: 'Current password is incorrect'\n });\n }\n\n const hashedPassword = await hashPassword(newPassword);\n\n await this.config.prisma.user.update({\n where: { id: userId },\n data: { password: hashedPassword }\n });\n\n await this.config.prisma.session.updateMany({\n where: { userId, revokedAt: null, NOT: { id: sessionId } },\n data: { revokedAt: new Date() }\n });\n\n if (this.config.hooks?.onPasswordChanged) {\n await this.config.hooks.onPasswordChanged(userId);\n }\n\n return {\n success: true,\n message: 'Password changed. You will need to re-login on other devices.'\n };\n });\n }\n\n private sendPasswordResetEmail() {\n return this.procedure\n .input(requestPasswordResetSchema)\n .mutation(async ({ input }) => {\n const { email } = input;\n\n const user = await this.config.prisma.user.findFirst({\n where: { email: { equals: email, mode: 'insensitive' }, status: 'ACTIVE' },\n select: { id: true, password: true, email: true }\n });\n\n if (!user) {\n return { message: 'If an account exists with that email, a reset link has been sent.' };\n }\n\n if (!user.password) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'This account uses social login. Please use that method.'\n });\n }\n\n await this.config.prisma.passwordReset.deleteMany({ where: { userId: user.id } });\n\n const passwordReset = await this.config.prisma.passwordReset.create({\n data: { userId: user.id }\n });\n\n if (this.config.emailService) {\n await this.config.emailService.sendPasswordResetEmail(user.email, String(passwordReset.id));\n }\n\n return { message: 'Password reset email sent.' };\n });\n }\n\n private checkPasswordReset() {\n return this.procedure\n .input(checkPasswordResetSchema)\n .query(async ({ input }) => {\n const { token } = input;\n\n const passwordReset = await this.config.prisma.passwordReset.findUnique({\n where: { id: token },\n select: { id: true, createdAt: true, userId: true }\n });\n\n if (!passwordReset) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Invalid reset token.' });\n }\n\n if (passwordReset.createdAt.getTime() + this.config.tokenSettings.passwordResetExpiryMs < Date.now()) {\n await this.config.prisma.passwordReset.delete({ where: { id: token } });\n throw new TRPCError({ code: 'FORBIDDEN', message: 'Reset token expired.' });\n }\n\n return { valid: true };\n });\n }\n\n private resetPassword() {\n return this.procedure\n .input(resetPasswordSchema)\n .mutation(async ({ input }) => {\n const { token, password } = input;\n\n const passwordReset = await this.config.prisma.passwordReset.findFirst({\n where: { id: token },\n select: { id: true, createdAt: true, userId: true }\n });\n\n if (!passwordReset) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Invalid reset token.' });\n }\n\n if (passwordReset.createdAt.getTime() + this.config.tokenSettings.passwordResetExpiryMs < Date.now()) {\n await this.config.prisma.passwordReset.delete({ where: { id: token } });\n throw new TRPCError({ code: 'FORBIDDEN', message: 'Reset token expired.' });\n }\n\n const hashedPassword = await hashPassword(password);\n\n await this.config.prisma.user.update({\n where: { id: passwordReset.userId },\n data: { password: hashedPassword }\n });\n\n await this.config.prisma.passwordReset.delete({ where: { id: token } });\n\n await this.config.prisma.session.updateMany({\n where: { userId: passwordReset.userId },\n data: { revokedAt: new Date() }\n });\n\n return { message: 'Password updated. Please log in with your new password.' };\n });\n }\n}\n","/**\n * Detect browser/platform from user agent string\n * @param userAgent - User agent string from request headers\n * @returns Detected browser name\n */\nexport function detectBrowser(userAgent: string): string {\n // Check if it's an iOS app by looking for specific app-related terms\n if (/cfnetwork|darwin/i.test(userAgent)) return 'iOS App';\n\n // Check for iOS browsers\n if (\n /iphone|ipad|ipod/i.test(userAgent) &&\n /safari/i.test(userAgent) &&\n !/crios|fxios|edg\\//i.test(userAgent)\n ) {\n return 'iOS Browser (Safari)';\n }\n if (/iphone|ipad|ipod/i.test(userAgent) && /crios/i.test(userAgent))\n return 'iOS Browser (Chrome)';\n if (/iphone|ipad|ipod/i.test(userAgent) && /fxios/i.test(userAgent))\n return 'iOS Browser (Firefox)';\n if (/iphone|ipad|ipod/i.test(userAgent) && /edg\\//i.test(userAgent))\n return 'iOS Browser (Edge)';\n\n // Check if it's an Android app\n if (\n /android/i.test(userAgent) &&\n !/chrome|firefox|samsungbrowser|opr\\/|edg\\//i.test(userAgent)\n ) {\n return 'Android App';\n }\n\n // Check for Android browsers\n if (/android/i.test(userAgent) && /chrome/i.test(userAgent))\n return 'Android Browser (Chrome)';\n if (/android/i.test(userAgent) && /firefox/i.test(userAgent))\n return 'Android Browser (Firefox)';\n if (/android/i.test(userAgent) && /samsungbrowser/i.test(userAgent))\n return 'Android Browser (Samsung)';\n if (/android/i.test(userAgent) && /opr\\//i.test(userAgent))\n return 'Android Browser (Opera)';\n if (/android/i.test(userAgent) && /edg\\//i.test(userAgent))\n return 'Android Browser (Edge)';\n\n // Check for common desktop browsers\n if (/chrome|chromium/i.test(userAgent)) return 'Chrome';\n if (/firefox/i.test(userAgent)) return 'Firefox';\n if (/safari/i.test(userAgent) && !/chrome|chromium|crios/i.test(userAgent))\n return 'Safari';\n if (/opr\\//i.test(userAgent)) return 'Opera';\n if (/edg\\//i.test(userAgent)) return 'Edge';\n\n return 'Unknown';\n}\n\n/**\n * Check if the user agent indicates a mobile device\n * @param userAgent - User agent string\n * @returns True if mobile device\n */\nexport function isMobileDevice(userAgent: string): boolean {\n return /android|iphone|ipad|ipod|mobile/i.test(userAgent);\n}\n\n/**\n * Check if the user agent indicates a native app\n * @param userAgent - User agent string\n * @returns True if native app\n */\nexport function isNativeApp(userAgent: string): boolean {\n const browser = detectBrowser(userAgent);\n return browser === 'iOS App' || browser === 'Android App';\n}\n","import appleSignin from 'apple-signin-auth';\nimport { OAuth2Client } from 'google-auth-library';\n\nexport type OAuthProvider = 'GOOGLE' | 'APPLE';\n\nexport interface OAuthResult {\n email: string;\n oauthId: string;\n}\n\n/**\n * OAuth keys configuration for Google and Apple providers\n */\nexport interface OAuthKeys {\n google?: {\n clientId: string;\n clientSecret?: string;\n iosClientId?: string;\n };\n apple?: {\n clientId: string;\n iosClientId?: string;\n };\n}\n\n/**\n * OAuth verification error\n */\nexport class OAuthVerificationError extends Error {\n constructor(\n message: string,\n public readonly statusCode = 401\n ) {\n super(message);\n this.name = 'OAuthVerificationError';\n }\n}\n\n/**\n * Creates an OAuth token verifier with the provided keys\n * @param keys OAuth provider keys configuration\n * @returns A function to verify OAuth tokens\n */\nexport function createOAuthVerifier(keys: OAuthKeys) {\n let googleClient: OAuth2Client | null = null;\n if (keys.google?.clientId) {\n googleClient = new OAuth2Client({\n clientId: keys.google.clientId,\n clientSecret: keys.google.clientSecret\n });\n }\n\n return async function verifyOAuthToken(\n provider: OAuthProvider,\n token: string,\n extra?: { email?: string }\n ): Promise<OAuthResult> {\n if (provider === 'GOOGLE') {\n if (!keys.google?.clientId) {\n throw new OAuthVerificationError(\n 'Google OAuth configuration missing',\n 500\n );\n }\n\n if (!googleClient) {\n throw new OAuthVerificationError(\n 'Google OAuth client not initialized',\n 500\n );\n }\n\n const audience = [keys.google.clientId];\n if (keys.google.iosClientId) {\n audience.push(keys.google.iosClientId);\n }\n\n const ticket = await googleClient.verifyIdToken({\n idToken: token,\n audience\n });\n\n const payload = ticket.getPayload();\n if (!payload?.sub || !payload.email) {\n throw new OAuthVerificationError('Invalid Google token', 401);\n }\n\n return {\n oauthId: payload.sub,\n email: payload.email\n };\n }\n\n if (provider === 'APPLE') {\n if (!keys.apple?.clientId) {\n throw new OAuthVerificationError(\n 'Apple OAuth configuration missing',\n 500\n );\n }\n\n const audience = [keys.apple.clientId];\n if (keys.apple.iosClientId) {\n audience.push(keys.apple.iosClientId);\n }\n\n const { sub, email } = await appleSignin.verifyIdToken(token, {\n audience,\n ignoreExpiration: false\n });\n\n const finalEmail = email || extra?.email;\n if (!finalEmail || !sub) {\n throw new OAuthVerificationError('Invalid Apple token', 401);\n }\n\n return {\n oauthId: sub,\n email: finalEmail\n };\n }\n\n throw new OAuthVerificationError('Unsupported OAuth provider', 400);\n };\n}\n","import bcrypt from 'bcryptjs';\n\n/**\n * Default salt rounds for password hashing\n */\nconst DEFAULT_SALT_ROUNDS = 10;\n\n/**\n * Hash a plain text password\n * @param password - Plain text password\n * @param saltRounds - Number of salt rounds (default: 10)\n * @returns Hashed password\n */\nexport async function hashPassword(\n password: string,\n saltRounds: number = DEFAULT_SALT_ROUNDS\n): Promise<string> {\n const salt = await bcrypt.genSalt(saltRounds);\n return bcrypt.hash(password, salt);\n}\n\n/**\n * Compare a plain text password with a hashed password\n * @param password - Plain text password\n * @param hashedPassword - Hashed password to compare against\n * @returns True if passwords match\n */\nexport async function comparePassword(\n password: string,\n hashedPassword: string\n): Promise<boolean> {\n return bcrypt.compare(password, hashedPassword);\n}\n\n/**\n * Check if a password meets minimum requirements\n * @param password - Password to validate\n * @param minLength - Minimum length (default: 6)\n * @returns Validation result with error message if invalid\n */\nexport function validatePasswordStrength(\n password: string,\n minLength = 6\n): { valid: boolean; error?: string } {\n if (password.length < minLength) {\n return {\n valid: false,\n error: `Password must be at least ${minLength} characters`\n };\n }\n return { valid: true };\n}\n","import crypto from 'crypto';\nimport { TOTP } from 'totp-generator';\n\n/**\n * Base32 character set for TOTP secret generation\n */\nconst BASE32_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';\n\n/**\n * Generate a random TOTP secret\n * @param length - Length of the secret (default: 16)\n * @returns Base32 encoded secret\n */\nexport function generateTotpSecret(length = 16): string {\n let secret = '';\n for (let i = 0; i < length; i++) {\n const randIndex = Math.floor(Math.random() * BASE32_CHARS.length);\n secret += BASE32_CHARS[randIndex];\n }\n return secret;\n}\n\n/**\n * Clean a Base32 string by removing invalid characters\n * @param input - Input string to clean\n * @returns Cleaned Base32 string\n */\nexport function cleanBase32String(input: string): string {\n return input.replace(/[^A-Z2-7]/gi, '').toUpperCase();\n}\n\n/**\n * Generate a TOTP code from a secret\n * @param secret - Base32 encoded secret\n * @returns Current TOTP code\n */\nexport async function generateTotpCode(secret: string) {\n const cleanSecret = cleanBase32String(secret);\n const { otp } = await TOTP.generate(cleanSecret);\n return otp;\n}\n\n/**\n * Verify a TOTP code against a secret\n * @param code - TOTP code to verify\n * @param secret - Base32 encoded secret\n * @param window - Number of time steps to check before/after current (default: 1)\n * @returns True if code is valid\n */\nexport async function verifyTotp(code: string, secret: string) {\n const cleanSecret = cleanBase32String(secret);\n const normalizedCode = code.replace(/\\s/g, '');\n const { otp } = await TOTP.generate(cleanSecret);\n return otp === normalizedCode;\n}\n\n/**\n * Generate a random OTP code (for email-based verification)\n * @param min - Minimum value (default: 100000)\n * @param max - Maximum value (default: 999999)\n * @returns Random 6-digit OTP\n */\nexport function generateOtp(min = 100000, max = 999999): number {\n return Math.floor(crypto.randomInt(min, max + 1));\n}\n","import { TRPCError } from '@trpc/server';\n\nimport { type AuthProcedure } from '../types/trpc';\nimport type { ResolvedAuthConfig } from '../utilities/config';\nimport { biometricVerifySchema } from '../validators';\n\n/** Factory for biometric verification procedures. */\nexport class BiometricProcedureFactory {\n constructor(\n private config: ResolvedAuthConfig,\n private authProcedure: AuthProcedure\n ) {}\n\n createBiometricProcedures() {\n return {\n verifyBiometric: this.verifyBiometric(),\n getBiometricStatus: this.getBiometricStatus()\n };\n }\n\n private checkConfig() {\n if (!this.config.features.biometric) {\n throw new TRPCError({ code: 'NOT_FOUND' });\n }\n }\n\n private verifyBiometric() {\n return this.authProcedure\n .input(biometricVerifySchema)\n .mutation(async ({ ctx }) => {\n this.checkConfig();\n const { userId } = ctx;\n\n await this.config.prisma.user.update({\n where: { id: userId },\n data: { verifiedHumanAt: new Date(), tag: 'HUMAN' }\n });\n\n if (this.config.hooks?.onBiometricVerified) {\n await this.config.hooks.onBiometricVerified(userId);\n }\n\n return { success: true, verifiedAt: new Date() };\n });\n }\n\n private getBiometricStatus() {\n return this.authProcedure.query(async ({ ctx }) => {\n this.checkConfig();\n const { userId } = ctx;\n\n const user = await this.config.prisma.user.findUnique({\n where: { id: userId },\n select: { verifiedHumanAt: true }\n });\n\n if (!user) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'User not found' });\n }\n\n let timeoutMs: number | null = null;\n if (this.config.hooks?.getBiometricTimeout) {\n timeoutMs = await this.config.hooks.getBiometricTimeout();\n }\n\n let isExpired = false;\n if (user.verifiedHumanAt && timeoutMs !== null) {\n const expiresAt = new Date(user.verifiedHumanAt.getTime() + timeoutMs);\n isExpired = new Date() > expiresAt;\n }\n\n return {\n verifiedHumanAt: user.verifiedHumanAt,\n isVerified: !!user.verifiedHumanAt && !isExpired,\n isExpired,\n requiresVerification: timeoutMs !== null\n };\n });\n }\n}\n","import { randomUUID } from 'node:crypto';\n\nimport { TRPCError } from '@trpc/server';\n\nimport { type AuthProcedure } from '../types/trpc';\nimport type { ResolvedAuthConfig } from '../utilities/config';\nimport { verifyEmailSchema } from '../validators';\n\n/** Factory for email verification procedures. */\nexport class EmailVerificationProcedureFactory {\n constructor(\n private config: ResolvedAuthConfig,\n private authProcedure: AuthProcedure\n ) {}\n\n createEmailVerificationProcedures() {\n return {\n sendVerificationEmail: this.sendVerificationEmail(),\n verifyEmail: this.verifyEmail(),\n getVerificationStatus: this.getVerificationStatus()\n };\n }\n\n private checkConfig() {\n if (!this.config.features.emailVerification) {\n throw new TRPCError({ code: 'NOT_FOUND' });\n }\n }\n\n private sendVerificationEmail() {\n return this.authProcedure.mutation(async ({ ctx }) => {\n this.checkConfig();\n const { userId } = ctx;\n\n const user = await this.config.prisma.user.findUnique({\n where: { id: userId, status: 'ACTIVE' },\n select: { id: true, email: true, emailVerificationStatus: true }\n });\n\n if (!user) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'User not found' });\n }\n\n if (user.emailVerificationStatus === 'VERIFIED') {\n return { message: 'Email is already verified', emailSent: false };\n }\n\n const otp = randomUUID();\n\n await this.config.prisma.user.update({\n where: { id: userId },\n data: { emailVerificationStatus: 'PENDING', otpForEmailVerification: otp }\n });\n\n if (this.config.emailService) {\n try {\n await this.config.emailService.sendVerificationEmail(user.email, otp);\n return { message: 'Verification email sent', emailSent: true };\n } catch {\n return { message: 'Failed to send email', emailSent: false };\n }\n }\n\n return { message: 'Email service not configured', emailSent: false };\n });\n }\n\n private verifyEmail() {\n return this.authProcedure\n .input(verifyEmailSchema)\n .mutation(async ({ ctx, input }) => {\n this.checkConfig();\n const { userId } = ctx;\n const { code } = input;\n\n const user = await this.config.prisma.user.findUnique({\n where: { id: userId, status: 'ACTIVE' },\n select: { id: true, emailVerificationStatus: true, otpForEmailVerification: true }\n });\n\n if (!user) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'User not found' });\n }\n\n if (user.emailVerificationStatus === 'VERIFIED') {\n return { success: true, message: 'Email is already verified' };\n }\n\n if (code !== user.otpForEmailVerification) {\n throw new TRPCError({ code: 'BAD_REQUEST', message: 'Invalid verification code' });\n }\n\n await this.config.prisma.user.update({\n where: { id: userId },\n data: { emailVerificationStatus: 'VERIFIED', otpForEmailVerification: null }\n });\n\n if (this.config.hooks?.onEmailVerified) {\n await this.config.hooks.onEmailVerified(userId);\n }\n\n return { success: true, message: 'Email verified' };\n });\n }\n\n private getVerificationStatus() {\n return this.authProcedure.query(async ({ ctx }) => {\n this.checkConfig();\n const { userId } = ctx;\n\n const user = await this.config.prisma.user.findUnique({\n where: { id: userId },\n select: { emailVerificationStatus: true, email: true }\n });\n\n if (!user) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'User not found' });\n }\n\n return {\n email: user.email,\n status: user.emailVerificationStatus,\n isVerified: user.emailVerificationStatus === 'VERIFIED'\n };\n });\n }\n}\n","import { randomUUID } from 'node:crypto';\n\nimport { TRPCError } from '@trpc/server';\nimport { type SignOptions } from 'jsonwebtoken';\n\nimport type { SchemaExtensions } from '../types/hooks';\nimport { type BaseProcedure } from '../types/trpc';\nimport { createAccessToken, detectBrowser, setAuthCookies } from '../utilities';\nimport type { ResolvedAuthConfig } from '../utilities/config';\nimport {\n createOAuthVerifier,\n type OAuthProvider,\n type OAuthResult\n} from '../utilities/oauth';\nimport { type CreatedSchemas, type OAuthSchemaInput } from '../validators';\n\n/** Factory for OAuth login procedures (Google, Apple). */\nexport class OAuthLoginProcedureFactory<TExtensions extends SchemaExtensions = {}> {\n private verifyOAuthToken:\n | ((provider: OAuthProvider, token: string, extra?: { email?: string }) => Promise<OAuthResult>)\n | null = null;\n\n constructor(\n private config: ResolvedAuthConfig,\n private procedure: BaseProcedure\n ) {\n if (config.oauthKeys) {\n this.verifyOAuthToken = createOAuthVerifier(config.oauthKeys);\n }\n }\n\n createOAuthLoginProcedures(schemas: CreatedSchemas<TExtensions>) {\n return { oAuthLogin: this.oAuthLogin(schemas.oauth) };\n }\n\n private checkConfig() {\n if (!this.config.features.oauth?.google && !this.config.features.oauth?.apple) {\n throw new TRPCError({ code: 'NOT_FOUND' });\n }\n }\n\n private oAuthLogin(schema: CreatedSchemas<TExtensions>['oauth']) {\n return this.procedure\n .input(schema)\n .mutation(async ({ ctx, input }) => {\n this.checkConfig();\n\n const typedInput = input as OAuthSchemaInput<TExtensions>;\n const { idToken, user: appleUser, provider } = typedInput;\n const userAgent = ctx.headers['user-agent'];\n\n if (!userAgent) {\n throw new TRPCError({ code: 'BAD_REQUEST', message: 'User agent not found' });\n }\n\n if (!this.verifyOAuthToken) {\n throw new TRPCError({\n code: 'INTERNAL_SERVER_ERROR',\n message: 'OAuth not configured. Provide oauthKeys in config.'\n });\n }\n\n const { email, oauthId } = await this.verifyOAuthToken(provider, idToken, appleUser);\n\n if (!email) {\n throw new TRPCError({ code: 'BAD_REQUEST', message: 'Email not provided by OAuth provider' });\n }\n\n let user = await this.config.prisma.user.findFirst({\n where: {\n OR: [\n { email: { equals: email, mode: 'insensitive' } },\n { oauthId: { equals: oauthId } }\n ]\n },\n select: {\n id: true,\n status: true,\n email: true,\n username: true,\n password: true,\n oauthProvider: true,\n oauthId: true,\n twoFaEnabled: true,\n verifiedHumanAt: true,\n emailVerificationStatus: true\n }\n });\n\n if (user?.oauthProvider && user.oauthProvider !== provider) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: `This email uses ${user.oauthProvider.toLowerCase()} sign-in.`\n });\n }\n\n if (user && !user.oauthProvider && user.password) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'This email uses password login. Please use email/password.'\n });\n }\n\n if (!user) {\n const generateUsername = this.config.generateUsername ?? (() => `user_${Date.now()}`);\n\n user = await this.config.prisma.user.create({\n data: {\n username: generateUsername(),\n email,\n password: null,\n emailVerificationStatus: 'VERIFIED',\n oauthProvider: provider,\n oauthId,\n status: 'ACTIVE',\n tag: this.config.features.biometric ? 'BOT' : 'HUMAN',\n twoFaEnabled: false,\n verifiedHumanAt: null\n }\n });\n\n if (this.config.hooks?.onUserCreated) {\n await this.config.hooks.onUserCreated(user.id, typedInput);\n }\n\n if (this.config.hooks?.onOAuthLinked) {\n await this.config.hooks.onOAuthLinked(user.id, provider);\n }\n }\n\n if (user.status === 'DEACTIVATED') {\n throw new TRPCError({ code: 'FORBIDDEN', message: 'Your account has been deactivated.' });\n }\n\n if (user.status === 'BANNED') {\n throw new TRPCError({ code: 'FORBIDDEN', message: 'Your account has been banned.' });\n }\n\n const refreshToken = randomUUID();\n const extraSessionData = this.config.hooks?.getSessionData\n ? await this.config.hooks.getSessionData(typedInput)\n : {};\n\n const session = await this.config.prisma.session.create({\n data: {\n userId: user.id,\n browserName: detectBrowser(userAgent),\n socketId: null,\n refreshToken,\n ...extraSessionData\n },\n select: {\n id: true,\n refreshToken: true,\n userId: true,\n socketId: true,\n browserName: true,\n issuedAt: true,\n lastUsed: true,\n revokedAt: true,\n deviceId: true,\n twoFaSecret: true\n }\n });\n\n if (this.config.hooks?.onUserLogin) {\n await this.config.hooks.onUserLogin(user.id, session.id);\n }\n\n if (this.config.hooks?.onSessionCreated) {\n await this.config.hooks.onSessionCreated(session.id, typedInput);\n }\n\n const accessToken = createAccessToken(\n { id: session.id, userId: session.userId, verifiedHumanAt: user.verifiedHumanAt ?? null },\n {\n secret: this.config.secrets.jwt,\n expiresIn: this.config.tokenSettings.accessTokenExpiry as SignOptions['expiresIn']\n }\n );\n\n setAuthCookies(\n ctx.res,\n { accessToken, refreshToken: session.refreshToken! },\n this.config.cookieSettings,\n this.config.storageKeys\n );\n\n return {\n success: true,\n user: { id: user.id, email: user.email, username: user.username }\n };\n });\n }\n}\n","import { TRPCError } from '@trpc/server';\n\nimport { type AuthProcedure, type BaseProcedure } from '../types/trpc';\nimport type { ResolvedAuthConfig } from '../utilities/config';\nimport { comparePassword } from '../utilities/password';\nimport {\n cleanBase32String,\n generateOtp,\n generateTotpSecret,\n verifyTotp\n} from '../utilities/totp';\nimport {\n deregisterPushTokenSchema,\n disableTwofaSchema,\n getTwofaSecretSchema,\n registerPushTokenSchema,\n twoFaResetSchema,\n twoFaResetVerifySchema\n} from '../validators';\n\n/** Factory for 2FA procedures: enable/disable, TOTP secrets, and reset flows. */\nexport class TwoFaProcedureFactory {\n constructor(\n private config: ResolvedAuthConfig,\n private procedure: BaseProcedure,\n private authProcedure: AuthProcedure\n ) {}\n\n createTwoFaProcedures() {\n return {\n enableTwofa: this.enableTwofa(),\n disableTwofa: this.disableTwofa(),\n getTwofaSecret: this.getTwofaSecret(),\n twoFaReset: this.twoFaReset(),\n twoFaResetVerify: this.twoFaResetVerify(),\n registerPushToken: this.registerPushToken(),\n deregisterPushToken: this.deregisterPushToken()\n };\n }\n\n private checkConfig() {\n if (!this.config.features.twoFa) {\n throw new TRPCError({ code: 'NOT_FOUND' });\n }\n }\n\n private enableTwofa() {\n return this.authProcedure.mutation(async ({ ctx }) => {\n this.checkConfig();\n const { userId, sessionId } = ctx;\n\n const user = await this.config.prisma.user.findFirst({\n where: { id: userId },\n select: { twoFaEnabled: true, oauthProvider: true, password: true }\n });\n\n if (!user) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'User not found.' });\n }\n\n if (user.oauthProvider) {\n throw new TRPCError({\n code: 'FORBIDDEN',\n message: '2FA is not available for social login accounts.'\n });\n }\n\n if (user.twoFaEnabled) {\n throw new TRPCError({ code: 'BAD_REQUEST', message: '2FA already enabled.' });\n }\n\n const checkSession = await this.config.prisma.session.findFirst({\n where: { userId, id: sessionId },\n select: { deviceId: true }\n });\n\n if (!checkSession?.deviceId) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'You must be logged in on mobile to enable 2FA.'\n });\n }\n\n await this.config.prisma.session.updateMany({\n where: { userId, revokedAt: null, NOT: { id: sessionId } },\n data: { revokedAt: new Date() }\n });\n\n await this.config.prisma.session.updateMany({\n where: { userId, NOT: { id: sessionId } },\n data: { twoFaSecret: null }\n });\n\n const secret = generateTotpSecret();\n\n await this.config.prisma.user.update({\n where: { id: userId },\n data: { twoFaEnabled: true }\n });\n\n await this.config.prisma.session.update({\n where: { id: sessionId },\n data: { twoFaSecret: secret }\n });\n\n if (this.config.hooks?.onTwoFaStatusChanged) {\n await this.config.hooks.onTwoFaStatusChanged(userId, true);\n }\n\n return { secret };\n });\n }\n\n private disableTwofa() {\n return this.authProcedure\n .input(disableTwofaSchema)\n .mutation(async ({ ctx, input }) => {\n this.checkConfig();\n const { userId, sessionId } = ctx;\n const { password } = input;\n\n const user = await this.config.prisma.user.findFirst({\n where: { id: userId },\n select: { password: true, status: true, oauthProvider: true }\n });\n\n if (!user) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'User not found.' });\n }\n\n if (user.status !== 'ACTIVE') {\n throw new TRPCError({ code: 'FORBIDDEN', message: 'Account deactivated.' });\n }\n\n if (user.oauthProvider) {\n throw new TRPCError({\n code: 'FORBIDDEN',\n message: '2FA is not available for social login accounts.'\n });\n }\n\n if (!user.password) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'Cannot verify password for social login account.'\n });\n }\n\n const isMatch = await comparePassword(password, user.password);\n if (!isMatch) {\n throw new TRPCError({ code: 'FORBIDDEN', message: 'Incorrect password.' });\n }\n\n await this.config.prisma.user.update({\n where: { id: userId },\n data: { twoFaEnabled: false }\n });\n\n await this.config.prisma.session.update({\n where: { id: sessionId },\n data: { twoFaSecret: null }\n });\n\n if (this.config.hooks?.onTwoFaStatusChanged) {\n await this.config.hooks.onTwoFaStatusChanged(userId, false);\n }\n\n return { disabled: true };\n });\n }\n\n private getTwofaSecret() {\n return this.authProcedure\n .input(getTwofaSecretSchema)\n .query(async ({ ctx, input }) => {\n this.checkConfig();\n const { userId, sessionId } = ctx;\n const { pushCode } = input;\n\n const user = await this.config.prisma.user.findFirst({\n where: { id: userId },\n select: { twoFaEnabled: true, oauthProvider: true }\n });\n\n if (user?.oauthProvider) {\n throw new TRPCError({\n code: 'FORBIDDEN',\n message: '2FA is not available for social login accounts.'\n });\n }\n\n if (!user?.twoFaEnabled) {\n throw new TRPCError({ code: 'BAD_REQUEST', message: '2FA not enabled.' });\n }\n\n const session = await this.config.prisma.session.findUnique({\n where: { id: sessionId, userId },\n select: { twoFaSecret: true, device: { select: { pushToken: true } } }\n });\n\n if (!session?.device) {\n throw new TRPCError({ code: 'BAD_REQUEST', message: 'Invalid request' });\n }\n\n const expectedCode = await verifyTotp(pushCode, cleanBase32String(session.device.pushToken));\n if (!expectedCode) {\n throw new TRPCError({ code: 'BAD_REQUEST', message: 'Invalid request' });\n }\n\n if (session.twoFaSecret) {\n return { secret: session.twoFaSecret };\n }\n\n const secret = generateTotpSecret();\n await this.config.prisma.session.update({\n where: { id: sessionId },\n data: { twoFaSecret: secret }\n });\n return { secret };\n });\n }\n\n private twoFaReset() {\n return this.procedure\n .input(twoFaResetSchema)\n .mutation(async ({ input }) => {\n this.checkConfig();\n const { username, password } = input;\n\n const user = await this.config.prisma.user.findFirst({\n where: { username: { equals: username, mode: 'insensitive' }, twoFaEnabled: true },\n select: { id: true, password: true, email: true }\n });\n\n if (!user) {\n throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Invalid credentials.' });\n }\n\n if (!user.password) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'Social login accounts cannot use 2FA reset.'\n });\n }\n\n const isMatch = await comparePassword(password, user.password);\n if (!isMatch) {\n throw new TRPCError({ code: 'FORBIDDEN', message: 'Invalid credentials.' });\n }\n\n const otp = generateOtp();\n await this.config.prisma.oTPBasedLogin.create({\n data: { userId: user.id, code: otp }\n });\n\n if (this.config.emailService) {\n await this.config.emailService.sendOTPEmail(user.email, otp);\n }\n\n return { success: true };\n });\n }\n\n private twoFaResetVerify() {\n return this.procedure\n .input(twoFaResetVerifySchema)\n .mutation(async ({ input }) => {\n this.checkConfig();\n const { code, username } = input;\n\n const user = await this.config.prisma.user.findFirst({\n where: { username: { equals: username, mode: 'insensitive' } },\n select: { id: true }\n });\n\n if (!user) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'User not found' });\n }\n\n const otp = await this.config.prisma.oTPBasedLogin.findFirst({\n where: {\n userId: user.id,\n code,\n disabled: false,\n createdAt: { gte: new Date(Date.now() - this.config.tokenSettings.otpValidityMs) }\n }\n });\n\n if (!otp) {\n throw new TRPCError({ code: 'FORBIDDEN', message: 'Invalid or expired OTP' });\n }\n\n await this.config.prisma.oTPBasedLogin.update({\n where: { id: otp.id },\n data: { disabled: true }\n });\n\n await this.config.prisma.user.update({\n where: { id: user.id },\n data: { twoFaEnabled: false }\n });\n\n await this.config.prisma.session.updateMany({\n where: { userId: user.id },\n data: { twoFaSecret: null }\n });\n\n return { success: true, message: '2FA has been reset.' };\n });\n }\n\n private registerPushToken() {\n return this.authProcedure\n .input(registerPushTokenSchema)\n .mutation(async ({ ctx, input }) => {\n this.checkConfig();\n const { userId, sessionId } = ctx;\n const { pushToken } = input;\n\n await this.config.prisma.session.updateMany({\n where: {\n userId,\n id: { not: sessionId },\n revokedAt: null,\n device: { pushToken }\n },\n data: { revokedAt: new Date() }\n });\n\n const checkDevice = await this.config.prisma.device.findFirst({\n where: {\n pushToken,\n sessions: { some: { id: sessionId } },\n users: { some: { id: userId } }\n },\n select: { id: true }\n });\n\n if (!checkDevice) {\n await this.config.prisma.device.upsert({\n where: { pushToken },\n create: {\n pushToken,\n sessions: { connect: { id: sessionId } },\n users: { connect: { id: userId } }\n },\n update: {\n sessions: { connect: { id: sessionId } },\n users: { connect: { id: userId } }\n }\n });\n }\n\n return { registered: true };\n });\n }\n\n private deregisterPushToken() {\n return this.authProcedure\n .meta({ ignoreExpiration: true })\n .input(deregisterPushTokenSchema)\n .mutation(async ({ ctx, input }) => {\n this.checkConfig();\n const { userId } = ctx;\n const { pushToken } = input;\n\n const device = await this.config.prisma.device.findFirst({\n where: {\n ...(userId !== 0 && { users: { some: { id: userId } } }),\n pushToken\n },\n select: { id: true }\n });\n\n if (device) {\n await this.config.prisma.device.delete({\n where: { id: device.id }\n });\n }\n\n return { deregistered: true };\n });\n }\n}\n","import { initTRPC } from '@trpc/server';\nimport { type IncomingMessage } from 'http';\nimport SuperJSON from 'superjson';\nimport { ZodError } from 'zod';\n\nimport { type createAuthGuard } from '../middleware/authGuard';\nimport { type Meta, type TrpcBuilder, type TrpcContext } from '../types/trpc';\nimport { type ResolvedAuthConfig } from './config';\n\n/**\n * Checks if an error is a Prisma connection error (infrastructure issue).\n * Connection errors are P1000-P1003:\n * - P1000: Authentication failed\n * - P1001: Can't reach database server\n * - P1002: Database server timeout\n * - P1003: Database does not exist\n */\nfunction isPrismaConnectionError(error: unknown): boolean {\n if (!error || typeof error !== 'object') {\n return false;\n }\n\n // Check for Prisma error code\n const errorCode = (error as { code?: string }).code;\n if (errorCode && typeof errorCode === 'string') {\n const codeMatch = errorCode.match(/^P(\\d+)$/);\n if (codeMatch) {\n const codeNum = parseInt(codeMatch[1], 10);\n if (codeNum >= 1000 && codeNum <= 1003) {\n return true;\n }\n }\n }\n\n // Check error constructor name for Prisma connection errors\n const constructorName = error.constructor?.name || '';\n if (constructorName.includes('Prisma')) {\n const errorMessage =\n (error as { message?: string }).message?.toLowerCase() || '';\n if (\n errorMessage.includes(\"can't reach database\") ||\n errorMessage.includes('authentication failed') ||\n errorMessage.includes('database server') ||\n errorMessage.includes('timeout') ||\n errorMessage.includes('connection')\n ) {\n return true;\n }\n }\n\n // Check error.cause recursively\n const cause = (error as { cause?: unknown }).cause;\n if (cause) {\n return isPrismaConnectionError(cause);\n }\n\n return false;\n}\n\nexport function createTrpcBuilder(config: ResolvedAuthConfig) {\n return initTRPC\n .context<TrpcContext>()\n .meta<Meta>()\n .create({\n transformer: SuperJSON,\n errorFormatter: (opts) => {\n const { shape, error } = opts;\n\n const { stack: _stack, ...safeData } = shape.data;\n\n // Handle 500 errors\n if (error.code === 'INTERNAL_SERVER_ERROR') {\n if (config.hooks?.logError) {\n const errorType =\n isPrismaConnectionError(error) ||\n isPrismaConnectionError(error.cause)\n ? 'DATABASE_ERROR'\n : 'SERVER_ERROR';\n\n config.hooks\n .logError({\n type: errorType,\n description: error.message,\n stack: error.stack || 'No stack trace',\n ip: opts.ctx?.ip,\n userId: opts.ctx?.userId ?? null\n })\n .catch(() => {\n // Silently fail - error logging should never throw\n });\n }\n\n // Customize the error message for users\n return {\n ...shape,\n message: 'An unexpected error occurred. Please try again later.',\n data: {\n ...safeData,\n zodError:\n error.cause instanceof ZodError ? error.cause.flatten() : null\n }\n };\n }\n\n return {\n ...shape,\n data: {\n ...safeData,\n zodError:\n error.cause instanceof ZodError ? error.cause.flatten() : null\n }\n };\n }\n });\n}\n\nexport function createBaseProcedure(\n t: TrpcBuilder,\n authGuard: ReturnType<typeof createAuthGuard>\n) {\n return t.procedure.use(authGuard);\n}\n\nexport function getClientIp(req: IncomingMessage): string | undefined {\n // Check for the X-Forwarded-For header\n const forwarded = req.headers['x-forwarded-for'] as string | undefined;\n\n if (forwarded) {\n return forwarded.split(',')[0]?.trim();\n }\n\n // Fallback to the connection's remote address\n return req.socket.remoteAddress || undefined;\n}\n","import { type CreateHTTPContextOptions } from '@trpc/server/adapters/standalone';\n\nimport { createAuthGuard } from './middleware/authGuard';\nimport { BaseProcedureFactory } from './procedures/base';\nimport { BiometricProcedureFactory } from './procedures/biometric';\nimport { EmailVerificationProcedureFactory } from './procedures/emailVerification';\nimport { OAuthLoginProcedureFactory } from './procedures/oauth';\nimport { TwoFaProcedureFactory } from './procedures/twoFa';\nimport type { SchemaExtensions } from './types/hooks';\nimport {\n type AuthProcedure,\n type BaseProcedure,\n type TrpcContext\n} from './types/trpc';\nimport type { AuthConfig, ResolvedAuthConfig } from './utilities/config';\nimport { createAuthConfig } from './utilities/config';\nimport {\n createBaseProcedure,\n createTrpcBuilder,\n getClientIp\n} from './utilities/trpc';\nimport { createSchemas, type CreatedSchemas } from './validators';\n\nexport const createContext = ({\n req,\n res\n}: CreateHTTPContextOptions): TrpcContext => ({\n headers: req.headers,\n userId: null,\n sessionId: null,\n refreshToken: null,\n socketId: null,\n ip: getClientIp(req),\n res\n});\n\nclass AuthRouterFactory<TExtensions extends SchemaExtensions = {}> {\n private config: ResolvedAuthConfig;\n private schemas: CreatedSchemas<TExtensions>;\n t: ReturnType<typeof createTrpcBuilder>;\n private authGuard: ReturnType<typeof createAuthGuard>;\n procedure: BaseProcedure;\n authProcedure: AuthProcedure;\n constructor(private userConfig: AuthConfig<TExtensions>) {\n this.config = createAuthConfig(this.userConfig);\n this.schemas = createSchemas<TExtensions>(\n this.config.schemaExtensions as TExtensions\n );\n this.t = createTrpcBuilder(this.config);\n this.authGuard = createAuthGuard(this.config, this.t);\n this.procedure = createBaseProcedure(this.t, this.authGuard);\n this.authProcedure = this.procedure.meta({ authRequired: true });\n }\n\n createRouter() {\n const baseRoutes = new BaseProcedureFactory<TExtensions>(\n this.config,\n this.procedure,\n this.authProcedure\n );\n const biometricRoutes = new BiometricProcedureFactory(\n this.config,\n this.authProcedure\n );\n const emailVerificationRoutes = new EmailVerificationProcedureFactory(\n this.config,\n this.authProcedure\n );\n const oAuthLoginRoutes = new OAuthLoginProcedureFactory<TExtensions>(\n this.config,\n this.procedure\n );\n const twoFaRoutes = new TwoFaProcedureFactory(\n this.config,\n this.procedure,\n this.authProcedure\n );\n\n return this.t.router({\n ...baseRoutes.createBaseProcedures(this.schemas),\n ...oAuthLoginRoutes.createOAuthLoginProcedures(this.schemas),\n ...twoFaRoutes.createTwoFaProcedures(),\n ...biometricRoutes.createBiometricProcedures(),\n ...emailVerificationRoutes.createEmailVerificationProcedures()\n });\n }\n}\n\nexport function createAuthRouter<TExtensions extends SchemaExtensions = {}>(\n config: AuthConfig<TExtensions>\n) {\n const factory = new AuthRouterFactory<TExtensions>(config);\n const router = factory.t.router({\n auth: factory.createRouter()\n });\n return {\n router: router,\n t: factory.t,\n procedure: factory.procedure,\n authProcedure: factory.authProcedure,\n createContext: createContext\n };\n}\n\nexport type AuthRouter<TExtensions extends SchemaExtensions = {}> = ReturnType<\n typeof createAuthRouter<TExtensions>\n>;\n"],"mappings":"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","names":["TRPCError","TRPCError","TRPCError","TRPCError","randomUUID","TRPCError","TRPCError","randomUUID","randomUUID","TRPCError","TRPCError","randomUUID","TRPCError","TRPCError"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/validators.ts"],"sourcesContent":["import { z, type AnyZodObject } from 'zod';\n\nimport type { SchemaExtensions } from './types/hooks';\n\n/**\n * Username validation regex - allows letters, numbers, and underscores\n */\nconst usernameValidationRegex = /^[a-zA-Z0-9_]+$/;\n\n/**\n * Schema for user registration\n */\nexport const signupSchema = z.object({\n username: z\n .string()\n .min(1, { message: 'Username is required' })\n .max(30, { message: 'Username must be 30 characters or less' })\n .regex(usernameValidationRegex, {\n message: 'Username can only contain letters, numbers, and underscores'\n }),\n email: z.string().email({ message: 'Invalid email address' }),\n password: z\n .string()\n .min(6, { message: 'Password must contain at least 6 characters' })\n});\n\n/**\n * Schema for user login\n */\nexport const loginSchema = z.object({\n username: z.string().min(1, { message: 'Username or email is required' }),\n password: z.string().min(1, { message: 'Password is required' }),\n code: z.string().optional() // 2FA code\n});\n\n/**\n * Schema for OAuth login\n */\nexport const oAuthLoginSchema = z.object({\n idToken: z.string(),\n user: z\n .object({\n email: z.string().email().optional()\n })\n .optional(),\n provider: z.enum(['GOOGLE', 'APPLE'])\n});\n\n/**\n * Schema for password reset request\n */\nexport const requestPasswordResetSchema = z.object({\n email: z.string().email({ message: 'Invalid email address' })\n});\n\n/**\n * Schema for password reset confirmation\n */\nexport const resetPasswordSchema = z.object({\n token: z.string().min(1, { message: 'Reset token is required' }),\n password: z\n .string()\n .min(6, { message: 'Password must contain at least 6 characters' })\n});\n\n/**\n * Schema for checking password reset token\n */\nexport const checkPasswordResetSchema = z.object({\n token: z.string().min(1, { message: 'Reset token is required' })\n});\n\n/**\n * Schema for changing password (authenticated)\n */\nexport const changePasswordSchema = z.object({\n currentPassword: z\n .string()\n .min(1, { message: 'Current password is required' }),\n newPassword: z\n .string()\n .min(6, { message: 'New password must contain at least 6 characters' })\n});\n\n/**\n * Schema for 2FA verification\n */\nexport const twoFaVerifySchema = z.object({\n code: z.string().min(6, { message: 'Verification code is required' }),\n sessionId: z.number().optional()\n});\n\n/**\n * Schema for 2FA setup\n */\nexport const twoFaSetupSchema = z.object({\n code: z.string().min(6, { message: 'Verification code is required' })\n});\n\n/**\n * Schema for 2FA reset request\n */\nexport const twoFaResetSchema = z.object({\n username: z.string().min(1),\n password: z.string().min(1)\n});\n\n/**\n * Schema for 2FA reset verification\n */\nexport const twoFaResetVerifySchema = z.object({\n code: z.number().min(100000).max(999999),\n username: z.string().min(1)\n});\n\n/**\n * Schema for email verification\n */\nexport const verifyEmailSchema = z.object({\n code: z.string().min(1, { message: 'Verification code is required' })\n});\n\n/**\n * Schema for resending verification email\n */\nexport const resendVerificationSchema = z.object({\n email: z.string().email().optional()\n});\n\n/**\n * Schema for biometric verification\n */\nexport const biometricVerifySchema = z.object({});\n\n/**\n * Schema for push token registration\n */\nexport const registerPushTokenSchema = z.object({\n pushToken: z.string().min(1, { message: 'Push token is required' })\n});\n\n/**\n * Schema for push token deregistration\n */\nexport const deregisterPushTokenSchema = z.object({\n pushToken: z.string().min(1, { message: 'Push token is required' })\n});\n\n/**\n * Schema for getting 2FA secret\n */\nexport const getTwofaSecretSchema = z.object({\n pushCode: z.string().min(6, { message: 'Push code is required' })\n});\n\n/**\n * Schema for disabling 2FA\n */\nexport const disableTwofaSchema = z.object({\n password: z.string().min(1, { message: 'Password is required' })\n});\n\n/**\n * Schema for logout\n */\nexport const logoutSchema = z.object({\n allDevices: z.boolean().optional().default(false)\n});\n\n/**\n * Schema for ending all sessions\n */\nexport const endAllSessionsSchema = z.object({\n skipCurrentSession: z.boolean().optional().default(true)\n});\n\n/**\n * Schema for OTP-based login request\n */\nexport const otpLoginRequestSchema = z.object({\n email: z.string().email({ message: 'Invalid email address' })\n});\n\n/**\n * Schema for OTP-based login verification\n */\nexport const otpLoginVerifySchema = z.object({\n email: z.string().email(),\n code: z.number().min(100000).max(999999)\n});\n\nexport type SignupInput = z.infer<typeof signupSchema>;\nexport type LoginInput = z.infer<typeof loginSchema>;\nexport type OAuthLoginInput = z.infer<typeof oAuthLoginSchema>;\nexport type ResetPasswordInput = z.infer<typeof resetPasswordSchema>;\nexport type ChangePasswordInput = z.infer<typeof changePasswordSchema>;\nexport type TwoFaVerifyInput = z.infer<typeof twoFaVerifySchema>;\nexport type VerifyEmailInput = z.infer<typeof verifyEmailSchema>;\nexport type LogoutInput = z.infer<typeof logoutSchema>;\n\n/** Schemas used by auth procedures */\nexport interface AuthSchemas {\n signup: AnyZodObject;\n login: AnyZodObject;\n oauth: AnyZodObject;\n}\n\n\n/**\n * Compute merged ZodObject type.\n * When TExt is defined, produces a schema with both base and extension shapes.\n * When TExt is undefined, produces the base schema.\n */\ntype MergedSchema<TBase extends AnyZodObject, TExt extends AnyZodObject | undefined> =\n [TExt] extends [AnyZodObject]\n ? z.ZodObject<TBase['shape'] & TExt['shape'], 'strip', z.ZodTypeAny>\n : TBase;\n\n/** Result type from createSchemas - preserves concrete schema types */\nexport type CreatedSchemas<TExtensions extends SchemaExtensions = {}> = {\n signup: MergedSchema<typeof signupSchema, TExtensions['signup']>;\n login: MergedSchema<typeof loginSchema, TExtensions['login']>;\n oauth: MergedSchema<typeof oAuthLoginSchema, TExtensions['oauth']>;\n};\n\nexport type SignupSchemaInput<TExtensions extends SchemaExtensions = {}> =\n SignupInput & (TExtensions['signup'] extends AnyZodObject ? z.infer<TExtensions['signup']> : {});\n\nexport type LoginSchemaInput<TExtensions extends SchemaExtensions = {}> =\n LoginInput & (TExtensions['login'] extends AnyZodObject ? z.infer<TExtensions['login']> : {});\n\nexport type OAuthSchemaInput<TExtensions extends SchemaExtensions = {}> =\n OAuthLoginInput & (TExtensions['oauth'] extends AnyZodObject ? z.infer<TExtensions['oauth']> : {});\n\n/** Create schemas with optional extensions merged in */\nexport function createSchemas<TExtensions extends SchemaExtensions = {}>(\n extensions?: TExtensions\n): CreatedSchemas<TExtensions> {\n return {\n signup: extensions?.signup\n ? signupSchema.merge(extensions.signup)\n : signupSchema,\n login: extensions?.login\n ? loginSchema.merge(extensions.login)\n : loginSchema,\n oauth: extensions?.oauth\n ? oAuthLoginSchema.merge(extensions.oauth)\n : oAuthLoginSchema\n } as CreatedSchemas<TExtensions>;\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -8,12 +8,12 @@ declare const signupSchema: z.ZodObject<{
8
8
  email: z.ZodString;
9
9
  password: z.ZodString;
10
10
  }, "strip", z.ZodTypeAny, {
11
- username: string;
12
11
  email: string;
12
+ username: string;
13
13
  password: string;
14
14
  }, {
15
- username: string;
16
15
  email: string;
16
+ username: string;
17
17
  password: string;
18
18
  }>;
19
19
  /**
@@ -8,12 +8,12 @@ declare const signupSchema: z.ZodObject<{
8
8
  email: z.ZodString;
9
9
  password: z.ZodString;
10
10
  }, "strip", z.ZodTypeAny, {
11
- username: string;
12
11
  email: string;
12
+ username: string;
13
13
  password: string;
14
14
  }, {
15
- username: string;
16
15
  email: string;
16
+ username: string;
17
17
  password: string;
18
18
  }>;
19
19
  /**