@voiceflow/encryption 0.2.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/README.md +94 -0
- package/build/cjs/aes-256-gcm.d.ts +49 -0
- package/build/cjs/aes-256-gcm.d.ts.map +1 -0
- package/build/cjs/aes-256-gcm.js +34 -0
- package/build/cjs/aes-256-gcm.js.map +1 -0
- package/build/cjs/aes-256-gcm.test.d.ts +2 -0
- package/build/cjs/aes-256-gcm.test.d.ts.map +1 -0
- package/build/cjs/aes-256-gcm.test.js +43 -0
- package/build/cjs/aes-256-gcm.test.js.map +1 -0
- package/build/cjs/encryption.const.d.ts +2 -0
- package/build/cjs/encryption.const.d.ts.map +1 -0
- package/build/cjs/encryption.const.js +5 -0
- package/build/cjs/encryption.const.js.map +1 -0
- package/build/cjs/encryption.interface.d.ts +9 -0
- package/build/cjs/encryption.interface.d.ts.map +1 -0
- package/build/cjs/encryption.interface.js +3 -0
- package/build/cjs/encryption.interface.js.map +1 -0
- package/build/cjs/encryption.module.d.ts +7 -0
- package/build/cjs/encryption.module.d.ts.map +1 -0
- package/build/cjs/encryption.module.js +99 -0
- package/build/cjs/encryption.module.js.map +1 -0
- package/build/cjs/encryption.service.d.ts +10 -0
- package/build/cjs/encryption.service.d.ts.map +1 -0
- package/build/cjs/encryption.service.js +76 -0
- package/build/cjs/encryption.service.js.map +1 -0
- package/build/cjs/main.d.ts +7 -0
- package/build/cjs/main.d.ts.map +1 -0
- package/build/cjs/main.js +16 -0
- package/build/cjs/main.js.map +1 -0
- package/build/cjs/package.json +1 -0
- package/build/esm/aes-256-gcm.d.ts +49 -0
- package/build/esm/aes-256-gcm.d.ts.map +1 -0
- package/build/esm/aes-256-gcm.js +27 -0
- package/build/esm/aes-256-gcm.js.map +1 -0
- package/build/esm/aes-256-gcm.test.d.ts +2 -0
- package/build/esm/aes-256-gcm.test.d.ts.map +1 -0
- package/build/esm/aes-256-gcm.test.js +38 -0
- package/build/esm/aes-256-gcm.test.js.map +1 -0
- package/build/esm/encryption.const.d.ts +2 -0
- package/build/esm/encryption.const.d.ts.map +1 -0
- package/build/esm/encryption.const.js +2 -0
- package/build/esm/encryption.const.js.map +1 -0
- package/build/esm/encryption.interface.d.ts +9 -0
- package/build/esm/encryption.interface.d.ts.map +1 -0
- package/build/esm/encryption.interface.js +2 -0
- package/build/esm/encryption.interface.js.map +1 -0
- package/build/esm/encryption.module.d.ts +7 -0
- package/build/esm/encryption.module.d.ts.map +1 -0
- package/build/esm/encryption.module.js +93 -0
- package/build/esm/encryption.module.js.map +1 -0
- package/build/esm/encryption.service.d.ts +10 -0
- package/build/esm/encryption.service.d.ts.map +1 -0
- package/build/esm/encryption.service.js +74 -0
- package/build/esm/encryption.service.js.map +1 -0
- package/build/esm/main.d.ts +7 -0
- package/build/esm/main.d.ts.map +1 -0
- package/build/esm/main.js +5 -0
- package/build/esm/main.js.map +1 -0
- package/build/esm/package.json +1 -0
- package/package.json +34 -0
package/README.md
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# encryption
|
|
2
|
+
|
|
3
|
+
Voiceflow encryption library
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
yarn add @voiceflow/encryption
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
### Basic encryption/decryption
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import crypto from 'crypto';
|
|
17
|
+
import { encryptAes256Gcm, decryptAes256Gcm } from '@voiceflow/encryption';
|
|
18
|
+
|
|
19
|
+
// create a key
|
|
20
|
+
const createAES256Key = () =>
|
|
21
|
+
new Promise<string>((resolve) => {
|
|
22
|
+
crypto.generateKey('aes', { length: 256 }, (err, key) => {
|
|
23
|
+
if (err) throw err;
|
|
24
|
+
resolve(key.export().toString('base64'));
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
const encryptionKey = await createAES256Key();
|
|
28
|
+
|
|
29
|
+
// Encrypt data
|
|
30
|
+
const plaintext = 'sensitive data';
|
|
31
|
+
const encrypted = encryptAes256Gcm(plaintext, encryptionKey);
|
|
32
|
+
|
|
33
|
+
// Decrypt data
|
|
34
|
+
const decrypted = decryptAes256Gcm(encrypted, encryptionKey);
|
|
35
|
+
console.log(decrypted); // 'sensitive data'
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Using with NestJS
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
import { Module } from '@nestjs/common';
|
|
42
|
+
import { EncryptionModule } from '@voiceflow/encryption';
|
|
43
|
+
|
|
44
|
+
@Module({
|
|
45
|
+
imports: [
|
|
46
|
+
EncryptionModule.register({
|
|
47
|
+
encryptionKey: 'your-base64-encoded-key',
|
|
48
|
+
}),
|
|
49
|
+
],
|
|
50
|
+
})
|
|
51
|
+
export class AppModule {}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Or with async configuration:
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
import { Module } from '@nestjs/common';
|
|
58
|
+
import { ConfigModule, ConfigService } from '@nestjs/config';
|
|
59
|
+
import { EncryptionModule } from '@voiceflow/encryption';
|
|
60
|
+
|
|
61
|
+
@Module({
|
|
62
|
+
imports: [
|
|
63
|
+
ConfigModule.forRoot(),
|
|
64
|
+
EncryptionModule.registerAsync({
|
|
65
|
+
imports: [ConfigModule],
|
|
66
|
+
inject: [ConfigService],
|
|
67
|
+
useFactory: (configService: ConfigService) => ({
|
|
68
|
+
encryptionKey: configService.get('ENCRYPTION_KEY'),
|
|
69
|
+
}),
|
|
70
|
+
}),
|
|
71
|
+
],
|
|
72
|
+
})
|
|
73
|
+
export class AppModule {}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Then inject and use the service:
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
import { Injectable } from '@nestjs/common';
|
|
80
|
+
import { EncryptionService } from '@voiceflow/encryption';
|
|
81
|
+
|
|
82
|
+
@Injectable()
|
|
83
|
+
export class YourService {
|
|
84
|
+
constructor(private readonly encryptionService: EncryptionService) {}
|
|
85
|
+
|
|
86
|
+
encryptSensitiveData(data: string) {
|
|
87
|
+
return this.encryptionService.encrypt(data);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
decryptSensitiveData(encryptedData) {
|
|
91
|
+
return this.encryptionService.decrypt(encryptedData);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
```
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file implements AES 256 Galois/counter (GCM) encryption. The AES algorithm
|
|
3
|
+
* is a symmetric-key block cipher that is considered to be a highly secure algorithm
|
|
4
|
+
* (as of 30 Sep 2024).
|
|
5
|
+
*
|
|
6
|
+
* For this implementation, we will use AES-256 with 256-bit keys, which provides the
|
|
7
|
+
* strongest security of all AES variants.
|
|
8
|
+
*
|
|
9
|
+
* GCM mode is the usual recommended mode of operation for encryption. AES 256 features
|
|
10
|
+
* a variety of modes of operation, such as ECB, CBC, CTR, and GCM. To understand why
|
|
11
|
+
* GCM is a good choice, we will discuss the weaknesses of each method mentioned.
|
|
12
|
+
*
|
|
13
|
+
* 1. ECB is considered insecure as it does not sufficiently scramble patterns in the
|
|
14
|
+
* original data, e.g, see the Tux image in
|
|
15
|
+
* https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Electronic_codebook_(ECB)
|
|
16
|
+
*
|
|
17
|
+
* 2. CBC is stronger than ECB but operates on fixed-length blocks of plaintext, so
|
|
18
|
+
* plaintext that does not conform to these requirements require *padding*. The use of
|
|
19
|
+
* padding opens CBC to "padding oracle attacks" which allows attackers to decrypt the
|
|
20
|
+
* ciphertext without knowing the symmetric key.
|
|
21
|
+
*
|
|
22
|
+
* 3. CTR does not suffer from padding oracle attacks as it does not require padding.
|
|
23
|
+
* However, it and other methods are vulnerable to attacks on data integrity such as
|
|
24
|
+
* "malleability attacks" which allows an attacker to manipulate the ciphertext to
|
|
25
|
+
* inject malicious data without knowing the symmetric key.
|
|
26
|
+
*
|
|
27
|
+
* GCM uses CTR under the hood, but adds a "message authenticate code" (MAC) to each ciphertext
|
|
28
|
+
* created. A trusted sender computes a MAC on some text, using the symmetric key. A trusted
|
|
29
|
+
* receiver will verify the MAC using the symmetric key to ensure that no attacker intercepted
|
|
30
|
+
* the message and tampered with its underlying contents. This is similar to the concept of
|
|
31
|
+
* "digital signatures" that is also used in cryptography.
|
|
32
|
+
*
|
|
33
|
+
* The MAC guards against malleability attacks, as a symmetric key is required to compute the
|
|
34
|
+
* exact MAC corresponding to the protected ciphertext. Manipulating the ciphertext without
|
|
35
|
+
* making the corresponding change in the MAC causes a mismatch which is flagged as an integrity
|
|
36
|
+
* violation.
|
|
37
|
+
*
|
|
38
|
+
* NOTE: While GCM is one of the more secure modes of operation, it is by no means perfect
|
|
39
|
+
* and requires careful adherence to best practice, e.g, AES-256 should ideally be used
|
|
40
|
+
* with 96-bit cryptographically secure pseudorandom initialization vectors.
|
|
41
|
+
*/
|
|
42
|
+
export interface GCMEncryptedData {
|
|
43
|
+
value: string;
|
|
44
|
+
iv: string;
|
|
45
|
+
mac: string;
|
|
46
|
+
}
|
|
47
|
+
export declare function encryptAes256Gcm(plaintext: string, symmetricKey: string): GCMEncryptedData;
|
|
48
|
+
export declare function decryptAes256Gcm(data: GCMEncryptedData, symmetricKey: string): string;
|
|
49
|
+
//# sourceMappingURL=aes-256-gcm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aes-256-gcm.d.ts","sourceRoot":"","sources":["../../src/aes-256-gcm.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;CACb;AAYD,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,gBAAgB,CAa1F;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,UAU5E"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.encryptAes256Gcm = encryptAes256Gcm;
|
|
7
|
+
exports.decryptAes256Gcm = decryptAes256Gcm;
|
|
8
|
+
const node_crypto_1 = __importDefault(require("node:crypto"));
|
|
9
|
+
const mode = 'aes-256-gcm';
|
|
10
|
+
// 96-bit IV is recommended by section 5.2.1.1 in
|
|
11
|
+
// https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf
|
|
12
|
+
const ivLengthBytes = 12;
|
|
13
|
+
const dbEncoding = 'base64';
|
|
14
|
+
const plaintextEncoding = 'utf8';
|
|
15
|
+
function encryptAes256Gcm(plaintext, symmetricKey) {
|
|
16
|
+
const key = Buffer.from(symmetricKey, dbEncoding);
|
|
17
|
+
const iv = node_crypto_1.default.randomBytes(ivLengthBytes);
|
|
18
|
+
const cipher = node_crypto_1.default.createCipheriv(mode, key, iv);
|
|
19
|
+
const ciphertext = cipher.update(plaintext, plaintextEncoding, dbEncoding) + cipher.final(dbEncoding);
|
|
20
|
+
return {
|
|
21
|
+
value: ciphertext,
|
|
22
|
+
iv: iv.toString(dbEncoding),
|
|
23
|
+
mac: cipher.getAuthTag().toString(dbEncoding),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function decryptAes256Gcm(data, symmetricKey) {
|
|
27
|
+
const key = Buffer.from(symmetricKey, dbEncoding);
|
|
28
|
+
const iv = Buffer.from(data.iv, dbEncoding);
|
|
29
|
+
const decipher = node_crypto_1.default.createDecipheriv(mode, key, iv);
|
|
30
|
+
const mac = Buffer.from(data.mac, dbEncoding);
|
|
31
|
+
decipher.setAuthTag(mac);
|
|
32
|
+
return decipher.update(data.value, dbEncoding, plaintextEncoding) + decipher.final(plaintextEncoding);
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=aes-256-gcm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aes-256-gcm.js","sourceRoot":"","sources":["../../src/aes-256-gcm.ts"],"names":[],"mappings":";;;;;AA4DA,4CAaC;AAED,4CAUC;AArFD,8DAAiC;AAkDjC,MAAM,IAAI,GAAG,aAAa,CAAC;AAE3B,iDAAiD;AACjD,gFAAgF;AAChF,MAAM,aAAa,GAAG,EAAE,CAAC;AAEzB,MAAM,UAAU,GAAG,QAAQ,CAAC;AAE5B,MAAM,iBAAiB,GAAG,MAAM,CAAC;AAEjC,SAAgB,gBAAgB,CAAC,SAAiB,EAAE,YAAoB;IACtE,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;IAElD,MAAM,EAAE,GAAG,qBAAM,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,qBAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;IAEpD,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,iBAAiB,EAAE,UAAU,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAEtG,OAAO;QACL,KAAK,EAAE,UAAU;QACjB,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC3B,GAAG,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC;KAC9C,CAAC;AACJ,CAAC;AAED,SAAgB,gBAAgB,CAAC,IAAsB,EAAE,YAAoB;IAC3E,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;IAElD,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;IAC5C,MAAM,QAAQ,GAAG,qBAAM,CAAC,gBAAgB,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;IAExD,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IAC9C,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAEzB,OAAO,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,iBAAiB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;AACxG,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aes-256-gcm.test.d.ts","sourceRoot":"","sources":["../../src/aes-256-gcm.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
7
|
+
const vitest_1 = require("vitest");
|
|
8
|
+
const aes_256_gcm_1 = require("./aes-256-gcm");
|
|
9
|
+
(0, vitest_1.describe)('AES-256 GCM', async () => {
|
|
10
|
+
const createAES256Key = () => new Promise((resolve) => {
|
|
11
|
+
crypto_1.default.generateKey('aes', { length: 256 }, (err, key) => {
|
|
12
|
+
if (err)
|
|
13
|
+
throw err;
|
|
14
|
+
resolve(key.export().toString('base64'));
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
const testKey = await createAES256Key();
|
|
18
|
+
(0, vitest_1.test)('successfully encrypts then decrypts', async () => {
|
|
19
|
+
const plaintext = 'hello, world!';
|
|
20
|
+
const cipherdata = await (0, aes_256_gcm_1.encryptAes256Gcm)(plaintext, testKey);
|
|
21
|
+
const deciphertext = await (0, aes_256_gcm_1.decryptAes256Gcm)(cipherdata, testKey);
|
|
22
|
+
(0, vitest_1.expect)(deciphertext).to.eq(plaintext);
|
|
23
|
+
});
|
|
24
|
+
(0, vitest_1.test)('throws error if decrypted with wrong key', async () => {
|
|
25
|
+
const plaintext = 'hello, world!';
|
|
26
|
+
const wrongKey = await createAES256Key();
|
|
27
|
+
const cipherdata = await (0, aes_256_gcm_1.encryptAes256Gcm)(plaintext, testKey);
|
|
28
|
+
const decipher = () => (0, aes_256_gcm_1.decryptAes256Gcm)(cipherdata, wrongKey);
|
|
29
|
+
await (0, vitest_1.expect)(decipher).to.throw('Unsupported state or unable to authenticate data');
|
|
30
|
+
});
|
|
31
|
+
(0, vitest_1.test)('throws error if ciphertext is not validated by the mac', async () => {
|
|
32
|
+
const plaintext = 'hello, world!';
|
|
33
|
+
const trueCipherdata = await (0, aes_256_gcm_1.encryptAes256Gcm)(plaintext, testKey);
|
|
34
|
+
const data = await (0, aes_256_gcm_1.encryptAes256Gcm)('malicious payload', testKey);
|
|
35
|
+
const forgedCipherdata = {
|
|
36
|
+
...trueCipherdata,
|
|
37
|
+
value: data.value,
|
|
38
|
+
};
|
|
39
|
+
const decipher = () => (0, aes_256_gcm_1.decryptAes256Gcm)(forgedCipherdata, testKey);
|
|
40
|
+
await (0, vitest_1.expect)(decipher).to.throw('Unsupported state or unable to authenticate data');
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
//# sourceMappingURL=aes-256-gcm.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aes-256-gcm.test.js","sourceRoot":"","sources":["../../src/aes-256-gcm.test.ts"],"names":[],"mappings":";;;;;AAAA,oDAA4B;AAC5B,mCAAgD;AAEhD,+CAAmE;AAEnE,IAAA,iBAAQ,EAAC,aAAa,EAAE,KAAK,IAAI,EAAE;IACjC,MAAM,eAAe,GAAG,GAAG,EAAE,CAC3B,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,EAAE;QAC9B,gBAAM,CAAC,WAAW,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;YACtD,IAAI,GAAG;gBAAE,MAAM,GAAG,CAAC;YACnB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACL,MAAM,OAAO,GAAG,MAAM,eAAe,EAAE,CAAC;IAExC,IAAA,aAAI,EAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QACrD,MAAM,SAAS,GAAG,eAAe,CAAC;QAElC,MAAM,UAAU,GAAG,MAAM,IAAA,8BAAgB,EAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAC9D,MAAM,YAAY,GAAG,MAAM,IAAA,8BAAgB,EAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAEjE,IAAA,eAAM,EAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,IAAA,aAAI,EAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;QAC1D,MAAM,SAAS,GAAG,eAAe,CAAC;QAClC,MAAM,QAAQ,GAAG,MAAM,eAAe,EAAE,CAAC;QAEzC,MAAM,UAAU,GAAG,MAAM,IAAA,8BAAgB,EAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAC9D,MAAM,QAAQ,GAAG,GAAG,EAAE,CAAC,IAAA,8BAAgB,EAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAE9D,MAAM,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtF,CAAC,CAAC,CAAC;IAEH,IAAA,aAAI,EAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;QACxE,MAAM,SAAS,GAAG,eAAe,CAAC;QAElC,MAAM,cAAc,GAAG,MAAM,IAAA,8BAAgB,EAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAClE,MAAM,IAAI,GAAG,MAAM,IAAA,8BAAgB,EAAC,mBAAmB,EAAE,OAAO,CAAC,CAAC;QAClE,MAAM,gBAAgB,GAAG;YACvB,GAAG,cAAc;YACjB,KAAK,EAAE,IAAI,CAAC,KAAK;SAClB,CAAC;QAEF,MAAM,QAAQ,GAAG,GAAG,EAAE,CAAC,IAAA,8BAAgB,EAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;QAEnE,MAAM,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtF,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encryption.const.d.ts","sourceRoot":"","sources":["../../src/encryption.const.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,8BAA8B,8BAA8B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encryption.const.js","sourceRoot":"","sources":["../../src/encryption.const.ts"],"names":[],"mappings":";;;AAAa,QAAA,8BAA8B,GAAG,2BAA2B,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ModuleMetadata } from '@nestjs/common';
|
|
2
|
+
export interface EncryptionModuleAsyncOptions extends Pick<ModuleMetadata, 'imports'> {
|
|
3
|
+
useFactory: (...args: any[]) => Promise<EncryptionModuleOptions> | EncryptionModuleOptions;
|
|
4
|
+
inject?: any[];
|
|
5
|
+
}
|
|
6
|
+
export interface EncryptionModuleOptions {
|
|
7
|
+
encryptionKey?: string | null;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=encryption.interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encryption.interface.d.ts","sourceRoot":"","sources":["../../src/encryption.interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErD,MAAM,WAAW,4BAA6B,SAAQ,IAAI,CAAC,cAAc,EAAE,SAAS,CAAC;IACnF,UAAU,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,uBAAuB,CAAC,GAAG,uBAAuB,CAAC;IAC3F,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;CAChB;AAED,MAAM,WAAW,uBAAuB;IACtC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encryption.interface.js","sourceRoot":"","sources":["../../src/encryption.interface.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { DynamicModule } from '@nestjs/common';
|
|
2
|
+
import { EncryptionModuleAsyncOptions, EncryptionModuleOptions } from './encryption.interface';
|
|
3
|
+
export declare class EncryptionModule {
|
|
4
|
+
static register(options: EncryptionModuleOptions): DynamicModule;
|
|
5
|
+
static registerAsync(options: EncryptionModuleAsyncOptions): DynamicModule;
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=encryption.module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encryption.module.d.ts","sourceRoot":"","sources":["../../src/encryption.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAU,MAAM,gBAAgB,CAAC;AAGvD,OAAO,EAAE,4BAA4B,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAG/F,qBACa,gBAAgB;IAC3B,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,uBAAuB,GAAG,aAAa;IAahE,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE,4BAA4B,GAAG,aAAa;CAqB3E"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
3
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
4
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
5
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
6
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
7
|
+
var _, done = false;
|
|
8
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
9
|
+
var context = {};
|
|
10
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
11
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
12
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
13
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
14
|
+
if (kind === "accessor") {
|
|
15
|
+
if (result === void 0) continue;
|
|
16
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
17
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
18
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
19
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
20
|
+
}
|
|
21
|
+
else if (_ = accept(result)) {
|
|
22
|
+
if (kind === "field") initializers.unshift(_);
|
|
23
|
+
else descriptor[key] = _;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
27
|
+
done = true;
|
|
28
|
+
};
|
|
29
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
30
|
+
var useValue = arguments.length > 2;
|
|
31
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
32
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
33
|
+
}
|
|
34
|
+
return useValue ? value : void 0;
|
|
35
|
+
};
|
|
36
|
+
var __setFunctionName = (this && this.__setFunctionName) || function (f, name, prefix) {
|
|
37
|
+
if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
|
|
38
|
+
return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
|
|
39
|
+
};
|
|
40
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
41
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
42
|
+
};
|
|
43
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
|
+
exports.EncryptionModule = void 0;
|
|
45
|
+
const common_1 = require("@nestjs/common");
|
|
46
|
+
const encryption_const_1 = require("./encryption.const");
|
|
47
|
+
const encryption_service_1 = __importDefault(require("./encryption.service"));
|
|
48
|
+
let EncryptionModule = (() => {
|
|
49
|
+
let _classDecorators = [(0, common_1.Module)({})];
|
|
50
|
+
let _classDescriptor;
|
|
51
|
+
let _classExtraInitializers = [];
|
|
52
|
+
let _classThis;
|
|
53
|
+
var EncryptionModule = _classThis = class {
|
|
54
|
+
static register(options) {
|
|
55
|
+
return {
|
|
56
|
+
module: EncryptionModule,
|
|
57
|
+
providers: [
|
|
58
|
+
{
|
|
59
|
+
provide: encryption_service_1.default,
|
|
60
|
+
useValue: new encryption_service_1.default(options.encryptionKey),
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
exports: [encryption_service_1.default],
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
static registerAsync(options) {
|
|
67
|
+
return {
|
|
68
|
+
module: EncryptionModule,
|
|
69
|
+
imports: options.imports || [],
|
|
70
|
+
providers: [
|
|
71
|
+
{
|
|
72
|
+
provide: encryption_const_1.EncryptionModuleOptionsProvide,
|
|
73
|
+
useFactory: options.useFactory,
|
|
74
|
+
inject: options.inject || [],
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
provide: encryption_service_1.default,
|
|
78
|
+
useFactory: (moduleOptions) => {
|
|
79
|
+
return new encryption_service_1.default(moduleOptions.encryptionKey);
|
|
80
|
+
},
|
|
81
|
+
inject: [encryption_const_1.EncryptionModuleOptionsProvide],
|
|
82
|
+
},
|
|
83
|
+
],
|
|
84
|
+
exports: [encryption_service_1.default],
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
__setFunctionName(_classThis, "EncryptionModule");
|
|
89
|
+
(() => {
|
|
90
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
91
|
+
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
92
|
+
EncryptionModule = _classThis = _classDescriptor.value;
|
|
93
|
+
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
94
|
+
__runInitializers(_classThis, _classExtraInitializers);
|
|
95
|
+
})();
|
|
96
|
+
return EncryptionModule = _classThis;
|
|
97
|
+
})();
|
|
98
|
+
exports.EncryptionModule = EncryptionModule;
|
|
99
|
+
//# sourceMappingURL=encryption.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encryption.module.js","sourceRoot":"","sources":["../../src/encryption.module.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAAuD;AAEvD,yDAAoE;AAEpE,8EAAqD;IAGxC,gBAAgB;4BAD5B,IAAA,eAAM,EAAC,EAAE,CAAC;;;;;QAET,MAAM,CAAC,QAAQ,CAAC,OAAgC;YAC9C,OAAO;gBACL,MAAM,EAAE,gBAAgB;gBACxB,SAAS,EAAE;oBACT;wBACE,OAAO,EAAE,4BAAiB;wBAC1B,QAAQ,EAAE,IAAI,4BAAiB,CAAC,OAAO,CAAC,aAAa,CAAC;qBACvD;iBACF;gBACD,OAAO,EAAE,CAAC,4BAAiB,CAAC;aAC7B,CAAC;QACJ,CAAC;QAED,MAAM,CAAC,aAAa,CAAC,OAAqC;YACxD,OAAO;gBACL,MAAM,EAAE,gBAAgB;gBACxB,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,EAAE;gBAC9B,SAAS,EAAE;oBACT;wBACE,OAAO,EAAE,iDAA8B;wBACvC,UAAU,EAAE,OAAO,CAAC,UAAU;wBAC9B,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,EAAE;qBAC7B;oBACD;wBACE,OAAO,EAAE,4BAAiB;wBAC1B,UAAU,EAAE,CAAC,aAAsC,EAAE,EAAE;4BACrD,OAAO,IAAI,4BAAiB,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;wBAC5D,CAAC;wBACD,MAAM,EAAE,CAAC,iDAA8B,CAAC;qBACzC;iBACF;gBACD,OAAO,EAAE,CAAC,4BAAiB,CAAC;aAC7B,CAAC;QACJ,CAAC;;;;;QAlCH,6KAmCC;;;QAnCY,uDAAgB;;;;AAAhB,4CAAgB"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { GCMEncryptedData } from './aes-256-gcm';
|
|
2
|
+
declare class EncryptionService {
|
|
3
|
+
private readonly _encryptionKey?;
|
|
4
|
+
constructor(_encryptionKey?: (string | null) | undefined);
|
|
5
|
+
private get encryptionKey();
|
|
6
|
+
encrypt(plaintext: string): GCMEncryptedData;
|
|
7
|
+
decrypt(data: GCMEncryptedData): string;
|
|
8
|
+
}
|
|
9
|
+
export default EncryptionService;
|
|
10
|
+
//# sourceMappingURL=encryption.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encryption.service.d.ts","sourceRoot":"","sources":["../../src/encryption.service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAGtD,cACM,iBAAiB;IACT,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC;gBAAf,cAAc,CAAC,GAAE,MAAM,GAAG,IAAI,aAAA;IAE3D,OAAO,KAAK,aAAa,GAMxB;IAEM,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB;IAI5C,OAAO,CAAC,IAAI,EAAE,gBAAgB,GAAG,MAAM;CAG/C;AAED,eAAe,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
3
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
4
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
5
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
6
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
7
|
+
var _, done = false;
|
|
8
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
9
|
+
var context = {};
|
|
10
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
11
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
12
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
13
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
14
|
+
if (kind === "accessor") {
|
|
15
|
+
if (result === void 0) continue;
|
|
16
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
17
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
18
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
19
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
20
|
+
}
|
|
21
|
+
else if (_ = accept(result)) {
|
|
22
|
+
if (kind === "field") initializers.unshift(_);
|
|
23
|
+
else descriptor[key] = _;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
27
|
+
done = true;
|
|
28
|
+
};
|
|
29
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
30
|
+
var useValue = arguments.length > 2;
|
|
31
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
32
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
33
|
+
}
|
|
34
|
+
return useValue ? value : void 0;
|
|
35
|
+
};
|
|
36
|
+
var __setFunctionName = (this && this.__setFunctionName) || function (f, name, prefix) {
|
|
37
|
+
if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
|
|
38
|
+
return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
|
|
39
|
+
};
|
|
40
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
|
+
const common_1 = require("@nestjs/common");
|
|
42
|
+
const aes_256_gcm_1 = require("./aes-256-gcm");
|
|
43
|
+
let EncryptionService = (() => {
|
|
44
|
+
let _classDecorators = [(0, common_1.Injectable)()];
|
|
45
|
+
let _classDescriptor;
|
|
46
|
+
let _classExtraInitializers = [];
|
|
47
|
+
let _classThis;
|
|
48
|
+
var EncryptionService = _classThis = class {
|
|
49
|
+
constructor(_encryptionKey) {
|
|
50
|
+
this._encryptionKey = _encryptionKey;
|
|
51
|
+
}
|
|
52
|
+
get encryptionKey() {
|
|
53
|
+
if (!this._encryptionKey) {
|
|
54
|
+
throw new Error('Encryption key is required');
|
|
55
|
+
}
|
|
56
|
+
return this._encryptionKey;
|
|
57
|
+
}
|
|
58
|
+
encrypt(plaintext) {
|
|
59
|
+
return (0, aes_256_gcm_1.encryptAes256Gcm)(plaintext, this.encryptionKey);
|
|
60
|
+
}
|
|
61
|
+
decrypt(data) {
|
|
62
|
+
return (0, aes_256_gcm_1.decryptAes256Gcm)(data, this.encryptionKey);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
__setFunctionName(_classThis, "EncryptionService");
|
|
66
|
+
(() => {
|
|
67
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
68
|
+
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
69
|
+
EncryptionService = _classThis = _classDescriptor.value;
|
|
70
|
+
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
71
|
+
__runInitializers(_classThis, _classExtraInitializers);
|
|
72
|
+
})();
|
|
73
|
+
return EncryptionService = _classThis;
|
|
74
|
+
})();
|
|
75
|
+
exports.default = EncryptionService;
|
|
76
|
+
//# sourceMappingURL=encryption.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encryption.service.js","sourceRoot":"","sources":["../../src/encryption.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAA4C;AAG5C,+CAAmE;IAG7D,iBAAiB;4BADtB,IAAA,mBAAU,GAAE;;;;;QAEX,YAA6B,cAA8B;YAA9B,mBAAc,GAAd,cAAc,CAAgB;QAAG,CAAC;QAE/D,IAAY,aAAa;YACvB,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;gBACzB,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;YAChD,CAAC;YAED,OAAO,IAAI,CAAC,cAAc,CAAC;QAC7B,CAAC;QAEM,OAAO,CAAC,SAAiB;YAC9B,OAAO,IAAA,8BAAgB,EAAC,SAAS,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QACzD,CAAC;QAEM,OAAO,CAAC,IAAsB;YACnC,OAAO,IAAA,8BAAgB,EAAC,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QACpD,CAAC;;;;;QAjBH,6KAkBC;;;QAlBK,uDAAiB;;;;AAoBvB,kBAAe,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type { GCMEncryptedData } from './aes-256-gcm';
|
|
2
|
+
export { decryptAes256Gcm, encryptAes256Gcm } from './aes-256-gcm';
|
|
3
|
+
export { EncryptionModuleOptionsProvide } from './encryption.const';
|
|
4
|
+
export type { EncryptionModuleAsyncOptions, EncryptionModuleOptions } from './encryption.interface';
|
|
5
|
+
export { EncryptionModule } from './encryption.module';
|
|
6
|
+
export { default as EncryptionService } from './encryption.service';
|
|
7
|
+
//# sourceMappingURL=main.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/main.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,8BAA8B,EAAE,MAAM,oBAAoB,CAAC;AACpE,YAAY,EAAE,4BAA4B,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACpG,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.EncryptionService = exports.EncryptionModule = exports.EncryptionModuleOptionsProvide = exports.encryptAes256Gcm = exports.decryptAes256Gcm = void 0;
|
|
7
|
+
var aes_256_gcm_1 = require("./aes-256-gcm");
|
|
8
|
+
Object.defineProperty(exports, "decryptAes256Gcm", { enumerable: true, get: function () { return aes_256_gcm_1.decryptAes256Gcm; } });
|
|
9
|
+
Object.defineProperty(exports, "encryptAes256Gcm", { enumerable: true, get: function () { return aes_256_gcm_1.encryptAes256Gcm; } });
|
|
10
|
+
var encryption_const_1 = require("./encryption.const");
|
|
11
|
+
Object.defineProperty(exports, "EncryptionModuleOptionsProvide", { enumerable: true, get: function () { return encryption_const_1.EncryptionModuleOptionsProvide; } });
|
|
12
|
+
var encryption_module_1 = require("./encryption.module");
|
|
13
|
+
Object.defineProperty(exports, "EncryptionModule", { enumerable: true, get: function () { return encryption_module_1.EncryptionModule; } });
|
|
14
|
+
var encryption_service_1 = require("./encryption.service");
|
|
15
|
+
Object.defineProperty(exports, "EncryptionService", { enumerable: true, get: function () { return __importDefault(encryption_service_1).default; } });
|
|
16
|
+
//# sourceMappingURL=main.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/main.ts"],"names":[],"mappings":";;;;;;AACA,6CAAmE;AAA1D,+GAAA,gBAAgB,OAAA;AAAE,+GAAA,gBAAgB,OAAA;AAC3C,uDAAoE;AAA3D,kIAAA,8BAA8B,OAAA;AAEvC,yDAAuD;AAA9C,qHAAA,gBAAgB,OAAA;AACzB,2DAAoE;AAA3D,wIAAA,OAAO,OAAqB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "type": "commonjs" }
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file implements AES 256 Galois/counter (GCM) encryption. The AES algorithm
|
|
3
|
+
* is a symmetric-key block cipher that is considered to be a highly secure algorithm
|
|
4
|
+
* (as of 30 Sep 2024).
|
|
5
|
+
*
|
|
6
|
+
* For this implementation, we will use AES-256 with 256-bit keys, which provides the
|
|
7
|
+
* strongest security of all AES variants.
|
|
8
|
+
*
|
|
9
|
+
* GCM mode is the usual recommended mode of operation for encryption. AES 256 features
|
|
10
|
+
* a variety of modes of operation, such as ECB, CBC, CTR, and GCM. To understand why
|
|
11
|
+
* GCM is a good choice, we will discuss the weaknesses of each method mentioned.
|
|
12
|
+
*
|
|
13
|
+
* 1. ECB is considered insecure as it does not sufficiently scramble patterns in the
|
|
14
|
+
* original data, e.g, see the Tux image in
|
|
15
|
+
* https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Electronic_codebook_(ECB)
|
|
16
|
+
*
|
|
17
|
+
* 2. CBC is stronger than ECB but operates on fixed-length blocks of plaintext, so
|
|
18
|
+
* plaintext that does not conform to these requirements require *padding*. The use of
|
|
19
|
+
* padding opens CBC to "padding oracle attacks" which allows attackers to decrypt the
|
|
20
|
+
* ciphertext without knowing the symmetric key.
|
|
21
|
+
*
|
|
22
|
+
* 3. CTR does not suffer from padding oracle attacks as it does not require padding.
|
|
23
|
+
* However, it and other methods are vulnerable to attacks on data integrity such as
|
|
24
|
+
* "malleability attacks" which allows an attacker to manipulate the ciphertext to
|
|
25
|
+
* inject malicious data without knowing the symmetric key.
|
|
26
|
+
*
|
|
27
|
+
* GCM uses CTR under the hood, but adds a "message authenticate code" (MAC) to each ciphertext
|
|
28
|
+
* created. A trusted sender computes a MAC on some text, using the symmetric key. A trusted
|
|
29
|
+
* receiver will verify the MAC using the symmetric key to ensure that no attacker intercepted
|
|
30
|
+
* the message and tampered with its underlying contents. This is similar to the concept of
|
|
31
|
+
* "digital signatures" that is also used in cryptography.
|
|
32
|
+
*
|
|
33
|
+
* The MAC guards against malleability attacks, as a symmetric key is required to compute the
|
|
34
|
+
* exact MAC corresponding to the protected ciphertext. Manipulating the ciphertext without
|
|
35
|
+
* making the corresponding change in the MAC causes a mismatch which is flagged as an integrity
|
|
36
|
+
* violation.
|
|
37
|
+
*
|
|
38
|
+
* NOTE: While GCM is one of the more secure modes of operation, it is by no means perfect
|
|
39
|
+
* and requires careful adherence to best practice, e.g, AES-256 should ideally be used
|
|
40
|
+
* with 96-bit cryptographically secure pseudorandom initialization vectors.
|
|
41
|
+
*/
|
|
42
|
+
export interface GCMEncryptedData {
|
|
43
|
+
value: string;
|
|
44
|
+
iv: string;
|
|
45
|
+
mac: string;
|
|
46
|
+
}
|
|
47
|
+
export declare function encryptAes256Gcm(plaintext: string, symmetricKey: string): GCMEncryptedData;
|
|
48
|
+
export declare function decryptAes256Gcm(data: GCMEncryptedData, symmetricKey: string): string;
|
|
49
|
+
//# sourceMappingURL=aes-256-gcm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aes-256-gcm.d.ts","sourceRoot":"","sources":["../../src/aes-256-gcm.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;CACb;AAYD,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,gBAAgB,CAa1F;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,UAU5E"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import crypto from 'node:crypto';
|
|
2
|
+
const mode = 'aes-256-gcm';
|
|
3
|
+
// 96-bit IV is recommended by section 5.2.1.1 in
|
|
4
|
+
// https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf
|
|
5
|
+
const ivLengthBytes = 12;
|
|
6
|
+
const dbEncoding = 'base64';
|
|
7
|
+
const plaintextEncoding = 'utf8';
|
|
8
|
+
export function encryptAes256Gcm(plaintext, symmetricKey) {
|
|
9
|
+
const key = Buffer.from(symmetricKey, dbEncoding);
|
|
10
|
+
const iv = crypto.randomBytes(ivLengthBytes);
|
|
11
|
+
const cipher = crypto.createCipheriv(mode, key, iv);
|
|
12
|
+
const ciphertext = cipher.update(plaintext, plaintextEncoding, dbEncoding) + cipher.final(dbEncoding);
|
|
13
|
+
return {
|
|
14
|
+
value: ciphertext,
|
|
15
|
+
iv: iv.toString(dbEncoding),
|
|
16
|
+
mac: cipher.getAuthTag().toString(dbEncoding),
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export function decryptAes256Gcm(data, symmetricKey) {
|
|
20
|
+
const key = Buffer.from(symmetricKey, dbEncoding);
|
|
21
|
+
const iv = Buffer.from(data.iv, dbEncoding);
|
|
22
|
+
const decipher = crypto.createDecipheriv(mode, key, iv);
|
|
23
|
+
const mac = Buffer.from(data.mac, dbEncoding);
|
|
24
|
+
decipher.setAuthTag(mac);
|
|
25
|
+
return decipher.update(data.value, dbEncoding, plaintextEncoding) + decipher.final(plaintextEncoding);
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=aes-256-gcm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aes-256-gcm.js","sourceRoot":"","sources":["../../src/aes-256-gcm.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AAkDjC,MAAM,IAAI,GAAG,aAAa,CAAC;AAE3B,iDAAiD;AACjD,gFAAgF;AAChF,MAAM,aAAa,GAAG,EAAE,CAAC;AAEzB,MAAM,UAAU,GAAG,QAAQ,CAAC;AAE5B,MAAM,iBAAiB,GAAG,MAAM,CAAC;AAEjC,MAAM,UAAU,gBAAgB,CAAC,SAAiB,EAAE,YAAoB;IACtE,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;IAElD,MAAM,EAAE,GAAG,MAAM,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;IAEpD,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,iBAAiB,EAAE,UAAU,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAEtG,OAAO;QACL,KAAK,EAAE,UAAU;QACjB,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC3B,GAAG,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC;KAC9C,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAsB,EAAE,YAAoB;IAC3E,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;IAElD,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;IAC5C,MAAM,QAAQ,GAAG,MAAM,CAAC,gBAAgB,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;IAExD,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IAC9C,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAEzB,OAAO,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,iBAAiB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;AACxG,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aes-256-gcm.test.d.ts","sourceRoot":"","sources":["../../src/aes-256-gcm.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import crypto from 'crypto';
|
|
2
|
+
import { describe, expect, test } from 'vitest';
|
|
3
|
+
import { decryptAes256Gcm, encryptAes256Gcm } from './aes-256-gcm.js';
|
|
4
|
+
describe('AES-256 GCM', async () => {
|
|
5
|
+
const createAES256Key = () => new Promise((resolve) => {
|
|
6
|
+
crypto.generateKey('aes', { length: 256 }, (err, key) => {
|
|
7
|
+
if (err)
|
|
8
|
+
throw err;
|
|
9
|
+
resolve(key.export().toString('base64'));
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
const testKey = await createAES256Key();
|
|
13
|
+
test('successfully encrypts then decrypts', async () => {
|
|
14
|
+
const plaintext = 'hello, world!';
|
|
15
|
+
const cipherdata = await encryptAes256Gcm(plaintext, testKey);
|
|
16
|
+
const deciphertext = await decryptAes256Gcm(cipherdata, testKey);
|
|
17
|
+
expect(deciphertext).to.eq(plaintext);
|
|
18
|
+
});
|
|
19
|
+
test('throws error if decrypted with wrong key', async () => {
|
|
20
|
+
const plaintext = 'hello, world!';
|
|
21
|
+
const wrongKey = await createAES256Key();
|
|
22
|
+
const cipherdata = await encryptAes256Gcm(plaintext, testKey);
|
|
23
|
+
const decipher = () => decryptAes256Gcm(cipherdata, wrongKey);
|
|
24
|
+
await expect(decipher).to.throw('Unsupported state or unable to authenticate data');
|
|
25
|
+
});
|
|
26
|
+
test('throws error if ciphertext is not validated by the mac', async () => {
|
|
27
|
+
const plaintext = 'hello, world!';
|
|
28
|
+
const trueCipherdata = await encryptAes256Gcm(plaintext, testKey);
|
|
29
|
+
const data = await encryptAes256Gcm('malicious payload', testKey);
|
|
30
|
+
const forgedCipherdata = {
|
|
31
|
+
...trueCipherdata,
|
|
32
|
+
value: data.value,
|
|
33
|
+
};
|
|
34
|
+
const decipher = () => decryptAes256Gcm(forgedCipherdata, testKey);
|
|
35
|
+
await expect(decipher).to.throw('Unsupported state or unable to authenticate data');
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
//# sourceMappingURL=aes-256-gcm.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aes-256-gcm.test.js","sourceRoot":"","sources":["../../src/aes-256-gcm.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAEhD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEnE,QAAQ,CAAC,aAAa,EAAE,KAAK,IAAI,EAAE;IACjC,MAAM,eAAe,GAAG,GAAG,EAAE,CAC3B,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,EAAE;QAC9B,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;YACtD,IAAI,GAAG;gBAAE,MAAM,GAAG,CAAC;YACnB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACL,MAAM,OAAO,GAAG,MAAM,eAAe,EAAE,CAAC;IAExC,IAAI,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QACrD,MAAM,SAAS,GAAG,eAAe,CAAC;QAElC,MAAM,UAAU,GAAG,MAAM,gBAAgB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAC9D,MAAM,YAAY,GAAG,MAAM,gBAAgB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAEjE,MAAM,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;QAC1D,MAAM,SAAS,GAAG,eAAe,CAAC;QAClC,MAAM,QAAQ,GAAG,MAAM,eAAe,EAAE,CAAC;QAEzC,MAAM,UAAU,GAAG,MAAM,gBAAgB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAC9D,MAAM,QAAQ,GAAG,GAAG,EAAE,CAAC,gBAAgB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAE9D,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtF,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;QACxE,MAAM,SAAS,GAAG,eAAe,CAAC;QAElC,MAAM,cAAc,GAAG,MAAM,gBAAgB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAClE,MAAM,IAAI,GAAG,MAAM,gBAAgB,CAAC,mBAAmB,EAAE,OAAO,CAAC,CAAC;QAClE,MAAM,gBAAgB,GAAG;YACvB,GAAG,cAAc;YACjB,KAAK,EAAE,IAAI,CAAC,KAAK;SAClB,CAAC;QAEF,MAAM,QAAQ,GAAG,GAAG,EAAE,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;QAEnE,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtF,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encryption.const.d.ts","sourceRoot":"","sources":["../../src/encryption.const.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,8BAA8B,8BAA8B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encryption.const.js","sourceRoot":"","sources":["../../src/encryption.const.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,8BAA8B,GAAG,2BAA2B,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ModuleMetadata } from '@nestjs/common';
|
|
2
|
+
export interface EncryptionModuleAsyncOptions extends Pick<ModuleMetadata, 'imports'> {
|
|
3
|
+
useFactory: (...args: any[]) => Promise<EncryptionModuleOptions> | EncryptionModuleOptions;
|
|
4
|
+
inject?: any[];
|
|
5
|
+
}
|
|
6
|
+
export interface EncryptionModuleOptions {
|
|
7
|
+
encryptionKey?: string | null;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=encryption.interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encryption.interface.d.ts","sourceRoot":"","sources":["../../src/encryption.interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErD,MAAM,WAAW,4BAA6B,SAAQ,IAAI,CAAC,cAAc,EAAE,SAAS,CAAC;IACnF,UAAU,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,uBAAuB,CAAC,GAAG,uBAAuB,CAAC;IAC3F,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;CAChB;AAED,MAAM,WAAW,uBAAuB;IACtC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encryption.interface.js","sourceRoot":"","sources":["../../src/encryption.interface.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { DynamicModule } from '@nestjs/common';
|
|
2
|
+
import { EncryptionModuleAsyncOptions, EncryptionModuleOptions } from './encryption.interface.js';
|
|
3
|
+
export declare class EncryptionModule {
|
|
4
|
+
static register(options: EncryptionModuleOptions): DynamicModule;
|
|
5
|
+
static registerAsync(options: EncryptionModuleAsyncOptions): DynamicModule;
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=encryption.module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encryption.module.d.ts","sourceRoot":"","sources":["../../src/encryption.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAU,MAAM,gBAAgB,CAAC;AAGvD,OAAO,EAAE,4BAA4B,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAG/F,qBACa,gBAAgB;IAC3B,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,uBAAuB,GAAG,aAAa;IAahE,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE,4BAA4B,GAAG,aAAa;CAqB3E"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
2
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
3
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
4
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
5
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
6
|
+
var _, done = false;
|
|
7
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
8
|
+
var context = {};
|
|
9
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
10
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
11
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
12
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
13
|
+
if (kind === "accessor") {
|
|
14
|
+
if (result === void 0) continue;
|
|
15
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
16
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
17
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
18
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
19
|
+
}
|
|
20
|
+
else if (_ = accept(result)) {
|
|
21
|
+
if (kind === "field") initializers.unshift(_);
|
|
22
|
+
else descriptor[key] = _;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
26
|
+
done = true;
|
|
27
|
+
};
|
|
28
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
29
|
+
var useValue = arguments.length > 2;
|
|
30
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
31
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
32
|
+
}
|
|
33
|
+
return useValue ? value : void 0;
|
|
34
|
+
};
|
|
35
|
+
var __setFunctionName = (this && this.__setFunctionName) || function (f, name, prefix) {
|
|
36
|
+
if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
|
|
37
|
+
return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
|
|
38
|
+
};
|
|
39
|
+
import { Module } from '@nestjs/common';
|
|
40
|
+
import { EncryptionModuleOptionsProvide } from './encryption.const.js';
|
|
41
|
+
import EncryptionService from './encryption.service.js';
|
|
42
|
+
let EncryptionModule = (() => {
|
|
43
|
+
let _classDecorators = [Module({})];
|
|
44
|
+
let _classDescriptor;
|
|
45
|
+
let _classExtraInitializers = [];
|
|
46
|
+
let _classThis;
|
|
47
|
+
var EncryptionModule = _classThis = class {
|
|
48
|
+
static register(options) {
|
|
49
|
+
return {
|
|
50
|
+
module: EncryptionModule,
|
|
51
|
+
providers: [
|
|
52
|
+
{
|
|
53
|
+
provide: EncryptionService,
|
|
54
|
+
useValue: new EncryptionService(options.encryptionKey),
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
exports: [EncryptionService],
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
static registerAsync(options) {
|
|
61
|
+
return {
|
|
62
|
+
module: EncryptionModule,
|
|
63
|
+
imports: options.imports || [],
|
|
64
|
+
providers: [
|
|
65
|
+
{
|
|
66
|
+
provide: EncryptionModuleOptionsProvide,
|
|
67
|
+
useFactory: options.useFactory,
|
|
68
|
+
inject: options.inject || [],
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
provide: EncryptionService,
|
|
72
|
+
useFactory: (moduleOptions) => {
|
|
73
|
+
return new EncryptionService(moduleOptions.encryptionKey);
|
|
74
|
+
},
|
|
75
|
+
inject: [EncryptionModuleOptionsProvide],
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
exports: [EncryptionService],
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
__setFunctionName(_classThis, "EncryptionModule");
|
|
83
|
+
(() => {
|
|
84
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
85
|
+
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
86
|
+
EncryptionModule = _classThis = _classDescriptor.value;
|
|
87
|
+
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
88
|
+
__runInitializers(_classThis, _classExtraInitializers);
|
|
89
|
+
})();
|
|
90
|
+
return EncryptionModule = _classThis;
|
|
91
|
+
})();
|
|
92
|
+
export { EncryptionModule };
|
|
93
|
+
//# sourceMappingURL=encryption.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encryption.module.js","sourceRoot":"","sources":["../../src/encryption.module.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,EAAiB,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAEvD,OAAO,EAAE,8BAA8B,EAAE,MAAM,oBAAoB,CAAC;AAEpE,OAAO,iBAAiB,MAAM,sBAAsB,CAAC;IAGxC,gBAAgB;4BAD5B,MAAM,CAAC,EAAE,CAAC;;;;;QAET,MAAM,CAAC,QAAQ,CAAC,OAAgC;YAC9C,OAAO;gBACL,MAAM,EAAE,gBAAgB;gBACxB,SAAS,EAAE;oBACT;wBACE,OAAO,EAAE,iBAAiB;wBAC1B,QAAQ,EAAE,IAAI,iBAAiB,CAAC,OAAO,CAAC,aAAa,CAAC;qBACvD;iBACF;gBACD,OAAO,EAAE,CAAC,iBAAiB,CAAC;aAC7B,CAAC;QACJ,CAAC;QAED,MAAM,CAAC,aAAa,CAAC,OAAqC;YACxD,OAAO;gBACL,MAAM,EAAE,gBAAgB;gBACxB,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,EAAE;gBAC9B,SAAS,EAAE;oBACT;wBACE,OAAO,EAAE,8BAA8B;wBACvC,UAAU,EAAE,OAAO,CAAC,UAAU;wBAC9B,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,EAAE;qBAC7B;oBACD;wBACE,OAAO,EAAE,iBAAiB;wBAC1B,UAAU,EAAE,CAAC,aAAsC,EAAE,EAAE;4BACrD,OAAO,IAAI,iBAAiB,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;wBAC5D,CAAC;wBACD,MAAM,EAAE,CAAC,8BAA8B,CAAC;qBACzC;iBACF;gBACD,OAAO,EAAE,CAAC,iBAAiB,CAAC;aAC7B,CAAC;QACJ,CAAC;;;;;QAlCH,6KAmCC;;;QAnCY,uDAAgB;;;;SAAhB,gBAAgB"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { GCMEncryptedData } from './aes-256-gcm.js';
|
|
2
|
+
declare class EncryptionService {
|
|
3
|
+
private readonly _encryptionKey?;
|
|
4
|
+
constructor(_encryptionKey?: (string | null) | undefined);
|
|
5
|
+
private get encryptionKey();
|
|
6
|
+
encrypt(plaintext: string): GCMEncryptedData;
|
|
7
|
+
decrypt(data: GCMEncryptedData): string;
|
|
8
|
+
}
|
|
9
|
+
export default EncryptionService;
|
|
10
|
+
//# sourceMappingURL=encryption.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encryption.service.d.ts","sourceRoot":"","sources":["../../src/encryption.service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAGtD,cACM,iBAAiB;IACT,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC;gBAAf,cAAc,CAAC,GAAE,MAAM,GAAG,IAAI,aAAA;IAE3D,OAAO,KAAK,aAAa,GAMxB;IAEM,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB;IAI5C,OAAO,CAAC,IAAI,EAAE,gBAAgB,GAAG,MAAM;CAG/C;AAED,eAAe,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
2
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
3
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
4
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
5
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
6
|
+
var _, done = false;
|
|
7
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
8
|
+
var context = {};
|
|
9
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
10
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
11
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
12
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
13
|
+
if (kind === "accessor") {
|
|
14
|
+
if (result === void 0) continue;
|
|
15
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
16
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
17
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
18
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
19
|
+
}
|
|
20
|
+
else if (_ = accept(result)) {
|
|
21
|
+
if (kind === "field") initializers.unshift(_);
|
|
22
|
+
else descriptor[key] = _;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
26
|
+
done = true;
|
|
27
|
+
};
|
|
28
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
29
|
+
var useValue = arguments.length > 2;
|
|
30
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
31
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
32
|
+
}
|
|
33
|
+
return useValue ? value : void 0;
|
|
34
|
+
};
|
|
35
|
+
var __setFunctionName = (this && this.__setFunctionName) || function (f, name, prefix) {
|
|
36
|
+
if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
|
|
37
|
+
return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
|
|
38
|
+
};
|
|
39
|
+
import { Injectable } from '@nestjs/common';
|
|
40
|
+
import { decryptAes256Gcm, encryptAes256Gcm } from './aes-256-gcm.js';
|
|
41
|
+
let EncryptionService = (() => {
|
|
42
|
+
let _classDecorators = [Injectable()];
|
|
43
|
+
let _classDescriptor;
|
|
44
|
+
let _classExtraInitializers = [];
|
|
45
|
+
let _classThis;
|
|
46
|
+
var EncryptionService = _classThis = class {
|
|
47
|
+
constructor(_encryptionKey) {
|
|
48
|
+
this._encryptionKey = _encryptionKey;
|
|
49
|
+
}
|
|
50
|
+
get encryptionKey() {
|
|
51
|
+
if (!this._encryptionKey) {
|
|
52
|
+
throw new Error('Encryption key is required');
|
|
53
|
+
}
|
|
54
|
+
return this._encryptionKey;
|
|
55
|
+
}
|
|
56
|
+
encrypt(plaintext) {
|
|
57
|
+
return encryptAes256Gcm(plaintext, this.encryptionKey);
|
|
58
|
+
}
|
|
59
|
+
decrypt(data) {
|
|
60
|
+
return decryptAes256Gcm(data, this.encryptionKey);
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
__setFunctionName(_classThis, "EncryptionService");
|
|
64
|
+
(() => {
|
|
65
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
66
|
+
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
67
|
+
EncryptionService = _classThis = _classDescriptor.value;
|
|
68
|
+
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
69
|
+
__runInitializers(_classThis, _classExtraInitializers);
|
|
70
|
+
})();
|
|
71
|
+
return EncryptionService = _classThis;
|
|
72
|
+
})();
|
|
73
|
+
export default EncryptionService;
|
|
74
|
+
//# sourceMappingURL=encryption.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encryption.service.js","sourceRoot":"","sources":["../../src/encryption.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAG5C,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;IAG7D,iBAAiB;4BADtB,UAAU,EAAE;;;;;QAEX,YAA6B,cAA8B;YAA9B,mBAAc,GAAd,cAAc,CAAgB;QAAG,CAAC;QAE/D,IAAY,aAAa;YACvB,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;gBACzB,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;YAChD,CAAC;YAED,OAAO,IAAI,CAAC,cAAc,CAAC;QAC7B,CAAC;QAEM,OAAO,CAAC,SAAiB;YAC9B,OAAO,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QACzD,CAAC;QAEM,OAAO,CAAC,IAAsB;YACnC,OAAO,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QACpD,CAAC;;;;;QAjBH,6KAkBC;;;QAlBK,uDAAiB;;;;AAoBvB,eAAe,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type { GCMEncryptedData } from './aes-256-gcm.js';
|
|
2
|
+
export { decryptAes256Gcm, encryptAes256Gcm } from './aes-256-gcm.js';
|
|
3
|
+
export { EncryptionModuleOptionsProvide } from './encryption.const.js';
|
|
4
|
+
export type { EncryptionModuleAsyncOptions, EncryptionModuleOptions } from './encryption.interface.js';
|
|
5
|
+
export { EncryptionModule } from './encryption.module.js';
|
|
6
|
+
export { default as EncryptionService } from './encryption.service.js';
|
|
7
|
+
//# sourceMappingURL=main.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/main.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,8BAA8B,EAAE,MAAM,oBAAoB,CAAC;AACpE,YAAY,EAAE,4BAA4B,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACpG,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { decryptAes256Gcm, encryptAes256Gcm } from './aes-256-gcm.js';
|
|
2
|
+
export { EncryptionModuleOptionsProvide } from './encryption.const.js';
|
|
3
|
+
export { EncryptionModule } from './encryption.module.js';
|
|
4
|
+
export { default as EncryptionService } from './encryption.service.js';
|
|
5
|
+
//# sourceMappingURL=main.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/main.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,8BAA8B,EAAE,MAAM,oBAAoB,CAAC;AAEpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "type": "module" }
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@voiceflow/encryption",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Voiceflow encryption library",
|
|
5
|
+
"license": "ISC",
|
|
6
|
+
"main": "build/cjs/main.js",
|
|
7
|
+
"module": "build/esm/main.js",
|
|
8
|
+
"types": "build/cjs/main.d.ts",
|
|
9
|
+
"files": [
|
|
10
|
+
"build"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "yarn g:turbo run build:cmd --filter=@voiceflow/encryption...",
|
|
14
|
+
"build:cjs": "yarn g:build:pkg cjs",
|
|
15
|
+
"build:cmd": "yarn g:run-p build:cjs build:esm",
|
|
16
|
+
"build:esm": "yarn g:build:pkg esm",
|
|
17
|
+
"clean": "yarn g:rimraf build",
|
|
18
|
+
"lint": "yarn g:run-p -c lint:eslint lint:prettier",
|
|
19
|
+
"lint:eslint": "yarn g:eslint",
|
|
20
|
+
"lint:fix": "yarn g:run-p -c \"lint:eslint --fix\" \"lint:prettier --write\"",
|
|
21
|
+
"lint:prettier": "yarn g:prettier --check",
|
|
22
|
+
"test": "yarn g:run-p -c test:dependencies test:types test:unit",
|
|
23
|
+
"test:dependencies": "yarn g:depcruise",
|
|
24
|
+
"test:types": "yarn g:tsc --noEmit",
|
|
25
|
+
"test:unit": "yarn g:vitest run --coverage"
|
|
26
|
+
},
|
|
27
|
+
"volta": {
|
|
28
|
+
"extends": "../../package.json"
|
|
29
|
+
},
|
|
30
|
+
"publishConfig": {
|
|
31
|
+
"access": "public"
|
|
32
|
+
},
|
|
33
|
+
"gitHead": "c71920a42998c80a09029b70724a39fb84f8df74"
|
|
34
|
+
}
|