@ackplus/nest-auth 1.1.19 → 1.1.21
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/package.json +1 -1
- package/src/lib/audit/services/audit.service.d.ts +15 -0
- package/src/lib/audit/services/audit.service.d.ts.map +1 -0
- package/src/lib/audit/services/audit.service.js +143 -0
- package/src/lib/auth/controllers/auth.controller.d.ts +1 -1
- package/src/lib/auth/events/index.d.ts +13 -0
- package/src/lib/auth/events/index.d.ts.map +1 -0
- package/src/lib/auth/events/index.js +15 -0
- package/src/lib/auth/events/user-2fa-disabled.event.d.ts +10 -0
- package/src/lib/auth/events/user-2fa-disabled.event.d.ts.map +1 -0
- package/src/lib/auth/events/user-2fa-disabled.event.js +12 -0
- package/src/lib/auth/events/user-2fa-enabled.event.d.ts +13 -0
- package/src/lib/auth/events/user-2fa-enabled.event.d.ts.map +1 -0
- package/src/lib/auth/events/user-2fa-enabled.event.js +15 -0
- package/src/lib/auth/events/user-password-changed.event.d.ts +12 -0
- package/src/lib/auth/events/user-password-changed.event.d.ts.map +1 -0
- package/src/lib/auth/events/user-password-changed.event.js +15 -0
- package/src/lib/auth/guards/auth.guard.d.ts +19 -1
- package/src/lib/auth/guards/auth.guard.d.ts.map +1 -1
- package/src/lib/auth/guards/auth.guard.js +90 -17
- package/src/lib/auth/services/auth.service.d.ts +10 -6
- package/src/lib/auth/services/auth.service.d.ts.map +1 -1
- package/src/lib/auth/services/auth.service.js +148 -95
- package/src/lib/auth/services/mfa.service.d.ts +1 -1
- package/src/lib/auth/services/mfa.service.d.ts.map +1 -1
- package/src/lib/auth/services/mfa.service.js +27 -2
- package/src/lib/auth.constants.d.ts +3 -0
- package/src/lib/auth.constants.d.ts.map +1 -1
- package/src/lib/auth.constants.js +3 -0
- package/src/lib/core/interfaces/auth-module-options.interface.d.ts +3 -3
- package/src/lib/core/interfaces/auth-module-options.interface.d.ts.map +1 -1
- package/src/lib/core/services/auth-config.service.js +1 -1
- package/src/lib/nest-auth.module.d.ts.map +1 -1
- package/src/lib/nest-auth.module.js +5 -2
- package/src/lib/session/services/session-manager.service.d.ts +3 -3
- package/src/lib/session/services/session-manager.service.d.ts.map +1 -1
- package/src/lib/session/services/session-manager.service.js +27 -4
- package/src/lib/user/entities/user.entity.d.ts.map +1 -1
- package/src/lib/user/entities/user.entity.js +19 -0
- package/src/lib/user/events/user-created.event.d.ts +1 -0
- package/src/lib/user/events/user-created.event.d.ts.map +1 -1
- package/src/lib/user/services/user.service.d.ts +7 -7
- package/src/lib/user/services/user.service.d.ts.map +1 -1
- package/src/lib/user/services/user.service.js +49 -56
|
@@ -8,10 +8,10 @@ export declare const SESSION_REPOSITORY = "SESSION_REPOSITORY";
|
|
|
8
8
|
*/
|
|
9
9
|
export declare class SessionManagerService {
|
|
10
10
|
private readonly repository;
|
|
11
|
-
private options;
|
|
12
|
-
private readonly maxSessionsPerUser;
|
|
13
|
-
private readonly slidingExpiration;
|
|
14
11
|
constructor(repository: ISessionRepository);
|
|
12
|
+
private get options();
|
|
13
|
+
private get maxSessionsPerUser();
|
|
14
|
+
private get slidingExpiration();
|
|
15
15
|
/**
|
|
16
16
|
* Create a new session
|
|
17
17
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-manager.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/nest-auth/src/lib/session/services/session-manager.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,4CAA4C,CAAC;AAChF,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAK7D,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAI/D,eAAO,MAAM,kBAAkB,uBAAuB,CAAC;AAEvD;;;GAGG;AACH,qBACa,qBAAqB;
|
|
1
|
+
{"version":3,"file":"session-manager.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/nest-auth/src/lib/session/services/session-manager.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,4CAA4C,CAAC;AAChF,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAK7D,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAI/D,eAAO,MAAM,kBAAkB,uBAAuB,CAAC;AAEvD;;;GAGG;AACH,qBACa,qBAAqB;IAG1B,OAAO,CAAC,QAAQ,CAAC,UAAU;gBAAV,UAAU,EAAE,kBAAkB;IAGnD,OAAO,KAAK,OAAO,GAElB;IAED,OAAO,KAAK,kBAAkB,GAE7B;IAED,OAAO,KAAK,iBAAiB,GAE5B;IAED;;OAEG;IACG,aAAa,CAAC,OAAO,EAAE;QACzB,MAAM,EAAE,MAAM,CAAC;QACf,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,IAAI,CAAC,EAAE,GAAG,CAAC;QACX,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,MAAM,CAAC;KACtB,GAAG,OAAO,CAAC,eAAe,CAAC;IA+B5B;;OAEG;IACG,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,cAAc,UAAO,GAAG,OAAO,CAAC,eAAe,CAAC;IAqBpF;;OAEG;IACG,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAIjE;;OAEG;IACG,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAInE;;OAEG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC;IAInG;;OAEG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAerD;;OAEG;IACG,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1D;;OAEG;IACG,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUlF;;OAEG;IACG,sBAAsB,IAAI,OAAO,CAAC,MAAM,CAAC;IAI/C;;OAEG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAKnF;;OAEG;IACG,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAQzE;;OAEG;IACG,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAK7D;;OAEG;YACW,kBAAkB;IAmBhC;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAM3B;;OAEG;IACH,OAAO,CAAC,SAAS;IAKjB;;;OAGG;IACG,qBAAqB,CAAC,IAAI,EAAE,YAAY,EAAE,SAAS,GAAE;QAAE,aAAa,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,OAAO,CAAC,eAAe,CAAC;IAkCtH;;;OAGG;IACG,cAAc,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC;IAiBxE;;;OAGG;IACG,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;CAGvE"}
|
|
@@ -15,9 +15,15 @@ exports.SESSION_REPOSITORY = 'SESSION_REPOSITORY';
|
|
|
15
15
|
let SessionManagerService = class SessionManagerService {
|
|
16
16
|
constructor(repository) {
|
|
17
17
|
this.repository = repository;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
}
|
|
19
|
+
get options() {
|
|
20
|
+
return auth_config_service_1.AuthConfigService.getOptions();
|
|
21
|
+
}
|
|
22
|
+
get maxSessionsPerUser() {
|
|
23
|
+
return this.options.session?.maxSessionsPerUser || 10;
|
|
24
|
+
}
|
|
25
|
+
get slidingExpiration() {
|
|
26
|
+
return this.options.session?.slidingExpiration ?? true;
|
|
21
27
|
}
|
|
22
28
|
/**
|
|
23
29
|
* Create a new session
|
|
@@ -37,7 +43,15 @@ let SessionManagerService = class SessionManagerService {
|
|
|
37
43
|
ipAddress: ipAddress || request_context_1.RequestContext.getDeviceInfo().ipAddress,
|
|
38
44
|
lastActive: new Date(),
|
|
39
45
|
};
|
|
40
|
-
|
|
46
|
+
const session = await this.repository.create(sessionPayload);
|
|
47
|
+
// Apply onCreated hook if configured
|
|
48
|
+
if (this.options.session?.onCreated) {
|
|
49
|
+
// We need to pass the user object if available.
|
|
50
|
+
// The payload might have data.user if it came from createSessionFromUser
|
|
51
|
+
const user = data?.user;
|
|
52
|
+
await this.options.session.onCreated(session, user);
|
|
53
|
+
}
|
|
54
|
+
return session;
|
|
41
55
|
}
|
|
42
56
|
/**
|
|
43
57
|
* Get session by ID and optionally refresh it
|
|
@@ -80,7 +94,16 @@ let SessionManagerService = class SessionManagerService {
|
|
|
80
94
|
* Revoke (delete) a session
|
|
81
95
|
*/
|
|
82
96
|
async revokeSession(sessionId) {
|
|
97
|
+
// Get session before deleting to pass to hook
|
|
98
|
+
let session = null;
|
|
99
|
+
if (this.options.session?.onRevoked) {
|
|
100
|
+
session = await this.repository.findById(sessionId);
|
|
101
|
+
}
|
|
83
102
|
await this.repository.delete(sessionId);
|
|
103
|
+
// Apply onRevoked hook if configured
|
|
104
|
+
if (this.options.session?.onRevoked && session) {
|
|
105
|
+
await this.options.session.onRevoked(session, 'admin'); // Default reason, could be passed as arg
|
|
106
|
+
}
|
|
84
107
|
}
|
|
85
108
|
/**
|
|
86
109
|
* Revoke all sessions for a user
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user.entity.d.ts","sourceRoot":"","sources":["../../../../../../../packages/nest-auth/src/lib/user/entities/user.entity.ts"],"names":[],"mappings":"AAAA,OAAO,EAQH,UAAU,EAMb,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"user.entity.d.ts","sourceRoot":"","sources":["../../../../../../../packages/nest-auth/src/lib/user/entities/user.entity.ts"],"names":[],"mappings":"AAAA,OAAO,EAQH,UAAU,EAMb,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AAExE,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAE/D,qBACa,YAAa,SAAQ,UAAU;IAExC,EAAE,EAAE,MAAM,CAAC;IAIX,KAAK,EAAE,MAAM,CAAC;IAId,eAAe,EAAE,IAAI,CAAC;IAItB,KAAK,EAAE,MAAM,CAAC;IAId,eAAe,EAAE,IAAI,CAAC;IAGtB,YAAY,EAAE,MAAM,CAAC;IAGrB,UAAU,EAAE,OAAO,CAAC;IAGpB,QAAQ,EAAE,OAAO,CAAC;IAGlB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAG/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAGlB,YAAY,EAAE,OAAO,CAAC;IAGtB,eAAe,CAAC,EAAE,MAAM,CAAC;IAGzB,MAAM,EAAE,cAAc,CAAC;IAGvB,UAAU,EAAE,gBAAgB,EAAE,CAAC;IAG/B,UAAU,EAAE,iBAAiB,EAAE,CAAC;IAGhC,QAAQ,EAAE,eAAe,EAAE,CAAC;IAG5B,IAAI,EAAE,WAAW,EAAE,CAAC;IAGpB,KAAK,EAAE,YAAY,EAAE,CAAC;IAItB,WAAW,EAAE,MAAM,CAAC;IAIpB,WAAW,EAAE,MAAM,CAAC;IAGpB,SAAS,EAAE,IAAI,CAAC;IAGhB,SAAS,EAAE,IAAI,CAAC;IAKhB,kBAAkB;IASZ,cAAc,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAkBnC,QAAQ,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IAenC,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYnE,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM;IAiBzD,sBAAsB,CACxB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAChC,OAAO,CAAC,gBAAgB,CAAC;IAiBtB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAiBpD,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAyBrD"}
|
|
@@ -4,6 +4,7 @@ exports.NestAuthUser = void 0;
|
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const typeorm_1 = require("typeorm");
|
|
6
6
|
const argon2 = tslib_1.__importStar(require("argon2"));
|
|
7
|
+
const auth_config_service_1 = require("../../core/services/auth-config.service");
|
|
7
8
|
const tenant_entity_1 = require("../../tenant/entities/tenant.entity");
|
|
8
9
|
const identity_entity_1 = require("./identity.entity");
|
|
9
10
|
const session_entity_1 = require("../../session/entities/session.entity");
|
|
@@ -93,6 +94,11 @@ let NestAuthUser = class NestAuthUser extends typeorm_1.BaseEntity {
|
|
|
93
94
|
async validatePassword(password) {
|
|
94
95
|
if (!this.passwordHash)
|
|
95
96
|
return false;
|
|
97
|
+
// Apply password.verify hook if configured
|
|
98
|
+
const options = auth_config_service_1.AuthConfigService.getOptions();
|
|
99
|
+
if (options.password?.verify) {
|
|
100
|
+
return await options.password.verify(password, this.passwordHash);
|
|
101
|
+
}
|
|
96
102
|
try {
|
|
97
103
|
return await argon2.verify(this.passwordHash, password);
|
|
98
104
|
}
|
|
@@ -102,6 +108,19 @@ let NestAuthUser = class NestAuthUser extends typeorm_1.BaseEntity {
|
|
|
102
108
|
}
|
|
103
109
|
}
|
|
104
110
|
async setPassword(password) {
|
|
111
|
+
const options = auth_config_service_1.AuthConfigService.getOptions();
|
|
112
|
+
// Apply password.validate hook if configured
|
|
113
|
+
if (options.password?.validate) {
|
|
114
|
+
const isValid = await options.password.validate(password);
|
|
115
|
+
if (!isValid) {
|
|
116
|
+
throw new Error('Password does not meet requirements');
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// Apply password.hash hook if configured
|
|
120
|
+
if (options.password?.hash) {
|
|
121
|
+
this.passwordHash = await options.password.hash(password);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
105
124
|
// Argon2id is the recommended variant (hybrid of Argon2i and Argon2d)
|
|
106
125
|
this.passwordHash = await argon2.hash(password, {
|
|
107
126
|
type: argon2.argon2id,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-created.event.d.ts","sourceRoot":"","sources":["../../../../../../../packages/nest-auth/src/lib/user/events/user-created.event.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,MAAM,WAAW,uBAAuB;IACpC,IAAI,EAAE,YAAY,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,gBAAgB;aACG,OAAO,EAAE,uBAAuB;gBAAhC,OAAO,EAAE,uBAAuB;CAC/D"}
|
|
1
|
+
{"version":3,"file":"user-created.event.d.ts","sourceRoot":"","sources":["../../../../../../../packages/nest-auth/src/lib/user/events/user-created.event.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,MAAM,WAAW,uBAAuB;IACpC,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,gBAAgB;aACG,OAAO,EAAE,uBAAuB;gBAAhC,OAAO,EAAE,uBAAuB;CAC/D"}
|
|
@@ -5,13 +5,13 @@ import { TenantService } from '../../tenant';
|
|
|
5
5
|
import { DebugLoggerService } from '../../core/services/debug-logger.service';
|
|
6
6
|
import { AuthConfigService } from '../../core/services/auth-config.service';
|
|
7
7
|
export declare class UserService {
|
|
8
|
-
private userRepository;
|
|
9
|
-
private
|
|
10
|
-
private
|
|
11
|
-
private
|
|
12
|
-
private
|
|
13
|
-
constructor(userRepository: Repository<NestAuthUser>, eventEmitter: EventEmitter2,
|
|
14
|
-
createUser(data: Partial<NestAuthUser
|
|
8
|
+
private readonly userRepository;
|
|
9
|
+
private readonly tenantService;
|
|
10
|
+
private readonly eventEmitter;
|
|
11
|
+
private readonly authConfigService;
|
|
12
|
+
private readonly debugLogger;
|
|
13
|
+
constructor(userRepository: Repository<NestAuthUser>, tenantService: TenantService, eventEmitter: EventEmitter2, authConfigService: AuthConfigService, debugLogger: DebugLoggerService);
|
|
14
|
+
createUser(data: Partial<NestAuthUser>, context?: any): Promise<NestAuthUser>;
|
|
15
15
|
getUserById(id: string, options?: FindOneOptions<NestAuthUser>): Promise<NestAuthUser>;
|
|
16
16
|
getUserByEmail(email: string, tenantId?: string, options?: FindOneOptions<NestAuthUser>): Promise<NestAuthUser>;
|
|
17
17
|
getUserByPhone(phone: string, tenantId?: string, options?: FindOneOptions<NestAuthUser>): Promise<NestAuthUser>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/nest-auth/src/lib/user/services/user.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAe,UAAU,EAAE,MAAM,SAAS,CAAC;AACnF,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAKtD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,0CAA0C,CAAC;AAC9E,OAAO,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AAE5E,qBACa,WAAW;IAGhB,OAAO,CAAC,cAAc;
|
|
1
|
+
{"version":3,"file":"user.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/nest-auth/src/lib/user/services/user.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,80 +15,73 @@ const tenant_1 = require("../../tenant");
|
|
|
15
15
|
const debug_logger_service_1 = require("../../core/services/debug-logger.service");
|
|
16
16
|
const auth_config_service_1 = require("../../core/services/auth-config.service");
|
|
17
17
|
let UserService = class UserService {
|
|
18
|
-
constructor(userRepository, eventEmitter,
|
|
18
|
+
constructor(userRepository, tenantService, eventEmitter, authConfigService, debugLogger) {
|
|
19
19
|
this.userRepository = userRepository;
|
|
20
|
-
this.eventEmitter = eventEmitter;
|
|
21
20
|
this.tenantService = tenantService;
|
|
22
|
-
this.
|
|
21
|
+
this.eventEmitter = eventEmitter;
|
|
23
22
|
this.authConfigService = authConfigService;
|
|
23
|
+
this.debugLogger = debugLogger;
|
|
24
24
|
}
|
|
25
|
-
async createUser(data) {
|
|
25
|
+
async createUser(data, context) {
|
|
26
26
|
this.debugLogger.logFunctionEntry('createUser', 'UserService', { email: data.email, phone: data.phone, hasPassword: !!data.password });
|
|
27
27
|
try {
|
|
28
28
|
const { email, phone } = data;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
29
|
+
let { tenantId = null } = data;
|
|
30
|
+
// Resolve tenant ID
|
|
31
|
+
tenantId = await this.tenantService.resolveTenantId(tenantId);
|
|
32
|
+
data.tenantId = tenantId;
|
|
33
|
+
// Check if user already exists
|
|
34
|
+
if (email) {
|
|
35
|
+
const existingUser = await this.getUserByEmail(email, tenantId);
|
|
36
|
+
if (existingUser) {
|
|
37
|
+
this.debugLogger.warn('User with email already exists', 'UserService', { email, tenantId });
|
|
38
|
+
throw new common_1.ConflictException({
|
|
39
|
+
message: 'User with this email already exists',
|
|
40
|
+
code: 'USER_ALREADY_EXISTS'
|
|
41
|
+
});
|
|
42
|
+
}
|
|
38
43
|
}
|
|
39
|
-
// Check for existing user with same email or phone in the same tenant
|
|
40
|
-
this.debugLogger.debug('Checking for existing user', 'UserService', { email: !!email, phone: !!phone, tenantId });
|
|
41
|
-
let existingUser = null;
|
|
42
|
-
// Normalize email to lowercase for case-insensitive matching
|
|
43
|
-
const normalizedEmail = email ? email.toLowerCase().trim() : email;
|
|
44
44
|
if (phone) {
|
|
45
|
-
existingUser = await this.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
if (existingUser) {
|
|
55
|
-
this.debugLogger.warn('User already exists', 'UserService', { email: !!email, phone: !!phone, tenantId, existingUserId: existingUser.id });
|
|
56
|
-
throw new common_1.ConflictException({
|
|
57
|
-
message: `User with ${email ? `email ${email}` : ''}${email && phone ? ' or ' : ''}${phone ? `phone ${phone}` : ''} already exists.`,
|
|
58
|
-
code: 'USER_ALREADY_EXISTS'
|
|
59
|
-
});
|
|
45
|
+
const existingUser = await this.getUserByPhone(phone, tenantId);
|
|
46
|
+
if (existingUser) {
|
|
47
|
+
this.debugLogger.warn('User with phone already exists', 'UserService', { phone, tenantId });
|
|
48
|
+
throw new common_1.ConflictException({
|
|
49
|
+
message: 'User with this phone number already exists',
|
|
50
|
+
code: 'USER_ALREADY_EXISTS'
|
|
51
|
+
});
|
|
52
|
+
}
|
|
60
53
|
}
|
|
61
|
-
|
|
62
|
-
// Apply beforeCreate hook if configured
|
|
63
|
-
let userData = {
|
|
64
|
-
...data,
|
|
65
|
-
email: normalizedEmail || data.email,
|
|
66
|
-
tenantId
|
|
67
|
-
};
|
|
54
|
+
// Apply user.beforeCreate hook if configured
|
|
68
55
|
const config = this.authConfigService.getConfig();
|
|
69
56
|
if (config.user?.beforeCreate) {
|
|
70
|
-
|
|
57
|
+
this.debugLogger.debug('Applying user.beforeCreate hook', 'UserService');
|
|
58
|
+
data = await config.user.beforeCreate(data, context);
|
|
59
|
+
}
|
|
60
|
+
this.debugLogger.debug('Creating new user entity', 'UserService');
|
|
61
|
+
const user = this.userRepository.create(data);
|
|
62
|
+
// Handle password if provided in data (even though it's not a column)
|
|
63
|
+
if (data.password) {
|
|
64
|
+
await user.setPassword(data.password);
|
|
71
65
|
}
|
|
72
|
-
const user = this.userRepository.create(userData);
|
|
73
66
|
await this.userRepository.save(user);
|
|
74
|
-
this.debugLogger.info('User created successfully', 'UserService', { userId: user.id
|
|
75
|
-
// Create
|
|
76
|
-
|
|
77
|
-
|
|
67
|
+
this.debugLogger.info('User created successfully', 'UserService', { userId: user.id });
|
|
68
|
+
// Create identities
|
|
69
|
+
const normalizedEmail = email?.toLowerCase().trim();
|
|
70
|
+
if (normalizedEmail)
|
|
78
71
|
await user.findOrCreateIdentity(auth_constants_1.EMAIL_AUTH_PROVIDER, normalizedEmail);
|
|
79
|
-
|
|
80
|
-
if (phone) {
|
|
81
|
-
this.debugLogger.debug('Creating phone identity', 'UserService', { userId: user.id });
|
|
72
|
+
if (phone)
|
|
82
73
|
await user.findOrCreateIdentity(auth_constants_1.PHONE_AUTH_PROVIDER, phone);
|
|
83
|
-
}
|
|
84
74
|
// Emit user created event
|
|
85
75
|
this.debugLogger.debug('Emitting user created event', 'UserService', { userId: user.id });
|
|
86
76
|
await this.eventEmitter.emitAsync(auth_constants_1.NestAuthEvents.USER_CREATED, new user_created_event_1.UserCreatedEvent({
|
|
87
|
-
user
|
|
77
|
+
user,
|
|
78
|
+
input: context,
|
|
79
|
+
tenantId: user.tenantId
|
|
88
80
|
}));
|
|
89
|
-
// Apply afterCreate hook if configured
|
|
81
|
+
// Apply user.afterCreate hook if configured
|
|
90
82
|
if (config.user?.afterCreate) {
|
|
91
|
-
|
|
83
|
+
this.debugLogger.debug('Applying user.afterCreate hook', 'UserService', { userId: user.id });
|
|
84
|
+
await config.user.afterCreate(user, context);
|
|
92
85
|
}
|
|
93
86
|
this.debugLogger.logFunctionExit('createUser', 'UserService', { userId: user.id });
|
|
94
87
|
return user;
|
|
@@ -350,8 +343,8 @@ exports.UserService = UserService = tslib_1.__decorate([
|
|
|
350
343
|
(0, common_1.Injectable)(),
|
|
351
344
|
tslib_1.__param(0, (0, typeorm_1.InjectRepository)(user_entity_1.NestAuthUser)),
|
|
352
345
|
tslib_1.__metadata("design:paramtypes", [typeorm_2.Repository,
|
|
353
|
-
event_emitter_1.EventEmitter2,
|
|
354
346
|
tenant_1.TenantService,
|
|
355
|
-
|
|
356
|
-
auth_config_service_1.AuthConfigService
|
|
347
|
+
event_emitter_1.EventEmitter2,
|
|
348
|
+
auth_config_service_1.AuthConfigService,
|
|
349
|
+
debug_logger_service_1.DebugLoggerService])
|
|
357
350
|
], UserService);
|