vr-commons 1.0.22 → 1.0.24

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.
@@ -0,0 +1,4 @@
1
+ export * from "./middlewares";
2
+ export * from "./validations";
3
+ export * from "./utils";
4
+ export { validate } from "./validations/validate.validations";
package/dist/index.js ADDED
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.validate = void 0;
18
+ // Core Functionality
19
+ __exportStar(require("./middlewares"), exports);
20
+ __exportStar(require("./validations"), exports);
21
+ __exportStar(require("./utils"), exports);
22
+ var validate_validations_1 = require("./validations/validate.validations");
23
+ Object.defineProperty(exports, "validate", { enumerable: true, get: function () { return validate_validations_1.validate; } });
@@ -0,0 +1,3 @@
1
+ import { Request, Response, NextFunction } from "express";
2
+ import { UserRole } from "vr-models";
3
+ export declare const checkUserAuthentication: (allowedRoles: UserRole[]) => (req: Request, res: Response, next: NextFunction) => Promise<Response<any, Record<string, any>> | undefined>;
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ // src/middlewares/auth/checkUserAuthentication.middleware.ts
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.checkUserAuthentication = void 0;
8
+ const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
9
+ const vr_models_1 = require("vr-models");
10
+ const checkUserAuthentication = (allowedRoles) => async (req, res, next) => {
11
+ try {
12
+ const authHeader = req.headers.authorization;
13
+ if (!authHeader || !authHeader.startsWith("Bearer ")) {
14
+ return res.status(401).json({ message: "Missing or invalid token" });
15
+ }
16
+ const token = authHeader.split(" ")[1];
17
+ let payload;
18
+ try {
19
+ payload = jsonwebtoken_1.default.verify(token, process.env.JWT_SECRET);
20
+ }
21
+ catch {
22
+ return res.status(401).json({ message: "Token expired or invalid" });
23
+ }
24
+ const user = await vr_models_1.User.findOne({
25
+ where: { id: payload.userId },
26
+ include: [
27
+ {
28
+ model: vr_models_1.SecurityClearance,
29
+ as: "securityClearance"
30
+ }
31
+ ]
32
+ });
33
+ if (!user || !user.securityClearance) {
34
+ return res.status(401).json({ message: "User not found" });
35
+ }
36
+ // 🔐 Token versioning (logout all devices)
37
+ if (user.tokenVersion !== payload.tokenVersion) {
38
+ return res.status(401).json({ message: "Session expired" });
39
+ }
40
+ // 🧱 Role enforcement
41
+ if (!allowedRoles.includes(user.securityClearance.role)) {
42
+ return res.status(403).json({ message: "Access denied" });
43
+ }
44
+ // ✅ Extend req
45
+ req.userId = user.id;
46
+ req.firstName = user.firstName;
47
+ req.lastName = user.lastName;
48
+ req.scRole = user.securityClearance.role;
49
+ req.scLevel = user.securityClearance.level;
50
+ req.tokenVersion = user.tokenVersion;
51
+ next();
52
+ }
53
+ catch (error) {
54
+ next(error);
55
+ }
56
+ };
57
+ exports.checkUserAuthentication = checkUserAuthentication;
@@ -0,0 +1 @@
1
+ export { checkUserAuthentication } from "./auth.middlewares";
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.checkUserAuthentication = void 0;
4
+ var auth_middlewares_1 = require("./auth.middlewares");
5
+ Object.defineProperty(exports, "checkUserAuthentication", { enumerable: true, get: function () { return auth_middlewares_1.checkUserAuthentication; } });
@@ -0,0 +1,9 @@
1
+ import { Transaction } from "sequelize";
2
+ export declare const checkAccountDependencies: (userId: string, transaction?: any) => Promise<{
3
+ hasDependencies: boolean;
4
+ activeDevicePlans: number;
5
+ pendingPayments: number;
6
+ activeSubscriptions: number;
7
+ messages: string[];
8
+ }>;
9
+ export declare const hasActiveDependencies: (userId: string, transaction?: Transaction) => Promise<boolean>;
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.hasActiveDependencies = exports.checkAccountDependencies = void 0;
4
+ const vr_models_1 = require("vr-models");
5
+ // Import other models as needed
6
+ const checkAccountDependencies = async (userId, transaction) => {
7
+ const messages = [];
8
+ // 1. Check for active device payment plans
9
+ const activeDevicePlans = await vr_models_1.DevicePaymentPlan.count({
10
+ where: {
11
+ userId,
12
+ status: "ACTIVE", // Adjust based on your status enum
13
+ },
14
+ transaction,
15
+ });
16
+ if (activeDevicePlans > 0) {
17
+ messages.push(`You have ${activeDevicePlans} active device payment plan(s)`);
18
+ }
19
+ // 2. Check for pending payments
20
+ const pendingPayments = await vr_models_1.Transaction.count({
21
+ where: {
22
+ userId,
23
+ status: "PENDING", // Adjust based on your status enum
24
+ },
25
+ transaction,
26
+ });
27
+ if (pendingPayments > 0) {
28
+ messages.push(`You have ${pendingPayments} pending payment(s)`);
29
+ }
30
+ // 3. Add more checks as needed (subscriptions, etc.)
31
+ const hasDependencies = activeDevicePlans > 0 || pendingPayments > 0;
32
+ return {
33
+ hasDependencies,
34
+ activeDevicePlans,
35
+ pendingPayments,
36
+ activeSubscriptions: 0, // Implement if needed
37
+ messages,
38
+ };
39
+ };
40
+ exports.checkAccountDependencies = checkAccountDependencies;
41
+ // Then update the hasActiveDependencies function in passengerUser.utils.ts:
42
+ const hasActiveDependencies = async (userId, transaction) => {
43
+ const result = await (0, exports.checkAccountDependencies)(userId, transaction);
44
+ return result.hasDependencies;
45
+ };
46
+ exports.hasActiveDependencies = hasActiveDependencies;
@@ -0,0 +1,11 @@
1
+ import { UserRole } from "vr-models";
2
+ export interface JWTPayload {
3
+ userId: string;
4
+ role: UserRole;
5
+ level: number;
6
+ tokenVersion: number;
7
+ }
8
+ export declare const generateAdminToken: (userId: string, role: UserRole, level: number, tokenVersion: number, expiresIn: number) => string;
9
+ export declare const generatePassengerToken: (userId: string, role: UserRole, level: number, tokenVersion: number, expiresIn: number) => string;
10
+ export declare const generateRiderToken: (userId: string, role: UserRole, level: number, tokenVersion: number, expiresIn: number) => string;
11
+ export declare const verifyToken: (token: string) => Promise<JWTPayload>;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.verifyToken = exports.generateRiderToken = exports.generatePassengerToken = exports.generateAdminToken = void 0;
7
+ const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
8
+ const generateAdminToken = (userId, role, level, tokenVersion, expiresIn) => {
9
+ const payload = { userId, role, level, tokenVersion };
10
+ return jsonwebtoken_1.default.sign(payload, process.env.JWT_SECRET, {
11
+ expiresIn: expiresIn || Number(process.env.ADMIN_TOKEN_LIFE_SPAN)
12
+ });
13
+ };
14
+ exports.generateAdminToken = generateAdminToken;
15
+ const generatePassengerToken = (userId, role, level, tokenVersion, expiresIn) => {
16
+ const payload = { userId, role, level, tokenVersion };
17
+ return jsonwebtoken_1.default.sign(payload, process.env.JWT_SECRET, {
18
+ expiresIn: expiresIn || Number(process.env.PASSENGER_TOKEN_LIFE_SPAN)
19
+ });
20
+ };
21
+ exports.generatePassengerToken = generatePassengerToken;
22
+ const generateRiderToken = (userId, role, level, tokenVersion, expiresIn) => {
23
+ const payload = { userId, role, level, tokenVersion };
24
+ return jsonwebtoken_1.default.sign(payload, process.env.JWT_SECRET, {
25
+ expiresIn: expiresIn || Number(process.env.RIDER_TOKEN_LIFE_SPAN)
26
+ });
27
+ };
28
+ exports.generateRiderToken = generateRiderToken;
29
+ const verifyToken = async (token) => {
30
+ return jsonwebtoken_1.default.verify(token, process.env.JWT_SECRET);
31
+ };
32
+ exports.verifyToken = verifyToken;
@@ -0,0 +1,13 @@
1
+ import { EventAction, EventActorType } from "vr-models";
2
+ interface LogEventInput {
3
+ actorId?: string | null;
4
+ actorType?: EventActorType;
5
+ action: EventAction;
6
+ entity: string;
7
+ entityId?: string | null;
8
+ metadata?: Record<string, any>;
9
+ ipAddress?: string | null;
10
+ userAgent?: string | null;
11
+ }
12
+ export declare const logEvent: ({ actorId, actorType, action, entity, entityId, metadata, ipAddress, userAgent }: LogEventInput) => Promise<void>;
13
+ export {};
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.logEvent = void 0;
4
+ const vr_models_1 = require("vr-models");
5
+ const logEvent = async ({ actorId = null, actorType = "SYSTEM", action, entity, entityId = null, metadata = {}, ipAddress = null, userAgent = null }) => {
6
+ try {
7
+ await vr_models_1.EventLog.create({
8
+ actorId,
9
+ actorType,
10
+ action,
11
+ entity,
12
+ entityId,
13
+ metadata,
14
+ ipAddress,
15
+ userAgent
16
+ });
17
+ }
18
+ catch (err) {
19
+ console.log("Error Logging event ::::::", err);
20
+ }
21
+ };
22
+ exports.logEvent = logEvent;
@@ -0,0 +1,5 @@
1
+ export { checkAccountDependencies, hasActiveDependencies, } from "./account.utils";
2
+ export { generateAdminToken, generatePassengerToken, generateRiderToken, verifyToken, } from "./authTokens.utils";
3
+ export { logEvent } from "./eventLog.utils";
4
+ export { sendSuccessResponse, sendErrorResponse } from "./response.utils";
5
+ export { formatUserForAdmin, formatAdminProfile, isUserAdmin, isUserAdminOrSuperAdmin, isUserSuperAdmin, getAdminWithClearance, getUserById, findSecurityClearanceByRole, hashPassword, validateUniqueFields, canAdminModifyUser, generateSearchConditions, } from "./profiles.utils";
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateSearchConditions = exports.canAdminModifyUser = exports.validateUniqueFields = exports.hashPassword = exports.findSecurityClearanceByRole = exports.getUserById = exports.getAdminWithClearance = exports.isUserSuperAdmin = exports.isUserAdminOrSuperAdmin = exports.isUserAdmin = exports.formatAdminProfile = exports.formatUserForAdmin = exports.sendErrorResponse = exports.sendSuccessResponse = exports.logEvent = exports.verifyToken = exports.generateRiderToken = exports.generatePassengerToken = exports.generateAdminToken = exports.hasActiveDependencies = exports.checkAccountDependencies = void 0;
4
+ var account_utils_1 = require("./account.utils");
5
+ Object.defineProperty(exports, "checkAccountDependencies", { enumerable: true, get: function () { return account_utils_1.checkAccountDependencies; } });
6
+ Object.defineProperty(exports, "hasActiveDependencies", { enumerable: true, get: function () { return account_utils_1.hasActiveDependencies; } });
7
+ var authTokens_utils_1 = require("./authTokens.utils");
8
+ Object.defineProperty(exports, "generateAdminToken", { enumerable: true, get: function () { return authTokens_utils_1.generateAdminToken; } });
9
+ Object.defineProperty(exports, "generatePassengerToken", { enumerable: true, get: function () { return authTokens_utils_1.generatePassengerToken; } });
10
+ Object.defineProperty(exports, "generateRiderToken", { enumerable: true, get: function () { return authTokens_utils_1.generateRiderToken; } });
11
+ Object.defineProperty(exports, "verifyToken", { enumerable: true, get: function () { return authTokens_utils_1.verifyToken; } });
12
+ var eventLog_utils_1 = require("./eventLog.utils");
13
+ Object.defineProperty(exports, "logEvent", { enumerable: true, get: function () { return eventLog_utils_1.logEvent; } });
14
+ var response_utils_1 = require("./response.utils");
15
+ Object.defineProperty(exports, "sendSuccessResponse", { enumerable: true, get: function () { return response_utils_1.sendSuccessResponse; } });
16
+ Object.defineProperty(exports, "sendErrorResponse", { enumerable: true, get: function () { return response_utils_1.sendErrorResponse; } });
17
+ var profiles_utils_1 = require("./profiles.utils");
18
+ Object.defineProperty(exports, "formatUserForAdmin", { enumerable: true, get: function () { return profiles_utils_1.formatUserForAdmin; } });
19
+ Object.defineProperty(exports, "formatAdminProfile", { enumerable: true, get: function () { return profiles_utils_1.formatAdminProfile; } });
20
+ Object.defineProperty(exports, "isUserAdmin", { enumerable: true, get: function () { return profiles_utils_1.isUserAdmin; } });
21
+ Object.defineProperty(exports, "isUserAdminOrSuperAdmin", { enumerable: true, get: function () { return profiles_utils_1.isUserAdminOrSuperAdmin; } });
22
+ Object.defineProperty(exports, "isUserSuperAdmin", { enumerable: true, get: function () { return profiles_utils_1.isUserSuperAdmin; } });
23
+ Object.defineProperty(exports, "getAdminWithClearance", { enumerable: true, get: function () { return profiles_utils_1.getAdminWithClearance; } });
24
+ Object.defineProperty(exports, "getUserById", { enumerable: true, get: function () { return profiles_utils_1.getUserById; } });
25
+ Object.defineProperty(exports, "findSecurityClearanceByRole", { enumerable: true, get: function () { return profiles_utils_1.findSecurityClearanceByRole; } });
26
+ Object.defineProperty(exports, "hashPassword", { enumerable: true, get: function () { return profiles_utils_1.hashPassword; } });
27
+ Object.defineProperty(exports, "validateUniqueFields", { enumerable: true, get: function () { return profiles_utils_1.validateUniqueFields; } });
28
+ Object.defineProperty(exports, "canAdminModifyUser", { enumerable: true, get: function () { return profiles_utils_1.canAdminModifyUser; } });
29
+ Object.defineProperty(exports, "generateSearchConditions", { enumerable: true, get: function () { return profiles_utils_1.generateSearchConditions; } });
@@ -0,0 +1,52 @@
1
+ import { User, SecurityClearance, UserRole } from "vr-models";
2
+ export interface AdminUserDetailResponse {
3
+ id: string;
4
+ firstName: string;
5
+ lastName: string;
6
+ phoneNumber: string;
7
+ email: string | null;
8
+ nationalId: string;
9
+ jacketId: string;
10
+ plateNumber: string | null;
11
+ isActive: boolean;
12
+ isSuspended: boolean;
13
+ isDeactivated: boolean;
14
+ deactivatedAt: Date | null;
15
+ lastLoginAt: Date | null;
16
+ createdAt: Date;
17
+ role?: string;
18
+ level?: number;
19
+ permissions: string[];
20
+ }
21
+ export interface AdminProfileResponse {
22
+ id: string;
23
+ firstName: string;
24
+ lastName: string;
25
+ phoneNumber: string;
26
+ email: string | null;
27
+ nationalId: string;
28
+ isActive: boolean;
29
+ lastLoginAt: Date | null;
30
+ createdAt: Date;
31
+ role?: string;
32
+ level?: number;
33
+ permissions: string[];
34
+ }
35
+ export declare const formatUserForAdmin: (user: User) => AdminUserDetailResponse;
36
+ export declare const formatAdminProfile: (user: User) => AdminProfileResponse;
37
+ export declare const isUserAdmin: (user: User) => boolean;
38
+ export declare const isUserSuperAdmin: (user: User) => boolean;
39
+ export declare const isUserAdminOrSuperAdmin: (user: User) => boolean;
40
+ export declare const getAdminWithClearance: (userId: string) => Promise<User | null>;
41
+ export declare const getUserById: (userId: string) => Promise<User | null>;
42
+ export declare const findSecurityClearanceByRole: (role: UserRole) => Promise<SecurityClearance | null>;
43
+ export declare const hashPassword: (password: string) => Promise<string>;
44
+ export declare const validateUniqueFields: (phoneNumber: string, nationalId: string, email?: string | null) => Promise<{
45
+ field: string;
46
+ message: string;
47
+ }[]>;
48
+ export declare const canAdminModifyUser: (admin: User, targetUser: User) => {
49
+ canModify: boolean;
50
+ reason?: string;
51
+ };
52
+ export declare const generateSearchConditions: (role?: UserRole, isActive?: boolean, search?: string) => any;
@@ -0,0 +1,198 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.generateSearchConditions = exports.canAdminModifyUser = exports.validateUniqueFields = exports.hashPassword = exports.findSecurityClearanceByRole = exports.getUserById = exports.getAdminWithClearance = exports.isUserAdminOrSuperAdmin = exports.isUserSuperAdmin = exports.isUserAdmin = exports.formatAdminProfile = exports.formatUserForAdmin = void 0;
7
+ const vr_models_1 = require("vr-models");
8
+ const bcryptjs_1 = __importDefault(require("bcryptjs"));
9
+ const sequelize_1 = require("sequelize");
10
+ const formatUserForAdmin = (user) => {
11
+ return {
12
+ id: user.id,
13
+ firstName: user.firstName,
14
+ lastName: user.lastName,
15
+ phoneNumber: user.phoneNumber,
16
+ email: user.email,
17
+ nationalId: user.nationalId,
18
+ jacketId: user.jacketId,
19
+ plateNumber: user.plateNumber,
20
+ isActive: user.isActive,
21
+ isSuspended: user.isSuspended,
22
+ isDeactivated: user.isDeactivated,
23
+ deactivatedAt: user.deactivatedAt,
24
+ lastLoginAt: user.lastLoginAt,
25
+ createdAt: user.createdAt,
26
+ role: user.securityClearance?.role,
27
+ level: user.securityClearance?.level,
28
+ permissions: user.securityClearance?.permissions || [],
29
+ };
30
+ };
31
+ exports.formatUserForAdmin = formatUserForAdmin;
32
+ // Format admin profile
33
+ const formatAdminProfile = (user) => {
34
+ return {
35
+ id: user.id,
36
+ firstName: user.firstName,
37
+ lastName: user.lastName,
38
+ phoneNumber: user.phoneNumber,
39
+ email: user.email,
40
+ nationalId: user.nationalId,
41
+ isActive: user.isActive,
42
+ lastLoginAt: user.lastLoginAt,
43
+ createdAt: user.createdAt,
44
+ role: user.securityClearance?.role,
45
+ level: user.securityClearance?.level,
46
+ permissions: user.securityClearance?.permissions || [],
47
+ };
48
+ };
49
+ exports.formatAdminProfile = formatAdminProfile;
50
+ // Check if user is an admin
51
+ const isUserAdmin = (user) => {
52
+ return user.securityClearance?.role === "ADMIN";
53
+ };
54
+ exports.isUserAdmin = isUserAdmin;
55
+ // Check if user is a super admin
56
+ const isUserSuperAdmin = (user) => {
57
+ return user.securityClearance?.role === "SUPER_ADMIN";
58
+ };
59
+ exports.isUserSuperAdmin = isUserSuperAdmin;
60
+ // Check if user is an admin or super admin
61
+ const isUserAdminOrSuperAdmin = (user) => {
62
+ const role = user.securityClearance?.role;
63
+ return role === "ADMIN" || role === "SUPER_ADMIN";
64
+ };
65
+ exports.isUserAdminOrSuperAdmin = isUserAdminOrSuperAdmin;
66
+ // Get admin with security clearance
67
+ const getAdminWithClearance = async (userId) => {
68
+ return await vr_models_1.User.findOne({
69
+ where: { id: userId },
70
+ include: [
71
+ {
72
+ model: vr_models_1.SecurityClearance,
73
+ as: "securityClearance",
74
+ attributes: ["role", "level", "permissions"],
75
+ },
76
+ ],
77
+ attributes: {
78
+ exclude: [
79
+ "password",
80
+ "otp",
81
+ "otpExpiresAt",
82
+ "tokenVersion",
83
+ "forgotPassword",
84
+ ],
85
+ },
86
+ });
87
+ };
88
+ exports.getAdminWithClearance = getAdminWithClearance;
89
+ // Get user by ID with security clearance
90
+ const getUserById = async (userId) => {
91
+ return await vr_models_1.User.findOne({
92
+ where: { id: userId },
93
+ include: [
94
+ {
95
+ model: vr_models_1.SecurityClearance,
96
+ as: "securityClearance",
97
+ attributes: ["role", "level", "permissions"],
98
+ },
99
+ ],
100
+ attributes: {
101
+ exclude: [
102
+ "password",
103
+ "otp",
104
+ "otpExpiresAt",
105
+ "tokenVersion",
106
+ "forgotPassword",
107
+ ],
108
+ },
109
+ });
110
+ };
111
+ exports.getUserById = getUserById;
112
+ // Find security clearance by role
113
+ const findSecurityClearanceByRole = async (role) => {
114
+ return await vr_models_1.SecurityClearance.findOne({
115
+ where: { role, isDefault: true },
116
+ });
117
+ };
118
+ exports.findSecurityClearanceByRole = findSecurityClearanceByRole;
119
+ // Hash password
120
+ const hashPassword = async (password) => {
121
+ return await bcryptjs_1.default.hash(password, 10);
122
+ };
123
+ exports.hashPassword = hashPassword;
124
+ // Validate unique fields
125
+ const validateUniqueFields = async (phoneNumber, nationalId, email) => {
126
+ const errors = [];
127
+ // Check phone number
128
+ const existingPhone = await vr_models_1.User.findOne({ where: { phoneNumber } });
129
+ if (existingPhone) {
130
+ errors.push({
131
+ field: "phoneNumber",
132
+ message: "Phone number already registered",
133
+ });
134
+ }
135
+ // Check national ID
136
+ const existingNationalId = await vr_models_1.User.findOne({ where: { nationalId } });
137
+ if (existingNationalId) {
138
+ errors.push({
139
+ field: "nationalId",
140
+ message: "National ID already registered",
141
+ });
142
+ }
143
+ // Check email if provided
144
+ if (email) {
145
+ const existingEmail = await vr_models_1.User.findOne({ where: { email } });
146
+ if (existingEmail) {
147
+ errors.push({ field: "email", message: "Email already registered" });
148
+ }
149
+ }
150
+ return errors;
151
+ };
152
+ exports.validateUniqueFields = validateUniqueFields;
153
+ // Check if admin can modify target user
154
+ const canAdminModifyUser = (admin, targetUser) => {
155
+ const adminRole = admin.securityClearance?.role;
156
+ const targetRole = targetUser.securityClearance?.role;
157
+ // Admins cannot modify super admins
158
+ if (targetRole === "SUPER_ADMIN") {
159
+ return { canModify: false, reason: "Cannot modify super admin accounts" };
160
+ }
161
+ // Admins cannot modify other admins (only super admins can)
162
+ if (targetRole === "ADMIN" && adminRole !== "SUPER_ADMIN") {
163
+ return {
164
+ canModify: false,
165
+ reason: "Admins cannot modify other admin accounts",
166
+ };
167
+ }
168
+ // Cannot modify self through this route
169
+ if (admin.id === targetUser.id) {
170
+ return {
171
+ canModify: false,
172
+ reason: "Use profile update route for self-updates",
173
+ };
174
+ }
175
+ return { canModify: true };
176
+ };
177
+ exports.canAdminModifyUser = canAdminModifyUser;
178
+ // Generate search conditions
179
+ const generateSearchConditions = (role, isActive, search) => {
180
+ const where = {};
181
+ if (role) {
182
+ where["$securityClearance.role$"] = role;
183
+ }
184
+ if (isActive !== undefined) {
185
+ where.isActive = isActive;
186
+ }
187
+ if (search) {
188
+ where[sequelize_1.Op.or] = [
189
+ { firstName: { [sequelize_1.Op.iLike]: `%${search}%` } },
190
+ { lastName: { [sequelize_1.Op.iLike]: `%${search}%` } },
191
+ { phoneNumber: { [sequelize_1.Op.iLike]: `%${search}%` } },
192
+ { email: { [sequelize_1.Op.iLike]: `%${search}%` } },
193
+ { nationalId: { [sequelize_1.Op.iLike]: `%${search}%` } },
194
+ ];
195
+ }
196
+ return where;
197
+ };
198
+ exports.generateSearchConditions = generateSearchConditions;
@@ -0,0 +1,3 @@
1
+ import { Response } from "express";
2
+ export declare const sendSuccessResponse: (res: Response, message: string, data?: any, statusCode?: number) => void;
3
+ export declare const sendErrorResponse: (res: Response, message: string, statusCode?: number, error?: any) => void;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sendErrorResponse = exports.sendSuccessResponse = void 0;
4
+ // Success response
5
+ const sendSuccessResponse = (res, message, data = null, statusCode = 200) => {
6
+ res.status(statusCode).json({
7
+ success: true,
8
+ message,
9
+ data
10
+ });
11
+ };
12
+ exports.sendSuccessResponse = sendSuccessResponse;
13
+ // Error response
14
+ const sendErrorResponse = (res, message, statusCode = 400, error = null) => {
15
+ console.error("Error sent to client::::::", error);
16
+ res.status(statusCode).json({
17
+ success: false,
18
+ message,
19
+ error: error?.message || error
20
+ });
21
+ };
22
+ exports.sendErrorResponse = sendErrorResponse;
@@ -0,0 +1,32 @@
1
+ import { z } from "zod";
2
+ export declare const userLoginSchema: z.ZodObject<{
3
+ body: z.ZodObject<{
4
+ phoneNumber: z.ZodString;
5
+ nationalId: z.ZodString;
6
+ }, "strip", z.ZodTypeAny, {
7
+ phoneNumber: string;
8
+ nationalId: string;
9
+ }, {
10
+ phoneNumber: string;
11
+ nationalId: string;
12
+ }>;
13
+ query: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
14
+ params: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
15
+ headers: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
16
+ }, "strip", z.ZodTypeAny, {
17
+ body: {
18
+ phoneNumber: string;
19
+ nationalId: string;
20
+ };
21
+ query?: {} | undefined;
22
+ params?: {} | undefined;
23
+ headers?: {} | undefined;
24
+ }, {
25
+ body: {
26
+ phoneNumber: string;
27
+ nationalId: string;
28
+ };
29
+ query?: {} | undefined;
30
+ params?: {} | undefined;
31
+ headers?: {} | undefined;
32
+ }>;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.userLoginSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ exports.userLoginSchema = zod_1.z.object({
6
+ body: zod_1.z.object({
7
+ phoneNumber: zod_1.z
8
+ .string()
9
+ .trim()
10
+ .min(10, "Phone number must be at least 10 digits")
11
+ .max(15, "Phone number must be at most 15 digits"),
12
+ nationalId: zod_1.z.string().min(16, "National ID must be atleast 16 digits")
13
+ }),
14
+ query: zod_1.z.object({}).optional(),
15
+ params: zod_1.z.object({}).optional(),
16
+ headers: zod_1.z.object({}).optional()
17
+ });
@@ -0,0 +1,3 @@
1
+ export { validate } from "./validate.validations";
2
+ export { userLoginSchema } from "./auth.validations";
3
+ export { createUserSchema, getUserByIdSchema, getAdminProfileSchema, updateUserProfileSchema, getAllUsersSchema, } from "./profiles.validations";
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getAllUsersSchema = exports.updateUserProfileSchema = exports.getAdminProfileSchema = exports.getUserByIdSchema = exports.createUserSchema = exports.userLoginSchema = exports.validate = void 0;
4
+ var validate_validations_1 = require("./validate.validations");
5
+ Object.defineProperty(exports, "validate", { enumerable: true, get: function () { return validate_validations_1.validate; } });
6
+ var auth_validations_1 = require("./auth.validations");
7
+ Object.defineProperty(exports, "userLoginSchema", { enumerable: true, get: function () { return auth_validations_1.userLoginSchema; } });
8
+ var profiles_validations_1 = require("./profiles.validations");
9
+ Object.defineProperty(exports, "createUserSchema", { enumerable: true, get: function () { return profiles_validations_1.createUserSchema; } });
10
+ Object.defineProperty(exports, "getUserByIdSchema", { enumerable: true, get: function () { return profiles_validations_1.getUserByIdSchema; } });
11
+ Object.defineProperty(exports, "getAdminProfileSchema", { enumerable: true, get: function () { return profiles_validations_1.getAdminProfileSchema; } });
12
+ Object.defineProperty(exports, "updateUserProfileSchema", { enumerable: true, get: function () { return profiles_validations_1.updateUserProfileSchema; } });
13
+ Object.defineProperty(exports, "getAllUsersSchema", { enumerable: true, get: function () { return profiles_validations_1.getAllUsersSchema; } });
@@ -0,0 +1,287 @@
1
+ import { z } from "zod";
2
+ export declare const createUserSchema: z.ZodObject<{
3
+ body: z.ZodObject<{
4
+ firstName: z.ZodString;
5
+ lastName: z.ZodString;
6
+ phoneNumber: z.ZodString;
7
+ nationalId: z.ZodString;
8
+ email: z.ZodUnion<[z.ZodNullable<z.ZodOptional<z.ZodString>>, z.ZodLiteral<"">]>;
9
+ password: z.ZodString;
10
+ role: z.ZodEnum<["AGENT", "RIDER"]>;
11
+ plateNumber: z.ZodNullable<z.ZodOptional<z.ZodString>>;
12
+ }, "strip", z.ZodTypeAny, {
13
+ firstName: string;
14
+ lastName: string;
15
+ phoneNumber: string;
16
+ password: string;
17
+ nationalId: string;
18
+ role: "RIDER" | "AGENT";
19
+ email?: string | null | undefined;
20
+ plateNumber?: string | null | undefined;
21
+ }, {
22
+ firstName: string;
23
+ lastName: string;
24
+ phoneNumber: string;
25
+ password: string;
26
+ nationalId: string;
27
+ role: "RIDER" | "AGENT";
28
+ email?: string | null | undefined;
29
+ plateNumber?: string | null | undefined;
30
+ }>;
31
+ params: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
32
+ query: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
33
+ headers: z.ZodObject<{
34
+ authorization: z.ZodString;
35
+ }, "strip", z.ZodTypeAny, {
36
+ authorization: string;
37
+ }, {
38
+ authorization: string;
39
+ }>;
40
+ }, "strip", z.ZodTypeAny, {
41
+ body: {
42
+ firstName: string;
43
+ lastName: string;
44
+ phoneNumber: string;
45
+ password: string;
46
+ nationalId: string;
47
+ role: "RIDER" | "AGENT";
48
+ email?: string | null | undefined;
49
+ plateNumber?: string | null | undefined;
50
+ };
51
+ headers: {
52
+ authorization: string;
53
+ };
54
+ query?: {} | undefined;
55
+ params?: {} | undefined;
56
+ }, {
57
+ body: {
58
+ firstName: string;
59
+ lastName: string;
60
+ phoneNumber: string;
61
+ password: string;
62
+ nationalId: string;
63
+ role: "RIDER" | "AGENT";
64
+ email?: string | null | undefined;
65
+ plateNumber?: string | null | undefined;
66
+ };
67
+ headers: {
68
+ authorization: string;
69
+ };
70
+ query?: {} | undefined;
71
+ params?: {} | undefined;
72
+ }>;
73
+ export declare const getUserByIdSchema: z.ZodObject<{
74
+ params: z.ZodObject<{
75
+ userId: z.ZodString;
76
+ }, "strip", z.ZodTypeAny, {
77
+ userId: string;
78
+ }, {
79
+ userId: string;
80
+ }>;
81
+ body: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
82
+ query: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
83
+ headers: z.ZodObject<{
84
+ authorization: z.ZodString;
85
+ }, "strip", z.ZodTypeAny, {
86
+ authorization: string;
87
+ }, {
88
+ authorization: string;
89
+ }>;
90
+ }, "strip", z.ZodTypeAny, {
91
+ params: {
92
+ userId: string;
93
+ };
94
+ headers: {
95
+ authorization: string;
96
+ };
97
+ body?: {} | undefined;
98
+ query?: {} | undefined;
99
+ }, {
100
+ params: {
101
+ userId: string;
102
+ };
103
+ headers: {
104
+ authorization: string;
105
+ };
106
+ body?: {} | undefined;
107
+ query?: {} | undefined;
108
+ }>;
109
+ export declare const getAdminProfileSchema: z.ZodObject<{
110
+ params: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
111
+ body: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
112
+ query: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
113
+ headers: z.ZodObject<{
114
+ authorization: z.ZodString;
115
+ }, "strip", z.ZodTypeAny, {
116
+ authorization: string;
117
+ }, {
118
+ authorization: string;
119
+ }>;
120
+ }, "strip", z.ZodTypeAny, {
121
+ headers: {
122
+ authorization: string;
123
+ };
124
+ body?: {} | undefined;
125
+ query?: {} | undefined;
126
+ params?: {} | undefined;
127
+ }, {
128
+ headers: {
129
+ authorization: string;
130
+ };
131
+ body?: {} | undefined;
132
+ query?: {} | undefined;
133
+ params?: {} | undefined;
134
+ }>;
135
+ export declare const updateUserProfileSchema: z.ZodObject<{
136
+ params: z.ZodObject<{
137
+ userId: z.ZodString;
138
+ }, "strip", z.ZodTypeAny, {
139
+ userId: string;
140
+ }, {
141
+ userId: string;
142
+ }>;
143
+ body: z.ZodEffects<z.ZodObject<{
144
+ firstName: z.ZodOptional<z.ZodString>;
145
+ lastName: z.ZodOptional<z.ZodString>;
146
+ email: z.ZodUnion<[z.ZodNullable<z.ZodOptional<z.ZodString>>, z.ZodLiteral<"">]>;
147
+ plateNumber: z.ZodNullable<z.ZodOptional<z.ZodString>>;
148
+ isActive: z.ZodOptional<z.ZodBoolean>;
149
+ isSuspended: z.ZodOptional<z.ZodBoolean>;
150
+ password: z.ZodOptional<z.ZodString>;
151
+ }, "strip", z.ZodTypeAny, {
152
+ firstName?: string | undefined;
153
+ lastName?: string | undefined;
154
+ email?: string | null | undefined;
155
+ password?: string | undefined;
156
+ plateNumber?: string | null | undefined;
157
+ isActive?: boolean | undefined;
158
+ isSuspended?: boolean | undefined;
159
+ }, {
160
+ firstName?: string | undefined;
161
+ lastName?: string | undefined;
162
+ email?: string | null | undefined;
163
+ password?: string | undefined;
164
+ plateNumber?: string | null | undefined;
165
+ isActive?: boolean | undefined;
166
+ isSuspended?: boolean | undefined;
167
+ }>, {
168
+ firstName?: string | undefined;
169
+ lastName?: string | undefined;
170
+ email?: string | null | undefined;
171
+ password?: string | undefined;
172
+ plateNumber?: string | null | undefined;
173
+ isActive?: boolean | undefined;
174
+ isSuspended?: boolean | undefined;
175
+ }, {
176
+ firstName?: string | undefined;
177
+ lastName?: string | undefined;
178
+ email?: string | null | undefined;
179
+ password?: string | undefined;
180
+ plateNumber?: string | null | undefined;
181
+ isActive?: boolean | undefined;
182
+ isSuspended?: boolean | undefined;
183
+ }>;
184
+ query: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
185
+ headers: z.ZodObject<{
186
+ authorization: z.ZodString;
187
+ }, "strip", z.ZodTypeAny, {
188
+ authorization: string;
189
+ }, {
190
+ authorization: string;
191
+ }>;
192
+ }, "strip", z.ZodTypeAny, {
193
+ body: {
194
+ firstName?: string | undefined;
195
+ lastName?: string | undefined;
196
+ email?: string | null | undefined;
197
+ password?: string | undefined;
198
+ plateNumber?: string | null | undefined;
199
+ isActive?: boolean | undefined;
200
+ isSuspended?: boolean | undefined;
201
+ };
202
+ params: {
203
+ userId: string;
204
+ };
205
+ headers: {
206
+ authorization: string;
207
+ };
208
+ query?: {} | undefined;
209
+ }, {
210
+ body: {
211
+ firstName?: string | undefined;
212
+ lastName?: string | undefined;
213
+ email?: string | null | undefined;
214
+ password?: string | undefined;
215
+ plateNumber?: string | null | undefined;
216
+ isActive?: boolean | undefined;
217
+ isSuspended?: boolean | undefined;
218
+ };
219
+ params: {
220
+ userId: string;
221
+ };
222
+ headers: {
223
+ authorization: string;
224
+ };
225
+ query?: {} | undefined;
226
+ }>;
227
+ export declare const getAllUsersSchema: z.ZodObject<{
228
+ params: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
229
+ body: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
230
+ query: z.ZodObject<{
231
+ page: z.ZodOptional<z.ZodEffects<z.ZodDefault<z.ZodString>, number, string | undefined>>;
232
+ limit: z.ZodOptional<z.ZodEffects<z.ZodDefault<z.ZodString>, number, string | undefined>>;
233
+ role: z.ZodOptional<z.ZodEnum<["RIDER", "PASSENGER", "AGENT", "ADMIN"]>>;
234
+ isActive: z.ZodOptional<z.ZodEffects<z.ZodEnum<["true", "false"]>, boolean, "true" | "false">>;
235
+ search: z.ZodOptional<z.ZodString>;
236
+ }, "strip", z.ZodTypeAny, {
237
+ search?: string | undefined;
238
+ limit?: number | undefined;
239
+ isActive?: boolean | undefined;
240
+ role?: "RIDER" | "PASSENGER" | "ADMIN" | "AGENT" | undefined;
241
+ page?: number | undefined;
242
+ }, {
243
+ search?: string | undefined;
244
+ limit?: string | undefined;
245
+ isActive?: "true" | "false" | undefined;
246
+ role?: "RIDER" | "PASSENGER" | "ADMIN" | "AGENT" | undefined;
247
+ page?: string | undefined;
248
+ }>;
249
+ headers: z.ZodObject<{
250
+ authorization: z.ZodString;
251
+ }, "strip", z.ZodTypeAny, {
252
+ authorization: string;
253
+ }, {
254
+ authorization: string;
255
+ }>;
256
+ }, "strip", z.ZodTypeAny, {
257
+ query: {
258
+ search?: string | undefined;
259
+ limit?: number | undefined;
260
+ isActive?: boolean | undefined;
261
+ role?: "RIDER" | "PASSENGER" | "ADMIN" | "AGENT" | undefined;
262
+ page?: number | undefined;
263
+ };
264
+ headers: {
265
+ authorization: string;
266
+ };
267
+ body?: {} | undefined;
268
+ params?: {} | undefined;
269
+ }, {
270
+ query: {
271
+ search?: string | undefined;
272
+ limit?: string | undefined;
273
+ isActive?: "true" | "false" | undefined;
274
+ role?: "RIDER" | "PASSENGER" | "ADMIN" | "AGENT" | undefined;
275
+ page?: string | undefined;
276
+ };
277
+ headers: {
278
+ authorization: string;
279
+ };
280
+ body?: {} | undefined;
281
+ params?: {} | undefined;
282
+ }>;
283
+ export type CreateUserInput = z.infer<typeof createUserSchema>;
284
+ export type GetUserByIdInput = z.infer<typeof getUserByIdSchema>;
285
+ export type GetAdminProfileInput = z.infer<typeof getAdminProfileSchema>;
286
+ export type UpdateUserProfileInput = z.infer<typeof updateUserProfileSchema>;
287
+ export type GetAllUsersInput = z.infer<typeof getAllUsersSchema>;
@@ -0,0 +1,141 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getAllUsersSchema = exports.updateUserProfileSchema = exports.getAdminProfileSchema = exports.getUserByIdSchema = exports.createUserSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ // Common validations
6
+ const phoneNumberRegex = /^(078|079|072|073)\d{7}$/;
7
+ const nationalIdRegex = /^\d{16}$/;
8
+ // Admin Create User Schema (for creating agents/riders)
9
+ exports.createUserSchema = zod_1.z.object({
10
+ body: zod_1.z.object({
11
+ firstName: zod_1.z
12
+ .string()
13
+ .min(2, "First name must be at least 2 characters")
14
+ .max(100, "First name cannot exceed 100 characters"),
15
+ lastName: zod_1.z
16
+ .string()
17
+ .min(2, "Last name must be at least 2 characters")
18
+ .max(100, "Last name cannot exceed 100 characters"),
19
+ phoneNumber: zod_1.z
20
+ .string()
21
+ .regex(phoneNumberRegex, "Phone number must be a valid Rwandan number (078/079/072/073) followed by 7 digits"),
22
+ nationalId: zod_1.z
23
+ .string()
24
+ .regex(nationalIdRegex, "National ID must be 16 digits"),
25
+ email: zod_1.z
26
+ .string()
27
+ .email("Invalid email address")
28
+ .optional()
29
+ .nullable()
30
+ .or(zod_1.z.literal("")),
31
+ password: zod_1.z
32
+ .string()
33
+ .min(6, "Password must be at least 6 characters")
34
+ .max(100, "Password cannot exceed 100 characters"),
35
+ role: zod_1.z.enum(["AGENT", "RIDER"], {
36
+ errorMap: () => ({ message: "Role must be either AGENT or RIDER" }),
37
+ }),
38
+ plateNumber: zod_1.z
39
+ .string()
40
+ .max(20, "Plate number cannot exceed 20 characters")
41
+ .optional()
42
+ .nullable(),
43
+ }),
44
+ params: zod_1.z.object({}).optional(),
45
+ query: zod_1.z.object({}).optional(),
46
+ headers: zod_1.z.object({
47
+ authorization: zod_1.z.string().regex(/^Bearer /, {
48
+ message: "Authorization header must start with 'Bearer '",
49
+ }),
50
+ }),
51
+ });
52
+ // Get User by ID Schema
53
+ exports.getUserByIdSchema = zod_1.z.object({
54
+ params: zod_1.z.object({
55
+ userId: zod_1.z.string().uuid("Invalid user ID format"),
56
+ }),
57
+ body: zod_1.z.object({}).optional(),
58
+ query: zod_1.z.object({}).optional(),
59
+ headers: zod_1.z.object({
60
+ authorization: zod_1.z.string().regex(/^Bearer /, {
61
+ message: "Authorization header must start with 'Bearer '",
62
+ }),
63
+ }),
64
+ });
65
+ // Get Admin Profile Schema
66
+ exports.getAdminProfileSchema = zod_1.z.object({
67
+ params: zod_1.z.object({}).optional(),
68
+ body: zod_1.z.object({}).optional(),
69
+ query: zod_1.z.object({}).optional(),
70
+ headers: zod_1.z.object({
71
+ authorization: zod_1.z.string().regex(/^Bearer /, {
72
+ message: "Authorization header must start with 'Bearer '",
73
+ }),
74
+ }),
75
+ });
76
+ // Update User Profile Schema
77
+ exports.updateUserProfileSchema = zod_1.z.object({
78
+ params: zod_1.z.object({
79
+ userId: zod_1.z.string().uuid("Invalid user ID format"),
80
+ }),
81
+ body: zod_1.z
82
+ .object({
83
+ firstName: zod_1.z
84
+ .string()
85
+ .min(2, "First name must be at least 2 characters")
86
+ .max(100, "First name cannot exceed 100 characters")
87
+ .optional(),
88
+ lastName: zod_1.z
89
+ .string()
90
+ .min(2, "Last name must be at least 2 characters")
91
+ .max(100, "Last name cannot exceed 100 characters")
92
+ .optional(),
93
+ email: zod_1.z
94
+ .string()
95
+ .email("Invalid email address")
96
+ .optional()
97
+ .nullable()
98
+ .or(zod_1.z.literal("")),
99
+ plateNumber: zod_1.z
100
+ .string()
101
+ .max(20, "Plate number cannot exceed 20 characters")
102
+ .optional()
103
+ .nullable(),
104
+ isActive: zod_1.z.boolean().optional(),
105
+ isSuspended: zod_1.z.boolean().optional(),
106
+ password: zod_1.z
107
+ .string()
108
+ .min(6, "Password must be at least 6 characters")
109
+ .max(100, "Password cannot exceed 100 characters")
110
+ .optional(),
111
+ })
112
+ .refine((data) => Object.keys(data).length > 0, {
113
+ message: "At least one field must be provided for update",
114
+ }),
115
+ query: zod_1.z.object({}).optional(),
116
+ headers: zod_1.z.object({
117
+ authorization: zod_1.z.string().regex(/^Bearer /, {
118
+ message: "Authorization header must start with 'Bearer '",
119
+ }),
120
+ }),
121
+ });
122
+ // Get All Users Schema (with pagination/filtering)
123
+ exports.getAllUsersSchema = zod_1.z.object({
124
+ params: zod_1.z.object({}).optional(),
125
+ body: zod_1.z.object({}).optional(),
126
+ query: zod_1.z.object({
127
+ page: zod_1.z.string().regex(/^\d+$/).default("1").transform(Number).optional(),
128
+ limit: zod_1.z.string().regex(/^\d+$/).default("20").transform(Number).optional(),
129
+ role: zod_1.z.enum(["RIDER", "PASSENGER", "AGENT", "ADMIN"]).optional(),
130
+ isActive: zod_1.z
131
+ .enum(["true", "false"])
132
+ .transform((val) => val === "true")
133
+ .optional(),
134
+ search: zod_1.z.string().optional(),
135
+ }),
136
+ headers: zod_1.z.object({
137
+ authorization: zod_1.z.string().regex(/^Bearer /, {
138
+ message: "Authorization header must start with 'Bearer '",
139
+ }),
140
+ }),
141
+ });
@@ -0,0 +1,13 @@
1
+ import { Request, Response, NextFunction } from "express";
2
+ import { AnyZodObject } from "zod";
3
+ declare global {
4
+ namespace Express {
5
+ interface Request {
6
+ validatedQuery?: any;
7
+ validatedParams?: any;
8
+ validatedBody?: any;
9
+ validatedHeaders?: any;
10
+ }
11
+ }
12
+ }
13
+ export declare const validate: (schema: AnyZodObject) => (req: Request, res: Response, next: NextFunction) => Promise<void>;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validate = void 0;
4
+ const zod_1 = require("zod");
5
+ const validate = (schema) => async (req, res, next) => {
6
+ try {
7
+ // Validate all parts of the request against the schema
8
+ const result = await schema.parseAsync({
9
+ body: req.body,
10
+ query: req.query,
11
+ params: req.params,
12
+ headers: req.headers // Add headers to validation
13
+ });
14
+ // Store validated values in custom properties
15
+ req.validatedBody = result.body;
16
+ req.validatedQuery = result.query;
17
+ req.validatedParams = result.params;
18
+ req.validatedHeaders = result.headers;
19
+ // Only replace body (other parts should remain read-only)
20
+ req.body = result.body || req.body;
21
+ return next();
22
+ }
23
+ catch (error) {
24
+ console.error(" validate middleware function Error::::::", error);
25
+ if (error instanceof zod_1.ZodError) {
26
+ res.status(400).json({
27
+ status: "fail",
28
+ errors: error.errors.map((err) => ({
29
+ path: err.path.join("."),
30
+ message: err.message
31
+ }))
32
+ });
33
+ return;
34
+ }
35
+ next(error);
36
+ }
37
+ };
38
+ exports.validate = validate;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vr-commons",
3
- "version": "1.0.22",
3
+ "version": "1.0.24",
4
4
  "description": "Shared functions package",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -15,7 +15,7 @@
15
15
  }
16
16
  },
17
17
  "scripts": {
18
- "clean": "rimraf dist",
18
+ "clean": "rimraf dist && rimraf tsconfig.tsbuildinfo",
19
19
  "build": "tsc",
20
20
  "pub:prepare": "npm run build && git add . && git commit -m \"Release preparation\" || true",
21
21
  "pub": "npm run pub:prepare && npm version patch && npm publish && git push --follow-tags"