@duvdu-v1/duvdu 1.1.363 → 1.1.365

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 './isEmailVerified.guard';
2
+ export * from './isPhoneNumberVerified.guard';
3
+ export * from './isFaceRecognitionVerified.guard';
4
+ export * from './isAccountPublished.guard';
@@ -0,0 +1,20 @@
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
+ __exportStar(require("./isEmailVerified.guard"), exports);
18
+ __exportStar(require("./isPhoneNumberVerified.guard"), exports);
19
+ __exportStar(require("./isFaceRecognitionVerified.guard"), exports);
20
+ __exportStar(require("./isAccountPublished.guard"), exports);
@@ -0,0 +1,2 @@
1
+ import type { Request, Response, NextFunction } from 'express';
2
+ export declare const isAccountPublishedGuard: (req: Request, res: Response, next: NextFunction) => Response<any, Record<string, any>> | undefined;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isAccountPublishedGuard = void 0;
4
+ const User_1 = require("../types/User");
5
+ const isAccountPublishedGuard = (req, res, next) => {
6
+ const loggedUser = req.loggedUser;
7
+ if ((loggedUser === null || loggedUser === void 0 ? void 0 : loggedUser.status) !== User_1.UserStatus.published)
8
+ return res.status(403).json({
9
+ message: {
10
+ en: 'Your account is still under review.',
11
+ ar: 'حسابك قيد المراجعة.',
12
+ },
13
+ });
14
+ next();
15
+ };
16
+ exports.isAccountPublishedGuard = isAccountPublishedGuard;
@@ -0,0 +1,2 @@
1
+ import type { Request, Response, NextFunction } from 'express';
2
+ export declare const isFaceRecognitionVerifiedGuard: (req: Request, res: Response, next: NextFunction) => Response<any, Record<string, any>> | undefined;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isFaceRecognitionVerifiedGuard = void 0;
4
+ const isFaceRecognitionVerifiedGuard = (req, res, next) => {
5
+ const loggedUser = req.loggedUser;
6
+ if (!(loggedUser === null || loggedUser === void 0 ? void 0 : loggedUser.isFaceRecognitionVerified))
7
+ return res.status(403).json({
8
+ message: {
9
+ en: 'Your face is not verified yet by an admin.',
10
+ ar: 'لم يتم التحقق من وجهك بعد بواسطة المسؤول.',
11
+ },
12
+ });
13
+ next();
14
+ };
15
+ exports.isFaceRecognitionVerifiedGuard = isFaceRecognitionVerifiedGuard;
package/build/index.d.ts CHANGED
@@ -106,3 +106,4 @@ export * from './config/winston';
106
106
  export * from './middlewares/pull.connection';
107
107
  export * from './mailer/mailer.service';
108
108
  export * from './mailer/mailer.interface';
109
+ export * from './guards';
package/build/index.js CHANGED
@@ -124,3 +124,4 @@ __exportStar(require("./config/winston"), exports);
124
124
  __exportStar(require("./middlewares/pull.connection"), exports);
125
125
  __exportStar(require("./mailer/mailer.service"), exports);
126
126
  __exportStar(require("./mailer/mailer.interface"), exports);
127
+ __exportStar(require("./guards"), exports);
@@ -61,6 +61,7 @@ const isauthenticated = (req, res, next) => __awaiter(void 0, void 0, void 0, fu
61
61
  if (!user) {
62
62
  return next(new unauthorized_error_1.UnauthorizedError({ en: 'user not found', ar: 'لا يوجد مستخدم' }, req.lang));
63
63
  }
64
+ req.loggedUser.status = user.status;
64
65
  if (user.isBlocked.value)
65
66
  return next(new unauthorized_error_1.UnauthorizedError({
66
67
  en: `Forbidden: User is blocked ${req.loggedUser.isBlocked.reason}`,
@@ -13,6 +13,7 @@ exports.Users = void 0;
13
13
  const mongoose_1 = require("mongoose");
14
14
  const rank_service_1 = require("../services/rank.service");
15
15
  const model_names_1 = require("../types/model-names");
16
+ const User_1 = require("../types/User");
16
17
  const userSchema = new mongoose_1.Schema({
17
18
  googleId: { type: String, default: null },
18
19
  appleId: { type: String, default: null },
@@ -76,6 +77,21 @@ const userSchema = new mongoose_1.Schema({
76
77
  projectsView: { type: Number, default: 0 },
77
78
  haveInvitation: { type: Boolean, default: false },
78
79
  faceRecognition: { type: String, default: null },
80
+ isFaceRecognitionVerified: { type: Boolean, default: false },
81
+ status: {
82
+ type: String,
83
+ enum: Object.values(User_1.UserStatus),
84
+ default: User_1.UserStatus.underReview,
85
+ },
86
+ adminReviewFeedback: {
87
+ type: [
88
+ new mongoose_1.Schema({
89
+ note: { type: String, required: true },
90
+ admin: { type: mongoose_1.Schema.Types.ObjectId, ref: model_names_1.MODELS.user, required: true },
91
+ }, { timestamps: { createdAt: true, updatedAt: false } }),
92
+ ],
93
+ default: [],
94
+ },
79
95
  projectsCount: { type: Number, default: 0 },
80
96
  hasFreeTime: { type: Boolean, default: false },
81
97
  experties: {
@@ -103,6 +119,7 @@ const userSchema = new mongoose_1.Schema({
103
119
  .index({ email: 1 }, { unique: true, partialFilterExpression: { isEmailVerified: true } })
104
120
  .index({ 'phoneNumber.number': 1 }, { unique: true, partialFilterExpression: { isPhoneNumberVerified: true } })
105
121
  .index({ username: 1 }, { unique: true });
122
+ userSchema.index({ status: 1, isFaceRecognitionVerified: 1 });
106
123
  userSchema.pre('save', function (next) {
107
124
  return __awaiter(this, void 0, void 0, function* () {
108
125
  if (this.isModified('acceptedProjectsCounter') ||
@@ -9,6 +9,9 @@ export declare enum PERMISSIONS {
9
9
  unBlockUser = "un-block-user",
10
10
  listUsers = "list-users",
11
11
  removeUser = "remove-user",
12
+ listEligibleUsersToReview = "list-eligible-users-to-review",
13
+ acceptUserReview = "accept-user-review",
14
+ declineUserReview = "decline-user-review",
12
15
  listAdmins = "list-admins",
13
16
  createAdmin = "create-admin",
14
17
  updateAdmin = "update-admin",
@@ -15,6 +15,9 @@ var PERMISSIONS;
15
15
  PERMISSIONS["unBlockUser"] = "un-block-user";
16
16
  PERMISSIONS["listUsers"] = "list-users";
17
17
  PERMISSIONS["removeUser"] = "remove-user";
18
+ PERMISSIONS["listEligibleUsersToReview"] = "list-eligible-users-to-review";
19
+ PERMISSIONS["acceptUserReview"] = "accept-user-review";
20
+ PERMISSIONS["declineUserReview"] = "decline-user-review";
18
21
  // admin
19
22
  PERMISSIONS["listAdmins"] = "list-admins";
20
23
  PERMISSIONS["createAdmin"] = "create-admin";
@@ -204,6 +207,9 @@ exports.permissions = {
204
207
  PERMISSIONS.blockAdmin,
205
208
  PERMISSIONS.unBlockAdmin,
206
209
  PERMISSIONS.removeAdmin,
210
+ PERMISSIONS.listEligibleUsersToReview,
211
+ PERMISSIONS.acceptUserReview,
212
+ PERMISSIONS.declineUserReview,
207
213
  ],
208
214
  category: [
209
215
  PERMISSIONS.createCategory,
@@ -227,6 +233,9 @@ exports.permissions = {
227
233
  PERMISSIONS.blockUser,
228
234
  PERMISSIONS.unBlockUser,
229
235
  PERMISSIONS.removeUser,
236
+ PERMISSIONS.listEligibleUsersToReview,
237
+ PERMISSIONS.acceptUserReview,
238
+ PERMISSIONS.declineUserReview,
230
239
  ],
231
240
  admins: [PERMISSIONS.listAdmins, PERMISSIONS.createAdmin, PERMISSIONS.updateAdmin, PERMISSIONS.blockAdmin, PERMISSIONS.unBlockAdmin, PERMISSIONS.removeAdmin],
232
241
  messages: [PERMISSIONS.listMessagesFromTo, PERMISSIONS.sendNotificationToUsers, PERMISSIONS.listMessages],
@@ -16,6 +16,15 @@ export declare enum VerificationReason {
16
16
  completeSginUp = "complete-sginup",
17
17
  CompleteSginUpVerfied = "complete-sginup-verified"
18
18
  }
19
+ export declare enum UserStatus {
20
+ underReview = "under_review",
21
+ published = "published"
22
+ }
23
+ export interface IadminReviewFeedback {
24
+ note: string;
25
+ createdAt: Date;
26
+ admin: Types.ObjectId;
27
+ }
19
28
  export interface Iuser {
20
29
  _id: Types.ObjectId;
21
30
  id: string;
@@ -85,6 +94,9 @@ export interface Iuser {
85
94
  projectsView: number;
86
95
  haveInvitation: boolean;
87
96
  faceRecognition: string | null;
97
+ isFaceRecognitionVerified: boolean;
98
+ status: UserStatus;
99
+ adminReviewFeedback: IadminReviewFeedback[];
88
100
  projectsCount: number;
89
101
  isDeleted: boolean;
90
102
  hasFreeTime: boolean;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.VerificationReason = void 0;
3
+ exports.UserStatus = exports.VerificationReason = void 0;
4
4
  var VerificationReason;
5
5
  (function (VerificationReason) {
6
6
  VerificationReason["updateOldPhoneNumber"] = "update-old-phone-number";
@@ -17,3 +17,8 @@ var VerificationReason;
17
17
  VerificationReason["completeSginUp"] = "complete-sginup";
18
18
  VerificationReason["CompleteSginUpVerfied"] = "complete-sginup-verified";
19
19
  })(VerificationReason || (exports.VerificationReason = VerificationReason = {}));
20
+ var UserStatus;
21
+ (function (UserStatus) {
22
+ UserStatus["underReview"] = "under_review";
23
+ UserStatus["published"] = "published";
24
+ })(UserStatus || (exports.UserStatus = UserStatus = {}));
@@ -9,6 +9,8 @@ declare class BucketWasabi {
9
9
  removeBucketFiles(...filePaths: string[]): Promise<void>;
10
10
  private getContentType;
11
11
  getPresignedUrl(fileKey: string): Promise<string>;
12
+ signKeys<T extends Record<string, any>>(obj: T, keys: (keyof T)[]): Promise<T>;
13
+ signList(keys: (string | null | undefined)[]): Promise<(string | null | undefined)[]>;
12
14
  private getImageBytes;
13
15
  validateFace(imageKey: string): Promise<{
14
16
  isValid: boolean;
@@ -204,7 +204,6 @@ class BucketWasabi {
204
204
  }
205
205
  getPresignedUrl(fileKey) {
206
206
  return __awaiter(this, void 0, void 0, function* () {
207
- console.log('[getPresignedUrl] fileKey:', fileKey, '| bucket:', this.bucketName);
208
207
  const redis = yield (0, redis_connection_1.getRedisClient)();
209
208
  const cacheKey = `wasabi:presigned:${fileKey}`;
210
209
  const cached = yield redis.get(cacheKey);
@@ -215,11 +214,28 @@ class BucketWasabi {
215
214
  Key: fileKey,
216
215
  Expires: 3600,
217
216
  });
218
- console.log('[getPresignedUrl] generated url:', url);
219
217
  yield redis.set(cacheKey, url, 'EX', 3000);
220
218
  return url;
221
219
  });
222
220
  }
221
+ signKeys(obj, keys) {
222
+ return __awaiter(this, void 0, void 0, function* () {
223
+ if (!obj)
224
+ return obj;
225
+ yield Promise.all(keys.map((k) => __awaiter(this, void 0, void 0, function* () {
226
+ if (obj[k])
227
+ obj[k] = yield this.getPresignedUrl(obj[k]);
228
+ })));
229
+ return obj;
230
+ });
231
+ }
232
+ signList(keys) {
233
+ return __awaiter(this, void 0, void 0, function* () {
234
+ if (!(keys === null || keys === void 0 ? void 0 : keys.length))
235
+ return keys;
236
+ return Promise.all(keys.map((k) => (k ? this.getPresignedUrl(k) : k)));
237
+ });
238
+ }
223
239
  // Fetches the image from Wasabi and returns it as bytes for Rekognition
224
240
  getImageBytes(imageKey) {
225
241
  return __awaiter(this, void 0, void 0, function* () {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@duvdu-v1/duvdu",
3
- "version": "1.1.363",
3
+ "version": "1.1.365",
4
4
  "main": "./build/index.js",
5
5
  "types": "./build/index.d.ts",
6
6
  "files": [