@7365admin1/core 2.28.1 → 2.30.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 +12 -0
- package/dist/index.d.ts +139 -46
- package/dist/index.js +1130 -485
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1140 -495
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1419,7 +1419,7 @@ import {
|
|
|
1419
1419
|
import { ObjectId as ObjectId6 } from "mongodb";
|
|
1420
1420
|
import Joi5 from "joi";
|
|
1421
1421
|
var schemaOccurrenceEntry = Joi5.object({
|
|
1422
|
-
site: Joi5.string().hex().required(),
|
|
1422
|
+
site: Joi5.string().hex().length(24).required(),
|
|
1423
1423
|
dailyOccurrenceBookId: Joi5.string().hex().optional().allow(null, ""),
|
|
1424
1424
|
serialNumber: Joi5.string().optional().allow(null, ""),
|
|
1425
1425
|
date: Joi5.date().iso().optional().allow(null, ""),
|
|
@@ -1431,14 +1431,14 @@ var schemaOccurrenceEntry = Joi5.object({
|
|
|
1431
1431
|
createdByName: Joi5.string().optional().allow(null, "")
|
|
1432
1432
|
});
|
|
1433
1433
|
var schemaUpdateOccurrenceEntry = Joi5.object({
|
|
1434
|
-
_id: Joi5.string().hex().required(),
|
|
1434
|
+
_id: Joi5.string().hex().length(24).required(),
|
|
1435
1435
|
serialNumber: Joi5.string().optional().allow(null, ""),
|
|
1436
1436
|
date: Joi5.date().iso().optional().allow(null, ""),
|
|
1437
1437
|
subject: Joi5.string().hex().optional().allow(null, ""),
|
|
1438
1438
|
occurrence: Joi5.string().optional().allow(null, ""),
|
|
1439
1439
|
signature: Joi5.string().hex().optional().allow(null, ""),
|
|
1440
1440
|
incidentReportId: Joi5.string().hex().optional().allow(null, ""),
|
|
1441
|
-
eSignature: Joi5.string().required(),
|
|
1441
|
+
eSignature: Joi5.string().hex().length(24).required(),
|
|
1442
1442
|
createdByName: Joi5.string().optional().allow(null, "")
|
|
1443
1443
|
});
|
|
1444
1444
|
function MOccurrenceEntry(value) {
|
|
@@ -1484,6 +1484,13 @@ function MOccurrenceEntry(value) {
|
|
|
1484
1484
|
throw new Error("Invalid incident report ID.");
|
|
1485
1485
|
}
|
|
1486
1486
|
}
|
|
1487
|
+
if (value.eSignature && typeof value.eSignature === "string") {
|
|
1488
|
+
try {
|
|
1489
|
+
value.eSignature = new ObjectId6(value.eSignature);
|
|
1490
|
+
} catch {
|
|
1491
|
+
throw new Error("Invalid incident report ID.");
|
|
1492
|
+
}
|
|
1493
|
+
}
|
|
1487
1494
|
return {
|
|
1488
1495
|
_id: value._id ?? new ObjectId6(),
|
|
1489
1496
|
site: value.site,
|
|
@@ -12876,12 +12883,9 @@ import Joi40 from "joi";
|
|
|
12876
12883
|
import {
|
|
12877
12884
|
BadRequestError as BadRequestError66,
|
|
12878
12885
|
InternalServerError as InternalServerError23,
|
|
12879
|
-
logger as logger47,
|
|
12880
|
-
makeCacheKey as makeCacheKey22,
|
|
12881
12886
|
paginate as paginate17,
|
|
12882
12887
|
toObjectId as toObjectId6,
|
|
12883
|
-
useAtlas as useAtlas30
|
|
12884
|
-
useCache as useCache23
|
|
12888
|
+
useAtlas as useAtlas30
|
|
12885
12889
|
} from "@7365admin1/node-server-utils";
|
|
12886
12890
|
|
|
12887
12891
|
// src/models/visitor-transactions.model.ts
|
|
@@ -12901,6 +12905,7 @@ var PersonTypes = /* @__PURE__ */ ((PersonTypes3) => {
|
|
|
12901
12905
|
PersonTypes3["GUEST"] = "guest";
|
|
12902
12906
|
PersonTypes3["TENANT"] = "tenant";
|
|
12903
12907
|
PersonTypes3["RESIDENT"] = "resident";
|
|
12908
|
+
PersonTypes3["VISITOR"] = "visitor";
|
|
12904
12909
|
return PersonTypes3;
|
|
12905
12910
|
})(PersonTypes || {});
|
|
12906
12911
|
var PersonStatus = /* @__PURE__ */ ((PersonStatus2) => {
|
|
@@ -13078,7 +13083,7 @@ var schemaVisitorTransaction = Joi36.object({
|
|
|
13078
13083
|
checkIn: Joi36.date().optional().allow(null, ""),
|
|
13079
13084
|
checkOut: Joi36.date().optional().allow(null, ""),
|
|
13080
13085
|
deliveryType: Joi36.string().optional().allow(null, ""),
|
|
13081
|
-
status: Joi36.string().optional().valid(...Object.values(VisitorStatus)).default("
|
|
13086
|
+
status: Joi36.string().optional().valid(...Object.values(VisitorStatus)).default("pending" /* PENDING */),
|
|
13082
13087
|
remarks: Joi36.string().optional().allow(null, ""),
|
|
13083
13088
|
members: Joi36.array().items(
|
|
13084
13089
|
Joi36.object({
|
|
@@ -13088,7 +13093,6 @@ var schemaVisitorTransaction = Joi36.object({
|
|
|
13088
13093
|
contact: Joi36.string().optional().allow(null, "")
|
|
13089
13094
|
})
|
|
13090
13095
|
).optional().allow(null),
|
|
13091
|
-
visitorPass: Joi36.string().optional().allow(null, ""),
|
|
13092
13096
|
unitName: Joi36.string().optional().allow(null, ""),
|
|
13093
13097
|
expiredAt: Joi36.date().iso().optional().allow(null, ""),
|
|
13094
13098
|
arrivalTime: Joi36.string().pattern(/^([01]\d|2[0-3]):([0-5]\d)$/).optional().allow(null, "").messages({
|
|
@@ -13097,7 +13101,15 @@ var schemaVisitorTransaction = Joi36.object({
|
|
|
13097
13101
|
duration: Joi36.number().integer().optional().allow(null),
|
|
13098
13102
|
isOvernightParking: Joi36.boolean().optional().default(false),
|
|
13099
13103
|
email: Joi36.string().email().optional().allow(null, ""),
|
|
13100
|
-
numberOfPassengers: Joi36.number().integer().optional().allow(null, "")
|
|
13104
|
+
numberOfPassengers: Joi36.number().integer().optional().allow(null, ""),
|
|
13105
|
+
visitorPass: Joi36.array().items(
|
|
13106
|
+
Joi36.string().hex().length(24).optional().allow(null)
|
|
13107
|
+
),
|
|
13108
|
+
passKeys: Joi36.array().items(
|
|
13109
|
+
Joi36.string().hex().length(24).optional().allow(null)
|
|
13110
|
+
),
|
|
13111
|
+
checkInRemarks: Joi36.string().optional().allow("", null),
|
|
13112
|
+
checkOutRemarks: Joi36.string().optional().allow("", null)
|
|
13101
13113
|
});
|
|
13102
13114
|
var schemaUpdateVisTrans = Joi36.object({
|
|
13103
13115
|
_id: Joi36.string().hex().length(24).required(),
|
|
@@ -13123,7 +13135,15 @@ var schemaUpdateVisTrans = Joi36.object({
|
|
|
13123
13135
|
status: Joi36.string().optional().allow(null, ""),
|
|
13124
13136
|
remarks: Joi36.string().optional().allow(null, ""),
|
|
13125
13137
|
manualCheckout: Joi36.boolean().optional().allow(null),
|
|
13126
|
-
expiredAt: Joi36.date().iso().optional().allow(null, "")
|
|
13138
|
+
expiredAt: Joi36.date().iso().optional().allow(null, ""),
|
|
13139
|
+
visitorPass: Joi36.array().items(
|
|
13140
|
+
Joi36.string().hex().length(24).optional().allow(null)
|
|
13141
|
+
),
|
|
13142
|
+
passKeys: Joi36.array().items(
|
|
13143
|
+
Joi36.string().hex().length(24).optional().allow(null)
|
|
13144
|
+
),
|
|
13145
|
+
checkInRemarks: Joi36.string().optional().allow("", null),
|
|
13146
|
+
checkOutRemarks: Joi36.string().optional().allow("", null)
|
|
13127
13147
|
});
|
|
13128
13148
|
function MVisitorTransaction(value) {
|
|
13129
13149
|
const { error } = schemaVisitorTransaction.validate(value, {
|
|
@@ -13167,6 +13187,14 @@ function MVisitorTransaction(value) {
|
|
|
13167
13187
|
throw new Error("Invalid type for manualCheckout key.");
|
|
13168
13188
|
}
|
|
13169
13189
|
}
|
|
13190
|
+
if (value.visitorPass && Array.isArray(value.visitorPass) && value.visitorPass.length > 0)
|
|
13191
|
+
value.visitorPass = value.visitorPass.map(
|
|
13192
|
+
(v) => typeof v === "string" ? new ObjectId39(v) : v
|
|
13193
|
+
);
|
|
13194
|
+
if (value.passKeys && Array.isArray(value.passKeys) && value.passKeys.length > 0)
|
|
13195
|
+
value.passKeys = value.passKeys.map(
|
|
13196
|
+
(p) => typeof p === "string" ? new ObjectId39(p) : p
|
|
13197
|
+
);
|
|
13170
13198
|
const newDate = (/* @__PURE__ */ new Date()).toISOString();
|
|
13171
13199
|
return {
|
|
13172
13200
|
_id: value._id,
|
|
@@ -13193,7 +13221,10 @@ function MVisitorTransaction(value) {
|
|
|
13193
13221
|
contractorType: value.contractorType,
|
|
13194
13222
|
manualCheckout: value.manualCheckout ?? false,
|
|
13195
13223
|
direction: value.direction,
|
|
13196
|
-
visitorPass: value.visitorPass,
|
|
13224
|
+
visitorPass: value.visitorPass ?? [],
|
|
13225
|
+
passKeys: value.passKeys ?? [],
|
|
13226
|
+
checkInRemarks: value.checkInRemarks,
|
|
13227
|
+
checkOutRemarks: value.checkOutRemarks,
|
|
13197
13228
|
unitName: value.unitName,
|
|
13198
13229
|
expiredAt: value.expiredAt ?? null,
|
|
13199
13230
|
createdAt: value.createdAt ?? newDate,
|
|
@@ -13211,9 +13242,6 @@ function useVisitorTransactionRepo() {
|
|
|
13211
13242
|
throw new InternalServerError23("Unable to connect to server.");
|
|
13212
13243
|
}
|
|
13213
13244
|
const collection = db.collection(visitors_namespace_collection);
|
|
13214
|
-
const { delNamespace, getCache, setCache } = useCache23(
|
|
13215
|
-
visitors_namespace_collection
|
|
13216
|
-
);
|
|
13217
13245
|
async function createTextIndex() {
|
|
13218
13246
|
try {
|
|
13219
13247
|
await collection.createIndex({
|
|
@@ -13234,16 +13262,6 @@ function useVisitorTransactionRepo() {
|
|
|
13234
13262
|
try {
|
|
13235
13263
|
value = MVisitorTransaction(value);
|
|
13236
13264
|
const res = await collection.insertOne(value, { session });
|
|
13237
|
-
delNamespace().then(() => {
|
|
13238
|
-
logger47.info(
|
|
13239
|
-
`Cache cleared for namespace: ${visitors_namespace_collection}`
|
|
13240
|
-
);
|
|
13241
|
-
}).catch((err) => {
|
|
13242
|
-
logger47.error(
|
|
13243
|
-
`Failed to clear cache for namespace: ${visitors_namespace_collection}`,
|
|
13244
|
-
err
|
|
13245
|
-
);
|
|
13246
|
-
});
|
|
13247
13265
|
return res.insertedId;
|
|
13248
13266
|
} catch (error) {
|
|
13249
13267
|
const isDuplicated = error.message.includes("duplicate");
|
|
@@ -13266,7 +13284,7 @@ function useVisitorTransactionRepo() {
|
|
|
13266
13284
|
type = "",
|
|
13267
13285
|
checkedOut,
|
|
13268
13286
|
plateNumber = ""
|
|
13269
|
-
}
|
|
13287
|
+
}) {
|
|
13270
13288
|
page = page > 0 ? page - 1 : 0;
|
|
13271
13289
|
const skip = page * limit;
|
|
13272
13290
|
let checkOutFilter;
|
|
@@ -13301,26 +13319,6 @@ function useVisitorTransactionRepo() {
|
|
|
13301
13319
|
...plateNumber && { plateNumber }
|
|
13302
13320
|
};
|
|
13303
13321
|
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
13304
|
-
const cacheOptions = {
|
|
13305
|
-
status,
|
|
13306
|
-
page,
|
|
13307
|
-
limit,
|
|
13308
|
-
sort: JSON.stringify(sort),
|
|
13309
|
-
...search && { search },
|
|
13310
|
-
...query.org && { org: query.org.toString() },
|
|
13311
|
-
...query.site && { site: query.site.toString() },
|
|
13312
|
-
...checkIn && { checkIn: JSON.stringify(checkIn) },
|
|
13313
|
-
...checkOutFilter && { checkOut: JSON.stringify(checkOutFilter) },
|
|
13314
|
-
...type && (Array.isArray(type) ? { type: JSON.stringify(type) } : { type }),
|
|
13315
|
-
...checkedOut !== void 0 && { checkedOut },
|
|
13316
|
-
...plateNumber && { plateNumber }
|
|
13317
|
-
};
|
|
13318
|
-
const cacheKey = makeCacheKey22(visitors_namespace_collection, cacheOptions);
|
|
13319
|
-
const cachedData = await getCache(cacheKey);
|
|
13320
|
-
if (cachedData) {
|
|
13321
|
-
logger47.info(`Cache hit for key: ${cacheKey}`);
|
|
13322
|
-
return cachedData;
|
|
13323
|
-
}
|
|
13324
13322
|
try {
|
|
13325
13323
|
const basePipeline = [{ $match: query }];
|
|
13326
13324
|
const [items, countResult] = await Promise.all([
|
|
@@ -13364,23 +13362,12 @@ function useVisitorTransactionRepo() {
|
|
|
13364
13362
|
]);
|
|
13365
13363
|
const totalCount = countResult[0]?.total || 0;
|
|
13366
13364
|
const data = paginate17(items, page, limit, totalCount);
|
|
13367
|
-
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
13368
|
-
logger47.info(`Cache set for key: ${cacheKey}`);
|
|
13369
|
-
}).catch((err) => {
|
|
13370
|
-
logger47.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
13371
|
-
});
|
|
13372
13365
|
return data;
|
|
13373
13366
|
} catch (error) {
|
|
13374
13367
|
throw error;
|
|
13375
13368
|
}
|
|
13376
13369
|
}
|
|
13377
13370
|
async function getVisitorTransactionById(id) {
|
|
13378
|
-
const cacheKey = makeCacheKey22(visitors_namespace_collection, { id });
|
|
13379
|
-
const cachedData = await getCache(cacheKey);
|
|
13380
|
-
if (cachedData) {
|
|
13381
|
-
logger47.info(`Cache hit for key: ${cacheKey}`);
|
|
13382
|
-
return cachedData;
|
|
13383
|
-
}
|
|
13384
13371
|
const _id = toObjectId6(id);
|
|
13385
13372
|
try {
|
|
13386
13373
|
const basePipeline = [{ $match: { _id } }];
|
|
@@ -13417,38 +13404,20 @@ function useVisitorTransactionRepo() {
|
|
|
13417
13404
|
}
|
|
13418
13405
|
}
|
|
13419
13406
|
]).toArray();
|
|
13420
|
-
setCache(cacheKey, result, 15 * 60).then(() => {
|
|
13421
|
-
logger47.info(`Cache set for key: ${cacheKey}`);
|
|
13422
|
-
}).catch((err) => {
|
|
13423
|
-
logger47.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
13424
|
-
});
|
|
13425
13407
|
return result;
|
|
13426
13408
|
} catch (error) {
|
|
13427
13409
|
throw error;
|
|
13428
13410
|
}
|
|
13429
13411
|
}
|
|
13430
13412
|
async function getOpenByPlateNumber(plateNumber, site) {
|
|
13431
|
-
const _site = typeof site === "string" ? site :
|
|
13432
|
-
const
|
|
13413
|
+
const _site = typeof site === "string" ? toObjectId6(site) : site;
|
|
13414
|
+
const query = {
|
|
13433
13415
|
plateNumber,
|
|
13434
|
-
|
|
13435
|
-
|
|
13436
|
-
}
|
|
13416
|
+
site: _site,
|
|
13417
|
+
checkOut: null
|
|
13418
|
+
};
|
|
13437
13419
|
try {
|
|
13438
|
-
const
|
|
13439
|
-
if (cacheData) {
|
|
13440
|
-
logger47.info(`Cache hit for key: ${cacheKey}`);
|
|
13441
|
-
return cacheData;
|
|
13442
|
-
}
|
|
13443
|
-
const data = await collection.findOne(
|
|
13444
|
-
{ plateNumber, site: _site, checkOut: null },
|
|
13445
|
-
{ sort: { _id: -1 } }
|
|
13446
|
-
);
|
|
13447
|
-
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
13448
|
-
logger47.info(`Cache set for key: ${cacheKey}`);
|
|
13449
|
-
}).catch((err) => {
|
|
13450
|
-
logger47.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
13451
|
-
});
|
|
13420
|
+
const data = await collection.findOne(query);
|
|
13452
13421
|
return data;
|
|
13453
13422
|
} catch (error) {
|
|
13454
13423
|
throw new InternalServerError23(
|
|
@@ -13472,16 +13441,6 @@ function useVisitorTransactionRepo() {
|
|
|
13472
13441
|
{ $set: value },
|
|
13473
13442
|
{ session }
|
|
13474
13443
|
);
|
|
13475
|
-
delNamespace().then(() => {
|
|
13476
|
-
logger47.info(
|
|
13477
|
-
`Cache cleared for namespace: ${visitors_namespace_collection}`
|
|
13478
|
-
);
|
|
13479
|
-
}).catch((err) => {
|
|
13480
|
-
logger47.error(
|
|
13481
|
-
`Failed to clear cache for namespace: ${visitors_namespace_collection}`,
|
|
13482
|
-
err
|
|
13483
|
-
);
|
|
13484
|
-
});
|
|
13485
13444
|
return result;
|
|
13486
13445
|
} catch (error) {
|
|
13487
13446
|
throw error;
|
|
@@ -13503,16 +13462,6 @@ function useVisitorTransactionRepo() {
|
|
|
13503
13462
|
if (res.modifiedCount === 0) {
|
|
13504
13463
|
throw new InternalServerError23("Unable to delete visitor transaction.");
|
|
13505
13464
|
}
|
|
13506
|
-
delNamespace().then(() => {
|
|
13507
|
-
logger47.info(
|
|
13508
|
-
`Cache cleared for namespace: ${visitors_namespace_collection}`
|
|
13509
|
-
);
|
|
13510
|
-
}).catch((err) => {
|
|
13511
|
-
logger47.error(
|
|
13512
|
-
`Failed to clear cache for namespace: ${visitors_namespace_collection}`,
|
|
13513
|
-
err
|
|
13514
|
-
);
|
|
13515
|
-
});
|
|
13516
13465
|
return res.modifiedCount;
|
|
13517
13466
|
} catch (error) {
|
|
13518
13467
|
throw error;
|
|
@@ -13578,16 +13527,6 @@ function useVisitorTransactionRepo() {
|
|
|
13578
13527
|
},
|
|
13579
13528
|
{ session }
|
|
13580
13529
|
);
|
|
13581
|
-
delNamespace().then(() => {
|
|
13582
|
-
logger47.info(
|
|
13583
|
-
`Cache cleared for namespace: ${visitors_namespace_collection}`
|
|
13584
|
-
);
|
|
13585
|
-
}).catch((err) => {
|
|
13586
|
-
logger47.error(
|
|
13587
|
-
`Failed to clear cache for namespace: ${visitors_namespace_collection}`,
|
|
13588
|
-
err
|
|
13589
|
-
);
|
|
13590
|
-
});
|
|
13591
13530
|
return res;
|
|
13592
13531
|
} catch (error) {
|
|
13593
13532
|
throw error;
|
|
@@ -13619,6 +13558,7 @@ var VehicleType = /* @__PURE__ */ ((VehicleType2) => {
|
|
|
13619
13558
|
var VehicleCategory = /* @__PURE__ */ ((VehicleCategory2) => {
|
|
13620
13559
|
VehicleCategory2["RESIDENT"] = "resident";
|
|
13621
13560
|
VehicleCategory2["VISITOR"] = "visitor";
|
|
13561
|
+
VehicleCategory2["GUEST"] = "guest";
|
|
13622
13562
|
return VehicleCategory2;
|
|
13623
13563
|
})(VehicleCategory || {});
|
|
13624
13564
|
var VehicleStatus = /* @__PURE__ */ ((VehicleStatus2) => {
|
|
@@ -13663,7 +13603,7 @@ var vehicleSchema = Joi37.object({
|
|
|
13663
13603
|
return value;
|
|
13664
13604
|
}).required(),
|
|
13665
13605
|
type: Joi37.string().required().valid(...Object.values(VehicleType)),
|
|
13666
|
-
category: Joi37.string().required().valid(...Object.values(
|
|
13606
|
+
category: Joi37.string().required().valid(...Object.values(PersonTypes)),
|
|
13667
13607
|
name: Joi37.string().required(),
|
|
13668
13608
|
phoneNumber: Joi37.string().optional().allow("", null),
|
|
13669
13609
|
recNo: Joi37.string().optional().allow("", null),
|
|
@@ -13801,12 +13741,10 @@ import {
|
|
|
13801
13741
|
BadRequestError as BadRequestError68,
|
|
13802
13742
|
InternalServerError as InternalServerError24,
|
|
13803
13743
|
logger as logger49,
|
|
13804
|
-
makeCacheKey as makeCacheKey23,
|
|
13805
13744
|
NotFoundError as NotFoundError17,
|
|
13806
13745
|
paginate as paginate18,
|
|
13807
13746
|
toObjectId as toObjectId7,
|
|
13808
|
-
useAtlas as useAtlas31
|
|
13809
|
-
useCache as useCache24
|
|
13747
|
+
useAtlas as useAtlas31
|
|
13810
13748
|
} from "@7365admin1/node-server-utils";
|
|
13811
13749
|
import { ObjectId as ObjectId42 } from "mongodb";
|
|
13812
13750
|
import Joi38 from "joi";
|
|
@@ -13818,9 +13756,6 @@ function useVehicleRepo() {
|
|
|
13818
13756
|
throw new InternalServerError24("Unable to connect to server.");
|
|
13819
13757
|
}
|
|
13820
13758
|
const collection = db.collection(vehicles_namespace_collection);
|
|
13821
|
-
const { delNamespace, setCache, getCache } = useCache24(
|
|
13822
|
-
vehicles_namespace_collection
|
|
13823
|
-
);
|
|
13824
13759
|
async function createIndex() {
|
|
13825
13760
|
try {
|
|
13826
13761
|
await collection.createIndexes([
|
|
@@ -13852,16 +13787,6 @@ function useVehicleRepo() {
|
|
|
13852
13787
|
try {
|
|
13853
13788
|
value = MVehicle(value);
|
|
13854
13789
|
const res = await collection.insertOne(value, { session });
|
|
13855
|
-
delNamespace().then(() => {
|
|
13856
|
-
logger49.info(
|
|
13857
|
-
`Cache cleared for namespace: ${vehicles_namespace_collection}`
|
|
13858
|
-
);
|
|
13859
|
-
}).catch((err) => {
|
|
13860
|
-
logger49.error(
|
|
13861
|
-
`Failed to clear cache for namespace: ${vehicles_namespace_collection}`,
|
|
13862
|
-
err
|
|
13863
|
-
);
|
|
13864
|
-
});
|
|
13865
13790
|
return res.insertedId;
|
|
13866
13791
|
} catch (error) {
|
|
13867
13792
|
logger49.log({
|
|
@@ -13886,29 +13811,12 @@ function useVehicleRepo() {
|
|
|
13886
13811
|
}) {
|
|
13887
13812
|
page = page > 0 ? page - 1 : 0;
|
|
13888
13813
|
const baseQuery = {
|
|
13889
|
-
...status && { status },
|
|
13890
|
-
...type && { type },
|
|
13891
|
-
...category && { category }
|
|
13892
|
-
};
|
|
13893
|
-
let query = { ...baseQuery };
|
|
13894
|
-
const cacheOptions = {
|
|
13895
13814
|
...status && { status },
|
|
13896
13815
|
...type && { type },
|
|
13897
13816
|
...category && { category },
|
|
13898
|
-
|
|
13899
|
-
limit: String(limit),
|
|
13900
|
-
sort: JSON.stringify(sort)
|
|
13817
|
+
...search && { $text: { search } }
|
|
13901
13818
|
};
|
|
13902
|
-
|
|
13903
|
-
query.$text = { $search: search };
|
|
13904
|
-
cacheOptions.search = search;
|
|
13905
|
-
}
|
|
13906
|
-
const cacheKey = makeCacheKey23(vehicles_namespace_collection, cacheOptions);
|
|
13907
|
-
const cachedData = await getCache(cacheKey);
|
|
13908
|
-
if (cachedData) {
|
|
13909
|
-
logger49.info(`Cache hit for key: ${cacheKey}`);
|
|
13910
|
-
return cachedData;
|
|
13911
|
-
}
|
|
13819
|
+
let query = { ...baseQuery };
|
|
13912
13820
|
const escapeRegex = (input) => input.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
13913
13821
|
const buildGroupedPipeline = (matchQuery) => [
|
|
13914
13822
|
{ $match: matchQuery },
|
|
@@ -14066,9 +13974,6 @@ function useVehicleRepo() {
|
|
|
14066
13974
|
length = regexCountResult[0]?.total || 0;
|
|
14067
13975
|
}
|
|
14068
13976
|
const data = paginate18(items, page, limit, length);
|
|
14069
|
-
setCache(cacheKey, data, 15 * 60).then(() => logger49.info(`Cache set for key: ${cacheKey}`)).catch(
|
|
14070
|
-
(err) => logger49.error(`Failed to set cache for key: ${cacheKey}`, err)
|
|
14071
|
-
);
|
|
14072
13977
|
return data;
|
|
14073
13978
|
} catch (error) {
|
|
14074
13979
|
throw error;
|
|
@@ -14080,14 +13985,6 @@ function useVehicleRepo() {
|
|
|
14080
13985
|
} catch (error) {
|
|
14081
13986
|
throw new BadRequestError68("Invalid site ID format.");
|
|
14082
13987
|
}
|
|
14083
|
-
const cacheKey = makeCacheKey23(vehicles_namespace_collection, {
|
|
14084
|
-
site,
|
|
14085
|
-
type: "season-pass-type-as-options"
|
|
14086
|
-
});
|
|
14087
|
-
const cachedData = await getCache(cacheKey);
|
|
14088
|
-
if (cachedData) {
|
|
14089
|
-
return cachedData;
|
|
14090
|
-
}
|
|
14091
13988
|
try {
|
|
14092
13989
|
const categories = await collection.aggregate([
|
|
14093
13990
|
{ $match: { site } },
|
|
@@ -14107,17 +14004,6 @@ function useVehicleRepo() {
|
|
|
14107
14004
|
},
|
|
14108
14005
|
{ $sort: { title: 1 } }
|
|
14109
14006
|
]).toArray();
|
|
14110
|
-
setCache(cacheKey, categories).then(() => {
|
|
14111
|
-
logger49.log({
|
|
14112
|
-
level: "info",
|
|
14113
|
-
message: `Cache set for get season pass type: ${cacheKey}`
|
|
14114
|
-
});
|
|
14115
|
-
}).catch((err) => {
|
|
14116
|
-
logger49.log({
|
|
14117
|
-
level: "error",
|
|
14118
|
-
message: `Failed to set cache for season pass type: ${err.message}`
|
|
14119
|
-
});
|
|
14120
|
-
});
|
|
14121
14007
|
return categories;
|
|
14122
14008
|
} catch (error) {
|
|
14123
14009
|
if (error instanceof BadRequestError68) {
|
|
@@ -14133,12 +14019,6 @@ function useVehicleRepo() {
|
|
|
14133
14019
|
throw new BadRequestError68("Invalid vehicle ID format.");
|
|
14134
14020
|
}
|
|
14135
14021
|
try {
|
|
14136
|
-
const cacheKey = makeCacheKey23(vehicles_namespace_collection, { _id });
|
|
14137
|
-
const cachedData = await getCache(cacheKey);
|
|
14138
|
-
if (cachedData) {
|
|
14139
|
-
logger49.info(`Cache hit for key: ${cacheKey}`);
|
|
14140
|
-
return cachedData;
|
|
14141
|
-
}
|
|
14142
14022
|
const data = await collection.aggregate([
|
|
14143
14023
|
{ $match: { _id } },
|
|
14144
14024
|
{ $limit: 1 },
|
|
@@ -14308,11 +14188,6 @@ function useVehicleRepo() {
|
|
|
14308
14188
|
throw new NotFoundError17("Vehicle not found.");
|
|
14309
14189
|
}
|
|
14310
14190
|
const result = data[0];
|
|
14311
|
-
setCache(cacheKey, result, 15 * 60).then(() => {
|
|
14312
|
-
logger49.info(`Cache set for key: ${cacheKey}`);
|
|
14313
|
-
}).catch((err) => {
|
|
14314
|
-
logger49.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
14315
|
-
});
|
|
14316
14191
|
return result;
|
|
14317
14192
|
} catch (error) {
|
|
14318
14193
|
throw error;
|
|
@@ -14324,15 +14199,6 @@ function useVehicleRepo() {
|
|
|
14324
14199
|
throw new BadRequestError68(error.details[0].message);
|
|
14325
14200
|
}
|
|
14326
14201
|
try {
|
|
14327
|
-
const cacheKey = makeCacheKey23(vehicles_namespace_collection, {
|
|
14328
|
-
plateNumber: value,
|
|
14329
|
-
status: "active"
|
|
14330
|
-
});
|
|
14331
|
-
const cachedData = await getCache(cacheKey);
|
|
14332
|
-
if (cachedData) {
|
|
14333
|
-
logger49.info(`Cache hit for key: ${cacheKey}`);
|
|
14334
|
-
return cachedData;
|
|
14335
|
-
}
|
|
14336
14202
|
const data = await collection.findOne({
|
|
14337
14203
|
plateNumber: value,
|
|
14338
14204
|
status: "active"
|
|
@@ -14340,11 +14206,6 @@ function useVehicleRepo() {
|
|
|
14340
14206
|
if (!data) {
|
|
14341
14207
|
throw new NotFoundError17("Vehicle not found.");
|
|
14342
14208
|
}
|
|
14343
|
-
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
14344
|
-
logger49.info(`Cache set for key: ${cacheKey}`);
|
|
14345
|
-
}).catch((err) => {
|
|
14346
|
-
logger49.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
14347
|
-
});
|
|
14348
14209
|
return data;
|
|
14349
14210
|
} catch (error2) {
|
|
14350
14211
|
throw error2;
|
|
@@ -14369,16 +14230,6 @@ function useVehicleRepo() {
|
|
|
14369
14230
|
if (res.modifiedCount === 0) {
|
|
14370
14231
|
throw new InternalServerError24("Unable to update vehicle.");
|
|
14371
14232
|
}
|
|
14372
|
-
delNamespace().then(() => {
|
|
14373
|
-
logger49.info(
|
|
14374
|
-
`Cache cleared for namespace: ${vehicles_namespace_collection}`
|
|
14375
|
-
);
|
|
14376
|
-
}).catch((err) => {
|
|
14377
|
-
logger49.error(
|
|
14378
|
-
`Failed to clear cache for namespace: ${vehicles_namespace_collection}`,
|
|
14379
|
-
err
|
|
14380
|
-
);
|
|
14381
|
-
});
|
|
14382
14233
|
return res.modifiedCount;
|
|
14383
14234
|
} catch (error) {
|
|
14384
14235
|
throw error;
|
|
@@ -14402,16 +14253,6 @@ function useVehicleRepo() {
|
|
|
14402
14253
|
);
|
|
14403
14254
|
if (res.modifiedCount === 0)
|
|
14404
14255
|
throw new InternalServerError24("Unable to delete vehicle.");
|
|
14405
|
-
delNamespace().then(() => {
|
|
14406
|
-
logger49.info(
|
|
14407
|
-
`Cache cleared for namespace: ${vehicles_namespace_collection}`
|
|
14408
|
-
);
|
|
14409
|
-
}).catch((err) => {
|
|
14410
|
-
logger49.error(
|
|
14411
|
-
`Failed to clear cache for namespace: ${vehicles_namespace_collection}`,
|
|
14412
|
-
err
|
|
14413
|
-
);
|
|
14414
|
-
});
|
|
14415
14256
|
return res.modifiedCount;
|
|
14416
14257
|
} catch (error) {
|
|
14417
14258
|
throw error;
|
|
@@ -14422,25 +14263,11 @@ function useVehicleRepo() {
|
|
|
14422
14263
|
if (error) {
|
|
14423
14264
|
throw new BadRequestError68(error.details[0].message);
|
|
14424
14265
|
}
|
|
14425
|
-
const cacheKey = makeCacheKey23(vehicles_namespace_collection, {
|
|
14426
|
-
plateNumber,
|
|
14427
|
-
status: "active"
|
|
14428
|
-
});
|
|
14429
14266
|
try {
|
|
14430
|
-
const cacheData = await getCache(cacheKey);
|
|
14431
|
-
if (cacheData) {
|
|
14432
|
-
logger49.info(`Cache hit for key: ${cacheKey}`);
|
|
14433
|
-
return cacheData;
|
|
14434
|
-
}
|
|
14435
14267
|
const data = await collection.findOne(
|
|
14436
14268
|
{ plateNumber, status: "active" },
|
|
14437
14269
|
{ sort: { _id: -1 } }
|
|
14438
14270
|
);
|
|
14439
|
-
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
14440
|
-
logger49.info(`Cache set for key: ${cacheKey}`);
|
|
14441
|
-
}).catch((err) => {
|
|
14442
|
-
logger49.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
14443
|
-
});
|
|
14444
14271
|
return data;
|
|
14445
14272
|
} catch (error2) {
|
|
14446
14273
|
throw new InternalServerError24(
|
|
@@ -14464,19 +14291,6 @@ function useVehicleRepo() {
|
|
|
14464
14291
|
nric: _nric
|
|
14465
14292
|
};
|
|
14466
14293
|
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
14467
|
-
const cacheOptions = {
|
|
14468
|
-
deletedAt: "",
|
|
14469
|
-
nric: _nric,
|
|
14470
|
-
page: String(page),
|
|
14471
|
-
limit: String(limit),
|
|
14472
|
-
sort: JSON.stringify(sort)
|
|
14473
|
-
};
|
|
14474
|
-
const cacheKey = makeCacheKey23(vehicles_namespace_collection, cacheOptions);
|
|
14475
|
-
const cachedData = await getCache(cacheKey);
|
|
14476
|
-
if (cachedData) {
|
|
14477
|
-
logger49.info(`Cache hit for key: ${cacheKey}`);
|
|
14478
|
-
return cachedData;
|
|
14479
|
-
}
|
|
14480
14294
|
try {
|
|
14481
14295
|
const items = await collection.aggregate([
|
|
14482
14296
|
{ $match: query },
|
|
@@ -14497,9 +14311,6 @@ function useVehicleRepo() {
|
|
|
14497
14311
|
]).toArray();
|
|
14498
14312
|
const length = await collection.countDocuments(query);
|
|
14499
14313
|
const data = paginate18(items, page, limit, length);
|
|
14500
|
-
setCache(cacheKey, data, 15 * 60).then(() => logger49.info(`Cache set for key: ${cacheKey}`)).catch(
|
|
14501
|
-
(err) => logger49.error(`Failed to set cache for key: ${cacheKey}`, err)
|
|
14502
|
-
);
|
|
14503
14314
|
return data;
|
|
14504
14315
|
} catch (error) {
|
|
14505
14316
|
throw error;
|
|
@@ -14514,19 +14325,9 @@ function useVehicleRepo() {
|
|
|
14514
14325
|
end: { $exists: true, $lte: now }
|
|
14515
14326
|
// check only end
|
|
14516
14327
|
},
|
|
14517
|
-
{ $set: { status: "deleted", deletedAt: now } },
|
|
14328
|
+
{ $set: { status: "deleted", deletedAt: now, isDeletedInDahua: true } },
|
|
14518
14329
|
{ session }
|
|
14519
14330
|
);
|
|
14520
|
-
delNamespace().then(() => {
|
|
14521
|
-
logger49.info(
|
|
14522
|
-
`Cache cleared for namespace: ${vehicles_namespace_collection}`
|
|
14523
|
-
);
|
|
14524
|
-
}).catch((err) => {
|
|
14525
|
-
logger49.error(
|
|
14526
|
-
`Failed to clear cache for namespace: ${vehicles_namespace_collection}`,
|
|
14527
|
-
err
|
|
14528
|
-
);
|
|
14529
|
-
});
|
|
14530
14331
|
return res.modifiedCount;
|
|
14531
14332
|
} catch (error) {
|
|
14532
14333
|
throw error;
|
|
@@ -14545,21 +14346,6 @@ function useVehicleRepo() {
|
|
|
14545
14346
|
const query = {
|
|
14546
14347
|
unit
|
|
14547
14348
|
};
|
|
14548
|
-
const cacheOptions = {
|
|
14549
|
-
unit: unitId,
|
|
14550
|
-
page,
|
|
14551
|
-
limit,
|
|
14552
|
-
sort: JSON.stringify(sort)
|
|
14553
|
-
};
|
|
14554
|
-
const cacheKey = makeCacheKey23(
|
|
14555
|
-
vehicles_namespace_collection,
|
|
14556
|
-
cacheOptions
|
|
14557
|
-
);
|
|
14558
|
-
const cachedData = await getCache(cacheKey);
|
|
14559
|
-
if (cachedData) {
|
|
14560
|
-
logger49.info(`Cache hit for key: ${cacheKey}`);
|
|
14561
|
-
return cachedData;
|
|
14562
|
-
}
|
|
14563
14349
|
const items = await collection.find(query, {
|
|
14564
14350
|
projection: {
|
|
14565
14351
|
createdAt: 0,
|
|
@@ -14572,14 +14358,24 @@ function useVehicleRepo() {
|
|
|
14572
14358
|
}).toArray();
|
|
14573
14359
|
const length = await collection.countDocuments(query);
|
|
14574
14360
|
const data = paginate18(items, page, limit, length);
|
|
14575
|
-
setCache(cacheKey, data, 15 * 60).then(() => logger49.info(`Cache set for key: ${cacheKey}`)).catch(
|
|
14576
|
-
(err) => logger49.error(`Failed to set cache for key: ${cacheKey}`, err)
|
|
14577
|
-
);
|
|
14578
14361
|
return data;
|
|
14579
14362
|
} catch (error) {
|
|
14580
14363
|
throw error;
|
|
14581
14364
|
}
|
|
14582
14365
|
}
|
|
14366
|
+
async function getAllExpiredVehicles() {
|
|
14367
|
+
try {
|
|
14368
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
14369
|
+
const query = {
|
|
14370
|
+
end: { $lte: now },
|
|
14371
|
+
status: { $ne: "deleted" }
|
|
14372
|
+
};
|
|
14373
|
+
const items = await collection.find(query).toArray();
|
|
14374
|
+
return items;
|
|
14375
|
+
} catch (error) {
|
|
14376
|
+
throw error;
|
|
14377
|
+
}
|
|
14378
|
+
}
|
|
14583
14379
|
return {
|
|
14584
14380
|
createIndex,
|
|
14585
14381
|
createTextIndex,
|
|
@@ -14593,7 +14389,8 @@ function useVehicleRepo() {
|
|
|
14593
14389
|
getVehicleByPlateNumber,
|
|
14594
14390
|
getVehiclesByNRIC,
|
|
14595
14391
|
deleteExpiredVehicles,
|
|
14596
|
-
getAllVehiclesByUnitId
|
|
14392
|
+
getAllVehiclesByUnitId,
|
|
14393
|
+
getAllExpiredVehicles
|
|
14597
14394
|
};
|
|
14598
14395
|
}
|
|
14599
14396
|
|
|
@@ -15220,18 +15017,32 @@ function formatDahuaDate(date) {
|
|
|
15220
15017
|
date.getSeconds()
|
|
15221
15018
|
)}`;
|
|
15222
15019
|
}
|
|
15020
|
+
function parseDahuaFind(text) {
|
|
15021
|
+
const found = Number(text.match(/found=(\d+)/)?.[1] || 0);
|
|
15022
|
+
if (!found) {
|
|
15023
|
+
return { exists: false };
|
|
15024
|
+
}
|
|
15025
|
+
return {
|
|
15026
|
+
exists: true,
|
|
15027
|
+
recNo: text.match(/records\[0\]\.RecNo=(.*)/)?.[1]?.trim(),
|
|
15028
|
+
plateNumber: text.match(/records\[0\]\.PlateNumber=(.*)/)?.[1]?.trim()
|
|
15029
|
+
};
|
|
15030
|
+
}
|
|
15223
15031
|
function useVehicleService() {
|
|
15224
15032
|
const {
|
|
15225
15033
|
add: _add,
|
|
15226
15034
|
deleteVehicle: _deleteVehicle,
|
|
15227
15035
|
updateVehicleById: _updateVehicleById,
|
|
15228
15036
|
getVehicleById: _getVehicleById,
|
|
15229
|
-
deleteExpiredVehicles: _deleteExpiredVehicles
|
|
15037
|
+
deleteExpiredVehicles: _deleteExpiredVehicles,
|
|
15038
|
+
getVehicleByPlateNumber: _getVehicleByPlateNumber,
|
|
15039
|
+
getAllExpiredVehicles: _getAllExpiredVehicles
|
|
15230
15040
|
} = useVehicleRepo();
|
|
15231
15041
|
const {
|
|
15232
15042
|
addPlateNumber: _addPlateNumber,
|
|
15233
15043
|
removePlateNumber: _removePlateNumber,
|
|
15234
|
-
updatePlateNumber: _updatePlateNumber
|
|
15044
|
+
updatePlateNumber: _updatePlateNumber,
|
|
15045
|
+
getPlateNumber: _getPlateNumber
|
|
15235
15046
|
} = useDahuaService();
|
|
15236
15047
|
const { getAllCameraWithPassword: _getAllSiteCameras } = useSiteCameraRepo();
|
|
15237
15048
|
const { getById: _getById } = useOrgRepo();
|
|
@@ -15242,9 +15053,15 @@ function useVehicleService() {
|
|
|
15242
15053
|
if (!session) {
|
|
15243
15054
|
throw new Error("Unable to start session for vehicle service.");
|
|
15244
15055
|
}
|
|
15245
|
-
const
|
|
15056
|
+
const [_vehiclePlateNumber] = value.plateNumber;
|
|
15057
|
+
const [existingPlateNumber, org] = await Promise.all([
|
|
15058
|
+
_getVehicleByPlateNumber(_vehiclePlateNumber),
|
|
15059
|
+
_getById(value.org)
|
|
15060
|
+
]);
|
|
15246
15061
|
if (!org)
|
|
15247
15062
|
throw new BadRequestError70("Org not found");
|
|
15063
|
+
if (existingPlateNumber)
|
|
15064
|
+
throw new BadRequestError70("Vehicle plate number already exists");
|
|
15248
15065
|
if (!Object.values(OrgNature).includes(org.nature)) {
|
|
15249
15066
|
throw new BadRequestError70(
|
|
15250
15067
|
"This organization is not allowed to add vehicles."
|
|
@@ -15324,29 +15141,61 @@ function useVehicleService() {
|
|
|
15324
15141
|
if (vehicleValue.status && vehicleValue.status !== "pending" /* PENDING */) {
|
|
15325
15142
|
for (const camera of siteCameras) {
|
|
15326
15143
|
const { host, username, password } = camera;
|
|
15327
|
-
const
|
|
15144
|
+
const plateNumber2 = vehicleValue.plateNumber;
|
|
15145
|
+
const dahuaQuery = {
|
|
15328
15146
|
host,
|
|
15329
15147
|
username,
|
|
15330
15148
|
password,
|
|
15331
|
-
plateNumber,
|
|
15332
|
-
mode: _mode
|
|
15333
|
-
owner,
|
|
15334
|
-
...startDateDahua ? { start: startDateDahua } : {},
|
|
15335
|
-
...endDateDahua ? { end: endDateDahua } : {}
|
|
15149
|
+
plateNumber: plateNumber2,
|
|
15150
|
+
mode: _mode
|
|
15336
15151
|
};
|
|
15337
|
-
const
|
|
15338
|
-
|
|
15339
|
-
|
|
15340
|
-
|
|
15341
|
-
|
|
15152
|
+
const raw = await _getPlateNumber(dahuaQuery);
|
|
15153
|
+
const parsed = parseDahuaFind(raw);
|
|
15154
|
+
if (!parsed.exists) {
|
|
15155
|
+
const dahuaPayload = {
|
|
15156
|
+
host,
|
|
15157
|
+
username,
|
|
15158
|
+
password,
|
|
15159
|
+
plateNumber: plateNumber2,
|
|
15160
|
+
mode: _mode,
|
|
15161
|
+
owner,
|
|
15162
|
+
...startDateDahua ? { start: startDateDahua } : {},
|
|
15163
|
+
...endDateDahua ? { end: endDateDahua } : {}
|
|
15164
|
+
};
|
|
15165
|
+
const dahuaResponse = await _addPlateNumber(dahuaPayload);
|
|
15166
|
+
if (dahuaResponse?.statusCode !== 200) {
|
|
15167
|
+
throw new BadRequestError70(
|
|
15168
|
+
`Failed to add plate number to ANPR ${_type}`
|
|
15169
|
+
);
|
|
15170
|
+
}
|
|
15171
|
+
const responseData = dahuaResponse?.data?.toString("utf-8") ?? "";
|
|
15172
|
+
vehicleValue.recNo = responseData.split("=")[1]?.trim();
|
|
15173
|
+
} else {
|
|
15174
|
+
const dahuaPayload = {
|
|
15175
|
+
host,
|
|
15176
|
+
username,
|
|
15177
|
+
password,
|
|
15178
|
+
plateNumber: plateNumber2,
|
|
15179
|
+
recno: parsed.recNo,
|
|
15180
|
+
mode: _mode,
|
|
15181
|
+
...startDateDahua ? { start: startDateDahua } : {},
|
|
15182
|
+
...endDateDahua ? { end: endDateDahua } : {},
|
|
15183
|
+
owner,
|
|
15184
|
+
isOpenGate: true
|
|
15185
|
+
};
|
|
15186
|
+
const dahuaResponse = await _updatePlateNumber(dahuaPayload);
|
|
15187
|
+
if (dahuaResponse?.statusCode !== 200) {
|
|
15188
|
+
throw new BadRequestError70(
|
|
15189
|
+
`Failed to update plate number to ANPR ${_type}`
|
|
15190
|
+
);
|
|
15191
|
+
}
|
|
15192
|
+
vehicleValue.recNo = parsed.recNo;
|
|
15342
15193
|
}
|
|
15343
|
-
const responseData = dahuaResponse?.data?.toString("utf-8") ?? "";
|
|
15344
|
-
vehicleValue.recNo = responseData.split("=")[1]?.trim();
|
|
15345
15194
|
if (value.peopleId && vehicleValue.recNo) {
|
|
15346
15195
|
await _pushVehicleById(
|
|
15347
15196
|
value.peopleId,
|
|
15348
15197
|
{
|
|
15349
|
-
plateNumber,
|
|
15198
|
+
plateNumber: plateNumber2,
|
|
15350
15199
|
recNo: vehicleValue.recNo
|
|
15351
15200
|
},
|
|
15352
15201
|
session
|
|
@@ -15537,6 +15386,43 @@ function useVehicleService() {
|
|
|
15537
15386
|
}
|
|
15538
15387
|
try {
|
|
15539
15388
|
session.startTransaction();
|
|
15389
|
+
const vehicles = await _getAllExpiredVehicles();
|
|
15390
|
+
let siteCameras = [];
|
|
15391
|
+
for (const vehicle of vehicles) {
|
|
15392
|
+
const site = vehicle.site;
|
|
15393
|
+
const recno = vehicle.recNo;
|
|
15394
|
+
let page = 1;
|
|
15395
|
+
let pages = 1;
|
|
15396
|
+
const limit = 20;
|
|
15397
|
+
do {
|
|
15398
|
+
const siteCameraReq = await _getAllSiteCameras({
|
|
15399
|
+
site,
|
|
15400
|
+
type: "anpr",
|
|
15401
|
+
direction: ["both", "entry"],
|
|
15402
|
+
page,
|
|
15403
|
+
limit
|
|
15404
|
+
});
|
|
15405
|
+
pages = siteCameraReq.pages || 1;
|
|
15406
|
+
siteCameras.push(...siteCameraReq.items);
|
|
15407
|
+
page++;
|
|
15408
|
+
} while (page < pages);
|
|
15409
|
+
if (!siteCameras.length) {
|
|
15410
|
+
throw new BadRequestError70("No site cameras found.");
|
|
15411
|
+
}
|
|
15412
|
+
for (const camera of siteCameras) {
|
|
15413
|
+
const host = camera.host;
|
|
15414
|
+
const username = camera.username;
|
|
15415
|
+
const password = camera.password;
|
|
15416
|
+
const dahuaPayload = {
|
|
15417
|
+
host,
|
|
15418
|
+
username,
|
|
15419
|
+
password,
|
|
15420
|
+
recno,
|
|
15421
|
+
mode: "TrafficRedList" /* TRAFFIC_REDLIST */
|
|
15422
|
+
};
|
|
15423
|
+
await _removePlateNumber(dahuaPayload);
|
|
15424
|
+
}
|
|
15425
|
+
}
|
|
15540
15426
|
await _deleteExpiredVehicles();
|
|
15541
15427
|
await session.commitTransaction();
|
|
15542
15428
|
return `Expired Vehicle plate numbers deleted successfully.`;
|
|
@@ -15932,16 +15818,20 @@ function useDahuaService() {
|
|
|
15932
15818
|
"resident" /* RESIDENT */,
|
|
15933
15819
|
"tenant" /* TENANT */
|
|
15934
15820
|
];
|
|
15821
|
+
let startDate = vehicle?.start ? new Date(vehicle?.start) : /* @__PURE__ */ new Date();
|
|
15822
|
+
let endDate = vehicle?.end ? new Date(vehicle?.end) : new Date(startDate.getTime() + 60 * 60 * 1e3);
|
|
15935
15823
|
if (vehicle && typeof vehicle.category === "string" && typesForAutoRegister.includes(vehicle.category)) {
|
|
15936
15824
|
visitorTransaction.name = vehicle.name;
|
|
15937
15825
|
visitorTransaction.nric = vehicle.nric;
|
|
15938
15826
|
visitorTransaction.contact = vehicle.phoneNumber;
|
|
15939
15827
|
visitorTransaction.block = Number(vehicle.block);
|
|
15940
15828
|
visitorTransaction.level = vehicle.level;
|
|
15941
|
-
visitorTransaction.unit = vehicle.unit;
|
|
15829
|
+
visitorTransaction.unit = vehicle.unit?.toString();
|
|
15942
15830
|
visitorTransaction.unitName = vehicle.unitName;
|
|
15943
|
-
visitorTransaction.type =
|
|
15831
|
+
visitorTransaction.type = "resident" /* RESIDENT */;
|
|
15944
15832
|
visitorTransaction.status = "registered" /* REGISTERED */;
|
|
15833
|
+
visitorTransaction.recNo = vehicle.recNo;
|
|
15834
|
+
visitorTransaction.expiredAt = vehicle.end;
|
|
15945
15835
|
}
|
|
15946
15836
|
const dahuaPayload = {
|
|
15947
15837
|
host,
|
|
@@ -15951,13 +15841,15 @@ function useDahuaService() {
|
|
|
15951
15841
|
mode: "TrafficRedList" /* TRAFFIC_REDLIST */,
|
|
15952
15842
|
owner: vehicle?.name ?? ""
|
|
15953
15843
|
};
|
|
15844
|
+
dahuaPayload.start = formatDahuaDate(startDate);
|
|
15845
|
+
dahuaPayload.end = formatDahuaDate(endDate);
|
|
15954
15846
|
const shouldHaveTimeLimit = visitorTransaction.type === "guest" /* GUEST */ || visitorTransaction.status === "unregistered" /* UNREGISTERED */;
|
|
15955
15847
|
if (shouldHaveTimeLimit) {
|
|
15956
|
-
const
|
|
15957
|
-
const
|
|
15958
|
-
dahuaPayload.start = formatDahuaDate(
|
|
15959
|
-
dahuaPayload.end = formatDahuaDate(
|
|
15960
|
-
visitorTransaction.expiredAt =
|
|
15848
|
+
const startDate2 = /* @__PURE__ */ new Date();
|
|
15849
|
+
const endDate2 = new Date(startDate2.getTime() + 60 * 60 * 1e3);
|
|
15850
|
+
dahuaPayload.start = formatDahuaDate(startDate2);
|
|
15851
|
+
dahuaPayload.end = formatDahuaDate(endDate2);
|
|
15852
|
+
visitorTransaction.expiredAt = endDate2.toISOString();
|
|
15961
15853
|
}
|
|
15962
15854
|
try {
|
|
15963
15855
|
await addPlateNumber(dahuaPayload);
|
|
@@ -16206,14 +16098,14 @@ function useDahuaService() {
|
|
|
16206
16098
|
start: Joi39.string().isoDate().optional().allow("", null),
|
|
16207
16099
|
end: Joi39.string().isoDate().optional().allow("", null),
|
|
16208
16100
|
owner: Joi39.string().optional().allow("", null),
|
|
16209
|
-
|
|
16101
|
+
isOpenGate: Joi39.boolean().optional().allow(null)
|
|
16210
16102
|
});
|
|
16211
16103
|
const { error } = validation.validate(value);
|
|
16212
16104
|
if (error) {
|
|
16213
16105
|
throw new BadRequestError71(`Validation error: ${error.message}`);
|
|
16214
16106
|
}
|
|
16215
16107
|
value.owner = String(value.owner ?? "").substring(0, 15) || "unknown";
|
|
16216
|
-
const _openGate = String(value.
|
|
16108
|
+
const _openGate = String(value.isOpenGate);
|
|
16217
16109
|
const isOpenGateString = _openGate && _openGate !== "undefined" ? _openGate : "true";
|
|
16218
16110
|
const endpoint = `/cgi-bin/recordUpdater.cgi?action=insert&name=${value.mode}&PlateNumber=${value.plateNumber}&BeginTime=${value.start}&CancelTime=${value.end}&+OpenGate=${isOpenGateString}&MasterOfCar=${value.owner}`;
|
|
16219
16111
|
try {
|
|
@@ -16274,7 +16166,7 @@ function useDahuaService() {
|
|
|
16274
16166
|
username: Joi39.string().required(),
|
|
16275
16167
|
password: Joi39.string().required(),
|
|
16276
16168
|
recno: Joi39.string().required(),
|
|
16277
|
-
mode: Joi39.string().valid(
|
|
16169
|
+
mode: Joi39.string().valid(...Object.values(ANPRMode)).required()
|
|
16278
16170
|
});
|
|
16279
16171
|
const { error } = validation.validate(value);
|
|
16280
16172
|
if (error) {
|
|
@@ -16292,12 +16184,39 @@ function useDahuaService() {
|
|
|
16292
16184
|
logger52.error(`[${value.host}] Error removing plate number:`, error2);
|
|
16293
16185
|
}
|
|
16294
16186
|
}
|
|
16187
|
+
async function getPlateNumber(value) {
|
|
16188
|
+
const validation = Joi39.object({
|
|
16189
|
+
host: Joi39.string().required(),
|
|
16190
|
+
username: Joi39.string().required(),
|
|
16191
|
+
password: Joi39.string().required(),
|
|
16192
|
+
plateNumber: Joi39.string().required(),
|
|
16193
|
+
mode: Joi39.string().valid(...Object.values(ANPRMode)).required()
|
|
16194
|
+
});
|
|
16195
|
+
const { error } = validation.validate(value);
|
|
16196
|
+
if (error) {
|
|
16197
|
+
throw new BadRequestError71(`Validation error: ${error.message}`);
|
|
16198
|
+
}
|
|
16199
|
+
try {
|
|
16200
|
+
const response = await useDahuaDigest({
|
|
16201
|
+
host: value.host,
|
|
16202
|
+
username: value.username,
|
|
16203
|
+
password: value.password,
|
|
16204
|
+
endpoint: `/cgi-bin/recordFinder.cgi?action=find&name=${value.mode}&condition.PlateNumber=${encodeURIComponent(value.plateNumber)}`
|
|
16205
|
+
});
|
|
16206
|
+
const text = response?.data?.toString?.("utf-8");
|
|
16207
|
+
return text;
|
|
16208
|
+
} catch (error2) {
|
|
16209
|
+
logger52.error(`[${value.host}] Error finding plate number:`, error2);
|
|
16210
|
+
throw error2;
|
|
16211
|
+
}
|
|
16212
|
+
}
|
|
16295
16213
|
return {
|
|
16296
16214
|
getSnapshot,
|
|
16297
16215
|
getTrafficJunction,
|
|
16298
16216
|
addPlateNumber,
|
|
16299
16217
|
removePlateNumber,
|
|
16300
|
-
updatePlateNumber
|
|
16218
|
+
updatePlateNumber,
|
|
16219
|
+
getPlateNumber
|
|
16301
16220
|
};
|
|
16302
16221
|
}
|
|
16303
16222
|
|
|
@@ -20630,10 +20549,13 @@ function useVisitorTransactionService() {
|
|
|
20630
20549
|
const { getSiteById: _getSiteById } = useSiteRepo();
|
|
20631
20550
|
const {
|
|
20632
20551
|
addPlateNumber: _addPlateNumber,
|
|
20633
|
-
removePlateNumber: _removePlateNumber
|
|
20552
|
+
removePlateNumber: _removePlateNumber,
|
|
20553
|
+
getPlateNumber: _getPlateNumber,
|
|
20554
|
+
updatePlateNumber: _updatePlateNumber
|
|
20634
20555
|
} = useDahuaService();
|
|
20635
20556
|
const { getAllSites: _getAllSites } = useSiteRepo();
|
|
20636
20557
|
const { getByUserId: _getByUserId } = usePersonRepo();
|
|
20558
|
+
const { add: addVehicle } = useVehicleRepo();
|
|
20637
20559
|
async function add(value) {
|
|
20638
20560
|
const session = useAtlas47.getClient()?.startSession();
|
|
20639
20561
|
const allowedPersonTypes = [
|
|
@@ -20650,12 +20572,12 @@ function useVisitorTransactionService() {
|
|
|
20650
20572
|
let site;
|
|
20651
20573
|
if (value.site) {
|
|
20652
20574
|
[camera, site] = await Promise.all([
|
|
20653
|
-
_getBySite(value.site, { type: "anpr" }),
|
|
20575
|
+
_getBySite(value.site, { type: "anpr" /* ANPR */ }),
|
|
20654
20576
|
_getSiteById(value.site)
|
|
20655
20577
|
]);
|
|
20656
20578
|
}
|
|
20657
|
-
const
|
|
20658
|
-
const end = value.checkOut ? new Date(value.checkOut) : new Date(start.getTime() +
|
|
20579
|
+
const hourExpiration = site?.dahuaTimeExpiration ? site?.dahuaTimeExpiration : 24 * 60;
|
|
20580
|
+
const end = value.checkOut ? new Date(value.checkOut) : new Date(start.getTime() + hourExpiration * 60 * 1e3);
|
|
20659
20581
|
const startString = start.toISOString();
|
|
20660
20582
|
const endString = end.toISOString();
|
|
20661
20583
|
const startDahuaDate = formatDahuaDate(start);
|
|
@@ -20731,27 +20653,76 @@ function useVisitorTransactionService() {
|
|
|
20731
20653
|
}
|
|
20732
20654
|
}
|
|
20733
20655
|
if (camera && value.plateNumber && camera.host && camera.username && camera.password) {
|
|
20734
|
-
const
|
|
20735
|
-
|
|
20736
|
-
|
|
20737
|
-
|
|
20738
|
-
|
|
20739
|
-
|
|
20740
|
-
|
|
20741
|
-
|
|
20742
|
-
|
|
20743
|
-
|
|
20656
|
+
const host = camera.host;
|
|
20657
|
+
const username = camera.username;
|
|
20658
|
+
const password = camera.password;
|
|
20659
|
+
const mode = "TrafficRedList" /* TRAFFIC_REDLIST */;
|
|
20660
|
+
const _plateNumber = value.plateNumber;
|
|
20661
|
+
const dahuaQuery = {
|
|
20662
|
+
host,
|
|
20663
|
+
username,
|
|
20664
|
+
password,
|
|
20665
|
+
plateNumber: _plateNumber,
|
|
20666
|
+
mode
|
|
20744
20667
|
};
|
|
20745
|
-
const
|
|
20746
|
-
|
|
20747
|
-
|
|
20748
|
-
|
|
20749
|
-
|
|
20668
|
+
const raw = await _getPlateNumber(dahuaQuery);
|
|
20669
|
+
const parsed = parseDahuaFind(raw);
|
|
20670
|
+
if (!parsed.exists) {
|
|
20671
|
+
const dahuaPayload = {
|
|
20672
|
+
host,
|
|
20673
|
+
username,
|
|
20674
|
+
password,
|
|
20675
|
+
plateNumber: _plateNumber,
|
|
20676
|
+
mode,
|
|
20677
|
+
start: startDahuaDate,
|
|
20678
|
+
end: endDahuaDate,
|
|
20679
|
+
owner: value.name ?? "",
|
|
20680
|
+
isOpenGate: site?.isOpenGate ?? true
|
|
20681
|
+
};
|
|
20682
|
+
const dahuaResponse = await _addPlateNumber(dahuaPayload);
|
|
20683
|
+
if (dahuaResponse?.statusCode !== 200) {
|
|
20684
|
+
throw new BadRequestError96(
|
|
20685
|
+
`Failed to add plate number to ANPR whitelist`
|
|
20686
|
+
);
|
|
20687
|
+
}
|
|
20688
|
+
const responseData = dahuaResponse?.data?.toString("utf-8") ?? "";
|
|
20689
|
+
value.recNo = responseData.split("=")[1]?.trim();
|
|
20690
|
+
value.checkIn = startString;
|
|
20691
|
+
value.expiredAt = endString;
|
|
20692
|
+
const vehiclePayload = {
|
|
20693
|
+
name: value.name ?? "",
|
|
20694
|
+
category: value.type,
|
|
20695
|
+
org: value.org,
|
|
20696
|
+
site: value.site,
|
|
20697
|
+
plateNumber: value.plateNumber,
|
|
20698
|
+
type: "whitelist" /* WHITELIST */,
|
|
20699
|
+
nric: value.nric,
|
|
20700
|
+
start: startString,
|
|
20701
|
+
end: endString,
|
|
20702
|
+
recNo: value.recNo
|
|
20703
|
+
};
|
|
20704
|
+
await addVehicle(vehiclePayload);
|
|
20705
|
+
} else {
|
|
20706
|
+
const dahuaPayload = {
|
|
20707
|
+
host,
|
|
20708
|
+
username,
|
|
20709
|
+
password,
|
|
20710
|
+
plateNumber: _plateNumber,
|
|
20711
|
+
recno: parsed.recNo,
|
|
20712
|
+
mode,
|
|
20713
|
+
start: startDahuaDate,
|
|
20714
|
+
end: endDahuaDate,
|
|
20715
|
+
owner: value.name ?? "",
|
|
20716
|
+
isOpenGate: site?.isOpenGate ?? true
|
|
20717
|
+
};
|
|
20718
|
+
const dahuaResponse = await _updatePlateNumber(dahuaPayload);
|
|
20719
|
+
if (dahuaResponse?.statusCode !== 200) {
|
|
20720
|
+
throw new BadRequestError96(
|
|
20721
|
+
`Failed to update plate number to ANPR ${"whitelist" /* WHITELIST */}`
|
|
20722
|
+
);
|
|
20723
|
+
}
|
|
20724
|
+
value.recNo = parsed.recNo;
|
|
20750
20725
|
}
|
|
20751
|
-
const responseData = dahuaResponse?.data?.toString("utf-8") ?? "";
|
|
20752
|
-
value.recNo = responseData.split("=")[1]?.trim();
|
|
20753
|
-
value.checkIn = startString;
|
|
20754
|
-
value.expiredAt = endString;
|
|
20755
20726
|
}
|
|
20756
20727
|
const result = await _add(value, session);
|
|
20757
20728
|
await session?.commitTransaction();
|
|
@@ -21085,7 +21056,6 @@ function useVisitorTransactionController() {
|
|
|
21085
21056
|
}
|
|
21086
21057
|
}
|
|
21087
21058
|
async function inviteVisitor(req, res, next) {
|
|
21088
|
-
const inviter = req.params.inviterId;
|
|
21089
21059
|
const schema2 = Joi55.object({
|
|
21090
21060
|
name: Joi55.string().required(),
|
|
21091
21061
|
contact: Joi55.string().required(),
|
|
@@ -34118,7 +34088,7 @@ function useOccurrenceBookRepo() {
|
|
|
34118
34088
|
date = "",
|
|
34119
34089
|
status = ""
|
|
34120
34090
|
}, session) {
|
|
34121
|
-
page = page > 0 ? page - 1 : 0;
|
|
34091
|
+
page = page > 0 && !date ? page - 1 : 0;
|
|
34122
34092
|
const _site = toObjectId12(site);
|
|
34123
34093
|
const query = {
|
|
34124
34094
|
site: _site,
|
|
@@ -37599,12 +37569,15 @@ function useIncidentReportRepo() {
|
|
|
37599
37569
|
}
|
|
37600
37570
|
if (dateFrom) {
|
|
37601
37571
|
const [year, month, day] = dateFrom.split("-").map(Number);
|
|
37602
|
-
const
|
|
37603
|
-
const
|
|
37572
|
+
const offset = 8;
|
|
37573
|
+
const start = new Date(Date.UTC(year, month - 1, day, -offset, 0, 0, 0));
|
|
37574
|
+
const end = new Date(
|
|
37575
|
+
Date.UTC(year, month - 1, day, 23 - offset, 59, 59, 999)
|
|
37576
|
+
);
|
|
37604
37577
|
dateExpr = {
|
|
37605
37578
|
"incidentInformation.incidentTypeAndTime.dateOfIncident": {
|
|
37606
|
-
$gte: start,
|
|
37607
|
-
$lte: end
|
|
37579
|
+
$gte: start.toISOString(),
|
|
37580
|
+
$lte: end.toISOString()
|
|
37608
37581
|
}
|
|
37609
37582
|
};
|
|
37610
37583
|
}
|
|
@@ -45500,12 +45473,6 @@ function useVerificationRepoV2() {
|
|
|
45500
45473
|
err
|
|
45501
45474
|
);
|
|
45502
45475
|
});
|
|
45503
|
-
const cacheKey = makeCacheKey64(namespace_collection, { _id });
|
|
45504
|
-
delCache(cacheKey).then(() => {
|
|
45505
|
-
logger175.info(`Cache deleted for key: ${cacheKey}`);
|
|
45506
|
-
}).catch((err) => {
|
|
45507
|
-
logger175.error(`Failed to delete cache for key: ${cacheKey}`, err);
|
|
45508
|
-
});
|
|
45509
45476
|
return result;
|
|
45510
45477
|
} catch (error) {
|
|
45511
45478
|
throw new InternalServerError68("Error updating verification status.");
|
|
@@ -45921,9 +45888,12 @@ function useVerificationControllerV2() {
|
|
|
45921
45888
|
async function verify(req, res, next) {
|
|
45922
45889
|
try {
|
|
45923
45890
|
const schema2 = Joi126.object({ verificationCode: Joi126.string().required() });
|
|
45924
|
-
const { error, value } = schema2.validate(
|
|
45925
|
-
|
|
45926
|
-
|
|
45891
|
+
const { error, value } = schema2.validate(
|
|
45892
|
+
{
|
|
45893
|
+
verificationCode: req.params.verificationCode
|
|
45894
|
+
},
|
|
45895
|
+
{ abortEarly: false }
|
|
45896
|
+
);
|
|
45927
45897
|
if (error) {
|
|
45928
45898
|
const messages = error.details.map((d) => d.message).join(", ");
|
|
45929
45899
|
logger177.log({ level: "error", message: messages });
|
|
@@ -45949,7 +45919,7 @@ function useVerificationControllerV2() {
|
|
|
45949
45919
|
siteId: Joi126.string().hex().length(24).optional().allow("", null),
|
|
45950
45920
|
siteName: Joi126.string().optional().allow("", null)
|
|
45951
45921
|
});
|
|
45952
|
-
const { error, value } = schema2.validate(req.body);
|
|
45922
|
+
const { error, value } = schema2.validate(req.body, { abortEarly: false });
|
|
45953
45923
|
if (error) {
|
|
45954
45924
|
const messages = error.details.map((d) => d.message).join(", ");
|
|
45955
45925
|
logger177.log({ level: "error", message: messages });
|
|
@@ -45984,7 +45954,7 @@ function useVerificationControllerV2() {
|
|
|
45984
45954
|
siteId: Joi126.string().hex().length(24).required(),
|
|
45985
45955
|
siteName: Joi126.string().required()
|
|
45986
45956
|
});
|
|
45987
|
-
const { error, value } = schema2.validate(req.body);
|
|
45957
|
+
const { error, value } = schema2.validate(req.body, { abortEarly: false });
|
|
45988
45958
|
if (error) {
|
|
45989
45959
|
const messages = error.details.map((d) => d.message).join(", ");
|
|
45990
45960
|
logger177.log({ level: "error", message: messages });
|
|
@@ -46010,7 +45980,7 @@ function useVerificationControllerV2() {
|
|
|
46010
45980
|
const schema2 = Joi126.object({
|
|
46011
45981
|
email: Joi126.string().email().lowercase().required()
|
|
46012
45982
|
});
|
|
46013
|
-
const { error, value } = schema2.validate(req.body);
|
|
45983
|
+
const { error, value } = schema2.validate(req.body, { abortEarly: false });
|
|
46014
45984
|
if (error) {
|
|
46015
45985
|
const messages = error.details.map((d) => d.message).join(", ");
|
|
46016
45986
|
logger177.log({ level: "error", message: messages });
|
|
@@ -46040,7 +46010,7 @@ function useVerificationControllerV2() {
|
|
|
46040
46010
|
|
|
46041
46011
|
// src/controllers/auth-v2.controller.ts
|
|
46042
46012
|
import Joi127 from "joi";
|
|
46043
|
-
import { BadRequestError as
|
|
46013
|
+
import { BadRequestError as BadRequestError201, logger as logger180 } from "@7365admin1/node-server-utils";
|
|
46044
46014
|
|
|
46045
46015
|
// src/services/auth-v2.service.ts
|
|
46046
46016
|
import {
|
|
@@ -46053,11 +46023,13 @@ import {
|
|
|
46053
46023
|
import { v4 as uuidv42 } from "uuid";
|
|
46054
46024
|
|
|
46055
46025
|
// src/repositories/user-v2.repo.ts
|
|
46026
|
+
import { ObjectId as ObjectId123 } from "mongodb";
|
|
46056
46027
|
import {
|
|
46057
46028
|
useAtlas as useAtlas113,
|
|
46058
46029
|
InternalServerError as InternalServerError70,
|
|
46059
46030
|
logger as logger178,
|
|
46060
46031
|
BadRequestError as BadRequestError198,
|
|
46032
|
+
paginate as paginate58,
|
|
46061
46033
|
NotFoundError as NotFoundError52,
|
|
46062
46034
|
AppError as AppError27,
|
|
46063
46035
|
useCache as useCache67,
|
|
@@ -46074,6 +46046,7 @@ function useUserRepoV2() {
|
|
|
46074
46046
|
}
|
|
46075
46047
|
const namespace_collection = "users";
|
|
46076
46048
|
const collection = db.collection(namespace_collection);
|
|
46049
|
+
const { delNamespace, setCache, getCache, delCache } = useCache67(namespace_collection);
|
|
46077
46050
|
async function createIndex() {
|
|
46078
46051
|
try {
|
|
46079
46052
|
await collection.createIndexes([{ key: { email: 1 } }]);
|
|
@@ -46083,10 +46056,7 @@ function useUserRepoV2() {
|
|
|
46083
46056
|
}
|
|
46084
46057
|
async function createTextIndex() {
|
|
46085
46058
|
try {
|
|
46086
|
-
await collection.createIndex({
|
|
46087
|
-
name: "text",
|
|
46088
|
-
email: "text"
|
|
46089
|
-
});
|
|
46059
|
+
await collection.createIndex({ name: "text", email: "text" });
|
|
46090
46060
|
} catch (error) {
|
|
46091
46061
|
throw new InternalServerError70("Failed to create text index on user.");
|
|
46092
46062
|
}
|
|
@@ -46101,24 +46071,22 @@ function useUserRepoV2() {
|
|
|
46101
46071
|
throw new InternalServerError70("Failed to create unique index on user.");
|
|
46102
46072
|
}
|
|
46103
46073
|
}
|
|
46104
|
-
const { delNamespace, setCache, getCache, delCache } = useCache67(namespace_collection);
|
|
46105
46074
|
async function createUser(value, session) {
|
|
46106
46075
|
try {
|
|
46107
46076
|
value = MUser(value);
|
|
46108
46077
|
const res = await collection.insertOne(value, { session });
|
|
46109
|
-
delNamespace().then(
|
|
46110
|
-
logger178.info(`Cache cleared for namespace: ${namespace_collection}`)
|
|
46111
|
-
|
|
46112
|
-
logger178.error(
|
|
46078
|
+
delNamespace().then(
|
|
46079
|
+
() => logger178.info(`Cache cleared for namespace: ${namespace_collection}`)
|
|
46080
|
+
).catch(
|
|
46081
|
+
(err) => logger178.error(
|
|
46113
46082
|
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
46114
46083
|
err
|
|
46115
|
-
)
|
|
46116
|
-
|
|
46084
|
+
)
|
|
46085
|
+
);
|
|
46117
46086
|
return res.insertedId;
|
|
46118
46087
|
} catch (error) {
|
|
46119
46088
|
logger178.log({ level: "error", message: `${error}` });
|
|
46120
|
-
|
|
46121
|
-
if (isDuplicated) {
|
|
46089
|
+
if (error.message.includes("duplicate")) {
|
|
46122
46090
|
throw new BadRequestError198("User already exists.");
|
|
46123
46091
|
}
|
|
46124
46092
|
throw error;
|
|
@@ -46135,11 +46103,9 @@ function useUserRepoV2() {
|
|
|
46135
46103
|
const data = await collection.findOne({
|
|
46136
46104
|
email: { $regex: `^${email}$`, $options: "i" }
|
|
46137
46105
|
});
|
|
46138
|
-
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
46139
|
-
logger178.
|
|
46140
|
-
|
|
46141
|
-
logger178.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
46142
|
-
});
|
|
46106
|
+
setCache(cacheKey, data, 15 * 60).then(() => logger178.info(`Cache set for key: ${cacheKey}`)).catch(
|
|
46107
|
+
(err) => logger178.error(`Failed to set cache for key: ${cacheKey}`, err)
|
|
46108
|
+
);
|
|
46143
46109
|
return data;
|
|
46144
46110
|
} catch (error) {
|
|
46145
46111
|
throw new InternalServerError70("Failed to get user by email.");
|
|
@@ -46147,26 +46113,22 @@ function useUserRepoV2() {
|
|
|
46147
46113
|
}
|
|
46148
46114
|
async function getUserByEmailStatus(email) {
|
|
46149
46115
|
try {
|
|
46150
|
-
const
|
|
46116
|
+
const cacheKey = makeCacheKey65(namespace_collection, {
|
|
46151
46117
|
email,
|
|
46152
46118
|
status: "complete" /* COMPLETE */
|
|
46153
|
-
};
|
|
46154
|
-
const cacheKey = makeCacheKey65(namespace_collection, cacheOptions);
|
|
46119
|
+
});
|
|
46155
46120
|
const cachedData = await getCache(cacheKey);
|
|
46156
46121
|
if (cachedData) {
|
|
46157
46122
|
logger178.info(`Cache hit for key: ${cacheKey}`);
|
|
46158
46123
|
return cachedData;
|
|
46159
46124
|
}
|
|
46160
|
-
const
|
|
46125
|
+
const data = await collection.findOne({
|
|
46161
46126
|
email: { $regex: `^${email}$`, $options: "i" },
|
|
46162
46127
|
status: "complete" /* COMPLETE */
|
|
46163
|
-
};
|
|
46164
|
-
const data = await collection.findOne(query);
|
|
46165
|
-
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
46166
|
-
logger178.info(`Cache set for key: ${cacheKey}`);
|
|
46167
|
-
}).catch((err) => {
|
|
46168
|
-
logger178.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
46169
46128
|
});
|
|
46129
|
+
setCache(cacheKey, data, 15 * 60).then(() => logger178.info(`Cache set for key: ${cacheKey}`)).catch(
|
|
46130
|
+
(err) => logger178.error(`Failed to set cache for key: ${cacheKey}`, err)
|
|
46131
|
+
);
|
|
46170
46132
|
return data;
|
|
46171
46133
|
} catch (error) {
|
|
46172
46134
|
throw new InternalServerError70("Failed to get user by email.");
|
|
@@ -46189,17 +46151,10 @@ function useUserRepoV2() {
|
|
|
46189
46151
|
let: { userOrgId: "$defaultOrg" },
|
|
46190
46152
|
pipeline: [
|
|
46191
46153
|
{
|
|
46192
|
-
$match: {
|
|
46193
|
-
$expr: { $eq: ["$orgId", "$$userOrgId"] }
|
|
46194
|
-
}
|
|
46154
|
+
$match: { $expr: { $eq: ["$orgId", "$$userOrgId"] } }
|
|
46195
46155
|
},
|
|
46196
46156
|
{
|
|
46197
|
-
$project: {
|
|
46198
|
-
_id: 1,
|
|
46199
|
-
name: 1,
|
|
46200
|
-
type: 1,
|
|
46201
|
-
siteId: 1
|
|
46202
|
-
}
|
|
46157
|
+
$project: { _id: 1, name: 1, type: 1, siteId: 1 }
|
|
46203
46158
|
}
|
|
46204
46159
|
],
|
|
46205
46160
|
as: "serviceProviders"
|
|
@@ -46207,9 +46162,117 @@ function useUserRepoV2() {
|
|
|
46207
46162
|
}
|
|
46208
46163
|
]).toArray();
|
|
46209
46164
|
const data = results.length > 0 ? results[0] : null;
|
|
46210
|
-
if (!data)
|
|
46165
|
+
if (!data)
|
|
46211
46166
|
throw new NotFoundError52("User not found.");
|
|
46167
|
+
setCache(cacheKey, data, 15 * 60).then(() => logger178.info(`Cache set for key: ${cacheKey}`)).catch(
|
|
46168
|
+
(err) => logger178.error(`Failed to set cache for key: ${cacheKey}`, err)
|
|
46169
|
+
);
|
|
46170
|
+
return data;
|
|
46171
|
+
} catch (error) {
|
|
46172
|
+
if (error instanceof AppError27)
|
|
46173
|
+
throw error;
|
|
46174
|
+
throw new InternalServerError70("Failed to get user by id.");
|
|
46175
|
+
}
|
|
46176
|
+
}
|
|
46177
|
+
async function getUserByReferralCode(referralCode) {
|
|
46178
|
+
try {
|
|
46179
|
+
const cacheKey = makeCacheKey65(namespace_collection, { referralCode });
|
|
46180
|
+
const cachedData = await getCache(cacheKey);
|
|
46181
|
+
if (cachedData) {
|
|
46182
|
+
logger178.info(`Cache hit for key: ${cacheKey}`);
|
|
46183
|
+
return cachedData;
|
|
46184
|
+
}
|
|
46185
|
+
const data = await collection.findOne({ referralCode });
|
|
46186
|
+
setCache(cacheKey, data, 15 * 60).then(() => logger178.info(`Cache set for key: ${cacheKey}`)).catch(
|
|
46187
|
+
(err) => logger178.error(`Failed to set cache for key: ${cacheKey}`, err)
|
|
46188
|
+
);
|
|
46189
|
+
return data;
|
|
46190
|
+
} catch (error) {
|
|
46191
|
+
throw new InternalServerError70("Failed to get user by referral code.");
|
|
46192
|
+
}
|
|
46193
|
+
}
|
|
46194
|
+
async function getByEmailApp(email, app) {
|
|
46195
|
+
try {
|
|
46196
|
+
const cacheKey = makeCacheKey65(namespace_collection, { email, app });
|
|
46197
|
+
const cachedData = await getCache(cacheKey);
|
|
46198
|
+
if (cachedData) {
|
|
46199
|
+
logger178.info(`Cache hit for key: ${cacheKey}`);
|
|
46200
|
+
return cachedData;
|
|
46212
46201
|
}
|
|
46202
|
+
const data = await collection.findOne({
|
|
46203
|
+
email,
|
|
46204
|
+
"roles.app": app
|
|
46205
|
+
});
|
|
46206
|
+
setCache(cacheKey, data, 15 * 60).then(() => logger178.info(`Cache set for key: ${cacheKey}`)).catch(
|
|
46207
|
+
(err) => logger178.error(`Failed to set cache for key: ${cacheKey}`, err)
|
|
46208
|
+
);
|
|
46209
|
+
return data;
|
|
46210
|
+
} catch (error) {
|
|
46211
|
+
throw new InternalServerError70("Failed to get user by email and app.");
|
|
46212
|
+
}
|
|
46213
|
+
}
|
|
46214
|
+
async function getUsersByOrgId({
|
|
46215
|
+
organization = "",
|
|
46216
|
+
search = "",
|
|
46217
|
+
page = 1,
|
|
46218
|
+
limit = 10,
|
|
46219
|
+
sort = {},
|
|
46220
|
+
type = "",
|
|
46221
|
+
status = "active"
|
|
46222
|
+
}) {
|
|
46223
|
+
page = page > 0 ? page - 1 : 0;
|
|
46224
|
+
const query = { status };
|
|
46225
|
+
const cacheOptions = { status };
|
|
46226
|
+
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
46227
|
+
cacheOptions.sort = JSON.stringify(sort);
|
|
46228
|
+
if (search) {
|
|
46229
|
+
query.$text = { $search: search };
|
|
46230
|
+
cacheOptions.search = search;
|
|
46231
|
+
}
|
|
46232
|
+
if (type) {
|
|
46233
|
+
query.type = type;
|
|
46234
|
+
cacheOptions.type = type;
|
|
46235
|
+
}
|
|
46236
|
+
if (organization) {
|
|
46237
|
+
try {
|
|
46238
|
+
query.defaultOrg = new ObjectId123(organization);
|
|
46239
|
+
cacheOptions.organization = organization.toString();
|
|
46240
|
+
} catch (error) {
|
|
46241
|
+
throw new BadRequestError198("Invalid organization ID format.");
|
|
46242
|
+
}
|
|
46243
|
+
}
|
|
46244
|
+
delNamespace().then(() => {
|
|
46245
|
+
logger178.info(`Cache cleared for namespace: ${namespace_collection}`);
|
|
46246
|
+
}).catch((err) => {
|
|
46247
|
+
logger178.error(
|
|
46248
|
+
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
46249
|
+
err
|
|
46250
|
+
);
|
|
46251
|
+
});
|
|
46252
|
+
const cacheKey = makeCacheKey65(namespace_collection, cacheOptions);
|
|
46253
|
+
const cachedData = await getCache(cacheKey);
|
|
46254
|
+
if (cachedData) {
|
|
46255
|
+
logger178.info(`Cache hit for key: ${cacheKey}`);
|
|
46256
|
+
return cachedData;
|
|
46257
|
+
}
|
|
46258
|
+
try {
|
|
46259
|
+
const items = await collection.aggregate([
|
|
46260
|
+
{ $match: query },
|
|
46261
|
+
{ $sort: sort },
|
|
46262
|
+
{ $skip: page * limit },
|
|
46263
|
+
{ $limit: limit },
|
|
46264
|
+
{
|
|
46265
|
+
$project: {
|
|
46266
|
+
_id: 1,
|
|
46267
|
+
name: 1,
|
|
46268
|
+
email: 1,
|
|
46269
|
+
type: 1,
|
|
46270
|
+
status: 1
|
|
46271
|
+
}
|
|
46272
|
+
}
|
|
46273
|
+
]).toArray();
|
|
46274
|
+
const length = await collection.countDocuments(query);
|
|
46275
|
+
const data = paginate58(items, page, limit, length);
|
|
46213
46276
|
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
46214
46277
|
logger178.info(`Cache set for key: ${cacheKey}`);
|
|
46215
46278
|
}).catch((err) => {
|
|
@@ -46217,12 +46280,197 @@ function useUserRepoV2() {
|
|
|
46217
46280
|
});
|
|
46218
46281
|
return data;
|
|
46219
46282
|
} catch (error) {
|
|
46220
|
-
|
|
46283
|
+
logger178.log({ level: "error", message: `${error}` });
|
|
46284
|
+
throw error;
|
|
46285
|
+
}
|
|
46286
|
+
}
|
|
46287
|
+
async function getUsers({
|
|
46288
|
+
search = "",
|
|
46289
|
+
page = 1,
|
|
46290
|
+
limit = 10,
|
|
46291
|
+
sort = {},
|
|
46292
|
+
type = "",
|
|
46293
|
+
status = "active"
|
|
46294
|
+
}) {
|
|
46295
|
+
page = page > 0 ? page - 1 : 0;
|
|
46296
|
+
const query = { status };
|
|
46297
|
+
const cacheOptions = { status };
|
|
46298
|
+
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
46299
|
+
cacheOptions.sort = JSON.stringify(sort);
|
|
46300
|
+
if (search) {
|
|
46301
|
+
query.$text = { $search: search };
|
|
46302
|
+
cacheOptions.search = search;
|
|
46303
|
+
}
|
|
46304
|
+
if (type) {
|
|
46305
|
+
query.type = type;
|
|
46306
|
+
cacheOptions.type = type;
|
|
46307
|
+
}
|
|
46308
|
+
delNamespace().then(
|
|
46309
|
+
() => logger178.info(`Cache cleared for namespace: ${namespace_collection}`)
|
|
46310
|
+
).catch(
|
|
46311
|
+
(err) => logger178.error(
|
|
46312
|
+
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
46313
|
+
err
|
|
46314
|
+
)
|
|
46315
|
+
);
|
|
46316
|
+
const cacheKey = makeCacheKey65(namespace_collection, cacheOptions);
|
|
46317
|
+
const cachedData = await getCache(cacheKey);
|
|
46318
|
+
if (cachedData) {
|
|
46319
|
+
logger178.info(`Cache hit for key: ${cacheKey}`);
|
|
46320
|
+
return cachedData;
|
|
46321
|
+
}
|
|
46322
|
+
try {
|
|
46323
|
+
const items = await collection.aggregate([
|
|
46324
|
+
{ $match: query },
|
|
46325
|
+
{ $sort: sort },
|
|
46326
|
+
{ $skip: page * limit },
|
|
46327
|
+
{ $limit: limit },
|
|
46328
|
+
{ $project: { _id: 1, name: 1, email: 1, type: 1, status: 1 } }
|
|
46329
|
+
]).toArray();
|
|
46330
|
+
const length = await collection.countDocuments(query);
|
|
46331
|
+
const data = paginate58(items, page, limit, length);
|
|
46332
|
+
setCache(cacheKey, data, 15 * 60).then(() => logger178.info(`Cache set for key: ${cacheKey}`)).catch(
|
|
46333
|
+
(err) => logger178.error(`Failed to set cache for key: ${cacheKey}`, err)
|
|
46334
|
+
);
|
|
46335
|
+
return data;
|
|
46336
|
+
} catch (error) {
|
|
46337
|
+
logger178.log({ level: "error", message: `${error}` });
|
|
46338
|
+
throw error;
|
|
46339
|
+
}
|
|
46340
|
+
}
|
|
46341
|
+
async function updatePasswordById({ _id, password }, session) {
|
|
46342
|
+
const cacheKey = makeCacheKey65(namespace_collection, { _id });
|
|
46343
|
+
_id = toObjectId18(_id);
|
|
46344
|
+
try {
|
|
46345
|
+
const result = await collection.updateOne(
|
|
46346
|
+
{ _id },
|
|
46347
|
+
{ $set: { password, updatedAt: (/* @__PURE__ */ new Date()).toISOString() } },
|
|
46348
|
+
{ session }
|
|
46349
|
+
);
|
|
46350
|
+
delCache(cacheKey).then(() => {
|
|
46351
|
+
logger178.info(`Cache deleted for key: ${cacheKey}`);
|
|
46352
|
+
}).catch((err) => {
|
|
46353
|
+
logger178.error(`Failed to delete cache for key: ${cacheKey}`, err);
|
|
46354
|
+
});
|
|
46355
|
+
return result;
|
|
46356
|
+
} catch (error) {
|
|
46357
|
+
throw new InternalServerError70("Failed to update user password.");
|
|
46358
|
+
}
|
|
46359
|
+
}
|
|
46360
|
+
async function updateUserFieldById({ _id, field, value } = {}, session) {
|
|
46361
|
+
const allowedFields = [
|
|
46362
|
+
"name",
|
|
46363
|
+
"email",
|
|
46364
|
+
"contact",
|
|
46365
|
+
"nric",
|
|
46366
|
+
"dateOfBirth",
|
|
46367
|
+
"profile",
|
|
46368
|
+
"gender",
|
|
46369
|
+
"defaultOrg"
|
|
46370
|
+
];
|
|
46371
|
+
if (!allowedFields.includes(field)) {
|
|
46372
|
+
throw new BadRequestError198(
|
|
46373
|
+
`Field "${field}" is not allowed to be updated.`
|
|
46374
|
+
);
|
|
46375
|
+
}
|
|
46376
|
+
try {
|
|
46377
|
+
_id = new ObjectId123(_id);
|
|
46378
|
+
} catch (error) {
|
|
46379
|
+
throw new BadRequestError198("Invalid ID.");
|
|
46380
|
+
}
|
|
46381
|
+
if (field === "defaultOrg") {
|
|
46382
|
+
try {
|
|
46383
|
+
value = new ObjectId123(value);
|
|
46384
|
+
} catch (error) {
|
|
46385
|
+
throw new BadRequestError198("Invalid organization ID.");
|
|
46386
|
+
}
|
|
46387
|
+
}
|
|
46388
|
+
if (field === "name") {
|
|
46389
|
+
try {
|
|
46390
|
+
await Promise.all([
|
|
46391
|
+
updateFeedbackCreatedByName(_id, value, session),
|
|
46392
|
+
updateWorkOrderCreatedByName(_id, value, session),
|
|
46393
|
+
updateUserNameBySignatureId(_id, value, session)
|
|
46394
|
+
]);
|
|
46395
|
+
} catch (error) {
|
|
46221
46396
|
throw error;
|
|
46222
|
-
} else {
|
|
46223
|
-
throw new InternalServerError70("Failed to get user by email.");
|
|
46224
46397
|
}
|
|
46225
46398
|
}
|
|
46399
|
+
try {
|
|
46400
|
+
await collection.updateOne(
|
|
46401
|
+
{ _id },
|
|
46402
|
+
{ $set: { [field]: value, updatedAt: (/* @__PURE__ */ new Date()).toISOString() } },
|
|
46403
|
+
// Dynamically set the field
|
|
46404
|
+
{ session }
|
|
46405
|
+
);
|
|
46406
|
+
const cacheKey = makeCacheKey65(namespace_collection, { _id });
|
|
46407
|
+
delCache(cacheKey).then(() => {
|
|
46408
|
+
logger178.info(`Cache deleted for key: ${cacheKey}`);
|
|
46409
|
+
}).catch((err) => {
|
|
46410
|
+
logger178.error(`Failed to delete cache for key: ${cacheKey}`, err);
|
|
46411
|
+
});
|
|
46412
|
+
return `Successfully updated user ${field}.`;
|
|
46413
|
+
} catch (error) {
|
|
46414
|
+
throw new InternalServerError70(`Failed to update user ${field}.`);
|
|
46415
|
+
}
|
|
46416
|
+
}
|
|
46417
|
+
async function updateBirthday({
|
|
46418
|
+
_id,
|
|
46419
|
+
month,
|
|
46420
|
+
day,
|
|
46421
|
+
year
|
|
46422
|
+
}, session) {
|
|
46423
|
+
try {
|
|
46424
|
+
_id = new ObjectId123(_id);
|
|
46425
|
+
} catch (error) {
|
|
46426
|
+
throw new BadRequestError198("Invalid user ID format.");
|
|
46427
|
+
}
|
|
46428
|
+
try {
|
|
46429
|
+
await collection.updateOne(
|
|
46430
|
+
{ _id },
|
|
46431
|
+
{
|
|
46432
|
+
$set: {
|
|
46433
|
+
birthMonth: month,
|
|
46434
|
+
birthDay: day,
|
|
46435
|
+
birthYear: year,
|
|
46436
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
46437
|
+
}
|
|
46438
|
+
},
|
|
46439
|
+
{ session }
|
|
46440
|
+
);
|
|
46441
|
+
const cacheKey = makeCacheKey65(namespace_collection, { _id });
|
|
46442
|
+
delCache(cacheKey).then(() => {
|
|
46443
|
+
logger178.info(`Cache deleted for key: ${cacheKey}`);
|
|
46444
|
+
}).catch((err) => {
|
|
46445
|
+
logger178.error(`Failed to delete cache for key: ${cacheKey}`, err);
|
|
46446
|
+
});
|
|
46447
|
+
return "Successfully updated user birthday.";
|
|
46448
|
+
} catch (error) {
|
|
46449
|
+
throw new InternalServerError70("Failed to update user birthday.");
|
|
46450
|
+
}
|
|
46451
|
+
}
|
|
46452
|
+
async function updatePassword({ _id, password }, session) {
|
|
46453
|
+
try {
|
|
46454
|
+
_id = new ObjectId123(_id);
|
|
46455
|
+
} catch (error) {
|
|
46456
|
+
throw new BadRequestError198("Invalid user ID format.");
|
|
46457
|
+
}
|
|
46458
|
+
try {
|
|
46459
|
+
const result = await collection.updateOne(
|
|
46460
|
+
{ _id },
|
|
46461
|
+
{ $set: { password, updatedAt: (/* @__PURE__ */ new Date()).toISOString() } },
|
|
46462
|
+
{ session }
|
|
46463
|
+
);
|
|
46464
|
+
const cacheKey = makeCacheKey65(namespace_collection, { _id });
|
|
46465
|
+
delCache(cacheKey).then(() => {
|
|
46466
|
+
logger178.info(`Cache deleted for key: ${cacheKey}`);
|
|
46467
|
+
}).catch((err) => {
|
|
46468
|
+
logger178.error(`Failed to delete cache for key: ${cacheKey}`, err);
|
|
46469
|
+
});
|
|
46470
|
+
return result;
|
|
46471
|
+
} catch (error) {
|
|
46472
|
+
throw new InternalServerError70("Failed to update user password.");
|
|
46473
|
+
}
|
|
46226
46474
|
}
|
|
46227
46475
|
return {
|
|
46228
46476
|
createIndex,
|
|
@@ -46231,7 +46479,13 @@ function useUserRepoV2() {
|
|
|
46231
46479
|
createUser,
|
|
46232
46480
|
getUserByEmail,
|
|
46233
46481
|
getUserByEmailStatus,
|
|
46234
|
-
getUserById
|
|
46482
|
+
getUserById,
|
|
46483
|
+
getUsers,
|
|
46484
|
+
getUsersByOrgId,
|
|
46485
|
+
updatePasswordById,
|
|
46486
|
+
updateUserFieldById,
|
|
46487
|
+
updateBirthday,
|
|
46488
|
+
updatePassword
|
|
46235
46489
|
};
|
|
46236
46490
|
}
|
|
46237
46491
|
|
|
@@ -46298,10 +46552,220 @@ function useAuthServiceV2() {
|
|
|
46298
46552
|
};
|
|
46299
46553
|
}
|
|
46300
46554
|
|
|
46555
|
+
// src/services/user-v2.service.ts
|
|
46556
|
+
import {
|
|
46557
|
+
BadRequestError as BadRequestError200,
|
|
46558
|
+
comparePassword as comparePassword4,
|
|
46559
|
+
hashPassword as hashPassword5,
|
|
46560
|
+
InternalServerError as InternalServerError72,
|
|
46561
|
+
NotFoundError as NotFoundError54,
|
|
46562
|
+
useAtlas as useAtlas114,
|
|
46563
|
+
useS3 as useS33
|
|
46564
|
+
} from "@7365admin1/node-server-utils";
|
|
46565
|
+
import "multer";
|
|
46566
|
+
function useUserServiceV2() {
|
|
46567
|
+
const {
|
|
46568
|
+
createUser: _createUser,
|
|
46569
|
+
getUserByEmail: _getUserByEmail,
|
|
46570
|
+
updatePasswordById: _updatePasswordById,
|
|
46571
|
+
updateUserFieldById: _updateUserFieldById,
|
|
46572
|
+
getUserById,
|
|
46573
|
+
updatePassword
|
|
46574
|
+
} = useUserRepoV2();
|
|
46575
|
+
const { getRoleByName, addRole } = useRoleRepo();
|
|
46576
|
+
const { add: addMember } = useMemberRepo();
|
|
46577
|
+
const { getById: getOrgById } = useOrgRepo();
|
|
46578
|
+
const { getSiteById } = useSiteRepo();
|
|
46579
|
+
const {
|
|
46580
|
+
getVerificationById: _getVerificationById,
|
|
46581
|
+
updateVerificationStatusById: _updateVerificationStatusById
|
|
46582
|
+
} = useVerificationRepoV2();
|
|
46583
|
+
const { verify: _verify } = useVerificationServiceV2();
|
|
46584
|
+
const { createFile, deleteFileById } = useFileRepo();
|
|
46585
|
+
async function createUserBySignUp({
|
|
46586
|
+
id = "",
|
|
46587
|
+
name = ""
|
|
46588
|
+
}) {
|
|
46589
|
+
const session = useAtlas114.getClient()?.startSession();
|
|
46590
|
+
session?.startTransaction();
|
|
46591
|
+
try {
|
|
46592
|
+
const signUp = await _getVerificationById(id);
|
|
46593
|
+
if (!signUp)
|
|
46594
|
+
throw new BadRequestError200("Invalid sign up link.");
|
|
46595
|
+
if (signUp.status === "complete" /* COMPLETE */)
|
|
46596
|
+
throw new BadRequestError200(
|
|
46597
|
+
"You have already an account created using this link."
|
|
46598
|
+
);
|
|
46599
|
+
const expired = signUp.expireAt < (/* @__PURE__ */ new Date()).toISOString();
|
|
46600
|
+
if (signUp.status === "expired" || expired)
|
|
46601
|
+
throw new BadRequestError200("Sign up link expired.");
|
|
46602
|
+
const email = signUp.email;
|
|
46603
|
+
const _user = await _getUserByEmail(email);
|
|
46604
|
+
if (_user)
|
|
46605
|
+
throw new BadRequestError200(`User already exists: ${email}.`);
|
|
46606
|
+
let org = null;
|
|
46607
|
+
if (signUp.metadata?.org) {
|
|
46608
|
+
org = await getOrgById(signUp.metadata.org);
|
|
46609
|
+
if (!org)
|
|
46610
|
+
signUp.metadata.org = "";
|
|
46611
|
+
}
|
|
46612
|
+
if (signUp.metadata?.siteId)
|
|
46613
|
+
await getSiteById(signUp.metadata?.siteId);
|
|
46614
|
+
const user = {
|
|
46615
|
+
email,
|
|
46616
|
+
password: signUp.metadata?.password,
|
|
46617
|
+
name,
|
|
46618
|
+
defaultOrg: org?._id?.toString() || ""
|
|
46619
|
+
};
|
|
46620
|
+
const userId = await _createUser(user, session);
|
|
46621
|
+
if (org?._id) {
|
|
46622
|
+
await addMember(
|
|
46623
|
+
{
|
|
46624
|
+
org: org?._id?.toString() || "",
|
|
46625
|
+
orgName: org?.name || "",
|
|
46626
|
+
user: userId.toString(),
|
|
46627
|
+
name,
|
|
46628
|
+
role: signUp.metadata?.role?.toString() || "",
|
|
46629
|
+
type: signUp.metadata?.app ?? "organization",
|
|
46630
|
+
siteId: signUp.metadata?.siteId?.toString() || "",
|
|
46631
|
+
siteName: signUp.metadata?.siteName || ""
|
|
46632
|
+
},
|
|
46633
|
+
session
|
|
46634
|
+
);
|
|
46635
|
+
}
|
|
46636
|
+
await _updateVerificationStatusById(
|
|
46637
|
+
id,
|
|
46638
|
+
"complete" /* COMPLETE */,
|
|
46639
|
+
session
|
|
46640
|
+
);
|
|
46641
|
+
await session?.commitTransaction();
|
|
46642
|
+
return userId;
|
|
46643
|
+
} catch (error) {
|
|
46644
|
+
await session?.abortTransaction();
|
|
46645
|
+
throw error;
|
|
46646
|
+
} finally {
|
|
46647
|
+
session?.endSession();
|
|
46648
|
+
}
|
|
46649
|
+
}
|
|
46650
|
+
async function resetPassword(id, newPassword, passwordConfirmation) {
|
|
46651
|
+
if (newPassword !== passwordConfirmation) {
|
|
46652
|
+
throw new BadRequestError200("Passwords do not match.");
|
|
46653
|
+
}
|
|
46654
|
+
let hashedPassword;
|
|
46655
|
+
const session = useAtlas114.getClient()?.startSession();
|
|
46656
|
+
session?.startTransaction();
|
|
46657
|
+
try {
|
|
46658
|
+
hashedPassword = await hashPassword5(newPassword);
|
|
46659
|
+
} catch (error) {
|
|
46660
|
+
throw new InternalServerError72(`Error hashing password: ${error}`);
|
|
46661
|
+
}
|
|
46662
|
+
try {
|
|
46663
|
+
const otpDoc = await _getVerificationById(id);
|
|
46664
|
+
if (!otpDoc) {
|
|
46665
|
+
throw new NotFoundError54("You are using an invalid reset link.");
|
|
46666
|
+
}
|
|
46667
|
+
if (otpDoc.status === "complete" /* COMPLETE */) {
|
|
46668
|
+
throw new BadRequestError200("This link has already been invalidated.");
|
|
46669
|
+
}
|
|
46670
|
+
const user = await _getUserByEmail(otpDoc.email);
|
|
46671
|
+
if (!user) {
|
|
46672
|
+
throw new NotFoundError54("User not found.");
|
|
46673
|
+
}
|
|
46674
|
+
if (!user._id) {
|
|
46675
|
+
throw new InternalServerError72("Invalid user ID.");
|
|
46676
|
+
}
|
|
46677
|
+
await Promise.all([
|
|
46678
|
+
_updateVerificationStatusById(id, "complete" /* COMPLETE */, session),
|
|
46679
|
+
_updatePasswordById(
|
|
46680
|
+
{ _id: user._id.toString(), password: hashedPassword },
|
|
46681
|
+
session
|
|
46682
|
+
)
|
|
46683
|
+
]);
|
|
46684
|
+
await session?.commitTransaction();
|
|
46685
|
+
return "Successfully reset password.";
|
|
46686
|
+
} catch (error) {
|
|
46687
|
+
await session?.abortTransaction();
|
|
46688
|
+
throw error;
|
|
46689
|
+
} finally {
|
|
46690
|
+
session?.endSession();
|
|
46691
|
+
}
|
|
46692
|
+
}
|
|
46693
|
+
const s3 = new useS33({
|
|
46694
|
+
accessKeyId: SPACES_ACCESS_KEY,
|
|
46695
|
+
secretAccessKey: SPACES_SECRET_KEY,
|
|
46696
|
+
endpoint: SPACES_ENDPOINT,
|
|
46697
|
+
region: SPACES_REGION,
|
|
46698
|
+
bucket: SPACES_BUCKET,
|
|
46699
|
+
forcePathStyle: false
|
|
46700
|
+
});
|
|
46701
|
+
async function updateUserProfile({
|
|
46702
|
+
file,
|
|
46703
|
+
user,
|
|
46704
|
+
previousProfile
|
|
46705
|
+
}) {
|
|
46706
|
+
const session = useAtlas114.getClient()?.startSession();
|
|
46707
|
+
session?.startTransaction();
|
|
46708
|
+
const _file = {
|
|
46709
|
+
name: file.originalname,
|
|
46710
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
46711
|
+
};
|
|
46712
|
+
try {
|
|
46713
|
+
const id = await createFile(_file, session);
|
|
46714
|
+
await s3.uploadObject({
|
|
46715
|
+
key: id,
|
|
46716
|
+
body: file.buffer,
|
|
46717
|
+
contentType: file.mimetype
|
|
46718
|
+
});
|
|
46719
|
+
if (previousProfile) {
|
|
46720
|
+
await deleteFileById(previousProfile, session);
|
|
46721
|
+
await s3.deleteObject(previousProfile);
|
|
46722
|
+
}
|
|
46723
|
+
await _updateUserFieldById(
|
|
46724
|
+
{ _id: user, field: "profile", value: id },
|
|
46725
|
+
session
|
|
46726
|
+
);
|
|
46727
|
+
await session?.commitTransaction();
|
|
46728
|
+
return id;
|
|
46729
|
+
} catch (error) {
|
|
46730
|
+
await session?.abortTransaction();
|
|
46731
|
+
throw error;
|
|
46732
|
+
} finally {
|
|
46733
|
+
session?.endSession();
|
|
46734
|
+
}
|
|
46735
|
+
}
|
|
46736
|
+
async function updatePasswordById(id, currentPassword, newPassword, passwordConfirmation) {
|
|
46737
|
+
let hashedPassword;
|
|
46738
|
+
const user = await getUserById(id);
|
|
46739
|
+
const isPasswordValid = await comparePassword4(
|
|
46740
|
+
currentPassword,
|
|
46741
|
+
user.password
|
|
46742
|
+
);
|
|
46743
|
+
if (!isPasswordValid)
|
|
46744
|
+
throw new BadRequestError200("Invalid current password.");
|
|
46745
|
+
if (newPassword !== passwordConfirmation)
|
|
46746
|
+
throw new BadRequestError200("Passwords do not match.");
|
|
46747
|
+
try {
|
|
46748
|
+
hashedPassword = await hashPassword5(newPassword);
|
|
46749
|
+
if (!hashedPassword)
|
|
46750
|
+
throw new InternalServerError72("Error hashing password.");
|
|
46751
|
+
return await updatePassword({ _id: id, password: hashedPassword });
|
|
46752
|
+
} catch (error) {
|
|
46753
|
+
throw error;
|
|
46754
|
+
}
|
|
46755
|
+
}
|
|
46756
|
+
return {
|
|
46757
|
+
createUserBySignUp,
|
|
46758
|
+
resetPassword,
|
|
46759
|
+
updateUserProfile,
|
|
46760
|
+
updatePasswordById
|
|
46761
|
+
};
|
|
46762
|
+
}
|
|
46763
|
+
|
|
46301
46764
|
// src/controllers/auth-v2.controller.ts
|
|
46302
46765
|
function useAuthControllerV2() {
|
|
46303
46766
|
const { signUp: _signUp } = useVerificationServiceV2();
|
|
46304
46767
|
const { login: _login, logout: _logout } = useAuthServiceV2();
|
|
46768
|
+
const { resetPassword: _resetPassword } = useUserServiceV2();
|
|
46305
46769
|
async function signUp(req, res, next) {
|
|
46306
46770
|
try {
|
|
46307
46771
|
const validation = Joi127.object({
|
|
@@ -46315,8 +46779,8 @@ function useAuthControllerV2() {
|
|
|
46315
46779
|
});
|
|
46316
46780
|
if (error) {
|
|
46317
46781
|
const messages = error.details.map((d) => d.message);
|
|
46318
|
-
|
|
46319
|
-
next(new
|
|
46782
|
+
logger180.log({ level: "error", message: messages.join(", ") });
|
|
46783
|
+
next(new BadRequestError201(messages.join(", ")));
|
|
46320
46784
|
return;
|
|
46321
46785
|
}
|
|
46322
46786
|
const { email, password, country, orgName } = value;
|
|
@@ -46332,7 +46796,7 @@ function useAuthControllerV2() {
|
|
|
46332
46796
|
return;
|
|
46333
46797
|
} catch (error) {
|
|
46334
46798
|
console.log(error);
|
|
46335
|
-
|
|
46799
|
+
logger180.log({ level: "error", message: error.message });
|
|
46336
46800
|
next(error);
|
|
46337
46801
|
return;
|
|
46338
46802
|
}
|
|
@@ -46350,8 +46814,8 @@ function useAuthControllerV2() {
|
|
|
46350
46814
|
});
|
|
46351
46815
|
if (error) {
|
|
46352
46816
|
const messages = error.details.map((d) => d.message);
|
|
46353
|
-
|
|
46354
|
-
next(new
|
|
46817
|
+
logger180.log({ level: "error", message: messages.join(", ") });
|
|
46818
|
+
next(new BadRequestError201(messages.join(", ")));
|
|
46355
46819
|
return;
|
|
46356
46820
|
}
|
|
46357
46821
|
const session = await _login(value);
|
|
@@ -46363,7 +46827,7 @@ function useAuthControllerV2() {
|
|
|
46363
46827
|
res.cookie("sid", session.sid, cookieOptions).cookie("user", session.user, cookieOptions).json(session);
|
|
46364
46828
|
return;
|
|
46365
46829
|
} catch (error) {
|
|
46366
|
-
|
|
46830
|
+
logger180.log({ level: "error", message: error.message });
|
|
46367
46831
|
next(error);
|
|
46368
46832
|
return;
|
|
46369
46833
|
}
|
|
@@ -46371,7 +46835,7 @@ function useAuthControllerV2() {
|
|
|
46371
46835
|
async function logout(req, res, next) {
|
|
46372
46836
|
const sid = req.headers["authorization"] ?? "";
|
|
46373
46837
|
if (!sid) {
|
|
46374
|
-
next(new
|
|
46838
|
+
next(new BadRequestError201("Session ID is required"));
|
|
46375
46839
|
return;
|
|
46376
46840
|
}
|
|
46377
46841
|
try {
|
|
@@ -46379,130 +46843,170 @@ function useAuthControllerV2() {
|
|
|
46379
46843
|
res.json({ message: "Logged out successfully" });
|
|
46380
46844
|
return;
|
|
46381
46845
|
} catch (error) {
|
|
46382
|
-
|
|
46846
|
+
logger180.log({ level: "error", message: error.message });
|
|
46383
46847
|
next(error);
|
|
46384
46848
|
return;
|
|
46385
46849
|
}
|
|
46386
46850
|
}
|
|
46387
|
-
|
|
46388
|
-
|
|
46389
|
-
|
|
46390
|
-
|
|
46391
|
-
|
|
46392
|
-
}
|
|
46393
|
-
|
|
46394
|
-
|
|
46395
|
-
|
|
46396
|
-
|
|
46397
|
-
|
|
46398
|
-
|
|
46399
|
-
|
|
46400
|
-
|
|
46401
|
-
|
|
46402
|
-
|
|
46403
|
-
const { add: addMember } = useMemberRepo();
|
|
46404
|
-
const { getById: getOrgById } = useOrgRepo();
|
|
46405
|
-
const { getSiteById } = useSiteRepo();
|
|
46406
|
-
const {
|
|
46407
|
-
getVerificationById: _getVerificationById,
|
|
46408
|
-
updateVerificationStatusById: _updateVerificationStatusById
|
|
46409
|
-
} = useVerificationRepoV2();
|
|
46410
|
-
const { verify } = useVerificationService();
|
|
46411
|
-
const { createFile, deleteFileById } = useFileRepo();
|
|
46412
|
-
async function createUserBySignUp({
|
|
46413
|
-
id = "",
|
|
46414
|
-
name = ""
|
|
46415
|
-
}) {
|
|
46416
|
-
const session = useAtlas114.getClient()?.startSession();
|
|
46417
|
-
session?.startTransaction();
|
|
46851
|
+
async function resetPassword(req, res, next) {
|
|
46852
|
+
const validation = Joi127.object({
|
|
46853
|
+
otp: Joi127.string().hex().required(),
|
|
46854
|
+
newPassword: Joi127.string().required().min(8),
|
|
46855
|
+
passwordConfirmation: Joi127.string().required().min(8)
|
|
46856
|
+
});
|
|
46857
|
+
const { error, value } = validation.validate(req.body, {
|
|
46858
|
+
abortEarly: false
|
|
46859
|
+
});
|
|
46860
|
+
if (error) {
|
|
46861
|
+
const messages = error.details.map((d) => d.message);
|
|
46862
|
+
logger180.log({ level: "error", message: messages.join(", ") });
|
|
46863
|
+
next(new BadRequestError201(messages.join(", ")));
|
|
46864
|
+
return;
|
|
46865
|
+
}
|
|
46866
|
+
const { otp, newPassword, passwordConfirmation } = value;
|
|
46418
46867
|
try {
|
|
46419
|
-
const
|
|
46420
|
-
|
|
46421
|
-
|
|
46422
|
-
|
|
46423
|
-
throw new BadRequestError201(
|
|
46424
|
-
"You have already an account created using this link."
|
|
46425
|
-
);
|
|
46426
|
-
const expired = signUp.expireAt < (/* @__PURE__ */ new Date()).toISOString();
|
|
46427
|
-
if (signUp.status === "expired" || expired)
|
|
46428
|
-
throw new BadRequestError201("Sign up link expired.");
|
|
46429
|
-
const email = signUp.email;
|
|
46430
|
-
const _user = await getUserByEmail(email);
|
|
46431
|
-
if (_user)
|
|
46432
|
-
throw new BadRequestError201(`User already exists: ${email}.`);
|
|
46433
|
-
let org = null;
|
|
46434
|
-
if (signUp.metadata?.org) {
|
|
46435
|
-
org = await getOrgById(signUp.metadata.org);
|
|
46436
|
-
if (!org)
|
|
46437
|
-
signUp.metadata.org = "";
|
|
46438
|
-
}
|
|
46439
|
-
if (signUp.metadata?.siteId)
|
|
46440
|
-
await getSiteById(signUp.metadata?.siteId);
|
|
46441
|
-
const user = {
|
|
46442
|
-
email,
|
|
46443
|
-
password: signUp.metadata?.password,
|
|
46444
|
-
name,
|
|
46445
|
-
defaultOrg: org?._id?.toString() || ""
|
|
46446
|
-
};
|
|
46447
|
-
const userId = await _createUser(user, session);
|
|
46448
|
-
if (org?._id) {
|
|
46449
|
-
await addMember(
|
|
46450
|
-
{
|
|
46451
|
-
org: org?._id?.toString() || "",
|
|
46452
|
-
orgName: org?.name || "",
|
|
46453
|
-
user: userId.toString(),
|
|
46454
|
-
name,
|
|
46455
|
-
role: signUp.metadata?.role?.toString() || "",
|
|
46456
|
-
type: signUp.metadata?.app ?? "organization",
|
|
46457
|
-
siteId: signUp.metadata?.siteId?.toString() || "",
|
|
46458
|
-
siteName: signUp.metadata?.siteName || ""
|
|
46459
|
-
},
|
|
46460
|
-
session
|
|
46461
|
-
);
|
|
46462
|
-
}
|
|
46463
|
-
await _updateVerificationStatusById(
|
|
46464
|
-
id,
|
|
46465
|
-
"complete" /* COMPLETE */,
|
|
46466
|
-
session
|
|
46868
|
+
const message = await _resetPassword(
|
|
46869
|
+
otp,
|
|
46870
|
+
newPassword,
|
|
46871
|
+
passwordConfirmation
|
|
46467
46872
|
);
|
|
46468
|
-
|
|
46469
|
-
return
|
|
46470
|
-
} catch (
|
|
46471
|
-
|
|
46472
|
-
|
|
46473
|
-
|
|
46474
|
-
session?.endSession();
|
|
46873
|
+
res.json({ message });
|
|
46874
|
+
return;
|
|
46875
|
+
} catch (error2) {
|
|
46876
|
+
logger180.log({ level: "error", message: error2.message });
|
|
46877
|
+
next(error2);
|
|
46878
|
+
return;
|
|
46475
46879
|
}
|
|
46476
46880
|
}
|
|
46477
46881
|
return {
|
|
46478
|
-
|
|
46882
|
+
signUp,
|
|
46883
|
+
login,
|
|
46884
|
+
logout,
|
|
46885
|
+
resetPassword
|
|
46479
46886
|
};
|
|
46480
46887
|
}
|
|
46481
46888
|
|
|
46482
46889
|
// src/controllers/user-v2.controller.ts
|
|
46483
46890
|
import Joi128 from "joi";
|
|
46891
|
+
import "multer";
|
|
46484
46892
|
import { BadRequestError as BadRequestError202, logger as logger181 } from "@7365admin1/node-server-utils";
|
|
46485
46893
|
function useUserControllerV2() {
|
|
46486
|
-
const {
|
|
46894
|
+
const {
|
|
46895
|
+
updateBirthday: _updateBirthday,
|
|
46896
|
+
getUserById: _getUserById,
|
|
46897
|
+
getUserByEmail: _getUserByEmail,
|
|
46898
|
+
getUserById: _getById,
|
|
46899
|
+
getUsers: _getUsers,
|
|
46900
|
+
getUsersByOrgId: _getUsersByOrgId,
|
|
46901
|
+
updateUserFieldById: _updateUserFieldById
|
|
46902
|
+
} = useUserRepoV2();
|
|
46903
|
+
const { createUserBySignUp, updateUserProfile: _updateUserProfile, updatePasswordById: _updatePasswordById } = useUserServiceV2();
|
|
46904
|
+
function rejectValidation(error, next) {
|
|
46905
|
+
const message = error.details.map((d) => d.message).join(", ");
|
|
46906
|
+
logger181.log({ level: "error", message });
|
|
46907
|
+
next(new BadRequestError202(message));
|
|
46908
|
+
}
|
|
46909
|
+
async function getById(req, res, next) {
|
|
46910
|
+
const validation = Joi128.string().hex().required();
|
|
46911
|
+
const _id = req.params.id;
|
|
46912
|
+
const { error, value } = validation.validate(_id);
|
|
46913
|
+
if (error) {
|
|
46914
|
+
logger181.log({ level: "error", message: `${error.message}` });
|
|
46915
|
+
next(new BadRequestError202(error.message));
|
|
46916
|
+
return;
|
|
46917
|
+
}
|
|
46918
|
+
try {
|
|
46919
|
+
const user = await _getById(value);
|
|
46920
|
+
res.json(user);
|
|
46921
|
+
return;
|
|
46922
|
+
} catch (error2) {
|
|
46923
|
+
logger181.log({ level: "error", message: `${error2.message}` });
|
|
46924
|
+
next(error2);
|
|
46925
|
+
return;
|
|
46926
|
+
}
|
|
46927
|
+
}
|
|
46928
|
+
async function getByEmail(req, res, next) {
|
|
46929
|
+
const { error, value } = Joi128.string().email().required().validate(req.params.email);
|
|
46930
|
+
if (error)
|
|
46931
|
+
return rejectValidation(error, next);
|
|
46932
|
+
try {
|
|
46933
|
+
const user = await _getUserByEmail(value);
|
|
46934
|
+
res.json(user);
|
|
46935
|
+
return;
|
|
46936
|
+
} catch (err) {
|
|
46937
|
+
logger181.log({ level: "error", message: `${err.message}` });
|
|
46938
|
+
next(err);
|
|
46939
|
+
return;
|
|
46940
|
+
}
|
|
46941
|
+
}
|
|
46942
|
+
async function getUsers(req, res, next) {
|
|
46943
|
+
const { search = "", page = 1, limit = 10, sort = {}, type = "", status = "active" } = req.query;
|
|
46944
|
+
const { error, value } = Joi128.object({
|
|
46945
|
+
search: Joi128.string().optional().allow("", null),
|
|
46946
|
+
page: Joi128.number().integer().min(1).allow("", null).default(1),
|
|
46947
|
+
limit: Joi128.number().integer().min(1).allow("", null).default(10),
|
|
46948
|
+
sort: Joi128.object().optional().allow("", null).default({}),
|
|
46949
|
+
type: Joi128.string().optional().allow("", null).default(""),
|
|
46950
|
+
status: Joi128.string().optional().allow("", null).default("active" /* ACTIVE */)
|
|
46951
|
+
}).validate({ search, page, limit, sort, type, status });
|
|
46952
|
+
if (error)
|
|
46953
|
+
return rejectValidation(error, next);
|
|
46954
|
+
try {
|
|
46955
|
+
const users = await _getUsers({
|
|
46956
|
+
search: value.search ?? "",
|
|
46957
|
+
page: value.page,
|
|
46958
|
+
limit: value.limit,
|
|
46959
|
+
sort: value.sort,
|
|
46960
|
+
type: value.type,
|
|
46961
|
+
status: value.status
|
|
46962
|
+
});
|
|
46963
|
+
res.json(users);
|
|
46964
|
+
return;
|
|
46965
|
+
} catch (err) {
|
|
46966
|
+
next(err);
|
|
46967
|
+
}
|
|
46968
|
+
}
|
|
46969
|
+
async function getUsersByOrgId(req, res, next) {
|
|
46970
|
+
const { search, page, status, organization } = req.query;
|
|
46971
|
+
const { error, value } = Joi128.object({
|
|
46972
|
+
search: Joi128.string().optional().allow("", null),
|
|
46973
|
+
page: Joi128.number().integer().min(1).allow("", null).default(1),
|
|
46974
|
+
status: Joi128.string().required(),
|
|
46975
|
+
organization: Joi128.string().required()
|
|
46976
|
+
}).validate({ search, page, status, organization });
|
|
46977
|
+
if (error)
|
|
46978
|
+
return rejectValidation(error, next);
|
|
46979
|
+
try {
|
|
46980
|
+
res.json(
|
|
46981
|
+
await _getUsersByOrgId({
|
|
46982
|
+
search: value.search ?? "",
|
|
46983
|
+
page: value.page,
|
|
46984
|
+
status: value.status,
|
|
46985
|
+
organization: value.organization
|
|
46986
|
+
})
|
|
46987
|
+
);
|
|
46988
|
+
} catch (err) {
|
|
46989
|
+
next(err);
|
|
46990
|
+
}
|
|
46991
|
+
}
|
|
46487
46992
|
async function createUserByVerification(req, res, next) {
|
|
46488
|
-
const
|
|
46489
|
-
|
|
46993
|
+
const allowedTypes = ["user-sign-up" /* USER_SIGN_UP */, "user-invite" /* USER_INVITE */];
|
|
46994
|
+
const validation = Joi128.object({
|
|
46995
|
+
id: Joi128.string().hex().required(),
|
|
46490
46996
|
name: Joi128.string().required(),
|
|
46491
|
-
|
|
46492
|
-
|
|
46493
|
-
const { error, value } = schema2.validate({
|
|
46494
|
-
id: req.params.id,
|
|
46495
|
-
...req.body
|
|
46997
|
+
password: Joi128.string().required(),
|
|
46998
|
+
type: Joi128.string().required().valid(...allowedTypes)
|
|
46496
46999
|
});
|
|
47000
|
+
const id = req.params.id;
|
|
47001
|
+
const payload = { ...req.body };
|
|
47002
|
+
const { error, value } = validation.validate({ id, ...payload });
|
|
46497
47003
|
if (error) {
|
|
46498
|
-
|
|
46499
|
-
|
|
46500
|
-
next(new BadRequestError202(messages));
|
|
47004
|
+
logger181.log({ level: "error", message: `${error.message}` });
|
|
47005
|
+
next(new BadRequestError202(error.message));
|
|
46501
47006
|
return;
|
|
46502
47007
|
}
|
|
46503
|
-
const { id, name } = value;
|
|
46504
47008
|
try {
|
|
46505
|
-
await
|
|
47009
|
+
await createUserBySignUp({ id: value.id, name: value.name });
|
|
46506
47010
|
res.status(201).json({ message: "Successfully created account." });
|
|
46507
47011
|
return;
|
|
46508
47012
|
} catch (error2) {
|
|
@@ -46511,8 +47015,148 @@ function useUserControllerV2() {
|
|
|
46511
47015
|
return;
|
|
46512
47016
|
}
|
|
46513
47017
|
}
|
|
47018
|
+
async function updateUserProfile(req, res, next) {
|
|
47019
|
+
if (!req.file) {
|
|
47020
|
+
next(new BadRequestError202("File is required!"));
|
|
47021
|
+
return;
|
|
47022
|
+
}
|
|
47023
|
+
const validation = Joi128.object({
|
|
47024
|
+
previousProfile: Joi128.string().hex().optional().allow("", null)
|
|
47025
|
+
});
|
|
47026
|
+
const payload = { ...req.body };
|
|
47027
|
+
const { error, value } = validation.validate(payload);
|
|
47028
|
+
if (error) {
|
|
47029
|
+
logger181.log({ level: "error", message: `${error.message}` });
|
|
47030
|
+
next(new BadRequestError202(error.message));
|
|
47031
|
+
return;
|
|
47032
|
+
}
|
|
47033
|
+
const user = req.headers.user ?? "";
|
|
47034
|
+
try {
|
|
47035
|
+
await _updateUserProfile({
|
|
47036
|
+
file: req.file,
|
|
47037
|
+
user,
|
|
47038
|
+
...value
|
|
47039
|
+
});
|
|
47040
|
+
res.json({ message: "Successfully updated profile picture." });
|
|
47041
|
+
return;
|
|
47042
|
+
} catch (error2) {
|
|
47043
|
+
logger181.log({ level: "error", message: `${error2.message}` });
|
|
47044
|
+
next(error2);
|
|
47045
|
+
return;
|
|
47046
|
+
}
|
|
47047
|
+
}
|
|
47048
|
+
async function updateBirthday(req, res, next) {
|
|
47049
|
+
const MONTHS = [
|
|
47050
|
+
"January",
|
|
47051
|
+
"February",
|
|
47052
|
+
"March",
|
|
47053
|
+
"April",
|
|
47054
|
+
"May",
|
|
47055
|
+
"June",
|
|
47056
|
+
"July",
|
|
47057
|
+
"August",
|
|
47058
|
+
"September",
|
|
47059
|
+
"October",
|
|
47060
|
+
"November",
|
|
47061
|
+
"December"
|
|
47062
|
+
];
|
|
47063
|
+
const validation = Joi128.object({
|
|
47064
|
+
_id: Joi128.string().hex().required(),
|
|
47065
|
+
month: Joi128.string().valid(...MONTHS).required(),
|
|
47066
|
+
day: Joi128.number().integer().min(1).max(31).required(),
|
|
47067
|
+
year: Joi128.number().integer().min(1900).max((/* @__PURE__ */ new Date()).getFullYear()).required()
|
|
47068
|
+
});
|
|
47069
|
+
const _id = req.params.id;
|
|
47070
|
+
const payload = { ...req.body };
|
|
47071
|
+
const { error } = validation.validate({ _id, ...payload });
|
|
47072
|
+
if (error) {
|
|
47073
|
+
logger181.log({ level: "error", message: `${error.message}` });
|
|
47074
|
+
next(new BadRequestError202(error.message));
|
|
47075
|
+
return;
|
|
47076
|
+
}
|
|
47077
|
+
try {
|
|
47078
|
+
const message = await _updateBirthday({ _id, ...payload });
|
|
47079
|
+
res.json({ message });
|
|
47080
|
+
return;
|
|
47081
|
+
} catch (error2) {
|
|
47082
|
+
logger181.log({ level: "error", message: `${error2.message}` });
|
|
47083
|
+
next(error2);
|
|
47084
|
+
return;
|
|
47085
|
+
}
|
|
47086
|
+
}
|
|
47087
|
+
async function updateUserFieldById(req, res, next) {
|
|
47088
|
+
const FIELDS = ["name", "email", "contact", "nric", "dateOfBirth", "profile", "gender", "defaultOrg"];
|
|
47089
|
+
const validation = Joi128.object({
|
|
47090
|
+
_id: Joi128.string().hex().required(),
|
|
47091
|
+
field: Joi128.string().valid(...FIELDS).required(),
|
|
47092
|
+
value: Joi128.when("field", {
|
|
47093
|
+
switch: [
|
|
47094
|
+
{ is: "email", then: Joi128.string().email().required() },
|
|
47095
|
+
{ is: "defaultOrg", then: Joi128.string().hex().required() }
|
|
47096
|
+
],
|
|
47097
|
+
otherwise: Joi128.string().required()
|
|
47098
|
+
})
|
|
47099
|
+
});
|
|
47100
|
+
const _id = req.params.id;
|
|
47101
|
+
const payload = { ...req.body };
|
|
47102
|
+
const { error } = validation.validate({ _id, ...payload });
|
|
47103
|
+
if (error) {
|
|
47104
|
+
logger181.log({ level: "error", message: `${error.message}` });
|
|
47105
|
+
next(new BadRequestError202(error.message));
|
|
47106
|
+
return;
|
|
47107
|
+
}
|
|
47108
|
+
try {
|
|
47109
|
+
const message = await _updateUserFieldById({ _id, ...payload });
|
|
47110
|
+
res.json({ message });
|
|
47111
|
+
return;
|
|
47112
|
+
} catch (error2) {
|
|
47113
|
+
logger181.log({ level: "error", message: `${error2.message}` });
|
|
47114
|
+
next(error2);
|
|
47115
|
+
return;
|
|
47116
|
+
}
|
|
47117
|
+
}
|
|
47118
|
+
async function updatePasswordById(req, res, next) {
|
|
47119
|
+
const validation = Joi128.object({
|
|
47120
|
+
_id: Joi128.string().hex().required(),
|
|
47121
|
+
currentPassword: Joi128.string().required().min(8),
|
|
47122
|
+
newPassword: Joi128.string().required().min(8),
|
|
47123
|
+
passwordConfirmation: Joi128.string().required().min(8)
|
|
47124
|
+
});
|
|
47125
|
+
const _id = req.params.id;
|
|
47126
|
+
const payload = { ...req.body };
|
|
47127
|
+
const { error } = validation.validate({
|
|
47128
|
+
_id,
|
|
47129
|
+
...payload
|
|
47130
|
+
});
|
|
47131
|
+
if (error) {
|
|
47132
|
+
next(new BadRequestError202(error.message));
|
|
47133
|
+
return;
|
|
47134
|
+
}
|
|
47135
|
+
const currentPassword = req.body.currentPassword ?? "";
|
|
47136
|
+
const newPassword = req.body.newPassword ?? "";
|
|
47137
|
+
const passwordConfirmation = req.body.passwordConfirmation ?? "";
|
|
47138
|
+
try {
|
|
47139
|
+
await _updatePasswordById(
|
|
47140
|
+
_id,
|
|
47141
|
+
currentPassword,
|
|
47142
|
+
newPassword,
|
|
47143
|
+
passwordConfirmation
|
|
47144
|
+
);
|
|
47145
|
+
res.json({ message: "Successfully updated password." });
|
|
47146
|
+
} catch (error2) {
|
|
47147
|
+
next(error2);
|
|
47148
|
+
}
|
|
47149
|
+
}
|
|
46514
47150
|
return {
|
|
46515
|
-
|
|
47151
|
+
getById,
|
|
47152
|
+
getByEmail,
|
|
47153
|
+
getUsersByOrgId,
|
|
47154
|
+
getUsers,
|
|
47155
|
+
createUserByVerification,
|
|
47156
|
+
updateUserProfile,
|
|
47157
|
+
updateBirthday,
|
|
47158
|
+
updateUserFieldById,
|
|
47159
|
+
updatePasswordById
|
|
46516
47160
|
};
|
|
46517
47161
|
}
|
|
46518
47162
|
export {
|
|
@@ -46654,6 +47298,7 @@ export {
|
|
|
46654
47298
|
occurrence_book_namespace_collection,
|
|
46655
47299
|
orgSchema,
|
|
46656
47300
|
overnight_parking_requests_namespace_collection,
|
|
47301
|
+
parseDahuaFind,
|
|
46657
47302
|
pestDashboardCollection,
|
|
46658
47303
|
poolDashboardCollection,
|
|
46659
47304
|
promoCodeSchema,
|