@nauth-toolkit/core 0.1.37 → 0.1.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dto/get-user-sessions-response.dto.d.ts +88 -0
- package/dist/dto/get-user-sessions-response.dto.d.ts.map +1 -0
- package/dist/dto/get-user-sessions-response.dto.js +181 -0
- package/dist/dto/get-user-sessions-response.dto.js.map +1 -0
- package/dist/dto/get-user-sessions.dto.d.ts +17 -0
- package/dist/dto/get-user-sessions.dto.d.ts.map +1 -0
- package/dist/dto/get-user-sessions.dto.js +38 -0
- package/dist/dto/get-user-sessions.dto.js.map +1 -0
- package/dist/dto/index.d.ts +5 -0
- package/dist/dto/index.d.ts.map +1 -1
- package/dist/dto/index.js +5 -0
- package/dist/dto/index.js.map +1 -1
- package/dist/dto/logout-session-response.dto.d.ts +20 -0
- package/dist/dto/logout-session-response.dto.d.ts.map +1 -0
- package/dist/dto/logout-session-response.dto.js +42 -0
- package/dist/dto/logout-session-response.dto.js.map +1 -0
- package/dist/dto/logout-session.dto.d.ts +22 -0
- package/dist/dto/logout-session.dto.d.ts.map +1 -0
- package/dist/dto/logout-session.dto.js +48 -0
- package/dist/dto/logout-session.dto.js.map +1 -0
- package/dist/dto/update-verified-status-request.dto.d.ts +70 -0
- package/dist/dto/update-verified-status-request.dto.d.ts.map +1 -0
- package/dist/dto/update-verified-status-request.dto.js +107 -0
- package/dist/dto/update-verified-status-request.dto.js.map +1 -0
- package/dist/interfaces/hooks.interface.d.ts +129 -0
- package/dist/interfaces/hooks.interface.d.ts.map +1 -1
- package/dist/services/auth-service-internal-helpers.d.ts +229 -0
- package/dist/services/auth-service-internal-helpers.d.ts.map +1 -0
- package/dist/services/auth-service-internal-helpers.js +1004 -0
- package/dist/services/auth-service-internal-helpers.js.map +1 -0
- package/dist/services/auth.service.d.ts +204 -145
- package/dist/services/auth.service.d.ts.map +1 -1
- package/dist/services/auth.service.js +485 -2086
- package/dist/services/auth.service.js.map +1 -1
- package/dist/services/email-verification.service.d.ts +3 -1
- package/dist/services/email-verification.service.d.ts.map +1 -1
- package/dist/services/email-verification.service.js +77 -1
- package/dist/services/email-verification.service.js.map +1 -1
- package/dist/services/hook-registry.service.d.ts +23 -1
- package/dist/services/hook-registry.service.d.ts.map +1 -1
- package/dist/services/hook-registry.service.js +39 -0
- package/dist/services/hook-registry.service.js.map +1 -1
- package/dist/services/phone-verification.service.d.ts +3 -1
- package/dist/services/phone-verification.service.d.ts.map +1 -1
- package/dist/services/phone-verification.service.js +80 -1
- package/dist/services/phone-verification.service.js.map +1 -1
- package/dist/services/social-auth-base.service.d.ts +2 -1
- package/dist/services/social-auth-base.service.d.ts.map +1 -1
- package/dist/services/social-auth-base.service.js +5 -2
- package/dist/services/social-auth-base.service.js.map +1 -1
- package/dist/services/user.service.d.ts +274 -0
- package/dist/services/user.service.d.ts.map +1 -0
- package/dist/services/user.service.js +1327 -0
- package/dist/services/user.service.js.map +1 -0
- package/dist/utils/setup/init-services.d.ts.map +1 -1
- package/dist/utils/setup/init-services.js +2 -2
- package/dist/utils/setup/init-services.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Update Verified Status Request DTO
|
|
4
|
+
*
|
|
5
|
+
* Request DTO for updating email and/or phone verification status.
|
|
6
|
+
* Intended for admin use cases such as migration or offline validation.
|
|
7
|
+
*
|
|
8
|
+
* Security:
|
|
9
|
+
* - User sub validated (UUID)
|
|
10
|
+
* - Cannot set verified=true if email/phone doesn't exist
|
|
11
|
+
* - Can set verified=false even if email/phone doesn't exist (default state)
|
|
12
|
+
* - Only updates provided fields (partial update)
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* // Update email verification only
|
|
17
|
+
* await authService.updateVerifiedStatus({
|
|
18
|
+
* sub: 'user-uuid',
|
|
19
|
+
* isEmailVerified: true
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* // Update both email and phone verification
|
|
23
|
+
* await authService.updateVerifiedStatus({
|
|
24
|
+
* sub: 'user-uuid',
|
|
25
|
+
* isEmailVerified: true,
|
|
26
|
+
* isPhoneVerified: false
|
|
27
|
+
* });
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
31
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
32
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
33
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
34
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
35
|
+
};
|
|
36
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
37
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
38
|
+
};
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
exports.UpdateVerifiedStatusRequestDTO = void 0;
|
|
41
|
+
const class_validator_1 = require("class-validator");
|
|
42
|
+
const class_transformer_1 = require("class-transformer");
|
|
43
|
+
/**
|
|
44
|
+
* Request DTO for updating verification status
|
|
45
|
+
*/
|
|
46
|
+
class UpdateVerifiedStatusRequestDTO {
|
|
47
|
+
/**
|
|
48
|
+
* User's unique identifier (UUID v4)
|
|
49
|
+
*
|
|
50
|
+
* Validation:
|
|
51
|
+
* - Must be a valid UUID v4 format
|
|
52
|
+
* - Matches DB constraint: char(36) or uuid
|
|
53
|
+
*
|
|
54
|
+
* Sanitization:
|
|
55
|
+
* - Trimmed
|
|
56
|
+
* - Lowercased for consistency
|
|
57
|
+
*
|
|
58
|
+
* @example "a21b654c-2746-4168-acee-c175083a65cd"
|
|
59
|
+
*/
|
|
60
|
+
sub;
|
|
61
|
+
/**
|
|
62
|
+
* Email verification status
|
|
63
|
+
*
|
|
64
|
+
* Validation:
|
|
65
|
+
* - If set to true, user must have an email address
|
|
66
|
+
* - If set to false, can be set even if email doesn't exist (default state)
|
|
67
|
+
* - Optional - only updates if provided
|
|
68
|
+
*
|
|
69
|
+
* @example true
|
|
70
|
+
*/
|
|
71
|
+
isEmailVerified;
|
|
72
|
+
/**
|
|
73
|
+
* Phone verification status
|
|
74
|
+
*
|
|
75
|
+
* Validation:
|
|
76
|
+
* - If set to true, user must have a phone number
|
|
77
|
+
* - If set to false, can be set even if phone doesn't exist (default state)
|
|
78
|
+
* - Optional - only updates if provided
|
|
79
|
+
*
|
|
80
|
+
* @example true
|
|
81
|
+
*/
|
|
82
|
+
isPhoneVerified;
|
|
83
|
+
}
|
|
84
|
+
exports.UpdateVerifiedStatusRequestDTO = UpdateVerifiedStatusRequestDTO;
|
|
85
|
+
__decorate([
|
|
86
|
+
(0, class_validator_1.IsUUID)('4', { message: 'User sub must be a valid UUID v4 format' }),
|
|
87
|
+
(0, class_transformer_1.Transform)(({ value }) => {
|
|
88
|
+
if (typeof value === 'string') {
|
|
89
|
+
return value.trim().toLowerCase();
|
|
90
|
+
}
|
|
91
|
+
return value;
|
|
92
|
+
}),
|
|
93
|
+
__metadata("design:type", String)
|
|
94
|
+
], UpdateVerifiedStatusRequestDTO.prototype, "sub", void 0);
|
|
95
|
+
__decorate([
|
|
96
|
+
(0, class_validator_1.IsOptional)(),
|
|
97
|
+
(0, class_validator_1.IsBoolean)({ message: 'isEmailVerified must be a boolean' }),
|
|
98
|
+
(0, class_validator_1.ValidateIf)((o) => o.isEmailVerified !== undefined),
|
|
99
|
+
__metadata("design:type", Boolean)
|
|
100
|
+
], UpdateVerifiedStatusRequestDTO.prototype, "isEmailVerified", void 0);
|
|
101
|
+
__decorate([
|
|
102
|
+
(0, class_validator_1.IsOptional)(),
|
|
103
|
+
(0, class_validator_1.IsBoolean)({ message: 'isPhoneVerified must be a boolean' }),
|
|
104
|
+
(0, class_validator_1.ValidateIf)((o) => o.isPhoneVerified !== undefined),
|
|
105
|
+
__metadata("design:type", Boolean)
|
|
106
|
+
], UpdateVerifiedStatusRequestDTO.prototype, "isPhoneVerified", void 0);
|
|
107
|
+
//# sourceMappingURL=update-verified-status-request.dto.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-verified-status-request.dto.js","sourceRoot":"","sources":["../../src/dto/update-verified-status-request.dto.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;;;;;;;;;;;;AAEH,qDAA4E;AAC5E,yDAA8C;AAE9C;;GAEG;AACH,MAAa,8BAA8B;IACzC;;;;;;;;;;;;OAYG;IAQH,GAAG,CAAU;IAEb;;;;;;;;;OASG;IAIH,eAAe,CAAW;IAE1B;;;;;;;;;OASG;IAIH,eAAe,CAAW;CAC3B;AApDD,wEAoDC;AA/BC;IAPC,IAAA,wBAAM,EAAC,GAAG,EAAE,EAAE,OAAO,EAAE,yCAAyC,EAAE,CAAC;IACnE,IAAA,6BAAS,EAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE;QACvB,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACpC,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;;2DACW;AAeb;IAHC,IAAA,4BAAU,GAAE;IACZ,IAAA,2BAAS,EAAC,EAAE,OAAO,EAAE,mCAAmC,EAAE,CAAC;IAC3D,IAAA,4BAAU,EAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,KAAK,SAAS,CAAC;;uEACzB;AAe1B;IAHC,IAAA,4BAAU,GAAE;IACZ,IAAA,2BAAS,EAAC,EAAE,OAAO,EAAE,mCAAmC,EAAE,CAAC;IAC3D,IAAA,4BAAU,EAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,KAAK,SAAS,CAAC;;uEACzB"}
|
|
@@ -96,5 +96,134 @@ export interface SignupMetadata {
|
|
|
96
96
|
* false (or undefined) for regular user signups
|
|
97
97
|
*/
|
|
98
98
|
adminSignup?: boolean;
|
|
99
|
+
/**
|
|
100
|
+
* Social metadata from OAuth provider (only present for social signups)
|
|
101
|
+
*
|
|
102
|
+
* Contains the raw OAuth profile data stored in the social account metadata field.
|
|
103
|
+
* This includes all provider-specific fields like sub, given_name, family_name, locale, etc.
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* ```json
|
|
107
|
+
* {
|
|
108
|
+
* "sub": "google_123",
|
|
109
|
+
* "email": "user@gmail.com",
|
|
110
|
+
* "given_name": "John",
|
|
111
|
+
* "family_name": "Doe",
|
|
112
|
+
* "picture": "https://...",
|
|
113
|
+
* "locale": "en"
|
|
114
|
+
* }
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
socialMetadata?: Record<string, unknown> | null;
|
|
118
|
+
/**
|
|
119
|
+
* Profile picture URL from OAuth provider (only present for social signups)
|
|
120
|
+
*
|
|
121
|
+
* Extracted from the OAuth profile for convenience.
|
|
122
|
+
* Also available in socialMetadata.picture.
|
|
123
|
+
*
|
|
124
|
+
* @example "https://lh3.googleusercontent.com/a/..."
|
|
125
|
+
*/
|
|
126
|
+
profilePicture?: string | null;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* User profile update source
|
|
130
|
+
*
|
|
131
|
+
* Indicates what triggered the profile update.
|
|
132
|
+
*/
|
|
133
|
+
export type UserProfileUpdateSource = 'user_request' | 'admin_action' | 'email_verification' | 'phone_verification';
|
|
134
|
+
/**
|
|
135
|
+
* Changed field metadata
|
|
136
|
+
*
|
|
137
|
+
* Tracks old and new values for a single field.
|
|
138
|
+
*/
|
|
139
|
+
export interface ChangedField {
|
|
140
|
+
/**
|
|
141
|
+
* Field name that changed
|
|
142
|
+
*/
|
|
143
|
+
fieldName: string;
|
|
144
|
+
/**
|
|
145
|
+
* Previous value before update
|
|
146
|
+
*/
|
|
147
|
+
oldValue: unknown;
|
|
148
|
+
/**
|
|
149
|
+
* New value after update
|
|
150
|
+
*/
|
|
151
|
+
newValue: unknown;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* User profile updated metadata
|
|
155
|
+
*
|
|
156
|
+
* Provides context about the profile update event.
|
|
157
|
+
*/
|
|
158
|
+
export interface UserProfileUpdatedMetadata {
|
|
159
|
+
/**
|
|
160
|
+
* Updated user entity (full object after change)
|
|
161
|
+
*/
|
|
162
|
+
user: IUser;
|
|
163
|
+
/**
|
|
164
|
+
* Array of fields that changed with old and new values
|
|
165
|
+
*/
|
|
166
|
+
changedFields: ChangedField[];
|
|
167
|
+
/**
|
|
168
|
+
* What triggered the update
|
|
169
|
+
*/
|
|
170
|
+
updateSource: UserProfileUpdateSource;
|
|
171
|
+
/**
|
|
172
|
+
* Admin user sub who performed the action (only for admin_action source)
|
|
173
|
+
*/
|
|
174
|
+
performedBy?: string;
|
|
175
|
+
/**
|
|
176
|
+
* Client information (IP address, user agent)
|
|
177
|
+
*/
|
|
178
|
+
clientInfo?: {
|
|
179
|
+
ipAddress?: string;
|
|
180
|
+
userAgent?: string;
|
|
181
|
+
ipCountry?: string;
|
|
182
|
+
ipCity?: string;
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* User profile updated hook provider interface
|
|
187
|
+
*
|
|
188
|
+
* Executes actions after user profile attributes change (non-blocking).
|
|
189
|
+
* Errors are logged but do not affect the update operation.
|
|
190
|
+
*
|
|
191
|
+
* @remarks
|
|
192
|
+
* This hook is triggered when:
|
|
193
|
+
* - Core attributes change (firstName, lastName, username, email, phone, metadata)
|
|
194
|
+
* - Verification status changes (isEmailVerified, isPhoneVerified)
|
|
195
|
+
*
|
|
196
|
+
* This hook is NOT triggered for:
|
|
197
|
+
* - Password changes
|
|
198
|
+
* - Account lock/unlock
|
|
199
|
+
* - Login state changes
|
|
200
|
+
* - MFA changes
|
|
201
|
+
* - Social account linkages
|
|
202
|
+
*
|
|
203
|
+
* The hook is non-blocking. If it throws an error, the error is logged but the update continues.
|
|
204
|
+
* The user profile has already been updated when the hook is called.
|
|
205
|
+
*
|
|
206
|
+
* @example
|
|
207
|
+
* ```typescript
|
|
208
|
+
* export class CrmSyncHook implements IUserProfileUpdatedHookProvider {
|
|
209
|
+
* async execute(metadata: UserProfileUpdatedMetadata): Promise<void> {
|
|
210
|
+
* // Sync to CRM when email changes
|
|
211
|
+
* const emailChange = metadata.changedFields.find(f => f.fieldName === 'email');
|
|
212
|
+
* if (emailChange) {
|
|
213
|
+
* await this.crmService.updateContact(metadata.user.sub, {
|
|
214
|
+
* email: emailChange.newValue
|
|
215
|
+
* });
|
|
216
|
+
* }
|
|
217
|
+
* }
|
|
218
|
+
* }
|
|
219
|
+
* ```
|
|
220
|
+
*/
|
|
221
|
+
export interface IUserProfileUpdatedHookProvider {
|
|
222
|
+
/**
|
|
223
|
+
* Execute user profile updated actions
|
|
224
|
+
*
|
|
225
|
+
* @param metadata - Profile update context with user, changed fields, and update source
|
|
226
|
+
*/
|
|
227
|
+
execute(metadata: UserProfileUpdatedMetadata): Promise<void>;
|
|
99
228
|
}
|
|
100
229
|
//# sourceMappingURL=hooks.interface.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/hooks.interface.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAE7C;;;;;;;GAOG;AACH,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,cAAc,GAAG,gBAAgB,CAAC;AAE9E;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;;;;;;OAQG;IACH,OAAO,CACL,IAAI,EAAE,iBAAiB,EACvB,UAAU,EAAE,UAAU,GAAG,QAAQ,EACjC,QAAQ,CAAC,EAAE,MAAM,EACjB,WAAW,CAAC,EAAE,OAAO,GACpB,OAAO,CAAC,IAAI,CAAC,CAAC;CAClB;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;;;OAKG;IACH,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAChE;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAE/B;;OAEG;IACH,UAAU,CAAC,EAAE,UAAU,GAAG,QAAQ,CAAC;IAEnC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"hooks.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/hooks.interface.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAE7C;;;;;;;GAOG;AACH,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,cAAc,GAAG,gBAAgB,CAAC;AAE9E;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;;;;;;OAQG;IACH,OAAO,CACL,IAAI,EAAE,iBAAiB,EACvB,UAAU,EAAE,UAAU,GAAG,QAAQ,EACjC,QAAQ,CAAC,EAAE,MAAM,EACjB,WAAW,CAAC,EAAE,OAAO,GACpB,OAAO,CAAC,IAAI,CAAC,CAAC;CAClB;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;;;OAKG;IACH,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAChE;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAE/B;;OAEG;IACH,UAAU,CAAC,EAAE,UAAU,GAAG,QAAQ,CAAC;IAEnC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;;;;;;;;;;;;;;;OAiBG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAEhD;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAMD;;;;GAIG;AACH,MAAM,MAAM,uBAAuB,GAC/B,cAAc,GACd,cAAc,GACd,oBAAoB,GACpB,oBAAoB,CAAC;AAEzB;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,QAAQ,EAAE,OAAO,CAAC;IAElB;;OAEG;IACH,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;;GAIG;AACH,MAAM,WAAW,0BAA0B;IACzC;;OAEG;IACH,IAAI,EAAE,KAAK,CAAC;IAEZ;;OAEG;IACH,aAAa,EAAE,YAAY,EAAE,CAAC;IAE9B;;OAEG;IACH,YAAY,EAAE,uBAAuB,CAAC;IAEtC;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,UAAU,CAAC,EAAE;QACX,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,MAAM,WAAW,+BAA+B;IAC9C;;;;OAIG;IACH,OAAO,CAAC,QAAQ,EAAE,0BAA0B,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9D"}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { Repository } from 'typeorm';
|
|
2
|
+
import { IUser } from '../interfaces/entities.interface';
|
|
3
|
+
import { BaseUser, BaseLoginAttempt, BaseChallengeSession } from '../entities';
|
|
4
|
+
import { PasswordService } from './password.service';
|
|
5
|
+
import { SessionService } from './session.service';
|
|
6
|
+
import { EmailVerificationService } from './email-verification.service';
|
|
7
|
+
import { PhoneVerificationService } from './phone-verification.service';
|
|
8
|
+
import { ClientInfoService } from './client-info.service';
|
|
9
|
+
import { ChallengeService } from './challenge.service';
|
|
10
|
+
import { AuthChallengeHelperService } from './auth-challenge-helper.service';
|
|
11
|
+
import { AccountLockoutStorageService } from '../storage/account-lockout-storage.service';
|
|
12
|
+
import { InternalAuthAuditService as AuthAuditService } from './auth-audit.service';
|
|
13
|
+
import { TrustedDeviceService } from './trusted-device.service';
|
|
14
|
+
import { MFAService } from './mfa.service';
|
|
15
|
+
import { AuthAuditEventType } from '../enums/auth-audit-event-type.enum';
|
|
16
|
+
import { ChallengeResponseData, CollectPhoneResponse, VerifyPhoneResponse, VerifyMFACodeResponse, VerifyMFAPasskeyResponse, MFASetupResponse } from '../dto/challenge-response.dto';
|
|
17
|
+
import { AuthResponseDTO } from '../dto/auth-response.dto';
|
|
18
|
+
import { UpdateUserAttributesRequestDTO } from '../dto/update-user-attributes-request.dto';
|
|
19
|
+
import { NAuthConfig } from '../interfaces/config.interface';
|
|
20
|
+
import { NAuthLogger } from '../utils/nauth-logger';
|
|
21
|
+
/**
|
|
22
|
+
* Internal helper service for AuthService
|
|
23
|
+
*
|
|
24
|
+
* Contains private utility methods for challenge handling, validation,
|
|
25
|
+
* password management, and login tracking. This class is NOT exported from
|
|
26
|
+
* the package and should only be used internally by AuthService.
|
|
27
|
+
*
|
|
28
|
+
* INTERNAL USE ONLY - DO NOT IMPORT DIRECTLY
|
|
29
|
+
*
|
|
30
|
+
* @internal
|
|
31
|
+
*/
|
|
32
|
+
export declare class AuthServiceInternalHelpers {
|
|
33
|
+
private readonly userRepository;
|
|
34
|
+
private readonly loginAttemptRepository;
|
|
35
|
+
private readonly emailVerificationService;
|
|
36
|
+
private readonly phoneVerificationService;
|
|
37
|
+
private readonly challengeService;
|
|
38
|
+
private readonly challengeHelper;
|
|
39
|
+
private readonly clientInfoService;
|
|
40
|
+
private readonly sessionService;
|
|
41
|
+
private readonly accountLockoutStorage;
|
|
42
|
+
private readonly config;
|
|
43
|
+
private readonly logger;
|
|
44
|
+
constructor(userRepository: Repository<BaseUser>, loginAttemptRepository: Repository<BaseLoginAttempt>, emailVerificationService: EmailVerificationService, phoneVerificationService: PhoneVerificationService | undefined, challengeService: ChallengeService, challengeHelper: AuthChallengeHelperService, clientInfoService: ClientInfoService, sessionService: SessionService, accountLockoutStorage: AccountLockoutStorageService, config: NAuthConfig, logger: NAuthLogger);
|
|
45
|
+
/**
|
|
46
|
+
* Handle VERIFY_EMAIL challenge
|
|
47
|
+
*
|
|
48
|
+
* @param challengeSession - Challenge session with user
|
|
49
|
+
* @param code - Email verification code
|
|
50
|
+
* @returns Authentication response with tokens or next challenge
|
|
51
|
+
*/
|
|
52
|
+
handleVerifyEmail(challengeSession: BaseChallengeSession & {
|
|
53
|
+
user?: BaseUser;
|
|
54
|
+
}, code: string): Promise<AuthResponseDTO>;
|
|
55
|
+
/**
|
|
56
|
+
* Handle VERIFY_PHONE challenge
|
|
57
|
+
*
|
|
58
|
+
* @param challengeSession - Challenge session with user
|
|
59
|
+
* @param data - Phone verification data (phone number or code)
|
|
60
|
+
* @returns Authentication response with tokens or next challenge
|
|
61
|
+
*/
|
|
62
|
+
handleVerifyPhone(challengeSession: BaseChallengeSession & {
|
|
63
|
+
user?: BaseUser;
|
|
64
|
+
}, data: VerifyPhoneResponse | CollectPhoneResponse): Promise<AuthResponseDTO>;
|
|
65
|
+
/**
|
|
66
|
+
* Handle MFA_REQUIRED challenge
|
|
67
|
+
*
|
|
68
|
+
* @param challengeSession - Challenge session with user
|
|
69
|
+
* @param data - MFA verification data
|
|
70
|
+
* @param mfaService - MFA service (passed from AuthService)
|
|
71
|
+
* @param trustedDeviceService - Trusted device service (optional, passed from AuthService)
|
|
72
|
+
* @param auditService - Audit service (optional, passed from AuthService)
|
|
73
|
+
* @returns Authentication response with tokens or next challenge
|
|
74
|
+
*/
|
|
75
|
+
handleMFAVerification(challengeSession: BaseChallengeSession & {
|
|
76
|
+
user?: BaseUser;
|
|
77
|
+
}, data: VerifyMFACodeResponse | VerifyMFAPasskeyResponse, mfaService: MFAService | undefined, trustedDeviceService: TrustedDeviceService | undefined, auditService: AuthAuditService | undefined): Promise<AuthResponseDTO>;
|
|
78
|
+
/**
|
|
79
|
+
* Handle FORCE_CHANGE_PASSWORD challenge
|
|
80
|
+
*
|
|
81
|
+
* @param challengeSession - Challenge session with user
|
|
82
|
+
* @param newPassword - New password
|
|
83
|
+
* @param passwordService - Password service (passed from AuthService)
|
|
84
|
+
* @param auditService - Audit service (optional, passed from AuthService)
|
|
85
|
+
* @returns Authentication response with tokens or next challenge
|
|
86
|
+
*/
|
|
87
|
+
handleForceChangePassword(challengeSession: BaseChallengeSession & {
|
|
88
|
+
user?: BaseUser;
|
|
89
|
+
}, newPassword: string, passwordService: PasswordService, auditService: AuthAuditService | undefined): Promise<AuthResponseDTO>;
|
|
90
|
+
/**
|
|
91
|
+
* Handle MFA_SETUP_REQUIRED challenge
|
|
92
|
+
*
|
|
93
|
+
* @param challengeSession - Challenge session with user
|
|
94
|
+
* @param data - MFA setup data
|
|
95
|
+
* @param mfaService - MFA service (passed from AuthService)
|
|
96
|
+
* @param auditService - Audit service (optional, passed from AuthService)
|
|
97
|
+
* @returns Authentication response with tokens or next challenge
|
|
98
|
+
*/
|
|
99
|
+
handleMFASetup(challengeSession: BaseChallengeSession & {
|
|
100
|
+
user?: BaseUser;
|
|
101
|
+
}, data: MFASetupResponse, mfaService: MFAService | undefined, _auditService: AuthAuditService | undefined): Promise<AuthResponseDTO>;
|
|
102
|
+
/**
|
|
103
|
+
* Validate that response type matches expected challenge type
|
|
104
|
+
*
|
|
105
|
+
* @param expected - Expected challenge type
|
|
106
|
+
* @param provided - Provided challenge type
|
|
107
|
+
* @throws {NAuthException} If types don't match
|
|
108
|
+
*/
|
|
109
|
+
validateChallengeTypeMatch(expected: string, provided: string): void;
|
|
110
|
+
/**
|
|
111
|
+
* Validate parameters for challenge type
|
|
112
|
+
*
|
|
113
|
+
* Service-level validation ensures Express/other frameworks get same validation as NestJS.
|
|
114
|
+
* This is critical for non-DTO-based applications.
|
|
115
|
+
*
|
|
116
|
+
* @param type - Challenge type
|
|
117
|
+
* @param data - Challenge response data
|
|
118
|
+
* @throws {NAuthException} If validation fails
|
|
119
|
+
*/
|
|
120
|
+
validateChallengeParams(type: string, data: ChallengeResponseData): void;
|
|
121
|
+
/**
|
|
122
|
+
* Checks if the login identifier matches the specified allowed type.
|
|
123
|
+
*
|
|
124
|
+
* Determines if the given identifier is a valid email, username, phone, or allowed hybrid,
|
|
125
|
+
* according to the configured identifier type restriction.
|
|
126
|
+
*
|
|
127
|
+
* @param identifier - The login identifier to check (email, username, or phone)
|
|
128
|
+
* @param allowedType - The permitted identifier type ('email', 'username', 'phone', or 'email_or_username')
|
|
129
|
+
* @returns True if the identifier conforms to the allowed type, otherwise false
|
|
130
|
+
*/
|
|
131
|
+
validateIdentifierType(identifier: string, allowedType: 'email' | 'username' | 'phone' | 'email_or_username'): boolean;
|
|
132
|
+
/**
|
|
133
|
+
* Ensures email, phone, and username are unique for other users before update.
|
|
134
|
+
*
|
|
135
|
+
* Throws if another user already has the specified email, phone, or username.
|
|
136
|
+
*
|
|
137
|
+
* @param userId - Internal numeric user ID (excluded from check)
|
|
138
|
+
* @param updateData - User fields to check for uniqueness
|
|
139
|
+
* @throws {NAuthException} If a unique constraint is violated for email, phone, or username
|
|
140
|
+
*/
|
|
141
|
+
validateUniquenessConstraints(userId: number, updateData: UpdateUserAttributesRequestDTO): Promise<void>;
|
|
142
|
+
/**
|
|
143
|
+
* Retrieves a user entity by login identifier.
|
|
144
|
+
*
|
|
145
|
+
* Performs a lookup for a user by email, username, or phone number.
|
|
146
|
+
* The search respects the identifierType restriction when provided, limiting which fields are queried.
|
|
147
|
+
*
|
|
148
|
+
* @param identifier - Login credential (email, username, or phone)
|
|
149
|
+
* @param identifierType - Restricts search to a specific identifier type ('email', 'username', 'phone', or 'email_or_username')
|
|
150
|
+
* @returns The user entity if found, otherwise null
|
|
151
|
+
*/
|
|
152
|
+
findUserByIdentifier(identifier: string, identifierType?: 'email' | 'username' | 'phone' | 'email_or_username'): Promise<IUser | null>;
|
|
153
|
+
/**
|
|
154
|
+
* Centralized password update flow used by:
|
|
155
|
+
* - changePassword()
|
|
156
|
+
* - confirmForgotPassword()
|
|
157
|
+
* - adminSetPassword()
|
|
158
|
+
* - FORCE_CHANGE_PASSWORD challenge handler
|
|
159
|
+
*
|
|
160
|
+
* WHY:
|
|
161
|
+
* - Prevent logic drift between different password-changing entrypoints
|
|
162
|
+
* - Ensure consistent validation, history enforcement, persistence, session revocation, and audit trails
|
|
163
|
+
*
|
|
164
|
+
* @param params - Password update parameters
|
|
165
|
+
* @param passwordService - Password service (passed from AuthService)
|
|
166
|
+
* @param auditService - Audit service (optional, passed from AuthService)
|
|
167
|
+
* @returns Sessions revoked count (0 when not revoked)
|
|
168
|
+
* @throws {NAuthException} WEAK_PASSWORD | PASSWORD_REUSED | NOT_FOUND
|
|
169
|
+
*/
|
|
170
|
+
updateUserPassword(params: {
|
|
171
|
+
user: IUser;
|
|
172
|
+
newPassword: string;
|
|
173
|
+
mustChangePassword: boolean;
|
|
174
|
+
revokeSessions: boolean;
|
|
175
|
+
revokeReason: string;
|
|
176
|
+
beforePersist?: () => Promise<void>;
|
|
177
|
+
audit?: {
|
|
178
|
+
eventType: AuthAuditEventType;
|
|
179
|
+
eventStatus: 'SUCCESS' | 'FAILURE' | 'INFO' | 'SUSPICIOUS';
|
|
180
|
+
reason?: string;
|
|
181
|
+
description?: string;
|
|
182
|
+
authMethod?: string;
|
|
183
|
+
metadata?: Record<string, unknown>;
|
|
184
|
+
};
|
|
185
|
+
}, passwordService: PasswordService, auditService: AuthAuditService | undefined): Promise<{
|
|
186
|
+
sessionsRevoked: number;
|
|
187
|
+
}>;
|
|
188
|
+
/**
|
|
189
|
+
* Handles a failed login by recording the attempt, applying IP-based lockout policy,
|
|
190
|
+
* and invoking relevant hooks.
|
|
191
|
+
*
|
|
192
|
+
* @param identifier - User identifier (email/username/phone)
|
|
193
|
+
* @param reason - Optional reason for failure
|
|
194
|
+
*/
|
|
195
|
+
handleFailedLogin(identifier: string, reason?: string): Promise<void>;
|
|
196
|
+
/**
|
|
197
|
+
* Records a login attempt with client context.
|
|
198
|
+
*
|
|
199
|
+
* @param email - User's email address
|
|
200
|
+
* @param success - True if login succeeded, false if failed
|
|
201
|
+
* @param failureReason - Optional reason for failure
|
|
202
|
+
* @param userId - Optional internal user ID (only for successful logins)
|
|
203
|
+
*/
|
|
204
|
+
recordLoginAttempt(email: string, success: boolean, failureReason?: string, userId?: number): Promise<void>;
|
|
205
|
+
/**
|
|
206
|
+
* Clear authentication cookies from response
|
|
207
|
+
*
|
|
208
|
+
* @param response - HTTP response object with clearCookie method
|
|
209
|
+
* @param forgetDevice - Whether to also clear device token cookie
|
|
210
|
+
*/
|
|
211
|
+
clearAuthCookies(response: {
|
|
212
|
+
clearCookie?: (name: string, options?: unknown) => void;
|
|
213
|
+
}, forgetDevice: boolean): void;
|
|
214
|
+
/**
|
|
215
|
+
* Mask email address for privacy (show first char and domain)
|
|
216
|
+
*
|
|
217
|
+
* @param email - Email address to mask
|
|
218
|
+
* @returns Masked email (e.g., 'u***r@example.com')
|
|
219
|
+
*/
|
|
220
|
+
maskEmail(email: string): string;
|
|
221
|
+
/**
|
|
222
|
+
* Mask phone number for privacy (show last 4 digits)
|
|
223
|
+
*
|
|
224
|
+
* @param phone - Phone number to mask
|
|
225
|
+
* @returns Masked phone (e.g., '***-***-1234')
|
|
226
|
+
*/
|
|
227
|
+
maskPhone(phone: string): string;
|
|
228
|
+
}
|
|
229
|
+
//# sourceMappingURL=auth-service-internal-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-service-internal-helpers.d.ts","sourceRoot":"","sources":["../../src/services/auth-service-internal-helpers.ts"],"names":[],"mappings":"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"}
|