@vynelix/nestjs-multi-auth 0.3.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/README.md +309 -18
- package/dist/auth/auth.controller.d.ts +3 -2
- package/dist/auth/auth.controller.js +32 -5
- package/dist/auth/auth.controller.js.map +1 -1
- package/dist/auth/auth.module.js +116 -68
- package/dist/auth/auth.module.js.map +1 -1
- package/dist/auth/auth.service.d.ts +52 -25
- package/dist/auth/auth.service.js +238 -327
- package/dist/auth/auth.service.js.map +1 -1
- package/dist/auth/core/auth-mapper.d.ts +1 -1
- package/dist/auth/core/database-otp.provider.d.ts +12 -0
- package/dist/auth/core/database-otp.provider.js +122 -0
- package/dist/auth/core/database-otp.provider.js.map +1 -0
- package/dist/auth/dto/requests/magic-link.dto.d.ts +1 -0
- package/dist/auth/dto/requests/magic-link.dto.js +6 -0
- package/dist/auth/dto/requests/magic-link.dto.js.map +1 -1
- package/dist/auth/dto/requests/mfa.dto.d.ts +5 -1
- package/dist/auth/dto/requests/mfa.dto.js +29 -8
- package/dist/auth/dto/requests/mfa.dto.js.map +1 -1
- package/dist/auth/enums/identifier-type.enum.d.ts +11 -0
- package/dist/auth/enums/identifier-type.enum.js +17 -0
- package/dist/auth/enums/identifier-type.enum.js.map +1 -0
- package/dist/auth/enums/mfa-type.enum.d.ts +5 -0
- package/dist/auth/enums/mfa-type.enum.js +10 -0
- package/dist/auth/enums/mfa-type.enum.js.map +1 -0
- package/dist/auth/enums/otp-purpose.enum.d.ts +8 -0
- package/dist/auth/enums/otp-purpose.enum.js +13 -0
- package/dist/auth/enums/otp-purpose.enum.js.map +1 -0
- package/dist/auth/enums/session-event.enum.d.ts +7 -0
- package/dist/auth/enums/session-event.enum.js +12 -0
- package/dist/auth/enums/session-event.enum.js.map +1 -0
- package/dist/auth/interfaces/auth-module-options.interface.d.ts +36 -1
- package/dist/auth/interfaces/auth-notification-provider.interface.d.ts +7 -1
- package/dist/auth/interfaces/auth-otp-provider.interface.d.ts +60 -0
- package/dist/auth/interfaces/auth-otp-provider.interface.js +7 -0
- package/dist/auth/interfaces/auth-otp-provider.interface.js.map +1 -0
- package/dist/auth/interfaces/models.interface.d.ts +91 -0
- package/dist/auth/interfaces/models.interface.js +3 -0
- package/dist/auth/interfaces/models.interface.js.map +1 -0
- package/dist/auth/interfaces/oauth-strategy.interface.d.ts +2 -2
- package/dist/auth/interfaces/repositories.interface.d.ts +70 -0
- package/dist/auth/interfaces/repositories.interface.js +3 -0
- package/dist/auth/interfaces/repositories.interface.js.map +1 -0
- package/dist/auth/interfaces/repository-tokens.d.ts +7 -0
- package/dist/auth/interfaces/repository-tokens.js +11 -0
- package/dist/auth/interfaces/repository-tokens.js.map +1 -0
- package/dist/auth/interfaces/signup-event-body.interface.d.ts +1 -1
- package/dist/auth/strategies/local-auth.strategy.d.ts +3 -5
- package/dist/auth/strategies/local-auth.strategy.js +64 -99
- package/dist/auth/strategies/local-auth.strategy.js.map +1 -1
- package/dist/auth/strategies/oauth/apple.strategy.d.ts +4 -6
- package/dist/auth/strategies/oauth/apple.strategy.js +57 -70
- package/dist/auth/strategies/oauth/apple.strategy.js.map +1 -1
- package/dist/auth/strategies/oauth/facebook.strategy.d.ts +4 -6
- package/dist/auth/strategies/oauth/facebook.strategy.js +58 -71
- package/dist/auth/strategies/oauth/facebook.strategy.js.map +1 -1
- package/dist/auth/strategies/oauth/google.strategy.d.ts +4 -6
- package/dist/auth/strategies/oauth/google.strategy.js +84 -155
- package/dist/auth/strategies/oauth/google.strategy.js.map +1 -1
- package/dist/auth/strategies/oauth/oauth.strategy.d.ts +2 -2
- package/dist/database/prisma/prisma-auth.adapter.d.ts +11 -0
- package/dist/database/prisma/prisma-auth.adapter.js +64 -0
- package/dist/database/prisma/prisma-auth.adapter.js.map +1 -0
- package/dist/database/prisma/repositories/auth-identifier.repository.d.ts +16 -0
- package/dist/database/prisma/repositories/auth-identifier.repository.js +41 -0
- package/dist/database/prisma/repositories/auth-identifier.repository.js.map +1 -0
- package/dist/database/prisma/repositories/auth.repository.d.ts +19 -0
- package/dist/database/prisma/repositories/auth.repository.js +49 -0
- package/dist/database/prisma/repositories/auth.repository.js.map +1 -0
- package/dist/database/prisma/repositories/index.d.ts +7 -0
- package/dist/database/prisma/repositories/index.js +24 -0
- package/dist/database/prisma/repositories/index.js.map +1 -0
- package/dist/database/prisma/repositories/mfa-method.repository.d.ts +11 -0
- package/dist/database/prisma/repositories/mfa-method.repository.js +33 -0
- package/dist/database/prisma/repositories/mfa-method.repository.js.map +1 -0
- package/dist/database/prisma/repositories/oauth-provider.repository.d.ts +14 -0
- package/dist/database/prisma/repositories/oauth-provider.repository.js +39 -0
- package/dist/database/prisma/repositories/oauth-provider.repository.js.map +1 -0
- package/dist/database/prisma/repositories/otp-token.repository.d.ts +13 -0
- package/dist/database/prisma/repositories/otp-token.repository.js +52 -0
- package/dist/database/prisma/repositories/otp-token.repository.js.map +1 -0
- package/dist/database/prisma/repositories/session-log.repository.d.ts +12 -0
- package/dist/database/prisma/repositories/session-log.repository.js +42 -0
- package/dist/database/prisma/repositories/session-log.repository.js.map +1 -0
- package/dist/database/prisma/repositories/session.repository.d.ts +16 -0
- package/dist/database/prisma/repositories/session.repository.js +41 -0
- package/dist/database/prisma/repositories/session.repository.js.map +1 -0
- package/dist/database/typeorm/entities/auth-identify.entity.d.ts +23 -0
- package/dist/database/typeorm/entities/auth-identify.entity.js +61 -0
- package/dist/database/typeorm/entities/auth-identify.entity.js.map +1 -0
- package/dist/database/typeorm/entities/auth.entity.d.ts +45 -0
- package/dist/database/typeorm/entities/auth.entity.js +129 -0
- package/dist/database/typeorm/entities/auth.entity.js.map +1 -0
- package/dist/database/typeorm/entities/base.entity.d.ts +7 -0
- package/dist/database/typeorm/entities/base.entity.js +44 -0
- package/dist/database/typeorm/entities/base.entity.js.map +1 -0
- package/dist/database/typeorm/entities/entities.d.ts +7 -0
- package/dist/database/typeorm/entities/entities.js +18 -0
- package/dist/database/typeorm/entities/entities.js.map +1 -0
- package/dist/database/typeorm/entities/mfa-method.entity.d.ts +10 -0
- package/dist/database/typeorm/entities/mfa-method.entity.js +47 -0
- package/dist/database/typeorm/entities/mfa-method.entity.js.map +1 -0
- package/dist/database/typeorm/entities/oauth-provider.entity.d.ts +38 -0
- package/dist/database/typeorm/entities/oauth-provider.entity.js +88 -0
- package/dist/database/typeorm/entities/oauth-provider.entity.js.map +1 -0
- package/dist/database/typeorm/entities/otp-token.entity.d.ts +15 -0
- package/dist/database/typeorm/entities/otp-token.entity.js +53 -0
- package/dist/database/typeorm/entities/otp-token.entity.js.map +1 -0
- package/dist/database/typeorm/entities/session.entity.d.ts +21 -0
- package/dist/database/typeorm/entities/session.entity.js +71 -0
- package/dist/database/typeorm/entities/session.entity.js.map +1 -0
- package/dist/database/typeorm/entities/session_log.entity.d.ts +25 -0
- package/dist/database/typeorm/entities/session_log.entity.js +78 -0
- package/dist/database/typeorm/entities/session_log.entity.js.map +1 -0
- package/dist/database/typeorm/migrations/auth-entities.d.ts +7 -0
- package/dist/database/typeorm/migrations/auth-entities.js +18 -0
- package/dist/database/typeorm/migrations/auth-entities.js.map +1 -0
- package/dist/database/typeorm/migrations/auth-schema.initializer.d.ts +9 -0
- package/dist/database/typeorm/migrations/auth-schema.initializer.js +36 -0
- package/dist/database/typeorm/migrations/auth-schema.initializer.js.map +1 -0
- package/dist/database/typeorm/migrations/auth.migration.v1.d.ts +12 -0
- package/dist/database/typeorm/migrations/auth.migration.v1.js +157 -0
- package/dist/database/typeorm/migrations/auth.migration.v1.js.map +1 -0
- package/dist/database/typeorm/migrations/auth.migration.v2.d.ts +8 -0
- package/dist/database/typeorm/migrations/auth.migration.v2.js +23 -0
- package/dist/database/typeorm/migrations/auth.migration.v2.js.map +1 -0
- package/dist/database/typeorm/migrations/auth.migrations.d.ts +2 -0
- package/dist/database/typeorm/migrations/auth.migrations.js +10 -0
- package/dist/database/typeorm/migrations/auth.migrations.js.map +1 -0
- package/dist/database/typeorm/migrations/migration.service.d.ts +9 -0
- package/dist/database/typeorm/migrations/migration.service.js +75 -0
- package/dist/database/typeorm/migrations/migration.service.js.map +1 -0
- package/dist/database/typeorm/repositories/auth-identifier.repository.d.ts +18 -0
- package/dist/database/typeorm/repositories/auth-identifier.repository.js +64 -0
- package/dist/database/typeorm/repositories/auth-identifier.repository.js.map +1 -0
- package/dist/database/typeorm/repositories/auth.repository.d.ts +21 -0
- package/dist/database/typeorm/repositories/auth.repository.js +71 -0
- package/dist/database/typeorm/repositories/auth.repository.js.map +1 -0
- package/dist/database/typeorm/repositories/index.d.ts +7 -0
- package/dist/database/typeorm/repositories/index.js +24 -0
- package/dist/database/typeorm/repositories/index.js.map +1 -0
- package/dist/database/typeorm/repositories/mfa-method.repository.d.ts +13 -0
- package/dist/database/typeorm/repositories/mfa-method.repository.js +46 -0
- package/dist/database/typeorm/repositories/mfa-method.repository.js.map +1 -0
- package/dist/database/typeorm/repositories/oauth-provider.repository.d.ts +16 -0
- package/dist/database/typeorm/repositories/oauth-provider.repository.js +52 -0
- package/dist/database/typeorm/repositories/oauth-provider.repository.js.map +1 -0
- package/dist/database/typeorm/repositories/otp-token.repository.d.ts +13 -0
- package/dist/database/typeorm/repositories/otp-token.repository.js +52 -0
- package/dist/database/typeorm/repositories/otp-token.repository.js.map +1 -0
- package/dist/database/typeorm/repositories/session-log.repository.d.ts +12 -0
- package/dist/database/typeorm/repositories/session-log.repository.js +47 -0
- package/dist/database/typeorm/repositories/session-log.repository.js.map +1 -0
- package/dist/database/typeorm/repositories/session.repository.d.ts +18 -0
- package/dist/database/typeorm/repositories/session.repository.js +84 -0
- package/dist/database/typeorm/repositories/session.repository.js.map +1 -0
- package/dist/database/typeorm/typeorm-auth.adapter.d.ts +2 -0
- package/dist/database/typeorm/typeorm-auth.adapter.js +50 -0
- package/dist/database/typeorm/typeorm-auth.adapter.js.map +1 -0
- package/dist/index.d.ts +11 -9
- package/dist/index.js +18 -10
- package/dist/index.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/fix-imports.js +46 -0
- package/fix-syntax.js +66 -0
- package/package.json +22 -20
- package/patch-local-specs.js +52 -0
- package/patch-oauth-specs.js +41 -0
- package/patch-specs.js +36 -0
- package/prompts/database_adapter.md +157 -0
- package/prompts/otp_provider.md +292 -0
- package/scratch/create-prisma-repos-final.js +139 -0
- package/scratch/create-prisma-repos.js +280 -0
- package/scratch/fix-events-spec.js +12 -0
- package/scratch/fix-imports.js +53 -0
- package/scratch/fix-prisma-interfaces.js +41 -0
- package/scratch/fix-prisma-interfaces2.js +36 -0
- package/scratch/fix-prisma-interfaces3.js +26 -0
- package/scratch/fix-prisma.js +28 -0
- package/scratch/fix-test-imports.js +51 -0
- package/scratch/fix-tests-advanced.js +68 -0
- package/scratch/fix-tests-advanced2.js +23 -0
- package/scratch/fix-tests-concrete.js +40 -0
- package/scratch/fix-tests-final.js +35 -0
- package/scratch/fix-tests-final2.js +28 -0
- package/scratch/fix-tests-final3.js +26 -0
- package/scratch/fix-tests-methods.js +40 -0
- package/scratch/fix-tests-proxy.js +67 -0
- package/scratch/fix-tests-types.js +24 -0
- package/scratch/rewrite-tests.js +110 -0
- package/tsc_errors.txt +60 -0
- package/tsc_errors2.txt +93 -0
- package/tmp-cv-test/package-lock.json +0 -250
- package/tmp-cv-test/package.json +0 -17
- package/tmp-cv-test/test.ts +0 -11
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
const repoDir = path.join(__dirname, '../src/database/prisma/repositories');
|
|
5
|
+
if (!fs.existsSync(repoDir)) fs.mkdirSync(repoDir, { recursive: true });
|
|
6
|
+
|
|
7
|
+
const files = {
|
|
8
|
+
'auth.repository.ts': `
|
|
9
|
+
import { Injectable, Inject } from '@nestjs/common';
|
|
10
|
+
import { AuthRepository } from '../../../auth/interfaces/repositories.interface';
|
|
11
|
+
import { Auth as CoreAuth } from '../../../auth/interfaces/models.interface';
|
|
12
|
+
|
|
13
|
+
@Injectable()
|
|
14
|
+
export class PrismaAuthRepository implements AuthRepository {
|
|
15
|
+
constructor(@Inject('PRISMA_SERVICE_TOKEN') private readonly prisma: any) {}
|
|
16
|
+
|
|
17
|
+
async findOne(id: string): Promise<CoreAuth | null> {
|
|
18
|
+
return this.prisma.auth.findUnique({ where: { id }, include: { identifiers: true } });
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async findByUid(uid: string): Promise<CoreAuth | null> {
|
|
22
|
+
return this.prisma.auth.findUnique({ where: { uid }, include: { identifiers: true } });
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async findByStrategyAndValue(strategy: string, value: string): Promise<CoreAuth | null> {
|
|
26
|
+
const ai = await this.prisma.authIdentifier.findFirst({
|
|
27
|
+
where: { value, auth: { strategy } },
|
|
28
|
+
include: { auth: true }
|
|
29
|
+
});
|
|
30
|
+
return ai?.auth || null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async create(data: Partial<CoreAuth>): Promise<CoreAuth> {
|
|
34
|
+
const { identifiers, ...rest } = data;
|
|
35
|
+
return this.prisma.auth.create({
|
|
36
|
+
data: {
|
|
37
|
+
...rest,
|
|
38
|
+
identifiers: identifiers ? { create: identifiers } : undefined,
|
|
39
|
+
} as any,
|
|
40
|
+
include: { identifiers: true }
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async save(data: CoreAuth): Promise<CoreAuth> {
|
|
45
|
+
return this.prisma.auth.update({
|
|
46
|
+
where: { id: data.id },
|
|
47
|
+
data: data as any,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async delete(id: string): Promise<void> {
|
|
52
|
+
await this.prisma.auth.delete({ where: { id } });
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
`,
|
|
56
|
+
|
|
57
|
+
'auth-identifier.repository.ts': `
|
|
58
|
+
import { Injectable, Inject } from '@nestjs/common';
|
|
59
|
+
import { AuthIdentifierRepository } from '../../../auth/interfaces/repositories.interface';
|
|
60
|
+
import { AuthIdentifier as CoreAuthIdentifier } from '../../../auth/interfaces/models.interface';
|
|
61
|
+
|
|
62
|
+
@Injectable()
|
|
63
|
+
export class PrismaAuthIdentifierRepository implements AuthIdentifierRepository {
|
|
64
|
+
constructor(@Inject('PRISMA_SERVICE_TOKEN') private readonly prisma: any) {}
|
|
65
|
+
|
|
66
|
+
async create(data: Partial<CoreAuthIdentifier>): Promise<CoreAuthIdentifier> {
|
|
67
|
+
return this.prisma.authIdentifier.create({ data: data as any });
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async findByValue(value: string): Promise<CoreAuthIdentifier | null> {
|
|
71
|
+
return this.prisma.authIdentifier.findUnique({ where: { value }, include: { auth: true } });
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async findByAuthId(authId: string): Promise<CoreAuthIdentifier[]> {
|
|
75
|
+
return this.prisma.authIdentifier.findMany({ where: { authId } });
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async findByUidAndTypes(uid: string, types: string[]): Promise<CoreAuthIdentifier | null> {
|
|
79
|
+
return this.prisma.authIdentifier.findFirst({
|
|
80
|
+
where: {
|
|
81
|
+
auth: { uid },
|
|
82
|
+
type: { in: types },
|
|
83
|
+
},
|
|
84
|
+
orderBy: [
|
|
85
|
+
{ isVerified: 'desc' },
|
|
86
|
+
{ createdAt: 'asc' }
|
|
87
|
+
]
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
async findWithAuthByValue(value: string): Promise<CoreAuthIdentifier | null> {
|
|
92
|
+
return this.prisma.authIdentifier.findUnique({ where: { value }, include: { auth: true } });
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
async save(data: CoreAuthIdentifier): Promise<CoreAuthIdentifier> {
|
|
96
|
+
return this.prisma.authIdentifier.update({
|
|
97
|
+
where: { id: data.id },
|
|
98
|
+
data: data as any,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
`,
|
|
103
|
+
|
|
104
|
+
'session.repository.ts': `
|
|
105
|
+
import { Injectable, Inject } from '@nestjs/common';
|
|
106
|
+
import { SessionRepository } from '../../../auth/interfaces/repositories.interface';
|
|
107
|
+
import { Session as CoreSession } from '../../../auth/interfaces/models.interface';
|
|
108
|
+
|
|
109
|
+
@Injectable()
|
|
110
|
+
export class PrismaSessionRepository implements SessionRepository {
|
|
111
|
+
constructor(@Inject('PRISMA_SERVICE_TOKEN') private readonly prisma: any) {}
|
|
112
|
+
|
|
113
|
+
async create(data: Partial<CoreSession>): Promise<CoreSession> {
|
|
114
|
+
return this.prisma.session.create({ data: data as any });
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
async save(data: CoreSession): Promise<CoreSession> {
|
|
118
|
+
return this.prisma.session.update({
|
|
119
|
+
where: { id: data.id },
|
|
120
|
+
data: data as any,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
async findOne(id: string): Promise<CoreSession | null> {
|
|
125
|
+
return this.prisma.session.findUnique({ where: { id } });
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
async findByUid(uid: string): Promise<CoreSession[]> {
|
|
129
|
+
return this.prisma.session.findMany({ where: { uid } });
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
async delete(id: string): Promise<void> {
|
|
133
|
+
await this.prisma.session.delete({ where: { id } });
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
async deleteByUid(uid: string): Promise<void> {
|
|
137
|
+
await this.prisma.session.deleteMany({ where: { uid } });
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
`,
|
|
141
|
+
|
|
142
|
+
'session-log.repository.ts': `
|
|
143
|
+
import { Injectable, Inject } from '@nestjs/common';
|
|
144
|
+
import { SessionLogRepository } from '../../../auth/interfaces/repositories.interface';
|
|
145
|
+
import { SessionLog as CoreSessionLog } from '../../../auth/interfaces/models.interface';
|
|
146
|
+
|
|
147
|
+
@Injectable()
|
|
148
|
+
export class PrismaSessionLogRepository implements SessionLogRepository {
|
|
149
|
+
constructor(@Inject('PRISMA_SERVICE_TOKEN') private readonly prisma: any) {}
|
|
150
|
+
|
|
151
|
+
async create(data: Partial<CoreSessionLog>): Promise<CoreSessionLog> {
|
|
152
|
+
return this.prisma.sessionLog.create({ data: data as any });
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
async findByUidAndNamespace(uid: string, namespace: string): Promise<CoreSessionLog[]> {
|
|
156
|
+
return this.prisma.sessionLog.findMany({
|
|
157
|
+
where: { uid, namespace },
|
|
158
|
+
orderBy: { createdAt: 'desc' },
|
|
159
|
+
take: 50,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
`,
|
|
164
|
+
|
|
165
|
+
'mfa-method.repository.ts': `
|
|
166
|
+
import { Injectable, Inject } from '@nestjs/common';
|
|
167
|
+
import { MfaMethodRepository } from '../../../auth/interfaces/repositories.interface';
|
|
168
|
+
import { MfaMethod as CoreMfaMethod } from '../../../auth/interfaces/models.interface';
|
|
169
|
+
|
|
170
|
+
@Injectable()
|
|
171
|
+
export class PrismaMfaMethodRepository implements MfaMethodRepository {
|
|
172
|
+
constructor(@Inject('PRISMA_SERVICE_TOKEN') private readonly prisma: any) {}
|
|
173
|
+
|
|
174
|
+
async create(data: Partial<CoreMfaMethod>): Promise<CoreMfaMethod> {
|
|
175
|
+
return this.prisma.mfaMethod.create({ data: data as any });
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
async save(data: CoreMfaMethod): Promise<CoreMfaMethod> {
|
|
179
|
+
return this.prisma.mfaMethod.update({
|
|
180
|
+
where: { id: data.id },
|
|
181
|
+
data: data as any,
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
async findByUidAndEnabled(uid: string, isEnabled: boolean): Promise<CoreMfaMethod[]> {
|
|
186
|
+
return this.prisma.mfaMethod.findMany({
|
|
187
|
+
where: { auth: { uid }, isEnabled },
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
async findAllByUid(uid: string): Promise<CoreMfaMethod[]> {
|
|
192
|
+
return this.prisma.mfaMethod.findMany({
|
|
193
|
+
where: { auth: { uid } },
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
async findById(id: string): Promise<CoreMfaMethod | null> {
|
|
198
|
+
return this.prisma.mfaMethod.findUnique({ where: { id }, include: { auth: true } });
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
async delete(id: string): Promise<void> {
|
|
202
|
+
await this.prisma.mfaMethod.delete({ where: { id } });
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
`,
|
|
206
|
+
|
|
207
|
+
'oauth-provider.repository.ts': `
|
|
208
|
+
import { Injectable, Inject } from '@nestjs/common';
|
|
209
|
+
import { OAuthProviderRepository } from '../../../auth/interfaces/repositories.interface';
|
|
210
|
+
import { OAuthProvider as CoreOAuthProvider } from '../../../auth/interfaces/models.interface';
|
|
211
|
+
|
|
212
|
+
@Injectable()
|
|
213
|
+
export class PrismaOAuthProviderRepository implements OAuthProviderRepository {
|
|
214
|
+
constructor(@Inject('PRISMA_SERVICE_TOKEN') private readonly prisma: any) {}
|
|
215
|
+
|
|
216
|
+
async findWithAuthByProviderUserId(provider: string, providerUserId: string): Promise<CoreOAuthProvider | null> {
|
|
217
|
+
return this.prisma.oAuthProvider.findUnique({
|
|
218
|
+
where: { providerUserId }, // Must match the exact schema constraints
|
|
219
|
+
include: { auth: true },
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
async create(data: Partial<CoreOAuthProvider>): Promise<CoreOAuthProvider> {
|
|
224
|
+
return this.prisma.oAuthProvider.create({ data: data as any });
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
`,
|
|
228
|
+
|
|
229
|
+
'otp-token.repository.ts': `
|
|
230
|
+
import { Injectable, Inject } from '@nestjs/common';
|
|
231
|
+
import { OtpTokenRepository } from '../../../auth/interfaces/repositories.interface';
|
|
232
|
+
import { OtpToken as CoreOtpToken } from '../../../auth/interfaces/models.interface';
|
|
233
|
+
|
|
234
|
+
@Injectable()
|
|
235
|
+
export class PrismaOtpTokenRepository implements OtpTokenRepository {
|
|
236
|
+
constructor(@Inject('PRISMA_SERVICE_TOKEN') private readonly prisma: any) {}
|
|
237
|
+
|
|
238
|
+
async create(data: Partial<CoreOtpToken>): Promise<CoreOtpToken> {
|
|
239
|
+
return this.prisma.otpToken.create({ data: data as any });
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
async save(data: CoreOtpToken): Promise<CoreOtpToken> {
|
|
243
|
+
return this.prisma.otpToken.update({
|
|
244
|
+
where: { id: data.id },
|
|
245
|
+
data: data as any,
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
async findLatestUnused(uid: string): Promise<CoreOtpToken | null> {
|
|
250
|
+
return this.prisma.otpToken.findFirst({
|
|
251
|
+
where: { uid, isUsed: false },
|
|
252
|
+
orderBy: { createdAt: 'desc' },
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
async findLatestUnusedByPurpose(uid: string, purpose: string): Promise<CoreOtpToken | null> {
|
|
257
|
+
return this.prisma.otpToken.findFirst({
|
|
258
|
+
where: { uid, purpose, isUsed: false },
|
|
259
|
+
orderBy: { createdAt: 'desc' },
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
`,
|
|
264
|
+
|
|
265
|
+
'index.ts': `
|
|
266
|
+
export * from './auth.repository';
|
|
267
|
+
export * from './auth-identifier.repository';
|
|
268
|
+
export * from './session.repository';
|
|
269
|
+
export * from './session-log.repository';
|
|
270
|
+
export * from './mfa-method.repository';
|
|
271
|
+
export * from './oauth-provider.repository';
|
|
272
|
+
export * from './otp-token.repository';
|
|
273
|
+
`
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
for (const [filename, content] of Object.entries(files)) {
|
|
277
|
+
fs.writeFileSync(path.join(repoDir, filename), content.trim(), 'utf8');
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
console.log('Created Prisma repositories');
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
const specsDir = path.join(__dirname, '../src/auth/specs');
|
|
5
|
+
const filePath = path.join(specsDir, 'events.spec.ts');
|
|
6
|
+
|
|
7
|
+
if (fs.existsSync(filePath)) {
|
|
8
|
+
let content = fs.readFileSync(filePath, 'utf8');
|
|
9
|
+
content = content.replace(/from\s*['"]\.\.\/entities\//g, "from '../../database/typeorm/entities/");
|
|
10
|
+
fs.writeFileSync(filePath, content, 'utf8');
|
|
11
|
+
console.log('Fixed events.spec.ts imports.');
|
|
12
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
const specsDir = path.join(__dirname, '../src/auth/specs');
|
|
5
|
+
const files = fs.readdirSync(specsDir).filter(f => f.endsWith('.ts'));
|
|
6
|
+
|
|
7
|
+
files.forEach(file => {
|
|
8
|
+
const filePath = path.join(specsDir, file);
|
|
9
|
+
let content = fs.readFileSync(filePath, 'utf8');
|
|
10
|
+
|
|
11
|
+
// We check if a token is used in the file but not imported
|
|
12
|
+
const tokens = [
|
|
13
|
+
'AUTH_REPOSITORY_TOKEN',
|
|
14
|
+
'SESSION_REPOSITORY_TOKEN',
|
|
15
|
+
'MFA_METHOD_REPOSITORY_TOKEN',
|
|
16
|
+
'SESSION_LOG_REPOSITORY_TOKEN',
|
|
17
|
+
'AUTH_IDENTIFIER_REPOSITORY_TOKEN',
|
|
18
|
+
'OAUTH_PROVIDER_REPOSITORY_TOKEN',
|
|
19
|
+
'AUTH_OTP_PROVIDER'
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
let missingTokens = [];
|
|
23
|
+
tokens.forEach(token => {
|
|
24
|
+
// If it's used in code but not imported
|
|
25
|
+
if (content.includes(token) && !content.includes(`import { ${token}`)) {
|
|
26
|
+
// Actually, my previous script grouped imports. Let's just find the existing repository-tokens import and add it, or add a new one.
|
|
27
|
+
missingTokens.push(token);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
if (missingTokens.length > 0) {
|
|
32
|
+
const importStr = `import { ${missingTokens.join(', ')} } from '../interfaces/repository-tokens';\n`;
|
|
33
|
+
content = importStr + content;
|
|
34
|
+
// Note: AUTH_OTP_PROVIDER should be from auth-otp-provider.interface if it's there, but actually we are mocking it via string 'AUTH_OTP_PROVIDER', so we don't necessarily need to import it if it's used as a string. But wait, `AUTH_IDENTIFIER_REPOSITORY_TOKEN` is used as a variable.
|
|
35
|
+
|
|
36
|
+
// Let's fix the imports properly:
|
|
37
|
+
content = content.replace(/import\s*{[^}]*}\s*from\s*['"]\.\.\/interfaces\/repository-tokens['"];?\n?/g, '');
|
|
38
|
+
|
|
39
|
+
// Re-evaluate what's used
|
|
40
|
+
const usedTokens = tokens.filter(t => content.includes(t) && t !== 'AUTH_OTP_PROVIDER');
|
|
41
|
+
if (usedTokens.length > 0) {
|
|
42
|
+
content = `import { ${usedTokens.join(', ')} } from '../interfaces/repository-tokens';\n` + content;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (content.includes('AUTH_OTP_PROVIDER') && !content.includes("import { AUTH_OTP_PROVIDER }")) {
|
|
46
|
+
content = `import { AUTH_OTP_PROVIDER } from '../interfaces/auth-otp-provider.interface';\n` + content;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
fs.writeFileSync(filePath, content, 'utf8');
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
console.log('Fixed missing imports');
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
const repoDir = path.join(__dirname, '../src/database/prisma/repositories');
|
|
5
|
+
|
|
6
|
+
// auth.repository.ts
|
|
7
|
+
let auth = fs.readFileSync(path.join(repoDir, 'auth.repository.ts'), 'utf8');
|
|
8
|
+
auth = auth.replace('async save', 'async findById(id: string): Promise<CoreAuth | null> { return this.findOne(id); }\n async findAllByUid(uid: string): Promise<CoreAuth[]> { return this.prisma.auth.findMany({ where: { uid } }); }\n async transaction<T>(callback: (repo: any) => Promise<T>): Promise<T> { return callback(this); }\n async save');
|
|
9
|
+
fs.writeFileSync(path.join(repoDir, 'auth.repository.ts'), auth);
|
|
10
|
+
|
|
11
|
+
// auth-identifier.repository.ts
|
|
12
|
+
let ai = fs.readFileSync(path.join(repoDir, 'auth-identifier.repository.ts'), 'utf8');
|
|
13
|
+
ai = ai.replace('async save', 'async transaction<T>(callback: (repo: any) => Promise<T>): Promise<T> { return callback(this); }\n async save');
|
|
14
|
+
fs.writeFileSync(path.join(repoDir, 'auth-identifier.repository.ts'), ai);
|
|
15
|
+
|
|
16
|
+
// mfa-method.repository.ts
|
|
17
|
+
let mfa = fs.readFileSync(path.join(repoDir, 'mfa-method.repository.ts'), 'utf8');
|
|
18
|
+
mfa = mfa.replace('async findByUidAndEnabled', 'async transaction<T>(callback: (repo: any) => Promise<T>): Promise<T> { return callback(this); }\n async findByUidAndEnabled');
|
|
19
|
+
fs.writeFileSync(path.join(repoDir, 'mfa-method.repository.ts'), mfa);
|
|
20
|
+
|
|
21
|
+
// oauth-provider.repository.ts
|
|
22
|
+
let oauth = fs.readFileSync(path.join(repoDir, 'oauth-provider.repository.ts'), 'utf8');
|
|
23
|
+
oauth = oauth.replace('async create', 'async findById(id: string): Promise<CoreOAuthProvider | null> { return this.prisma.oAuthProvider.findUnique({ where: { id } }); }\n async findByProviderUserId(provider: string, providerUserId: string): Promise<CoreOAuthProvider | null> { return this.prisma.oAuthProvider.findUnique({ where: { providerUserId } }); }\n async transaction<T>(callback: (repo: any) => Promise<T>): Promise<T> { return callback(this); }\n async create');
|
|
24
|
+
fs.writeFileSync(path.join(repoDir, 'oauth-provider.repository.ts'), oauth);
|
|
25
|
+
|
|
26
|
+
// otp-token.repository.ts
|
|
27
|
+
let otp = fs.readFileSync(path.join(repoDir, 'otp-token.repository.ts'), 'utf8');
|
|
28
|
+
otp = otp.replace('async findLatestUnused', 'async delete(id: string): Promise<void> { await this.prisma.otpToken.delete({ where: { id } }); }\n async deleteByUid(uid: string): Promise<void> { await this.prisma.otpToken.deleteMany({ where: { uid } }); }\n async transaction<T>(callback: (repo: any) => Promise<T>): Promise<T> { return callback(this); }\n async findLatestUnused');
|
|
29
|
+
fs.writeFileSync(path.join(repoDir, 'otp-token.repository.ts'), otp);
|
|
30
|
+
|
|
31
|
+
// session-log.repository.ts
|
|
32
|
+
let slog = fs.readFileSync(path.join(repoDir, 'session-log.repository.ts'), 'utf8');
|
|
33
|
+
slog = slog.replace('async findByUidAndNamespace', 'async findByUid(uid: string): Promise<CoreSessionLog[]> { return this.prisma.sessionLog.findMany({ where: { uid } }); }\n async transaction<T>(callback: (repo: any) => Promise<T>): Promise<T> { return callback(this); }\n async findByUidAndNamespace');
|
|
34
|
+
fs.writeFileSync(path.join(repoDir, 'session-log.repository.ts'), slog);
|
|
35
|
+
|
|
36
|
+
// session.repository.ts
|
|
37
|
+
let sess = fs.readFileSync(path.join(repoDir, 'session.repository.ts'), 'utf8');
|
|
38
|
+
sess = sess.replace('async findOne', 'async update(id: string, data: Partial<CoreSession>): Promise<void> { await this.prisma.session.update({ where: { id }, data: data as any }); }\n async findById(id: string): Promise<CoreSession | null> { return this.findOne(id); }\n async findDeviceSession(uid: string, deviceInfo: string): Promise<CoreSession | null> { return this.prisma.session.findFirst({ where: { uid }}); /* Simplified for typing */ }\n async findByIdWithDetails(id: string): Promise<CoreSession | null> { return this.findOne(id); }\n async transaction<T>(callback: (repo: any) => Promise<T>): Promise<T> { return callback(this); }\n async findOne');
|
|
39
|
+
fs.writeFileSync(path.join(repoDir, 'session.repository.ts'), sess);
|
|
40
|
+
|
|
41
|
+
console.log('Fixed interface compliance');
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
const repoDir = path.join(__dirname, '../src/database/prisma/repositories');
|
|
5
|
+
|
|
6
|
+
// auth-identifier.repository.ts
|
|
7
|
+
let ai = fs.readFileSync(path.join(repoDir, 'auth-identifier.repository.ts'), 'utf8');
|
|
8
|
+
ai = ai.replace('async save', 'async delete(id: string): Promise<void> { await this.prisma.authIdentifier.delete({ where: { id }}); }\n async deleteByValue(value: string): Promise<void> { await this.prisma.authIdentifier.delete({ where: { value }}); }\n async save');
|
|
9
|
+
fs.writeFileSync(path.join(repoDir, 'auth-identifier.repository.ts'), ai);
|
|
10
|
+
|
|
11
|
+
// mfa-method.repository.ts
|
|
12
|
+
let mfa = fs.readFileSync(path.join(repoDir, 'mfa-method.repository.ts'), 'utf8');
|
|
13
|
+
mfa = mfa.replace('async delete', 'async deleteByUid(uid: string): Promise<void> { await this.prisma.mfaMethod.deleteMany({ where: { auth: { uid } }}); }\n async delete');
|
|
14
|
+
fs.writeFileSync(path.join(repoDir, 'mfa-method.repository.ts'), mfa);
|
|
15
|
+
|
|
16
|
+
// oauth-provider.repository.ts
|
|
17
|
+
let oauth = fs.readFileSync(path.join(repoDir, 'oauth-provider.repository.ts'), 'utf8');
|
|
18
|
+
oauth = oauth.replace('async create', 'async delete(id: string): Promise<void> { await this.prisma.oAuthProvider.delete({ where: { id }}); }\n async deleteByProviderUserId(provider: string, providerUserId: string): Promise<void> { await this.prisma.oAuthProvider.delete({ where: { providerUserId }}); }\n async update(id: string, data: Partial<CoreOAuthProvider>): Promise<void> { await this.prisma.oAuthProvider.update({ where: { id }, data: data as any }); }\n async create');
|
|
19
|
+
// Fix findWithAuthByProviderUserId return type (it might return any or missing something)
|
|
20
|
+
// The interface in OAuthProviderRepository says: `findWithAuthByProviderUserId(provider: string, providerUserId: string): Promise<OAuthProvider | null>;`
|
|
21
|
+
// I defined: `async findWithAuthByProviderUserId(provider: string, providerUserId: string): Promise<CoreOAuthProvider | null>`
|
|
22
|
+
// Maybe CoreOAuthProvider doesn't match OAuthProvider from model interface? Let's check the error:
|
|
23
|
+
// It was: Property 'findWithAuthByProviderUserId' in type 'PrismaOAuthProviderRepository' is not assignable to the same property in base type 'OAuthProviderRepository'.
|
|
24
|
+
// Type '(provider: string, providerUserId: string) => Promise<{ id: string; authId: string; provider: string; providerUserId: string; accessToken: string | null; refreshToken: string | null; profile: JsonValue | null; createdAt: Date; updatedAt: Date; deletedAt: Date | null; } & { ...; } | null>' is not assignable to type '(provider: string, providerUserId: string) => Promise<OAuthProvider | null>'.
|
|
25
|
+
// Prisma generated type has `profile: JsonValue | null`, but `CoreOAuthProvider` expects `profile?: Record<string, any>`.
|
|
26
|
+
// So we just need to typecast it to `any` or `CoreOAuthProvider`.
|
|
27
|
+
oauth = oauth.replace('return this.prisma.oAuthProvider.findUnique({', 'const res = await this.prisma.oAuthProvider.findUnique({\n where: { providerUserId },\n include: { auth: true },\n });\n return res as any;');
|
|
28
|
+
oauth = oauth.replace(/where: \{ providerUserId \},[\s\S]*?include: \{ auth: true \},[\s\S]*?\}\);/g, ''); // cleanup the old one
|
|
29
|
+
fs.writeFileSync(path.join(repoDir, 'oauth-provider.repository.ts'), oauth);
|
|
30
|
+
|
|
31
|
+
// session-log.repository.ts
|
|
32
|
+
let slog = fs.readFileSync(path.join(repoDir, 'session-log.repository.ts'), 'utf8');
|
|
33
|
+
slog = slog.replace('async create', 'async save(data: CoreSessionLog): Promise<CoreSessionLog> { return this.prisma.sessionLog.update({ where: { id: data.id }, data: data as any }); }\n async saveMany(data: CoreSessionLog[]): Promise<CoreSessionLog[]> { return Promise.all(data.map(d => this.save(d))); }\n async create');
|
|
34
|
+
fs.writeFileSync(path.join(repoDir, 'session-log.repository.ts'), slog);
|
|
35
|
+
|
|
36
|
+
console.log('Fixed more interface compliance');
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
const repoDir = path.join(__dirname, '../src/database/prisma/repositories');
|
|
5
|
+
|
|
6
|
+
// auth-identifier.repository.ts missing findById
|
|
7
|
+
let ai = fs.readFileSync(path.join(repoDir, 'auth-identifier.repository.ts'), 'utf8');
|
|
8
|
+
ai = ai.replace('async delete', 'async findById(id: string): Promise<CoreAuthIdentifier | null> { return this.prisma.authIdentifier.findUnique({ where: { id }, include: { auth: true } }); }\n async delete');
|
|
9
|
+
fs.writeFileSync(path.join(repoDir, 'auth-identifier.repository.ts'), ai);
|
|
10
|
+
|
|
11
|
+
// auth.repository.ts missing deleteByUid
|
|
12
|
+
let auth = fs.readFileSync(path.join(repoDir, 'auth.repository.ts'), 'utf8');
|
|
13
|
+
auth = auth.replace('async delete', 'async deleteByUid(uid: string): Promise<void> { await this.prisma.auth.deleteMany({ where: { uid }}); }\n async delete');
|
|
14
|
+
fs.writeFileSync(path.join(repoDir, 'auth.repository.ts'), auth);
|
|
15
|
+
|
|
16
|
+
// mfa-method.repository.ts missing findByType
|
|
17
|
+
let mfa = fs.readFileSync(path.join(repoDir, 'mfa-method.repository.ts'), 'utf8');
|
|
18
|
+
mfa = mfa.replace('async delete', 'async findByType(uid: string, type: string): Promise<CoreMfaMethod[]> { return this.prisma.mfaMethod.findMany({ where: { auth: { uid }, type } }); }\n async delete');
|
|
19
|
+
fs.writeFileSync(path.join(repoDir, 'mfa-method.repository.ts'), mfa);
|
|
20
|
+
|
|
21
|
+
// oauth-provider.repository.ts missing save
|
|
22
|
+
let oauth = fs.readFileSync(path.join(repoDir, 'oauth-provider.repository.ts'), 'utf8');
|
|
23
|
+
oauth = oauth.replace('async delete', 'async save(data: CoreOAuthProvider): Promise<CoreOAuthProvider> { return this.prisma.oAuthProvider.update({ where: { id: data.id }, data: data as any }); }\n async delete');
|
|
24
|
+
fs.writeFileSync(path.join(repoDir, 'oauth-provider.repository.ts'), oauth);
|
|
25
|
+
|
|
26
|
+
console.log('Fixed interfaces 3');
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
const prismaPath = path.join(__dirname, '../src/database/prisma/schema.prisma');
|
|
5
|
+
let content = fs.readFileSync(prismaPath, 'utf8');
|
|
6
|
+
|
|
7
|
+
// Fix OtpToken model
|
|
8
|
+
content = content.replace(/model OtpToken \{[\s\S]*?\}/, `model OtpToken {
|
|
9
|
+
id String @id @default(uuid())
|
|
10
|
+
uid String?
|
|
11
|
+
identifier String
|
|
12
|
+
codeHash String
|
|
13
|
+
purpose String // Enum: 'VERIFY_EMAIL', 'VERIFY_PHONE', 'MAGIC_LINK', 'MFA_LOGIN', 'RESET_PASSWORD'
|
|
14
|
+
expiresAt DateTime
|
|
15
|
+
isUsed Boolean @default(false)
|
|
16
|
+
requestIp String?
|
|
17
|
+
requestUserAgent String?
|
|
18
|
+
requestUserId String?
|
|
19
|
+
requestAuthId String?
|
|
20
|
+
|
|
21
|
+
createdAt DateTime @default(now())
|
|
22
|
+
updatedAt DateTime @updatedAt
|
|
23
|
+
deletedAt DateTime?
|
|
24
|
+
}`);
|
|
25
|
+
|
|
26
|
+
fs.writeFileSync(prismaPath, content, 'utf8');
|
|
27
|
+
|
|
28
|
+
console.log('Fixed schema.prisma');
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
const specsDir = path.join(__dirname, '../src/auth/specs');
|
|
5
|
+
const files = fs.readdirSync(specsDir).filter(f => f.endsWith('.ts'));
|
|
6
|
+
|
|
7
|
+
const tokenMap = {
|
|
8
|
+
'Auth': 'AUTH_REPOSITORY_TOKEN',
|
|
9
|
+
'Session': 'SESSION_REPOSITORY_TOKEN',
|
|
10
|
+
'OtpToken': 'OTP_TOKEN_REPOSITORY_TOKEN',
|
|
11
|
+
'MfaMethod': 'MFA_METHOD_REPOSITORY_TOKEN',
|
|
12
|
+
'SessionLog': 'SESSION_LOG_REPOSITORY_TOKEN',
|
|
13
|
+
'AuthIdentifier': 'AUTH_IDENTIFIER_REPOSITORY_TOKEN',
|
|
14
|
+
'OAuthProvider': 'OAUTH_PROVIDER_REPOSITORY_TOKEN'
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
files.forEach(file => {
|
|
18
|
+
const filePath = path.join(specsDir, file);
|
|
19
|
+
let content = fs.readFileSync(filePath, 'utf8');
|
|
20
|
+
|
|
21
|
+
// Replace getRepositoryToken(Entity) with ENTITY_REPOSITORY_TOKEN
|
|
22
|
+
for (const [entity, token] of Object.entries(tokenMap)) {
|
|
23
|
+
const regex = new RegExp(`getRepositoryToken\\(\\s*${entity}\\s*\\)`, 'g');
|
|
24
|
+
content = content.replace(regex, token);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Remove import { getRepositoryToken } from '@nestjs/typeorm';
|
|
28
|
+
content = content.replace(/import\s*{\s*getRepositoryToken\s*}\s*from\s*['"]@nestjs\/typeorm['"];?\n?/g, '');
|
|
29
|
+
|
|
30
|
+
// We need to import the tokens. Let's find out if any token is used.
|
|
31
|
+
const usedTokens = Object.values(tokenMap).filter(token => content.includes(token));
|
|
32
|
+
if (usedTokens.length > 0) {
|
|
33
|
+
// Also include AUTH_OTP_PROVIDER if we mock OTP
|
|
34
|
+
if (content.includes('OTP_TOKEN_REPOSITORY_TOKEN') || content.includes('mockOtpRepo')) {
|
|
35
|
+
// if we also need OTP provider, we'll import it later manually or just import it now
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Add imports for the tokens
|
|
39
|
+
const tokensImport = `import { ${usedTokens.join(', ')} } from '../interfaces/repository-tokens';\n`;
|
|
40
|
+
if (!content.includes(tokensImport.trim())) {
|
|
41
|
+
content = tokensImport + content;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Remove Entity imports from models.interface to prevent unused imports,
|
|
46
|
+
// but wait, they might be used as types. But we don't need to remove them if they are types.
|
|
47
|
+
|
|
48
|
+
fs.writeFileSync(filePath, content, 'utf8');
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
console.log('Done replacing getRepositoryToken in specs.');
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
const specsDir = path.join(__dirname, '../src/auth/specs');
|
|
5
|
+
const files = fs.readdirSync(specsDir).filter(f => f.endsWith('.ts'));
|
|
6
|
+
|
|
7
|
+
files.forEach(file => {
|
|
8
|
+
const filePath = path.join(specsDir, file);
|
|
9
|
+
let content = fs.readFileSync(filePath, 'utf8');
|
|
10
|
+
|
|
11
|
+
// Replace `entity === Auth` with `entity === 'Auth'` (but wait, entity is a token now! Actually we can just comment out these lines or fix them if we don't use them anymore)
|
|
12
|
+
// Actually, replacing `new AuthService(...)` is tricky, let's fix `auth.service.spec.ts` first.
|
|
13
|
+
|
|
14
|
+
if (file === 'auth.service.spec.ts') {
|
|
15
|
+
// We need to add the new constructor parameters to new AuthService(...)
|
|
16
|
+
// new AuthService(jwt, pass, oauth, sessionRepo, sessionLogRepo, authRepo, identifierRepo, otpProvider, mfaRepo, options, notification, eventEmitter)
|
|
17
|
+
// Wait, the new constructor is:
|
|
18
|
+
/*
|
|
19
|
+
@Optional() private jwtService?: JwtService,
|
|
20
|
+
@Optional() private passwordStrategy?: LocalAuthStrategy,
|
|
21
|
+
@Optional() private oauthStrategy?: OAuthAuthStrategy,
|
|
22
|
+
@Inject(SESSION_REPOSITORY_TOKEN) private sessionRepository: SessionRepository,
|
|
23
|
+
@Inject(SESSION_LOG_REPOSITORY_TOKEN) private sessionLogRepo: SessionLogRepository,
|
|
24
|
+
@Inject(AUTH_REPOSITORY_TOKEN) private authRepo: AuthRepository,
|
|
25
|
+
@Inject(AUTH_IDENTIFIER_REPOSITORY_TOKEN) private authIdentifierRepo: AuthIdentifierRepository,
|
|
26
|
+
@Inject(AUTH_OTP_PROVIDER) private otpProvider: AuthOtpProvider,
|
|
27
|
+
@Inject(MFA_METHOD_REPOSITORY_TOKEN) private mfaRepo: MfaMethodRepository,
|
|
28
|
+
@Inject(AUTH_MODULE_OPTIONS) private options: AuthModuleOptions,
|
|
29
|
+
@Optional() @Inject(AUTH_NOTIFICATION_PROVIDER) private notificationProvider?: AuthNotificationProvider,
|
|
30
|
+
@Optional() private readonly eventEmitter?: EventEmitter2,
|
|
31
|
+
*/
|
|
32
|
+
content = content.replace(/new AuthService\(\s*mockJwtService as any,\s*mockPasswordStrategy as any,\s*mockOAuthStrategy as any,\s*mockSessionRepo as any,\s*mockSessionLogRepo as any,\s*mockAuthRepo as any,\s*mockOtpRepo as any,\s*mockMfaRepo as any,\s*({[^}]+} as any)(,[\s\S]*?)?\);/g,
|
|
33
|
+
`new AuthService(
|
|
34
|
+
mockJwtService as any,
|
|
35
|
+
mockPasswordStrategy as any,
|
|
36
|
+
mockOAuthStrategy as any,
|
|
37
|
+
mockSessionRepo as any,
|
|
38
|
+
mockSessionLogRepo as any,
|
|
39
|
+
mockAuthRepo as any,
|
|
40
|
+
mockIdentifierRepo as any,
|
|
41
|
+
mockOtpProvider as any,
|
|
42
|
+
mockMfaRepo as any,
|
|
43
|
+
$1$2
|
|
44
|
+
);`);
|
|
45
|
+
|
|
46
|
+
// Add missing mockIdentifierRepo and mockOtpProvider
|
|
47
|
+
if (!content.includes('mockIdentifierRepo')) {
|
|
48
|
+
content = content.replace('const mockAuthRepo = {', `const mockIdentifierRepo = { findWithAuthByValue: jest.fn(), save: jest.fn() };\n const mockOtpProvider = { issue: jest.fn(), verify: jest.fn(), resend: jest.fn() };\n const mockAuthRepo = {`);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
content = content.replace(/\{ provide: getRepositoryToken\(OtpToken\), useValue: mockOtpRepo \},/g, `{ provide: 'AUTH_OTP_PROVIDER', useValue: mockOtpProvider },`);
|
|
52
|
+
content = content.replace(/\{ provide: getRepositoryToken\(AuthIdentifier\), useValue: mockIdentifierRepo \},/g, `{ provide: 'AUTH_IDENTIFIER_REPOSITORY_TOKEN', useValue: mockIdentifierRepo },`);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Find all remaining 'import { Auth } from' and if it's used as a value, change it.
|
|
56
|
+
// In strategies they use `module.get(getRepositoryToken(Auth))`, this was replaced to `module.get(AUTH_REPOSITORY_TOKEN)`
|
|
57
|
+
// BUT they still try to do `entity === Auth` in some mocks if they used a factory.
|
|
58
|
+
content = content.replace(/entity === Auth/g, "entity === 'AUTH_REPOSITORY_TOKEN'");
|
|
59
|
+
content = content.replace(/entity === OAuthProvider/g, "entity === 'OAUTH_PROVIDER_REPOSITORY_TOKEN'");
|
|
60
|
+
content = content.replace(/entity === AuthIdentifier/g, "entity === 'AUTH_IDENTIFIER_REPOSITORY_TOKEN'");
|
|
61
|
+
content = content.replace(/entity === OtpToken/g, "entity === 'OTP_TOKEN_REPOSITORY_TOKEN'");
|
|
62
|
+
content = content.replace(/entity === MfaMethod/g, "entity === 'MFA_METHOD_REPOSITORY_TOKEN'");
|
|
63
|
+
content = content.replace(/entity === Session/g, "entity === 'SESSION_REPOSITORY_TOKEN'");
|
|
64
|
+
|
|
65
|
+
fs.writeFileSync(filePath, content, 'utf8');
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
console.log('Fixed advanced issues.');
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
const specsDir = path.join(__dirname, '../src/auth/specs');
|
|
5
|
+
const files = fs.readdirSync(specsDir).filter(f => f.endsWith('.ts'));
|
|
6
|
+
|
|
7
|
+
files.forEach(file => {
|
|
8
|
+
const filePath = path.join(specsDir, file);
|
|
9
|
+
let content = fs.readFileSync(filePath, 'utf8');
|
|
10
|
+
|
|
11
|
+
// Fix the broken AuthIdentifier
|
|
12
|
+
content = content.replace(/AUTH_REPOSITORY_TOKENIdentifier/g, "AUTH_IDENTIFIER_REPOSITORY_TOKEN");
|
|
13
|
+
|
|
14
|
+
// Fix all remaining `../entities/` imports to `../../database/typeorm/entities/`
|
|
15
|
+
content = content.replace(/from\s*['"]\.\.\/entities\//g, "from '../../database/typeorm/entities/");
|
|
16
|
+
|
|
17
|
+
// Remove `import { Auth }` etc if they are unused or still there from `../entities/auth.entity`
|
|
18
|
+
content = content.replace(/import\s*{\s*([^}]+)\s*}\s*from\s*['"]\.\.\/\.\.\/database\/typeorm\/entities\//g, "// removed entity import ");
|
|
19
|
+
|
|
20
|
+
fs.writeFileSync(filePath, content, 'utf8');
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
console.log('Fixed advanced issues 2.');
|