favalib 0.0.1

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.
Files changed (67) hide show
  1. package/build/Command/BaseCommand.d.mts +65 -0
  2. package/build/Command/BaseCommand.mjs +54 -0
  3. package/build/Command/CommandQueue.d.mts +28 -0
  4. package/build/Command/CommandQueue.mjs +43 -0
  5. package/build/Command/commandConstructors.d.mts +11 -0
  6. package/build/Command/commandConstructors.mjs +11 -0
  7. package/build/Command/commands/AddEntryCommand.d.mts +31 -0
  8. package/build/Command/commands/AddEntryCommand.mjs +43 -0
  9. package/build/Command/commands/AddSyncDeviceCommand.d.mts +36 -0
  10. package/build/Command/commands/AddSyncDeviceCommand.mjs +42 -0
  11. package/build/Command/commands/DeleteEntryCommand.d.mts +35 -0
  12. package/build/Command/commands/DeleteEntryCommand.mjs +50 -0
  13. package/build/Command/commands/UpdateEntryCommand.d.mts +38 -0
  14. package/build/Command/commands/UpdateEntryCommand.mjs +51 -0
  15. package/build/CryptoProviders/browser/index.d.mts +73 -0
  16. package/build/CryptoProviders/browser/index.mjs +209 -0
  17. package/build/CryptoProviders/node/index.d.mts +62 -0
  18. package/build/CryptoProviders/node/index.mjs +189 -0
  19. package/build/TwoFALibError.d.mts +77 -0
  20. package/build/TwoFALibError.mjs +91 -0
  21. package/build/TwoFaLib.d.mts +95 -0
  22. package/build/TwoFaLib.mjs +180 -0
  23. package/build/TwoFaLibEvent.d.mts +8 -0
  24. package/build/TwoFaLibEvent.mjs +9 -0
  25. package/build/TwoFaLibMediator.d.mts +37 -0
  26. package/build/TwoFaLibMediator.mjs +58 -0
  27. package/build/interfaces/CommandTypes.d.mts +20 -0
  28. package/build/interfaces/CommandTypes.mjs +1 -0
  29. package/build/interfaces/CryptoLib.d.mts +113 -0
  30. package/build/interfaces/CryptoLib.mjs +1 -0
  31. package/build/interfaces/Entry.d.mts +33 -0
  32. package/build/interfaces/Entry.mjs +1 -0
  33. package/build/interfaces/Events.d.mts +22 -0
  34. package/build/interfaces/Events.mjs +1 -0
  35. package/build/interfaces/PassphraseExtraDict.d.ts +2 -0
  36. package/build/interfaces/PassphraseExtraDict.js +1 -0
  37. package/build/interfaces/SyncTypes.d.mts +45 -0
  38. package/build/interfaces/SyncTypes.mjs +1 -0
  39. package/build/interfaces/Vault.d.mts +30 -0
  40. package/build/interfaces/Vault.mjs +1 -0
  41. package/build/main.d.mts +12 -0
  42. package/build/main.mjs +5 -0
  43. package/build/subclasses/CommandManager.d.mts +46 -0
  44. package/build/subclasses/CommandManager.mjs +117 -0
  45. package/build/subclasses/ExportImportManager.d.mts +58 -0
  46. package/build/subclasses/ExportImportManager.mjs +105 -0
  47. package/build/subclasses/LibraryLoader.d.mts +56 -0
  48. package/build/subclasses/LibraryLoader.mjs +108 -0
  49. package/build/subclasses/PersistentStorageManager.d.mts +71 -0
  50. package/build/subclasses/PersistentStorageManager.mjs +127 -0
  51. package/build/subclasses/SyncManager.d.mts +161 -0
  52. package/build/subclasses/SyncManager.mjs +567 -0
  53. package/build/subclasses/VaultDataManager.d.mts +68 -0
  54. package/build/subclasses/VaultDataManager.mjs +114 -0
  55. package/build/subclasses/VaultOperationsManager.d.mts +91 -0
  56. package/build/subclasses/VaultOperationsManager.mjs +163 -0
  57. package/build/utils/constants.d.mts +2 -0
  58. package/build/utils/constants.mjs +1 -0
  59. package/build/utils/creationUtils.d.mts +43 -0
  60. package/build/utils/creationUtils.mjs +125 -0
  61. package/build/utils/exportImportUtils.d.mts +53 -0
  62. package/build/utils/exportImportUtils.mjs +185 -0
  63. package/build/utils/qrUtils.d.mts +25 -0
  64. package/build/utils/qrUtils.mjs +84 -0
  65. package/build/utils/syncUtils.d.mts +26 -0
  66. package/build/utils/syncUtils.mjs +78 -0
  67. package/package.json +56 -0
@@ -0,0 +1,209 @@
1
+ import forge from 'node-forge';
2
+ import { base64ToUint8Array, stringToUint8Array, uint8ArrayToBase64, uint8ArrayToString, } from 'uint8array-extras';
3
+ import { argon2id } from 'hash-wasm';
4
+ import { CryptoError } from '../../TwoFALibError.mjs';
5
+ /**
6
+ * Normalizes line endings in a string so they match the
7
+ * node cryptoprovider format
8
+ * @param str - The input string to normalize.
9
+ * @returns The normalized string with consistent line endings.
10
+ */
11
+ const normalizeLineEndings = (str) => {
12
+ return str.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
13
+ };
14
+ /**
15
+ * Create a password hash
16
+ * @param salt - The salt to use
17
+ * @param passphrase - The passphrase to hash
18
+ * @returns The calculated password hash
19
+ */
20
+ export const generatePassphraseHash = (salt, passphrase) => {
21
+ return argon2id({
22
+ password: passphrase,
23
+ salt,
24
+ parallelism: 1,
25
+ iterations: 256,
26
+ memorySize: 512,
27
+ hashLength: 64,
28
+ outputType: 'hex',
29
+ });
30
+ };
31
+ /**
32
+ * @inheritdoc
33
+ */
34
+ class BrowserCryptoLib {
35
+ /**
36
+ * @inheritdoc
37
+ */
38
+ async getRandomBytes(count) {
39
+ return Promise.resolve(window.crypto.getRandomValues(new Uint8Array(count)));
40
+ }
41
+ /**
42
+ * @inheritdoc
43
+ */
44
+ async createKeys(passphrase) {
45
+ // create random salt
46
+ const salt = uint8ArrayToBase64(window.crypto.getRandomValues(new Uint8Array(16)));
47
+ // create passwordHash
48
+ const passphraseHash = await generatePassphraseHash(salt, passphrase);
49
+ const { privateKey, encryptedPrivateKey, publicKey } = await this.createKeyPair(passphraseHash);
50
+ const symmetricKey = await this.createSymmetricKey();
51
+ const encryptedSymmetricKey = await this.encrypt(publicKey, symmetricKey);
52
+ return {
53
+ privateKey,
54
+ symmetricKey,
55
+ encryptedPrivateKey,
56
+ encryptedSymmetricKey: encryptedSymmetricKey,
57
+ salt,
58
+ publicKey,
59
+ };
60
+ }
61
+ /**
62
+ * @inheritdoc
63
+ */
64
+ async encryptKeys(privateKey, symmetricKey, salt, passphrase) {
65
+ // recreate passwordHash
66
+ const passphraseHash = await generatePassphraseHash(salt, passphrase);
67
+ const encryptedPrivateKey = await this.encryptPrivateKey(privateKey, passphraseHash);
68
+ const publicKey = await this.getPublicKeyFromPrivateKey(privateKey);
69
+ const encryptedSymmetricKey = await this.encrypt(publicKey, symmetricKey);
70
+ return {
71
+ encryptedPrivateKey,
72
+ encryptedSymmetricKey: encryptedSymmetricKey,
73
+ };
74
+ }
75
+ /**
76
+ * @inheritdoc
77
+ */
78
+ async decryptKeys(encryptedPrivateKey, encryptedSymmetricKey, salt, passphrase) {
79
+ // recreate passwordHash
80
+ const passphraseHash = await generatePassphraseHash(salt, passphrase);
81
+ const { privateKey, publicKey } = await this.decryptPrivateKey(encryptedPrivateKey, passphraseHash);
82
+ const symmetricKey = (await this.decrypt(privateKey, encryptedSymmetricKey));
83
+ return { privateKey, publicKey, symmetricKey };
84
+ }
85
+ /**
86
+ * @inheritdoc
87
+ */
88
+ async encrypt(publicKey, plainText) {
89
+ const publicKeyObj = forge.pki.publicKeyFromPem(publicKey);
90
+ const encrypted = publicKeyObj.encrypt(plainText, 'RSA-OAEP');
91
+ return Promise.resolve(btoa(encrypted));
92
+ }
93
+ /**
94
+ * @inheritdoc
95
+ */
96
+ async decrypt(privateKey, encryptedText) {
97
+ const privateKeyObj = forge.pki.privateKeyFromPem(privateKey);
98
+ const decrypted = privateKeyObj.decrypt(atob(encryptedText), 'RSA-OAEP');
99
+ return Promise.resolve(decrypted);
100
+ }
101
+ /**
102
+ * @inheritdoc
103
+ */
104
+ async encryptSymmetric(symmetricKey, plainText) {
105
+ const key = await window.crypto.subtle.importKey('raw', base64ToUint8Array(symmetricKey), { name: 'AES-CBC', length: 256 }, false, ['encrypt']);
106
+ const iv = window.crypto.getRandomValues(new Uint8Array(16));
107
+ const encrypted = await window.crypto.subtle.encrypt({ name: 'AES-CBC', iv }, key, stringToUint8Array(plainText));
108
+ const result = [
109
+ uint8ArrayToBase64(iv),
110
+ uint8ArrayToBase64(new Uint8Array(encrypted)),
111
+ ];
112
+ return result.join(':');
113
+ }
114
+ /**
115
+ * @inheritdoc
116
+ */
117
+ async decryptSymmetric(symmetricKey, encryptedText) {
118
+ const [ivString, encryptedData] = encryptedText.split(':');
119
+ const iv = base64ToUint8Array(ivString);
120
+ const keyUint8Array = base64ToUint8Array(symmetricKey);
121
+ const key = await window.crypto.subtle.importKey('raw', keyUint8Array, { name: 'AES-CBC', length: 256 }, false, ['decrypt']);
122
+ const encrypted = base64ToUint8Array(encryptedData);
123
+ const decrypted = await window.crypto.subtle.decrypt({ name: 'AES-CBC', iv }, key, encrypted);
124
+ return uint8ArrayToString(decrypted);
125
+ }
126
+ /**
127
+ * @inheritdoc
128
+ */
129
+ async createSymmetricKey() {
130
+ const key = await window.crypto.subtle.generateKey({ name: 'AES-CBC', length: 256 }, true, ['encrypt', 'decrypt']);
131
+ const exportedKey = await window.crypto.subtle.exportKey('raw', key);
132
+ return uint8ArrayToBase64(new Uint8Array(exportedKey));
133
+ }
134
+ /**
135
+ * @inheritdoc
136
+ */
137
+ async createSyncKey(sharedKey, salt) {
138
+ const key = await argon2id({
139
+ password: sharedKey,
140
+ salt,
141
+ parallelism: 1,
142
+ iterations: 256,
143
+ memorySize: 512,
144
+ hashLength: 32,
145
+ outputType: 'binary',
146
+ });
147
+ return uint8ArrayToBase64(key);
148
+ }
149
+ async encryptPrivateKey(privateKey, passphraseHash) {
150
+ const privateKeyObj = forge.pki.privateKeyFromPem(privateKey);
151
+ const encryptedPrivateKey = forge.pki.encryptRsaPrivateKey(privateKeyObj, passphraseHash, {
152
+ algorithm: 'aes256',
153
+ });
154
+ return Promise.resolve(encryptedPrivateKey);
155
+ }
156
+ async decryptPrivateKey(encryptedPrivateKey, passphraseHash) {
157
+ try {
158
+ const privateKeyPem = forge.pki.decryptRsaPrivateKey(encryptedPrivateKey, passphraseHash);
159
+ if (!privateKeyPem) {
160
+ throw new CryptoError('Invalid passphrase');
161
+ }
162
+ const privateKey = forge.pki.privateKeyToPem(privateKeyPem);
163
+ const publicKey = forge.pki.publicKeyToPem(forge.pki.setRsaPublicKey(privateKeyPem.n, privateKeyPem.e));
164
+ return Promise.resolve({
165
+ privateKey: normalizeLineEndings(privateKey),
166
+ publicKey: normalizeLineEndings(publicKey),
167
+ });
168
+ }
169
+ catch (err) {
170
+ // eslint-disable-next-line no-restricted-globals
171
+ if (err instanceof Error) {
172
+ if (err.message === 'Invalid passphrase') {
173
+ throw new CryptoError('Invalid passphrase');
174
+ }
175
+ if (err.message.includes('Unsupported private key')) {
176
+ throw new CryptoError('Invalid private key');
177
+ }
178
+ }
179
+ throw err;
180
+ }
181
+ }
182
+ async createKeyPair(passphrase) {
183
+ return new Promise((resolve, reject) => {
184
+ forge.pki.rsa.generateKeyPair({ bits: 4096 }, (err, keyPair) => {
185
+ if (err) {
186
+ reject(err);
187
+ }
188
+ else {
189
+ const publicKey = forge.pki.publicKeyToPem(keyPair.publicKey);
190
+ const privateKey = forge.pki.privateKeyToPem(keyPair.privateKey);
191
+ const encryptedPrivateKey = forge.pki.encryptRsaPrivateKey(keyPair.privateKey, passphrase, {
192
+ algorithm: 'aes256',
193
+ });
194
+ resolve({
195
+ privateKey: normalizeLineEndings(privateKey),
196
+ publicKey: normalizeLineEndings(publicKey),
197
+ encryptedPrivateKey,
198
+ });
199
+ }
200
+ });
201
+ });
202
+ }
203
+ async getPublicKeyFromPrivateKey(privateKey) {
204
+ const privateKeyObj = forge.pki.privateKeyFromPem(privateKey);
205
+ const publicKey = forge.pki.publicKeyToPem(forge.pki.setRsaPublicKey(privateKeyObj.n, privateKeyObj.e));
206
+ return Promise.resolve(normalizeLineEndings(publicKey));
207
+ }
208
+ }
209
+ export default BrowserCryptoLib;
@@ -0,0 +1,62 @@
1
+ import type CryptoLib from '../../interfaces/CryptoLib.mjs';
2
+ import type { Encrypted, EncryptedPrivateKey, EncryptedSymmetricKey, Passphrase, PrivateKey, PublicKey, Salt, SymmetricKey, SyncKey } from '../../interfaces/CryptoLib.mjs';
3
+ /**
4
+ * @inheritdoc
5
+ */
6
+ declare class NodeCryptoLib implements CryptoLib {
7
+ /**
8
+ * @inheritdoc
9
+ */
10
+ getRandomBytes(count: number): Promise<Uint8Array>;
11
+ /**
12
+ * @inheritdoc
13
+ */
14
+ createKeys(passphrase: Passphrase): Promise<{
15
+ privateKey: PrivateKey;
16
+ symmetricKey: SymmetricKey;
17
+ publicKey: PublicKey;
18
+ salt: Salt;
19
+ encryptedPrivateKey: EncryptedPrivateKey;
20
+ encryptedSymmetricKey: EncryptedSymmetricKey;
21
+ }>;
22
+ /**
23
+ * @inheritdoc
24
+ */
25
+ encryptKeys(privateKey: PrivateKey, symmetricKey: SymmetricKey, salt: Salt, passphrase: Passphrase): Promise<{
26
+ encryptedPrivateKey: EncryptedPrivateKey;
27
+ encryptedSymmetricKey: EncryptedSymmetricKey;
28
+ }>;
29
+ /**
30
+ * @inheritdoc
31
+ */
32
+ decryptKeys(encryptedPrivateKey: EncryptedPrivateKey, encryptedSymmetricKey: EncryptedSymmetricKey, salt: Salt, passphrase: Passphrase): Promise<{
33
+ privateKey: PrivateKey;
34
+ publicKey: PublicKey;
35
+ symmetricKey: SymmetricKey;
36
+ }>;
37
+ /**
38
+ * @inheritdoc
39
+ */
40
+ encrypt<T extends string>(publicKey: PublicKey, plainText: T): Promise<Encrypted<T>>;
41
+ /**
42
+ * @inheritdoc
43
+ */
44
+ decrypt<T extends string>(privateKey: PrivateKey, encryptedText: Encrypted<T>): Promise<T>;
45
+ /**
46
+ * @inheritdoc
47
+ */
48
+ encryptSymmetric<T extends string>(symmetricKey: SymmetricKey, plainText: T): Promise<Encrypted<T>>;
49
+ /**
50
+ * @inheritdoc
51
+ */
52
+ decryptSymmetric<T extends string>(symmetricKey: SymmetricKey, encryptedText: Encrypted<T>): Promise<T>;
53
+ /**
54
+ * @inheritdoc
55
+ */
56
+ createSymmetricKey(): Promise<SymmetricKey>;
57
+ /**
58
+ * @inheritdoc
59
+ */
60
+ createSyncKey(sharedKey: Uint8Array, salt: string): Promise<SyncKey>;
61
+ }
62
+ export default NodeCryptoLib;
@@ -0,0 +1,189 @@
1
+ /* eslint no-restricted-globals: ["error", "Error"] */
2
+ import { promisify } from 'node:util';
3
+ import { generateKeyPair as generateKeyPairCb, generateKey as generateKeyCb, publicEncrypt, privateDecrypt, createPrivateKey, createPublicKey, randomBytes, createCipheriv, createDecipheriv, } from 'node:crypto';
4
+ import { argon2id } from 'hash-wasm';
5
+ import { toUint8Array } from 'uint8array-extras';
6
+ import { CryptoError } from '../../TwoFALibError.mjs';
7
+ import { generatePassphraseHash } from '../browser/index.mjs';
8
+ const generateKeyPair = promisify(generateKeyPairCb);
9
+ const generateKey = promisify(generateKeyCb);
10
+ /**
11
+ * @inheritdoc
12
+ */
13
+ class NodeCryptoLib {
14
+ /**
15
+ * @inheritdoc
16
+ */
17
+ async getRandomBytes(count) {
18
+ return Promise.resolve(toUint8Array(randomBytes(count)));
19
+ }
20
+ /**
21
+ * @inheritdoc
22
+ */
23
+ async createKeys(passphrase) {
24
+ // create random salt
25
+ const salt = randomBytes(16).toString('base64');
26
+ // create passwordHash
27
+ const passphraseHash = await generatePassphraseHash(salt, passphrase);
28
+ // Generate public/private key pair
29
+ const { publicKey, privateKey: encryptedPrivateKey } = await generateKeyPair('rsa', {
30
+ modulusLength: 4096,
31
+ publicKeyEncoding: {
32
+ type: 'spki',
33
+ format: 'pem',
34
+ },
35
+ privateKeyEncoding: {
36
+ type: 'pkcs8',
37
+ format: 'pem',
38
+ cipher: 'aes-256-cbc',
39
+ passphrase: passphraseHash,
40
+ },
41
+ });
42
+ // Create and encrypt symmetric key with public key
43
+ const symmetricKey = await this.createSymmetricKey();
44
+ const encryptedSymmetricKey = await this.encrypt(publicKey, symmetricKey);
45
+ const { privateKey } = await this.decryptKeys(encryptedPrivateKey, encryptedSymmetricKey, salt, passphrase);
46
+ return {
47
+ privateKey: privateKey,
48
+ symmetricKey,
49
+ publicKey: publicKey,
50
+ salt: salt,
51
+ encryptedPrivateKey: encryptedPrivateKey,
52
+ encryptedSymmetricKey: encryptedSymmetricKey,
53
+ };
54
+ }
55
+ /**
56
+ * @inheritdoc
57
+ */
58
+ async encryptKeys(privateKey, symmetricKey, salt, passphrase) {
59
+ // recreate passwordHash
60
+ const passphraseHash = await generatePassphraseHash(salt, passphrase);
61
+ // Encrypt private key
62
+ const privateKeyObject = createPrivateKey({
63
+ key: privateKey,
64
+ format: 'pem',
65
+ });
66
+ const encryptedPrivateKey = privateKeyObject.export({
67
+ type: 'pkcs8',
68
+ format: 'pem',
69
+ cipher: 'aes-256-cbc',
70
+ passphrase: passphraseHash,
71
+ });
72
+ // Encrypt symmetric key with public key
73
+ const publicKeyObject = createPublicKey(privateKeyObject);
74
+ const publicKey = publicKeyObject.export({
75
+ type: 'spki',
76
+ format: 'pem',
77
+ });
78
+ const encryptedSymmetricKey = await this.encrypt(publicKey, symmetricKey);
79
+ return {
80
+ encryptedPrivateKey,
81
+ encryptedSymmetricKey: encryptedSymmetricKey,
82
+ };
83
+ }
84
+ /**
85
+ * @inheritdoc
86
+ */
87
+ async decryptKeys(encryptedPrivateKey, encryptedSymmetricKey, salt, passphrase) {
88
+ // recreate passwordHash
89
+ const passphraseHash = await generatePassphraseHash(salt, passphrase);
90
+ let privateKeyObject;
91
+ let privateKey;
92
+ try {
93
+ privateKeyObject = createPrivateKey({
94
+ key: encryptedPrivateKey,
95
+ type: 'pkcs8',
96
+ format: 'pem',
97
+ passphrase: passphraseHash,
98
+ });
99
+ privateKey = privateKeyObject.export({
100
+ type: 'pkcs8',
101
+ format: 'pem',
102
+ });
103
+ }
104
+ catch (err) {
105
+ // eslint-disable-next-line no-restricted-globals
106
+ if (err instanceof Error && 'code' in err) {
107
+ if (err.code === 'ERR_OSSL_BAD_DECRYPT') {
108
+ throw new CryptoError('Invalid passphrase');
109
+ }
110
+ if (err.code === 'ERR_OSSL_UNSUPPORTED') {
111
+ throw new CryptoError('Invalid private key');
112
+ }
113
+ }
114
+ throw err;
115
+ }
116
+ const publicKeyObject = createPublicKey(privateKeyObject);
117
+ const publicKey = publicKeyObject.export({
118
+ type: 'spki',
119
+ format: 'pem',
120
+ });
121
+ // Decrypt the symmetric key
122
+ const symmetricKey = (await this.decrypt(privateKey, encryptedSymmetricKey));
123
+ return { privateKey, publicKey, symmetricKey };
124
+ }
125
+ /**
126
+ * @inheritdoc
127
+ */
128
+ async encrypt(publicKey, plainText) {
129
+ const buffer = Buffer.from(plainText, 'utf8');
130
+ const encrypted = publicEncrypt(publicKey, buffer);
131
+ return Promise.resolve(encrypted.toString('base64'));
132
+ }
133
+ /**
134
+ * @inheritdoc
135
+ */
136
+ async decrypt(privateKey, encryptedText) {
137
+ const buffer = Buffer.from(encryptedText, 'base64');
138
+ const decrypted = privateDecrypt({
139
+ key: privateKey,
140
+ }, buffer);
141
+ return Promise.resolve(decrypted.toString('utf8'));
142
+ }
143
+ /**
144
+ * @inheritdoc
145
+ */
146
+ async encryptSymmetric(symmetricKey, plainText) {
147
+ const iv = randomBytes(16);
148
+ const keyBuffer = Buffer.from(symmetricKey, 'base64');
149
+ const cipher = createCipheriv('aes-256-cbc', keyBuffer, iv);
150
+ let encrypted = cipher.update(plainText, 'utf8', 'base64');
151
+ encrypted += cipher.final('base64');
152
+ return Promise.resolve((iv.toString('base64') + ':' + encrypted));
153
+ }
154
+ /**
155
+ * @inheritdoc
156
+ */
157
+ async decryptSymmetric(symmetricKey, encryptedText) {
158
+ const [ivString, encryptedData] = encryptedText.split(':');
159
+ const iv = Buffer.from(ivString, 'base64');
160
+ const keyBuffer = Buffer.from(symmetricKey, 'base64');
161
+ const decipher = createDecipheriv('aes-256-cbc', keyBuffer, iv);
162
+ let decrypted = decipher.update(encryptedData, 'base64', 'utf8');
163
+ decrypted += decipher.final('utf8');
164
+ return Promise.resolve(decrypted);
165
+ }
166
+ /**
167
+ * @inheritdoc
168
+ */
169
+ async createSymmetricKey() {
170
+ const key = await generateKey('aes', { length: 256 });
171
+ return key.export().toString('base64');
172
+ }
173
+ /**
174
+ * @inheritdoc
175
+ */
176
+ async createSyncKey(sharedKey, salt) {
177
+ const keyBuffer = await argon2id({
178
+ password: sharedKey,
179
+ salt,
180
+ parallelism: 1,
181
+ iterations: 256,
182
+ memorySize: 512,
183
+ hashLength: 32,
184
+ outputType: 'binary',
185
+ });
186
+ return Buffer.from(keyBuffer).toString('base64');
187
+ }
188
+ }
189
+ export default NodeCryptoLib;
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Custom error class for the libs errors.
3
+ */
4
+ export declare class TwoFALibError extends Error {
5
+ /**
6
+ * Creates a new Error.
7
+ * @param message - The error message.
8
+ */
9
+ constructor(message: string);
10
+ }
11
+ /**
12
+ * Error thrown during lib initialization failures.
13
+ */
14
+ export declare class InitializationError extends TwoFALibError {
15
+ }
16
+ /**
17
+ * Error thrown during authentication, e.g. wrong passphrase for locked vault.
18
+ */
19
+ export declare class AuthenticationError extends TwoFALibError {
20
+ }
21
+ /**
22
+ * Error thrown when an entry is requested but not found.
23
+ */
24
+ export declare class EntryNotFoundError extends TwoFALibError {
25
+ }
26
+ /**
27
+ * Error thrown when token generation fails.
28
+ */
29
+ export declare class TokenGenerationError extends TwoFALibError {
30
+ }
31
+ /**
32
+ * Error thrown when an unexpected error occurs during cryptographic operations.
33
+ */
34
+ export declare class CryptoError extends TwoFALibError {
35
+ }
36
+ /**
37
+ * Error thrown when an unexpected error occurs during export/import operations.
38
+ */
39
+ export declare class ExportImportError extends TwoFALibError {
40
+ }
41
+ /**
42
+ * Error thrown when an unexpected error occurs during synchronization.
43
+ */
44
+ export declare class SyncError extends TwoFALibError {
45
+ }
46
+ /**
47
+ * Error thrown when synchronization is in the wrong state for the operation.
48
+ */
49
+ export declare class SyncInWrongStateError extends SyncError {
50
+ /**
51
+ * @inheritdoc
52
+ */
53
+ constructor(message?: string);
54
+ }
55
+ /**
56
+ * Error thrown when starting an add device flow while a previous one is still active.
57
+ */
58
+ export declare class SyncAddDeviceFlowConflictError extends SyncError {
59
+ /**
60
+ * @inheritdoc
61
+ */
62
+ constructor(message?: string);
63
+ }
64
+ /**
65
+ * Error thrown when attempting a sync operation when there is no server connection.
66
+ */
67
+ export declare class SyncNoServerConnectionError extends SyncError {
68
+ /**
69
+ * @inheritdoc
70
+ */
71
+ constructor(message?: string);
72
+ }
73
+ /**
74
+ * Error thrown when an invalid command is being executed.
75
+ */
76
+ export declare class InvalidCommandError extends TwoFALibError {
77
+ }
@@ -0,0 +1,91 @@
1
+ /* eslint-disable no-restricted-globals */
2
+ /**
3
+ * Custom error class for the libs errors.
4
+ */
5
+ export class TwoFALibError extends Error {
6
+ /**
7
+ * Creates a new Error.
8
+ * @param message - The error message.
9
+ */
10
+ constructor(message) {
11
+ super(message);
12
+ this.name = 'TwoFALibError';
13
+ }
14
+ }
15
+ /**
16
+ * Error thrown during lib initialization failures.
17
+ */
18
+ export class InitializationError extends TwoFALibError {
19
+ }
20
+ /**
21
+ * Error thrown during authentication, e.g. wrong passphrase for locked vault.
22
+ */
23
+ export class AuthenticationError extends TwoFALibError {
24
+ }
25
+ /**
26
+ * Error thrown when an entry is requested but not found.
27
+ */
28
+ export class EntryNotFoundError extends TwoFALibError {
29
+ }
30
+ /**
31
+ * Error thrown when token generation fails.
32
+ */
33
+ export class TokenGenerationError extends TwoFALibError {
34
+ }
35
+ /**
36
+ * Error thrown when an unexpected error occurs during cryptographic operations.
37
+ */
38
+ export class CryptoError extends TwoFALibError {
39
+ }
40
+ /**
41
+ * Error thrown when an unexpected error occurs during export/import operations.
42
+ */
43
+ export class ExportImportError extends TwoFALibError {
44
+ }
45
+ /**
46
+ * Error thrown when an unexpected error occurs during synchronization.
47
+ */
48
+ export class SyncError extends TwoFALibError {
49
+ }
50
+ /**
51
+ * Error thrown when synchronization is in the wrong state for the operation.
52
+ */
53
+ export class SyncInWrongStateError extends SyncError {
54
+ /**
55
+ * @inheritdoc
56
+ */
57
+ constructor(message) {
58
+ super(message ?? 'Unexpected state while syncing');
59
+ this.name = 'TwoFALibError';
60
+ }
61
+ }
62
+ /**
63
+ * Error thrown when starting an add device flow while a previous one is still active.
64
+ */
65
+ export class SyncAddDeviceFlowConflictError extends SyncError {
66
+ /**
67
+ * @inheritdoc
68
+ */
69
+ constructor(message) {
70
+ super(message ??
71
+ "Can't start an add device flow while a previous one is still active");
72
+ this.name = 'TwoFALibError';
73
+ }
74
+ }
75
+ /**
76
+ * Error thrown when attempting a sync operation when there is no server connection.
77
+ */
78
+ export class SyncNoServerConnectionError extends SyncError {
79
+ /**
80
+ * @inheritdoc
81
+ */
82
+ constructor(message) {
83
+ super(message ?? 'No server connection available');
84
+ this.name = 'TwoFALibError';
85
+ }
86
+ }
87
+ /**
88
+ * Error thrown when an invalid command is being executed.
89
+ */
90
+ export class InvalidCommandError extends TwoFALibError {
91
+ }