favalib 0.0.11 → 0.0.13
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/build/TwoFALibError.d.mts +1 -1
- package/build/TwoFALibError.mjs +1 -1
- package/build/TwoFaLib.d.mts +6 -6
- package/build/TwoFaLib.mjs +22 -18
- package/build/interfaces/CryptoLib.d.mts +11 -11
- package/build/interfaces/OpenPgpLib.d.mts +20 -0
- package/build/interfaces/PasswordExtraDict.d.ts +2 -0
- package/build/interfaces/PasswordExtraDict.js +1 -0
- package/build/interfaces/PlatformProviders.d.mts +26 -0
- package/build/interfaces/PlatformProviders.mjs +1 -0
- package/build/interfaces/QrCodeLib.d.mts +19 -0
- package/build/interfaces/QrCodeLib.mjs +1 -0
- package/build/main.d.mts +3 -2
- package/build/{CryptoProviders/browser/index.d.mts → platformProviders/browser/cryptoLib.d.mts} +6 -6
- package/build/{CryptoProviders/browser/index.mjs → platformProviders/browser/cryptoLib.mjs} +21 -21
- package/build/platformProviders/browser/index.d.mts +6 -0
- package/build/platformProviders/browser/index.mjs +13 -0
- package/build/platformProviders/browser/openPgpLib.d.mts +20 -0
- package/build/platformProviders/browser/openPgpLib.mjs +44 -0
- package/build/platformProviders/browser/qrCodeLib.d.mts +25 -0
- package/build/platformProviders/browser/qrCodeLib.mjs +69 -0
- package/build/{CryptoProviders/node/index.d.mts → platformProviders/node/cryptoLib.d.mts} +4 -4
- package/build/{CryptoProviders/node/index.mjs → platformProviders/node/cryptoLib.mjs} +12 -12
- package/build/platformProviders/node/index.d.mts +6 -0
- package/build/platformProviders/node/index.mjs +13 -0
- package/build/platformProviders/node/openPgpLib.d.mts +20 -0
- package/build/platformProviders/node/openPgpLib.mjs +44 -0
- package/build/platformProviders/node/qrCodeLib.d.mts +28 -0
- package/build/platformProviders/node/qrCodeLib.mjs +54 -0
- package/build/subclasses/ExportImportManager.d.mts +8 -8
- package/build/subclasses/ExportImportManager.mjs +15 -15
- package/build/subclasses/LibraryLoader.d.mts +26 -12
- package/build/subclasses/LibraryLoader.mjs +26 -34
- package/build/subclasses/PersistentStorageManager.d.mts +16 -16
- package/build/subclasses/PersistentStorageManager.mjs +20 -20
- package/build/subclasses/StorageOperationsManager.d.mts +7 -7
- package/build/subclasses/StorageOperationsManager.mjs +7 -7
- package/build/subclasses/SyncManager.mjs +7 -6
- package/build/utils/creationUtils.d.mts +20 -20
- package/build/utils/creationUtils.mjs +36 -34
- package/build/utils/exportImportUtils.d.mts +5 -3
- package/build/utils/exportImportUtils.mjs +2 -12
- package/build/utils/qrUtils.d.mts +0 -16
- package/build/utils/qrUtils.mjs +2 -68
- package/build/utils/syncUtils.d.mts +3 -2
- package/build/utils/syncUtils.mjs +3 -19
- package/package.json +8 -8
- package/build/interfaces/PassphraseExtraDict.d.ts +0 -2
- /package/build/interfaces/{PassphraseExtraDict.js → OpenPgpLib.mjs} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { InitializationError
|
|
1
|
+
import { InitializationError } from '../TwoFALibError.mjs';
|
|
2
2
|
/**
|
|
3
3
|
* Class responsible for loading various external (big) libraries required by the application.
|
|
4
4
|
* All libraries (except CryptoLib) are loaded on demand. This helps to reduce the initial bundle size.
|
|
@@ -6,14 +6,15 @@ import { InitializationError, TwoFALibError } from '../TwoFALibError.mjs';
|
|
|
6
6
|
class LibraryLoader {
|
|
7
7
|
/**
|
|
8
8
|
* Constructs a new instance of LibraryLoader.
|
|
9
|
-
* @param
|
|
10
|
-
* @throws {InitializationError} If the provided
|
|
9
|
+
* @param platformProviders - Platform-specific providers containing CryptoLib and other providers.
|
|
10
|
+
* @throws {InitializationError} If the provided platform providers are invalid.
|
|
11
11
|
*/
|
|
12
|
-
constructor(
|
|
13
|
-
if (!
|
|
14
|
-
throw new InitializationError('CryptoLib is required');
|
|
12
|
+
constructor(platformProviders) {
|
|
13
|
+
if (!platformProviders?.CryptoLib) {
|
|
14
|
+
throw new InitializationError('PlatformProviders with CryptoLib is required');
|
|
15
15
|
}
|
|
16
|
-
this.
|
|
16
|
+
this.platformProviders = platformProviders;
|
|
17
|
+
this.cryptoLib = new platformProviders.CryptoLib();
|
|
17
18
|
}
|
|
18
19
|
/**
|
|
19
20
|
* @returns The CryptoLib instance.
|
|
@@ -21,28 +22,26 @@ class LibraryLoader {
|
|
|
21
22
|
getCryptoLib() {
|
|
22
23
|
return this.cryptoLib;
|
|
23
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* @returns The PlatformProviders instance.
|
|
27
|
+
*/
|
|
28
|
+
getPlatformProviders() {
|
|
29
|
+
return this.platformProviders;
|
|
30
|
+
}
|
|
24
31
|
/**
|
|
25
32
|
* Loads and returns the OpenPGP library on demand.
|
|
26
33
|
* @returns A promise that resolves to the OpenPGP library.
|
|
27
34
|
*/
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
const module = await import('openpgp');
|
|
31
|
-
// enable Authenticated Encryption with Associated Data
|
|
32
|
-
module.config.aeadProtect = true;
|
|
33
|
-
this.openPgpLib = module;
|
|
34
|
-
}
|
|
35
|
+
getOpenPGPLib() {
|
|
36
|
+
this.openPgpLib ??= new this.platformProviders.OpenPgpLib();
|
|
35
37
|
return this.openPgpLib;
|
|
36
38
|
}
|
|
37
39
|
/**
|
|
38
40
|
* Loads and returns the QR Generator library on demand.
|
|
39
41
|
* @returns A promise that resolves to the QR Generator library.
|
|
40
42
|
*/
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const module = await import('qrcode');
|
|
44
|
-
this.qrGeneratorLib = module.default;
|
|
45
|
-
}
|
|
43
|
+
getQrGeneratorLib() {
|
|
44
|
+
this.qrGeneratorLib ??= new this.platformProviders.QrCodeLib();
|
|
46
45
|
return this.qrGeneratorLib;
|
|
47
46
|
}
|
|
48
47
|
/**
|
|
@@ -56,21 +55,6 @@ class LibraryLoader {
|
|
|
56
55
|
}
|
|
57
56
|
return this.jsQrLib;
|
|
58
57
|
}
|
|
59
|
-
/**
|
|
60
|
-
* Loads and returns the Canvas library on demand.
|
|
61
|
-
* @returns A promise that resolves to the Canvas library.
|
|
62
|
-
* @throws {TwoFALibError} If the library cannot be loaded in a browser environment.
|
|
63
|
-
*/
|
|
64
|
-
async getCanvasLib() {
|
|
65
|
-
if (typeof window !== 'undefined') {
|
|
66
|
-
throw new TwoFALibError('Canvas lib can not be loaded in browser env');
|
|
67
|
-
}
|
|
68
|
-
if (!this.canvasLib) {
|
|
69
|
-
const module = await import('canvas');
|
|
70
|
-
this.canvasLib = module.default;
|
|
71
|
-
}
|
|
72
|
-
return this.canvasLib;
|
|
73
|
-
}
|
|
74
58
|
/**
|
|
75
59
|
* Loads and returns the URL Parser library on demand.
|
|
76
60
|
* @returns A promise that resolves to the URL Parser library.
|
|
@@ -82,6 +66,14 @@ class LibraryLoader {
|
|
|
82
66
|
}
|
|
83
67
|
return this.urlParserLib;
|
|
84
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* Loads and returns the WebSocket library on demand.
|
|
71
|
+
* @returns The WebSocket library.
|
|
72
|
+
*/
|
|
73
|
+
getWebSocketLib() {
|
|
74
|
+
this.webSocketLib ??= this.platformProviders.WebSocketLib();
|
|
75
|
+
return this.webSocketLib;
|
|
76
|
+
}
|
|
85
77
|
/**
|
|
86
78
|
* Loads and returns the Zxcvbn library on demand.
|
|
87
79
|
* @returns A promise that resolves to the Zxcvbn library.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { EncryptedPrivateKey, EncryptedSymmetricKey,
|
|
1
|
+
import type { EncryptedPrivateKey, EncryptedSymmetricKey, Password, PrivateKey, Salt, SymmetricKey } from '../interfaces/CryptoLib.mjs';
|
|
2
2
|
import { EncryptedVaultStateString, LockedRepresentationString } from '../interfaces/Vault.mjs';
|
|
3
3
|
import type TwoFaLibMediator from '../TwoFaLibMediator.mjs';
|
|
4
4
|
import type { FavaMeta } from '../interfaces/FavaMeta.mjs';
|
|
5
|
-
import type {
|
|
5
|
+
import type { PasswordExtraDict } from '../interfaces/PasswordExtraDict.js';
|
|
6
6
|
import type { SaveFunction } from '../interfaces/SaveFunction.mjs';
|
|
7
7
|
import type { DeviceId } from '../interfaces/SyncTypes.mjs';
|
|
8
8
|
/**
|
|
@@ -10,7 +10,7 @@ import type { DeviceId } from '../interfaces/SyncTypes.mjs';
|
|
|
10
10
|
*/
|
|
11
11
|
declare class PersistentStorageManager {
|
|
12
12
|
private mediator;
|
|
13
|
-
private readonly
|
|
13
|
+
private readonly passwordExtraDict;
|
|
14
14
|
private readonly favaMeta;
|
|
15
15
|
private readonly privateKey;
|
|
16
16
|
private readonly symmetricKey;
|
|
@@ -23,7 +23,7 @@ declare class PersistentStorageManager {
|
|
|
23
23
|
/**
|
|
24
24
|
* Constructs a new instance of PersistentStorageManager.
|
|
25
25
|
* @param mediator - The mediator for accessing other components.
|
|
26
|
-
* @param
|
|
26
|
+
* @param passwordExtraDict - Additional words to be used for password strength evaluation.
|
|
27
27
|
* @param favaMeta - Meta info containing at least a unique identifier for this device.
|
|
28
28
|
* @param privateKey - The private key used for cryptographic operations.
|
|
29
29
|
* @param symmetricKey - The symmetric key used for cryptographic operations.
|
|
@@ -32,7 +32,7 @@ declare class PersistentStorageManager {
|
|
|
32
32
|
* @param salt - The salt used for key derivation.
|
|
33
33
|
* @param saveFunction - The function to save the data.
|
|
34
34
|
*/
|
|
35
|
-
constructor(mediator: TwoFaLibMediator,
|
|
35
|
+
constructor(mediator: TwoFaLibMediator, passwordExtraDict: PasswordExtraDict, favaMeta: FavaMeta, privateKey: PrivateKey, symmetricKey: SymmetricKey, encryptedPrivateKey: EncryptedPrivateKey, encryptedSymmetricKey: EncryptedSymmetricKey, salt: Salt, saveFunction?: SaveFunction | undefined);
|
|
36
36
|
private get cryptoLib();
|
|
37
37
|
private get vaultDataManager();
|
|
38
38
|
private get syncManager();
|
|
@@ -46,7 +46,7 @@ declare class PersistentStorageManager {
|
|
|
46
46
|
getEncryptedVaultState(key?: SymmetricKey, forDeviceId?: DeviceId): Promise<EncryptedVaultStateString>;
|
|
47
47
|
/**
|
|
48
48
|
* Creates a partially encrypted representation of all data, except for
|
|
49
|
-
* the
|
|
49
|
+
* the password, that is needed to load the library. This can be used
|
|
50
50
|
* for secure storage of the library's data.
|
|
51
51
|
* @returns A promise that resolves with a json encoded string of
|
|
52
52
|
* the partially encrypted library's data.
|
|
@@ -67,19 +67,19 @@ declare class PersistentStorageManager {
|
|
|
67
67
|
*/
|
|
68
68
|
private performSave;
|
|
69
69
|
/**
|
|
70
|
-
* Validates the provided
|
|
70
|
+
* Validates the provided password against the current library password.
|
|
71
71
|
* @param salt - The salt used for key derivation.
|
|
72
|
-
* @param
|
|
73
|
-
* @returns A promise that resolves with a boolean indicating whether the
|
|
72
|
+
* @param password - The password to validate.
|
|
73
|
+
* @returns A promise that resolves with a boolean indicating whether the password is valid.
|
|
74
74
|
*/
|
|
75
|
-
|
|
75
|
+
validatePassword(salt: Salt, password: Password): Promise<boolean>;
|
|
76
76
|
/**
|
|
77
|
-
* Changes the library's
|
|
78
|
-
* @param
|
|
79
|
-
* @param
|
|
80
|
-
* @returns A promise that resolves when the
|
|
81
|
-
* @throws {AuthenticationError} If the provided old
|
|
77
|
+
* Changes the library's password.
|
|
78
|
+
* @param oldPassword - The current password.
|
|
79
|
+
* @param newPassword - The new password to set.
|
|
80
|
+
* @returns A promise that resolves when the password change is complete.
|
|
81
|
+
* @throws {AuthenticationError} If the provided old password is incorrect.
|
|
82
82
|
*/
|
|
83
|
-
|
|
83
|
+
changePassword(oldPassword: Password, newPassword: Password): Promise<void>;
|
|
84
84
|
}
|
|
85
85
|
export default PersistentStorageManager;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AuthenticationError } from '../TwoFALibError.mjs';
|
|
2
2
|
import TwoFaLib from '../TwoFaLib.mjs';
|
|
3
|
-
import {
|
|
3
|
+
import { validatePasswordStrength } from '../utils/creationUtils.mjs';
|
|
4
4
|
/**
|
|
5
5
|
* Manages all storage of data that should be persistent.
|
|
6
6
|
*/
|
|
@@ -9,7 +9,7 @@ class PersistentStorageManager {
|
|
|
9
9
|
/**
|
|
10
10
|
* Constructs a new instance of PersistentStorageManager.
|
|
11
11
|
* @param mediator - The mediator for accessing other components.
|
|
12
|
-
* @param
|
|
12
|
+
* @param passwordExtraDict - Additional words to be used for password strength evaluation.
|
|
13
13
|
* @param favaMeta - Meta info containing at least a unique identifier for this device.
|
|
14
14
|
* @param privateKey - The private key used for cryptographic operations.
|
|
15
15
|
* @param symmetricKey - The symmetric key used for cryptographic operations.
|
|
@@ -18,9 +18,9 @@ class PersistentStorageManager {
|
|
|
18
18
|
* @param salt - The salt used for key derivation.
|
|
19
19
|
* @param saveFunction - The function to save the data.
|
|
20
20
|
*/
|
|
21
|
-
constructor(mediator,
|
|
21
|
+
constructor(mediator, passwordExtraDict, favaMeta, privateKey, symmetricKey, encryptedPrivateKey, encryptedSymmetricKey, salt, saveFunction) {
|
|
22
22
|
this.mediator = mediator;
|
|
23
|
-
this.
|
|
23
|
+
this.passwordExtraDict = passwordExtraDict;
|
|
24
24
|
this.favaMeta = favaMeta;
|
|
25
25
|
this.privateKey = privateKey;
|
|
26
26
|
this.symmetricKey = symmetricKey;
|
|
@@ -67,7 +67,7 @@ class PersistentStorageManager {
|
|
|
67
67
|
}
|
|
68
68
|
/**
|
|
69
69
|
* Creates a partially encrypted representation of all data, except for
|
|
70
|
-
* the
|
|
70
|
+
* the password, that is needed to load the library. This can be used
|
|
71
71
|
* for secure storage of the library's data.
|
|
72
72
|
* @returns A promise that resolves with a json encoded string of
|
|
73
73
|
* the partially encrypted library's data.
|
|
@@ -122,14 +122,14 @@ class PersistentStorageManager {
|
|
|
122
122
|
await this.saveFunction(lockedRepresentation);
|
|
123
123
|
}
|
|
124
124
|
/**
|
|
125
|
-
* Validates the provided
|
|
125
|
+
* Validates the provided password against the current library password.
|
|
126
126
|
* @param salt - The salt used for key derivation.
|
|
127
|
-
* @param
|
|
128
|
-
* @returns A promise that resolves with a boolean indicating whether the
|
|
127
|
+
* @param password - The password to validate.
|
|
128
|
+
* @returns A promise that resolves with a boolean indicating whether the password is valid.
|
|
129
129
|
*/
|
|
130
|
-
async
|
|
130
|
+
async validatePassword(salt, password) {
|
|
131
131
|
try {
|
|
132
|
-
await this.cryptoLib.decryptKeys(this.encryptedPrivateKey, this.encryptedSymmetricKey, salt,
|
|
132
|
+
await this.cryptoLib.decryptKeys(this.encryptedPrivateKey, this.encryptedSymmetricKey, salt, password);
|
|
133
133
|
return true;
|
|
134
134
|
}
|
|
135
135
|
catch {
|
|
@@ -137,18 +137,18 @@ class PersistentStorageManager {
|
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
139
|
/**
|
|
140
|
-
* Changes the library's
|
|
141
|
-
* @param
|
|
142
|
-
* @param
|
|
143
|
-
* @returns A promise that resolves when the
|
|
144
|
-
* @throws {AuthenticationError} If the provided old
|
|
140
|
+
* Changes the library's password.
|
|
141
|
+
* @param oldPassword - The current password.
|
|
142
|
+
* @param newPassword - The new password to set.
|
|
143
|
+
* @returns A promise that resolves when the password change is complete.
|
|
144
|
+
* @throws {AuthenticationError} If the provided old password is incorrect.
|
|
145
145
|
*/
|
|
146
|
-
async
|
|
147
|
-
await
|
|
148
|
-
const isValid = await this.
|
|
146
|
+
async changePassword(oldPassword, newPassword) {
|
|
147
|
+
await validatePasswordStrength(this.mediator.getComponent('libraryLoader'), newPassword, this.passwordExtraDict);
|
|
148
|
+
const isValid = await this.validatePassword(this.salt, oldPassword);
|
|
149
149
|
if (!isValid)
|
|
150
|
-
throw new AuthenticationError('Invalid old
|
|
151
|
-
const { encryptedPrivateKey: newEncryptedPrivateKey, encryptedSymmetricKey: newEncryptedSymmetricKey, } = await this.cryptoLib.encryptKeys(this.privateKey, this.symmetricKey, this.salt,
|
|
150
|
+
throw new AuthenticationError('Invalid old password');
|
|
151
|
+
const { encryptedPrivateKey: newEncryptedPrivateKey, encryptedSymmetricKey: newEncryptedSymmetricKey, } = await this.cryptoLib.encryptKeys(this.privateKey, this.symmetricKey, this.salt, newPassword);
|
|
152
152
|
this.encryptedPrivateKey = newEncryptedPrivateKey;
|
|
153
153
|
this.encryptedSymmetricKey = newEncryptedSymmetricKey;
|
|
154
154
|
await this.save();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type TwoFaLibMediator from '../TwoFaLibMediator.mjs';
|
|
2
|
-
import type {
|
|
2
|
+
import type { Password } from '../interfaces/CryptoLib.mjs';
|
|
3
3
|
import type { SaveFunction } from '../interfaces/SaveFunction.mjs';
|
|
4
4
|
/**
|
|
5
5
|
* Manages the public operations related to the vault storage
|
|
@@ -21,13 +21,13 @@ declare class StorageOperationsManager {
|
|
|
21
21
|
*/
|
|
22
22
|
forceSave(): Promise<void>;
|
|
23
23
|
/**
|
|
24
|
-
* Changes the library's
|
|
25
|
-
* @param
|
|
26
|
-
* @param
|
|
27
|
-
* @returns A promise that resolves when the
|
|
28
|
-
* @throws {AuthenticationError} If the provided old
|
|
24
|
+
* Changes the library's password.
|
|
25
|
+
* @param oldPassword - The current password.
|
|
26
|
+
* @param newPassword - The new password to set.
|
|
27
|
+
* @returns A promise that resolves when the password change is complete.
|
|
28
|
+
* @throws {AuthenticationError} If the provided old password is incorrect.
|
|
29
29
|
*/
|
|
30
|
-
|
|
30
|
+
changePassword(oldPassword: Password, newPassword: Password): Promise<void>;
|
|
31
31
|
/**
|
|
32
32
|
* Sets the save function for the library.
|
|
33
33
|
* @param saveFunction - The save function to set.
|
|
@@ -23,14 +23,14 @@ class StorageOperationsManager {
|
|
|
23
23
|
return this.persistentStorage.save();
|
|
24
24
|
}
|
|
25
25
|
/**
|
|
26
|
-
* Changes the library's
|
|
27
|
-
* @param
|
|
28
|
-
* @param
|
|
29
|
-
* @returns A promise that resolves when the
|
|
30
|
-
* @throws {AuthenticationError} If the provided old
|
|
26
|
+
* Changes the library's password.
|
|
27
|
+
* @param oldPassword - The current password.
|
|
28
|
+
* @param newPassword - The new password to set.
|
|
29
|
+
* @returns A promise that resolves when the password change is complete.
|
|
30
|
+
* @throws {AuthenticationError} If the provided old password is incorrect.
|
|
31
31
|
*/
|
|
32
|
-
async
|
|
33
|
-
return this.persistentStorage.
|
|
32
|
+
async changePassword(oldPassword, newPassword) {
|
|
33
|
+
return this.persistentStorage.changePassword(oldPassword, newPassword);
|
|
34
34
|
}
|
|
35
35
|
/**
|
|
36
36
|
* Sets the save function for the library.
|
|
@@ -141,12 +141,13 @@ class SyncManager {
|
|
|
141
141
|
* Initializes the WebSocket connection to the server.
|
|
142
142
|
*/
|
|
143
143
|
initServerConnection() {
|
|
144
|
-
const
|
|
144
|
+
const WebSocketLib = this.libraryLoader.getWebSocketLib();
|
|
145
|
+
const ws = new WebSocketLib(this.serverUrl);
|
|
145
146
|
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
146
147
|
const syncManager = this;
|
|
147
|
-
ws.addEventListener('error', (
|
|
148
|
-
//
|
|
149
|
-
syncManager.log('warning', `Error in websocket
|
|
148
|
+
ws.addEventListener('error', () => {
|
|
149
|
+
// no error information seems to be available...
|
|
150
|
+
syncManager.log('warning', `Error in websocket.`);
|
|
150
151
|
});
|
|
151
152
|
ws.addEventListener('message', function message(message) {
|
|
152
153
|
try {
|
|
@@ -326,7 +327,7 @@ class SyncManager {
|
|
|
326
327
|
};
|
|
327
328
|
let returnQr = null;
|
|
328
329
|
if (returnAs.qr) {
|
|
329
|
-
const qrGeneratorLib =
|
|
330
|
+
const qrGeneratorLib = this.libraryLoader.getQrGeneratorLib();
|
|
330
331
|
returnQr = await qrGeneratorLib.toDataURL(JSON.stringify(returnData));
|
|
331
332
|
}
|
|
332
333
|
const returnText = returnAs.text
|
|
@@ -352,7 +353,7 @@ class SyncManager {
|
|
|
352
353
|
if (this.activeAddDeviceFlow) {
|
|
353
354
|
throw new SyncAddDeviceFlowConflictError();
|
|
354
355
|
}
|
|
355
|
-
const { addDevicePassword, initiatorDeviceId, timestamp, pass1Result } = await decodeInitiatorData(initiatorData, initiatorDataType, await this.libraryLoader.getJsQrLib(), this.libraryLoader.
|
|
356
|
+
const { addDevicePassword, initiatorDeviceId, timestamp, pass1Result } = await decodeInitiatorData(initiatorData, initiatorDataType, await this.libraryLoader.getJsQrLib(), this.libraryLoader.getQrGeneratorLib());
|
|
356
357
|
if (!addDevicePassword ||
|
|
357
358
|
!initiatorDeviceId ||
|
|
358
359
|
!timestamp ||
|
|
@@ -1,45 +1,45 @@
|
|
|
1
1
|
import type { ZxcvbnResult } from '@zxcvbn-ts/core';
|
|
2
|
-
import type
|
|
3
|
-
import type {
|
|
2
|
+
import type { PlatformProviders } from '../interfaces/PlatformProviders.mjs';
|
|
3
|
+
import type { Password } from '../interfaces/CryptoLib.mjs';
|
|
4
4
|
import type { DeviceType } from '../interfaces/SyncTypes.mjs';
|
|
5
5
|
import TwoFaLib from '../TwoFaLib.mjs';
|
|
6
6
|
import LibraryLoader from '../subclasses/LibraryLoader.mjs';
|
|
7
7
|
import type { LockedRepresentationString } from '../interfaces/Vault.mjs';
|
|
8
|
-
import type {
|
|
8
|
+
import type { PasswordExtraDict } from '../interfaces/PasswordExtraDict.js';
|
|
9
9
|
import { SaveFunction } from '../interfaces/SaveFunction.mjs';
|
|
10
10
|
/**
|
|
11
|
-
* Evaluates the strength of a
|
|
11
|
+
* Evaluates the strength of a password.
|
|
12
12
|
* @param libraryLoader - An instance of LibraryLoader.
|
|
13
|
-
* @param
|
|
14
|
-
* @param
|
|
15
|
-
* @returns Promise resolving to the
|
|
13
|
+
* @param password - The password to evaluate.
|
|
14
|
+
* @param passwordExtraDict - Additional words to be used for password strength evaluation.
|
|
15
|
+
* @returns Promise resolving to the password strength result.
|
|
16
16
|
*/
|
|
17
|
-
export declare const
|
|
17
|
+
export declare const getPasswordStrength: (libraryLoader: LibraryLoader, password: Password, passwordExtraDict: PasswordExtraDict) => Promise<ZxcvbnResult>;
|
|
18
18
|
/**
|
|
19
|
-
* Validates the strength of a
|
|
19
|
+
* Validates the strength of a password.
|
|
20
20
|
* @param libraryLoader - An instance of LibraryLoader.
|
|
21
|
-
* @param
|
|
22
|
-
* @param
|
|
23
|
-
* @throws {InitializationError} If the
|
|
21
|
+
* @param password - The password to validate.
|
|
22
|
+
* @param passwordExtraDict - Additional words to be used for password strength evaluation.
|
|
23
|
+
* @throws {InitializationError} If the password is too weak.
|
|
24
24
|
*/
|
|
25
|
-
export declare const
|
|
25
|
+
export declare const validatePasswordStrength: (libraryLoader: LibraryLoader, password: Password, passwordExtraDict: PasswordExtraDict) => Promise<void>;
|
|
26
26
|
/**
|
|
27
27
|
* Returns utility functions useful in creating a new twoFaLib vault
|
|
28
|
-
* @param
|
|
28
|
+
* @param platformProviders - The platform-specific providers containing CryptoLib and other providers.
|
|
29
29
|
* @param deviceType - A unique identifier for this device type (e.g. 2fa-cli).
|
|
30
|
-
* @param
|
|
30
|
+
* @param passwordExtraDict - Additional words to be used for password strength evaluation.
|
|
31
31
|
* @param saveFunction - The function to save the data.
|
|
32
32
|
* @param serverUrl - The server URL for syncing.
|
|
33
|
-
* @returns An object with methods to evaluate
|
|
33
|
+
* @returns An object with methods to evaluate password strength and create a new TwoFaLib vault.
|
|
34
34
|
*/
|
|
35
|
-
export declare const getTwoFaLibVaultCreationUtils: (
|
|
36
|
-
|
|
37
|
-
createNewTwoFaLibVault: (
|
|
35
|
+
export declare const getTwoFaLibVaultCreationUtils: (platformProviders: PlatformProviders, deviceType: DeviceType, passwordExtraDict: PasswordExtraDict, saveFunction?: SaveFunction, serverUrl?: string) => {
|
|
36
|
+
getPasswordStrength: (password: Password, passwordExtraDict: PasswordExtraDict) => Promise<ZxcvbnResult>;
|
|
37
|
+
createNewTwoFaLibVault: (password: Password) => Promise<{
|
|
38
38
|
twoFaLib: TwoFaLib;
|
|
39
39
|
publicKey: import("../interfaces/CryptoLib.mjs").PublicKey;
|
|
40
40
|
encryptedPrivateKey: import("../interfaces/CryptoLib.mjs").EncryptedPrivateKey;
|
|
41
41
|
encryptedSymmetricKey: import("../interfaces/CryptoLib.mjs").EncryptedSymmetricKey;
|
|
42
42
|
salt: import("../interfaces/CryptoLib.mjs").Salt;
|
|
43
43
|
}>;
|
|
44
|
-
loadTwoFaLibFromLockedRepesentation: (lockedRepresentationString: LockedRepresentationString,
|
|
44
|
+
loadTwoFaLibFromLockedRepesentation: (lockedRepresentationString: LockedRepresentationString, password: Password) => Promise<TwoFaLib>;
|
|
45
45
|
};
|
|
@@ -3,15 +3,15 @@ import TwoFaLib from '../TwoFaLib.mjs';
|
|
|
3
3
|
import { InitializationError, TwoFALibError } from '../TwoFALibError.mjs';
|
|
4
4
|
import LibraryLoader from '../subclasses/LibraryLoader.mjs';
|
|
5
5
|
/**
|
|
6
|
-
* Evaluates the strength of a
|
|
6
|
+
* Evaluates the strength of a password.
|
|
7
7
|
* @param libraryLoader - An instance of LibraryLoader.
|
|
8
|
-
* @param
|
|
9
|
-
* @param
|
|
10
|
-
* @returns Promise resolving to the
|
|
8
|
+
* @param password - The password to evaluate.
|
|
9
|
+
* @param passwordExtraDict - Additional words to be used for password strength evaluation.
|
|
10
|
+
* @returns Promise resolving to the password strength result.
|
|
11
11
|
*/
|
|
12
|
-
export const
|
|
12
|
+
export const getPasswordStrength = async (libraryLoader, password, passwordExtraDict) => {
|
|
13
13
|
const zxcvbn = await libraryLoader.getZxcvbn();
|
|
14
|
-
return zxcvbn(
|
|
14
|
+
return zxcvbn(password, [
|
|
15
15
|
'twofactor',
|
|
16
16
|
'authentication',
|
|
17
17
|
'token',
|
|
@@ -34,20 +34,20 @@ export const getPassphraseStrength = async (libraryLoader, passphrase, passphras
|
|
|
34
34
|
'key',
|
|
35
35
|
'trust',
|
|
36
36
|
'secure',
|
|
37
|
-
...
|
|
37
|
+
...passwordExtraDict,
|
|
38
38
|
]);
|
|
39
39
|
};
|
|
40
40
|
/**
|
|
41
|
-
* Validates the strength of a
|
|
41
|
+
* Validates the strength of a password.
|
|
42
42
|
* @param libraryLoader - An instance of LibraryLoader.
|
|
43
|
-
* @param
|
|
44
|
-
* @param
|
|
45
|
-
* @throws {InitializationError} If the
|
|
43
|
+
* @param password - The password to validate.
|
|
44
|
+
* @param passwordExtraDict - Additional words to be used for password strength evaluation.
|
|
45
|
+
* @throws {InitializationError} If the password is too weak.
|
|
46
46
|
*/
|
|
47
|
-
export const
|
|
48
|
-
const
|
|
49
|
-
if (
|
|
50
|
-
throw new TwoFALibError('
|
|
47
|
+
export const validatePasswordStrength = async (libraryLoader, password, passwordExtraDict) => {
|
|
48
|
+
const passwordStrength = await getPasswordStrength(libraryLoader, password, passwordExtraDict);
|
|
49
|
+
if (passwordStrength.score < 3) {
|
|
50
|
+
throw new TwoFALibError('Password is too weak');
|
|
51
51
|
}
|
|
52
52
|
};
|
|
53
53
|
/**
|
|
@@ -55,17 +55,18 @@ export const validatePassphraseStrength = async (libraryLoader, passphrase, pass
|
|
|
55
55
|
* @param libraryLoader - An instance of LibraryLoader.
|
|
56
56
|
* @param deviceType - A unique identifier for the device type e.g. 2fa-cli.
|
|
57
57
|
* @param serverUrl - The server URL for syncing.
|
|
58
|
-
* @param
|
|
58
|
+
* @param passwordExtraDict - Additional words to be used for password strength evaluation.
|
|
59
59
|
* @param saveFunction - The function to save the data.
|
|
60
|
-
* @param
|
|
60
|
+
* @param password - The password to be used to encrypt the private key.
|
|
61
61
|
* @returns Promise resolving to an object containing the newly created TwoFaLib instance and related data.
|
|
62
62
|
*/
|
|
63
|
-
const createNewTwoFaLibVault = async (libraryLoader, deviceType, serverUrl,
|
|
63
|
+
const createNewTwoFaLibVault = async (libraryLoader, deviceType, serverUrl, passwordExtraDict, saveFunction, password) => {
|
|
64
64
|
const cryptoLib = libraryLoader.getCryptoLib();
|
|
65
|
-
const
|
|
66
|
-
|
|
65
|
+
const platformProviders = libraryLoader.getPlatformProviders();
|
|
66
|
+
const { publicKey, privateKey, symmetricKey, encryptedPrivateKey, encryptedSymmetricKey, salt, } = await cryptoLib.createKeys(password);
|
|
67
|
+
await validatePasswordStrength(libraryLoader, password, passwordExtraDict);
|
|
67
68
|
const deviceId = genUuidV4();
|
|
68
|
-
const twoFaLib = new TwoFaLib(deviceType,
|
|
69
|
+
const twoFaLib = new TwoFaLib(deviceType, platformProviders, passwordExtraDict, privateKey, symmetricKey, encryptedPrivateKey, encryptedSymmetricKey, salt, publicKey, {
|
|
69
70
|
deviceId,
|
|
70
71
|
}, [], saveFunction, {
|
|
71
72
|
serverUrl,
|
|
@@ -84,15 +85,16 @@ const createNewTwoFaLibVault = async (libraryLoader, deviceType, serverUrl, pass
|
|
|
84
85
|
* Loads the library state from a previously locked representation.
|
|
85
86
|
* @param libraryLoader - An instance of LibraryLoader.
|
|
86
87
|
* @param deviceType - A unique identifier for this device type (e.g. 2fa-cli).
|
|
87
|
-
* @param
|
|
88
|
+
* @param passwordExtraDict - Additional words to be used for password strength evaluation.
|
|
88
89
|
* @param saveFunction - The function to save the data.
|
|
89
90
|
* @param lockedRepresentationString - The string representation of the locked library state representation.
|
|
90
|
-
* @param
|
|
91
|
+
* @param password - The password for decrypting the keys.
|
|
91
92
|
* @returns A promise that resolves when loading is complete.
|
|
92
93
|
* @throws {InitializationError} If loading fails due to invalid or corrupted data.
|
|
93
94
|
*/
|
|
94
|
-
const loadTwoFaLibFromLockedRepesentation = async (libraryLoader, deviceType,
|
|
95
|
+
const loadTwoFaLibFromLockedRepesentation = async (libraryLoader, deviceType, passwordExtraDict, saveFunction, lockedRepresentationString, password) => {
|
|
95
96
|
const cryptoLib = libraryLoader.getCryptoLib();
|
|
97
|
+
const platformProviders = libraryLoader.getPlatformProviders();
|
|
96
98
|
const lockedRepresentation = JSON.parse(lockedRepresentationString);
|
|
97
99
|
if (!lockedRepresentation ||
|
|
98
100
|
!lockedRepresentation.encryptedPrivateKey ||
|
|
@@ -101,7 +103,7 @@ const loadTwoFaLibFromLockedRepesentation = async (libraryLoader, deviceType, pa
|
|
|
101
103
|
!lockedRepresentation.encryptedVaultState) {
|
|
102
104
|
throw new InitializationError('lockedRepresentation is incomplete or corrupted');
|
|
103
105
|
}
|
|
104
|
-
const { privateKey, symmetricKey, publicKey } = await cryptoLib.decryptKeys(lockedRepresentation.encryptedPrivateKey, lockedRepresentation.encryptedSymmetricKey, lockedRepresentation.salt,
|
|
106
|
+
const { privateKey, symmetricKey, publicKey } = await cryptoLib.decryptKeys(lockedRepresentation.encryptedPrivateKey, lockedRepresentation.encryptedSymmetricKey, lockedRepresentation.salt, password);
|
|
105
107
|
const vaultState = JSON.parse(await cryptoLib.decryptSymmetric(symmetricKey, lockedRepresentation.encryptedVaultState));
|
|
106
108
|
if (!vaultState ||
|
|
107
109
|
!vaultState.deviceId ||
|
|
@@ -109,25 +111,25 @@ const loadTwoFaLibFromLockedRepesentation = async (libraryLoader, deviceType, pa
|
|
|
109
111
|
!vaultState.sync?.devices) {
|
|
110
112
|
throw new InitializationError('encryptedVaultState is incomplete or corrupted');
|
|
111
113
|
}
|
|
112
|
-
return new TwoFaLib(deviceType,
|
|
114
|
+
return new TwoFaLib(deviceType, platformProviders, passwordExtraDict, privateKey, symmetricKey, lockedRepresentation.encryptedPrivateKey, lockedRepresentation.encryptedSymmetricKey, lockedRepresentation.salt, publicKey, {
|
|
113
115
|
deviceId: vaultState.deviceId,
|
|
114
116
|
deviceFriendlyName: vaultState.deviceFriendlyName,
|
|
115
117
|
}, vaultState.vault, saveFunction, vaultState.sync);
|
|
116
118
|
};
|
|
117
119
|
/**
|
|
118
120
|
* Returns utility functions useful in creating a new twoFaLib vault
|
|
119
|
-
* @param
|
|
121
|
+
* @param platformProviders - The platform-specific providers containing CryptoLib and other providers.
|
|
120
122
|
* @param deviceType - A unique identifier for this device type (e.g. 2fa-cli).
|
|
121
|
-
* @param
|
|
123
|
+
* @param passwordExtraDict - Additional words to be used for password strength evaluation.
|
|
122
124
|
* @param saveFunction - The function to save the data.
|
|
123
125
|
* @param serverUrl - The server URL for syncing.
|
|
124
|
-
* @returns An object with methods to evaluate
|
|
126
|
+
* @returns An object with methods to evaluate password strength and create a new TwoFaLib vault.
|
|
125
127
|
*/
|
|
126
|
-
export const getTwoFaLibVaultCreationUtils = (
|
|
127
|
-
const libraryLoader = new LibraryLoader(
|
|
128
|
+
export const getTwoFaLibVaultCreationUtils = (platformProviders, deviceType, passwordExtraDict, saveFunction, serverUrl) => {
|
|
129
|
+
const libraryLoader = new LibraryLoader(platformProviders);
|
|
128
130
|
return {
|
|
129
|
-
|
|
130
|
-
createNewTwoFaLibVault: createNewTwoFaLibVault.bind(null, libraryLoader, deviceType, serverUrl,
|
|
131
|
-
loadTwoFaLibFromLockedRepesentation: loadTwoFaLibFromLockedRepesentation.bind(null, libraryLoader, deviceType,
|
|
131
|
+
getPasswordStrength: getPasswordStrength.bind(null, libraryLoader),
|
|
132
|
+
createNewTwoFaLibVault: createNewTwoFaLibVault.bind(null, libraryLoader, deviceType, serverUrl, passwordExtraDict, saveFunction),
|
|
133
|
+
loadTwoFaLibFromLockedRepesentation: loadTwoFaLibFromLockedRepesentation.bind(null, libraryLoader, deviceType, passwordExtraDict, saveFunction),
|
|
132
134
|
};
|
|
133
135
|
};
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { NewEntry } from '../interfaces/Entry.mjs';
|
|
2
2
|
import type Entry from '../interfaces/Entry.mjs';
|
|
3
3
|
import type { EntryId } from '../interfaces/Entry.mjs';
|
|
4
|
+
import type { QrCodeLib } from '../interfaces/QrCodeLib.mjs';
|
|
5
|
+
import type { OpenPgpLib } from '../interfaces/OpenPgpLib.mjs';
|
|
4
6
|
/**
|
|
5
7
|
* Parses an OTP URI and extracts the relevant information to create a new entry.
|
|
6
8
|
* @param UrlParser - The URL parsing library.
|
|
@@ -15,7 +17,7 @@ export declare const parseOtpUri: (UrlParser: typeof import("whatwg-url"), otpUr
|
|
|
15
17
|
* @param entries - An array of OTP entries.
|
|
16
18
|
* @returns A promise that resolves to the HTML string.
|
|
17
19
|
*/
|
|
18
|
-
export declare const generateHtmlExport: (qrGeneratorLib:
|
|
20
|
+
export declare const generateHtmlExport: (qrGeneratorLib: QrCodeLib, entries: Entry[]) => Promise<string>;
|
|
19
21
|
/**
|
|
20
22
|
* Generates a text export of OTP URIs for the provided entries.
|
|
21
23
|
* @param entries - An array of OTP entries.
|
|
@@ -42,7 +44,7 @@ export declare const processImportLines: (lines: string[], importFromUri: (uri:
|
|
|
42
44
|
* @param password - The password to use for encryption.
|
|
43
45
|
* @returns A promise that resolves to the encrypted data.
|
|
44
46
|
*/
|
|
45
|
-
export declare const encryptExport: (openPgpLib:
|
|
47
|
+
export declare const encryptExport: (openPgpLib: OpenPgpLib, data: string, password: string) => Promise<string>;
|
|
46
48
|
/**
|
|
47
49
|
* Decrypts the given data using OpenPGP.
|
|
48
50
|
* @param openPgpLib - The OpenPGP library.
|
|
@@ -50,4 +52,4 @@ export declare const encryptExport: (openPgpLib: typeof import("openpgp"), data:
|
|
|
50
52
|
* @param password - The password to use for decryption.
|
|
51
53
|
* @returns A promise that resolves to the decrypted data.
|
|
52
54
|
*/
|
|
53
|
-
export declare const decryptExport: (openPgpLib:
|
|
55
|
+
export declare const decryptExport: (openPgpLib: OpenPgpLib, data: string, password: string) => Promise<string>;
|
|
@@ -162,13 +162,7 @@ export const processImportLines = async (lines, importFromUri) => {
|
|
|
162
162
|
* @returns A promise that resolves to the encrypted data.
|
|
163
163
|
*/
|
|
164
164
|
export const encryptExport = async (openPgpLib, data, password) => {
|
|
165
|
-
|
|
166
|
-
const encrypted = await openPgpLib.encrypt({
|
|
167
|
-
message: await openPgpLib.createMessage({ text: data }),
|
|
168
|
-
passwords: [password],
|
|
169
|
-
format: 'armored',
|
|
170
|
-
});
|
|
171
|
-
return encrypted;
|
|
165
|
+
return openPgpLib.encrypt(data, password);
|
|
172
166
|
};
|
|
173
167
|
/**
|
|
174
168
|
* Decrypts the given data using OpenPGP.
|
|
@@ -178,9 +172,5 @@ export const encryptExport = async (openPgpLib, data, password) => {
|
|
|
178
172
|
* @returns A promise that resolves to the decrypted data.
|
|
179
173
|
*/
|
|
180
174
|
export const decryptExport = async (openPgpLib, data, password) => {
|
|
181
|
-
|
|
182
|
-
message: await openPgpLib.readMessage({ armoredMessage: data }),
|
|
183
|
-
passwords: [password],
|
|
184
|
-
});
|
|
185
|
-
return decrypted.data;
|
|
175
|
+
return openPgpLib.decrypt(data, password);
|
|
186
176
|
};
|