@pallasoft/ps-utilities 1.3.0 → 2.0.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/dist/client/http-service.d.ts +3 -0
- package/dist/client/http-service.js +14 -6
- package/dist/common/crypto-service.d.ts +11 -0
- package/dist/common/crypto-service.js +120 -4
- package/dist/common/encrypted-fields-service.d.ts +10 -0
- package/dist/common/encrypted-fields-service.js +178 -0
- package/dist/common/envelope-crypto-service.d.ts +17 -0
- package/dist/common/envelope-crypto-service.js +167 -0
- package/dist/common/index.d.ts +3 -0
- package/dist/common/index.js +3 -0
- package/dist/common/recaptcha-service.d.ts +0 -1
- package/dist/common/recaptcha-service.js +5 -3
- package/dist/index.d.ts +2 -0
- package/package.json +1 -1
|
@@ -16,5 +16,8 @@ export declare class HttpService {
|
|
|
16
16
|
static createApiClient(options?: CreateApiClientOptions): {
|
|
17
17
|
get: <T>(url: string, config?: PsHttpRequestConfig) => Promise<PsHttpResponse<T>>;
|
|
18
18
|
post: <T>(url: string, data?: unknown, config?: PsHttpRequestConfig) => Promise<PsHttpResponse<T>>;
|
|
19
|
+
put: <T>(url: string, data?: unknown, config?: PsHttpRequestConfig) => Promise<PsHttpResponse<T>>;
|
|
20
|
+
patch: <T>(url: string, data?: unknown, config?: PsHttpRequestConfig) => Promise<PsHttpResponse<T>>;
|
|
21
|
+
delete: <T>(url: string, config?: PsHttpRequestConfig) => Promise<PsHttpResponse<T>>;
|
|
19
22
|
};
|
|
20
23
|
}
|
|
@@ -52,9 +52,8 @@ var HttpService = /** @class */ (function () {
|
|
|
52
52
|
var apiKey = options.apiKey, _a = options.apiKeyHeader, apiKeyHeader = _a === void 0 ? 'X-API-Key' : _a, baseURL = options.baseURL;
|
|
53
53
|
var request = function (method, url, data, config) { return __awaiter(_this, void 0, void 0, function () {
|
|
54
54
|
var fullUrl, sendsBinaryBody, headers, body, response, responseData, error;
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
switch (_b.label) {
|
|
55
|
+
return __generator(this, function (_a) {
|
|
56
|
+
switch (_a.label) {
|
|
58
57
|
case 0:
|
|
59
58
|
fullUrl = baseURL ? "".concat(baseURL).concat(url) : url;
|
|
60
59
|
sendsBinaryBody = isBinaryBody(data);
|
|
@@ -68,18 +67,18 @@ var HttpService = /** @class */ (function () {
|
|
|
68
67
|
body = data === undefined ? undefined : sendsBinaryBody ? data : JSON.stringify(data);
|
|
69
68
|
return [4 /*yield*/, fetch(fullUrl, { method: method, headers: headers, body: body })];
|
|
70
69
|
case 1:
|
|
71
|
-
response =
|
|
70
|
+
response = _a.sent();
|
|
72
71
|
return [4 /*yield*/, ((config === null || config === void 0 ? void 0 : config.responseType) === 'arraybuffer'
|
|
73
72
|
? response.arrayBuffer()
|
|
74
73
|
: (config === null || config === void 0 ? void 0 : config.responseType) === 'text'
|
|
75
74
|
? response.text()
|
|
76
75
|
: (config === null || config === void 0 ? void 0 : config.responseType) === 'json'
|
|
77
76
|
? response.json()
|
|
78
|
-
: (
|
|
77
|
+
: String(response.headers.get('content-type')).includes('application/json')
|
|
79
78
|
? response.json()
|
|
80
79
|
: response.text())];
|
|
81
80
|
case 2:
|
|
82
|
-
responseData =
|
|
81
|
+
responseData = _a.sent();
|
|
83
82
|
if (!response.ok) {
|
|
84
83
|
error = new Error("Request failed with status ".concat(response.status));
|
|
85
84
|
error.response = { data: responseData, status: response.status };
|
|
@@ -96,6 +95,15 @@ var HttpService = /** @class */ (function () {
|
|
|
96
95
|
post: function (url, data, config) {
|
|
97
96
|
return request('POST', url, data, config);
|
|
98
97
|
},
|
|
98
|
+
put: function (url, data, config) {
|
|
99
|
+
return request('PUT', url, data, config);
|
|
100
|
+
},
|
|
101
|
+
patch: function (url, data, config) {
|
|
102
|
+
return request('PATCH', url, data, config);
|
|
103
|
+
},
|
|
104
|
+
delete: function (url, config) {
|
|
105
|
+
return request('DELETE', url, undefined, config);
|
|
106
|
+
},
|
|
99
107
|
};
|
|
100
108
|
};
|
|
101
109
|
return HttpService;
|
|
@@ -7,6 +7,8 @@ export declare class CryptoService {
|
|
|
7
7
|
private static _textEncoder;
|
|
8
8
|
private static _textDecoder;
|
|
9
9
|
private static _payloadVersion;
|
|
10
|
+
private static _dataKeyPayloadVersion;
|
|
11
|
+
private static _dataKeyLength;
|
|
10
12
|
private static _payloadAlgorithm;
|
|
11
13
|
private static _aad;
|
|
12
14
|
private static _toBase64;
|
|
@@ -15,5 +17,14 @@ export declare class CryptoService {
|
|
|
15
17
|
private static _parsePayload;
|
|
16
18
|
private static _deriveKey;
|
|
17
19
|
static encryptPayload(payload: Record<string, unknown>, cryptoKey: string): Promise<string>;
|
|
20
|
+
private static _importDataKey;
|
|
21
|
+
static generateDataKey(): string;
|
|
22
|
+
static encryptPayloadWithDataKey(payload: Record<string, unknown>, dataKey: string): Promise<string>;
|
|
23
|
+
static decryptPayloadWithDataKey<T>(encryptedPayload: string, dataKey: string): Promise<T>;
|
|
24
|
+
static encryptValueWithDataKey(value: string, dataKey: string): Promise<string>;
|
|
25
|
+
static decryptValueWithDataKey(encryptedPayload: string, dataKey: string): Promise<string>;
|
|
26
|
+
static encryptValue(value: string, cryptoKey: string): Promise<string>;
|
|
27
|
+
static decryptValue(encryptedPayload: string, cryptoKey: string): Promise<string>;
|
|
28
|
+
static isEncryptedPayload(candidate: string): boolean;
|
|
18
29
|
static decryptPayload<T>(encryptedPayload: string, cryptoKey: string): Promise<T>;
|
|
19
30
|
}
|
|
@@ -60,11 +60,12 @@ var CryptoService = /** @class */ (function () {
|
|
|
60
60
|
};
|
|
61
61
|
CryptoService._parsePayload = function (encryptedPayload) {
|
|
62
62
|
var payload = JSON.parse(encryptedPayload);
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
var isDerived = payload.v === this._payloadVersion && Boolean(payload.salt);
|
|
64
|
+
var isDataKey = payload.v === this._dataKeyPayloadVersion;
|
|
65
|
+
if (payload.alg !== this._payloadAlgorithm ||
|
|
65
66
|
!payload.iv ||
|
|
66
|
-
!payload.
|
|
67
|
-
!
|
|
67
|
+
!payload.ciphertext ||
|
|
68
|
+
(!isDerived && !isDataKey)) {
|
|
68
69
|
throw new Error('Encrypted payload is malformed');
|
|
69
70
|
}
|
|
70
71
|
return payload;
|
|
@@ -121,6 +122,119 @@ var CryptoService = /** @class */ (function () {
|
|
|
121
122
|
});
|
|
122
123
|
});
|
|
123
124
|
};
|
|
125
|
+
CryptoService._importDataKey = function (dataKey) {
|
|
126
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
127
|
+
return __generator(this, function (_a) {
|
|
128
|
+
switch (_a.label) {
|
|
129
|
+
case 0: return [4 /*yield*/, crypto.subtle.importKey('raw', this._fromBase64(dataKey), { name: this._algorithm, length: this._keyLength }, false, ['encrypt', 'decrypt'])];
|
|
130
|
+
case 1: return [2 /*return*/, _a.sent()];
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
};
|
|
135
|
+
CryptoService.generateDataKey = function () {
|
|
136
|
+
return this._toBase64(crypto.getRandomValues(new Uint8Array(this._dataKeyLength)));
|
|
137
|
+
};
|
|
138
|
+
CryptoService.encryptPayloadWithDataKey = function (payload, dataKey) {
|
|
139
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
140
|
+
var iv, encryptedBuffer, _a, _b, _c;
|
|
141
|
+
return __generator(this, function (_d) {
|
|
142
|
+
switch (_d.label) {
|
|
143
|
+
case 0:
|
|
144
|
+
iv = crypto.getRandomValues(new Uint8Array(this._ivLength));
|
|
145
|
+
_b = (_a = crypto.subtle).encrypt;
|
|
146
|
+
_c = [{ name: this._algorithm, iv: iv, additionalData: this._getAdditionalData() }];
|
|
147
|
+
return [4 /*yield*/, this._importDataKey(dataKey)];
|
|
148
|
+
case 1: return [4 /*yield*/, _b.apply(_a, _c.concat([_d.sent(), this._textEncoder.encode(JSON.stringify(payload))]))];
|
|
149
|
+
case 2:
|
|
150
|
+
encryptedBuffer = _d.sent();
|
|
151
|
+
return [2 /*return*/, JSON.stringify({
|
|
152
|
+
v: this._dataKeyPayloadVersion,
|
|
153
|
+
alg: this._payloadAlgorithm,
|
|
154
|
+
iv: this._toBase64(iv),
|
|
155
|
+
ciphertext: this._toBase64(new Uint8Array(encryptedBuffer)),
|
|
156
|
+
})];
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
};
|
|
161
|
+
CryptoService.decryptPayloadWithDataKey = function (encryptedPayload, dataKey) {
|
|
162
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
163
|
+
var payload, decryptedBuffer, _a, _b, _c;
|
|
164
|
+
return __generator(this, function (_d) {
|
|
165
|
+
switch (_d.label) {
|
|
166
|
+
case 0:
|
|
167
|
+
payload = this._parsePayload(encryptedPayload);
|
|
168
|
+
_b = (_a = crypto.subtle).decrypt;
|
|
169
|
+
_c = [{
|
|
170
|
+
name: this._algorithm,
|
|
171
|
+
iv: this._fromBase64(payload.iv),
|
|
172
|
+
additionalData: this._getAdditionalData(),
|
|
173
|
+
}];
|
|
174
|
+
return [4 /*yield*/, this._importDataKey(dataKey)];
|
|
175
|
+
case 1: return [4 /*yield*/, _b.apply(_a, _c.concat([_d.sent(), this._fromBase64(payload.ciphertext)]))];
|
|
176
|
+
case 2:
|
|
177
|
+
decryptedBuffer = _d.sent();
|
|
178
|
+
return [2 /*return*/, JSON.parse(this._textDecoder.decode(decryptedBuffer))];
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
};
|
|
183
|
+
CryptoService.encryptValueWithDataKey = function (value, dataKey) {
|
|
184
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
185
|
+
return __generator(this, function (_a) {
|
|
186
|
+
switch (_a.label) {
|
|
187
|
+
case 0: return [4 /*yield*/, this.encryptPayloadWithDataKey({ value: value }, dataKey)];
|
|
188
|
+
case 1: return [2 /*return*/, _a.sent()];
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
};
|
|
193
|
+
CryptoService.decryptValueWithDataKey = function (encryptedPayload, dataKey) {
|
|
194
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
195
|
+
var value;
|
|
196
|
+
return __generator(this, function (_a) {
|
|
197
|
+
switch (_a.label) {
|
|
198
|
+
case 0: return [4 /*yield*/, this.decryptPayloadWithDataKey(encryptedPayload, dataKey)];
|
|
199
|
+
case 1:
|
|
200
|
+
value = (_a.sent()).value;
|
|
201
|
+
return [2 /*return*/, value];
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
});
|
|
205
|
+
};
|
|
206
|
+
CryptoService.encryptValue = function (value, cryptoKey) {
|
|
207
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
208
|
+
return __generator(this, function (_a) {
|
|
209
|
+
switch (_a.label) {
|
|
210
|
+
case 0: return [4 /*yield*/, this.encryptPayload({ value: value }, cryptoKey)];
|
|
211
|
+
case 1: return [2 /*return*/, _a.sent()];
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
};
|
|
216
|
+
CryptoService.decryptValue = function (encryptedPayload, cryptoKey) {
|
|
217
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
218
|
+
var value;
|
|
219
|
+
return __generator(this, function (_a) {
|
|
220
|
+
switch (_a.label) {
|
|
221
|
+
case 0: return [4 /*yield*/, this.decryptPayload(encryptedPayload, cryptoKey)];
|
|
222
|
+
case 1:
|
|
223
|
+
value = (_a.sent()).value;
|
|
224
|
+
return [2 /*return*/, value];
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
};
|
|
229
|
+
CryptoService.isEncryptedPayload = function (candidate) {
|
|
230
|
+
try {
|
|
231
|
+
this._parsePayload(candidate);
|
|
232
|
+
return true;
|
|
233
|
+
}
|
|
234
|
+
catch (_a) {
|
|
235
|
+
return false;
|
|
236
|
+
}
|
|
237
|
+
};
|
|
124
238
|
CryptoService.decryptPayload = function (encryptedPayload, cryptoKey) {
|
|
125
239
|
return __awaiter(this, void 0, void 0, function () {
|
|
126
240
|
var payload, key, decryptedBuffer;
|
|
@@ -151,6 +265,8 @@ var CryptoService = /** @class */ (function () {
|
|
|
151
265
|
CryptoService._textEncoder = new TextEncoder();
|
|
152
266
|
CryptoService._textDecoder = new TextDecoder();
|
|
153
267
|
CryptoService._payloadVersion = 1;
|
|
268
|
+
CryptoService._dataKeyPayloadVersion = 2;
|
|
269
|
+
CryptoService._dataKeyLength = 32;
|
|
154
270
|
CryptoService._payloadAlgorithm = 'A256GCM';
|
|
155
271
|
CryptoService._aad = 'encrypted-form:v1:a256gcm';
|
|
156
272
|
return CryptoService;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface EncryptedFieldsSpec<T> {
|
|
2
|
+
json?: readonly (keyof T)[];
|
|
3
|
+
values?: readonly (keyof T)[];
|
|
4
|
+
}
|
|
5
|
+
export declare class EncryptedFieldsService {
|
|
6
|
+
private static _isBlank;
|
|
7
|
+
static encrypt<Row extends object, Entity extends object>(row: Row, spec: EncryptedFieldsSpec<Entity>, wrappedDataKey: string, masterKey: string): Promise<Row>;
|
|
8
|
+
static decrypt<Row extends object, Entity extends object>(row: Row, spec: EncryptedFieldsSpec<Entity>, wrappedDataKey: string, masterKey: string): Promise<Row>;
|
|
9
|
+
static decryptMany<Row extends object, Entity extends object>(rows: Row[], spec: EncryptedFieldsSpec<Entity>, wrappedDataKey: string, masterKey: string): Promise<Row[]>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __assign = (this && this.__assign) || function () {
|
|
3
|
+
__assign = Object.assign || function(t) {
|
|
4
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
+
s = arguments[i];
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
}
|
|
9
|
+
return t;
|
|
10
|
+
};
|
|
11
|
+
return __assign.apply(this, arguments);
|
|
12
|
+
};
|
|
13
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
14
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
15
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
16
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
17
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
18
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
19
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
23
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
24
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
25
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
26
|
+
function step(op) {
|
|
27
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
28
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
29
|
+
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;
|
|
30
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
31
|
+
switch (op[0]) {
|
|
32
|
+
case 0: case 1: t = op; break;
|
|
33
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
34
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
35
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
36
|
+
default:
|
|
37
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
38
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
39
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
40
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
41
|
+
if (t[2]) _.ops.pop();
|
|
42
|
+
_.trys.pop(); continue;
|
|
43
|
+
}
|
|
44
|
+
op = body.call(thisArg, _);
|
|
45
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
46
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
|
+
exports.EncryptedFieldsService = void 0;
|
|
51
|
+
var envelope_crypto_service_1 = require("./envelope-crypto-service");
|
|
52
|
+
var EncryptedFieldsService = /** @class */ (function () {
|
|
53
|
+
function EncryptedFieldsService() {
|
|
54
|
+
}
|
|
55
|
+
EncryptedFieldsService._isBlank = function (value) {
|
|
56
|
+
return value === null || value === undefined || value === '';
|
|
57
|
+
};
|
|
58
|
+
EncryptedFieldsService.encrypt = function (row, spec, wrappedDataKey, masterKey) {
|
|
59
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
60
|
+
var encrypted, _i, _a, field, value, _b, _c, _d, _e, field, value, _f, _g;
|
|
61
|
+
return __generator(this, function (_h) {
|
|
62
|
+
switch (_h.label) {
|
|
63
|
+
case 0:
|
|
64
|
+
encrypted = __assign({}, row);
|
|
65
|
+
_i = 0, _a = (spec.values !== null && spec.values !== undefined
|
|
66
|
+
? spec.values
|
|
67
|
+
: []);
|
|
68
|
+
_h.label = 1;
|
|
69
|
+
case 1:
|
|
70
|
+
if (!(_i < _a.length)) return [3 /*break*/, 4];
|
|
71
|
+
field = _a[_i];
|
|
72
|
+
value = encrypted[field];
|
|
73
|
+
if (this._isBlank(value))
|
|
74
|
+
return [3 /*break*/, 3];
|
|
75
|
+
_b = encrypted;
|
|
76
|
+
_c = field;
|
|
77
|
+
return [4 /*yield*/, envelope_crypto_service_1.EnvelopeCryptoService.encryptValue(value, wrappedDataKey, masterKey)];
|
|
78
|
+
case 2:
|
|
79
|
+
_b[_c] = _h.sent();
|
|
80
|
+
_h.label = 3;
|
|
81
|
+
case 3:
|
|
82
|
+
_i++;
|
|
83
|
+
return [3 /*break*/, 1];
|
|
84
|
+
case 4:
|
|
85
|
+
_d = 0, _e = (spec.json !== null && spec.json !== undefined
|
|
86
|
+
? spec.json
|
|
87
|
+
: []);
|
|
88
|
+
_h.label = 5;
|
|
89
|
+
case 5:
|
|
90
|
+
if (!(_d < _e.length)) return [3 /*break*/, 8];
|
|
91
|
+
field = _e[_d];
|
|
92
|
+
value = encrypted[field];
|
|
93
|
+
if (this._isBlank(value))
|
|
94
|
+
return [3 /*break*/, 7];
|
|
95
|
+
_f = encrypted;
|
|
96
|
+
_g = field;
|
|
97
|
+
return [4 /*yield*/, envelope_crypto_service_1.EnvelopeCryptoService.encryptPayload(value, wrappedDataKey, masterKey)];
|
|
98
|
+
case 6:
|
|
99
|
+
_f[_g] = _h.sent();
|
|
100
|
+
_h.label = 7;
|
|
101
|
+
case 7:
|
|
102
|
+
_d++;
|
|
103
|
+
return [3 /*break*/, 5];
|
|
104
|
+
case 8: return [2 /*return*/, encrypted];
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
};
|
|
109
|
+
EncryptedFieldsService.decrypt = function (row, spec, wrappedDataKey, masterKey) {
|
|
110
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
111
|
+
var decrypted, _i, _a, field, value, _b, _c, _d, _e, field, value, _f, _g;
|
|
112
|
+
return __generator(this, function (_h) {
|
|
113
|
+
switch (_h.label) {
|
|
114
|
+
case 0:
|
|
115
|
+
decrypted = __assign({}, row);
|
|
116
|
+
_i = 0, _a = (spec.values !== null && spec.values !== undefined
|
|
117
|
+
? spec.values
|
|
118
|
+
: []);
|
|
119
|
+
_h.label = 1;
|
|
120
|
+
case 1:
|
|
121
|
+
if (!(_i < _a.length)) return [3 /*break*/, 4];
|
|
122
|
+
field = _a[_i];
|
|
123
|
+
value = decrypted[field];
|
|
124
|
+
if (this._isBlank(value))
|
|
125
|
+
return [3 /*break*/, 3];
|
|
126
|
+
_b = decrypted;
|
|
127
|
+
_c = field;
|
|
128
|
+
return [4 /*yield*/, envelope_crypto_service_1.EnvelopeCryptoService.decryptValue(value, wrappedDataKey, masterKey)];
|
|
129
|
+
case 2:
|
|
130
|
+
_b[_c] = _h.sent();
|
|
131
|
+
_h.label = 3;
|
|
132
|
+
case 3:
|
|
133
|
+
_i++;
|
|
134
|
+
return [3 /*break*/, 1];
|
|
135
|
+
case 4:
|
|
136
|
+
_d = 0, _e = (spec.json !== null && spec.json !== undefined
|
|
137
|
+
? spec.json
|
|
138
|
+
: []);
|
|
139
|
+
_h.label = 5;
|
|
140
|
+
case 5:
|
|
141
|
+
if (!(_d < _e.length)) return [3 /*break*/, 8];
|
|
142
|
+
field = _e[_d];
|
|
143
|
+
value = decrypted[field];
|
|
144
|
+
if (this._isBlank(value))
|
|
145
|
+
return [3 /*break*/, 7];
|
|
146
|
+
_f = decrypted;
|
|
147
|
+
_g = field;
|
|
148
|
+
return [4 /*yield*/, envelope_crypto_service_1.EnvelopeCryptoService.decryptPayload(value, wrappedDataKey, masterKey)];
|
|
149
|
+
case 6:
|
|
150
|
+
_f[_g] = _h.sent();
|
|
151
|
+
_h.label = 7;
|
|
152
|
+
case 7:
|
|
153
|
+
_d++;
|
|
154
|
+
return [3 /*break*/, 5];
|
|
155
|
+
case 8: return [2 /*return*/, decrypted];
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
};
|
|
160
|
+
EncryptedFieldsService.decryptMany = function (rows, spec, wrappedDataKey, masterKey) {
|
|
161
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
162
|
+
var _this = this;
|
|
163
|
+
return __generator(this, function (_a) {
|
|
164
|
+
switch (_a.label) {
|
|
165
|
+
case 0: return [4 /*yield*/, Promise.all(rows.map(function (row) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
|
|
166
|
+
switch (_a.label) {
|
|
167
|
+
case 0: return [4 /*yield*/, this.decrypt(row, spec, wrappedDataKey, masterKey)];
|
|
168
|
+
case 1: return [2 /*return*/, _a.sent()];
|
|
169
|
+
}
|
|
170
|
+
}); }); }))];
|
|
171
|
+
case 1: return [2 /*return*/, _a.sent()];
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
};
|
|
176
|
+
return EncryptedFieldsService;
|
|
177
|
+
}());
|
|
178
|
+
exports.EncryptedFieldsService = EncryptedFieldsService;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface DataKeyPair {
|
|
2
|
+
dataKey: string;
|
|
3
|
+
wrappedDataKey: string;
|
|
4
|
+
}
|
|
5
|
+
export declare class EnvelopeCryptoService {
|
|
6
|
+
private static _cache;
|
|
7
|
+
private static _cacheLimit;
|
|
8
|
+
private static _remember;
|
|
9
|
+
static createDataKey(masterKey: string): Promise<DataKeyPair>;
|
|
10
|
+
static unwrapDataKey(wrappedDataKey: string, masterKey: string): Promise<string>;
|
|
11
|
+
static rewrapDataKey(wrappedDataKey: string, currentMasterKey: string, nextMasterKey: string): Promise<string>;
|
|
12
|
+
static encryptValue(value: string, wrappedDataKey: string, masterKey: string): Promise<string>;
|
|
13
|
+
static decryptValue(encryptedPayload: string, wrappedDataKey: string, masterKey: string): Promise<string>;
|
|
14
|
+
static encryptPayload(payload: Record<string, unknown>, wrappedDataKey: string, masterKey: string): Promise<string>;
|
|
15
|
+
static decryptPayload<T>(encryptedPayload: string, wrappedDataKey: string, masterKey: string): Promise<T>;
|
|
16
|
+
static forget(wrappedDataKey: string): void;
|
|
17
|
+
}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
13
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
+
function step(op) {
|
|
16
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
18
|
+
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;
|
|
19
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
+
switch (op[0]) {
|
|
21
|
+
case 0: case 1: t = op; break;
|
|
22
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
+
default:
|
|
26
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
+
if (t[2]) _.ops.pop();
|
|
31
|
+
_.trys.pop(); continue;
|
|
32
|
+
}
|
|
33
|
+
op = body.call(thisArg, _);
|
|
34
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.EnvelopeCryptoService = void 0;
|
|
40
|
+
var crypto_service_1 = require("./crypto-service");
|
|
41
|
+
var EnvelopeCryptoService = /** @class */ (function () {
|
|
42
|
+
function EnvelopeCryptoService() {
|
|
43
|
+
}
|
|
44
|
+
EnvelopeCryptoService._remember = function (wrappedDataKey, dataKey) {
|
|
45
|
+
if (this._cache.size >= this._cacheLimit) {
|
|
46
|
+
var oldest = this._cache.keys().next().value;
|
|
47
|
+
if (oldest)
|
|
48
|
+
this._cache.delete(oldest);
|
|
49
|
+
}
|
|
50
|
+
this._cache.set(wrappedDataKey, dataKey);
|
|
51
|
+
};
|
|
52
|
+
EnvelopeCryptoService.createDataKey = function (masterKey) {
|
|
53
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
54
|
+
var dataKey, wrappedDataKey;
|
|
55
|
+
return __generator(this, function (_a) {
|
|
56
|
+
switch (_a.label) {
|
|
57
|
+
case 0:
|
|
58
|
+
dataKey = crypto_service_1.CryptoService.generateDataKey();
|
|
59
|
+
return [4 /*yield*/, crypto_service_1.CryptoService.encryptValue(dataKey, masterKey)];
|
|
60
|
+
case 1:
|
|
61
|
+
wrappedDataKey = _a.sent();
|
|
62
|
+
this._remember(wrappedDataKey, dataKey);
|
|
63
|
+
return [2 /*return*/, { dataKey: dataKey, wrappedDataKey: wrappedDataKey }];
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
};
|
|
68
|
+
EnvelopeCryptoService.unwrapDataKey = function (wrappedDataKey, masterKey) {
|
|
69
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
70
|
+
var cached, dataKey;
|
|
71
|
+
return __generator(this, function (_a) {
|
|
72
|
+
switch (_a.label) {
|
|
73
|
+
case 0:
|
|
74
|
+
cached = this._cache.get(wrappedDataKey);
|
|
75
|
+
if (cached)
|
|
76
|
+
return [2 /*return*/, cached];
|
|
77
|
+
return [4 /*yield*/, crypto_service_1.CryptoService.decryptValue(wrappedDataKey, masterKey)];
|
|
78
|
+
case 1:
|
|
79
|
+
dataKey = _a.sent();
|
|
80
|
+
this._remember(wrappedDataKey, dataKey);
|
|
81
|
+
return [2 /*return*/, dataKey];
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
};
|
|
86
|
+
EnvelopeCryptoService.rewrapDataKey = function (wrappedDataKey, currentMasterKey, nextMasterKey) {
|
|
87
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
88
|
+
var dataKey;
|
|
89
|
+
return __generator(this, function (_a) {
|
|
90
|
+
switch (_a.label) {
|
|
91
|
+
case 0: return [4 /*yield*/, this.unwrapDataKey(wrappedDataKey, currentMasterKey)];
|
|
92
|
+
case 1:
|
|
93
|
+
dataKey = _a.sent();
|
|
94
|
+
return [4 /*yield*/, crypto_service_1.CryptoService.encryptValue(dataKey, nextMasterKey)];
|
|
95
|
+
case 2: return [2 /*return*/, _a.sent()];
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
};
|
|
100
|
+
EnvelopeCryptoService.encryptValue = function (value, wrappedDataKey, masterKey) {
|
|
101
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
102
|
+
var _a, _b, _c;
|
|
103
|
+
return __generator(this, function (_d) {
|
|
104
|
+
switch (_d.label) {
|
|
105
|
+
case 0:
|
|
106
|
+
_b = (_a = crypto_service_1.CryptoService).encryptValueWithDataKey;
|
|
107
|
+
_c = [value];
|
|
108
|
+
return [4 /*yield*/, this.unwrapDataKey(wrappedDataKey, masterKey)];
|
|
109
|
+
case 1: return [4 /*yield*/, _b.apply(_a, _c.concat([_d.sent()]))];
|
|
110
|
+
case 2: return [2 /*return*/, _d.sent()];
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
};
|
|
115
|
+
EnvelopeCryptoService.decryptValue = function (encryptedPayload, wrappedDataKey, masterKey) {
|
|
116
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
117
|
+
var _a, _b, _c;
|
|
118
|
+
return __generator(this, function (_d) {
|
|
119
|
+
switch (_d.label) {
|
|
120
|
+
case 0:
|
|
121
|
+
_b = (_a = crypto_service_1.CryptoService).decryptValueWithDataKey;
|
|
122
|
+
_c = [encryptedPayload];
|
|
123
|
+
return [4 /*yield*/, this.unwrapDataKey(wrappedDataKey, masterKey)];
|
|
124
|
+
case 1: return [4 /*yield*/, _b.apply(_a, _c.concat([_d.sent()]))];
|
|
125
|
+
case 2: return [2 /*return*/, _d.sent()];
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
};
|
|
130
|
+
EnvelopeCryptoService.encryptPayload = function (payload, wrappedDataKey, masterKey) {
|
|
131
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
132
|
+
var _a, _b, _c;
|
|
133
|
+
return __generator(this, function (_d) {
|
|
134
|
+
switch (_d.label) {
|
|
135
|
+
case 0:
|
|
136
|
+
_b = (_a = crypto_service_1.CryptoService).encryptPayloadWithDataKey;
|
|
137
|
+
_c = [payload];
|
|
138
|
+
return [4 /*yield*/, this.unwrapDataKey(wrappedDataKey, masterKey)];
|
|
139
|
+
case 1: return [4 /*yield*/, _b.apply(_a, _c.concat([_d.sent()]))];
|
|
140
|
+
case 2: return [2 /*return*/, _d.sent()];
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
};
|
|
145
|
+
EnvelopeCryptoService.decryptPayload = function (encryptedPayload, wrappedDataKey, masterKey) {
|
|
146
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
147
|
+
var _a, _b, _c;
|
|
148
|
+
return __generator(this, function (_d) {
|
|
149
|
+
switch (_d.label) {
|
|
150
|
+
case 0:
|
|
151
|
+
_b = (_a = crypto_service_1.CryptoService).decryptPayloadWithDataKey;
|
|
152
|
+
_c = [encryptedPayload];
|
|
153
|
+
return [4 /*yield*/, this.unwrapDataKey(wrappedDataKey, masterKey)];
|
|
154
|
+
case 1: return [4 /*yield*/, _b.apply(_a, _c.concat([_d.sent()]))];
|
|
155
|
+
case 2: return [2 /*return*/, _d.sent()];
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
};
|
|
160
|
+
EnvelopeCryptoService.forget = function (wrappedDataKey) {
|
|
161
|
+
this._cache.delete(wrappedDataKey);
|
|
162
|
+
};
|
|
163
|
+
EnvelopeCryptoService._cache = new Map();
|
|
164
|
+
EnvelopeCryptoService._cacheLimit = 500;
|
|
165
|
+
return EnvelopeCryptoService;
|
|
166
|
+
}());
|
|
167
|
+
exports.EnvelopeCryptoService = EnvelopeCryptoService;
|
package/dist/common/index.d.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
export * from './color-service';
|
|
2
2
|
export * from './crypto-service';
|
|
3
|
+
export * from './encrypted-fields-service';
|
|
4
|
+
export * from './envelope-crypto-service';
|
|
3
5
|
export * from './date-service';
|
|
4
6
|
export * from './number-format-service';
|
|
5
7
|
export * from './recaptcha-service';
|
|
6
8
|
export * from './url-service';
|
|
7
9
|
export * from './string-service';
|
|
10
|
+
export * from './transform-service';
|
package/dist/common/index.js
CHANGED
|
@@ -16,8 +16,11 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./color-service"), exports);
|
|
18
18
|
__exportStar(require("./crypto-service"), exports);
|
|
19
|
+
__exportStar(require("./encrypted-fields-service"), exports);
|
|
20
|
+
__exportStar(require("./envelope-crypto-service"), exports);
|
|
19
21
|
__exportStar(require("./date-service"), exports);
|
|
20
22
|
__exportStar(require("./number-format-service"), exports);
|
|
21
23
|
__exportStar(require("./recaptcha-service"), exports);
|
|
22
24
|
__exportStar(require("./url-service"), exports);
|
|
23
25
|
__exportStar(require("./string-service"), exports);
|
|
26
|
+
__exportStar(require("./transform-service"), exports);
|
|
@@ -46,10 +46,13 @@ var RecaptchaService = /** @class */ (function () {
|
|
|
46
46
|
return __generator(this, function (_a) {
|
|
47
47
|
switch (_a.label) {
|
|
48
48
|
case 0:
|
|
49
|
+
if (!process.env.RECAPTCHA_VERIFY_URL) {
|
|
50
|
+
throw new Error('No reCAPTCHA verify URL found');
|
|
51
|
+
}
|
|
49
52
|
params = new URLSearchParams({ secret: secretKey, response: token });
|
|
50
53
|
if (remoteIp)
|
|
51
54
|
params.set('remoteip', remoteIp);
|
|
52
|
-
return [4 /*yield*/, fetch(
|
|
55
|
+
return [4 /*yield*/, fetch(process.env.RECAPTCHA_VERIFY_URL, {
|
|
53
56
|
method: 'POST',
|
|
54
57
|
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
55
58
|
body: params.toString(),
|
|
@@ -64,13 +67,12 @@ var RecaptchaService = /** @class */ (function () {
|
|
|
64
67
|
data = (_a.sent());
|
|
65
68
|
return [2 /*return*/, {
|
|
66
69
|
success: !!data.success,
|
|
67
|
-
errorCodes: data['error-codes']
|
|
70
|
+
errorCodes: data['error-codes'] ? data['error-codes'] : [],
|
|
68
71
|
}];
|
|
69
72
|
}
|
|
70
73
|
});
|
|
71
74
|
});
|
|
72
75
|
};
|
|
73
|
-
RecaptchaService._verifyUrl = 'https://www.google.com/recaptcha/api/siteverify';
|
|
74
76
|
return RecaptchaService;
|
|
75
77
|
}());
|
|
76
78
|
exports.RecaptchaService = RecaptchaService;
|
package/dist/index.d.ts
CHANGED
|
@@ -2,3 +2,5 @@ import * as ClientNamespace from './client';
|
|
|
2
2
|
import * as CommonNamespace from './common';
|
|
3
3
|
export declare const Common: typeof CommonNamespace;
|
|
4
4
|
export declare const Client: typeof ClientNamespace;
|
|
5
|
+
export type { EncryptedFieldsSpec } from './common/encrypted-fields-service';
|
|
6
|
+
export type { DataKeyPair } from './common/envelope-crypto-service';
|