@7365admin1/core 3.51.1-staging.228 → 3.52.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 +73 -0
- package/dist/index.js +72 -38
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1160 -1125
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/test/hid-secret.util.test.mjs +98 -0
- package/.changeset/camera-edit-audit-trail.md +0 -16
- package/.changeset/camera-health-decouple-from-wall-cap.md +0 -17
- package/.changeset/hid-face-photo-retention.md +0 -9
- package/.changeset/site-camera-bulk-import.md +0 -14
- package/.changeset/site-camera-direction-valid.md +0 -15
- package/.changeset/visitor-guest-status-filter.md +0 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,78 @@
|
|
|
1
1
|
# @iservice365/core
|
|
2
2
|
|
|
3
|
+
## 3.52.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- bd4bd88: Add a bulk camera import on the existing guided path.
|
|
8
|
+
|
|
9
|
+
`POST /api/site-cameras/bulk` accepts a site and up to 200 rows from the
|
|
10
|
+
technician survey sheet, derives each camera's relay address from its recorder
|
|
11
|
+
and channel number, and returns a per-row result. `commit: false` previews and
|
|
12
|
+
writes nothing; `commit: true` writes the rows that passed. Rows that are ANPR,
|
|
13
|
+
that carry a hand-written address, or whose channel is outside 1-256 are refused
|
|
14
|
+
by name, and a camera already at the site is reported as a duplicate rather than
|
|
15
|
+
as a write error. Creates `type: "ip"` cameras only and needs the same write
|
|
16
|
+
gate as the single-camera form.
|
|
17
|
+
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
- 5af369c: Record who added, changed or removed a camera.
|
|
21
|
+
|
|
22
|
+
"Who changed this camera's address, and when" had no answer anywhere in the system: a camera record
|
|
23
|
+
carries `createdAt`/`updatedAt` and no actor, and a write overwrites the previous `host` in place. At
|
|
24
|
+
Seventh Condominium that turned a one-line port correction into nine days.
|
|
25
|
+
|
|
26
|
+
`add`, `updateById` and `deleteById` on site cameras now append a row to the existing append-only
|
|
27
|
+
`console-audit` collection, with the actor from the session, the camera id, and `before`/`after`
|
|
28
|
+
values drawn from a per-action allow-list. No schema changes, no migration, and no new collection.
|
|
29
|
+
|
|
30
|
+
The allow-list is the boundary that matters: a camera document holds a device credential, and
|
|
31
|
+
`username` and `password` are not on it. `loadForWrite` still never reads them.
|
|
32
|
+
|
|
33
|
+
- 16a9105: Decouple the camera health sweep from the wall's tile ceiling.
|
|
34
|
+
|
|
35
|
+
`getSiteHealth` sliced its input to `maxTiles` (9), so a health request covering a 150-camera site
|
|
36
|
+
answered for the first nine cameras and said nothing at all about the other 141 — and did not report
|
|
37
|
+
that it had shortened the list. No client could build a site-wide "which of my cameras is down" view,
|
|
38
|
+
however it asked.
|
|
39
|
+
|
|
40
|
+
Health is now bounded by its own `maxHealthCameras` (`CAMERA_HEALTH_MAX_CAMERAS`, default 200), and a
|
|
41
|
+
request past that cap comes back with `requested` / `returned` / `truncated` instead of a quietly
|
|
42
|
+
partial list. The device fan-out is unchanged: `maxConcurrentProbes` still bounds probes in flight at
|
|
43
|
+
4, the reachability probe is still cached per recorder, and `probeCamera` still reads a cached device
|
|
44
|
+
probe rather than making a fresh one — so a 150-camera sweep costs a recorder no more than a 9-camera
|
|
45
|
+
one after the first pass.
|
|
46
|
+
|
|
47
|
+
- 398b374: HID Amico: stop silently deriving the credential encryption key from
|
|
48
|
+
ACCESS_TOKEN_SECRET. Reading still accepts the legacy key so existing credentials
|
|
49
|
+
keep working (and now logs an error saying so), but writing a new credential
|
|
50
|
+
refuses with a message naming HID_AMICO_SECRET, so a later rotation of the JWT
|
|
51
|
+
signing secret cannot orphan credentials that were written after this.
|
|
52
|
+
- 8113e31: HID face registration: never retain the captured photo. Identity `metadata` is stripped of
|
|
53
|
+
`photo` and of any inline `data:image/...` value on every write, and reader notification
|
|
54
|
+
payloads (`user_image`, `access_photo`) are redacted of image data before they are persisted
|
|
55
|
+
as audit events. Enrollment state (`facialEnrolled`, `facialEnrolledAt`, `facialData`,
|
|
56
|
+
`imageTimestamp`) is unchanged.
|
|
57
|
+
- b097964: Constrain a site camera's `direction` to a fixed set instead of accepting any string.
|
|
58
|
+
|
|
59
|
+
`Joi.string().allow("entry", "exit", "both", "none")` reads like a whitelist but is not one — on a
|
|
60
|
+
validator that already accepts every non-empty string, `.allow()` only adds permitted values, so the
|
|
61
|
+
field rejected nothing. It is now `.valid()`.
|
|
62
|
+
|
|
63
|
+
The accepted set is `entry | exit | both | none | visitors | residents`: the four values the staging
|
|
64
|
+
collection actually holds (measured read-only across all 22 rows), plus the two extra options
|
|
65
|
+
layer-common's live `CameraForm.vue` offers for ANPR cameras. No stored camera and no reachable form
|
|
66
|
+
is refused. Whether `visitors` and `residents` are directions at all is a product question; dropping
|
|
67
|
+
them later is a zero-row migration.
|
|
68
|
+
|
|
69
|
+
- Visitor list: decide the Guests tab by "every requested status is pre-arrival"
|
|
70
|
+
instead of matching one specific status set, so the tab keeps filtering on the
|
|
71
|
+
expected arrival date for both the approved+pending request sent by
|
|
72
|
+
layer-common `main` and the approved+pending+rejected request sent by
|
|
73
|
+
layer-common `staging` (DV-0080). Extracted as `isPreCheckInStatusOnly` with
|
|
74
|
+
tests pinning each case.
|
|
75
|
+
|
|
3
76
|
## 3.51.0
|
|
4
77
|
|
|
5
78
|
### Minor Changes
|
package/dist/index.js
CHANGED
|
@@ -536,13 +536,13 @@ var require_logger = __commonJS({
|
|
|
536
536
|
"use strict";
|
|
537
537
|
exports.__esModule = true;
|
|
538
538
|
var _utils = require_utils();
|
|
539
|
-
var
|
|
539
|
+
var logger220 = {
|
|
540
540
|
methodMap: ["debug", "info", "warn", "error"],
|
|
541
541
|
level: "info",
|
|
542
542
|
// Maps a given level value to the `methodMap` indexes above.
|
|
543
543
|
lookupLevel: function lookupLevel(level) {
|
|
544
544
|
if (typeof level === "string") {
|
|
545
|
-
var levelMap = _utils.indexOf(
|
|
545
|
+
var levelMap = _utils.indexOf(logger220.methodMap, level.toLowerCase());
|
|
546
546
|
if (levelMap >= 0) {
|
|
547
547
|
level = levelMap;
|
|
548
548
|
} else {
|
|
@@ -553,9 +553,9 @@ var require_logger = __commonJS({
|
|
|
553
553
|
},
|
|
554
554
|
// Can be overridden in the host environment
|
|
555
555
|
log: function log(level) {
|
|
556
|
-
level =
|
|
557
|
-
if (typeof console !== "undefined" &&
|
|
558
|
-
var method =
|
|
556
|
+
level = logger220.lookupLevel(level);
|
|
557
|
+
if (typeof console !== "undefined" && logger220.lookupLevel(logger220.level) <= level) {
|
|
558
|
+
var method = logger220.methodMap[level];
|
|
559
559
|
if (!console[method]) {
|
|
560
560
|
method = "log";
|
|
561
561
|
}
|
|
@@ -566,7 +566,7 @@ var require_logger = __commonJS({
|
|
|
566
566
|
}
|
|
567
567
|
}
|
|
568
568
|
};
|
|
569
|
-
exports["default"] =
|
|
569
|
+
exports["default"] = logger220;
|
|
570
570
|
module2.exports = exports["default"];
|
|
571
571
|
}
|
|
572
572
|
});
|
|
@@ -43973,7 +43973,7 @@ var VALID_STATUSES = /* @__PURE__ */ new Set([
|
|
|
43973
43973
|
]);
|
|
43974
43974
|
|
|
43975
43975
|
// src/services/hid-amico.service.ts
|
|
43976
|
-
var
|
|
43976
|
+
var import_crypto3 = __toESM(require("crypto"));
|
|
43977
43977
|
var import_axios = __toESM(require("axios"));
|
|
43978
43978
|
var import_node_server_utils133 = require("@7365admin1/node-server-utils");
|
|
43979
43979
|
|
|
@@ -45927,6 +45927,31 @@ function stringifyHidJson(value) {
|
|
|
45927
45927
|
);
|
|
45928
45928
|
}
|
|
45929
45929
|
|
|
45930
|
+
// src/utils/hid-secret.util.ts
|
|
45931
|
+
var import_crypto2 = __toESM(require("crypto"));
|
|
45932
|
+
var HID_SECRET_ENV = "HID_AMICO_SECRET";
|
|
45933
|
+
var HID_LEGACY_SECRET_ENV = "ACCESS_TOKEN_SECRET";
|
|
45934
|
+
var HID_SECRET_MISSING_FOR_WRITE = `${HID_SECRET_ENV} is not configured, so a new HID credential cannot be encrypted. Set ${HID_SECRET_ENV} on this service and try again. It is deliberately NOT falling back to ${HID_LEGACY_SECRET_ENV}: that key is rotated independently, and anything encrypted with it becomes permanently unreadable the moment it is.`;
|
|
45935
|
+
var HID_SECRET_MISSING_ENTIRELY = `Neither ${HID_SECRET_ENV} nor ${HID_LEGACY_SECRET_ENV} is configured, so stored HID credentials cannot be decrypted. Set ${HID_SECRET_ENV} on this service.`;
|
|
45936
|
+
var HID_SECRET_LEGACY_FALLBACK_IN_USE = `${HID_SECRET_ENV} is not configured. Stored HID credentials are being decrypted with ${HID_LEGACY_SECRET_ENV}, which is rotated independently \u2014 when it is rotated they become permanently unreadable. Set ${HID_SECRET_ENV} and re-save the affected HID readers and SIP accounts.`;
|
|
45937
|
+
function resolveHidSecretKey(purpose, env2 = process.env) {
|
|
45938
|
+
const dedicated = env2[HID_SECRET_ENV];
|
|
45939
|
+
if (dedicated) {
|
|
45940
|
+
return { key: deriveKey(dedicated), usedLegacyFallback: false };
|
|
45941
|
+
}
|
|
45942
|
+
if (purpose === "encrypt") {
|
|
45943
|
+
throw new Error(HID_SECRET_MISSING_FOR_WRITE);
|
|
45944
|
+
}
|
|
45945
|
+
const legacy = env2[HID_LEGACY_SECRET_ENV];
|
|
45946
|
+
if (!legacy) {
|
|
45947
|
+
throw new Error(HID_SECRET_MISSING_ENTIRELY);
|
|
45948
|
+
}
|
|
45949
|
+
return { key: deriveKey(legacy), usedLegacyFallback: true };
|
|
45950
|
+
}
|
|
45951
|
+
function deriveKey(secret) {
|
|
45952
|
+
return import_crypto2.default.createHash("sha256").update(secret).digest();
|
|
45953
|
+
}
|
|
45954
|
+
|
|
45930
45955
|
// src/services/hid-amico.service.ts
|
|
45931
45956
|
var PASSWORD_PREFIX = "v1";
|
|
45932
45957
|
var HID_READER_NOT_FOUND = "HID Amico reader not found.";
|
|
@@ -46047,14 +46072,22 @@ function sanitizeHidObjectPayload(object, value) {
|
|
|
46047
46072
|
};
|
|
46048
46073
|
return redactValue(sanitized);
|
|
46049
46074
|
}
|
|
46050
|
-
|
|
46051
|
-
|
|
46052
|
-
|
|
46053
|
-
|
|
46054
|
-
|
|
46055
|
-
|
|
46075
|
+
var reportedLegacyHidSecret = false;
|
|
46076
|
+
function getSecretKey(purpose) {
|
|
46077
|
+
try {
|
|
46078
|
+
const { key, usedLegacyFallback } = resolveHidSecretKey(purpose);
|
|
46079
|
+
if (usedLegacyFallback && !reportedLegacyHidSecret) {
|
|
46080
|
+
reportedLegacyHidSecret = true;
|
|
46081
|
+
import_node_server_utils133.logger.error({
|
|
46082
|
+
operation: "hid-amico:getSecretKey",
|
|
46083
|
+
message: HID_SECRET_LEGACY_FALLBACK_IN_USE
|
|
46084
|
+
});
|
|
46085
|
+
}
|
|
46086
|
+
return key;
|
|
46087
|
+
} catch (error) {
|
|
46088
|
+
import_node_server_utils133.logger.error({ operation: "hid-amico:getSecretKey", purpose, message: error.message });
|
|
46089
|
+
throw new import_node_server_utils133.InternalServerError(error.message);
|
|
46056
46090
|
}
|
|
46057
|
-
return import_crypto2.default.createHash("sha256").update(secret).digest();
|
|
46058
46091
|
}
|
|
46059
46092
|
function getReaderCapabilities(readerModel, firmwareVersion) {
|
|
46060
46093
|
const isAmicoBiometricReader2 = readerModel === "VL35LF" || readerModel === "VL70LF";
|
|
@@ -46120,8 +46153,8 @@ function getPublicMonitorConfiguration(monitor, callbackToken) {
|
|
|
46120
46153
|
};
|
|
46121
46154
|
}
|
|
46122
46155
|
function encryptSecret(value) {
|
|
46123
|
-
const iv =
|
|
46124
|
-
const cipher =
|
|
46156
|
+
const iv = import_crypto3.default.randomBytes(12);
|
|
46157
|
+
const cipher = import_crypto3.default.createCipheriv("aes-256-gcm", getSecretKey("encrypt"), iv);
|
|
46125
46158
|
const encrypted = Buffer.concat([cipher.update(value, "utf8"), cipher.final()]);
|
|
46126
46159
|
const tag = cipher.getAuthTag();
|
|
46127
46160
|
return [PASSWORD_PREFIX, iv.toString("hex"), tag.toString("hex"), encrypted.toString("hex")].join(":");
|
|
@@ -46130,9 +46163,10 @@ function decryptSecret(value) {
|
|
|
46130
46163
|
if (!value?.startsWith(`${PASSWORD_PREFIX}:`)) {
|
|
46131
46164
|
return value;
|
|
46132
46165
|
}
|
|
46166
|
+
const key = getSecretKey("decrypt");
|
|
46133
46167
|
try {
|
|
46134
46168
|
const [, ivHex, tagHex, encryptedHex] = value.split(":");
|
|
46135
|
-
const decipher =
|
|
46169
|
+
const decipher = import_crypto3.default.createDecipheriv("aes-256-gcm", key, Buffer.from(ivHex, "hex"));
|
|
46136
46170
|
decipher.setAuthTag(Buffer.from(tagHex, "hex"));
|
|
46137
46171
|
return Buffer.concat([
|
|
46138
46172
|
decipher.update(Buffer.from(encryptedHex, "hex")),
|
|
@@ -46172,7 +46206,7 @@ function normalizeHidReaderBaseUrl(value) {
|
|
|
46172
46206
|
return endpoint.origin;
|
|
46173
46207
|
}
|
|
46174
46208
|
function createStableHidId(seed) {
|
|
46175
|
-
const bytes =
|
|
46209
|
+
const bytes = import_crypto3.default.createHash("sha256").update(seed).digest().subarray(0, 6);
|
|
46176
46210
|
return Number.parseInt(bytes.toString("hex"), 16) || 1;
|
|
46177
46211
|
}
|
|
46178
46212
|
function isUnknownRecord2(value) {
|
|
@@ -46247,7 +46281,7 @@ function resolveProfileIdentityType(memberType, userType) {
|
|
|
46247
46281
|
var VISITOR_QR_FORMAT = "0";
|
|
46248
46282
|
function createVisitorQrCredential(visitorId, readerId, qrValue) {
|
|
46249
46283
|
const credentialId = createStableHidId(`visitor-qr:${readerId}:${visitorId}`);
|
|
46250
|
-
const token = qrValue || `VIS${
|
|
46284
|
+
const token = qrValue || `VIS${import_crypto3.default.randomBytes(12).toString("hex").toUpperCase()}`;
|
|
46251
46285
|
return { credentialId, object: "qrcodes", value: token, qrValue: token };
|
|
46252
46286
|
}
|
|
46253
46287
|
async function configureVisitorQrReader(client) {
|
|
@@ -46751,7 +46785,7 @@ function getSipProvisioningConfig() {
|
|
|
46751
46785
|
return { provisionerUrl, provisionerToken, websocketUrl, domain };
|
|
46752
46786
|
}
|
|
46753
46787
|
function createSipPassword() {
|
|
46754
|
-
return
|
|
46788
|
+
return import_crypto3.default.randomBytes(12).toString("base64url");
|
|
46755
46789
|
}
|
|
46756
46790
|
function sipAccountResponse(account) {
|
|
46757
46791
|
const { websocketUrl, domain } = getSipProvisioningConfig();
|
|
@@ -49431,7 +49465,7 @@ function useHidAmicoService() {
|
|
|
49431
49465
|
assertReaderCardProfile(reader, cardType);
|
|
49432
49466
|
const hidUserId = Number(hidUserIdValue);
|
|
49433
49467
|
const client = new HidAmicoClient(reader);
|
|
49434
|
-
const lockOwner =
|
|
49468
|
+
const lockOwner = import_crypto3.default.randomUUID();
|
|
49435
49469
|
const acquired = await repo.acquireEnrollmentLock(readerId, lockOwner, timeoutSeconds + 30);
|
|
49436
49470
|
if (!acquired) {
|
|
49437
49471
|
throw new import_node_server_utils133.BadRequestError("Another physical HID card enrollment is already running on this reader.");
|
|
@@ -51445,17 +51479,17 @@ var import_fs5 = __toESM(require("fs"));
|
|
|
51445
51479
|
var import_path2 = __toESM(require("path"));
|
|
51446
51480
|
var import_axios2 = __toESM(require("axios"));
|
|
51447
51481
|
var import_xml2js = require("xml2js");
|
|
51448
|
-
var
|
|
51482
|
+
var import_crypto4 = __toESM(require("crypto"));
|
|
51449
51483
|
var ALGORITHM = "aes-256-gcm";
|
|
51450
|
-
var SECRET_KEY =
|
|
51451
|
-
new Uint8Array(
|
|
51484
|
+
var SECRET_KEY = import_crypto4.default.createSecretKey(
|
|
51485
|
+
new Uint8Array(import_crypto4.default.createHash("sha256").update("acm-secret-key").digest())
|
|
51452
51486
|
);
|
|
51453
51487
|
function decryptAcmUrl(encryptedText) {
|
|
51454
51488
|
const [ivB64, authTagB64, encryptedB64] = encryptedText.split(":");
|
|
51455
51489
|
const iv = Buffer.from(ivB64, "base64");
|
|
51456
51490
|
const authTag = Buffer.from(authTagB64, "base64");
|
|
51457
51491
|
const encrypted = Buffer.from(encryptedB64, "base64");
|
|
51458
|
-
const decipher =
|
|
51492
|
+
const decipher = import_crypto4.default.createDecipheriv(
|
|
51459
51493
|
ALGORITHM,
|
|
51460
51494
|
SECRET_KEY,
|
|
51461
51495
|
new Uint8Array(iv)
|
|
@@ -51598,10 +51632,10 @@ async function getTransactions(index, url) {
|
|
|
51598
51632
|
}
|
|
51599
51633
|
function encryptPayload(payloadHex) {
|
|
51600
51634
|
const buffer = Buffer.from(payloadHex, "ascii");
|
|
51601
|
-
const encrypted =
|
|
51635
|
+
const encrypted = import_crypto4.default.publicEncrypt(
|
|
51602
51636
|
{
|
|
51603
51637
|
key: "testing",
|
|
51604
|
-
padding:
|
|
51638
|
+
padding: import_crypto4.default.constants.RSA_PKCS1_PADDING
|
|
51605
51639
|
},
|
|
51606
51640
|
buffer
|
|
51607
51641
|
);
|
|
@@ -51611,7 +51645,7 @@ function toHex(num, length) {
|
|
|
51611
51645
|
return num.toString(16).padStart(length * 2, "0");
|
|
51612
51646
|
}
|
|
51613
51647
|
function buildPayload(cardNumber, validityMinutes) {
|
|
51614
|
-
const randomHex =
|
|
51648
|
+
const randomHex = import_crypto4.default.randomBytes(2).toString("hex");
|
|
51615
51649
|
const cardHex = toHex(cardNumber, 4);
|
|
51616
51650
|
const epochHex = toHex(Math.floor(Date.now() / 1e3), 4);
|
|
51617
51651
|
const validityHex = toHex(validityMinutes, 2);
|
|
@@ -51626,7 +51660,7 @@ function generateQrCodeData(cardNumber, validityMinutes) {
|
|
|
51626
51660
|
var import_xml2js2 = require("xml2js");
|
|
51627
51661
|
|
|
51628
51662
|
// src/utils/rsa-encryption.ts
|
|
51629
|
-
var
|
|
51663
|
+
var crypto7 = __toESM(require("crypto"));
|
|
51630
51664
|
var import_fs6 = __toESM(require("fs"));
|
|
51631
51665
|
var import_path3 = __toESM(require("path"));
|
|
51632
51666
|
var pub = import_path3.default.resolve(process.cwd(), "./src/public/rsa-keys/new_rsa_512_pub.pem");
|
|
@@ -51656,7 +51690,7 @@ var EntrypassRSAEncryption = class extends EncryptionCredentials {
|
|
|
51656
51690
|
static constructQrcode(params) {
|
|
51657
51691
|
const { virtualCardNo, validityMinutes } = params;
|
|
51658
51692
|
const virtualCardNoHex = this.cardNumberToHex(virtualCardNo);
|
|
51659
|
-
const randomHex =
|
|
51693
|
+
const randomHex = crypto7.randomBytes(2).toString("hex").toUpperCase();
|
|
51660
51694
|
const epochHex = Math.floor(Date.now() / 1e3).toString(16).toUpperCase();
|
|
51661
51695
|
const validityHex = validityMinutes.toString(16).padStart(4, "0").toUpperCase();
|
|
51662
51696
|
const plainHex = randomHex + virtualCardNoHex.toUpperCase() + epochHex + validityHex;
|
|
@@ -51667,10 +51701,10 @@ var EntrypassRSAEncryption = class extends EncryptionCredentials {
|
|
|
51667
51701
|
const bufferValue = this.constructQrcode(params);
|
|
51668
51702
|
const plainTextPayload = bufferValue;
|
|
51669
51703
|
console.log("Payload to be encrypted:", plainTextPayload);
|
|
51670
|
-
const encryptedBuffer =
|
|
51704
|
+
const encryptedBuffer = crypto7.publicEncrypt(
|
|
51671
51705
|
{
|
|
51672
51706
|
key: this.RAW_PUBLIC_KEY,
|
|
51673
|
-
padding:
|
|
51707
|
+
padding: crypto7.constants.RSA_PKCS1_PADDING
|
|
51674
51708
|
},
|
|
51675
51709
|
Buffer.from(plainTextPayload, "utf8")
|
|
51676
51710
|
);
|
|
@@ -51681,10 +51715,10 @@ var EntrypassRSAEncryption = class extends EncryptionCredentials {
|
|
|
51681
51715
|
static decryptQRCode(base64Cipher) {
|
|
51682
51716
|
try {
|
|
51683
51717
|
const buffer = Buffer.from(base64Cipher, "base64");
|
|
51684
|
-
const decryptedBuffer =
|
|
51718
|
+
const decryptedBuffer = crypto7.privateDecrypt(
|
|
51685
51719
|
{
|
|
51686
51720
|
key: this.RAW_PRIVATE_KEY,
|
|
51687
|
-
padding:
|
|
51721
|
+
padding: crypto7.constants.RSA_PKCS1_PADDING
|
|
51688
51722
|
},
|
|
51689
51723
|
buffer
|
|
51690
51724
|
);
|
|
@@ -81718,12 +81752,12 @@ async function manpowerEvents(io) {
|
|
|
81718
81752
|
var import_axios4 = __toESM(require("axios"));
|
|
81719
81753
|
|
|
81720
81754
|
// src/utils/payment-signature.util.ts
|
|
81721
|
-
var
|
|
81755
|
+
var crypto8 = __toESM(require("crypto"));
|
|
81722
81756
|
function hasOwn(obj, key) {
|
|
81723
81757
|
return Object.prototype.hasOwnProperty.call(obj, key);
|
|
81724
81758
|
}
|
|
81725
81759
|
function sha512(input) {
|
|
81726
|
-
return
|
|
81760
|
+
return crypto8.createHash("sha512").update(input).digest("hex");
|
|
81727
81761
|
}
|
|
81728
81762
|
function assertSecret(secretKey) {
|
|
81729
81763
|
if (!secretKey) {
|
|
@@ -82595,7 +82629,7 @@ function useRedDotPaymentController() {
|
|
|
82595
82629
|
|
|
82596
82630
|
// src/services/verification-v2.service.ts
|
|
82597
82631
|
var import_node_server_utils262 = require("@7365admin1/node-server-utils");
|
|
82598
|
-
var
|
|
82632
|
+
var import_crypto5 = __toESM(require("crypto"));
|
|
82599
82633
|
var import_joi138 = __toESM(require("joi"));
|
|
82600
82634
|
var import_mongodb160 = require("mongodb");
|
|
82601
82635
|
function useVerificationServiceV2() {
|
|
@@ -82657,7 +82691,7 @@ function useVerificationServiceV2() {
|
|
|
82657
82691
|
}
|
|
82658
82692
|
function generateVerificationCode(length = 8) {
|
|
82659
82693
|
const chars = "0123456789";
|
|
82660
|
-
const bytes =
|
|
82694
|
+
const bytes = import_crypto5.default.randomBytes(length);
|
|
82661
82695
|
let result = "";
|
|
82662
82696
|
for (let i = 0; i < length; i++) {
|
|
82663
82697
|
result += chars[bytes[i] % chars.length];
|