favalib 0.0.10 → 0.0.12
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/Command/commandConstructors.d.mts +2 -2
- package/build/Command/commandConstructors.mjs +2 -2
- package/build/Command/commands/ChangeDeviceInfoCommand.d.mts +6 -6
- package/build/Command/commands/ChangeDeviceInfoCommand.mjs +3 -3
- package/build/TwoFaLib.d.mts +3 -3
- package/build/TwoFaLib.mjs +16 -12
- package/build/interfaces/CommandTypes.d.mts +4 -4
- package/build/interfaces/OpenPgpLib.d.mts +20 -0
- package/build/interfaces/OpenPgpLib.mjs +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 +2 -1
- 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.mjs → platformProviders/node/cryptoLib.mjs} +1 -1
- 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.mjs +3 -3
- package/build/subclasses/LibraryLoader.d.mts +26 -12
- package/build/subclasses/LibraryLoader.mjs +26 -34
- package/build/subclasses/SyncManager.mjs +7 -6
- package/build/utils/creationUtils.d.mts +3 -3
- package/build/utils/creationUtils.mjs +7 -5
- 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/{CryptoProviders/browser/index.d.mts → platformProviders/browser/cryptoLib.d.mts} +0 -0
- /package/build/{CryptoProviders/browser/index.mjs → platformProviders/browser/cryptoLib.mjs} +0 -0
- /package/build/{CryptoProviders/node/index.d.mts → platformProviders/node/cryptoLib.d.mts} +0 -0
|
@@ -2,12 +2,12 @@ import AddEntryCommand from './commands/AddEntryCommand.mjs';
|
|
|
2
2
|
import AddSyncDeviceCommand from './commands/AddSyncDeviceCommand.mjs';
|
|
3
3
|
import DeleteEntryCommand from './commands/DeleteEntryCommand.mjs';
|
|
4
4
|
import UpdateEntryCommand from './commands/UpdateEntryCommand.mjs';
|
|
5
|
-
import
|
|
5
|
+
import ChangeDeviceInfoCommand from './commands/ChangeDeviceInfoCommand.mjs';
|
|
6
6
|
declare const commandConstructors: {
|
|
7
7
|
AddEntry: typeof AddEntryCommand;
|
|
8
8
|
DeleteEntry: typeof DeleteEntryCommand;
|
|
9
9
|
UpdateEntry: typeof UpdateEntryCommand;
|
|
10
10
|
AddSyncDevice: typeof AddSyncDeviceCommand;
|
|
11
|
-
|
|
11
|
+
ChangeDeviceInfo: typeof ChangeDeviceInfoCommand;
|
|
12
12
|
};
|
|
13
13
|
export default commandConstructors;
|
|
@@ -2,12 +2,12 @@ import AddEntryCommand from './commands/AddEntryCommand.mjs';
|
|
|
2
2
|
import AddSyncDeviceCommand from './commands/AddSyncDeviceCommand.mjs';
|
|
3
3
|
import DeleteEntryCommand from './commands/DeleteEntryCommand.mjs';
|
|
4
4
|
import UpdateEntryCommand from './commands/UpdateEntryCommand.mjs';
|
|
5
|
-
import
|
|
5
|
+
import ChangeDeviceInfoCommand from './commands/ChangeDeviceInfoCommand.mjs';
|
|
6
6
|
const commandConstructors = {
|
|
7
7
|
AddEntry: AddEntryCommand,
|
|
8
8
|
DeleteEntry: DeleteEntryCommand,
|
|
9
9
|
UpdateEntry: UpdateEntryCommand,
|
|
10
10
|
AddSyncDevice: AddSyncDeviceCommand,
|
|
11
|
-
|
|
11
|
+
ChangeDeviceInfo: ChangeDeviceInfoCommand,
|
|
12
12
|
};
|
|
13
13
|
export default commandConstructors;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type TwoFaLibMediator from '../../TwoFaLibMediator.mjs';
|
|
2
2
|
import Command from '../BaseCommand.mjs';
|
|
3
3
|
import type { DeviceFriendlyName, DeviceId, DeviceType } from '../../interfaces/SyncTypes.mjs';
|
|
4
|
-
export interface
|
|
4
|
+
export interface ChangeDeviceInfoData {
|
|
5
5
|
deviceId: DeviceId;
|
|
6
6
|
newDeviceInfo: {
|
|
7
7
|
deviceFriendlyName?: DeviceFriendlyName;
|
|
@@ -11,17 +11,17 @@ export interface ChangeSyncDeviceInfoData {
|
|
|
11
11
|
/**
|
|
12
12
|
* Represents a command that when executed changes the device info of a sync device
|
|
13
13
|
*/
|
|
14
|
-
declare class ChangeDeviceInfoCommand extends Command<
|
|
14
|
+
declare class ChangeDeviceInfoCommand extends Command<ChangeDeviceInfoData> {
|
|
15
15
|
/**
|
|
16
|
-
* Creates a new
|
|
16
|
+
* Creates a new ChangeDeviceMetaCommand instance.
|
|
17
17
|
* @inheritdoc
|
|
18
18
|
* @param data - The id of the device to change and the new meta info
|
|
19
19
|
*/
|
|
20
|
-
constructor(data:
|
|
20
|
+
constructor(data: ChangeDeviceInfoData, id?: string, timestamp?: number, version?: string, fromRemote?: boolean);
|
|
21
21
|
/**
|
|
22
|
-
* Executes the command to change the
|
|
22
|
+
* Executes the command to change the device info
|
|
23
23
|
* @inheritdoc
|
|
24
|
-
* @throws {InvalidCommandError} If the referenced
|
|
24
|
+
* @throws {InvalidCommandError} If the referenced device cannot be found
|
|
25
25
|
*/
|
|
26
26
|
execute(mediator: TwoFaLibMediator): Promise<void>;
|
|
27
27
|
/**
|
|
@@ -5,7 +5,7 @@ import Command from '../BaseCommand.mjs';
|
|
|
5
5
|
*/
|
|
6
6
|
class ChangeDeviceInfoCommand extends Command {
|
|
7
7
|
/**
|
|
8
|
-
* Creates a new
|
|
8
|
+
* Creates a new ChangeDeviceMetaCommand instance.
|
|
9
9
|
* @inheritdoc
|
|
10
10
|
* @param data - The id of the device to change and the new meta info
|
|
11
11
|
*/
|
|
@@ -13,9 +13,9 @@ class ChangeDeviceInfoCommand extends Command {
|
|
|
13
13
|
super('ChangeDeviceInfo', data, id, timestamp, version, fromRemote);
|
|
14
14
|
}
|
|
15
15
|
/**
|
|
16
|
-
* Executes the command to change the
|
|
16
|
+
* Executes the command to change the device info
|
|
17
17
|
* @inheritdoc
|
|
18
|
-
* @throws {InvalidCommandError} If the referenced
|
|
18
|
+
* @throws {InvalidCommandError} If the referenced device cannot be found
|
|
19
19
|
*/
|
|
20
20
|
async execute(mediator) {
|
|
21
21
|
if (!this.validate(mediator)) {
|
package/build/TwoFaLib.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { TypedEventTarget } from 'typescript-event-target';
|
|
2
|
-
import type
|
|
2
|
+
import type { PlatformProviders } from './interfaces/PlatformProviders.mjs';
|
|
3
3
|
import type { EncryptedPrivateKey, EncryptedSymmetricKey, PrivateKey, PublicKey, Salt, SymmetricKey } from './interfaces/CryptoLib.mjs';
|
|
4
4
|
import type { DeviceFriendlyName, DeviceType } from './interfaces/SyncTypes.mjs';
|
|
5
5
|
import type { TwoFaLibEventMapEvents } from './interfaces/Events.mjs';
|
|
@@ -34,7 +34,7 @@ declare class TwoFaLib extends TypedEventTarget<TwoFaLibEventMapEvents> {
|
|
|
34
34
|
/**
|
|
35
35
|
* Constructs a new instance of TwoFaLib. If a serverUrl is provided, the library will use it for its sync operations.
|
|
36
36
|
* @param deviceType - The identifier for this device type (e.g. 2fa-cli).
|
|
37
|
-
* @param
|
|
37
|
+
* @param platformProviders - The platform-specific providers containing CryptoLib and other providers.
|
|
38
38
|
* @param passphraseExtraDict - Additional words to be used for passphrase strength evaluation.
|
|
39
39
|
* @param privateKey - The private key used for cryptographic operations.
|
|
40
40
|
* @param symmetricKey - The symmetric key used for cryptographic operations.
|
|
@@ -50,7 +50,7 @@ declare class TwoFaLib extends TypedEventTarget<TwoFaLibEventMapEvents> {
|
|
|
50
50
|
* @throws {InitializationError} If some parameter has an invalid value
|
|
51
51
|
* @throws {AuthenticationError} If the provided passphrase is incorrect.
|
|
52
52
|
*/
|
|
53
|
-
constructor(deviceType: DeviceType,
|
|
53
|
+
constructor(deviceType: DeviceType, platformProviders: PlatformProviders, passphraseExtraDict: PassphraseExtraDict, privateKey: PrivateKey, symmetricKey: SymmetricKey, encryptedPrivateKey: EncryptedPrivateKey, encryptedSymmetricKey: EncryptedSymmetricKey, salt: Salt, publicKey: PublicKey, favaMeta: FavaMeta, vault?: Vault, saveFunction?: SaveFunction, syncState?: VaultSyncState);
|
|
54
54
|
/**
|
|
55
55
|
* @returns The persistent storage manager instance which can be used to store data.
|
|
56
56
|
*/
|
package/build/TwoFaLib.mjs
CHANGED
|
@@ -30,7 +30,7 @@ class TwoFaLib extends TypedEventTarget {
|
|
|
30
30
|
/**
|
|
31
31
|
* Constructs a new instance of TwoFaLib. If a serverUrl is provided, the library will use it for its sync operations.
|
|
32
32
|
* @param deviceType - The identifier for this device type (e.g. 2fa-cli).
|
|
33
|
-
* @param
|
|
33
|
+
* @param platformProviders - The platform-specific providers containing CryptoLib and other providers.
|
|
34
34
|
* @param passphraseExtraDict - Additional words to be used for passphrase strength evaluation.
|
|
35
35
|
* @param privateKey - The private key used for cryptographic operations.
|
|
36
36
|
* @param symmetricKey - The symmetric key used for cryptographic operations.
|
|
@@ -46,7 +46,7 @@ class TwoFaLib extends TypedEventTarget {
|
|
|
46
46
|
* @throws {InitializationError} If some parameter has an invalid value
|
|
47
47
|
* @throws {AuthenticationError} If the provided passphrase is incorrect.
|
|
48
48
|
*/
|
|
49
|
-
constructor(deviceType,
|
|
49
|
+
constructor(deviceType, platformProviders, passphraseExtraDict, privateKey, symmetricKey, encryptedPrivateKey, encryptedSymmetricKey, salt, publicKey, favaMeta, vault, saveFunction, syncState) {
|
|
50
50
|
super();
|
|
51
51
|
if (!deviceType) {
|
|
52
52
|
throw new InitializationError('Device type is required');
|
|
@@ -70,7 +70,7 @@ class TwoFaLib extends TypedEventTarget {
|
|
|
70
70
|
this.privateKey = privateKey;
|
|
71
71
|
this.mediator = new TwoFaLibMediator();
|
|
72
72
|
this.mediator.registerComponents([
|
|
73
|
-
['libraryLoader', new LibraryLoader(
|
|
73
|
+
['libraryLoader', new LibraryLoader(platformProviders)],
|
|
74
74
|
[
|
|
75
75
|
'persistentStorageManager',
|
|
76
76
|
new PersistentStorageManager(this.mediator, passphraseExtraDict, favaMeta, privateKey, symmetricKey, encryptedPrivateKey, encryptedSymmetricKey, salt, saveFunction),
|
|
@@ -153,9 +153,10 @@ class TwoFaLib extends TypedEventTarget {
|
|
|
153
153
|
* @param force - Force setting the sync server url, even if no connection can be made
|
|
154
154
|
*/
|
|
155
155
|
async setSyncServerUrl(serverUrl, force = false) {
|
|
156
|
-
|
|
156
|
+
const oldSyncManager = this.sync;
|
|
157
|
+
if (oldSyncManager) {
|
|
157
158
|
// close connection so no data is send to the old syncServer
|
|
158
|
-
|
|
159
|
+
oldSyncManager.closeServerConnection();
|
|
159
160
|
}
|
|
160
161
|
const newSyncState = {
|
|
161
162
|
serverUrl,
|
|
@@ -163,6 +164,9 @@ class TwoFaLib extends TypedEventTarget {
|
|
|
163
164
|
commandSendQueue: [],
|
|
164
165
|
};
|
|
165
166
|
const newSyncManager = new SyncManager(this.mediator, this.publicKey, this.privateKey, this.favaMeta, newSyncState, this.deviceType);
|
|
167
|
+
// Temporarily register the new sync manager so its events can be heard
|
|
168
|
+
this.mediator.unRegisterComponent('syncManager');
|
|
169
|
+
this.mediator.registerComponent('syncManager', newSyncManager);
|
|
166
170
|
const success = await new Promise((resolve) => {
|
|
167
171
|
this.addEventListener(TwoFaLibEvent.ConnectionToSyncServerStatusChanged, (event) => {
|
|
168
172
|
if (event.detail.newStatus === ConnectionStatus.CONNECTED) {
|
|
@@ -178,18 +182,18 @@ class TwoFaLib extends TypedEventTarget {
|
|
|
178
182
|
this.log('warning', `Failed to connect to server at ${serverUrl}, force setting`);
|
|
179
183
|
}
|
|
180
184
|
else {
|
|
181
|
-
|
|
185
|
+
// Close the new sync manager and restore the old one
|
|
186
|
+
newSyncManager.closeServerConnection();
|
|
187
|
+
this.mediator.unRegisterComponent('syncManager');
|
|
188
|
+
if (oldSyncManager) {
|
|
182
189
|
// re-establish old connection
|
|
183
|
-
this.
|
|
190
|
+
this.mediator.registerComponent('syncManager', oldSyncManager);
|
|
191
|
+
oldSyncManager.initServerConnection();
|
|
184
192
|
}
|
|
185
|
-
newSyncManager.closeServerConnection();
|
|
186
193
|
throw new SyncError(`Failed to connect to server at ${serverUrl}, not setting`);
|
|
187
194
|
}
|
|
188
195
|
}
|
|
189
|
-
// connection succeeded (or force=true)
|
|
190
|
-
// switch to the new syncManager
|
|
191
|
-
this.mediator.unRegisterComponent('syncManager');
|
|
192
|
-
this.mediator.registerComponent('syncManager', newSyncManager);
|
|
196
|
+
// connection succeeded (or force=true) - new sync manager is already registered
|
|
193
197
|
// save
|
|
194
198
|
await this.persistentStorageManager.save();
|
|
195
199
|
}
|
|
@@ -2,7 +2,7 @@ import type { AddEntryData } from '../Command/commands/AddEntryCommand.mjs';
|
|
|
2
2
|
import type { DeleteEntryData } from '../Command/commands/DeleteEntryCommand.mjs';
|
|
3
3
|
import type { UpdateEntryData } from '../Command/commands/UpdateEntryCommand.mjs';
|
|
4
4
|
import type { AddSyncDeviceData } from '../Command/commands/AddSyncDeviceCommand.mjs';
|
|
5
|
-
import type {
|
|
5
|
+
import type { ChangeDeviceInfoData } from '../Command/commands/ChangeDeviceInfoCommand.mjs';
|
|
6
6
|
export type SyncCommand = ({
|
|
7
7
|
type: 'AddEntry';
|
|
8
8
|
data: AddEntryData;
|
|
@@ -16,9 +16,9 @@ export type SyncCommand = ({
|
|
|
16
16
|
type: 'AddSyncDevice';
|
|
17
17
|
data: AddSyncDeviceData;
|
|
18
18
|
} | {
|
|
19
|
-
type: '
|
|
20
|
-
data:
|
|
19
|
+
type: 'ChangeDeviceInfo';
|
|
20
|
+
data: ChangeDeviceInfoData;
|
|
21
21
|
}) & {
|
|
22
22
|
id: string;
|
|
23
23
|
};
|
|
24
|
-
export type CommandData = AddEntryData | DeleteEntryData | UpdateEntryData | AddSyncDeviceData |
|
|
24
|
+
export type CommandData = AddEntryData | DeleteEntryData | UpdateEntryData | AddSyncDeviceData | ChangeDeviceInfoData;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interface for OpenPGP operations
|
|
3
|
+
*/
|
|
4
|
+
export interface OpenPgpLib {
|
|
5
|
+
/**
|
|
6
|
+
* Encrypts the given data using OpenPGP.
|
|
7
|
+
* @param data - The data to encrypt.
|
|
8
|
+
* @param password - The password to use for encryption.
|
|
9
|
+
* @returns A promise that resolves to the encrypted data.
|
|
10
|
+
*/
|
|
11
|
+
encrypt(data: string, password: string): Promise<string>;
|
|
12
|
+
/**
|
|
13
|
+
* Decrypts the given data using OpenPGP.
|
|
14
|
+
* @param data - The data to decrypt.
|
|
15
|
+
* @param password - The password to use for decryption.
|
|
16
|
+
* @returns A promise that resolves to the decrypted data.
|
|
17
|
+
*/
|
|
18
|
+
decrypt(data: string, password: string): Promise<string>;
|
|
19
|
+
}
|
|
20
|
+
export default OpenPgpLib;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type CryptoLib from './CryptoLib.mjs';
|
|
2
|
+
import type { QrCodeLib } from './QrCodeLib.mjs';
|
|
3
|
+
import type { OpenPgpLib } from './OpenPgpLib.mjs';
|
|
4
|
+
/**
|
|
5
|
+
* Interface for platform-specific providers
|
|
6
|
+
* Includes platform-specific implementations for various libraries
|
|
7
|
+
*/
|
|
8
|
+
export interface PlatformProviders {
|
|
9
|
+
/**
|
|
10
|
+
* Cryptographic operations provider
|
|
11
|
+
*/
|
|
12
|
+
CryptoLib: new () => CryptoLib;
|
|
13
|
+
/**
|
|
14
|
+
* WebSocket library
|
|
15
|
+
*/
|
|
16
|
+
WebSocketLib: () => typeof WebSocket;
|
|
17
|
+
/**
|
|
18
|
+
* QR code generation library with platform-specific extensions
|
|
19
|
+
*/
|
|
20
|
+
QrCodeLib: new () => QrCodeLib;
|
|
21
|
+
/**
|
|
22
|
+
* OpenPGP encryption library
|
|
23
|
+
*/
|
|
24
|
+
OpenPgpLib: new () => OpenPgpLib;
|
|
25
|
+
}
|
|
26
|
+
export default PlatformProviders;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ImageData } from 'canvas';
|
|
2
|
+
/**
|
|
3
|
+
* Interface for QR code operations
|
|
4
|
+
*/
|
|
5
|
+
export interface QrCodeLib {
|
|
6
|
+
/**
|
|
7
|
+
* Generates a QR code as a data URL.
|
|
8
|
+
* @param text - The text to encode.
|
|
9
|
+
* @returns A promise that resolves to a data URL string.
|
|
10
|
+
*/
|
|
11
|
+
toDataURL(text: string): Promise<string>;
|
|
12
|
+
/**
|
|
13
|
+
* Gets ImageData from various input types for QR code processing.
|
|
14
|
+
* @param imageInput - The image input (string URL, File, or Uint8Array).
|
|
15
|
+
* @returns A promise that resolves to ImageData.
|
|
16
|
+
*/
|
|
17
|
+
getImageDataFromInput(imageInput: string | File | Uint8Array): Promise<ImageData>;
|
|
18
|
+
}
|
|
19
|
+
export default QrCodeLib;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/build/main.d.mts
CHANGED
|
@@ -6,8 +6,9 @@ import type { Encrypted, EncryptedPrivateKey, EncryptedSymmetricKey, EncryptedPu
|
|
|
6
6
|
import type { PublicSyncDevice, DeviceId, DeviceType, DeviceFriendlyName, DeviceInfo } from './interfaces/SyncTypes.mjs';
|
|
7
7
|
import type { EncryptedVaultStateString, LockedRepresentationString } from './interfaces/Vault.mjs';
|
|
8
8
|
import type { SaveFunction } from './interfaces/SaveFunction.mjs';
|
|
9
|
+
import type { PlatformProviders } from './interfaces/PlatformProviders.mjs';
|
|
9
10
|
import { TwoFALibError, InitializationError, AuthenticationError, EntryNotFoundError, TokenGenerationError } from './TwoFALibError.mjs';
|
|
10
11
|
import { TwoFaLibEvent } from './TwoFaLibEvent.mjs';
|
|
11
12
|
import { getTwoFaLibVaultCreationUtils } from './utils/creationUtils.mjs';
|
|
12
13
|
export { TwoFaLib, TwoFALibError, getTwoFaLibVaultCreationUtils, InitializationError, AuthenticationError, EntryNotFoundError, TokenGenerationError, TwoFaLibEvent, };
|
|
13
|
-
export type { Entry, EntryId, NewEntry, EntryMeta, EntryMetaWithToken, EntryType, TotpPayload, Token, EncryptedVaultStateString, LockedRepresentationString, CryptoLib, Encrypted, EncryptedPrivateKey, EncryptedPublicKey, EncryptedSymmetricKey, PrivateKey, SymmetricKey, PublicKey, Passphrase, Salt, DeviceId, DeviceType, DeviceFriendlyName, DeviceInfo, PublicSyncDevice, SaveFunction, };
|
|
14
|
+
export type { Entry, EntryId, NewEntry, EntryMeta, EntryMetaWithToken, EntryType, TotpPayload, Token, EncryptedVaultStateString, LockedRepresentationString, CryptoLib, Encrypted, EncryptedPrivateKey, EncryptedPublicKey, EncryptedSymmetricKey, PrivateKey, SymmetricKey, PublicKey, Passphrase, Salt, DeviceId, DeviceType, DeviceFriendlyName, DeviceInfo, PublicSyncDevice, SaveFunction, PlatformProviders, };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import BrowserCryptoLib from './cryptoLib.mjs';
|
|
2
|
+
import { BrowserQrCodeLib } from './qrCodeLib.mjs';
|
|
3
|
+
import { BrowserOpenPgpLib } from './openPgpLib.mjs';
|
|
4
|
+
/**
|
|
5
|
+
* Browser-specific platform providers
|
|
6
|
+
*/
|
|
7
|
+
export const browserProviders = {
|
|
8
|
+
CryptoLib: BrowserCryptoLib,
|
|
9
|
+
WebSocketLib: () => WebSocket,
|
|
10
|
+
QrCodeLib: BrowserQrCodeLib,
|
|
11
|
+
OpenPgpLib: BrowserOpenPgpLib,
|
|
12
|
+
};
|
|
13
|
+
export default browserProviders;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { OpenPgpLib } from '../../interfaces/OpenPgpLib.mjs';
|
|
2
|
+
/**
|
|
3
|
+
* Browser implementation of OpenPGP library wrapper
|
|
4
|
+
*/
|
|
5
|
+
export declare class BrowserOpenPgpLib implements OpenPgpLib {
|
|
6
|
+
private openPgpModule;
|
|
7
|
+
/**
|
|
8
|
+
* Gets the OpenPGP module, loading it if necessary
|
|
9
|
+
* @returns Promise that resolves to the OpenPGP module
|
|
10
|
+
*/
|
|
11
|
+
private getOpenPgpModule;
|
|
12
|
+
/**
|
|
13
|
+
* @inheritdoc
|
|
14
|
+
*/
|
|
15
|
+
encrypt(data: string, password: string): Promise<string>;
|
|
16
|
+
/**
|
|
17
|
+
* @inheritdoc
|
|
18
|
+
*/
|
|
19
|
+
decrypt(data: string, password: string): Promise<string>;
|
|
20
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser implementation of OpenPGP library wrapper
|
|
3
|
+
*/
|
|
4
|
+
export class BrowserOpenPgpLib {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.openPgpModule = null;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Gets the OpenPGP module, loading it if necessary
|
|
10
|
+
* @returns Promise that resolves to the OpenPGP module
|
|
11
|
+
*/
|
|
12
|
+
async getOpenPgpModule() {
|
|
13
|
+
if (!this.openPgpModule) {
|
|
14
|
+
this.openPgpModule = await import('openpgp');
|
|
15
|
+
// enable Authenticated Encryption with Associated Data
|
|
16
|
+
this.openPgpModule.config.aeadProtect = true;
|
|
17
|
+
}
|
|
18
|
+
return this.openPgpModule;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* @inheritdoc
|
|
22
|
+
*/
|
|
23
|
+
async encrypt(data, password) {
|
|
24
|
+
const openPgp = await this.getOpenPgpModule();
|
|
25
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
26
|
+
const encrypted = await openPgp.encrypt({
|
|
27
|
+
message: await openPgp.createMessage({ text: data }),
|
|
28
|
+
passwords: [password],
|
|
29
|
+
format: 'armored',
|
|
30
|
+
});
|
|
31
|
+
return encrypted;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* @inheritdoc
|
|
35
|
+
*/
|
|
36
|
+
async decrypt(data, password) {
|
|
37
|
+
const openPgp = await this.getOpenPgpModule();
|
|
38
|
+
const decrypted = await openPgp.decrypt({
|
|
39
|
+
message: await openPgp.readMessage({ armoredMessage: data }),
|
|
40
|
+
passwords: [password],
|
|
41
|
+
});
|
|
42
|
+
return decrypted.data;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ImageData } from 'canvas';
|
|
2
|
+
import type { QrCodeLib } from '../../interfaces/QrCodeLib.mjs';
|
|
3
|
+
/**
|
|
4
|
+
* Gets the ImageData from an image, for browser environments.
|
|
5
|
+
* This ImageData is then further processed to get QR codes.
|
|
6
|
+
* @param input - The image to get the ImageData from.
|
|
7
|
+
* @returns A promise that resolves to the ImageData.
|
|
8
|
+
*/
|
|
9
|
+
export declare const getImageDataFromInput: (input: string | File | Uint8Array) => Promise<ImageData>;
|
|
10
|
+
/**
|
|
11
|
+
* Browser implementation of QR code library wrapper
|
|
12
|
+
*/
|
|
13
|
+
export declare class BrowserQrCodeLib implements QrCodeLib {
|
|
14
|
+
private qrCodeModule;
|
|
15
|
+
/**
|
|
16
|
+
* Gets the QR code module, loading it if necessary
|
|
17
|
+
* @returns Promise that resolves to the QR code module
|
|
18
|
+
*/
|
|
19
|
+
private getQrCodeModule;
|
|
20
|
+
/**
|
|
21
|
+
* @inheritdoc
|
|
22
|
+
*/
|
|
23
|
+
toDataURL(text: string): Promise<string>;
|
|
24
|
+
getImageDataFromInput: (input: string | File | Uint8Array) => Promise<ImageData>;
|
|
25
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { TwoFALibError } from '../../TwoFALibError.mjs';
|
|
2
|
+
/**
|
|
3
|
+
* Gets the ImageData from an image, for browser environments.
|
|
4
|
+
* This ImageData is then further processed to get QR codes.
|
|
5
|
+
* @param input - The image to get the ImageData from.
|
|
6
|
+
* @returns A promise that resolves to the ImageData.
|
|
7
|
+
*/
|
|
8
|
+
export const getImageDataFromInput = (input) => {
|
|
9
|
+
return new Promise((resolve, reject) => {
|
|
10
|
+
if (input instanceof Uint8Array) {
|
|
11
|
+
reject(new TwoFALibError('Uint8Array input not supported in browser environment'));
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
const img = new Image();
|
|
15
|
+
img.onload = () => {
|
|
16
|
+
const canvas = document.createElement('canvas');
|
|
17
|
+
canvas.width = img.width;
|
|
18
|
+
canvas.height = img.height;
|
|
19
|
+
const ctx = canvas.getContext('2d');
|
|
20
|
+
if (!ctx) {
|
|
21
|
+
reject(new TwoFALibError('Could not create canvas context'));
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
ctx.drawImage(img, 0, 0);
|
|
25
|
+
resolve(ctx.getImageData(0, 0, img.width, img.height));
|
|
26
|
+
};
|
|
27
|
+
img.onerror = () => reject(new TwoFALibError('Failed to load image'));
|
|
28
|
+
if (typeof input === 'string') {
|
|
29
|
+
// URL or Data URL
|
|
30
|
+
img.src = input;
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
// File object
|
|
34
|
+
const reader = new FileReader();
|
|
35
|
+
reader.onload = (e) => {
|
|
36
|
+
img.src = e.target?.result;
|
|
37
|
+
};
|
|
38
|
+
reader.onerror = () => reject(new TwoFALibError('Failed to read file'));
|
|
39
|
+
reader.readAsDataURL(input);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Browser implementation of QR code library wrapper
|
|
45
|
+
*/
|
|
46
|
+
export class BrowserQrCodeLib {
|
|
47
|
+
constructor() {
|
|
48
|
+
this.qrCodeModule = null;
|
|
49
|
+
this.getImageDataFromInput = getImageDataFromInput;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Gets the QR code module, loading it if necessary
|
|
53
|
+
* @returns Promise that resolves to the QR code module
|
|
54
|
+
*/
|
|
55
|
+
async getQrCodeModule() {
|
|
56
|
+
if (!this.qrCodeModule) {
|
|
57
|
+
const qrcode = await import('qrcode');
|
|
58
|
+
this.qrCodeModule = qrcode.default;
|
|
59
|
+
}
|
|
60
|
+
return this.qrCodeModule;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* @inheritdoc
|
|
64
|
+
*/
|
|
65
|
+
async toDataURL(text) {
|
|
66
|
+
const qrCode = await this.getQrCodeModule();
|
|
67
|
+
return qrCode.toDataURL(text);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -4,7 +4,7 @@ import { generateKeyPair as generateKeyPairCb, generateKey as generateKeyCb, pub
|
|
|
4
4
|
import { argon2id } from 'hash-wasm';
|
|
5
5
|
import { toUint8Array } from 'uint8array-extras';
|
|
6
6
|
import { CryptoError } from '../../TwoFALibError.mjs';
|
|
7
|
-
import { generatePassphraseHash } from '../browser/
|
|
7
|
+
import { generatePassphraseHash } from '../browser/cryptoLib.mjs';
|
|
8
8
|
const generateKeyPair = promisify(generateKeyPairCb);
|
|
9
9
|
const generateKey = promisify(generateKeyCb);
|
|
10
10
|
/**
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import NodeCryptoLib from './cryptoLib.mjs';
|
|
2
|
+
import { NodeQrCodeLib } from './qrCodeLib.mjs';
|
|
3
|
+
import { NodeOpenPgpLib } from './openPgpLib.mjs';
|
|
4
|
+
/**
|
|
5
|
+
* Node.js-specific platform providers
|
|
6
|
+
*/
|
|
7
|
+
export const nodeProviders = {
|
|
8
|
+
CryptoLib: NodeCryptoLib,
|
|
9
|
+
WebSocketLib: () => WebSocket,
|
|
10
|
+
QrCodeLib: NodeQrCodeLib,
|
|
11
|
+
OpenPgpLib: NodeOpenPgpLib,
|
|
12
|
+
};
|
|
13
|
+
export default nodeProviders;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { OpenPgpLib } from '../../interfaces/OpenPgpLib.mjs';
|
|
2
|
+
/**
|
|
3
|
+
* Node.js implementation of OpenPGP library wrapper
|
|
4
|
+
*/
|
|
5
|
+
export declare class NodeOpenPgpLib implements OpenPgpLib {
|
|
6
|
+
private openPgpModule;
|
|
7
|
+
/**
|
|
8
|
+
* Gets the OpenPGP module, loading it if necessary
|
|
9
|
+
* @returns Promise that resolves to the OpenPGP module
|
|
10
|
+
*/
|
|
11
|
+
private getOpenPgpModule;
|
|
12
|
+
/**
|
|
13
|
+
* @inheritdoc
|
|
14
|
+
*/
|
|
15
|
+
encrypt(data: string, password: string): Promise<string>;
|
|
16
|
+
/**
|
|
17
|
+
* @inheritdoc
|
|
18
|
+
*/
|
|
19
|
+
decrypt(data: string, password: string): Promise<string>;
|
|
20
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node.js implementation of OpenPGP library wrapper
|
|
3
|
+
*/
|
|
4
|
+
export class NodeOpenPgpLib {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.openPgpModule = null;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Gets the OpenPGP module, loading it if necessary
|
|
10
|
+
* @returns Promise that resolves to the OpenPGP module
|
|
11
|
+
*/
|
|
12
|
+
async getOpenPgpModule() {
|
|
13
|
+
if (!this.openPgpModule) {
|
|
14
|
+
this.openPgpModule = await import('openpgp');
|
|
15
|
+
// enable Authenticated Encryption with Associated Data
|
|
16
|
+
this.openPgpModule.config.aeadProtect = true;
|
|
17
|
+
}
|
|
18
|
+
return this.openPgpModule;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* @inheritdoc
|
|
22
|
+
*/
|
|
23
|
+
async encrypt(data, password) {
|
|
24
|
+
const openPgp = await this.getOpenPgpModule();
|
|
25
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
26
|
+
const encrypted = await openPgp.encrypt({
|
|
27
|
+
message: await openPgp.createMessage({ text: data }),
|
|
28
|
+
passwords: [password],
|
|
29
|
+
format: 'armored',
|
|
30
|
+
});
|
|
31
|
+
return encrypted;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* @inheritdoc
|
|
35
|
+
*/
|
|
36
|
+
async decrypt(data, password) {
|
|
37
|
+
const openPgp = await this.getOpenPgpModule();
|
|
38
|
+
const decrypted = await openPgp.decrypt({
|
|
39
|
+
message: await openPgp.readMessage({ armoredMessage: data }),
|
|
40
|
+
passwords: [password],
|
|
41
|
+
});
|
|
42
|
+
return decrypted.data;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { ImageData } from 'canvas';
|
|
2
|
+
import type { QrCodeLib } from '../../interfaces/QrCodeLib.mjs';
|
|
3
|
+
/**
|
|
4
|
+
* Gets the ImageData from an image, for Node.js environments.
|
|
5
|
+
* This ImageData is then further processed to get QR codes.
|
|
6
|
+
* @param inputImage - The image to get the ImageData from.
|
|
7
|
+
* @returns A promise that resolves to the ImageData.
|
|
8
|
+
*/
|
|
9
|
+
export declare const getImageDataFromInput: (inputImage: string | File | Uint8Array) => Promise<ImageData>;
|
|
10
|
+
/**
|
|
11
|
+
* Node.js implementation of QR code library wrapper
|
|
12
|
+
*/
|
|
13
|
+
export declare class NodeQrCodeLib implements QrCodeLib {
|
|
14
|
+
private qrCodeModule;
|
|
15
|
+
/**
|
|
16
|
+
* Gets the QR code module, loading it if necessary
|
|
17
|
+
* @returns Promise that resolves to the QR code module
|
|
18
|
+
*/
|
|
19
|
+
private getQrCodeModule;
|
|
20
|
+
/**
|
|
21
|
+
* @inheritdoc
|
|
22
|
+
*/
|
|
23
|
+
toDataURL(text: string): Promise<string>;
|
|
24
|
+
/**
|
|
25
|
+
* @inheritdoc
|
|
26
|
+
*/
|
|
27
|
+
getImageDataFromInput(imageInput: string | File | Uint8Array): Promise<ImageData>;
|
|
28
|
+
}
|