@dereekb/nestjs 13.10.8 → 13.11.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/discord/package.json +4 -4
- package/eslint/package.json +1 -1
- package/index.cjs.js +1458 -26
- package/index.esm.js +1453 -30
- package/mailgun/package.json +6 -6
- package/openai/package.json +6 -6
- package/package.json +3 -3
- package/src/lib/util/cache/cache.file.d.ts +106 -0
- package/src/lib/util/cache/index.d.ts +1 -0
- package/src/lib/util/file/file.json.d.ts +57 -0
- package/src/lib/util/file/index.d.ts +1 -0
- package/src/lib/util/index.d.ts +3 -0
- package/src/lib/util/pdf/index.d.ts +1 -0
- package/src/lib/util/pdf/pdf.encryption.d.ts +48 -0
- package/stripe/package.json +6 -6
- package/typeform/package.json +6 -6
- package/vapiai/package.json +6 -6
package/index.esm.js
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import { assetLoaderFromGetFn, fetchAssetLoader, delegatedAssetLoader, AssetLoader } from '@dereekb/rxjs';
|
|
2
2
|
import { readFile } from 'fs/promises';
|
|
3
|
-
import { resolve } from 'node:path';
|
|
3
|
+
import { resolve, dirname } from 'node:path';
|
|
4
4
|
import { createParamDecorator, Logger, BadRequestException, InternalServerErrorException, Injectable, RequestMethod, Module, Inject } from '@nestjs/common';
|
|
5
5
|
import rawbody from 'raw-body';
|
|
6
6
|
import { parse } from 'querystring';
|
|
7
7
|
import bodyParser from 'body-parser';
|
|
8
|
-
import { asArray, mergeArrays, isHex, getValueFromGetter } from '@dereekb/util';
|
|
8
|
+
import { asArray, mergeArrays, memoizeAsyncKeyedValueCache, memoizeAsyncValueCache, isHex, getValueFromGetter, PDF_ENCRYPT_MARKER } from '@dereekb/util';
|
|
9
9
|
import { ConfigService, ConfigModule } from '@nestjs/config';
|
|
10
|
-
import {
|
|
10
|
+
import { readFile as readFile$1, mkdirSync, writeFile, chmod } from 'node:fs';
|
|
11
|
+
import { rm } from 'node:fs/promises';
|
|
12
|
+
import { createDecipheriv, randomBytes, createCipheriv, createHash } from 'node:crypto';
|
|
11
13
|
|
|
12
|
-
function asyncGeneratorStep$
|
|
14
|
+
function asyncGeneratorStep$2(gen, resolve, reject, _next, _throw, key, arg) {
|
|
13
15
|
try {
|
|
14
16
|
var info = gen[key](arg);
|
|
15
17
|
var value = info.value;
|
|
@@ -23,22 +25,22 @@ function asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, key, arg) {
|
|
|
23
25
|
Promise.resolve(value).then(_next, _throw);
|
|
24
26
|
}
|
|
25
27
|
}
|
|
26
|
-
function _async_to_generator$
|
|
28
|
+
function _async_to_generator$2(fn) {
|
|
27
29
|
return function() {
|
|
28
30
|
var self = this, args = arguments;
|
|
29
31
|
return new Promise(function(resolve, reject) {
|
|
30
32
|
var gen = fn.apply(self, args);
|
|
31
33
|
function _next(value) {
|
|
32
|
-
asyncGeneratorStep$
|
|
34
|
+
asyncGeneratorStep$2(gen, resolve, reject, _next, _throw, "next", value);
|
|
33
35
|
}
|
|
34
36
|
function _throw(err) {
|
|
35
|
-
asyncGeneratorStep$
|
|
37
|
+
asyncGeneratorStep$2(gen, resolve, reject, _next, _throw, "throw", err);
|
|
36
38
|
}
|
|
37
39
|
_next(undefined);
|
|
38
40
|
});
|
|
39
41
|
};
|
|
40
42
|
}
|
|
41
|
-
function _ts_generator$
|
|
43
|
+
function _ts_generator$2(thisArg, body) {
|
|
42
44
|
var f, y, t, _ = {
|
|
43
45
|
label: 0,
|
|
44
46
|
sent: function() {
|
|
@@ -157,9 +159,9 @@ function _ts_generator$1(thisArg, body) {
|
|
|
157
159
|
*/ function nodeJsLocalAssetLoader(config) {
|
|
158
160
|
var basePath = config.basePath;
|
|
159
161
|
var getFn = function getFn(ref) {
|
|
160
|
-
return _async_to_generator$
|
|
162
|
+
return _async_to_generator$2(function() {
|
|
161
163
|
var localRef, fullPath, buffer;
|
|
162
|
-
return _ts_generator$
|
|
164
|
+
return _ts_generator$2(this, function(_state) {
|
|
163
165
|
switch(_state.label){
|
|
164
166
|
case 0:
|
|
165
167
|
localRef = ref;
|
|
@@ -238,7 +240,7 @@ function _ts_generator$1(thisArg, body) {
|
|
|
238
240
|
return origin.startsWith('http://localhost') || origin.startsWith('https://localhost');
|
|
239
241
|
}
|
|
240
242
|
|
|
241
|
-
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
|
|
243
|
+
function asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, key, arg) {
|
|
242
244
|
try {
|
|
243
245
|
var info = gen[key](arg);
|
|
244
246
|
var value = info.value;
|
|
@@ -252,22 +254,22 @@ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
|
|
|
252
254
|
Promise.resolve(value).then(_next, _throw);
|
|
253
255
|
}
|
|
254
256
|
}
|
|
255
|
-
function _async_to_generator(fn) {
|
|
257
|
+
function _async_to_generator$1(fn) {
|
|
256
258
|
return function() {
|
|
257
259
|
var self = this, args = arguments;
|
|
258
260
|
return new Promise(function(resolve, reject) {
|
|
259
261
|
var gen = fn.apply(self, args);
|
|
260
262
|
function _next(value) {
|
|
261
|
-
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
|
|
263
|
+
asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, "next", value);
|
|
262
264
|
}
|
|
263
265
|
function _throw(err) {
|
|
264
|
-
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
|
|
266
|
+
asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, "throw", err);
|
|
265
267
|
}
|
|
266
268
|
_next(undefined);
|
|
267
269
|
});
|
|
268
270
|
};
|
|
269
271
|
}
|
|
270
|
-
function _ts_generator(thisArg, body) {
|
|
272
|
+
function _ts_generator$1(thisArg, body) {
|
|
271
273
|
var f, y, t, _ = {
|
|
272
274
|
label: 0,
|
|
273
275
|
sent: function() {
|
|
@@ -380,9 +382,9 @@ function _ts_generator(thisArg, body) {
|
|
|
380
382
|
* ```
|
|
381
383
|
*/ var rawBodyLogger = new Logger('RawBody');
|
|
382
384
|
var ParseRawBody = createParamDecorator(function(_, context) {
|
|
383
|
-
return _async_to_generator(function() {
|
|
385
|
+
return _async_to_generator$1(function() {
|
|
384
386
|
var req, body;
|
|
385
|
-
return _ts_generator(this, function(_state) {
|
|
387
|
+
return _ts_generator$1(this, function(_state) {
|
|
386
388
|
switch(_state.label){
|
|
387
389
|
case 0:
|
|
388
390
|
req = context.switchToHttp().getRequest();
|
|
@@ -417,9 +419,9 @@ var ParseRawBody = createParamDecorator(function(_, context) {
|
|
|
417
419
|
* handleWebhook(@RawBody() body: RawBodyBuffer) { ... }
|
|
418
420
|
* ```
|
|
419
421
|
*/ var RawBody = createParamDecorator(function(_, context) {
|
|
420
|
-
return _async_to_generator(function() {
|
|
422
|
+
return _async_to_generator$1(function() {
|
|
421
423
|
var req, body;
|
|
422
|
-
return _ts_generator(this, function(_state) {
|
|
424
|
+
return _ts_generator$1(this, function(_state) {
|
|
423
425
|
req = context.switchToHttp().getRequest();
|
|
424
426
|
body = req.body;
|
|
425
427
|
if (!Buffer.isBuffer(body)) {
|
|
@@ -443,9 +445,9 @@ var ParseRawBody = createParamDecorator(function(_, context) {
|
|
|
443
445
|
* handleForm(@ParsedQueryRawBody() body: ParsedUrlQuery) { ... }
|
|
444
446
|
* ```
|
|
445
447
|
*/ var ParsedQueryRawBody = createParamDecorator(function(_, context) {
|
|
446
|
-
return _async_to_generator(function() {
|
|
448
|
+
return _async_to_generator$1(function() {
|
|
447
449
|
var req;
|
|
448
|
-
return _ts_generator(this, function(_state) {
|
|
450
|
+
return _ts_generator$1(this, function(_state) {
|
|
449
451
|
req = context.switchToHttp().getRequest();
|
|
450
452
|
req.body = RawBodyToParsedQueryString(req.body);
|
|
451
453
|
return [
|
|
@@ -629,7 +631,7 @@ function _create_class$3(Constructor, protoProps, staticProps) {
|
|
|
629
631
|
if (protoProps) _defineProperties$3(Constructor.prototype, protoProps);
|
|
630
632
|
return Constructor;
|
|
631
633
|
}
|
|
632
|
-
function _define_property$
|
|
634
|
+
function _define_property$4(obj, key, value) {
|
|
633
635
|
if (key in obj) {
|
|
634
636
|
Object.defineProperty(obj, key, {
|
|
635
637
|
value: value,
|
|
@@ -737,7 +739,7 @@ var DEFAULT_WEBHOOK_MIDDLEWARE_ROUTE_INFO = {
|
|
|
737
739
|
function ConfigureWebhookMiddlewareModule() {
|
|
738
740
|
_class_call_check$5(this, ConfigureWebhookMiddlewareModule);
|
|
739
741
|
var _this;
|
|
740
|
-
_this = _call_super(this, ConfigureWebhookMiddlewareModule, arguments), _define_property$
|
|
742
|
+
_this = _call_super(this, ConfigureWebhookMiddlewareModule, arguments), _define_property$4(_this, "logger", new Logger('ConfigureWebhookMiddlewareModule'));
|
|
741
743
|
return _this;
|
|
742
744
|
}
|
|
743
745
|
_create_class$3(ConfigureWebhookMiddlewareModule, [
|
|
@@ -834,7 +836,7 @@ function _create_class$2(Constructor, protoProps, staticProps) {
|
|
|
834
836
|
if (staticProps) _defineProperties$2(Constructor, staticProps);
|
|
835
837
|
return Constructor;
|
|
836
838
|
}
|
|
837
|
-
function _define_property$
|
|
839
|
+
function _define_property$3(obj, key, value) {
|
|
838
840
|
if (key in obj) {
|
|
839
841
|
Object.defineProperty(obj, key, {
|
|
840
842
|
value: value,
|
|
@@ -854,7 +856,7 @@ function _define_property$2(obj, key, value) {
|
|
|
854
856
|
*/ var ClientAppServiceConfig = /*#__PURE__*/ function() {
|
|
855
857
|
function ClientAppServiceConfig() {
|
|
856
858
|
_class_call_check$4(this, ClientAppServiceConfig);
|
|
857
|
-
_define_property$
|
|
859
|
+
_define_property$3(this, "client", void 0);
|
|
858
860
|
}
|
|
859
861
|
_create_class$2(ClientAppServiceConfig, null, [
|
|
860
862
|
{
|
|
@@ -893,7 +895,7 @@ function _create_class$1(Constructor, protoProps, staticProps) {
|
|
|
893
895
|
if (protoProps) _defineProperties$1(Constructor.prototype, protoProps);
|
|
894
896
|
return Constructor;
|
|
895
897
|
}
|
|
896
|
-
function _define_property$
|
|
898
|
+
function _define_property$2(obj, key, value) {
|
|
897
899
|
if (key in obj) {
|
|
898
900
|
Object.defineProperty(obj, key, {
|
|
899
901
|
value: value,
|
|
@@ -911,7 +913,7 @@ function _define_property$1(obj, key, value) {
|
|
|
911
913
|
*/ var ClientAppService = /*#__PURE__*/ function() {
|
|
912
914
|
function ClientAppService(config) {
|
|
913
915
|
_class_call_check$3(this, ClientAppService);
|
|
914
|
-
_define_property$
|
|
916
|
+
_define_property$2(this, "_config", void 0);
|
|
915
917
|
this._config = config;
|
|
916
918
|
}
|
|
917
919
|
_create_class$1(ClientAppService, [
|
|
@@ -1050,7 +1052,7 @@ function _create_class(Constructor, protoProps, staticProps) {
|
|
|
1050
1052
|
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
|
|
1051
1053
|
return Constructor;
|
|
1052
1054
|
}
|
|
1053
|
-
function _define_property(obj, key, value) {
|
|
1055
|
+
function _define_property$1(obj, key, value) {
|
|
1054
1056
|
if (key in obj) {
|
|
1055
1057
|
Object.defineProperty(obj, key, {
|
|
1056
1058
|
value: value,
|
|
@@ -1066,7 +1068,7 @@ function _define_property(obj, key, value) {
|
|
|
1066
1068
|
var ServerEnvironmentService = /*#__PURE__*/ function() {
|
|
1067
1069
|
function ServerEnvironmentService(env) {
|
|
1068
1070
|
_class_call_check(this, ServerEnvironmentService);
|
|
1069
|
-
_define_property(this, "env", void 0);
|
|
1071
|
+
_define_property$1(this, "env", void 0);
|
|
1070
1072
|
this.env = env;
|
|
1071
1073
|
}
|
|
1072
1074
|
_create_class(ServerEnvironmentService, [
|
|
@@ -1114,6 +1116,639 @@ ServerEnvironmentService = __decorate([
|
|
|
1114
1116
|
__param(0, Inject(SERVER_ENV_TOKEN))
|
|
1115
1117
|
], ServerEnvironmentService);
|
|
1116
1118
|
|
|
1119
|
+
/**
|
|
1120
|
+
* Reads JSON from disk, resolving `undefined` when the file is missing (ENOENT) or its
|
|
1121
|
+
* contents fail to parse as JSON. Other I/O errors (permission denied, busy handles) are
|
|
1122
|
+
* forwarded to the caller — silently swallowing them masks real failures.
|
|
1123
|
+
*
|
|
1124
|
+
* @param filePath - Absolute path to the JSON file to read.
|
|
1125
|
+
* @returns The parsed JSON cast to `T`, or `undefined` when the file does not exist or its contents are not valid JSON.
|
|
1126
|
+
*/ function readJsonFile(filePath) {
|
|
1127
|
+
return new Promise(function(resolve, reject) {
|
|
1128
|
+
readFile$1(filePath, {
|
|
1129
|
+
encoding: 'utf-8'
|
|
1130
|
+
}, function(err, data) {
|
|
1131
|
+
if (err) {
|
|
1132
|
+
if (err.code === 'ENOENT') {
|
|
1133
|
+
resolve(undefined);
|
|
1134
|
+
} else {
|
|
1135
|
+
reject(err);
|
|
1136
|
+
}
|
|
1137
|
+
return;
|
|
1138
|
+
}
|
|
1139
|
+
try {
|
|
1140
|
+
resolve(JSON.parse(data));
|
|
1141
|
+
} catch (unused) {
|
|
1142
|
+
resolve(undefined);
|
|
1143
|
+
}
|
|
1144
|
+
});
|
|
1145
|
+
});
|
|
1146
|
+
}
|
|
1147
|
+
/**
|
|
1148
|
+
* Writes a value to disk as JSON. Creates the parent directory if it does not exist.
|
|
1149
|
+
*
|
|
1150
|
+
* The `mode` option is enforced via an explicit `chmod` after the write — `writeFile`'s `mode`
|
|
1151
|
+
* parameter is ignored when the file already exists, which would otherwise leave a
|
|
1152
|
+
* pre-existing file at its original (potentially world-readable) permissions.
|
|
1153
|
+
*
|
|
1154
|
+
* @param input - Configuration describing the destination, payload, and optional file mode.
|
|
1155
|
+
* @param input.filePath - Absolute path to the file to write.
|
|
1156
|
+
* @param input.dirPath - Absolute path to the parent directory; created (recursively) when missing.
|
|
1157
|
+
* @param input.data - Value to serialize as JSON (pretty-printed with two-space indentation).
|
|
1158
|
+
* @param input.mode - Optional numeric file mode (e.g. `0o600`) applied via `chmod` after the write.
|
|
1159
|
+
* @returns A promise that resolves once the JSON has been written and the optional `chmod` has completed.
|
|
1160
|
+
*/ function writeJsonFile(input) {
|
|
1161
|
+
mkdirSync(input.dirPath, {
|
|
1162
|
+
recursive: true
|
|
1163
|
+
});
|
|
1164
|
+
return new Promise(function(resolve, reject) {
|
|
1165
|
+
writeFile(input.filePath, JSON.stringify(input.data, null, 2), {
|
|
1166
|
+
mode: input.mode
|
|
1167
|
+
}, function(err) {
|
|
1168
|
+
if (err) {
|
|
1169
|
+
reject(err);
|
|
1170
|
+
return;
|
|
1171
|
+
}
|
|
1172
|
+
if (input.mode == null) {
|
|
1173
|
+
resolve();
|
|
1174
|
+
return;
|
|
1175
|
+
}
|
|
1176
|
+
chmod(input.filePath, input.mode, function(chmodErr) {
|
|
1177
|
+
if (chmodErr) reject(chmodErr);
|
|
1178
|
+
else resolve();
|
|
1179
|
+
});
|
|
1180
|
+
});
|
|
1181
|
+
});
|
|
1182
|
+
}
|
|
1183
|
+
/**
|
|
1184
|
+
* Removes the file at the given path.
|
|
1185
|
+
*
|
|
1186
|
+
* Resolves silently when the file does not exist (`force: true`); other errors
|
|
1187
|
+
* (permission denied, busy file handles) are forwarded to the caller — silently
|
|
1188
|
+
* swallowing them masks real failures and makes operations appear to have succeeded.
|
|
1189
|
+
*
|
|
1190
|
+
* @param filePath - Absolute path to the file to remove.
|
|
1191
|
+
* @returns A promise that resolves once the file is removed (or was already absent).
|
|
1192
|
+
*/ function removeFile(filePath) {
|
|
1193
|
+
return rm(filePath, {
|
|
1194
|
+
force: true
|
|
1195
|
+
});
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
function _array_like_to_array$1(arr, len) {
|
|
1199
|
+
if (len == null || len > arr.length) len = arr.length;
|
|
1200
|
+
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
1201
|
+
return arr2;
|
|
1202
|
+
}
|
|
1203
|
+
function _array_with_holes$1(arr) {
|
|
1204
|
+
if (Array.isArray(arr)) return arr;
|
|
1205
|
+
}
|
|
1206
|
+
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
|
|
1207
|
+
try {
|
|
1208
|
+
var info = gen[key](arg);
|
|
1209
|
+
var value = info.value;
|
|
1210
|
+
} catch (error) {
|
|
1211
|
+
reject(error);
|
|
1212
|
+
return;
|
|
1213
|
+
}
|
|
1214
|
+
if (info.done) {
|
|
1215
|
+
resolve(value);
|
|
1216
|
+
} else {
|
|
1217
|
+
Promise.resolve(value).then(_next, _throw);
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
function _async_to_generator(fn) {
|
|
1221
|
+
return function() {
|
|
1222
|
+
var self = this, args = arguments;
|
|
1223
|
+
return new Promise(function(resolve, reject) {
|
|
1224
|
+
var gen = fn.apply(self, args);
|
|
1225
|
+
function _next(value) {
|
|
1226
|
+
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
|
|
1227
|
+
}
|
|
1228
|
+
function _throw(err) {
|
|
1229
|
+
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
|
|
1230
|
+
}
|
|
1231
|
+
_next(undefined);
|
|
1232
|
+
});
|
|
1233
|
+
};
|
|
1234
|
+
}
|
|
1235
|
+
function _define_property(obj, key, value) {
|
|
1236
|
+
if (key in obj) {
|
|
1237
|
+
Object.defineProperty(obj, key, {
|
|
1238
|
+
value: value,
|
|
1239
|
+
enumerable: true,
|
|
1240
|
+
configurable: true,
|
|
1241
|
+
writable: true
|
|
1242
|
+
});
|
|
1243
|
+
} else {
|
|
1244
|
+
obj[key] = value;
|
|
1245
|
+
}
|
|
1246
|
+
return obj;
|
|
1247
|
+
}
|
|
1248
|
+
function _iterable_to_array_limit$1(arr, i) {
|
|
1249
|
+
var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
|
|
1250
|
+
if (_i == null) return;
|
|
1251
|
+
var _arr = [];
|
|
1252
|
+
var _n = true;
|
|
1253
|
+
var _d = false;
|
|
1254
|
+
var _s, _e;
|
|
1255
|
+
try {
|
|
1256
|
+
for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
|
|
1257
|
+
_arr.push(_s.value);
|
|
1258
|
+
if (i && _arr.length === i) break;
|
|
1259
|
+
}
|
|
1260
|
+
} catch (err) {
|
|
1261
|
+
_d = true;
|
|
1262
|
+
_e = err;
|
|
1263
|
+
} finally{
|
|
1264
|
+
try {
|
|
1265
|
+
if (!_n && _i["return"] != null) _i["return"]();
|
|
1266
|
+
} finally{
|
|
1267
|
+
if (_d) throw _e;
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1270
|
+
return _arr;
|
|
1271
|
+
}
|
|
1272
|
+
function _non_iterable_rest$1() {
|
|
1273
|
+
throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
1274
|
+
}
|
|
1275
|
+
function _object_spread(target) {
|
|
1276
|
+
for(var i = 1; i < arguments.length; i++){
|
|
1277
|
+
var source = arguments[i] != null ? arguments[i] : {};
|
|
1278
|
+
var ownKeys = Object.keys(source);
|
|
1279
|
+
if (typeof Object.getOwnPropertySymbols === "function") {
|
|
1280
|
+
ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
|
|
1281
|
+
return Object.getOwnPropertyDescriptor(source, sym).enumerable;
|
|
1282
|
+
}));
|
|
1283
|
+
}
|
|
1284
|
+
ownKeys.forEach(function(key) {
|
|
1285
|
+
_define_property(target, key, source[key]);
|
|
1286
|
+
});
|
|
1287
|
+
}
|
|
1288
|
+
return target;
|
|
1289
|
+
}
|
|
1290
|
+
function ownKeys(object, enumerableOnly) {
|
|
1291
|
+
var keys = Object.keys(object);
|
|
1292
|
+
if (Object.getOwnPropertySymbols) {
|
|
1293
|
+
var symbols = Object.getOwnPropertySymbols(object);
|
|
1294
|
+
keys.push.apply(keys, symbols);
|
|
1295
|
+
}
|
|
1296
|
+
return keys;
|
|
1297
|
+
}
|
|
1298
|
+
function _object_spread_props(target, source) {
|
|
1299
|
+
source = source != null ? source : {};
|
|
1300
|
+
if (Object.getOwnPropertyDescriptors) {
|
|
1301
|
+
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
|
|
1302
|
+
} else {
|
|
1303
|
+
ownKeys(Object(source)).forEach(function(key) {
|
|
1304
|
+
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
|
1305
|
+
});
|
|
1306
|
+
}
|
|
1307
|
+
return target;
|
|
1308
|
+
}
|
|
1309
|
+
function _sliced_to_array$1(arr, i) {
|
|
1310
|
+
return _array_with_holes$1(arr) || _iterable_to_array_limit$1(arr, i) || _unsupported_iterable_to_array$1(arr, i) || _non_iterable_rest$1();
|
|
1311
|
+
}
|
|
1312
|
+
function _unsupported_iterable_to_array$1(o, minLen) {
|
|
1313
|
+
if (!o) return;
|
|
1314
|
+
if (typeof o === "string") return _array_like_to_array$1(o, minLen);
|
|
1315
|
+
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
1316
|
+
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
1317
|
+
if (n === "Map" || n === "Set") return Array.from(n);
|
|
1318
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$1(o, minLen);
|
|
1319
|
+
}
|
|
1320
|
+
function _ts_generator(thisArg, body) {
|
|
1321
|
+
var f, y, t, _ = {
|
|
1322
|
+
label: 0,
|
|
1323
|
+
sent: function() {
|
|
1324
|
+
if (t[0] & 1) throw t[1];
|
|
1325
|
+
return t[1];
|
|
1326
|
+
},
|
|
1327
|
+
trys: [],
|
|
1328
|
+
ops: []
|
|
1329
|
+
}, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype), d = Object.defineProperty;
|
|
1330
|
+
return d(g, "next", {
|
|
1331
|
+
value: verb(0)
|
|
1332
|
+
}), d(g, "throw", {
|
|
1333
|
+
value: verb(1)
|
|
1334
|
+
}), d(g, "return", {
|
|
1335
|
+
value: verb(2)
|
|
1336
|
+
}), typeof Symbol === "function" && d(g, Symbol.iterator, {
|
|
1337
|
+
value: function() {
|
|
1338
|
+
return this;
|
|
1339
|
+
}
|
|
1340
|
+
}), g;
|
|
1341
|
+
function verb(n) {
|
|
1342
|
+
return function(v) {
|
|
1343
|
+
return step([
|
|
1344
|
+
n,
|
|
1345
|
+
v
|
|
1346
|
+
]);
|
|
1347
|
+
};
|
|
1348
|
+
}
|
|
1349
|
+
function step(op) {
|
|
1350
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
1351
|
+
while(g && (g = 0, op[0] && (_ = 0)), _)try {
|
|
1352
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
1353
|
+
if (y = 0, t) op = [
|
|
1354
|
+
op[0] & 2,
|
|
1355
|
+
t.value
|
|
1356
|
+
];
|
|
1357
|
+
switch(op[0]){
|
|
1358
|
+
case 0:
|
|
1359
|
+
case 1:
|
|
1360
|
+
t = op;
|
|
1361
|
+
break;
|
|
1362
|
+
case 4:
|
|
1363
|
+
_.label++;
|
|
1364
|
+
return {
|
|
1365
|
+
value: op[1],
|
|
1366
|
+
done: false
|
|
1367
|
+
};
|
|
1368
|
+
case 5:
|
|
1369
|
+
_.label++;
|
|
1370
|
+
y = op[1];
|
|
1371
|
+
op = [
|
|
1372
|
+
0
|
|
1373
|
+
];
|
|
1374
|
+
continue;
|
|
1375
|
+
case 7:
|
|
1376
|
+
op = _.ops.pop();
|
|
1377
|
+
_.trys.pop();
|
|
1378
|
+
continue;
|
|
1379
|
+
default:
|
|
1380
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
|
|
1381
|
+
_ = 0;
|
|
1382
|
+
continue;
|
|
1383
|
+
}
|
|
1384
|
+
if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
|
|
1385
|
+
_.label = op[1];
|
|
1386
|
+
break;
|
|
1387
|
+
}
|
|
1388
|
+
if (op[0] === 6 && _.label < t[1]) {
|
|
1389
|
+
_.label = t[1];
|
|
1390
|
+
t = op;
|
|
1391
|
+
break;
|
|
1392
|
+
}
|
|
1393
|
+
if (t && _.label < t[2]) {
|
|
1394
|
+
_.label = t[2];
|
|
1395
|
+
_.ops.push(op);
|
|
1396
|
+
break;
|
|
1397
|
+
}
|
|
1398
|
+
if (t[2]) _.ops.pop();
|
|
1399
|
+
_.trys.pop();
|
|
1400
|
+
continue;
|
|
1401
|
+
}
|
|
1402
|
+
op = body.call(thisArg, _);
|
|
1403
|
+
} catch (e) {
|
|
1404
|
+
op = [
|
|
1405
|
+
6,
|
|
1406
|
+
e
|
|
1407
|
+
];
|
|
1408
|
+
y = 0;
|
|
1409
|
+
} finally{
|
|
1410
|
+
f = t = 0;
|
|
1411
|
+
}
|
|
1412
|
+
if (op[0] & 5) throw op[1];
|
|
1413
|
+
return {
|
|
1414
|
+
value: op[0] ? op[1] : void 0,
|
|
1415
|
+
done: true
|
|
1416
|
+
};
|
|
1417
|
+
}
|
|
1418
|
+
}
|
|
1419
|
+
/**
|
|
1420
|
+
* Default file mode used by the JSON-file caches when none is provided.
|
|
1421
|
+
*
|
|
1422
|
+
* 0o600 restricts the file to read/write for the owning user only — appropriate for
|
|
1423
|
+
* secrets like cached access/refresh tokens.
|
|
1424
|
+
*/ var DEFAULT_JSON_FILE_CACHE_MODE = 384;
|
|
1425
|
+
/**
|
|
1426
|
+
* Creates an {@link AsyncValueCache} backed by a single JSON file on disk.
|
|
1427
|
+
*
|
|
1428
|
+
* Reads always touch disk; wrap with {@link memoizeAsyncValueCache} (or use
|
|
1429
|
+
* {@link createMemoizedJsonFileAsyncValueCache}) to add per-process memoization.
|
|
1430
|
+
*
|
|
1431
|
+
* Multi-process invalidation is not provided. Two processes writing to the same file
|
|
1432
|
+
* will last-writer-wins; once memoized, a long-running process will not observe writes
|
|
1433
|
+
* from another process.
|
|
1434
|
+
*
|
|
1435
|
+
* @param input - Configuration bag describing the backing file and optional JSON revive/replace hooks.
|
|
1436
|
+
* @param input.filePath - Absolute path to the JSON file that backs the cache.
|
|
1437
|
+
* @param input.mode - Optional file mode applied on write; defaults to {@link DEFAULT_JSON_FILE_CACHE_MODE} (0o600).
|
|
1438
|
+
* @param input.reviver - Optional transform applied to the raw JSON-parsed payload before it is returned from `load()` (e.g. revive `Date` fields).
|
|
1439
|
+
* @param input.replacer - Optional transform applied to the value before it is stringified to JSON on `update()`.
|
|
1440
|
+
* @returns An {@link AsyncValueCache} that persists the value to the configured JSON file.
|
|
1441
|
+
*/ function createJsonFileAsyncValueCache(input) {
|
|
1442
|
+
var filePath = input.filePath, mode = input.mode, reviver = input.reviver, replacer = input.replacer;
|
|
1443
|
+
var fileMode = mode !== null && mode !== void 0 ? mode : DEFAULT_JSON_FILE_CACHE_MODE;
|
|
1444
|
+
return {
|
|
1445
|
+
load: function load() {
|
|
1446
|
+
return _async_to_generator(function() {
|
|
1447
|
+
var raw;
|
|
1448
|
+
return _ts_generator(this, function(_state) {
|
|
1449
|
+
switch(_state.label){
|
|
1450
|
+
case 0:
|
|
1451
|
+
return [
|
|
1452
|
+
4,
|
|
1453
|
+
readJsonFile(filePath)
|
|
1454
|
+
];
|
|
1455
|
+
case 1:
|
|
1456
|
+
raw = _state.sent();
|
|
1457
|
+
if (raw == null) {
|
|
1458
|
+
return [
|
|
1459
|
+
2,
|
|
1460
|
+
undefined
|
|
1461
|
+
];
|
|
1462
|
+
}
|
|
1463
|
+
return [
|
|
1464
|
+
2,
|
|
1465
|
+
reviver == null ? raw : reviver(raw)
|
|
1466
|
+
];
|
|
1467
|
+
}
|
|
1468
|
+
});
|
|
1469
|
+
})();
|
|
1470
|
+
},
|
|
1471
|
+
update: function update(value) {
|
|
1472
|
+
return _async_to_generator(function() {
|
|
1473
|
+
var data;
|
|
1474
|
+
return _ts_generator(this, function(_state) {
|
|
1475
|
+
switch(_state.label){
|
|
1476
|
+
case 0:
|
|
1477
|
+
data = replacer == null ? value : replacer(value);
|
|
1478
|
+
return [
|
|
1479
|
+
4,
|
|
1480
|
+
writeJsonFile({
|
|
1481
|
+
filePath: filePath,
|
|
1482
|
+
dirPath: dirname(filePath),
|
|
1483
|
+
data: data,
|
|
1484
|
+
mode: fileMode
|
|
1485
|
+
})
|
|
1486
|
+
];
|
|
1487
|
+
case 1:
|
|
1488
|
+
_state.sent();
|
|
1489
|
+
return [
|
|
1490
|
+
2
|
|
1491
|
+
];
|
|
1492
|
+
}
|
|
1493
|
+
});
|
|
1494
|
+
})();
|
|
1495
|
+
},
|
|
1496
|
+
clear: function clear() {
|
|
1497
|
+
return _async_to_generator(function() {
|
|
1498
|
+
return _ts_generator(this, function(_state) {
|
|
1499
|
+
switch(_state.label){
|
|
1500
|
+
case 0:
|
|
1501
|
+
return [
|
|
1502
|
+
4,
|
|
1503
|
+
removeFile(filePath)
|
|
1504
|
+
];
|
|
1505
|
+
case 1:
|
|
1506
|
+
_state.sent();
|
|
1507
|
+
return [
|
|
1508
|
+
2
|
|
1509
|
+
];
|
|
1510
|
+
}
|
|
1511
|
+
});
|
|
1512
|
+
})();
|
|
1513
|
+
}
|
|
1514
|
+
};
|
|
1515
|
+
}
|
|
1516
|
+
/**
|
|
1517
|
+
* Convenience wrapper around {@link createJsonFileAsyncValueCache} composed with
|
|
1518
|
+
* {@link memoizeAsyncValueCache}.
|
|
1519
|
+
*
|
|
1520
|
+
* @param input - Same configuration accepted by {@link createJsonFileAsyncValueCache}; see {@link CreateJsonFileAsyncValueCacheInput}.
|
|
1521
|
+
* @returns An {@link AsyncValueCache} backed by the JSON file with a per-process single-load memoization layer in front.
|
|
1522
|
+
*/ function createMemoizedJsonFileAsyncValueCache(input) {
|
|
1523
|
+
return memoizeAsyncValueCache(createJsonFileAsyncValueCache(input));
|
|
1524
|
+
}
|
|
1525
|
+
/**
|
|
1526
|
+
* Creates an {@link AsyncKeyedValueCache} backed by a single JSON file holding a `Record<string, T>`.
|
|
1527
|
+
*
|
|
1528
|
+
* Reads/writes always touch disk; wrap with {@link memoizeAsyncKeyedValueCache} (or use
|
|
1529
|
+
* {@link createMemoizedJsonFileAsyncKeyedValueCache}) to add per-process memoization of the
|
|
1530
|
+
* entire record.
|
|
1531
|
+
*
|
|
1532
|
+
* Multi-process invalidation is not provided; see {@link createJsonFileAsyncValueCache} for caveats.
|
|
1533
|
+
*
|
|
1534
|
+
* Concurrent `set`/`remove`/`clear` calls are serialized through a per-instance promise chain so
|
|
1535
|
+
* the read-modify-write of the entire record file does not race within the same process.
|
|
1536
|
+
*
|
|
1537
|
+
* @param input - Configuration bag describing the backing file and optional per-entry revive/replace hooks.
|
|
1538
|
+
* @param input.filePath - Absolute path to the JSON file that holds the entire `Record<string, T>`.
|
|
1539
|
+
* @param input.mode - Optional file mode applied on write; defaults to {@link DEFAULT_JSON_FILE_CACHE_MODE} (0o600).
|
|
1540
|
+
* @param input.reviver - Optional transform applied to each entry after it is JSON-parsed on `load()`/`get()`. Returning null/undefined drops the entry.
|
|
1541
|
+
* @param input.replacer - Optional transform applied to each entry before it is stringified on `set()`.
|
|
1542
|
+
* @returns An {@link AsyncKeyedValueCache} that persists all entries in the configured JSON file.
|
|
1543
|
+
*/ function createJsonFileAsyncKeyedValueCache(input) {
|
|
1544
|
+
var filePath = input.filePath, mode = input.mode, reviver = input.reviver, replacer = input.replacer;
|
|
1545
|
+
var fileMode = mode !== null && mode !== void 0 ? mode : DEFAULT_JSON_FILE_CACHE_MODE;
|
|
1546
|
+
function readEntries() {
|
|
1547
|
+
return _async_to_generator(function() {
|
|
1548
|
+
var raw, result, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, key, revived;
|
|
1549
|
+
return _ts_generator(this, function(_state) {
|
|
1550
|
+
switch(_state.label){
|
|
1551
|
+
case 0:
|
|
1552
|
+
return [
|
|
1553
|
+
4,
|
|
1554
|
+
readJsonFile(filePath)
|
|
1555
|
+
];
|
|
1556
|
+
case 1:
|
|
1557
|
+
raw = _state.sent();
|
|
1558
|
+
if (raw == null) {
|
|
1559
|
+
return [
|
|
1560
|
+
2,
|
|
1561
|
+
{}
|
|
1562
|
+
];
|
|
1563
|
+
}
|
|
1564
|
+
if (reviver == null) {
|
|
1565
|
+
return [
|
|
1566
|
+
2,
|
|
1567
|
+
raw
|
|
1568
|
+
];
|
|
1569
|
+
}
|
|
1570
|
+
result = {};
|
|
1571
|
+
_iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
1572
|
+
try {
|
|
1573
|
+
for(_iterator = Object.keys(raw)[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
1574
|
+
key = _step.value;
|
|
1575
|
+
revived = reviver(raw[key]);
|
|
1576
|
+
if (revived != null) {
|
|
1577
|
+
result[key] = revived;
|
|
1578
|
+
}
|
|
1579
|
+
}
|
|
1580
|
+
} catch (err) {
|
|
1581
|
+
_didIteratorError = true;
|
|
1582
|
+
_iteratorError = err;
|
|
1583
|
+
} finally{
|
|
1584
|
+
try {
|
|
1585
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
1586
|
+
_iterator.return();
|
|
1587
|
+
}
|
|
1588
|
+
} finally{
|
|
1589
|
+
if (_didIteratorError) {
|
|
1590
|
+
throw _iteratorError;
|
|
1591
|
+
}
|
|
1592
|
+
}
|
|
1593
|
+
}
|
|
1594
|
+
return [
|
|
1595
|
+
2,
|
|
1596
|
+
result
|
|
1597
|
+
];
|
|
1598
|
+
}
|
|
1599
|
+
});
|
|
1600
|
+
})();
|
|
1601
|
+
}
|
|
1602
|
+
function writeEntries(entries) {
|
|
1603
|
+
return _async_to_generator(function() {
|
|
1604
|
+
var data;
|
|
1605
|
+
return _ts_generator(this, function(_state) {
|
|
1606
|
+
switch(_state.label){
|
|
1607
|
+
case 0:
|
|
1608
|
+
data = replacer == null ? entries : Object.fromEntries(Object.entries(entries).map(function(param) {
|
|
1609
|
+
var _param = _sliced_to_array$1(param, 2), key = _param[0], value = _param[1];
|
|
1610
|
+
return [
|
|
1611
|
+
key,
|
|
1612
|
+
replacer(value)
|
|
1613
|
+
];
|
|
1614
|
+
}));
|
|
1615
|
+
return [
|
|
1616
|
+
4,
|
|
1617
|
+
writeJsonFile({
|
|
1618
|
+
filePath: filePath,
|
|
1619
|
+
dirPath: dirname(filePath),
|
|
1620
|
+
data: data,
|
|
1621
|
+
mode: fileMode
|
|
1622
|
+
})
|
|
1623
|
+
];
|
|
1624
|
+
case 1:
|
|
1625
|
+
_state.sent();
|
|
1626
|
+
return [
|
|
1627
|
+
2
|
|
1628
|
+
];
|
|
1629
|
+
}
|
|
1630
|
+
});
|
|
1631
|
+
})();
|
|
1632
|
+
}
|
|
1633
|
+
// Serialize set/remove through a per-instance promise chain. Without this, two concurrent
|
|
1634
|
+
// mutations would race on the read-modify-write of the entire record file and the second
|
|
1635
|
+
// writer's snapshot of the entries would clobber the first.
|
|
1636
|
+
var mutationQueue = Promise.resolve();
|
|
1637
|
+
function enqueueMutation(fn) {
|
|
1638
|
+
var next = mutationQueue.then(fn, fn);
|
|
1639
|
+
mutationQueue = next.catch(function() {
|
|
1640
|
+
return undefined;
|
|
1641
|
+
});
|
|
1642
|
+
return next;
|
|
1643
|
+
}
|
|
1644
|
+
return {
|
|
1645
|
+
load: readEntries,
|
|
1646
|
+
get: function get(key) {
|
|
1647
|
+
return _async_to_generator(function() {
|
|
1648
|
+
return _ts_generator(this, function(_state) {
|
|
1649
|
+
switch(_state.label){
|
|
1650
|
+
case 0:
|
|
1651
|
+
return [
|
|
1652
|
+
4,
|
|
1653
|
+
readEntries()
|
|
1654
|
+
];
|
|
1655
|
+
case 1:
|
|
1656
|
+
return [
|
|
1657
|
+
2,
|
|
1658
|
+
_state.sent()[key]
|
|
1659
|
+
];
|
|
1660
|
+
}
|
|
1661
|
+
});
|
|
1662
|
+
})();
|
|
1663
|
+
},
|
|
1664
|
+
set: function set(key, value) {
|
|
1665
|
+
return enqueueMutation(function() {
|
|
1666
|
+
return _async_to_generator(function() {
|
|
1667
|
+
var current;
|
|
1668
|
+
return _ts_generator(this, function(_state) {
|
|
1669
|
+
switch(_state.label){
|
|
1670
|
+
case 0:
|
|
1671
|
+
return [
|
|
1672
|
+
4,
|
|
1673
|
+
readEntries()
|
|
1674
|
+
];
|
|
1675
|
+
case 1:
|
|
1676
|
+
current = _state.sent();
|
|
1677
|
+
return [
|
|
1678
|
+
4,
|
|
1679
|
+
writeEntries(_object_spread_props(_object_spread({}, current), _define_property({}, key, value)))
|
|
1680
|
+
];
|
|
1681
|
+
case 2:
|
|
1682
|
+
_state.sent();
|
|
1683
|
+
return [
|
|
1684
|
+
2
|
|
1685
|
+
];
|
|
1686
|
+
}
|
|
1687
|
+
});
|
|
1688
|
+
})();
|
|
1689
|
+
});
|
|
1690
|
+
},
|
|
1691
|
+
remove: function remove(key) {
|
|
1692
|
+
return enqueueMutation(function() {
|
|
1693
|
+
return _async_to_generator(function() {
|
|
1694
|
+
var current, next;
|
|
1695
|
+
return _ts_generator(this, function(_state) {
|
|
1696
|
+
switch(_state.label){
|
|
1697
|
+
case 0:
|
|
1698
|
+
return [
|
|
1699
|
+
4,
|
|
1700
|
+
readEntries()
|
|
1701
|
+
];
|
|
1702
|
+
case 1:
|
|
1703
|
+
current = _state.sent();
|
|
1704
|
+
next = _object_spread({}, current);
|
|
1705
|
+
delete next[key];
|
|
1706
|
+
return [
|
|
1707
|
+
4,
|
|
1708
|
+
writeEntries(next)
|
|
1709
|
+
];
|
|
1710
|
+
case 2:
|
|
1711
|
+
_state.sent();
|
|
1712
|
+
return [
|
|
1713
|
+
2
|
|
1714
|
+
];
|
|
1715
|
+
}
|
|
1716
|
+
});
|
|
1717
|
+
})();
|
|
1718
|
+
});
|
|
1719
|
+
},
|
|
1720
|
+
clear: function clear() {
|
|
1721
|
+
return enqueueMutation(function() {
|
|
1722
|
+
return _async_to_generator(function() {
|
|
1723
|
+
return _ts_generator(this, function(_state) {
|
|
1724
|
+
switch(_state.label){
|
|
1725
|
+
case 0:
|
|
1726
|
+
return [
|
|
1727
|
+
4,
|
|
1728
|
+
removeFile(filePath)
|
|
1729
|
+
];
|
|
1730
|
+
case 1:
|
|
1731
|
+
_state.sent();
|
|
1732
|
+
return [
|
|
1733
|
+
2
|
|
1734
|
+
];
|
|
1735
|
+
}
|
|
1736
|
+
});
|
|
1737
|
+
})();
|
|
1738
|
+
});
|
|
1739
|
+
}
|
|
1740
|
+
};
|
|
1741
|
+
}
|
|
1742
|
+
/**
|
|
1743
|
+
* Convenience wrapper around {@link createJsonFileAsyncKeyedValueCache} composed with
|
|
1744
|
+
* {@link memoizeAsyncKeyedValueCache}.
|
|
1745
|
+
*
|
|
1746
|
+
* @param input - Same configuration accepted by {@link createJsonFileAsyncKeyedValueCache}; see {@link CreateJsonFileAsyncKeyedValueCacheInput}.
|
|
1747
|
+
* @returns An {@link AsyncKeyedValueCache} backed by the JSON file with a per-process record-level memoization layer in front.
|
|
1748
|
+
*/ function createMemoizedJsonFileAsyncKeyedValueCache(input) {
|
|
1749
|
+
return memoizeAsyncKeyedValueCache(createJsonFileAsyncKeyedValueCache(input));
|
|
1750
|
+
}
|
|
1751
|
+
|
|
1117
1752
|
// MARK: Constants
|
|
1118
1753
|
/**
|
|
1119
1754
|
* AES-256-GCM encryption constants.
|
|
@@ -1305,4 +1940,792 @@ var ENCRYPTED_FIELD_KEY_LENGTH = 32;
|
|
|
1305
1940
|
return result;
|
|
1306
1941
|
}
|
|
1307
1942
|
|
|
1308
|
-
|
|
1943
|
+
function _array_like_to_array(arr, len) {
|
|
1944
|
+
if (len == null || len > arr.length) len = arr.length;
|
|
1945
|
+
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
1946
|
+
return arr2;
|
|
1947
|
+
}
|
|
1948
|
+
function _array_with_holes(arr) {
|
|
1949
|
+
if (Array.isArray(arr)) return arr;
|
|
1950
|
+
}
|
|
1951
|
+
function _iterable_to_array_limit(arr, i) {
|
|
1952
|
+
var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
|
|
1953
|
+
if (_i == null) return;
|
|
1954
|
+
var _arr = [];
|
|
1955
|
+
var _n = true;
|
|
1956
|
+
var _d = false;
|
|
1957
|
+
var _s, _e;
|
|
1958
|
+
try {
|
|
1959
|
+
for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
|
|
1960
|
+
_arr.push(_s.value);
|
|
1961
|
+
if (i && _arr.length === i) break;
|
|
1962
|
+
}
|
|
1963
|
+
} catch (err) {
|
|
1964
|
+
_d = true;
|
|
1965
|
+
_e = err;
|
|
1966
|
+
} finally{
|
|
1967
|
+
try {
|
|
1968
|
+
if (!_n && _i["return"] != null) _i["return"]();
|
|
1969
|
+
} finally{
|
|
1970
|
+
if (_d) throw _e;
|
|
1971
|
+
}
|
|
1972
|
+
}
|
|
1973
|
+
return _arr;
|
|
1974
|
+
}
|
|
1975
|
+
function _non_iterable_rest() {
|
|
1976
|
+
throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
1977
|
+
}
|
|
1978
|
+
function _sliced_to_array(arr, i) {
|
|
1979
|
+
return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
|
|
1980
|
+
}
|
|
1981
|
+
function _unsupported_iterable_to_array(o, minLen) {
|
|
1982
|
+
if (!o) return;
|
|
1983
|
+
if (typeof o === "string") return _array_like_to_array(o, minLen);
|
|
1984
|
+
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
1985
|
+
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
1986
|
+
if (n === "Map" || n === "Set") return Array.from(n);
|
|
1987
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
|
|
1988
|
+
}
|
|
1989
|
+
/**
|
|
1990
|
+
* 32-byte password padding string defined by ISO 32000 §7.6.3.3 (Algorithm 2).
|
|
1991
|
+
* Used to pad short or empty user/owner passwords for the standard security handler.
|
|
1992
|
+
*/ var PDF_PASSWORD_PADDING = Buffer.from([
|
|
1993
|
+
0x28,
|
|
1994
|
+
0xbf,
|
|
1995
|
+
0x4e,
|
|
1996
|
+
0x5e,
|
|
1997
|
+
0x4e,
|
|
1998
|
+
0x75,
|
|
1999
|
+
0x8a,
|
|
2000
|
+
0x41,
|
|
2001
|
+
0x64,
|
|
2002
|
+
0x00,
|
|
2003
|
+
0x4e,
|
|
2004
|
+
0x56,
|
|
2005
|
+
0xff,
|
|
2006
|
+
0xfa,
|
|
2007
|
+
0x01,
|
|
2008
|
+
0x08,
|
|
2009
|
+
0x2e,
|
|
2010
|
+
0x2e,
|
|
2011
|
+
0x00,
|
|
2012
|
+
0xb6,
|
|
2013
|
+
0xd0,
|
|
2014
|
+
0x68,
|
|
2015
|
+
0x3e,
|
|
2016
|
+
0x80,
|
|
2017
|
+
0x2f,
|
|
2018
|
+
0x0c,
|
|
2019
|
+
0xa9,
|
|
2020
|
+
0xfe,
|
|
2021
|
+
0x64,
|
|
2022
|
+
0x53,
|
|
2023
|
+
0x69,
|
|
2024
|
+
0x7a
|
|
2025
|
+
]);
|
|
2026
|
+
/**
|
|
2027
|
+
* Detects whether a PDF is unencrypted, write-protected (openable without a password
|
|
2028
|
+
* but restricted from editing/printing), or fully encrypted (requires a password to open).
|
|
2029
|
+
*
|
|
2030
|
+
* Implements the user-password validation algorithms from ISO 32000-1 §7.6.3 (R≤4) and
|
|
2031
|
+
* ISO 32000-2 §7.6.4.4 (R=5/6) using only the empty password. If the empty password
|
|
2032
|
+
* validates successfully, the PDF is openable by anyone and only its modify/print/copy
|
|
2033
|
+
* permissions are restricted; otherwise a non-empty user password is required.
|
|
2034
|
+
*
|
|
2035
|
+
* Supported security handlers:
|
|
2036
|
+
* - Standard security handler, R=2,3,4 (RC4-40, RC4-128, AES-128 with crypt filters).
|
|
2037
|
+
* - Standard security handler, R=5 (AES-256, deprecated Adobe extension).
|
|
2038
|
+
* - Standard security handler, R=6 (AES-256, ISO 32000-2 / PDF 2.0).
|
|
2039
|
+
*
|
|
2040
|
+
* Unrecognised security handlers (e.g. PubSec, custom handlers) return
|
|
2041
|
+
* `unknown_encrypted` so callers can choose whether to treat them as fully encrypted.
|
|
2042
|
+
*
|
|
2043
|
+
* Lives in `@dereekb/nestjs` (rather than `@dereekb/util`) because it uses Node's
|
|
2044
|
+
* built-in `node:crypto` module, which isn't available in the browser.
|
|
2045
|
+
*
|
|
2046
|
+
* @example
|
|
2047
|
+
* ```ts
|
|
2048
|
+
* const status = detectPdfEncryption(buffer);
|
|
2049
|
+
*
|
|
2050
|
+
* if (status === 'fully_encrypted') {
|
|
2051
|
+
* throw new Error('PDF requires a password to open.');
|
|
2052
|
+
* }
|
|
2053
|
+
* if (status === 'write_protected_only') {
|
|
2054
|
+
* // Safe to read, but not to mutate without the owner password.
|
|
2055
|
+
* }
|
|
2056
|
+
* ```
|
|
2057
|
+
*
|
|
2058
|
+
* @param buffer - PDF file contents.
|
|
2059
|
+
* @returns The encryption status of the PDF.
|
|
2060
|
+
*/ function detectPdfEncryption(buffer) {
|
|
2061
|
+
var result = 'unknown_encrypted';
|
|
2062
|
+
var encryptIndex = findEncryptKeywordIndex(buffer);
|
|
2063
|
+
if (encryptIndex < 0) {
|
|
2064
|
+
result = 'none';
|
|
2065
|
+
} else {
|
|
2066
|
+
var dict = extractEncryptionDictionary(buffer, encryptIndex);
|
|
2067
|
+
var info = dict ? parseEncryptionInfo(dict) : null;
|
|
2068
|
+
if ((info === null || info === void 0 ? void 0 : info.filter) === 'Standard') {
|
|
2069
|
+
var opensWithEmptyPassword = checkStandardHandlerEmptyPassword(info, buffer);
|
|
2070
|
+
if (opensWithEmptyPassword !== null) {
|
|
2071
|
+
result = opensWithEmptyPassword ? 'write_protected_only' : 'fully_encrypted';
|
|
2072
|
+
}
|
|
2073
|
+
}
|
|
2074
|
+
}
|
|
2075
|
+
return result;
|
|
2076
|
+
}
|
|
2077
|
+
function checkStandardHandlerEmptyPassword(info, buffer) {
|
|
2078
|
+
var result = null;
|
|
2079
|
+
if (info.R >= 2 && info.R <= 4) {
|
|
2080
|
+
var fileId = extractFirstFileId(buffer);
|
|
2081
|
+
if (fileId && info.O.length >= 32 && info.U.length >= 32) {
|
|
2082
|
+
result = validateEmptyPasswordR2to4(info, fileId);
|
|
2083
|
+
}
|
|
2084
|
+
} else if (info.R === 5 && info.U.length >= 48) {
|
|
2085
|
+
result = validateEmptyPasswordR5(info);
|
|
2086
|
+
} else if (info.R === 6 && info.U.length >= 48) {
|
|
2087
|
+
result = validateEmptyPasswordR6(info);
|
|
2088
|
+
}
|
|
2089
|
+
return result;
|
|
2090
|
+
}
|
|
2091
|
+
function isPdfWhitespaceByte(b) {
|
|
2092
|
+
return b === 0x00 || b === 0x09 || b === 0x0a || b === 0x0c || b === 0x0d || b === 0x20;
|
|
2093
|
+
}
|
|
2094
|
+
function isPdfDelimiterByte(b) {
|
|
2095
|
+
return b === 0x28 || b === 0x29 || b === 0x3c || b === 0x3e || b === 0x5b || b === 0x5d || b === 0x7b || b === 0x7d || b === 0x2f || b === 0x25;
|
|
2096
|
+
}
|
|
2097
|
+
function isPdfWhitespaceOrDelimiter(b) {
|
|
2098
|
+
return isPdfWhitespaceByte(b) || isPdfDelimiterByte(b);
|
|
2099
|
+
}
|
|
2100
|
+
function skipPdfWhitespaceAndComments(buffer, start) {
|
|
2101
|
+
var i = start;
|
|
2102
|
+
while(i < buffer.length){
|
|
2103
|
+
var b = buffer[i];
|
|
2104
|
+
if (isPdfWhitespaceByte(b)) {
|
|
2105
|
+
i++;
|
|
2106
|
+
} else if (b === 0x25 /* % */ ) {
|
|
2107
|
+
while(i < buffer.length && buffer[i] !== 0x0a && buffer[i] !== 0x0d)i++;
|
|
2108
|
+
} else {
|
|
2109
|
+
break;
|
|
2110
|
+
}
|
|
2111
|
+
}
|
|
2112
|
+
return i;
|
|
2113
|
+
}
|
|
2114
|
+
function skipPdfLiteralString(buffer, start) {
|
|
2115
|
+
var depth = 1;
|
|
2116
|
+
var i = start + 1;
|
|
2117
|
+
while(i < buffer.length && depth > 0){
|
|
2118
|
+
var b = buffer[i];
|
|
2119
|
+
if (b === 0x5c /* \ */ ) {
|
|
2120
|
+
i += 2;
|
|
2121
|
+
} else if (b === 0x28 /* ( */ ) {
|
|
2122
|
+
depth++;
|
|
2123
|
+
i++;
|
|
2124
|
+
} else if (b === 0x29 /* ) */ ) {
|
|
2125
|
+
depth--;
|
|
2126
|
+
i++;
|
|
2127
|
+
} else {
|
|
2128
|
+
i++;
|
|
2129
|
+
}
|
|
2130
|
+
}
|
|
2131
|
+
return i;
|
|
2132
|
+
}
|
|
2133
|
+
function skipPdfHexString(buffer, start) {
|
|
2134
|
+
var i = start + 1;
|
|
2135
|
+
while(i < buffer.length && buffer[i] !== 0x3e /* > */ )i++;
|
|
2136
|
+
return i < buffer.length ? i + 1 : i;
|
|
2137
|
+
}
|
|
2138
|
+
function findDictEnd(buffer, start) {
|
|
2139
|
+
var depth = 1;
|
|
2140
|
+
var i = start;
|
|
2141
|
+
var endIndex = -1;
|
|
2142
|
+
while(i < buffer.length && endIndex < 0){
|
|
2143
|
+
var b = buffer[i];
|
|
2144
|
+
if (b === 0x3c && buffer[i + 1] === 0x3c) {
|
|
2145
|
+
depth++;
|
|
2146
|
+
i += 2;
|
|
2147
|
+
} else if (b === 0x3e && buffer[i + 1] === 0x3e) {
|
|
2148
|
+
depth--;
|
|
2149
|
+
if (depth === 0) {
|
|
2150
|
+
endIndex = i;
|
|
2151
|
+
} else {
|
|
2152
|
+
i += 2;
|
|
2153
|
+
}
|
|
2154
|
+
} else if (b === 0x28) {
|
|
2155
|
+
i = skipPdfLiteralString(buffer, i);
|
|
2156
|
+
} else if (b === 0x3c) {
|
|
2157
|
+
i = skipPdfHexString(buffer, i);
|
|
2158
|
+
} else if (b === 0x25) {
|
|
2159
|
+
while(i < buffer.length && buffer[i] !== 0x0a && buffer[i] !== 0x0d)i++;
|
|
2160
|
+
} else {
|
|
2161
|
+
i++;
|
|
2162
|
+
}
|
|
2163
|
+
}
|
|
2164
|
+
return endIndex >= 0 ? endIndex : i;
|
|
2165
|
+
}
|
|
2166
|
+
function decodePdfLiteralString(content) {
|
|
2167
|
+
var out = [];
|
|
2168
|
+
var i = 0;
|
|
2169
|
+
while(i < content.length){
|
|
2170
|
+
var b = content[i];
|
|
2171
|
+
if (b !== 0x5c /* \ */ ) {
|
|
2172
|
+
out.push(b);
|
|
2173
|
+
i++;
|
|
2174
|
+
continue;
|
|
2175
|
+
}
|
|
2176
|
+
i++;
|
|
2177
|
+
if (i >= content.length) break;
|
|
2178
|
+
var c = content[i];
|
|
2179
|
+
if (c >= 0x30 && c <= 0x37) {
|
|
2180
|
+
var oct = c - 0x30;
|
|
2181
|
+
i++;
|
|
2182
|
+
if (i < content.length && content[i] >= 0x30 && content[i] <= 0x37) {
|
|
2183
|
+
oct = oct * 8 + (content[i] - 0x30);
|
|
2184
|
+
i++;
|
|
2185
|
+
if (i < content.length && content[i] >= 0x30 && content[i] <= 0x37) {
|
|
2186
|
+
oct = oct * 8 + (content[i] - 0x30);
|
|
2187
|
+
i++;
|
|
2188
|
+
}
|
|
2189
|
+
}
|
|
2190
|
+
out.push(oct & 0xff);
|
|
2191
|
+
} else if (c === 0x6e /* n */ ) {
|
|
2192
|
+
out.push(0x0a);
|
|
2193
|
+
i++;
|
|
2194
|
+
} else if (c === 0x72 /* r */ ) {
|
|
2195
|
+
out.push(0x0d);
|
|
2196
|
+
i++;
|
|
2197
|
+
} else if (c === 0x74 /* t */ ) {
|
|
2198
|
+
out.push(0x09);
|
|
2199
|
+
i++;
|
|
2200
|
+
} else if (c === 0x62 /* b */ ) {
|
|
2201
|
+
out.push(0x08);
|
|
2202
|
+
i++;
|
|
2203
|
+
} else if (c === 0x66 /* f */ ) {
|
|
2204
|
+
out.push(0x0c);
|
|
2205
|
+
i++;
|
|
2206
|
+
} else if (c === 0x0a) {
|
|
2207
|
+
i++;
|
|
2208
|
+
} else if (c === 0x0d) {
|
|
2209
|
+
i++;
|
|
2210
|
+
if (i < content.length && content[i] === 0x0a) i++;
|
|
2211
|
+
} else {
|
|
2212
|
+
out.push(c);
|
|
2213
|
+
i++;
|
|
2214
|
+
}
|
|
2215
|
+
}
|
|
2216
|
+
return Buffer.from(out);
|
|
2217
|
+
}
|
|
2218
|
+
function decodePdfHexString(content) {
|
|
2219
|
+
var hex = [];
|
|
2220
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
2221
|
+
try {
|
|
2222
|
+
for(var _iterator = content[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
2223
|
+
var b = _step.value;
|
|
2224
|
+
if (isPdfWhitespaceByte(b)) continue;
|
|
2225
|
+
if (b >= 0x30 && b <= 0x39 || b >= 0x41 && b <= 0x46 || b >= 0x61 && b <= 0x66) hex.push(b);
|
|
2226
|
+
}
|
|
2227
|
+
} catch (err) {
|
|
2228
|
+
_didIteratorError = true;
|
|
2229
|
+
_iteratorError = err;
|
|
2230
|
+
} finally{
|
|
2231
|
+
try {
|
|
2232
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
2233
|
+
_iterator.return();
|
|
2234
|
+
}
|
|
2235
|
+
} finally{
|
|
2236
|
+
if (_didIteratorError) {
|
|
2237
|
+
throw _iteratorError;
|
|
2238
|
+
}
|
|
2239
|
+
}
|
|
2240
|
+
}
|
|
2241
|
+
if (hex.length % 2 === 1) hex.push(0x30);
|
|
2242
|
+
var out = Buffer.alloc(hex.length / 2);
|
|
2243
|
+
for(var i = 0; i < out.length; i++){
|
|
2244
|
+
out[i] = parseInt(String.fromCharCode(hex[i * 2], hex[i * 2 + 1]), 16);
|
|
2245
|
+
}
|
|
2246
|
+
return out;
|
|
2247
|
+
}
|
|
2248
|
+
function readPdfNumber(buffer, start) {
|
|
2249
|
+
var i = start;
|
|
2250
|
+
while(i < buffer.length && !isPdfWhitespaceOrDelimiter(buffer[i]))i++;
|
|
2251
|
+
var result = null;
|
|
2252
|
+
if (i > start) {
|
|
2253
|
+
var text = buffer.toString('latin1', start, i);
|
|
2254
|
+
var value = Number(text);
|
|
2255
|
+
if (!Number.isNaN(value)) {
|
|
2256
|
+
result = {
|
|
2257
|
+
value: value,
|
|
2258
|
+
end: i
|
|
2259
|
+
};
|
|
2260
|
+
}
|
|
2261
|
+
}
|
|
2262
|
+
return result;
|
|
2263
|
+
}
|
|
2264
|
+
function parsePdfDict(buffer, dictStart) {
|
|
2265
|
+
// dictStart is the byte after `<<`.
|
|
2266
|
+
var entries = new Map();
|
|
2267
|
+
var i = skipPdfWhitespaceAndComments(buffer, dictStart);
|
|
2268
|
+
var result = null;
|
|
2269
|
+
var aborted = false;
|
|
2270
|
+
while(i < buffer.length && !aborted && result === null){
|
|
2271
|
+
if (buffer[i] === 0x3e && buffer[i + 1] === 0x3e) {
|
|
2272
|
+
result = {
|
|
2273
|
+
entries: entries,
|
|
2274
|
+
end: i + 2
|
|
2275
|
+
};
|
|
2276
|
+
} else if (buffer[i] !== 0x2f /* / */ ) {
|
|
2277
|
+
aborted = true;
|
|
2278
|
+
} else {
|
|
2279
|
+
var nameStart = i + 1;
|
|
2280
|
+
var nameEnd = nameStart;
|
|
2281
|
+
while(nameEnd < buffer.length && !isPdfWhitespaceOrDelimiter(buffer[nameEnd]))nameEnd++;
|
|
2282
|
+
var name = buffer.toString('latin1', nameStart, nameEnd);
|
|
2283
|
+
i = skipPdfWhitespaceAndComments(buffer, nameEnd);
|
|
2284
|
+
if (i >= buffer.length) {
|
|
2285
|
+
aborted = true;
|
|
2286
|
+
} else {
|
|
2287
|
+
var valueResult = readPdfValue(buffer, i);
|
|
2288
|
+
if (!valueResult) {
|
|
2289
|
+
aborted = true;
|
|
2290
|
+
} else {
|
|
2291
|
+
entries.set(name, valueResult.entry);
|
|
2292
|
+
i = skipPdfWhitespaceAndComments(buffer, valueResult.end);
|
|
2293
|
+
}
|
|
2294
|
+
}
|
|
2295
|
+
}
|
|
2296
|
+
}
|
|
2297
|
+
return result;
|
|
2298
|
+
}
|
|
2299
|
+
function readPdfValue(buffer, start) {
|
|
2300
|
+
var b = buffer[start];
|
|
2301
|
+
var result;
|
|
2302
|
+
if (b === 0x3c && buffer[start + 1] === 0x3c) {
|
|
2303
|
+
result = readPdfDictValue(buffer, start);
|
|
2304
|
+
} else if (b === 0x3c) {
|
|
2305
|
+
result = readPdfHexStringValue(buffer, start);
|
|
2306
|
+
} else if (b === 0x28) {
|
|
2307
|
+
result = readPdfLiteralStringValue(buffer, start);
|
|
2308
|
+
} else if (b === 0x5b /* [ */ ) {
|
|
2309
|
+
result = readPdfArrayValue(buffer, start);
|
|
2310
|
+
} else if (b === 0x2f /* / */ ) {
|
|
2311
|
+
result = readPdfNameValue(buffer, start);
|
|
2312
|
+
} else {
|
|
2313
|
+
result = readPdfTokenOrRefValue(buffer, start);
|
|
2314
|
+
}
|
|
2315
|
+
return result;
|
|
2316
|
+
}
|
|
2317
|
+
function readPdfDictValue(buffer, start) {
|
|
2318
|
+
var dictEnd = findDictEnd(buffer, start + 2);
|
|
2319
|
+
var end = dictEnd < buffer.length && buffer[dictEnd] === 0x3e && buffer[dictEnd + 1] === 0x3e ? dictEnd + 2 : dictEnd;
|
|
2320
|
+
return {
|
|
2321
|
+
entry: {
|
|
2322
|
+
type: 'dict',
|
|
2323
|
+
raw: buffer.subarray(start, end)
|
|
2324
|
+
},
|
|
2325
|
+
end: end
|
|
2326
|
+
};
|
|
2327
|
+
}
|
|
2328
|
+
function readPdfHexStringValue(buffer, start) {
|
|
2329
|
+
var end = skipPdfHexString(buffer, start);
|
|
2330
|
+
return {
|
|
2331
|
+
entry: {
|
|
2332
|
+
type: 'string',
|
|
2333
|
+
raw: decodePdfHexString(buffer.subarray(start + 1, end - 1))
|
|
2334
|
+
},
|
|
2335
|
+
end: end
|
|
2336
|
+
};
|
|
2337
|
+
}
|
|
2338
|
+
function readPdfLiteralStringValue(buffer, start) {
|
|
2339
|
+
var end = skipPdfLiteralString(buffer, start);
|
|
2340
|
+
return {
|
|
2341
|
+
entry: {
|
|
2342
|
+
type: 'string',
|
|
2343
|
+
raw: decodePdfLiteralString(buffer.subarray(start + 1, end - 1))
|
|
2344
|
+
},
|
|
2345
|
+
end: end
|
|
2346
|
+
};
|
|
2347
|
+
}
|
|
2348
|
+
function readPdfArrayValue(buffer, start) {
|
|
2349
|
+
var depth = 1;
|
|
2350
|
+
var i = start + 1;
|
|
2351
|
+
while(i < buffer.length && depth > 0){
|
|
2352
|
+
var c = buffer[i];
|
|
2353
|
+
if (c === 0x5b) {
|
|
2354
|
+
depth++;
|
|
2355
|
+
i++;
|
|
2356
|
+
} else if (c === 0x5d) {
|
|
2357
|
+
depth--;
|
|
2358
|
+
i++;
|
|
2359
|
+
} else if (c === 0x28) {
|
|
2360
|
+
i = skipPdfLiteralString(buffer, i);
|
|
2361
|
+
} else if (c === 0x3c && buffer[i + 1] === 0x3c) {
|
|
2362
|
+
var e = findDictEnd(buffer, i + 2);
|
|
2363
|
+
i = e < buffer.length && buffer[e] === 0x3e && buffer[e + 1] === 0x3e ? e + 2 : e;
|
|
2364
|
+
} else if (c === 0x3c) {
|
|
2365
|
+
i = skipPdfHexString(buffer, i);
|
|
2366
|
+
} else if (c === 0x25) {
|
|
2367
|
+
while(i < buffer.length && buffer[i] !== 0x0a && buffer[i] !== 0x0d)i++;
|
|
2368
|
+
} else {
|
|
2369
|
+
i++;
|
|
2370
|
+
}
|
|
2371
|
+
}
|
|
2372
|
+
return {
|
|
2373
|
+
entry: {
|
|
2374
|
+
type: 'array',
|
|
2375
|
+
raw: buffer.subarray(start, i)
|
|
2376
|
+
},
|
|
2377
|
+
end: i
|
|
2378
|
+
};
|
|
2379
|
+
}
|
|
2380
|
+
function readPdfNameValue(buffer, start) {
|
|
2381
|
+
var i = start + 1;
|
|
2382
|
+
while(i < buffer.length && !isPdfWhitespaceOrDelimiter(buffer[i]))i++;
|
|
2383
|
+
return {
|
|
2384
|
+
entry: {
|
|
2385
|
+
type: 'name',
|
|
2386
|
+
raw: buffer.subarray(start + 1, i)
|
|
2387
|
+
},
|
|
2388
|
+
end: i
|
|
2389
|
+
};
|
|
2390
|
+
}
|
|
2391
|
+
function readPdfTokenOrRefValue(buffer, start) {
|
|
2392
|
+
// Number, boolean, null, or indirect reference like `12 0 R`.
|
|
2393
|
+
var i = start;
|
|
2394
|
+
while(i < buffer.length && !isPdfWhitespaceOrDelimiter(buffer[i]))i++;
|
|
2395
|
+
var tokenEnd = i;
|
|
2396
|
+
var token = buffer.toString('latin1', start, tokenEnd);
|
|
2397
|
+
var referenceEnd = readIndirectReferenceEnd(buffer, tokenEnd);
|
|
2398
|
+
var result;
|
|
2399
|
+
if (referenceEnd !== null) {
|
|
2400
|
+
result = {
|
|
2401
|
+
entry: {
|
|
2402
|
+
type: 'ref',
|
|
2403
|
+
raw: buffer.subarray(start, referenceEnd)
|
|
2404
|
+
},
|
|
2405
|
+
end: referenceEnd
|
|
2406
|
+
};
|
|
2407
|
+
} else if (token === 'true' || token === 'false') {
|
|
2408
|
+
result = {
|
|
2409
|
+
entry: {
|
|
2410
|
+
type: 'boolean',
|
|
2411
|
+
raw: buffer.subarray(start, tokenEnd)
|
|
2412
|
+
},
|
|
2413
|
+
end: tokenEnd
|
|
2414
|
+
};
|
|
2415
|
+
} else if (token === 'null') {
|
|
2416
|
+
result = {
|
|
2417
|
+
entry: {
|
|
2418
|
+
type: 'null',
|
|
2419
|
+
raw: buffer.subarray(start, tokenEnd)
|
|
2420
|
+
},
|
|
2421
|
+
end: tokenEnd
|
|
2422
|
+
};
|
|
2423
|
+
} else {
|
|
2424
|
+
result = {
|
|
2425
|
+
entry: {
|
|
2426
|
+
type: 'number',
|
|
2427
|
+
raw: buffer.subarray(start, tokenEnd)
|
|
2428
|
+
},
|
|
2429
|
+
end: tokenEnd
|
|
2430
|
+
};
|
|
2431
|
+
}
|
|
2432
|
+
return result;
|
|
2433
|
+
}
|
|
2434
|
+
function readIndirectReferenceEnd(buffer, tokenEnd) {
|
|
2435
|
+
// Probe ahead for `GEN R` after a leading object number to detect `N G R`.
|
|
2436
|
+
var result = null;
|
|
2437
|
+
var probe = skipPdfWhitespaceAndComments(buffer, tokenEnd);
|
|
2438
|
+
if (probe < buffer.length) {
|
|
2439
|
+
var c = buffer[probe];
|
|
2440
|
+
if (c >= 0x30 && c <= 0x39) {
|
|
2441
|
+
var secondEnd = probe;
|
|
2442
|
+
while(secondEnd < buffer.length && !isPdfWhitespaceOrDelimiter(buffer[secondEnd]))secondEnd++;
|
|
2443
|
+
var probe2 = skipPdfWhitespaceAndComments(buffer, secondEnd);
|
|
2444
|
+
if (probe2 < buffer.length && buffer[probe2] === 0x52 /* R */ && (probe2 + 1 === buffer.length || isPdfWhitespaceOrDelimiter(buffer[probe2 + 1]))) {
|
|
2445
|
+
result = probe2 + 1;
|
|
2446
|
+
}
|
|
2447
|
+
}
|
|
2448
|
+
}
|
|
2449
|
+
return result;
|
|
2450
|
+
}
|
|
2451
|
+
function findEncryptKeywordIndex(buffer) {
|
|
2452
|
+
var marker = PDF_ENCRYPT_MARKER;
|
|
2453
|
+
var last = -1;
|
|
2454
|
+
var pos = 0;
|
|
2455
|
+
while(true){
|
|
2456
|
+
var found = buffer.indexOf(marker, pos);
|
|
2457
|
+
if (found < 0) break;
|
|
2458
|
+
var next = buffer[found + marker.length];
|
|
2459
|
+
// Avoid matching `/EncryptMetadata` (a different name).
|
|
2460
|
+
var isAlpha = next >= 0x41 && next <= 0x5a || next >= 0x61 && next <= 0x7a;
|
|
2461
|
+
if (!isAlpha) last = found;
|
|
2462
|
+
pos = found + marker.length;
|
|
2463
|
+
}
|
|
2464
|
+
return last;
|
|
2465
|
+
}
|
|
2466
|
+
function extractEncryptionDictionary(buffer, encryptIndex) {
|
|
2467
|
+
var result = null;
|
|
2468
|
+
var i = encryptIndex + PDF_ENCRYPT_MARKER.length;
|
|
2469
|
+
i = skipPdfWhitespaceAndComments(buffer, i);
|
|
2470
|
+
if (i < buffer.length) {
|
|
2471
|
+
if (buffer[i] === 0x3c && buffer[i + 1] === 0x3c) {
|
|
2472
|
+
// Inline dictionary.
|
|
2473
|
+
var dictEnd = findDictEnd(buffer, i + 2);
|
|
2474
|
+
result = buffer.subarray(i, dictEnd + 2);
|
|
2475
|
+
} else {
|
|
2476
|
+
// Indirect reference: `N G R`.
|
|
2477
|
+
result = resolveIndirectEncryptionDictionary(buffer, i);
|
|
2478
|
+
}
|
|
2479
|
+
}
|
|
2480
|
+
return result;
|
|
2481
|
+
}
|
|
2482
|
+
function resolveIndirectEncryptionDictionary(buffer, start) {
|
|
2483
|
+
var result = null;
|
|
2484
|
+
var numResult = readPdfNumber(buffer, start);
|
|
2485
|
+
if (numResult) {
|
|
2486
|
+
var afterFirst = skipPdfWhitespaceAndComments(buffer, numResult.end);
|
|
2487
|
+
var genResult = readPdfNumber(buffer, afterFirst);
|
|
2488
|
+
if (genResult) {
|
|
2489
|
+
var afterSecond = skipPdfWhitespaceAndComments(buffer, genResult.end);
|
|
2490
|
+
if (buffer[afterSecond] === 0x52 /* R */ ) {
|
|
2491
|
+
var objStart = findIndirectObjectStart(buffer, numResult.value, genResult.value);
|
|
2492
|
+
if (objStart >= 0) {
|
|
2493
|
+
var dictStart = buffer.indexOf('<<', objStart);
|
|
2494
|
+
if (dictStart >= 0) {
|
|
2495
|
+
var dictEnd = findDictEnd(buffer, dictStart + 2);
|
|
2496
|
+
result = buffer.subarray(dictStart, dictEnd + 2);
|
|
2497
|
+
}
|
|
2498
|
+
}
|
|
2499
|
+
}
|
|
2500
|
+
}
|
|
2501
|
+
}
|
|
2502
|
+
return result;
|
|
2503
|
+
}
|
|
2504
|
+
function findIndirectObjectStart(buffer, objNum, objGen) {
|
|
2505
|
+
var text = buffer.toString('latin1');
|
|
2506
|
+
var re = new RegExp("(?:^|[\\r\\n\\s])".concat(objNum, "\\s+").concat(objGen, "\\s+obj\\b"));
|
|
2507
|
+
var match = re.exec(text);
|
|
2508
|
+
return match ? match.index + match[0].length : -1;
|
|
2509
|
+
}
|
|
2510
|
+
function parseEncryptionInfo(dictBuffer) {
|
|
2511
|
+
// `dictBuffer` is the full `<< ... >>`; pass the body to parsePdfDict.
|
|
2512
|
+
var result = null;
|
|
2513
|
+
var isDict = dictBuffer.length >= 4 && dictBuffer[0] === 0x3c && dictBuffer[1] === 0x3c;
|
|
2514
|
+
var parsed = isDict ? parsePdfDict(dictBuffer, 2) : null;
|
|
2515
|
+
if (parsed) {
|
|
2516
|
+
var _readNameValue, _readNumberValue, _readNumberValue1, _readNumberValue2, _readStringValue, _readStringValue1, _readNumberValue3, _readBooleanValue;
|
|
2517
|
+
var entries = parsed.entries;
|
|
2518
|
+
var filter = (_readNameValue = readNameValue(entries.get('Filter'))) !== null && _readNameValue !== void 0 ? _readNameValue : '';
|
|
2519
|
+
var V = (_readNumberValue = readNumberValue(entries.get('V'))) !== null && _readNumberValue !== void 0 ? _readNumberValue : 0;
|
|
2520
|
+
var R = (_readNumberValue1 = readNumberValue(entries.get('R'))) !== null && _readNumberValue1 !== void 0 ? _readNumberValue1 : 0;
|
|
2521
|
+
var Length = (_readNumberValue2 = readNumberValue(entries.get('Length'))) !== null && _readNumberValue2 !== void 0 ? _readNumberValue2 : V >= 5 ? 256 : 40;
|
|
2522
|
+
var O = (_readStringValue = readStringValue(entries.get('O'))) !== null && _readStringValue !== void 0 ? _readStringValue : Buffer.alloc(0);
|
|
2523
|
+
var U = (_readStringValue1 = readStringValue(entries.get('U'))) !== null && _readStringValue1 !== void 0 ? _readStringValue1 : Buffer.alloc(0);
|
|
2524
|
+
var P = (_readNumberValue3 = readNumberValue(entries.get('P'))) !== null && _readNumberValue3 !== void 0 ? _readNumberValue3 : 0;
|
|
2525
|
+
var encryptMetadataEntry = entries.get('EncryptMetadata');
|
|
2526
|
+
var encryptMetadata = encryptMetadataEntry ? (_readBooleanValue = readBooleanValue(encryptMetadataEntry)) !== null && _readBooleanValue !== void 0 ? _readBooleanValue : true : true;
|
|
2527
|
+
if (R !== 0 && V !== 0) {
|
|
2528
|
+
result = {
|
|
2529
|
+
filter: filter,
|
|
2530
|
+
V: V,
|
|
2531
|
+
R: R,
|
|
2532
|
+
Length: Length,
|
|
2533
|
+
O: O,
|
|
2534
|
+
U: U,
|
|
2535
|
+
P: P,
|
|
2536
|
+
encryptMetadata: encryptMetadata
|
|
2537
|
+
};
|
|
2538
|
+
}
|
|
2539
|
+
}
|
|
2540
|
+
return result;
|
|
2541
|
+
}
|
|
2542
|
+
function readNumberValue(entry) {
|
|
2543
|
+
var result = null;
|
|
2544
|
+
if ((entry === null || entry === void 0 ? void 0 : entry.type) === 'number') {
|
|
2545
|
+
var value = Number(entry.raw.toString('latin1'));
|
|
2546
|
+
if (!Number.isNaN(value)) {
|
|
2547
|
+
result = value;
|
|
2548
|
+
}
|
|
2549
|
+
}
|
|
2550
|
+
return result;
|
|
2551
|
+
}
|
|
2552
|
+
function readNameValue(entry) {
|
|
2553
|
+
return (entry === null || entry === void 0 ? void 0 : entry.type) === 'name' ? entry.raw.toString('latin1') : null;
|
|
2554
|
+
}
|
|
2555
|
+
function readStringValue(entry) {
|
|
2556
|
+
return (entry === null || entry === void 0 ? void 0 : entry.type) === 'string' ? entry.raw : null;
|
|
2557
|
+
}
|
|
2558
|
+
function readBooleanValue(entry) {
|
|
2559
|
+
return entry.type === 'boolean' ? entry.raw.toString('latin1') === 'true' : null;
|
|
2560
|
+
}
|
|
2561
|
+
function extractFirstFileId(buffer) {
|
|
2562
|
+
// The /ID array lives in the trailer or the cross-reference stream dictionary.
|
|
2563
|
+
// Walk the buffer right-to-left to find the most recent /ID array.
|
|
2564
|
+
var result = null;
|
|
2565
|
+
var pos = buffer.length;
|
|
2566
|
+
var done = false;
|
|
2567
|
+
while(pos > 0 && !done){
|
|
2568
|
+
var found = buffer.lastIndexOf('/ID', pos);
|
|
2569
|
+
if (found < 0) {
|
|
2570
|
+
done = true;
|
|
2571
|
+
} else {
|
|
2572
|
+
var after = found + 3;
|
|
2573
|
+
var isExactName = after >= buffer.length || isPdfWhitespaceOrDelimiter(buffer[after]);
|
|
2574
|
+
if (isExactName) {
|
|
2575
|
+
var i = skipPdfWhitespaceAndComments(buffer, after);
|
|
2576
|
+
if (buffer[i] === 0x5b /* [ */ ) {
|
|
2577
|
+
i = skipPdfWhitespaceAndComments(buffer, i + 1);
|
|
2578
|
+
var valueResult = readPdfValue(buffer, i);
|
|
2579
|
+
if ((valueResult === null || valueResult === void 0 ? void 0 : valueResult.entry.type) === 'string') {
|
|
2580
|
+
result = valueResult.entry.raw;
|
|
2581
|
+
done = true;
|
|
2582
|
+
}
|
|
2583
|
+
}
|
|
2584
|
+
}
|
|
2585
|
+
if (!done) {
|
|
2586
|
+
pos = found - 1;
|
|
2587
|
+
}
|
|
2588
|
+
}
|
|
2589
|
+
}
|
|
2590
|
+
return result;
|
|
2591
|
+
}
|
|
2592
|
+
// MARK: Standard security handler — empty-password validation
|
|
2593
|
+
function rc4(key, data) {
|
|
2594
|
+
var S = new Uint8Array(256);
|
|
2595
|
+
for(var i = 0; i < 256; i++)S[i] = i;
|
|
2596
|
+
var j = 0;
|
|
2597
|
+
for(var i1 = 0; i1 < 256; i1++){
|
|
2598
|
+
j = j + S[i1] + key[i1 % key.length] & 0xff;
|
|
2599
|
+
var t = S[i1];
|
|
2600
|
+
S[i1] = S[j];
|
|
2601
|
+
S[j] = t;
|
|
2602
|
+
}
|
|
2603
|
+
var out = Buffer.alloc(data.length);
|
|
2604
|
+
var ii = 0;
|
|
2605
|
+
var jj = 0;
|
|
2606
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
2607
|
+
try {
|
|
2608
|
+
for(var _iterator = data.entries()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
2609
|
+
var _step_value = _sliced_to_array(_step.value, 2), n = _step_value[0], byte = _step_value[1];
|
|
2610
|
+
ii = ii + 1 & 0xff;
|
|
2611
|
+
jj = jj + S[ii] & 0xff;
|
|
2612
|
+
var t1 = S[ii];
|
|
2613
|
+
S[ii] = S[jj];
|
|
2614
|
+
S[jj] = t1;
|
|
2615
|
+
out[n] = byte ^ S[S[ii] + S[jj] & 0xff];
|
|
2616
|
+
}
|
|
2617
|
+
} catch (err) {
|
|
2618
|
+
_didIteratorError = true;
|
|
2619
|
+
_iteratorError = err;
|
|
2620
|
+
} finally{
|
|
2621
|
+
try {
|
|
2622
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
2623
|
+
_iterator.return();
|
|
2624
|
+
}
|
|
2625
|
+
} finally{
|
|
2626
|
+
if (_didIteratorError) {
|
|
2627
|
+
throw _iteratorError;
|
|
2628
|
+
}
|
|
2629
|
+
}
|
|
2630
|
+
}
|
|
2631
|
+
return out;
|
|
2632
|
+
}
|
|
2633
|
+
function computeFileEncryptionKeyR2to4(info, password, fileId) {
|
|
2634
|
+
var padded = Buffer.alloc(32);
|
|
2635
|
+
password.copy(padded, 0, 0, Math.min(password.length, 32));
|
|
2636
|
+
if (password.length < 32) PDF_PASSWORD_PADDING.copy(padded, password.length, 0, 32 - password.length);
|
|
2637
|
+
var md5 = createHash('md5');
|
|
2638
|
+
md5.update(padded);
|
|
2639
|
+
md5.update(info.O);
|
|
2640
|
+
var pBytes = Buffer.alloc(4);
|
|
2641
|
+
pBytes.writeInt32LE(info.P | 0, 0);
|
|
2642
|
+
md5.update(pBytes);
|
|
2643
|
+
md5.update(fileId);
|
|
2644
|
+
if (info.R >= 4 && !info.encryptMetadata) md5.update(Buffer.from([
|
|
2645
|
+
0xff,
|
|
2646
|
+
0xff,
|
|
2647
|
+
0xff,
|
|
2648
|
+
0xff
|
|
2649
|
+
]));
|
|
2650
|
+
var key = md5.digest();
|
|
2651
|
+
var keyBytes = Math.min(Math.floor(info.Length / 8), key.length);
|
|
2652
|
+
if (info.R >= 3) {
|
|
2653
|
+
for(var i = 0; i < 50; i++){
|
|
2654
|
+
key = createHash('md5').update(key.subarray(0, keyBytes)).digest();
|
|
2655
|
+
}
|
|
2656
|
+
}
|
|
2657
|
+
return key.subarray(0, keyBytes);
|
|
2658
|
+
}
|
|
2659
|
+
function validateEmptyPasswordR2to4(info, fileId) {
|
|
2660
|
+
var password = Buffer.alloc(0);
|
|
2661
|
+
var key = computeFileEncryptionKeyR2to4(info, password, fileId);
|
|
2662
|
+
var matches;
|
|
2663
|
+
if (info.R === 2) {
|
|
2664
|
+
var expected = rc4(key, PDF_PASSWORD_PADDING);
|
|
2665
|
+
matches = constantTimeEquals(expected, info.U.subarray(0, 32));
|
|
2666
|
+
} else {
|
|
2667
|
+
var computed = createHash('md5').update(PDF_PASSWORD_PADDING).update(fileId).digest();
|
|
2668
|
+
computed = rc4(key, computed);
|
|
2669
|
+
for(var i = 1; i <= 19; i++){
|
|
2670
|
+
var xorKey = Buffer.alloc(key.length);
|
|
2671
|
+
for(var j = 0; j < key.length; j++)xorKey[j] = key[j] ^ i;
|
|
2672
|
+
computed = rc4(xorKey, computed);
|
|
2673
|
+
}
|
|
2674
|
+
matches = constantTimeEquals(computed, info.U.subarray(0, 16));
|
|
2675
|
+
}
|
|
2676
|
+
return matches;
|
|
2677
|
+
}
|
|
2678
|
+
function validateEmptyPasswordR5(info) {
|
|
2679
|
+
var validationSalt = info.U.subarray(32, 40);
|
|
2680
|
+
var computed = createHash('sha256').update(validationSalt).digest();
|
|
2681
|
+
return constantTimeEquals(computed, info.U.subarray(0, 32));
|
|
2682
|
+
}
|
|
2683
|
+
function validateEmptyPasswordR6(info) {
|
|
2684
|
+
var validationSalt = info.U.subarray(32, 40);
|
|
2685
|
+
var password = Buffer.alloc(0);
|
|
2686
|
+
var computed = pdfAlgorithm2B(Buffer.concat([
|
|
2687
|
+
password,
|
|
2688
|
+
validationSalt
|
|
2689
|
+
]), password, Buffer.alloc(0));
|
|
2690
|
+
return constantTimeEquals(computed, info.U.subarray(0, 32));
|
|
2691
|
+
}
|
|
2692
|
+
function pdfAlgorithm2B(input, password, userKey) {
|
|
2693
|
+
var K = createHash('sha256').update(input).digest();
|
|
2694
|
+
var round = 0;
|
|
2695
|
+
var lastE = Buffer.alloc(0);
|
|
2696
|
+
while(true){
|
|
2697
|
+
var part = Buffer.concat([
|
|
2698
|
+
password,
|
|
2699
|
+
K,
|
|
2700
|
+
userKey
|
|
2701
|
+
]);
|
|
2702
|
+
var K1 = Buffer.alloc(part.length * 64);
|
|
2703
|
+
for(var i = 0; i < 64; i++)part.copy(K1, i * part.length);
|
|
2704
|
+
var cipher = createCipheriv('aes-128-cbc', K.subarray(0, 16), K.subarray(16, 32));
|
|
2705
|
+
cipher.setAutoPadding(false);
|
|
2706
|
+
var E = Buffer.concat([
|
|
2707
|
+
cipher.update(K1),
|
|
2708
|
+
cipher.final()
|
|
2709
|
+
]);
|
|
2710
|
+
lastE = E;
|
|
2711
|
+
var n = 0;
|
|
2712
|
+
for(var i1 = 0; i1 < 16; i1++)n = (n * 256 + E[i1]) % 3;
|
|
2713
|
+
if (n === 0) K = createHash('sha256').update(E).digest();
|
|
2714
|
+
else if (n === 1) K = createHash('sha384').update(E).digest();
|
|
2715
|
+
else K = createHash('sha512').update(E).digest();
|
|
2716
|
+
round++;
|
|
2717
|
+
if (round >= 64 && lastE[lastE.length - 1] <= round - 32) break;
|
|
2718
|
+
}
|
|
2719
|
+
return K.subarray(0, 32);
|
|
2720
|
+
}
|
|
2721
|
+
function constantTimeEquals(a, b) {
|
|
2722
|
+
var result = false;
|
|
2723
|
+
if (a.length === b.length) {
|
|
2724
|
+
var diff = 0;
|
|
2725
|
+
for(var i = 0; i < a.length; i++)diff |= a[i] ^ b[i];
|
|
2726
|
+
result = diff === 0;
|
|
2727
|
+
}
|
|
2728
|
+
return result;
|
|
2729
|
+
}
|
|
2730
|
+
|
|
2731
|
+
export { AppModuleWithWebhooksEnabled, CLIENT_WEB_APP_URL_ENV_VAR, ClientAppModule, ClientAppService, ClientAppServiceConfig, ConfigureWebhookMiddlewareModule, DEFAULT_BASE_WEBHOOK_PATH, DEFAULT_JSON_FILE_CACHE_MODE, DEFAULT_WEBHOOK_MIDDLEWARE_ROUTE_INFO, IsRequestFromLocalHost, JsonBodyMiddleware, ParseRawBody, ParsedQueryRawBody, RawBody, RawBodyMiddleware, RawBodyToJson, RawBodyToParsedQueryString, RawBodyToString, SERVER_ENV_TOKEN, ServerEnvironmentConfig, ServerEnvironmentService, appAssetLoaderModuleMetadata, clientAppConfigFactory, consumeWebhooksWithRawBodyMiddleware, createAES256GCMEncryption, createAesStringEncryptionProvider, createJsonFileAsyncKeyedValueCache, createJsonFileAsyncValueCache, createMemoizedJsonFileAsyncKeyedValueCache, createMemoizedJsonFileAsyncValueCache, decryptValue, detectPdfEncryption, encryptValue, injectionTokensFromProviders, isLocalhost, isTestNodeEnv, isValidAES256GCMEncryptionSecret, mergeModuleMetadata, nodeJsLocalAssetLoader, readJsonFile, removeFile, resolveEncryptionKey, serverEnvTokenProvider, writeJsonFile };
|