vr-commons 1.0.84 → 1.0.86

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.
@@ -150,8 +150,12 @@ export declare const getSortOrder: (sortBy?: string, order?: string) => any[];
150
150
  * Generate unique jacket ID
151
151
  */
152
152
  export declare const generateJacketId: () => Promise<string>;
153
+ export interface ValidationError {
154
+ field: string;
155
+ message: string;
156
+ }
153
157
  /**
154
- * Validate unique user fields
158
+ * Validate unique user fields (phone number is in PhoneContact table)
155
159
  */
156
160
  export declare const validateUniqueFields: (fields: {
157
161
  phoneNumber?: string;
@@ -381,41 +381,62 @@ const generateJacketId = async () => {
381
381
  return jacketId;
382
382
  };
383
383
  exports.generateJacketId = generateJacketId;
384
- // ============================================================================
385
- // VALIDATION FUNCTIONS
386
- // ============================================================================
387
384
  /**
388
- * Validate unique user fields
385
+ * Validate unique user fields (phone number is in PhoneContact table)
389
386
  */
390
387
  const validateUniqueFields = async (fields, excludeUserId) => {
391
388
  const errors = [];
392
- for (const [field, value] of Object.entries(fields)) {
393
- if (!value)
394
- continue;
395
- const where = { [field]: value };
389
+ // Check phone number (in PhoneContact table)
390
+ if (fields.phoneNumber) {
391
+ const phoneWhere = { phoneNumber: fields.phoneNumber, isActive: true };
396
392
  if (excludeUserId) {
397
- where.id = { [sequelize_1.Op.ne]: excludeUserId };
393
+ phoneWhere.userId = { [sequelize_1.Op.ne]: excludeUserId };
398
394
  }
399
- const existing = await vr_models_1.User.findOne({ where });
400
- if (existing) {
401
- let message = "";
402
- switch (field) {
403
- case "phoneNumber":
404
- message = "Phone number already registered";
405
- break;
406
- case "nationalId":
407
- message = "National ID already registered";
408
- break;
409
- case "email":
410
- message = "Email already registered";
411
- break;
412
- case "jacketId":
413
- message = "Jacket ID already taken";
414
- break;
415
- default:
416
- message = `${field} already exists`;
417
- }
418
- errors.push({ field, message });
395
+ const existingPhone = await vr_models_1.PhoneContact.findOne({
396
+ where: phoneWhere,
397
+ include: [{ model: vr_models_1.User, as: "user", attributes: ["id"] }],
398
+ });
399
+ if (existingPhone && existingPhone.userId !== excludeUserId) {
400
+ errors.push({
401
+ field: "phoneNumber",
402
+ message: "Phone number already registered",
403
+ });
404
+ }
405
+ }
406
+ // Check nationalId (on User model)
407
+ if (fields.nationalId) {
408
+ const userWhere = { nationalId: fields.nationalId };
409
+ if (excludeUserId) {
410
+ userWhere.id = { [sequelize_1.Op.ne]: excludeUserId };
411
+ }
412
+ const existingUser = await vr_models_1.User.findOne({ where: userWhere });
413
+ if (existingUser) {
414
+ errors.push({
415
+ field: "nationalId",
416
+ message: "National ID already registered",
417
+ });
418
+ }
419
+ }
420
+ // Check email (on User model)
421
+ if (fields.email) {
422
+ const userWhere = { email: fields.email };
423
+ if (excludeUserId) {
424
+ userWhere.id = { [sequelize_1.Op.ne]: excludeUserId };
425
+ }
426
+ const existingUser = await vr_models_1.User.findOne({ where: userWhere });
427
+ if (existingUser) {
428
+ errors.push({ field: "email", message: "Email already registered" });
429
+ }
430
+ }
431
+ // Check jacketId (on User model)
432
+ if (fields.jacketId) {
433
+ const userWhere = { jacketId: fields.jacketId };
434
+ if (excludeUserId) {
435
+ userWhere.id = { [sequelize_1.Op.ne]: excludeUserId };
436
+ }
437
+ const existingUser = await vr_models_1.User.findOne({ where: userWhere });
438
+ if (existingUser) {
439
+ errors.push({ field: "jacketId", message: "Jacket ID already taken" });
419
440
  }
420
441
  }
421
442
  return errors;
@@ -1,37 +1,6 @@
1
1
  import { z } from "zod";
2
2
  export declare const phoneRegex: RegExp;
3
3
  export declare const passwordRegex: RegExp;
4
- export declare const riderLoginSchema: z.ZodObject<{
5
- body: z.ZodObject<{
6
- phoneNumber: z.ZodString;
7
- nationalId: z.ZodString;
8
- }, "strip", z.ZodTypeAny, {
9
- phoneNumber: string;
10
- nationalId: string;
11
- }, {
12
- phoneNumber: string;
13
- nationalId: string;
14
- }>;
15
- query: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
16
- params: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
17
- headers: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
18
- }, "strip", z.ZodTypeAny, {
19
- body: {
20
- phoneNumber: string;
21
- nationalId: string;
22
- };
23
- params?: {} | undefined;
24
- query?: {} | undefined;
25
- headers?: {} | undefined;
26
- }, {
27
- body: {
28
- phoneNumber: string;
29
- nationalId: string;
30
- };
31
- params?: {} | undefined;
32
- query?: {} | undefined;
33
- headers?: {} | undefined;
34
- }>;
35
4
  export declare const userLoginSchema: z.ZodObject<{
36
5
  body: z.ZodObject<{
37
6
  email: z.ZodString;
@@ -71,6 +40,28 @@ export declare const forgotPasswordSchema: z.ZodObject<{
71
40
  email: string;
72
41
  };
73
42
  }>;
43
+ export declare const changePasswordSchema: z.ZodObject<{
44
+ body: z.ZodObject<{
45
+ oldPassword: z.ZodString;
46
+ newPassword: z.ZodString;
47
+ }, "strip", z.ZodTypeAny, {
48
+ oldPassword: string;
49
+ newPassword: string;
50
+ }, {
51
+ oldPassword: string;
52
+ newPassword: string;
53
+ }>;
54
+ }, "strip", z.ZodTypeAny, {
55
+ body: {
56
+ oldPassword: string;
57
+ newPassword: string;
58
+ };
59
+ }, {
60
+ body: {
61
+ oldPassword: string;
62
+ newPassword: string;
63
+ };
64
+ }>;
74
65
  export declare const refreshTokenSchema: z.ZodObject<{
75
66
  body: z.ZodObject<{
76
67
  refreshToken: z.ZodString;
@@ -96,35 +87,66 @@ export declare const registerSchema: z.ZodObject<{
96
87
  email: z.ZodOptional<z.ZodString>;
97
88
  password: z.ZodString;
98
89
  }, "strict", z.ZodTypeAny, {
99
- phoneNumber: string;
100
90
  password: string;
101
91
  firstName: string;
102
92
  lastName: string;
93
+ phoneNumber: string;
103
94
  email?: string | undefined;
104
95
  }, {
105
- phoneNumber: string;
106
96
  password: string;
107
97
  firstName: string;
108
98
  lastName: string;
99
+ phoneNumber: string;
109
100
  email?: string | undefined;
110
101
  }>;
111
102
  }, "strip", z.ZodTypeAny, {
112
103
  body: {
113
- phoneNumber: string;
114
104
  password: string;
115
105
  firstName: string;
116
106
  lastName: string;
107
+ phoneNumber: string;
117
108
  email?: string | undefined;
118
109
  };
119
110
  }, {
120
111
  body: {
121
- phoneNumber: string;
122
112
  password: string;
123
113
  firstName: string;
124
114
  lastName: string;
115
+ phoneNumber: string;
125
116
  email?: string | undefined;
126
117
  };
127
118
  }>;
119
+ export declare const riderLoginSchema: z.ZodObject<{
120
+ body: z.ZodObject<{
121
+ phoneNumber: z.ZodString;
122
+ nationalId: z.ZodString;
123
+ }, "strip", z.ZodTypeAny, {
124
+ phoneNumber: string;
125
+ nationalId: string;
126
+ }, {
127
+ phoneNumber: string;
128
+ nationalId: string;
129
+ }>;
130
+ query: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
131
+ params: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
132
+ headers: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
133
+ }, "strip", z.ZodTypeAny, {
134
+ body: {
135
+ phoneNumber: string;
136
+ nationalId: string;
137
+ };
138
+ params?: {} | undefined;
139
+ query?: {} | undefined;
140
+ headers?: {} | undefined;
141
+ }, {
142
+ body: {
143
+ phoneNumber: string;
144
+ nationalId: string;
145
+ };
146
+ params?: {} | undefined;
147
+ query?: {} | undefined;
148
+ headers?: {} | undefined;
149
+ }>;
128
150
  export declare const requestOtpSchema: z.ZodObject<{
129
151
  body: z.ZodObject<{
130
152
  phoneNumber: z.ZodString;
@@ -146,42 +168,42 @@ export declare const verifyOtpSchema: z.ZodObject<{
146
168
  body: z.ZodEffects<z.ZodObject<{
147
169
  phoneNumber: z.ZodString;
148
170
  otp: z.ZodString;
149
- firstName: z.ZodString;
150
- lastName: z.ZodString;
171
+ firstName: z.ZodOptional<z.ZodString>;
172
+ lastName: z.ZodOptional<z.ZodString>;
151
173
  }, "strip", z.ZodTypeAny, {
152
174
  phoneNumber: string;
153
- firstName: string;
154
- lastName: string;
155
175
  otp: string;
176
+ firstName?: string | undefined;
177
+ lastName?: string | undefined;
156
178
  }, {
157
179
  phoneNumber: string;
158
- firstName: string;
159
- lastName: string;
160
180
  otp: string;
181
+ firstName?: string | undefined;
182
+ lastName?: string | undefined;
161
183
  }>, {
162
184
  phoneNumber: string;
163
- firstName: string;
164
- lastName: string;
165
185
  otp: string;
186
+ firstName?: string | undefined;
187
+ lastName?: string | undefined;
166
188
  }, {
167
189
  phoneNumber: string;
168
- firstName: string;
169
- lastName: string;
170
190
  otp: string;
191
+ firstName?: string | undefined;
192
+ lastName?: string | undefined;
171
193
  }>;
172
194
  }, "strip", z.ZodTypeAny, {
173
195
  body: {
174
196
  phoneNumber: string;
175
- firstName: string;
176
- lastName: string;
177
197
  otp: string;
198
+ firstName?: string | undefined;
199
+ lastName?: string | undefined;
178
200
  };
179
201
  }, {
180
202
  body: {
181
203
  phoneNumber: string;
182
- firstName: string;
183
- lastName: string;
184
204
  otp: string;
205
+ firstName?: string | undefined;
206
+ lastName?: string | undefined;
185
207
  };
186
208
  }>;
187
209
  export declare const resendOtpSchema: z.ZodObject<{
@@ -1,22 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.resendOtpSchema = exports.verifyOtpSchema = exports.requestOtpSchema = exports.registerSchema = exports.refreshTokenSchema = exports.forgotPasswordSchema = exports.userLoginSchema = exports.riderLoginSchema = exports.passwordRegex = exports.phoneRegex = void 0;
3
+ exports.resendOtpSchema = exports.verifyOtpSchema = exports.requestOtpSchema = exports.riderLoginSchema = exports.registerSchema = exports.refreshTokenSchema = exports.changePasswordSchema = exports.forgotPasswordSchema = exports.userLoginSchema = exports.passwordRegex = exports.phoneRegex = void 0;
4
+ // src/validations/auth.schema.ts
4
5
  const zod_1 = require("zod");
5
6
  exports.phoneRegex = /^\+250(78|79|73|72)[0-9]{7}$/;
6
7
  exports.passwordRegex = /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{6,}$/;
7
- exports.riderLoginSchema = zod_1.z.object({
8
- body: zod_1.z.object({
9
- phoneNumber: zod_1.z
10
- .string()
11
- .trim()
12
- .min(10, "Phone number must be at least 10 digits")
13
- .max(15, "Phone number must be at most 15 digits"),
14
- nationalId: zod_1.z.string().min(16, "National ID must be atleast 16 digits"),
15
- }),
16
- query: zod_1.z.object({}).optional(),
17
- params: zod_1.z.object({}).optional(),
18
- headers: zod_1.z.object({}).optional(),
19
- });
8
+ // ==================== ADMIN AUTH VALIDATIONS ====================
20
9
  exports.userLoginSchema = zod_1.z.object({
21
10
  body: zod_1.z.object({
22
11
  email: zod_1.z.string().email(),
@@ -28,6 +17,14 @@ exports.forgotPasswordSchema = zod_1.z.object({
28
17
  email: zod_1.z.string().email(),
29
18
  }),
30
19
  });
20
+ exports.changePasswordSchema = zod_1.z.object({
21
+ body: zod_1.z.object({
22
+ oldPassword: zod_1.z.string().min(1, "Old password is required"),
23
+ newPassword: zod_1.z
24
+ .string()
25
+ .regex(exports.passwordRegex, "Password must be at least 6 characters with at least one letter and one number"),
26
+ }),
27
+ });
31
28
  exports.refreshTokenSchema = zod_1.z.object({
32
29
  body: zod_1.z.object({
33
30
  refreshToken: zod_1.z.string().min(1, "Refresh token is required"),
@@ -52,6 +49,20 @@ exports.registerSchema = zod_1.z.object({
52
49
  })
53
50
  .strict(),
54
51
  });
52
+ // ==================== USER (RIDER/PASSENGER) AUTH VALIDATIONS ====================
53
+ exports.riderLoginSchema = zod_1.z.object({
54
+ body: zod_1.z.object({
55
+ phoneNumber: zod_1.z
56
+ .string()
57
+ .trim()
58
+ .min(10, "Phone number must be at least 10 digits")
59
+ .max(15, "Phone number must be at most 15 digits"),
60
+ nationalId: zod_1.z.string().min(16, "National ID must be atleast 16 digits"),
61
+ }),
62
+ query: zod_1.z.object({}).optional(),
63
+ params: zod_1.z.object({}).optional(),
64
+ headers: zod_1.z.object({}).optional(),
65
+ });
55
66
  exports.requestOtpSchema = zod_1.z.object({
56
67
  body: zod_1.z.object({
57
68
  phoneNumber: zod_1.z
@@ -67,15 +78,15 @@ exports.verifyOtpSchema = zod_1.z.object({
67
78
  firstName: zod_1.z
68
79
  .string()
69
80
  .min(2, "First name must be at least 2 characters")
70
- .max(50),
81
+ .max(50)
82
+ .optional(),
71
83
  lastName: zod_1.z
72
84
  .string()
73
85
  .min(2, "Last name must be at least 2 characters")
74
- .max(50),
86
+ .max(50)
87
+ .optional(),
75
88
  })
76
89
  .refine((data) => {
77
- // If it's a new user, firstName and lastName are required
78
- // We'll check this in service by checking if user exists
79
90
  return true;
80
91
  }, {
81
92
  message: "First name and last name are required for new users",
@@ -1,39 +1,39 @@
1
1
  import { z } from "zod";
2
2
  export declare const listUserPaymentPlansSchema: z.ZodObject<{
3
3
  query: z.ZodObject<{
4
- status: z.ZodOptional<z.ZodEnum<["PENDING", "SUCCESSFUL", "FAILED"]>>;
4
+ status: z.ZodOptional<z.ZodEnum<["ACTIVE", "COMPLETED", "DEFAULTED", "CANCELLED"]>>;
5
5
  page: z.ZodPipeline<z.ZodEffects<z.ZodOptional<z.ZodString>, number, string | undefined>, z.ZodNumber>;
6
6
  limit: z.ZodPipeline<z.ZodEffects<z.ZodOptional<z.ZodString>, number, string | undefined>, z.ZodNumber>;
7
7
  sortBy: z.ZodOptional<z.ZodEnum<["createdAt", "updatedAt", "nextInstallmentDueAt", "status"]>>;
8
8
  sortOrder: z.ZodOptional<z.ZodEnum<["ASC", "DESC"]>>;
9
9
  }, "strip", z.ZodTypeAny, {
10
- limit: number;
11
10
  page: number;
12
- status?: "PENDING" | "SUCCESSFUL" | "FAILED" | undefined;
13
- sortBy?: "createdAt" | "updatedAt" | "status" | "nextInstallmentDueAt" | undefined;
14
- sortOrder?: "DESC" | "ASC" | undefined;
11
+ limit: number;
12
+ status?: "ACTIVE" | "COMPLETED" | "DEFAULTED" | "CANCELLED" | undefined;
13
+ sortBy?: "status" | "createdAt" | "updatedAt" | "nextInstallmentDueAt" | undefined;
14
+ sortOrder?: "ASC" | "DESC" | undefined;
15
15
  }, {
16
- limit?: string | undefined;
17
- status?: "PENDING" | "SUCCESSFUL" | "FAILED" | undefined;
16
+ status?: "ACTIVE" | "COMPLETED" | "DEFAULTED" | "CANCELLED" | undefined;
18
17
  page?: string | undefined;
19
- sortBy?: "createdAt" | "updatedAt" | "status" | "nextInstallmentDueAt" | undefined;
20
- sortOrder?: "DESC" | "ASC" | undefined;
18
+ limit?: string | undefined;
19
+ sortBy?: "status" | "createdAt" | "updatedAt" | "nextInstallmentDueAt" | undefined;
20
+ sortOrder?: "ASC" | "DESC" | undefined;
21
21
  }>;
22
22
  }, "strip", z.ZodTypeAny, {
23
23
  query: {
24
- limit: number;
25
24
  page: number;
26
- status?: "PENDING" | "SUCCESSFUL" | "FAILED" | undefined;
27
- sortBy?: "createdAt" | "updatedAt" | "status" | "nextInstallmentDueAt" | undefined;
28
- sortOrder?: "DESC" | "ASC" | undefined;
25
+ limit: number;
26
+ status?: "ACTIVE" | "COMPLETED" | "DEFAULTED" | "CANCELLED" | undefined;
27
+ sortBy?: "status" | "createdAt" | "updatedAt" | "nextInstallmentDueAt" | undefined;
28
+ sortOrder?: "ASC" | "DESC" | undefined;
29
29
  };
30
30
  }, {
31
31
  query: {
32
- limit?: string | undefined;
33
- status?: "PENDING" | "SUCCESSFUL" | "FAILED" | undefined;
32
+ status?: "ACTIVE" | "COMPLETED" | "DEFAULTED" | "CANCELLED" | undefined;
34
33
  page?: string | undefined;
35
- sortBy?: "createdAt" | "updatedAt" | "status" | "nextInstallmentDueAt" | undefined;
36
- sortOrder?: "DESC" | "ASC" | undefined;
34
+ limit?: string | undefined;
35
+ sortBy?: "status" | "createdAt" | "updatedAt" | "nextInstallmentDueAt" | undefined;
36
+ sortOrder?: "ASC" | "DESC" | undefined;
37
37
  };
38
38
  }>;
39
39
  export declare const getUserPaymentPlanSchema: z.ZodObject<{
@@ -6,7 +6,7 @@ const vr_models_1 = require("vr-models");
6
6
  const uuidSchema = zod_1.z.string().uuid("Invalid ID format");
7
7
  exports.listUserPaymentPlansSchema = zod_1.z.object({
8
8
  query: zod_1.z.object({
9
- status: zod_1.z.enum(vr_models_1.PAYMENT_STATUS).optional(),
9
+ status: zod_1.z.enum(vr_models_1.PAYMENT_PLAN_STATUS).optional(),
10
10
  page: zod_1.z
11
11
  .string()
12
12
  .optional()
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.extendSessionSchema = exports.unlockDeviceSchema = void 0;
4
4
  const zod_1 = require("zod");
5
- const serialRegex = /^[A-Z0-9]{8,32}$/i;
5
+ const serialRegex = /^[A-Z0-9]{8,24}$/i;
6
6
  exports.unlockDeviceSchema = zod_1.z.object({
7
7
  body: zod_1.z.object({
8
8
  deviceSerialNumber: zod_1.z
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vr-commons",
3
- "version": "1.0.84",
3
+ "version": "1.0.86",
4
4
  "description": "Shared functions package",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",