@vynelix/nestjs-multi-auth 0.3.2 → 1.0.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.
Files changed (196) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +309 -18
  3. package/dist/auth/auth.controller.d.ts +3 -2
  4. package/dist/auth/auth.controller.js +32 -5
  5. package/dist/auth/auth.controller.js.map +1 -1
  6. package/dist/auth/auth.module.js +116 -68
  7. package/dist/auth/auth.module.js.map +1 -1
  8. package/dist/auth/auth.service.d.ts +52 -25
  9. package/dist/auth/auth.service.js +238 -327
  10. package/dist/auth/auth.service.js.map +1 -1
  11. package/dist/auth/core/auth-mapper.d.ts +1 -1
  12. package/dist/auth/core/database-otp.provider.d.ts +12 -0
  13. package/dist/auth/core/database-otp.provider.js +122 -0
  14. package/dist/auth/core/database-otp.provider.js.map +1 -0
  15. package/dist/auth/dto/requests/magic-link.dto.d.ts +1 -0
  16. package/dist/auth/dto/requests/magic-link.dto.js +6 -0
  17. package/dist/auth/dto/requests/magic-link.dto.js.map +1 -1
  18. package/dist/auth/dto/requests/mfa.dto.d.ts +5 -1
  19. package/dist/auth/dto/requests/mfa.dto.js +29 -8
  20. package/dist/auth/dto/requests/mfa.dto.js.map +1 -1
  21. package/dist/auth/enums/identifier-type.enum.d.ts +11 -0
  22. package/dist/auth/enums/identifier-type.enum.js +17 -0
  23. package/dist/auth/enums/identifier-type.enum.js.map +1 -0
  24. package/dist/auth/enums/mfa-type.enum.d.ts +5 -0
  25. package/dist/auth/enums/mfa-type.enum.js +10 -0
  26. package/dist/auth/enums/mfa-type.enum.js.map +1 -0
  27. package/dist/auth/enums/otp-purpose.enum.d.ts +8 -0
  28. package/dist/auth/enums/otp-purpose.enum.js +13 -0
  29. package/dist/auth/enums/otp-purpose.enum.js.map +1 -0
  30. package/dist/auth/enums/session-event.enum.d.ts +7 -0
  31. package/dist/auth/enums/session-event.enum.js +12 -0
  32. package/dist/auth/enums/session-event.enum.js.map +1 -0
  33. package/dist/auth/interfaces/auth-module-options.interface.d.ts +36 -1
  34. package/dist/auth/interfaces/auth-notification-provider.interface.d.ts +7 -1
  35. package/dist/auth/interfaces/auth-otp-provider.interface.d.ts +60 -0
  36. package/dist/auth/interfaces/auth-otp-provider.interface.js +7 -0
  37. package/dist/auth/interfaces/auth-otp-provider.interface.js.map +1 -0
  38. package/dist/auth/interfaces/models.interface.d.ts +91 -0
  39. package/dist/auth/interfaces/models.interface.js +3 -0
  40. package/dist/auth/interfaces/models.interface.js.map +1 -0
  41. package/dist/auth/interfaces/oauth-strategy.interface.d.ts +2 -2
  42. package/dist/auth/interfaces/repositories.interface.d.ts +70 -0
  43. package/dist/auth/interfaces/repositories.interface.js +3 -0
  44. package/dist/auth/interfaces/repositories.interface.js.map +1 -0
  45. package/dist/auth/interfaces/repository-tokens.d.ts +7 -0
  46. package/dist/auth/interfaces/repository-tokens.js +11 -0
  47. package/dist/auth/interfaces/repository-tokens.js.map +1 -0
  48. package/dist/auth/interfaces/signup-event-body.interface.d.ts +1 -1
  49. package/dist/auth/strategies/local-auth.strategy.d.ts +3 -5
  50. package/dist/auth/strategies/local-auth.strategy.js +64 -99
  51. package/dist/auth/strategies/local-auth.strategy.js.map +1 -1
  52. package/dist/auth/strategies/oauth/apple.strategy.d.ts +4 -6
  53. package/dist/auth/strategies/oauth/apple.strategy.js +57 -70
  54. package/dist/auth/strategies/oauth/apple.strategy.js.map +1 -1
  55. package/dist/auth/strategies/oauth/facebook.strategy.d.ts +4 -6
  56. package/dist/auth/strategies/oauth/facebook.strategy.js +58 -71
  57. package/dist/auth/strategies/oauth/facebook.strategy.js.map +1 -1
  58. package/dist/auth/strategies/oauth/google.strategy.d.ts +4 -6
  59. package/dist/auth/strategies/oauth/google.strategy.js +84 -155
  60. package/dist/auth/strategies/oauth/google.strategy.js.map +1 -1
  61. package/dist/auth/strategies/oauth/oauth.strategy.d.ts +2 -2
  62. package/dist/database/prisma/prisma-auth.adapter.d.ts +11 -0
  63. package/dist/database/prisma/prisma-auth.adapter.js +64 -0
  64. package/dist/database/prisma/prisma-auth.adapter.js.map +1 -0
  65. package/dist/database/prisma/repositories/auth-identifier.repository.d.ts +16 -0
  66. package/dist/database/prisma/repositories/auth-identifier.repository.js +41 -0
  67. package/dist/database/prisma/repositories/auth-identifier.repository.js.map +1 -0
  68. package/dist/database/prisma/repositories/auth.repository.d.ts +19 -0
  69. package/dist/database/prisma/repositories/auth.repository.js +49 -0
  70. package/dist/database/prisma/repositories/auth.repository.js.map +1 -0
  71. package/dist/database/prisma/repositories/index.d.ts +7 -0
  72. package/dist/database/prisma/repositories/index.js +24 -0
  73. package/dist/database/prisma/repositories/index.js.map +1 -0
  74. package/dist/database/prisma/repositories/mfa-method.repository.d.ts +11 -0
  75. package/dist/database/prisma/repositories/mfa-method.repository.js +33 -0
  76. package/dist/database/prisma/repositories/mfa-method.repository.js.map +1 -0
  77. package/dist/database/prisma/repositories/oauth-provider.repository.d.ts +14 -0
  78. package/dist/database/prisma/repositories/oauth-provider.repository.js +39 -0
  79. package/dist/database/prisma/repositories/oauth-provider.repository.js.map +1 -0
  80. package/dist/database/prisma/repositories/otp-token.repository.d.ts +13 -0
  81. package/dist/database/prisma/repositories/otp-token.repository.js +52 -0
  82. package/dist/database/prisma/repositories/otp-token.repository.js.map +1 -0
  83. package/dist/database/prisma/repositories/session-log.repository.d.ts +12 -0
  84. package/dist/database/prisma/repositories/session-log.repository.js +42 -0
  85. package/dist/database/prisma/repositories/session-log.repository.js.map +1 -0
  86. package/dist/database/prisma/repositories/session.repository.d.ts +16 -0
  87. package/dist/database/prisma/repositories/session.repository.js +41 -0
  88. package/dist/database/prisma/repositories/session.repository.js.map +1 -0
  89. package/dist/database/typeorm/entities/auth-identify.entity.d.ts +23 -0
  90. package/dist/database/typeorm/entities/auth-identify.entity.js +61 -0
  91. package/dist/database/typeorm/entities/auth-identify.entity.js.map +1 -0
  92. package/dist/database/typeorm/entities/auth.entity.d.ts +45 -0
  93. package/dist/database/typeorm/entities/auth.entity.js +129 -0
  94. package/dist/database/typeorm/entities/auth.entity.js.map +1 -0
  95. package/dist/database/typeorm/entities/base.entity.d.ts +7 -0
  96. package/dist/database/typeorm/entities/base.entity.js +44 -0
  97. package/dist/database/typeorm/entities/base.entity.js.map +1 -0
  98. package/dist/database/typeorm/entities/entities.d.ts +7 -0
  99. package/dist/database/typeorm/entities/entities.js +18 -0
  100. package/dist/database/typeorm/entities/entities.js.map +1 -0
  101. package/dist/database/typeorm/entities/mfa-method.entity.d.ts +10 -0
  102. package/dist/database/typeorm/entities/mfa-method.entity.js +47 -0
  103. package/dist/database/typeorm/entities/mfa-method.entity.js.map +1 -0
  104. package/dist/database/typeorm/entities/oauth-provider.entity.d.ts +38 -0
  105. package/dist/database/typeorm/entities/oauth-provider.entity.js +88 -0
  106. package/dist/database/typeorm/entities/oauth-provider.entity.js.map +1 -0
  107. package/dist/database/typeorm/entities/otp-token.entity.d.ts +15 -0
  108. package/dist/database/typeorm/entities/otp-token.entity.js +53 -0
  109. package/dist/database/typeorm/entities/otp-token.entity.js.map +1 -0
  110. package/dist/database/typeorm/entities/session.entity.d.ts +21 -0
  111. package/dist/database/typeorm/entities/session.entity.js +71 -0
  112. package/dist/database/typeorm/entities/session.entity.js.map +1 -0
  113. package/dist/database/typeorm/entities/session_log.entity.d.ts +25 -0
  114. package/dist/database/typeorm/entities/session_log.entity.js +78 -0
  115. package/dist/database/typeorm/entities/session_log.entity.js.map +1 -0
  116. package/dist/database/typeorm/migrations/auth-entities.d.ts +7 -0
  117. package/dist/database/typeorm/migrations/auth-entities.js +18 -0
  118. package/dist/database/typeorm/migrations/auth-entities.js.map +1 -0
  119. package/dist/database/typeorm/migrations/auth-schema.initializer.d.ts +9 -0
  120. package/dist/database/typeorm/migrations/auth-schema.initializer.js +36 -0
  121. package/dist/database/typeorm/migrations/auth-schema.initializer.js.map +1 -0
  122. package/dist/database/typeorm/migrations/auth.migration.v1.d.ts +12 -0
  123. package/dist/database/typeorm/migrations/auth.migration.v1.js +157 -0
  124. package/dist/database/typeorm/migrations/auth.migration.v1.js.map +1 -0
  125. package/dist/database/typeorm/migrations/auth.migration.v2.d.ts +8 -0
  126. package/dist/database/typeorm/migrations/auth.migration.v2.js +23 -0
  127. package/dist/database/typeorm/migrations/auth.migration.v2.js.map +1 -0
  128. package/dist/database/typeorm/migrations/auth.migrations.d.ts +2 -0
  129. package/dist/database/typeorm/migrations/auth.migrations.js +10 -0
  130. package/dist/database/typeorm/migrations/auth.migrations.js.map +1 -0
  131. package/dist/database/typeorm/migrations/migration.service.d.ts +9 -0
  132. package/dist/database/typeorm/migrations/migration.service.js +75 -0
  133. package/dist/database/typeorm/migrations/migration.service.js.map +1 -0
  134. package/dist/database/typeorm/repositories/auth-identifier.repository.d.ts +18 -0
  135. package/dist/database/typeorm/repositories/auth-identifier.repository.js +64 -0
  136. package/dist/database/typeorm/repositories/auth-identifier.repository.js.map +1 -0
  137. package/dist/database/typeorm/repositories/auth.repository.d.ts +21 -0
  138. package/dist/database/typeorm/repositories/auth.repository.js +71 -0
  139. package/dist/database/typeorm/repositories/auth.repository.js.map +1 -0
  140. package/dist/database/typeorm/repositories/index.d.ts +7 -0
  141. package/dist/database/typeorm/repositories/index.js +24 -0
  142. package/dist/database/typeorm/repositories/index.js.map +1 -0
  143. package/dist/database/typeorm/repositories/mfa-method.repository.d.ts +13 -0
  144. package/dist/database/typeorm/repositories/mfa-method.repository.js +46 -0
  145. package/dist/database/typeorm/repositories/mfa-method.repository.js.map +1 -0
  146. package/dist/database/typeorm/repositories/oauth-provider.repository.d.ts +16 -0
  147. package/dist/database/typeorm/repositories/oauth-provider.repository.js +52 -0
  148. package/dist/database/typeorm/repositories/oauth-provider.repository.js.map +1 -0
  149. package/dist/database/typeorm/repositories/otp-token.repository.d.ts +13 -0
  150. package/dist/database/typeorm/repositories/otp-token.repository.js +52 -0
  151. package/dist/database/typeorm/repositories/otp-token.repository.js.map +1 -0
  152. package/dist/database/typeorm/repositories/session-log.repository.d.ts +12 -0
  153. package/dist/database/typeorm/repositories/session-log.repository.js +47 -0
  154. package/dist/database/typeorm/repositories/session-log.repository.js.map +1 -0
  155. package/dist/database/typeorm/repositories/session.repository.d.ts +18 -0
  156. package/dist/database/typeorm/repositories/session.repository.js +84 -0
  157. package/dist/database/typeorm/repositories/session.repository.js.map +1 -0
  158. package/dist/database/typeorm/typeorm-auth.adapter.d.ts +2 -0
  159. package/dist/database/typeorm/typeorm-auth.adapter.js +50 -0
  160. package/dist/database/typeorm/typeorm-auth.adapter.js.map +1 -0
  161. package/dist/index.d.ts +11 -9
  162. package/dist/index.js +18 -10
  163. package/dist/index.js.map +1 -1
  164. package/dist/tsconfig.tsbuildinfo +1 -1
  165. package/fix-imports.js +46 -0
  166. package/fix-syntax.js +66 -0
  167. package/package.json +22 -20
  168. package/patch-local-specs.js +52 -0
  169. package/patch-oauth-specs.js +41 -0
  170. package/patch-specs.js +36 -0
  171. package/prompts/database_adapter.md +157 -0
  172. package/prompts/otp_provider.md +292 -0
  173. package/scratch/create-prisma-repos-final.js +139 -0
  174. package/scratch/create-prisma-repos.js +280 -0
  175. package/scratch/fix-events-spec.js +12 -0
  176. package/scratch/fix-imports.js +53 -0
  177. package/scratch/fix-prisma-interfaces.js +41 -0
  178. package/scratch/fix-prisma-interfaces2.js +36 -0
  179. package/scratch/fix-prisma-interfaces3.js +26 -0
  180. package/scratch/fix-prisma.js +28 -0
  181. package/scratch/fix-test-imports.js +51 -0
  182. package/scratch/fix-tests-advanced.js +68 -0
  183. package/scratch/fix-tests-advanced2.js +23 -0
  184. package/scratch/fix-tests-concrete.js +40 -0
  185. package/scratch/fix-tests-final.js +35 -0
  186. package/scratch/fix-tests-final2.js +28 -0
  187. package/scratch/fix-tests-final3.js +26 -0
  188. package/scratch/fix-tests-methods.js +40 -0
  189. package/scratch/fix-tests-proxy.js +67 -0
  190. package/scratch/fix-tests-types.js +24 -0
  191. package/scratch/rewrite-tests.js +110 -0
  192. package/tsc_errors.txt +60 -0
  193. package/tsc_errors2.txt +93 -0
  194. package/tmp-cv-test/package-lock.json +0 -250
  195. package/tmp-cv-test/package.json +0 -17
  196. package/tmp-cv-test/test.ts +0 -11
@@ -0,0 +1,292 @@
1
+ # Refactor OTP Architecture — nestjs-multi-auth
2
+
3
+ ## Context
4
+
5
+ You are working on **nestjs-multi-auth**, a production-grade authentication library for NestJS.
6
+
7
+ ## Objective
8
+
9
+ Refactor the OTP architecture to separate OTP lifecycle management from notification delivery, while maintaining full backward compatibility.
10
+
11
+ ## Problem
12
+
13
+ The current implementation assumes the library always:
14
+
15
+ 1. Generates the OTP
16
+ 2. Stores it in the database
17
+ 3. Passes the generated code to `AuthNotificationProvider.sendVerificationCode()`
18
+
19
+ This assumption prevents integration with providers like **Twilio Verify**, **Firebase Phone Authentication**, **Vonage Verify**, and **MessageBird Verify**, because these services generate, store, expire, and validate OTPs themselves — the raw code is never exposed to the library.
20
+
21
+ The authentication library must support both:
22
+
23
+ - **Internal database-managed OTPs** (current behavior)
24
+ - **External OTP providers** (Twilio Verify, Firebase Phone, etc.)
25
+
26
+ ...without changing the public authentication API.
27
+
28
+ ---
29
+
30
+ ## Design Principles
31
+
32
+ ### The authentication library IS responsible for
33
+
34
+ - Authentication
35
+ - Authorization
36
+ - Identity verification workflow
37
+ - Session management
38
+ - Password reset
39
+ - Email verification
40
+ - Phone verification
41
+ - MFA orchestration
42
+
43
+ ### The authentication library is NOT responsible for
44
+
45
+ - SMS delivery
46
+ - Email delivery
47
+ - Push notifications
48
+ - WhatsApp
49
+ - OTP transport
50
+
51
+ Notification delivery remains the responsibility of the consuming application.
52
+
53
+ ---
54
+
55
+ ## New Architecture
56
+
57
+ Split the current OTP implementation into two abstractions.
58
+
59
+ ### 1. `AuthOtpProvider` (NEW)
60
+
61
+ Responsible for the **lifecycle** of an OTP: generate, store, validate, resend, expire.
62
+
63
+ **Example implementations:**
64
+
65
+ - `DatabaseOtpProvider`
66
+ - `TwilioVerifyOtpProvider`
67
+ - `FirebasePhoneOtpProvider`
68
+ - `CustomOtpProvider`
69
+
70
+ **Interface:**
71
+
72
+ ```typescript
73
+ export interface AuthOtpProvider {
74
+ issue(request: IssueOtpRequest): Promise<IssueOtpResult>;
75
+ verify(request: VerifyOtpRequest): Promise<VerifyOtpResult>;
76
+ resend?(request: ResendOtpRequest): Promise<ResendOtpResult>;
77
+ }
78
+ ```
79
+
80
+ **`IssueOtpRequest`** — should contain enough information for any provider:
81
+
82
+ ```typescript
83
+ {
84
+ uid,
85
+ authId,
86
+ identifier,
87
+ identifierType,
88
+ purpose,
89
+ expiresIn
90
+ }
91
+ ```
92
+
93
+ **`IssueOtpResult`** — must support both internal and external providers.
94
+
95
+ For database providers:
96
+
97
+ ```typescript
98
+ {
99
+ handledDelivery: false,
100
+ code: "483921",
101
+ expiresAt: Date
102
+ }
103
+ ```
104
+
105
+ For Twilio Verify:
106
+
107
+ ```typescript
108
+ {
109
+ handledDelivery: true,
110
+ verificationId: "...",
111
+ expiresAt: Date | undefined
112
+ }
113
+ ```
114
+
115
+ > **Note:** External providers will not return the OTP.
116
+
117
+ **`VerifyOtpResult`** — should be provider-independent:
118
+
119
+ ```typescript
120
+ {
121
+ success: true,
122
+ metadata?: {}
123
+ }
124
+ ```
125
+
126
+ ### 2. `AuthNotificationProvider` (existing — to be improved)
127
+
128
+ Keep the notification provider, but enrich its signature.
129
+
130
+ **Current:**
131
+
132
+ ```typescript
133
+ sendVerificationCode(to, code, type)
134
+ ```
135
+
136
+ **Replace with:**
137
+
138
+ ```typescript
139
+ sendVerificationCode({
140
+ to,
141
+ code,
142
+ type,
143
+ purpose,
144
+ expiresAt
145
+ })
146
+ ```
147
+
148
+ This lets applications customize messages based on purpose (email verification, phone verification, password reset, login verification, etc.)
149
+
150
+ > The notification provider should **never** know where the OTP came from.
151
+
152
+ ---
153
+
154
+ ## Default OTP Provider
155
+
156
+ Create a built-in provider named `DatabaseOtpProvider`.
157
+
158
+ Move all current logic from:
159
+
160
+ - `sendVerification()`
161
+ - `forgotPassword()`
162
+ - `resetPassword()`
163
+ - `verifyCode()`
164
+ - `resendVerification()`
165
+
166
+ ...into this provider. It must preserve current behavior exactly:
167
+
168
+ - Generate OTP
169
+ - Hash OTP
170
+ - Store hash
171
+ - Handle expiration
172
+ - Resend logic
173
+ - Verification logic
174
+
175
+ **Nothing should change functionally.**
176
+
177
+ ---
178
+
179
+ ## Twilio Verify Support
180
+
181
+ Design the architecture so that implementing `TwilioVerifyOtpProvider` requires **no changes to `AuthService`**.
182
+
183
+ **`issue()` flow:**
184
+
185
+ ```
186
+ issue()
187
+ → Call Twilio Verify
188
+ → Twilio generates OTP
189
+ → Twilio stores OTP
190
+ → Twilio sends SMS
191
+ → Return { handledDelivery: true, verificationId }
192
+ ```
193
+
194
+ **`verify()` flow:**
195
+
196
+ ```
197
+ verify()
198
+ → Call Twilio Verify Check
199
+ → Return success
200
+ ```
201
+
202
+ > Twilio Verify never exposes the OTP — the library must support this.
203
+
204
+ ---
205
+
206
+ ## `AuthService` Changes
207
+
208
+ Replace all direct OTP generation with `otpProvider.issue(...)`.
209
+
210
+ **Before:**
211
+
212
+ ```
213
+ generate OTP → hash → save → notificationProvider.send(...)
214
+ ```
215
+
216
+ **After:**
217
+
218
+ ```typescript
219
+ const result = await otpProvider.issue(...);
220
+
221
+ if (!result.handledDelivery) {
222
+ await notificationProvider.sendVerificationCode(...);
223
+ }
224
+ ```
225
+
226
+ The authentication flow should **not** know whether the OTP came from the database, Twilio, Firebase, or a custom provider.
227
+
228
+ Replace every direct OTP verification with:
229
+
230
+ ```typescript
231
+ await otpProvider.verify(...);
232
+ ```
233
+
234
+ `AuthService` should **never** call `bcrypt.compare()` directly anymore — that logic belongs inside `DatabaseOtpProvider`.
235
+
236
+ ---
237
+
238
+ ## Existing Features (must keep working, no breaking changes)
239
+
240
+ - Signup verification
241
+ - Login verification
242
+ - Resend verification
243
+ - Forgot password
244
+ - Password reset
245
+ - Secure account
246
+ - Magic link
247
+ - MFA
248
+ - Passwordless authentication
249
+
250
+ ---
251
+
252
+ ## OTP Purposes
253
+
254
+ Continue using the existing enum:
255
+
256
+ - `VERIFY_EMAIL`
257
+ - `VERIFY_PHONE`
258
+ - `PASSWORD_RESET`
259
+ - `MAGIC_LINK`
260
+ - `SECURE_ACCOUNT`
261
+
262
+ Providers should receive the purpose.
263
+
264
+ ---
265
+
266
+ ## Dependency Injection
267
+
268
+ Introduce `AUTH_OTP_PROVIDER`, similar to `AUTH_NOTIFICATION_PROVIDER`.
269
+
270
+ If no provider is registered, automatically register `DatabaseOtpProvider` so existing users do not need to change anything.
271
+
272
+ ---
273
+
274
+ ## Backward Compatibility
275
+
276
+ This refactor must **not** break existing applications.
277
+
278
+ - Applications that already implement `AuthNotificationProvider` should continue working exactly as before.
279
+ - Only developers who wish to use Twilio Verify or another external OTP provider need to implement `AuthOtpProvider`.
280
+
281
+ ---
282
+
283
+ ## Code Quality Requirements
284
+
285
+ - Follow SOLID principles.
286
+ - Separate orchestration from provider implementations.
287
+ - Avoid duplicating OTP logic between `AuthService` and providers.
288
+ - Keep `AuthService` focused on authentication workflows, not OTP implementation details.
289
+ - Use dependency injection throughout.
290
+ - Ensure each provider is independently unit testable.
291
+ - Preserve all current tests and behavior where possible.
292
+ - Keep public authentication endpoints unchanged — only the internal OTP architecture should be refactored.
@@ -0,0 +1,139 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+
4
+ const repoDir = path.join(__dirname, '../src/database/prisma/repositories');
5
+
6
+ const files = {
7
+ 'auth.repository.ts': `
8
+ import { Injectable, Inject } from '@nestjs/common';
9
+ import { AuthRepository } from '../../../auth/interfaces/repositories.interface';
10
+ import { Auth as CoreAuth } from '../../../auth/interfaces/models.interface';
11
+ import { AuthStrategy } from '../../../auth/enums/auth-type.enum';
12
+
13
+ @Injectable()
14
+ export class PrismaAuthRepository implements AuthRepository {
15
+ constructor(@Inject('PRISMA_SERVICE_TOKEN') private readonly prisma: any) {}
16
+
17
+ async create(data: Partial<CoreAuth>): Promise<CoreAuth> {
18
+ const { identifiers, ...rest } = data;
19
+ return this.prisma.auth.create({
20
+ data: {
21
+ ...rest,
22
+ identifiers: identifiers ? { create: identifiers } : undefined,
23
+ } as any,
24
+ include: { identifiers: true }
25
+ });
26
+ }
27
+
28
+ async findById(id: string): Promise<CoreAuth | null> { return this.prisma.auth.findUnique({ where: { id }, include: { identifiers: true } }); }
29
+ async findByUid(uid: string): Promise<CoreAuth | null> { return this.prisma.auth.findUnique({ where: { uid }, include: { identifiers: true } }); }
30
+ async findAllByUid(uid: string): Promise<CoreAuth[]> { return this.prisma.auth.findMany({ where: { uid } }); }
31
+ async findAll(): Promise<CoreAuth[]> { return this.prisma.auth.findMany(); }
32
+ async findByUidAndStrategy(uid: string, strategy: AuthStrategy): Promise<CoreAuth | null> { return this.prisma.auth.findFirst({ where: { uid, strategy } }); }
33
+ async findByUidAndStrategies(uid: string, strategies: AuthStrategy[]): Promise<CoreAuth | null> { return this.prisma.auth.findFirst({ where: { uid, strategy: { in: strategies } } }); }
34
+ async save(auth: CoreAuth): Promise<CoreAuth> { return this.prisma.auth.update({ where: { id: auth.id }, data: auth as any }); }
35
+ async update(id: string, data: Partial<CoreAuth>): Promise<void> { await this.prisma.auth.update({ where: { id }, data: data as any }); }
36
+ async delete(id: string): Promise<void> { await this.prisma.auth.delete({ where: { id } }); }
37
+ async deleteByUid(uid: string): Promise<void> { await this.prisma.auth.deleteMany({ where: { uid } }); }
38
+ async findWithIdentifiers(id: string): Promise<CoreAuth | null> { return this.prisma.auth.findUnique({ where: { id }, include: { identifiers: true } }); }
39
+ }
40
+ `,
41
+
42
+ 'auth-identifier.repository.ts': `
43
+ import { Injectable, Inject } from '@nestjs/common';
44
+ import { AuthIdentifierRepository } from '../../../auth/interfaces/repositories.interface';
45
+ import { AuthIdentifier as CoreAuthIdentifier, Auth as CoreAuth } from '../../../auth/interfaces/models.interface';
46
+
47
+ @Injectable()
48
+ export class PrismaAuthIdentifierRepository implements AuthIdentifierRepository {
49
+ constructor(@Inject('PRISMA_SERVICE_TOKEN') private readonly prisma: any) {}
50
+
51
+ async create(data: Partial<CoreAuthIdentifier>): Promise<CoreAuthIdentifier> { return this.prisma.authIdentifier.create({ data: data as any }); }
52
+ async findByValue(value: string): Promise<CoreAuthIdentifier | null> { return this.prisma.authIdentifier.findUnique({ where: { value } }); }
53
+ async findByAuthId(authId: string): Promise<CoreAuthIdentifier[]> { return this.prisma.authIdentifier.findMany({ where: { authId } }); }
54
+ async findByUidAndTypes(uid: string, types: string[]): Promise<CoreAuthIdentifier | null> { return this.prisma.authIdentifier.findFirst({ where: { auth: { uid }, type: { in: types } }}); }
55
+
56
+ async findWithAuthByValue(value: string): Promise<{ identifier: CoreAuthIdentifier; auth: CoreAuth } | null> {
57
+ const res = await this.prisma.authIdentifier.findUnique({ where: { value }, include: { auth: true } });
58
+ if (!res) return null;
59
+ const { auth, ...identifier } = res;
60
+ return { identifier: identifier as any, auth: auth as any };
61
+ }
62
+
63
+ async save(identifier: CoreAuthIdentifier): Promise<CoreAuthIdentifier> { return this.prisma.authIdentifier.update({ where: { id: identifier.id }, data: identifier as any }); }
64
+ async markVerifiedByAuthId(authId: string): Promise<void> { await this.prisma.authIdentifier.updateMany({ where: { authId }, data: { isVerified: true } }); }
65
+ }
66
+ `,
67
+
68
+ 'mfa-method.repository.ts': `
69
+ import { Injectable, Inject } from '@nestjs/common';
70
+ import { MfaMethodRepository } from '../../../auth/interfaces/repositories.interface';
71
+ import { MfaMethod as CoreMfaMethod } from '../../../auth/interfaces/models.interface';
72
+
73
+ @Injectable()
74
+ export class PrismaMfaMethodRepository implements MfaMethodRepository {
75
+ constructor(@Inject('PRISMA_SERVICE_TOKEN') private readonly prisma: any) {}
76
+
77
+ async create(data: Partial<CoreMfaMethod>): Promise<CoreMfaMethod> { return this.prisma.mfaMethod.create({ data: data as any }); }
78
+ async findByUidAndType(uid: string, type: string): Promise<CoreMfaMethod | null> { return this.prisma.mfaMethod.findFirst({ where: { auth: { uid }, type } }); }
79
+ async findByUidAndEnabled(uid: string): Promise<CoreMfaMethod | null> { return this.prisma.mfaMethod.findFirst({ where: { auth: { uid }, isEnabled: true } }); }
80
+ async save(method: CoreMfaMethod): Promise<CoreMfaMethod> { return this.prisma.mfaMethod.update({ where: { id: method.id }, data: method as any }); }
81
+ async deleteByUid(uid: string): Promise<void> { await this.prisma.mfaMethod.deleteMany({ where: { auth: { uid } } }); }
82
+ }
83
+ `,
84
+
85
+ 'oauth-provider.repository.ts': `
86
+ import { Injectable, Inject } from '@nestjs/common';
87
+ import { OAuthProviderRepository } from '../../../auth/interfaces/repositories.interface';
88
+ import { OAuthProvider as CoreOAuthProvider, Auth as CoreAuth } from '../../../auth/interfaces/models.interface';
89
+
90
+ @Injectable()
91
+ export class PrismaOAuthProviderRepository implements OAuthProviderRepository {
92
+ constructor(@Inject('PRISMA_SERVICE_TOKEN') private readonly prisma: any) {}
93
+
94
+ async create(data: Partial<CoreOAuthProvider>): Promise<CoreOAuthProvider> { return this.prisma.oAuthProvider.create({ data: data as any }); }
95
+ async findByProviderUserId(provider: string, providerUserId: string): Promise<CoreOAuthProvider | null> { return this.prisma.oAuthProvider.findUnique({ where: { providerUserId } }); }
96
+
97
+ async findWithAuthByProviderUserId(provider: string, providerUserId: string): Promise<{ provider: CoreOAuthProvider; auth: CoreAuth } | null> {
98
+ const res = await this.prisma.oAuthProvider.findUnique({ where: { providerUserId }, include: { auth: true } });
99
+ if (!res) return null;
100
+ const { auth, ...prov } = res;
101
+ return { provider: prov as any, auth: auth as any };
102
+ }
103
+
104
+ async save(provider: CoreOAuthProvider): Promise<CoreOAuthProvider> { return this.prisma.oAuthProvider.update({ where: { id: provider.id }, data: provider as any }); }
105
+ async update(id: string, data: Partial<CoreOAuthProvider>): Promise<void> { await this.prisma.oAuthProvider.update({ where: { id }, data: data as any }); }
106
+ }
107
+ `,
108
+
109
+ 'session.repository.ts': `
110
+ import { Injectable, Inject } from '@nestjs/common';
111
+ import { SessionRepository } from '../../../auth/interfaces/repositories.interface';
112
+ import { Session as CoreSession } from '../../../auth/interfaces/models.interface';
113
+
114
+ @Injectable()
115
+ export class PrismaSessionRepository implements SessionRepository {
116
+ constructor(@Inject('PRISMA_SERVICE_TOKEN') private readonly prisma: any) {}
117
+
118
+ async create(data: Partial<CoreSession>): Promise<CoreSession> { return this.prisma.session.create({ data: data as any }); }
119
+ async findById(id: string): Promise<CoreSession | null> { return this.prisma.session.findUnique({ where: { id } }); }
120
+ async findDeviceSession(uid: string, namespace: string | undefined, deviceFingerprint: string): Promise<CoreSession | null> {
121
+ // simplified lookup since Prisma cannot easily query inside Json without raw queries across different DBs.
122
+ return this.prisma.session.findFirst({ where: { uid } });
123
+ }
124
+ async findByUid(uid: string): Promise<CoreSession[]> { return this.prisma.session.findMany({ where: { uid } }); }
125
+ async findByIdWithDetails(id: string, namespace?: string): Promise<CoreSession | null> { return this.prisma.session.findUnique({ where: { id } }); }
126
+ async save(session: CoreSession): Promise<CoreSession> { return this.prisma.session.update({ where: { id: session.id }, data: session as any }); }
127
+ async update(id: string, data: Partial<CoreSession>): Promise<void> { await this.prisma.session.update({ where: { id }, data: data as any }); }
128
+ async delete(id: string): Promise<void> { await this.prisma.session.delete({ where: { id } }); }
129
+ async deleteByUid(uid: string): Promise<void> { await this.prisma.session.deleteMany({ where: { uid } }); }
130
+ async transaction(runInTransaction: (repo: SessionRepository) => Promise<void>): Promise<void> { await runInTransaction(this); }
131
+ }
132
+ `
133
+ };
134
+
135
+ for (const [filename, content] of Object.entries(files)) {
136
+ fs.writeFileSync(path.join(repoDir, filename), content.trim(), 'utf8');
137
+ }
138
+
139
+ console.log('Fixed Prisma repositories completely');