vr-commons 1.0.113 → 1.0.115

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.
@@ -21,7 +21,7 @@ const checkUserAuthentication = (allowedRoles) => async (req, res, next) => {
21
21
  }
22
22
  catch (error) {
23
23
  if (error instanceof jsonwebtoken_1.default.TokenExpiredError) {
24
- return (0, response_utils_1.sendErrorResponse)(res, "Token expired. Please re-verify your phone.", 401);
24
+ return (0, response_utils_1.sendErrorResponse)(res, "Token expired. Please re-verify your Email/Phone", 401);
25
25
  }
26
26
  return (0, response_utils_1.sendErrorResponse)(res, "Token invalid", 401);
27
27
  }
@@ -40,7 +40,7 @@ const checkUserAuthentication = (allowedRoles) => async (req, res, next) => {
40
40
  }
41
41
  // 🔐 Token versioning (logout all devices)
42
42
  if (user.tokenVersion !== payload.tokenVersion) {
43
- return (0, response_utils_1.sendErrorResponse)(res, "Session expired. Please re-verify your phone.", 401);
43
+ return (0, response_utils_1.sendErrorResponse)(res, "Session expired. Please re-verify your Email/Phone", 401);
44
44
  }
45
45
  // 🧱 Role enforcement
46
46
  if (!allowedRoles.includes(user.securityClearance.role)) {
@@ -7,7 +7,7 @@ export { canModerate, canModerateUser, getModeratableRoles, hasHigherAuthority,
7
7
  export { banUtil } from "./bans.utils";
8
8
  export { suspensionUtil } from "./suspension.utils";
9
9
  export { createDeviceSession } from "./session.utils";
10
- export { generateOTP, getOTPExpiry, getVerificationMethod, sendEmail, sendSMS, sendVerificationCode, } from "./verification.utils";
10
+ export { generateOTP, getOTPExpiry, getVerificationMethod, sendEmail, sendSMS, sendVerificationCode, detectContactType, validateContactValue, } from "./verification.utils";
11
11
  export { getUserLevel, isRankEqual, isSubordinate, isSubordinateOrEqual, isSuperior, isSuperiorOrEqual, validateHierarchy, } from "./hierarchy.utils";
12
12
  export { stockUtil } from "./admin.device.utils";
13
13
  export { cloudinaryUtil } from "./product.utils";
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isRankEqual = exports.getUserLevel = exports.sendVerificationCode = exports.sendSMS = exports.sendEmail = exports.getVerificationMethod = exports.getOTPExpiry = exports.generateOTP = exports.createDeviceSession = exports.suspensionUtil = exports.banUtil = exports.hasHigherAuthority = exports.getModeratableRoles = exports.canModerateUser = exports.canModerate = exports.softDeleteUser = exports.hashPassword = exports.validatePassword = exports.validateUniqueFields = exports.generateJacketId = exports.getSortOrder = exports.generateEventSearchConditions = exports.generateUserSearchConditions = exports.findSecurityClearanceByRole = exports.getUsersByRole = exports.getUserById = exports.isAccountAccessible = exports.canModifyAccount = exports.hasAllPermissions = exports.hasAnyPermission = exports.hasPermission = exports.hasRole = exports.formatUserListResponse = exports.formatUserProfile = exports.sendErrorResponse = exports.sendSuccessResponse = exports.logEvent = exports.formatTimeRemaining = exports.getTokenTimeRemaining = exports.generateToken = exports.shouldRefreshToken = exports.verifyToken = exports.generateRiderToken = exports.generatePassengerToken = exports.generateAdminToken = exports.checkSuspensionStatus = exports.checkIsUserBannedOrSuspended = exports.checkBanStatus = exports.hasActiveDependencies = exports.checkAccountDependencies = void 0;
4
- exports.buildUserSearchConditions = exports.buildSearchConditions = exports.buildEventLogWhereClause = exports.formatEventLogs = exports.formatEventLog = exports.formatDeviceSession = exports.DPP_OperationsUtil = exports.cloudinaryUtil = exports.stockUtil = exports.validateHierarchy = exports.isSuperiorOrEqual = exports.isSuperior = exports.isSubordinateOrEqual = exports.isSubordinate = void 0;
3
+ exports.validateContactValue = exports.detectContactType = exports.sendVerificationCode = exports.sendSMS = exports.sendEmail = exports.getVerificationMethod = exports.getOTPExpiry = exports.generateOTP = exports.createDeviceSession = exports.suspensionUtil = exports.banUtil = exports.hasHigherAuthority = exports.getModeratableRoles = exports.canModerateUser = exports.canModerate = exports.softDeleteUser = exports.hashPassword = exports.validatePassword = exports.validateUniqueFields = exports.generateJacketId = exports.getSortOrder = exports.generateEventSearchConditions = exports.generateUserSearchConditions = exports.findSecurityClearanceByRole = exports.getUsersByRole = exports.getUserById = exports.isAccountAccessible = exports.canModifyAccount = exports.hasAllPermissions = exports.hasAnyPermission = exports.hasPermission = exports.hasRole = exports.formatUserListResponse = exports.formatUserProfile = exports.sendErrorResponse = exports.sendSuccessResponse = exports.logEvent = exports.formatTimeRemaining = exports.getTokenTimeRemaining = exports.generateToken = exports.shouldRefreshToken = exports.verifyToken = exports.generateRiderToken = exports.generatePassengerToken = exports.generateAdminToken = exports.checkSuspensionStatus = exports.checkIsUserBannedOrSuspended = exports.checkBanStatus = exports.hasActiveDependencies = exports.checkAccountDependencies = void 0;
4
+ exports.buildUserSearchConditions = exports.buildSearchConditions = exports.buildEventLogWhereClause = exports.formatEventLogs = exports.formatEventLog = exports.formatDeviceSession = exports.DPP_OperationsUtil = exports.cloudinaryUtil = exports.stockUtil = exports.validateHierarchy = exports.isSuperiorOrEqual = exports.isSuperior = exports.isSubordinateOrEqual = exports.isSubordinate = exports.isRankEqual = exports.getUserLevel = void 0;
5
5
  var account_utils_1 = require("./account.utils");
6
6
  Object.defineProperty(exports, "checkAccountDependencies", { enumerable: true, get: function () { return account_utils_1.checkAccountDependencies; } });
7
7
  Object.defineProperty(exports, "hasActiveDependencies", { enumerable: true, get: function () { return account_utils_1.hasActiveDependencies; } });
@@ -67,6 +67,8 @@ Object.defineProperty(exports, "getVerificationMethod", { enumerable: true, get:
67
67
  Object.defineProperty(exports, "sendEmail", { enumerable: true, get: function () { return verification_utils_1.sendEmail; } });
68
68
  Object.defineProperty(exports, "sendSMS", { enumerable: true, get: function () { return verification_utils_1.sendSMS; } });
69
69
  Object.defineProperty(exports, "sendVerificationCode", { enumerable: true, get: function () { return verification_utils_1.sendVerificationCode; } });
70
+ Object.defineProperty(exports, "detectContactType", { enumerable: true, get: function () { return verification_utils_1.detectContactType; } });
71
+ Object.defineProperty(exports, "validateContactValue", { enumerable: true, get: function () { return verification_utils_1.validateContactValue; } });
70
72
  var hierarchy_utils_1 = require("./hierarchy.utils");
71
73
  Object.defineProperty(exports, "getUserLevel", { enumerable: true, get: function () { return hierarchy_utils_1.getUserLevel; } });
72
74
  Object.defineProperty(exports, "isRankEqual", { enumerable: true, get: function () { return hierarchy_utils_1.isRankEqual; } });
@@ -1,4 +1,21 @@
1
1
  import { VerificationMethod } from "./types";
2
+ /**
3
+ * Regular expressions for contact validation
4
+ */
5
+ export declare const phoneRegex: RegExp;
6
+ export declare const emailRegex: RegExp;
7
+ /**
8
+ * Detect the type of contact value
9
+ * @param value - The contact value to check (email or phone number)
10
+ * @returns The contact type: 'EMAIL', 'PHONE', 'WHATSAPP', or 'UNKNOWN'
11
+ */
12
+ export declare const detectContactType: (value: string) => "EMAIL" | "PHONE" | "WHATSAPP" | "UNKNOWN";
13
+ /**
14
+ * Validate if a contact value is valid (either email or phone)
15
+ * @param value - The contact value to validate
16
+ * @returns True if valid email or phone, false otherwise
17
+ */
18
+ export declare const validateContactValue: (value: string) => boolean;
2
19
  export declare const getVerificationMethod: () => VerificationMethod;
3
20
  export declare const generateOTP: (length?: number) => string;
4
21
  export declare const getOTPExpiry: (minutes?: number) => Date;
@@ -3,8 +3,44 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.sendVerificationCode = exports.sendEmail = exports.sendSMS = exports.getOTPExpiry = exports.generateOTP = exports.getVerificationMethod = void 0;
6
+ exports.sendVerificationCode = exports.sendEmail = exports.sendSMS = exports.getOTPExpiry = exports.generateOTP = exports.getVerificationMethod = exports.validateContactValue = exports.detectContactType = exports.emailRegex = exports.phoneRegex = void 0;
7
7
  const nodemailer_1 = __importDefault(require("nodemailer"));
8
+ // ==================== CONTACT VALIDATION HELPERS ====================
9
+ /**
10
+ * Regular expressions for contact validation
11
+ */
12
+ exports.phoneRegex = /^\+250(78|79|73|72)[0-9]{7}$/;
13
+ exports.emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
14
+ /**
15
+ * Detect the type of contact value
16
+ * @param value - The contact value to check (email or phone number)
17
+ * @returns The contact type: 'EMAIL', 'PHONE', 'WHATSAPP', or 'UNKNOWN'
18
+ */
19
+ const detectContactType = (value) => {
20
+ if (!value)
21
+ return "UNKNOWN";
22
+ // Check if it's an email
23
+ if (exports.emailRegex.test(value)) {
24
+ return "EMAIL";
25
+ }
26
+ // Check if it's a phone number
27
+ if (exports.phoneRegex.test(value)) {
28
+ return "PHONE";
29
+ }
30
+ return "UNKNOWN";
31
+ };
32
+ exports.detectContactType = detectContactType;
33
+ /**
34
+ * Validate if a contact value is valid (either email or phone)
35
+ * @param value - The contact value to validate
36
+ * @returns True if valid email or phone, false otherwise
37
+ */
38
+ const validateContactValue = (value) => {
39
+ if (!value)
40
+ return false;
41
+ return exports.emailRegex.test(value) || exports.phoneRegex.test(value);
42
+ };
43
+ exports.validateContactValue = validateContactValue;
8
44
  // Get verification method from env
9
45
  const getVerificationMethod = () => {
10
46
  const method = process.env.VERIFICATION_METHOD?.toUpperCase();
@@ -1,6 +1,9 @@
1
1
  import { z } from "zod";
2
2
  export declare const phoneRegex: RegExp;
3
+ export declare const emailRegex: RegExp;
3
4
  export declare const strongPasswordRegex: RegExp;
5
+ export declare const detectContactType: (value: string) => "EMAIL" | "PHONE" | "WHATSAPP" | "UNKNOWN";
6
+ export declare const validateContactValue: (value: string) => boolean;
4
7
  export declare const updateProfileSchema: z.ZodObject<{
5
8
  body: z.ZodObject<{
6
9
  firstName: z.ZodOptional<z.ZodString>;
@@ -28,6 +31,40 @@ export declare const updateProfileSchema: z.ZodObject<{
28
31
  plateNumber?: string | undefined;
29
32
  };
30
33
  }>;
34
+ export declare const updateContactSchema: z.ZodObject<{
35
+ body: z.ZodObject<{
36
+ contactValue: z.ZodEffects<z.ZodString, string, string>;
37
+ }, "strip", z.ZodTypeAny, {
38
+ contactValue: string;
39
+ }, {
40
+ contactValue: string;
41
+ }>;
42
+ }, "strip", z.ZodTypeAny, {
43
+ body: {
44
+ contactValue: string;
45
+ };
46
+ }, {
47
+ body: {
48
+ contactValue: string;
49
+ };
50
+ }>;
51
+ export declare const changeEmailSchema: z.ZodObject<{
52
+ body: z.ZodObject<{
53
+ newEmail: z.ZodString;
54
+ }, "strip", z.ZodTypeAny, {
55
+ newEmail: string;
56
+ }, {
57
+ newEmail: string;
58
+ }>;
59
+ }, "strip", z.ZodTypeAny, {
60
+ body: {
61
+ newEmail: string;
62
+ };
63
+ }, {
64
+ body: {
65
+ newEmail: string;
66
+ };
67
+ }>;
31
68
  export declare const requestPhoneChangeSchema: z.ZodObject<{
32
69
  body: z.ZodObject<{
33
70
  newPhoneNumber: z.ZodString;
@@ -67,6 +104,113 @@ export declare const verifyPhoneChangeSchema: z.ZodObject<{
67
104
  newPhoneOtp: string;
68
105
  };
69
106
  }>;
107
+ export declare const verifyEmailChangeSchema: z.ZodObject<{
108
+ body: z.ZodObject<{
109
+ emailOtp: z.ZodString;
110
+ }, "strip", z.ZodTypeAny, {
111
+ emailOtp: string;
112
+ }, {
113
+ emailOtp: string;
114
+ }>;
115
+ }, "strip", z.ZodTypeAny, {
116
+ body: {
117
+ emailOtp: string;
118
+ };
119
+ }, {
120
+ body: {
121
+ emailOtp: string;
122
+ };
123
+ }>;
124
+ export declare const addContactSchema: z.ZodObject<{
125
+ body: z.ZodObject<{
126
+ contactValue: z.ZodEffects<z.ZodString, string, string>;
127
+ type: z.ZodEffects<z.ZodOptional<z.ZodEnum<["EMAIL", "PHONE", "WHATSAPP"]>>, "EMAIL" | "PHONE" | "WHATSAPP" | undefined, "EMAIL" | "PHONE" | "WHATSAPP" | undefined>;
128
+ }, "strip", z.ZodTypeAny, {
129
+ contactValue: string;
130
+ type?: "EMAIL" | "PHONE" | "WHATSAPP" | undefined;
131
+ }, {
132
+ contactValue: string;
133
+ type?: "EMAIL" | "PHONE" | "WHATSAPP" | undefined;
134
+ }>;
135
+ }, "strip", z.ZodTypeAny, {
136
+ body: {
137
+ contactValue: string;
138
+ type?: "EMAIL" | "PHONE" | "WHATSAPP" | undefined;
139
+ };
140
+ }, {
141
+ body: {
142
+ contactValue: string;
143
+ type?: "EMAIL" | "PHONE" | "WHATSAPP" | undefined;
144
+ };
145
+ }>;
146
+ export declare const deleteContactSchema: z.ZodObject<{
147
+ params: z.ZodObject<{
148
+ contactId: z.ZodString;
149
+ }, "strip", z.ZodTypeAny, {
150
+ contactId: string;
151
+ }, {
152
+ contactId: string;
153
+ }>;
154
+ }, "strip", z.ZodTypeAny, {
155
+ params: {
156
+ contactId: string;
157
+ };
158
+ }, {
159
+ params: {
160
+ contactId: string;
161
+ };
162
+ }>;
163
+ export declare const setPrimaryContactSchema: z.ZodObject<{
164
+ params: z.ZodObject<{
165
+ contactId: z.ZodString;
166
+ }, "strip", z.ZodTypeAny, {
167
+ contactId: string;
168
+ }, {
169
+ contactId: string;
170
+ }>;
171
+ }, "strip", z.ZodTypeAny, {
172
+ params: {
173
+ contactId: string;
174
+ };
175
+ }, {
176
+ params: {
177
+ contactId: string;
178
+ };
179
+ }>;
180
+ export declare const verifyContactSchema: z.ZodObject<{
181
+ params: z.ZodObject<{
182
+ contactId: z.ZodString;
183
+ }, "strip", z.ZodTypeAny, {
184
+ contactId: string;
185
+ }, {
186
+ contactId: string;
187
+ }>;
188
+ }, "strip", z.ZodTypeAny, {
189
+ params: {
190
+ contactId: string;
191
+ };
192
+ }, {
193
+ params: {
194
+ contactId: string;
195
+ };
196
+ }>;
197
+ export declare const confirmVerificationSchema: z.ZodObject<{
198
+ body: z.ZodObject<{
199
+ otp: z.ZodString;
200
+ }, "strip", z.ZodTypeAny, {
201
+ otp: string;
202
+ }, {
203
+ otp: string;
204
+ }>;
205
+ }, "strip", z.ZodTypeAny, {
206
+ body: {
207
+ otp: string;
208
+ };
209
+ }, {
210
+ body: {
211
+ otp: string;
212
+ };
213
+ }>;
70
214
  export declare const deleteAccountSchema: z.ZodObject<{
71
215
  body: z.ZodObject<{
72
216
  confirmation: z.ZodLiteral<"DELETE">;
@@ -111,3 +255,90 @@ export declare const changePasswordSchema: z.ZodObject<{
111
255
  newPassword: string;
112
256
  };
113
257
  }>;
258
+ export declare const loginSchema: z.ZodObject<{
259
+ body: z.ZodObject<{
260
+ contactValue: z.ZodEffects<z.ZodString, string, string>;
261
+ password: z.ZodString;
262
+ }, "strip", z.ZodTypeAny, {
263
+ password: string;
264
+ contactValue: string;
265
+ }, {
266
+ password: string;
267
+ contactValue: string;
268
+ }>;
269
+ }, "strip", z.ZodTypeAny, {
270
+ body: {
271
+ password: string;
272
+ contactValue: string;
273
+ };
274
+ }, {
275
+ body: {
276
+ password: string;
277
+ contactValue: string;
278
+ };
279
+ }>;
280
+ export declare const forgotPasswordSchema: z.ZodObject<{
281
+ body: z.ZodObject<{
282
+ contactValue: z.ZodEffects<z.ZodString, string, string>;
283
+ }, "strip", z.ZodTypeAny, {
284
+ contactValue: string;
285
+ }, {
286
+ contactValue: string;
287
+ }>;
288
+ }, "strip", z.ZodTypeAny, {
289
+ body: {
290
+ contactValue: string;
291
+ };
292
+ }, {
293
+ body: {
294
+ contactValue: string;
295
+ };
296
+ }>;
297
+ export declare const resetPasswordSchema: z.ZodEffects<z.ZodObject<{
298
+ body: z.ZodObject<{
299
+ newPassword: z.ZodString;
300
+ confirmPassword: z.ZodString;
301
+ }, "strip", z.ZodTypeAny, {
302
+ newPassword: string;
303
+ confirmPassword: string;
304
+ }, {
305
+ newPassword: string;
306
+ confirmPassword: string;
307
+ }>;
308
+ }, "strip", z.ZodTypeAny, {
309
+ body: {
310
+ newPassword: string;
311
+ confirmPassword: string;
312
+ };
313
+ }, {
314
+ body: {
315
+ newPassword: string;
316
+ confirmPassword: string;
317
+ };
318
+ }>, {
319
+ body: {
320
+ newPassword: string;
321
+ confirmPassword: string;
322
+ };
323
+ }, {
324
+ body: {
325
+ newPassword: string;
326
+ confirmPassword: string;
327
+ };
328
+ }>;
329
+ export type UpdateProfileSchema = z.infer<typeof updateProfileSchema>;
330
+ export type UpdateContactSchema = z.infer<typeof updateContactSchema>;
331
+ export type ChangeEmailSchema = z.infer<typeof changeEmailSchema>;
332
+ export type RequestPhoneChangeSchema = z.infer<typeof requestPhoneChangeSchema>;
333
+ export type VerifyPhoneChangeSchema = z.infer<typeof verifyPhoneChangeSchema>;
334
+ export type VerifyEmailChangeSchema = z.infer<typeof verifyEmailChangeSchema>;
335
+ export type AddContactSchema = z.infer<typeof addContactSchema>;
336
+ export type DeleteContactSchema = z.infer<typeof deleteContactSchema>;
337
+ export type SetPrimaryContactSchema = z.infer<typeof setPrimaryContactSchema>;
338
+ export type VerifyContactSchema = z.infer<typeof verifyContactSchema>;
339
+ export type ConfirmVerificationSchema = z.infer<typeof confirmVerificationSchema>;
340
+ export type DeleteAccountSchema = z.infer<typeof deleteAccountSchema>;
341
+ export type ChangePasswordSchema = z.infer<typeof changePasswordSchema>;
342
+ export type LoginSchema = z.infer<typeof loginSchema>;
343
+ export type ForgotPasswordSchema = z.infer<typeof forgotPasswordSchema>;
344
+ export type ResetPasswordSchema = z.infer<typeof resetPasswordSchema>;
@@ -1,11 +1,33 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.changePasswordSchema = exports.deleteAccountSchema = exports.verifyPhoneChangeSchema = exports.requestPhoneChangeSchema = exports.updateProfileSchema = exports.strongPasswordRegex = exports.phoneRegex = void 0;
3
+ exports.resetPasswordSchema = exports.forgotPasswordSchema = exports.loginSchema = exports.changePasswordSchema = exports.deleteAccountSchema = exports.confirmVerificationSchema = exports.verifyContactSchema = exports.setPrimaryContactSchema = exports.deleteContactSchema = exports.addContactSchema = exports.verifyEmailChangeSchema = exports.verifyPhoneChangeSchema = exports.requestPhoneChangeSchema = exports.changeEmailSchema = exports.updateContactSchema = exports.updateProfileSchema = exports.validateContactValue = exports.detectContactType = exports.strongPasswordRegex = exports.emailRegex = exports.phoneRegex = void 0;
4
4
  // src/modules/account/validations/account.schema.ts
5
5
  const zod_1 = require("zod");
6
+ // ==================== REGEX PATTERNS ====================
6
7
  exports.phoneRegex = /^\+250(78|79|73|72)[0-9]{7}$/;
8
+ exports.emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
7
9
  const plateRegex = /^[A-Z0-9]{3,10}$/i;
8
10
  exports.strongPasswordRegex = /^(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&#^()_\-+=])[A-Za-z\d@$!%*?&#^()_\-+=]{8,}$/;
11
+ // ==================== CONTACT VALIDATION HELPERS ====================
12
+ const detectContactType = (value) => {
13
+ if (!value)
14
+ return "UNKNOWN";
15
+ // Check if it's an email
16
+ if (exports.emailRegex.test(value)) {
17
+ return "EMAIL";
18
+ }
19
+ // Check if it's a phone number
20
+ if (exports.phoneRegex.test(value)) {
21
+ return "PHONE";
22
+ }
23
+ return "UNKNOWN";
24
+ };
25
+ exports.detectContactType = detectContactType;
26
+ const validateContactValue = (value) => {
27
+ return exports.emailRegex.test(value) || exports.phoneRegex.test(value);
28
+ };
29
+ exports.validateContactValue = validateContactValue;
30
+ // ==================== SCHEMAS ====================
9
31
  exports.updateProfileSchema = zod_1.z.object({
10
32
  body: zod_1.z.object({
11
33
  firstName: zod_1.z.string().min(2).max(50).optional(),
@@ -16,18 +38,91 @@ exports.updateProfileSchema = zod_1.z.object({
16
38
  .optional(),
17
39
  }),
18
40
  });
41
+ // Schema for updating contact (email or phone)
42
+ exports.updateContactSchema = zod_1.z.object({
43
+ body: zod_1.z.object({
44
+ contactValue: zod_1.z
45
+ .string()
46
+ .min(1, "Contact value is required")
47
+ .refine((val) => (0, exports.validateContactValue)(val), {
48
+ message: "Invalid contact value. Must be a valid email or Rwandan phone number (+250...)",
49
+ }),
50
+ }),
51
+ });
52
+ // Schema for changing email specifically
53
+ exports.changeEmailSchema = zod_1.z.object({
54
+ body: zod_1.z.object({
55
+ newEmail: zod_1.z
56
+ .string()
57
+ .email("Invalid email format")
58
+ .min(1, "Email is required"),
59
+ }),
60
+ });
61
+ // Schema for changing phone number specifically
19
62
  exports.requestPhoneChangeSchema = zod_1.z.object({
20
63
  body: zod_1.z.object({
21
- newPhoneNumber: zod_1.z.string().regex(exports.phoneRegex, "Invalid phone number format"),
64
+ newPhoneNumber: zod_1.z
65
+ .string()
66
+ .regex(exports.phoneRegex, "Invalid phone number format. Must be a valid Rwandan phone number (+250...)"),
22
67
  }),
23
68
  });
24
- // Updated validation schema
69
+ // Schema for verifying phone change with OTP
25
70
  exports.verifyPhoneChangeSchema = zod_1.z.object({
26
71
  body: zod_1.z.object({
27
72
  oldPhoneOtp: zod_1.z.string().length(6, "Old phone OTP must be 6 digits"),
28
73
  newPhoneOtp: zod_1.z.string().length(6, "New phone OTP must be 6 digits"),
29
74
  }),
30
75
  });
76
+ // Schema for verifying email change with OTP
77
+ exports.verifyEmailChangeSchema = zod_1.z.object({
78
+ body: zod_1.z.object({
79
+ emailOtp: zod_1.z.string().length(6, "Email OTP must be 6 digits"),
80
+ }),
81
+ });
82
+ // Schema for adding new contact
83
+ exports.addContactSchema = zod_1.z.object({
84
+ body: zod_1.z.object({
85
+ contactValue: zod_1.z
86
+ .string()
87
+ .min(1, "Contact value is required")
88
+ .refine((val) => (0, exports.validateContactValue)(val), {
89
+ message: "Invalid contact value. Must be a valid email or Rwandan phone number (+250...)",
90
+ }),
91
+ type: zod_1.z
92
+ .enum(["EMAIL", "PHONE", "WHATSAPP"])
93
+ .optional()
94
+ .refine((val) => {
95
+ if (!val)
96
+ return true;
97
+ return true;
98
+ }, { message: "Invalid contact type" }),
99
+ }),
100
+ });
101
+ // Schema for deleting a contact
102
+ exports.deleteContactSchema = zod_1.z.object({
103
+ params: zod_1.z.object({
104
+ contactId: zod_1.z.string().uuid("Invalid contact ID"),
105
+ }),
106
+ });
107
+ // Schema for making a contact primary
108
+ exports.setPrimaryContactSchema = zod_1.z.object({
109
+ params: zod_1.z.object({
110
+ contactId: zod_1.z.string().uuid("Invalid contact ID"),
111
+ }),
112
+ });
113
+ // Schema for verifying contact (sending OTP)
114
+ exports.verifyContactSchema = zod_1.z.object({
115
+ params: zod_1.z.object({
116
+ contactId: zod_1.z.string().uuid("Invalid contact ID"),
117
+ }),
118
+ });
119
+ // Schema for confirming contact verification with OTP
120
+ exports.confirmVerificationSchema = zod_1.z.object({
121
+ body: zod_1.z.object({
122
+ otp: zod_1.z.string().length(6, "OTP must be 6 digits"),
123
+ }),
124
+ });
125
+ // Schema for deleting account
31
126
  exports.deleteAccountSchema = zod_1.z.object({
32
127
  body: zod_1.z.object({
33
128
  confirmation: zod_1.z.literal("DELETE", {
@@ -36,6 +131,7 @@ exports.deleteAccountSchema = zod_1.z.object({
36
131
  reason: zod_1.z.string().max(500).optional(),
37
132
  }),
38
133
  });
134
+ // Schema for changing password
39
135
  exports.changePasswordSchema = zod_1.z.object({
40
136
  body: zod_1.z.object({
41
137
  oldPassword: zod_1.z.string().min(1, "Old password is required"),
@@ -44,3 +140,40 @@ exports.changePasswordSchema = zod_1.z.object({
44
140
  .regex(exports.strongPasswordRegex, "Password must be at least 8 characters, include 1 uppercase letter, 1 number and 1 symbol"),
45
141
  }),
46
142
  });
143
+ // Schema for login with contact
144
+ exports.loginSchema = zod_1.z.object({
145
+ body: zod_1.z.object({
146
+ contactValue: zod_1.z
147
+ .string()
148
+ .min(1, "Email or phone number is required")
149
+ .refine((val) => (0, exports.validateContactValue)(val), {
150
+ message: "Invalid contact value. Must be a valid email or Rwandan phone number (+250...)",
151
+ }),
152
+ password: zod_1.z.string().min(1, "Password is required"),
153
+ }),
154
+ });
155
+ // Schema for forgot password
156
+ exports.forgotPasswordSchema = zod_1.z.object({
157
+ body: zod_1.z.object({
158
+ contactValue: zod_1.z
159
+ .string()
160
+ .min(1, "Email or phone number is required")
161
+ .refine((val) => (0, exports.validateContactValue)(val), {
162
+ message: "Invalid contact value. Must be a valid email or Rwandan phone number (+250...)",
163
+ }),
164
+ }),
165
+ });
166
+ // Schema for reset password
167
+ exports.resetPasswordSchema = zod_1.z
168
+ .object({
169
+ body: zod_1.z.object({
170
+ newPassword: zod_1.z
171
+ .string()
172
+ .regex(exports.strongPasswordRegex, "Password must be at least 8 characters, include 1 uppercase letter, 1 number and 1 symbol"),
173
+ confirmPassword: zod_1.z.string(),
174
+ }),
175
+ })
176
+ .refine((data) => data.body.newPassword === data.body.confirmPassword, {
177
+ message: "Passwords do not match",
178
+ path: ["confirmPassword"],
179
+ });