@7365admin1/core 3.37.0 → 3.39.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @iservice365/core
2
2
 
3
+ ## 3.39.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 7bd9e97: VMS pass and key bugfixes, nfc patrol search filter, etc
8
+
9
+ ## 3.38.0
10
+
11
+ ### Minor Changes
12
+
13
+ - d433685: VMS Checkout Bugfix
14
+
3
15
  ## 3.37.0
4
16
 
5
17
  ### Minor Changes
package/dist/index.d.ts CHANGED
@@ -6107,8 +6107,8 @@ declare function useNfcPatrolLogRepo(): {
6107
6107
  date?: string | undefined;
6108
6108
  type?: "month" | undefined;
6109
6109
  route?: {
6110
- _id: ObjectId | string;
6111
- startTime: string;
6110
+ _id?: string | ObjectId | undefined;
6111
+ startTime?: string | undefined;
6112
6112
  } | undefined;
6113
6113
  }, session?: ClientSession) => Promise<{
6114
6114
  items: any[];
@@ -6139,7 +6139,7 @@ declare function useNfcPatrolLogService(): {
6139
6139
 
6140
6140
  declare function useNfcPatrolLogController(): {
6141
6141
  add: (req: Request, res: Response, next: NextFunction) => Promise<void>;
6142
- getAllBySite: (req: Request, res: Response, next: NextFunction) => Promise<void>;
6142
+ getAllBySite: (req: Request, res: Response, next: NextFunction) => Promise<void | Response<any, Record<string, any>>>;
6143
6143
  completeCheckpoint: (req: Request, res: Response, next: NextFunction) => Promise<void>;
6144
6144
  getLog: (req: Request, res: Response, next: NextFunction) => Promise<void>;
6145
6145
  sign: (req: Request, res: Response, next: NextFunction) => Promise<void>;
package/dist/index.js CHANGED
@@ -25303,9 +25303,9 @@ function usePersonRepo() {
25303
25303
  { email: { $regex: search, $options: "i" } },
25304
25304
  { nric: { $regex: search, $options: "i" } },
25305
25305
  { "plates.plateNumber": { $regex: search, $options: "i" } },
25306
- { contact: { $regex: makeContainsRegex(contact) } },
25307
- { contacts: { $regex: makeContainsRegex(contact) } },
25308
- { plateNumbers: { $regex: makeContainsRegex(plateNumber) } }
25306
+ { contact: { $regex: makeContainsRegex(search) } },
25307
+ { contacts: { $regex: makeContainsRegex(search) } },
25308
+ { plateNumbers: { $regex: makeContainsRegex(search) } }
25309
25309
  ]
25310
25310
  },
25311
25311
  ...import_mongodb45.ObjectId.isValid(org) && { org: new import_mongodb45.ObjectId(org) },
@@ -25918,7 +25918,7 @@ function usePersonRepo() {
25918
25918
  const data = await collection.find(query, { session }).limit(10).toArray();
25919
25919
  return data;
25920
25920
  } catch (error) {
25921
- throw new import_node_server_utils74.InternalServerError("Failed to find many persons.");
25921
+ throw new import_node_server_utils74.InternalServerError("Failed to find persons" + error);
25922
25922
  }
25923
25923
  }
25924
25924
  async function addFromVisitor(value, session) {
@@ -33150,7 +33150,7 @@ function useAttendanceRepository() {
33150
33150
  localField: "user",
33151
33151
  foreignField: "_id",
33152
33152
  as: "user",
33153
- pipeline: [{ $project: { name: 1 } }]
33153
+ pipeline: [{ $project: { name: 1, profile: 1 } }]
33154
33154
  }
33155
33155
  },
33156
33156
  { $unwind: { path: "$user", preserveNullAndEmptyArrays: true } }
@@ -33164,6 +33164,7 @@ function useAttendanceRepository() {
33164
33164
  {
33165
33165
  $project: {
33166
33166
  userName: "$user.name",
33167
+ userProfile: "$user.profile",
33167
33168
  checkInTimestamp: "$checkIn.timestamp",
33168
33169
  checkOutTimestamp: "$checkOut.timestamp",
33169
33170
  createdAt: 1
@@ -35636,7 +35637,7 @@ function useVisitorTransactionService() {
35636
35637
  value.unitName = unit?.name;
35637
35638
  }
35638
35639
  const { nric = "", name = "", contact = "", plateNumber = "", email = "", site = "", type = "guest", company, createdBy } = value;
35639
- if (/^(guest|walk-in|contractor|delivery)$/.test(type)) {
35640
+ if (/^(guest|walk-in|contractor|delivery)$/.test(type) && site) {
35640
35641
  await addUpdateFromVisitor({
35641
35642
  nric,
35642
35643
  name,
@@ -35867,7 +35868,7 @@ function useVisitorTransactionService() {
35867
35868
  value.checkIn = isNaN(parsed.getTime()) ? null : parsed;
35868
35869
  }
35869
35870
  const { nric = "", name = "", contact = "", plateNumber = "", email = "", site = "", type = "guest", company, createdBy } = value;
35870
- if (/^(guest|walk-in|contractor|delivery)$/.test(type)) {
35871
+ if (/^(guest|walk-in|contractor|delivery)$/.test(type) && site) {
35871
35872
  await addUpdateFromVisitor({
35872
35873
  nric,
35873
35874
  name,
@@ -36051,7 +36052,9 @@ function useVisitorTransactionService() {
36051
36052
  value.site,
36052
36053
  session,
36053
36054
  void 0,
36054
- id
36055
+ id,
36056
+ void 0,
36057
+ true
36055
36058
  );
36056
36059
  item.receivedDate = /* @__PURE__ */ new Date();
36057
36060
  item.status = "Not Returned" /* NOT_RETURNED */;
@@ -36100,7 +36103,9 @@ function useVisitorTransactionService() {
36100
36103
  value.site,
36101
36104
  session,
36102
36105
  void 0,
36103
- id
36106
+ id,
36107
+ void 0,
36108
+ true
36104
36109
  );
36105
36110
  item.receivedDate = /* @__PURE__ */ new Date();
36106
36111
  item.status = "Not Returned" /* NOT_RETURNED */;
@@ -55287,8 +55292,11 @@ function useNfcPatrolRouteRepo() {
55287
55292
  const query = {
55288
55293
  site
55289
55294
  };
55290
- if (search) {
55291
- query.$text = { $search: search };
55295
+ if (search?.trim()) {
55296
+ query.name = {
55297
+ $regex: search.trim(),
55298
+ $options: "i"
55299
+ };
55292
55300
  }
55293
55301
  if (filter === "today" || filter === "notToday") {
55294
55302
  const singaporeDateString = (/* @__PURE__ */ new Date()).toLocaleString("en-US", {
@@ -58651,13 +58659,9 @@ function useNfcPatrolLogRepo() {
58651
58659
  };
58652
58660
  if (date) {
58653
58661
  if (type === "month") {
58654
- const [year, month] = date.split("-").map(Number);
58655
- const endDay = new Date(year, month, 0).getDate();
58656
58662
  query.date = {
58657
- $gte: `${year}-${String(month).padStart(2, "0")}-01`,
58658
- $lte: `${year}-${String(month).padStart(2, "0")}-${String(
58659
- endDay
58660
- ).padStart(2, "0")}`
58663
+ $gte: `${date}-01-01`,
58664
+ $lte: `${date}-12-31`
58661
58665
  };
58662
58666
  } else {
58663
58667
  query.date = date;
@@ -58978,47 +58982,52 @@ function useNfcPatrolLogController() {
58978
58982
  page: import_joi111.default.number().integer().min(1).default(1),
58979
58983
  limit: import_joi111.default.number().integer().min(1).max(100).default(10),
58980
58984
  site: import_joi111.default.string().length(24).hex().required(),
58981
- date: import_joi111.default.string().pattern(/^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$/).required().messages({
58982
- "string.pattern.base": "Date must be in YYYY-MM-DD format (e.g. 2026-07-17)"
58985
+ date: import_joi111.default.string().pattern(/^\d{4}(-(0[1-9]|1[0-2])(-(0[1-9]|[12][0-9]|3[01]))?)?$/).optional().messages({
58986
+ "string.pattern.base": "Date must be YYYY or YYYY-MM or YYYY-MM-DD"
58983
58987
  }),
58984
58988
  type: import_joi111.default.string().valid("month").optional(),
58985
58989
  route: import_joi111.default.object({
58986
- _id: import_joi111.default.string().length(24).hex().required(),
58987
- startTime: import_joi111.default.string().pattern(/^([01]\d|2[0-3]):([0-5]\d)$/).required()
58988
- }).required()
58990
+ _id: import_joi111.default.string().length(24).hex().optional(),
58991
+ startTime: import_joi111.default.string().pattern(/^([01]\d|2[0-3]):([0-5]\d)$/).optional().messages({
58992
+ "string.pattern.base": "startTime must be in HH:mm 24-hour format"
58993
+ })
58994
+ }).min(1).optional()
58989
58995
  });
58990
58996
  const query = {
58997
+ page: req.query.page,
58998
+ limit: req.query.limit,
58991
58999
  site: req.query.site,
58992
59000
  date: req.query.date,
58993
- route: {
58994
- _id: req.query["route._id"],
58995
- startTime: req.query["route.startTime"]
58996
- }
59001
+ type: req.query.type,
59002
+ route: req.query["route._id"] || req.query["route.startTime"] ? {
59003
+ ...req.query["route._id"] ? { _id: req.query["route._id"] } : {},
59004
+ ...req.query["route.startTime"] ? { startTime: req.query["route.startTime"] } : {}
59005
+ } : void 0
58997
59006
  };
58998
59007
  const { error, value } = validation.validate(query, {
58999
- abortEarly: false
59008
+ abortEarly: false,
59009
+ allowUnknown: true,
59010
+ stripUnknown: true
59000
59011
  });
59001
59012
  if (error) {
59002
- const messages = error.details.map((d) => d.message).join(", ");
59003
- import_node_server_utils200.logger.log({ level: "error", message: messages });
59004
- next(new import_node_server_utils200.BadRequestError(messages));
59005
- return;
59013
+ return next(
59014
+ new import_node_server_utils200.BadRequestError(
59015
+ error.details.map((d) => d.message).join(", ")
59016
+ )
59017
+ );
59006
59018
  }
59007
- const { page, limit, site, date, route } = value;
59008
59019
  try {
59009
59020
  const data = await _getAllBySite({
59010
- page,
59011
- limit,
59012
- site,
59013
- date,
59014
- route
59021
+ page: value.page,
59022
+ limit: value.limit,
59023
+ site: value.site,
59024
+ date: value.date,
59025
+ type: value.type,
59026
+ route: value.route
59015
59027
  });
59016
- res.status(200).json(data);
59017
- return;
59028
+ return res.status(200).json(data);
59018
59029
  } catch (error2) {
59019
- import_node_server_utils200.logger.log({ level: "error", message: error2.message });
59020
- next(error2);
59021
- return;
59030
+ return next(error2);
59022
59031
  }
59023
59032
  }
59024
59033
  async function completeCheckpoint(req, res, next) {
@@ -64548,34 +64557,62 @@ var import_axios3 = __toESM(require("axios"));
64548
64557
 
64549
64558
  // src/utils/payment-signature.util.ts
64550
64559
  var crypto3 = __toESM(require("crypto"));
64560
+ function hasOwn(obj, key) {
64561
+ return Object.prototype.hasOwnProperty.call(obj, key);
64562
+ }
64563
+ function sha512(input) {
64564
+ return crypto3.createHash("sha512").update(input).digest("hex");
64565
+ }
64566
+ function assertSecret(secretKey) {
64567
+ if (!secretKey) {
64568
+ throw new Error("Payment signature: missing secret key.");
64569
+ }
64570
+ }
64551
64571
  function paymentSignature(params, secretKey) {
64552
- const fieldOrder = ["mid", "order_id", "payment_type", "amount", "ccy", "card_no", "exp_date", "cvv2"];
64572
+ assertSecret(secretKey);
64573
+ const fieldOrder = [
64574
+ "mid",
64575
+ "order_id",
64576
+ "payment_type",
64577
+ "amount",
64578
+ "ccy",
64579
+ "card_no",
64580
+ "exp_date",
64581
+ "cvv2"
64582
+ ];
64553
64583
  let concatenated = "";
64554
64584
  fieldOrder.forEach((v) => {
64555
- if (!params.hasOwnProperty(v)) {
64585
+ if (!hasOwn(params, v)) {
64556
64586
  return;
64557
- } else if (v === "cvv2") {
64558
- concatenated += (params[v] ?? "").toString().slice(-1);
64587
+ }
64588
+ const raw = String(params[v] ?? "");
64589
+ if (v === "cvv2") {
64590
+ concatenated += raw.slice(-1);
64559
64591
  } else if (v === "card_no") {
64560
- concatenated += (params[v] ?? "").substring(0, 6) + (params[v] ?? "").slice(-4);
64592
+ concatenated += raw.substring(0, 6) + raw.slice(-4);
64561
64593
  } else {
64562
- concatenated += params[v];
64594
+ concatenated += raw;
64563
64595
  }
64564
64596
  });
64565
64597
  concatenated += secretKey;
64566
- const signature = crypto3.createHash("sha512").update(concatenated).digest("hex");
64567
- return signature;
64598
+ return sha512(concatenated);
64568
64599
  }
64569
64600
  function genericSignature(params, secretKey) {
64570
- const paramsCopy = { ...params };
64601
+ assertSecret(secretKey);
64602
+ const paramsCopy = {
64603
+ ...params
64604
+ };
64571
64605
  delete paramsCopy["signature"];
64572
- const sortedParams = Object.keys(paramsCopy).sort().reduce((obj, key) => {
64573
- obj[key] = paramsCopy[key];
64574
- return obj;
64575
- }, {});
64576
- const concatenated = Object.values(sortedParams).join("") + secretKey;
64577
- const signature = crypto3.createHash("sha512").update(concatenated).digest("hex");
64578
- return signature;
64606
+ const concatenated = Object.keys(paramsCopy).sort().map((key) => {
64607
+ const value = paramsCopy[key];
64608
+ if (value !== null && typeof value === "object") {
64609
+ throw new Error(
64610
+ `Payment signature: non-primitive value for field "${key}".`
64611
+ );
64612
+ }
64613
+ return String(value ?? "");
64614
+ }).join("") + secretKey;
64615
+ return sha512(concatenated);
64579
64616
  }
64580
64617
 
64581
64618
  // src/repositories/reddot-payment.repository.ts
@@ -64998,7 +65035,7 @@ var useRedDotPaymentSvc = () => {
64998
65035
  };
64999
65036
  if (!process.env.MERCHANT_ENQUIRY) {
65000
65037
  throw new Error(
65001
- "MERCHANT_PAYMENT environment variable is not defined."
65038
+ "MERCHANT_ENQUIRY environment variable is not defined."
65002
65039
  );
65003
65040
  }
65004
65041
  const url = process.env.MERCHANT_ENQUIRY;