@7365admin1/core 2.29.0 → 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 +6 -0
- package/dist/index.d.ts +139 -46
- package/dist/index.js +1122 -480
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1132 -490
- 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(),
|
|
@@ -45503,12 +45473,6 @@ function useVerificationRepoV2() {
|
|
|
45503
45473
|
err
|
|
45504
45474
|
);
|
|
45505
45475
|
});
|
|
45506
|
-
const cacheKey = makeCacheKey64(namespace_collection, { _id });
|
|
45507
|
-
delCache(cacheKey).then(() => {
|
|
45508
|
-
logger175.info(`Cache deleted for key: ${cacheKey}`);
|
|
45509
|
-
}).catch((err) => {
|
|
45510
|
-
logger175.error(`Failed to delete cache for key: ${cacheKey}`, err);
|
|
45511
|
-
});
|
|
45512
45476
|
return result;
|
|
45513
45477
|
} catch (error) {
|
|
45514
45478
|
throw new InternalServerError68("Error updating verification status.");
|
|
@@ -45924,9 +45888,12 @@ function useVerificationControllerV2() {
|
|
|
45924
45888
|
async function verify(req, res, next) {
|
|
45925
45889
|
try {
|
|
45926
45890
|
const schema2 = Joi126.object({ verificationCode: Joi126.string().required() });
|
|
45927
|
-
const { error, value } = schema2.validate(
|
|
45928
|
-
|
|
45929
|
-
|
|
45891
|
+
const { error, value } = schema2.validate(
|
|
45892
|
+
{
|
|
45893
|
+
verificationCode: req.params.verificationCode
|
|
45894
|
+
},
|
|
45895
|
+
{ abortEarly: false }
|
|
45896
|
+
);
|
|
45930
45897
|
if (error) {
|
|
45931
45898
|
const messages = error.details.map((d) => d.message).join(", ");
|
|
45932
45899
|
logger177.log({ level: "error", message: messages });
|
|
@@ -45952,7 +45919,7 @@ function useVerificationControllerV2() {
|
|
|
45952
45919
|
siteId: Joi126.string().hex().length(24).optional().allow("", null),
|
|
45953
45920
|
siteName: Joi126.string().optional().allow("", null)
|
|
45954
45921
|
});
|
|
45955
|
-
const { error, value } = schema2.validate(req.body);
|
|
45922
|
+
const { error, value } = schema2.validate(req.body, { abortEarly: false });
|
|
45956
45923
|
if (error) {
|
|
45957
45924
|
const messages = error.details.map((d) => d.message).join(", ");
|
|
45958
45925
|
logger177.log({ level: "error", message: messages });
|
|
@@ -45987,7 +45954,7 @@ function useVerificationControllerV2() {
|
|
|
45987
45954
|
siteId: Joi126.string().hex().length(24).required(),
|
|
45988
45955
|
siteName: Joi126.string().required()
|
|
45989
45956
|
});
|
|
45990
|
-
const { error, value } = schema2.validate(req.body);
|
|
45957
|
+
const { error, value } = schema2.validate(req.body, { abortEarly: false });
|
|
45991
45958
|
if (error) {
|
|
45992
45959
|
const messages = error.details.map((d) => d.message).join(", ");
|
|
45993
45960
|
logger177.log({ level: "error", message: messages });
|
|
@@ -46013,7 +45980,7 @@ function useVerificationControllerV2() {
|
|
|
46013
45980
|
const schema2 = Joi126.object({
|
|
46014
45981
|
email: Joi126.string().email().lowercase().required()
|
|
46015
45982
|
});
|
|
46016
|
-
const { error, value } = schema2.validate(req.body);
|
|
45983
|
+
const { error, value } = schema2.validate(req.body, { abortEarly: false });
|
|
46017
45984
|
if (error) {
|
|
46018
45985
|
const messages = error.details.map((d) => d.message).join(", ");
|
|
46019
45986
|
logger177.log({ level: "error", message: messages });
|
|
@@ -46043,7 +46010,7 @@ function useVerificationControllerV2() {
|
|
|
46043
46010
|
|
|
46044
46011
|
// src/controllers/auth-v2.controller.ts
|
|
46045
46012
|
import Joi127 from "joi";
|
|
46046
|
-
import { BadRequestError as
|
|
46013
|
+
import { BadRequestError as BadRequestError201, logger as logger180 } from "@7365admin1/node-server-utils";
|
|
46047
46014
|
|
|
46048
46015
|
// src/services/auth-v2.service.ts
|
|
46049
46016
|
import {
|
|
@@ -46056,11 +46023,13 @@ import {
|
|
|
46056
46023
|
import { v4 as uuidv42 } from "uuid";
|
|
46057
46024
|
|
|
46058
46025
|
// src/repositories/user-v2.repo.ts
|
|
46026
|
+
import { ObjectId as ObjectId123 } from "mongodb";
|
|
46059
46027
|
import {
|
|
46060
46028
|
useAtlas as useAtlas113,
|
|
46061
46029
|
InternalServerError as InternalServerError70,
|
|
46062
46030
|
logger as logger178,
|
|
46063
46031
|
BadRequestError as BadRequestError198,
|
|
46032
|
+
paginate as paginate58,
|
|
46064
46033
|
NotFoundError as NotFoundError52,
|
|
46065
46034
|
AppError as AppError27,
|
|
46066
46035
|
useCache as useCache67,
|
|
@@ -46077,6 +46046,7 @@ function useUserRepoV2() {
|
|
|
46077
46046
|
}
|
|
46078
46047
|
const namespace_collection = "users";
|
|
46079
46048
|
const collection = db.collection(namespace_collection);
|
|
46049
|
+
const { delNamespace, setCache, getCache, delCache } = useCache67(namespace_collection);
|
|
46080
46050
|
async function createIndex() {
|
|
46081
46051
|
try {
|
|
46082
46052
|
await collection.createIndexes([{ key: { email: 1 } }]);
|
|
@@ -46086,10 +46056,7 @@ function useUserRepoV2() {
|
|
|
46086
46056
|
}
|
|
46087
46057
|
async function createTextIndex() {
|
|
46088
46058
|
try {
|
|
46089
|
-
await collection.createIndex({
|
|
46090
|
-
name: "text",
|
|
46091
|
-
email: "text"
|
|
46092
|
-
});
|
|
46059
|
+
await collection.createIndex({ name: "text", email: "text" });
|
|
46093
46060
|
} catch (error) {
|
|
46094
46061
|
throw new InternalServerError70("Failed to create text index on user.");
|
|
46095
46062
|
}
|
|
@@ -46104,24 +46071,22 @@ function useUserRepoV2() {
|
|
|
46104
46071
|
throw new InternalServerError70("Failed to create unique index on user.");
|
|
46105
46072
|
}
|
|
46106
46073
|
}
|
|
46107
|
-
const { delNamespace, setCache, getCache, delCache } = useCache67(namespace_collection);
|
|
46108
46074
|
async function createUser(value, session) {
|
|
46109
46075
|
try {
|
|
46110
46076
|
value = MUser(value);
|
|
46111
46077
|
const res = await collection.insertOne(value, { session });
|
|
46112
|
-
delNamespace().then(
|
|
46113
|
-
logger178.info(`Cache cleared for namespace: ${namespace_collection}`)
|
|
46114
|
-
|
|
46115
|
-
logger178.error(
|
|
46078
|
+
delNamespace().then(
|
|
46079
|
+
() => logger178.info(`Cache cleared for namespace: ${namespace_collection}`)
|
|
46080
|
+
).catch(
|
|
46081
|
+
(err) => logger178.error(
|
|
46116
46082
|
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
46117
46083
|
err
|
|
46118
|
-
)
|
|
46119
|
-
|
|
46084
|
+
)
|
|
46085
|
+
);
|
|
46120
46086
|
return res.insertedId;
|
|
46121
46087
|
} catch (error) {
|
|
46122
46088
|
logger178.log({ level: "error", message: `${error}` });
|
|
46123
|
-
|
|
46124
|
-
if (isDuplicated) {
|
|
46089
|
+
if (error.message.includes("duplicate")) {
|
|
46125
46090
|
throw new BadRequestError198("User already exists.");
|
|
46126
46091
|
}
|
|
46127
46092
|
throw error;
|
|
@@ -46138,11 +46103,9 @@ function useUserRepoV2() {
|
|
|
46138
46103
|
const data = await collection.findOne({
|
|
46139
46104
|
email: { $regex: `^${email}$`, $options: "i" }
|
|
46140
46105
|
});
|
|
46141
|
-
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
46142
|
-
logger178.
|
|
46143
|
-
|
|
46144
|
-
logger178.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
46145
|
-
});
|
|
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
|
+
);
|
|
46146
46109
|
return data;
|
|
46147
46110
|
} catch (error) {
|
|
46148
46111
|
throw new InternalServerError70("Failed to get user by email.");
|
|
@@ -46150,26 +46113,22 @@ function useUserRepoV2() {
|
|
|
46150
46113
|
}
|
|
46151
46114
|
async function getUserByEmailStatus(email) {
|
|
46152
46115
|
try {
|
|
46153
|
-
const
|
|
46116
|
+
const cacheKey = makeCacheKey65(namespace_collection, {
|
|
46154
46117
|
email,
|
|
46155
46118
|
status: "complete" /* COMPLETE */
|
|
46156
|
-
};
|
|
46157
|
-
const cacheKey = makeCacheKey65(namespace_collection, cacheOptions);
|
|
46119
|
+
});
|
|
46158
46120
|
const cachedData = await getCache(cacheKey);
|
|
46159
46121
|
if (cachedData) {
|
|
46160
46122
|
logger178.info(`Cache hit for key: ${cacheKey}`);
|
|
46161
46123
|
return cachedData;
|
|
46162
46124
|
}
|
|
46163
|
-
const
|
|
46125
|
+
const data = await collection.findOne({
|
|
46164
46126
|
email: { $regex: `^${email}$`, $options: "i" },
|
|
46165
46127
|
status: "complete" /* COMPLETE */
|
|
46166
|
-
};
|
|
46167
|
-
const data = await collection.findOne(query);
|
|
46168
|
-
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
46169
|
-
logger178.info(`Cache set for key: ${cacheKey}`);
|
|
46170
|
-
}).catch((err) => {
|
|
46171
|
-
logger178.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
46172
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
|
+
);
|
|
46173
46132
|
return data;
|
|
46174
46133
|
} catch (error) {
|
|
46175
46134
|
throw new InternalServerError70("Failed to get user by email.");
|
|
@@ -46192,17 +46151,10 @@ function useUserRepoV2() {
|
|
|
46192
46151
|
let: { userOrgId: "$defaultOrg" },
|
|
46193
46152
|
pipeline: [
|
|
46194
46153
|
{
|
|
46195
|
-
$match: {
|
|
46196
|
-
$expr: { $eq: ["$orgId", "$$userOrgId"] }
|
|
46197
|
-
}
|
|
46154
|
+
$match: { $expr: { $eq: ["$orgId", "$$userOrgId"] } }
|
|
46198
46155
|
},
|
|
46199
46156
|
{
|
|
46200
|
-
$project: {
|
|
46201
|
-
_id: 1,
|
|
46202
|
-
name: 1,
|
|
46203
|
-
type: 1,
|
|
46204
|
-
siteId: 1
|
|
46205
|
-
}
|
|
46157
|
+
$project: { _id: 1, name: 1, type: 1, siteId: 1 }
|
|
46206
46158
|
}
|
|
46207
46159
|
],
|
|
46208
46160
|
as: "serviceProviders"
|
|
@@ -46210,9 +46162,117 @@ function useUserRepoV2() {
|
|
|
46210
46162
|
}
|
|
46211
46163
|
]).toArray();
|
|
46212
46164
|
const data = results.length > 0 ? results[0] : null;
|
|
46213
|
-
if (!data)
|
|
46165
|
+
if (!data)
|
|
46214
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;
|
|
46215
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);
|
|
46216
46276
|
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
46217
46277
|
logger178.info(`Cache set for key: ${cacheKey}`);
|
|
46218
46278
|
}).catch((err) => {
|
|
@@ -46220,12 +46280,197 @@ function useUserRepoV2() {
|
|
|
46220
46280
|
});
|
|
46221
46281
|
return data;
|
|
46222
46282
|
} catch (error) {
|
|
46223
|
-
|
|
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) {
|
|
46224
46396
|
throw error;
|
|
46225
|
-
} else {
|
|
46226
|
-
throw new InternalServerError70("Failed to get user by email.");
|
|
46227
46397
|
}
|
|
46228
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
|
+
}
|
|
46229
46474
|
}
|
|
46230
46475
|
return {
|
|
46231
46476
|
createIndex,
|
|
@@ -46234,7 +46479,13 @@ function useUserRepoV2() {
|
|
|
46234
46479
|
createUser,
|
|
46235
46480
|
getUserByEmail,
|
|
46236
46481
|
getUserByEmailStatus,
|
|
46237
|
-
getUserById
|
|
46482
|
+
getUserById,
|
|
46483
|
+
getUsers,
|
|
46484
|
+
getUsersByOrgId,
|
|
46485
|
+
updatePasswordById,
|
|
46486
|
+
updateUserFieldById,
|
|
46487
|
+
updateBirthday,
|
|
46488
|
+
updatePassword
|
|
46238
46489
|
};
|
|
46239
46490
|
}
|
|
46240
46491
|
|
|
@@ -46301,10 +46552,220 @@ function useAuthServiceV2() {
|
|
|
46301
46552
|
};
|
|
46302
46553
|
}
|
|
46303
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
|
+
|
|
46304
46764
|
// src/controllers/auth-v2.controller.ts
|
|
46305
46765
|
function useAuthControllerV2() {
|
|
46306
46766
|
const { signUp: _signUp } = useVerificationServiceV2();
|
|
46307
46767
|
const { login: _login, logout: _logout } = useAuthServiceV2();
|
|
46768
|
+
const { resetPassword: _resetPassword } = useUserServiceV2();
|
|
46308
46769
|
async function signUp(req, res, next) {
|
|
46309
46770
|
try {
|
|
46310
46771
|
const validation = Joi127.object({
|
|
@@ -46318,8 +46779,8 @@ function useAuthControllerV2() {
|
|
|
46318
46779
|
});
|
|
46319
46780
|
if (error) {
|
|
46320
46781
|
const messages = error.details.map((d) => d.message);
|
|
46321
|
-
|
|
46322
|
-
next(new
|
|
46782
|
+
logger180.log({ level: "error", message: messages.join(", ") });
|
|
46783
|
+
next(new BadRequestError201(messages.join(", ")));
|
|
46323
46784
|
return;
|
|
46324
46785
|
}
|
|
46325
46786
|
const { email, password, country, orgName } = value;
|
|
@@ -46335,7 +46796,7 @@ function useAuthControllerV2() {
|
|
|
46335
46796
|
return;
|
|
46336
46797
|
} catch (error) {
|
|
46337
46798
|
console.log(error);
|
|
46338
|
-
|
|
46799
|
+
logger180.log({ level: "error", message: error.message });
|
|
46339
46800
|
next(error);
|
|
46340
46801
|
return;
|
|
46341
46802
|
}
|
|
@@ -46353,8 +46814,8 @@ function useAuthControllerV2() {
|
|
|
46353
46814
|
});
|
|
46354
46815
|
if (error) {
|
|
46355
46816
|
const messages = error.details.map((d) => d.message);
|
|
46356
|
-
|
|
46357
|
-
next(new
|
|
46817
|
+
logger180.log({ level: "error", message: messages.join(", ") });
|
|
46818
|
+
next(new BadRequestError201(messages.join(", ")));
|
|
46358
46819
|
return;
|
|
46359
46820
|
}
|
|
46360
46821
|
const session = await _login(value);
|
|
@@ -46366,7 +46827,7 @@ function useAuthControllerV2() {
|
|
|
46366
46827
|
res.cookie("sid", session.sid, cookieOptions).cookie("user", session.user, cookieOptions).json(session);
|
|
46367
46828
|
return;
|
|
46368
46829
|
} catch (error) {
|
|
46369
|
-
|
|
46830
|
+
logger180.log({ level: "error", message: error.message });
|
|
46370
46831
|
next(error);
|
|
46371
46832
|
return;
|
|
46372
46833
|
}
|
|
@@ -46374,7 +46835,7 @@ function useAuthControllerV2() {
|
|
|
46374
46835
|
async function logout(req, res, next) {
|
|
46375
46836
|
const sid = req.headers["authorization"] ?? "";
|
|
46376
46837
|
if (!sid) {
|
|
46377
|
-
next(new
|
|
46838
|
+
next(new BadRequestError201("Session ID is required"));
|
|
46378
46839
|
return;
|
|
46379
46840
|
}
|
|
46380
46841
|
try {
|
|
@@ -46382,130 +46843,170 @@ function useAuthControllerV2() {
|
|
|
46382
46843
|
res.json({ message: "Logged out successfully" });
|
|
46383
46844
|
return;
|
|
46384
46845
|
} catch (error) {
|
|
46385
|
-
|
|
46846
|
+
logger180.log({ level: "error", message: error.message });
|
|
46386
46847
|
next(error);
|
|
46387
46848
|
return;
|
|
46388
46849
|
}
|
|
46389
46850
|
}
|
|
46390
|
-
|
|
46391
|
-
|
|
46392
|
-
|
|
46393
|
-
|
|
46394
|
-
|
|
46395
|
-
}
|
|
46396
|
-
|
|
46397
|
-
|
|
46398
|
-
|
|
46399
|
-
|
|
46400
|
-
|
|
46401
|
-
|
|
46402
|
-
|
|
46403
|
-
|
|
46404
|
-
|
|
46405
|
-
|
|
46406
|
-
const { add: addMember } = useMemberRepo();
|
|
46407
|
-
const { getById: getOrgById } = useOrgRepo();
|
|
46408
|
-
const { getSiteById } = useSiteRepo();
|
|
46409
|
-
const {
|
|
46410
|
-
getVerificationById: _getVerificationById,
|
|
46411
|
-
updateVerificationStatusById: _updateVerificationStatusById
|
|
46412
|
-
} = useVerificationRepoV2();
|
|
46413
|
-
const { verify } = useVerificationService();
|
|
46414
|
-
const { createFile, deleteFileById } = useFileRepo();
|
|
46415
|
-
async function createUserBySignUp({
|
|
46416
|
-
id = "",
|
|
46417
|
-
name = ""
|
|
46418
|
-
}) {
|
|
46419
|
-
const session = useAtlas114.getClient()?.startSession();
|
|
46420
|
-
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;
|
|
46421
46867
|
try {
|
|
46422
|
-
const
|
|
46423
|
-
|
|
46424
|
-
|
|
46425
|
-
|
|
46426
|
-
throw new BadRequestError201(
|
|
46427
|
-
"You have already an account created using this link."
|
|
46428
|
-
);
|
|
46429
|
-
const expired = signUp.expireAt < (/* @__PURE__ */ new Date()).toISOString();
|
|
46430
|
-
if (signUp.status === "expired" || expired)
|
|
46431
|
-
throw new BadRequestError201("Sign up link expired.");
|
|
46432
|
-
const email = signUp.email;
|
|
46433
|
-
const _user = await getUserByEmail(email);
|
|
46434
|
-
if (_user)
|
|
46435
|
-
throw new BadRequestError201(`User already exists: ${email}.`);
|
|
46436
|
-
let org = null;
|
|
46437
|
-
if (signUp.metadata?.org) {
|
|
46438
|
-
org = await getOrgById(signUp.metadata.org);
|
|
46439
|
-
if (!org)
|
|
46440
|
-
signUp.metadata.org = "";
|
|
46441
|
-
}
|
|
46442
|
-
if (signUp.metadata?.siteId)
|
|
46443
|
-
await getSiteById(signUp.metadata?.siteId);
|
|
46444
|
-
const user = {
|
|
46445
|
-
email,
|
|
46446
|
-
password: signUp.metadata?.password,
|
|
46447
|
-
name,
|
|
46448
|
-
defaultOrg: org?._id?.toString() || ""
|
|
46449
|
-
};
|
|
46450
|
-
const userId = await _createUser(user, session);
|
|
46451
|
-
if (org?._id) {
|
|
46452
|
-
await addMember(
|
|
46453
|
-
{
|
|
46454
|
-
org: org?._id?.toString() || "",
|
|
46455
|
-
orgName: org?.name || "",
|
|
46456
|
-
user: userId.toString(),
|
|
46457
|
-
name,
|
|
46458
|
-
role: signUp.metadata?.role?.toString() || "",
|
|
46459
|
-
type: signUp.metadata?.app ?? "organization",
|
|
46460
|
-
siteId: signUp.metadata?.siteId?.toString() || "",
|
|
46461
|
-
siteName: signUp.metadata?.siteName || ""
|
|
46462
|
-
},
|
|
46463
|
-
session
|
|
46464
|
-
);
|
|
46465
|
-
}
|
|
46466
|
-
await _updateVerificationStatusById(
|
|
46467
|
-
id,
|
|
46468
|
-
"complete" /* COMPLETE */,
|
|
46469
|
-
session
|
|
46868
|
+
const message = await _resetPassword(
|
|
46869
|
+
otp,
|
|
46870
|
+
newPassword,
|
|
46871
|
+
passwordConfirmation
|
|
46470
46872
|
);
|
|
46471
|
-
|
|
46472
|
-
return
|
|
46473
|
-
} catch (
|
|
46474
|
-
|
|
46475
|
-
|
|
46476
|
-
|
|
46477
|
-
session?.endSession();
|
|
46873
|
+
res.json({ message });
|
|
46874
|
+
return;
|
|
46875
|
+
} catch (error2) {
|
|
46876
|
+
logger180.log({ level: "error", message: error2.message });
|
|
46877
|
+
next(error2);
|
|
46878
|
+
return;
|
|
46478
46879
|
}
|
|
46479
46880
|
}
|
|
46480
46881
|
return {
|
|
46481
|
-
|
|
46882
|
+
signUp,
|
|
46883
|
+
login,
|
|
46884
|
+
logout,
|
|
46885
|
+
resetPassword
|
|
46482
46886
|
};
|
|
46483
46887
|
}
|
|
46484
46888
|
|
|
46485
46889
|
// src/controllers/user-v2.controller.ts
|
|
46486
46890
|
import Joi128 from "joi";
|
|
46891
|
+
import "multer";
|
|
46487
46892
|
import { BadRequestError as BadRequestError202, logger as logger181 } from "@7365admin1/node-server-utils";
|
|
46488
46893
|
function useUserControllerV2() {
|
|
46489
|
-
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
|
+
}
|
|
46490
46992
|
async function createUserByVerification(req, res, next) {
|
|
46491
|
-
const
|
|
46492
|
-
|
|
46993
|
+
const allowedTypes = ["user-sign-up" /* USER_SIGN_UP */, "user-invite" /* USER_INVITE */];
|
|
46994
|
+
const validation = Joi128.object({
|
|
46995
|
+
id: Joi128.string().hex().required(),
|
|
46493
46996
|
name: Joi128.string().required(),
|
|
46494
|
-
|
|
46495
|
-
|
|
46496
|
-
const { error, value } = schema2.validate({
|
|
46497
|
-
id: req.params.id,
|
|
46498
|
-
...req.body
|
|
46997
|
+
password: Joi128.string().required(),
|
|
46998
|
+
type: Joi128.string().required().valid(...allowedTypes)
|
|
46499
46999
|
});
|
|
47000
|
+
const id = req.params.id;
|
|
47001
|
+
const payload = { ...req.body };
|
|
47002
|
+
const { error, value } = validation.validate({ id, ...payload });
|
|
46500
47003
|
if (error) {
|
|
46501
|
-
|
|
46502
|
-
|
|
46503
|
-
next(new BadRequestError202(messages));
|
|
47004
|
+
logger181.log({ level: "error", message: `${error.message}` });
|
|
47005
|
+
next(new BadRequestError202(error.message));
|
|
46504
47006
|
return;
|
|
46505
47007
|
}
|
|
46506
|
-
const { id, name } = value;
|
|
46507
47008
|
try {
|
|
46508
|
-
await
|
|
47009
|
+
await createUserBySignUp({ id: value.id, name: value.name });
|
|
46509
47010
|
res.status(201).json({ message: "Successfully created account." });
|
|
46510
47011
|
return;
|
|
46511
47012
|
} catch (error2) {
|
|
@@ -46514,8 +47015,148 @@ function useUserControllerV2() {
|
|
|
46514
47015
|
return;
|
|
46515
47016
|
}
|
|
46516
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
|
+
}
|
|
46517
47150
|
return {
|
|
46518
|
-
|
|
47151
|
+
getById,
|
|
47152
|
+
getByEmail,
|
|
47153
|
+
getUsersByOrgId,
|
|
47154
|
+
getUsers,
|
|
47155
|
+
createUserByVerification,
|
|
47156
|
+
updateUserProfile,
|
|
47157
|
+
updateBirthday,
|
|
47158
|
+
updateUserFieldById,
|
|
47159
|
+
updatePasswordById
|
|
46519
47160
|
};
|
|
46520
47161
|
}
|
|
46521
47162
|
export {
|
|
@@ -46657,6 +47298,7 @@ export {
|
|
|
46657
47298
|
occurrence_book_namespace_collection,
|
|
46658
47299
|
orgSchema,
|
|
46659
47300
|
overnight_parking_requests_namespace_collection,
|
|
47301
|
+
parseDahuaFind,
|
|
46660
47302
|
pestDashboardCollection,
|
|
46661
47303
|
poolDashboardCollection,
|
|
46662
47304
|
promoCodeSchema,
|