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,114 @@
1
+ import { TOTP } from 'totp-generator';
2
+ import { EntryNotFoundError, TokenGenerationError } from '../TwoFALibError.mjs';
3
+ import { SUPPORTED_ALGORITHMS, } from '../utils/constants.mjs';
4
+ /**
5
+ * Manages the data within the vault. This class should only be used internally
6
+ * by the library, for public methods, see VaultOperationsManager.
7
+ */
8
+ class VaultDataManager {
9
+ /**
10
+ * Constructs a new VaultDataManager instance.
11
+ * @param mediator - The mediator for accessing other components.
12
+ */
13
+ constructor(mediator) {
14
+ this.mediator = mediator;
15
+ this.vault = [];
16
+ }
17
+ get persistentStorageManager() {
18
+ return this.mediator.getComponent('persistentStorageManager');
19
+ }
20
+ /**
21
+ * @returns The number of entries in the vault.
22
+ */
23
+ get size() {
24
+ return this.vault.length;
25
+ }
26
+ /**
27
+ * Retrieve a specific entry.
28
+ * @param entryId - The unique identifier of the entry.
29
+ * @returns The entry.
30
+ * @throws {EntryNotFoundError} If no entry exists with the given ID.
31
+ */
32
+ getFullEntry(entryId) {
33
+ const entry = this.vault.find((e) => e.id === entryId);
34
+ if (!entry)
35
+ throw new EntryNotFoundError('Entry not found');
36
+ return entry;
37
+ }
38
+ /**
39
+ * Retrieve all entries in the vault.
40
+ * @returns An array of all entries.
41
+ */
42
+ getAllEntries() {
43
+ return this.vault;
44
+ }
45
+ /**
46
+ * Generate a time-based one-time password (TOTP) for a specific entry.
47
+ * @param id - The unique identifier of the entry.
48
+ * @param timestamp - Optional timestamp to use for token generation (default is current time).
49
+ * @returns An object containing the token and the validity period.
50
+ * @throws {EntryNotFoundError} If no entry exists with the given ID.
51
+ * @throws {TokenGenerationError} If token generation fails due to invalid entry data or technical issues.
52
+ */
53
+ generateTokenForEntry(id, timestamp) {
54
+ const entry = this.vault.find((e) => e.id === id);
55
+ if (!entry || entry.type !== 'TOTP') {
56
+ throw new EntryNotFoundError('TOTP entry not found');
57
+ }
58
+ const { secret, period, algorithm, digits } = entry.payload;
59
+ if (!SUPPORTED_ALGORITHMS.includes(algorithm)) {
60
+ throw new TokenGenerationError(`Algorithm ${algorithm} is not supported`);
61
+ }
62
+ const totpOptions = {
63
+ digits,
64
+ period,
65
+ algorithm: algorithm,
66
+ timestamp: timestamp ?? Date.now(),
67
+ };
68
+ const { otp, expires } = TOTP.generate(secret, totpOptions);
69
+ return { otp, validFrom: expires - period * 1000, validTill: expires };
70
+ }
71
+ /**
72
+ * Add a new entry to the vault.
73
+ * @param entry - The entry data to add (without an ID, as it will be generated).
74
+ * @returns A promise that resolves when the entry is added.
75
+ */
76
+ async addEntry(entry) {
77
+ this.vault.push(entry);
78
+ await this.persistentStorageManager.save();
79
+ }
80
+ /**
81
+ * Delete an entry from the vault.
82
+ * @param entryId - The identifier of the entry to delete.
83
+ * @throws {EntryNotFoundError} If no entry exists with the given ID.
84
+ */
85
+ async deleteEntry(entryId) {
86
+ const index = this.vault.findIndex((e) => e.id === entryId);
87
+ if (index === -1)
88
+ throw new EntryNotFoundError('Entry not found');
89
+ this.vault.splice(index, 1);
90
+ await this.persistentStorageManager.save();
91
+ }
92
+ /**
93
+ * Update an existing entry in the vault.
94
+ * @param updatedEntry - An object containing the updated entry.
95
+ * @returns A promise that resolves when the entry is updated.
96
+ * @throws {EntryNotFoundError} If no entry exists with the given ID.
97
+ */
98
+ async updateEntry(updatedEntry) {
99
+ const { id } = updatedEntry;
100
+ const index = this.vault.findIndex((e) => e.id === id);
101
+ if (index === -1)
102
+ throw new EntryNotFoundError('Entry not found');
103
+ this.vault[index] = updatedEntry;
104
+ await this.persistentStorageManager.save();
105
+ }
106
+ /**
107
+ * Replace the current vault with a new one.
108
+ * @param newVault - The new vault data to replace the existing vault.
109
+ */
110
+ replaceVault(newVault) {
111
+ this.vault = newVault;
112
+ }
113
+ }
114
+ export default VaultDataManager;
@@ -0,0 +1,91 @@
1
+ import type Entry from '../interfaces/Entry.mjs';
2
+ import type { EntryId, EntryMeta, EntryMetaWithToken, NewEntry, Token } from '../interfaces/Entry.mjs';
3
+ import type TwoFaLibMediator from '../TwoFaLibMediator.mjs';
4
+ /**
5
+ * Manages the public operations related to the vault, including adding, deleting, and updating entries.
6
+ */
7
+ declare class VaultManager {
8
+ private readonly mediator;
9
+ /**
10
+ * Constructs a new instance of VaultManager.
11
+ * @param mediator - The mediator for accessing other components.
12
+ */
13
+ constructor(mediator: TwoFaLibMediator);
14
+ private get vaultDataManager();
15
+ private get commandManager();
16
+ /**
17
+ * @returns The number of entries in the vault.
18
+ */
19
+ get size(): number;
20
+ /**
21
+ * Retrieve metadata for a specific entry.
22
+ * @param entryId - The ID of the entry.
23
+ * @returns The entry's metadata.
24
+ * @throws {EntryNotFoundError} If no entry exists with the given ID.
25
+ */
26
+ getEntryMeta(entryId: EntryId): EntryMeta;
27
+ /**
28
+ * Search for entry ids matching the provided query.
29
+ * @param query - The search query string.
30
+ * @returns An array of matching entry IDs.
31
+ */
32
+ searchEntries(query: string): EntryId[];
33
+ /**
34
+ * Search for entries matching the provided query.
35
+ * @param query - The search query string.
36
+ * @param includeTokens - When true, includes current tokens with the metas.
37
+ * @returns An array of matching entry metas, optionally with tokens.
38
+ */
39
+ searchEntriesMetas(query: string, includeTokens: true): EntryMetaWithToken[];
40
+ /**
41
+ * @inheritdoc
42
+ */
43
+ searchEntriesMetas(query: string, includeTokens?: false): EntryMeta[];
44
+ /**
45
+ * Retrieve a list of all entry IDs in the library.
46
+ * @returns An array of all entry IDs.
47
+ */
48
+ listEntries(): EntryId[];
49
+ /**
50
+ * Retrieve a list of all entry metas in the library.
51
+ * @param includeTokens - When true, includes current tokens with the metas.
52
+ * @returns An array of all entry metas, optionally with tokens.
53
+ */
54
+ listEntriesMetas(includeTokens: true): EntryMetaWithToken[];
55
+ /**
56
+ * @inheritdoc
57
+ */
58
+ listEntriesMetas(includeTokens?: false): EntryMeta[];
59
+ /**
60
+ * Generate a time-based one-time password (TOTP) for a specific entry.
61
+ * @param id - The unique identifier of the entry.
62
+ * @param timestamp - Optional timestamp to use for token generation (default is current time).
63
+ * @returns An object containing the token and between which timestamps it is valid
64
+ * @throws {EntryNotFoundError} If no entry exists with the given ID.
65
+ * @throws {TokenGenerationError} If token generation fails due to invalid entry data or technical issues.
66
+ */
67
+ generateTokenForEntry(id: EntryId, timestamp?: number): Token;
68
+ /**
69
+ * Add a new entry to the library.
70
+ * @param entry - The entry data to add (without an ID, as it will be generated).
71
+ * @returns A promise that resolves to the newly generated EntryId.
72
+ * @throws {InvalidCommandError} If the provided entry data is invalid or incomplete.
73
+ */
74
+ addEntry(entry: NewEntry): Promise<EntryId>;
75
+ /**
76
+ * Delete an existing entry from the library.
77
+ * @param entryId - The unique identifier of the entry to delete.
78
+ * @throws {EntryNotFoundError} If no entry exists with the given ID.
79
+ */
80
+ deleteEntry(entryId: EntryId): Promise<void>;
81
+ /**
82
+ * Update an existing entry in the library.
83
+ * @param entryId - The unique identifier of the entry to update.
84
+ * @param updates - An object containing the fields to update and their new values.
85
+ * @returns A promise that resolves to the updated entry's metadata.
86
+ * @throws {EntryNotFoundError} If no entry exists with the given ID.
87
+ * @throws {InvalidCommandError} If the update data is invalid or would result in an invalid entry.
88
+ */
89
+ updateEntry(entryId: EntryId, updates: Partial<Omit<Entry, 'id'>>): Promise<EntryMeta>;
90
+ }
91
+ export default VaultManager;
@@ -0,0 +1,163 @@
1
+ import { v4 as genUuidV4 } from 'uuid';
2
+ import AddEntryCommand from '../Command/commands/AddEntryCommand.mjs';
3
+ import DeleteEntryCommand from '../Command/commands/DeleteEntryCommand.mjs';
4
+ import UpdateEntryCommand from '../Command/commands/UpdateEntryCommand.mjs';
5
+ import { EntryNotFoundError } from '../TwoFALibError.mjs';
6
+ const getMetaForEntry = (entry) => ({
7
+ id: entry.id,
8
+ name: entry.name,
9
+ issuer: entry.issuer,
10
+ type: entry.type,
11
+ addedAt: entry.addedAt,
12
+ updatedAt: entry.updatedAt,
13
+ });
14
+ /**
15
+ * Manages the public operations related to the vault, including adding, deleting, and updating entries.
16
+ */
17
+ class VaultManager {
18
+ /**
19
+ * Constructs a new instance of VaultManager.
20
+ * @param mediator - The mediator for accessing other components.
21
+ */
22
+ constructor(mediator) {
23
+ this.mediator = mediator;
24
+ }
25
+ get vaultDataManager() {
26
+ return this.mediator.getComponent('vaultDataManager');
27
+ }
28
+ get commandManager() {
29
+ return this.mediator.getComponent('commandManager');
30
+ }
31
+ /**
32
+ * @returns The number of entries in the vault.
33
+ */
34
+ get size() {
35
+ return this.vaultDataManager.size;
36
+ }
37
+ /**
38
+ * Retrieve metadata for a specific entry.
39
+ * @param entryId - The ID of the entry.
40
+ * @returns The entry's metadata.
41
+ * @throws {EntryNotFoundError} If no entry exists with the given ID.
42
+ */
43
+ getEntryMeta(entryId) {
44
+ return getMetaForEntry(this.vaultDataManager.getFullEntry(entryId));
45
+ }
46
+ /**
47
+ * Search for entry ids matching the provided query.
48
+ * @param query - The search query string.
49
+ * @returns An array of matching entry IDs.
50
+ */
51
+ searchEntries(query) {
52
+ const lowercaseQuery = query.toLowerCase();
53
+ const entries = this.vaultDataManager.getAllEntries();
54
+ return entries
55
+ .filter((entry) => entry.name.toLowerCase().includes(lowercaseQuery) ||
56
+ entry.issuer.toLowerCase().includes(lowercaseQuery))
57
+ .map((entry) => entry.id);
58
+ }
59
+ /**
60
+ * @inheritdoc
61
+ */
62
+ searchEntriesMetas(query, includeTokens) {
63
+ const lowercaseQuery = query.toLowerCase();
64
+ const entries = this.vaultDataManager.getAllEntries();
65
+ return entries
66
+ .filter((entry) => entry.name.toLowerCase().includes(lowercaseQuery) ||
67
+ entry.issuer.toLowerCase().includes(lowercaseQuery))
68
+ .map((entry) => {
69
+ const meta = getMetaForEntry(entry);
70
+ if (includeTokens) {
71
+ return {
72
+ ...meta,
73
+ token: this.generateTokenForEntry(entry.id),
74
+ };
75
+ }
76
+ return meta;
77
+ });
78
+ }
79
+ /**
80
+ * Retrieve a list of all entry IDs in the library.
81
+ * @returns An array of all entry IDs.
82
+ */
83
+ listEntries() {
84
+ return this.vaultDataManager.getAllEntries().map((entry) => entry.id);
85
+ }
86
+ /**
87
+ * @inheritdoc
88
+ */
89
+ listEntriesMetas(includeTokens) {
90
+ const entries = this.vaultDataManager.getAllEntries();
91
+ return entries.map((entry) => {
92
+ const meta = getMetaForEntry(entry);
93
+ if (includeTokens) {
94
+ return {
95
+ ...meta,
96
+ token: this.generateTokenForEntry(entry.id),
97
+ };
98
+ }
99
+ return meta;
100
+ });
101
+ }
102
+ /**
103
+ * Generate a time-based one-time password (TOTP) for a specific entry.
104
+ * @param id - The unique identifier of the entry.
105
+ * @param timestamp - Optional timestamp to use for token generation (default is current time).
106
+ * @returns An object containing the token and between which timestamps it is valid
107
+ * @throws {EntryNotFoundError} If no entry exists with the given ID.
108
+ * @throws {TokenGenerationError} If token generation fails due to invalid entry data or technical issues.
109
+ */
110
+ generateTokenForEntry(id, timestamp) {
111
+ return this.vaultDataManager.generateTokenForEntry(id, timestamp);
112
+ }
113
+ /**
114
+ * Add a new entry to the library.
115
+ * @param entry - The entry data to add (without an ID, as it will be generated).
116
+ * @returns A promise that resolves to the newly generated EntryId.
117
+ * @throws {InvalidCommandError} If the provided entry data is invalid or incomplete.
118
+ */
119
+ async addEntry(entry) {
120
+ const newId = genUuidV4();
121
+ const newEntry = {
122
+ ...entry,
123
+ id: newId,
124
+ addedAt: Date.now(),
125
+ updatedAt: null,
126
+ };
127
+ const command = AddEntryCommand.create(newEntry);
128
+ await this.commandManager.execute(command);
129
+ return newId;
130
+ }
131
+ /**
132
+ * Delete an existing entry from the library.
133
+ * @param entryId - The unique identifier of the entry to delete.
134
+ * @throws {EntryNotFoundError} If no entry exists with the given ID.
135
+ */
136
+ async deleteEntry(entryId) {
137
+ const command = DeleteEntryCommand.create({ entryId });
138
+ await this.commandManager.execute(command);
139
+ }
140
+ /**
141
+ * Update an existing entry in the library.
142
+ * @param entryId - The unique identifier of the entry to update.
143
+ * @param updates - An object containing the fields to update and their new values.
144
+ * @returns A promise that resolves to the updated entry's metadata.
145
+ * @throws {EntryNotFoundError} If no entry exists with the given ID.
146
+ * @throws {InvalidCommandError} If the update data is invalid or would result in an invalid entry.
147
+ */
148
+ async updateEntry(entryId, updates) {
149
+ if (Object.keys(updates).includes('id')) {
150
+ throw new EntryNotFoundError("Can't update id");
151
+ }
152
+ const oldEntry = this.vaultDataManager.getFullEntry(entryId);
153
+ const updatedEntry = { ...oldEntry, ...updates };
154
+ const command = UpdateEntryCommand.create({
155
+ entryId,
156
+ oldEntry,
157
+ updatedEntry,
158
+ });
159
+ await this.commandManager.execute(command);
160
+ return getMetaForEntry(updatedEntry);
161
+ }
162
+ }
163
+ export default VaultManager;
@@ -0,0 +1,2 @@
1
+ export declare const SUPPORTED_ALGORITHMS: readonly ["SHA-1", "SHA-256", "SHA-512"];
2
+ export type SupportedAlgorithmsType = (typeof SUPPORTED_ALGORITHMS)[number];
@@ -0,0 +1 @@
1
+ export const SUPPORTED_ALGORITHMS = ['SHA-1', 'SHA-256', 'SHA-512'];
@@ -0,0 +1,43 @@
1
+ import type { ZxcvbnResult } from '@zxcvbn-ts/core';
2
+ import type CryptoLib from '../interfaces/CryptoLib.mjs';
3
+ import type { Passphrase } from '../interfaces/CryptoLib.mjs';
4
+ import type { DeviceType } from '../interfaces/SyncTypes.mjs';
5
+ import TwoFaLib from '../TwoFaLib.mjs';
6
+ import LibraryLoader from '../subclasses/LibraryLoader.mjs';
7
+ import type { LockedRepresentationString } from '../interfaces/Vault.mjs';
8
+ import type { PassphraseExtraDict } from '../interfaces/PassphraseExtraDict.js';
9
+ /**
10
+ * Evaluates the strength of a passphrase.
11
+ * @param libraryLoader - An instance of LibraryLoader.
12
+ * @param passphrase - The passphrase to evaluate.
13
+ * @param passphraseExtraDict - Additional words to be used for passphrase strength evaluation.
14
+ * @returns Promise resolving to the passphrase strength result.
15
+ */
16
+ export declare const getPassphraseStrength: (libraryLoader: LibraryLoader, passphrase: Passphrase, passphraseExtraDict: PassphraseExtraDict) => Promise<ZxcvbnResult>;
17
+ /**
18
+ * Validates the strength of a passphrase.
19
+ * @param libraryLoader - An instance of LibraryLoader.
20
+ * @param passphrase - The passphrase to validate.
21
+ * @param passphraseExtraDict - Additional words to be used for passphrase strength evaluation.
22
+ * @throws {InitializationError} If the passphrase is too weak.
23
+ */
24
+ export declare const validatePassphraseStrength: (libraryLoader: LibraryLoader, passphrase: Passphrase, passphraseExtraDict: PassphraseExtraDict) => Promise<void>;
25
+ /**
26
+ * Returns utility functions useful in creating a new twoFaLib vault
27
+ * @param cryptoLib - An instance of CryptoLib that is compatible with the environment.
28
+ * @param deviceType - A unique identifier for this device type (e.g. 2fa-cli).
29
+ * @param passphraseExtraDict - Additional words to be used for passphrase strength evaluation.
30
+ * @param serverUrl - The server URL for syncing.
31
+ * @returns An object with methods to evaluate passphrase strength and create a new TwoFaLib vault.
32
+ */
33
+ export declare const getTwoFaLibVaultCreationUtils: (cryptoLib: CryptoLib, deviceType: DeviceType, passphraseExtraDict: PassphraseExtraDict, serverUrl?: string) => {
34
+ getPassphraseStrength: (passphrase: Passphrase, passphraseExtraDict: PassphraseExtraDict) => Promise<ZxcvbnResult>;
35
+ createNewTwoFaLibVault: (passphrase: Passphrase) => Promise<{
36
+ twoFaLib: TwoFaLib;
37
+ publicKey: import("../interfaces/CryptoLib.mjs").PublicKey;
38
+ encryptedPrivateKey: import("../interfaces/CryptoLib.mjs").EncryptedPrivateKey;
39
+ encryptedSymmetricKey: import("../interfaces/CryptoLib.mjs").EncryptedSymmetricKey;
40
+ salt: import("../interfaces/CryptoLib.mjs").Salt;
41
+ }>;
42
+ loadTwoFaLibFromLockedRepesentation: (lockedRepresentationString: LockedRepresentationString, passphrase: Passphrase) => Promise<TwoFaLib>;
43
+ };
@@ -0,0 +1,125 @@
1
+ import { v4 as genUuidV4 } from 'uuid';
2
+ import TwoFaLib from '../TwoFaLib.mjs';
3
+ import { InitializationError, TwoFALibError } from '../TwoFALibError.mjs';
4
+ import LibraryLoader from '../subclasses/LibraryLoader.mjs';
5
+ /**
6
+ * Evaluates the strength of a passphrase.
7
+ * @param libraryLoader - An instance of LibraryLoader.
8
+ * @param passphrase - The passphrase to evaluate.
9
+ * @param passphraseExtraDict - Additional words to be used for passphrase strength evaluation.
10
+ * @returns Promise resolving to the passphrase strength result.
11
+ */
12
+ export const getPassphraseStrength = async (libraryLoader, passphrase, passphraseExtraDict) => {
13
+ const zxcvbn = await libraryLoader.getZxcvbn();
14
+ return zxcvbn(passphrase, [
15
+ 'twofactor',
16
+ 'authentication',
17
+ 'token',
18
+ '2fa',
19
+ 'otp',
20
+ 'tfa',
21
+ 'mfa',
22
+ 'security',
23
+ 'login',
24
+ 'verify',
25
+ 'app',
26
+ 'yubikey',
27
+ 'secret',
28
+ 'vault',
29
+ 'encrypt',
30
+ 'decrypt',
31
+ 'qr',
32
+ 'timebased',
33
+ 'hmac',
34
+ 'key',
35
+ 'trust',
36
+ 'secure',
37
+ ...passphraseExtraDict,
38
+ ]);
39
+ };
40
+ /**
41
+ * Validates the strength of a passphrase.
42
+ * @param libraryLoader - An instance of LibraryLoader.
43
+ * @param passphrase - The passphrase to validate.
44
+ * @param passphraseExtraDict - Additional words to be used for passphrase strength evaluation.
45
+ * @throws {InitializationError} If the passphrase is too weak.
46
+ */
47
+ export const validatePassphraseStrength = async (libraryLoader, passphrase, passphraseExtraDict) => {
48
+ const passphraseStrength = await getPassphraseStrength(libraryLoader, passphrase, passphraseExtraDict);
49
+ if (passphraseStrength.score < 3) {
50
+ throw new TwoFALibError('Passphrase is too weak');
51
+ }
52
+ };
53
+ /**
54
+ * Creates a new TwoFaLib vault.
55
+ * @param libraryLoader - An instance of LibraryLoader.
56
+ * @param deviceType - A unique identifier for the device type e.g. 2fa-cli.
57
+ * @param serverUrl - The server URL for syncing.
58
+ * @param passphraseExtraDict - Additional words to be used for passphrase strength evaluation.
59
+ * @param passphrase - The passphrase to be used to encrypt the private key.
60
+ * @returns Promise resolving to an object containing the newly created TwoFaLib instance and related data.
61
+ */
62
+ const createNewTwoFaLibVault = async (libraryLoader, deviceType, serverUrl, passphraseExtraDict, passphrase) => {
63
+ const cryptoLib = libraryLoader.getCryptoLib();
64
+ const { publicKey, privateKey, symmetricKey, encryptedPrivateKey, encryptedSymmetricKey, salt, } = await cryptoLib.createKeys(passphrase);
65
+ await validatePassphraseStrength(libraryLoader, passphrase, passphraseExtraDict);
66
+ const deviceId = genUuidV4();
67
+ const twoFaLib = new TwoFaLib(deviceType, cryptoLib, passphraseExtraDict, privateKey, symmetricKey, encryptedPrivateKey, encryptedSymmetricKey, salt, publicKey, deviceId, [], {
68
+ serverUrl,
69
+ devices: [],
70
+ commandSendQueue: [],
71
+ });
72
+ return {
73
+ twoFaLib,
74
+ publicKey,
75
+ encryptedPrivateKey,
76
+ encryptedSymmetricKey,
77
+ salt,
78
+ };
79
+ };
80
+ /**
81
+ * Loads the library state from a previously locked representation.
82
+ * @param libraryLoader - An instance of LibraryLoader.
83
+ * @param deviceType - A unique identifier for this device type (e.g. 2fa-cli).
84
+ * @param passphraseExtraDict - Additional words to be used for passphrase strength evaluation.
85
+ * @param lockedRepresentationString - The string representation of the locked library state representation.
86
+ * @param passphrase - The passphrase for decrypting the keys.
87
+ * @returns A promise that resolves when loading is complete.
88
+ * @throws {InitializationError} If loading fails due to invalid or corrupted data.
89
+ */
90
+ const loadTwoFaLibFromLockedRepesentation = async (libraryLoader, deviceType, passphraseExtraDict, lockedRepresentationString, passphrase) => {
91
+ const cryptoLib = libraryLoader.getCryptoLib();
92
+ const lockedRepresentation = JSON.parse(lockedRepresentationString);
93
+ if (!lockedRepresentation ||
94
+ !lockedRepresentation.encryptedPrivateKey ||
95
+ !lockedRepresentation.encryptedSymmetricKey ||
96
+ !lockedRepresentation.salt ||
97
+ !lockedRepresentation.encryptedVaultState) {
98
+ throw new InitializationError('lockedRepresentation is incomplete or corrupted');
99
+ }
100
+ const { privateKey, symmetricKey, publicKey } = await cryptoLib.decryptKeys(lockedRepresentation.encryptedPrivateKey, lockedRepresentation.encryptedSymmetricKey, lockedRepresentation.salt, passphrase);
101
+ const vaultState = JSON.parse(await cryptoLib.decryptSymmetric(symmetricKey, lockedRepresentation.encryptedVaultState));
102
+ if (!vaultState ||
103
+ !vaultState.deviceId ||
104
+ !vaultState.sync?.commandSendQueue ||
105
+ !vaultState.sync?.devices) {
106
+ throw new InitializationError('encryptedVaultState is incomplete or corrupted');
107
+ }
108
+ return new TwoFaLib(deviceType, cryptoLib, passphraseExtraDict, privateKey, symmetricKey, lockedRepresentation.encryptedPrivateKey, lockedRepresentation.encryptedSymmetricKey, lockedRepresentation.salt, publicKey, vaultState.deviceId, vaultState.vault, vaultState.sync);
109
+ };
110
+ /**
111
+ * Returns utility functions useful in creating a new twoFaLib vault
112
+ * @param cryptoLib - An instance of CryptoLib that is compatible with the environment.
113
+ * @param deviceType - A unique identifier for this device type (e.g. 2fa-cli).
114
+ * @param passphraseExtraDict - Additional words to be used for passphrase strength evaluation.
115
+ * @param serverUrl - The server URL for syncing.
116
+ * @returns An object with methods to evaluate passphrase strength and create a new TwoFaLib vault.
117
+ */
118
+ export const getTwoFaLibVaultCreationUtils = (cryptoLib, deviceType, passphraseExtraDict, serverUrl) => {
119
+ const libraryLoader = new LibraryLoader(cryptoLib);
120
+ return {
121
+ getPassphraseStrength: getPassphraseStrength.bind(null, libraryLoader),
122
+ createNewTwoFaLibVault: createNewTwoFaLibVault.bind(null, libraryLoader, deviceType, serverUrl, passphraseExtraDict),
123
+ loadTwoFaLibFromLockedRepesentation: loadTwoFaLibFromLockedRepesentation.bind(null, libraryLoader, deviceType, passphraseExtraDict),
124
+ };
125
+ };
@@ -0,0 +1,53 @@
1
+ import type { NewEntry } from '../interfaces/Entry.mjs';
2
+ import type Entry from '../interfaces/Entry.mjs';
3
+ import type { EntryId } from '../interfaces/Entry.mjs';
4
+ /**
5
+ * Parses an OTP URI and extracts the relevant information to create a new entry.
6
+ * @param UrlParser - The URL parsing library.
7
+ * @param otpUri - The OTP URI to parse.
8
+ * @returns An object representing the new entry.
9
+ * @throws ExportImportError if the URI is invalid or contains unsupported features.
10
+ */
11
+ export declare const parseOtpUri: (UrlParser: typeof import("whatwg-url"), otpUri: string) => NewEntry;
12
+ /**
13
+ * Generates an HTML page with QR codes for the provided OTP entries.
14
+ * @param qrGeneratorLib - The QR code generation library.
15
+ * @param entries - An array of OTP entries.
16
+ * @returns A promise that resolves to the HTML string.
17
+ */
18
+ export declare const generateHtmlExport: (qrGeneratorLib: typeof import("qrcode"), entries: Entry[]) => Promise<string>;
19
+ /**
20
+ * Generates a text export of OTP URIs for the provided entries.
21
+ * @param entries - An array of OTP entries.
22
+ * @returns A string containing the OTP URIs, one per line.
23
+ */
24
+ export declare const generateTextExport: (entries: Entry[]) => string;
25
+ /**
26
+ * Processes the lines of a text file containing OTP URIs and returns an array of objects, each containing the line number,
27
+ * the EntryId or null if it was not a valid entry and the error if there was one.
28
+ * @param lines - An array of strings, each containing an OTP URI.
29
+ * @param importFromUri - A function that takes a URI and returns a promise that resolves to the EntryId.
30
+ * @returns A promise that resolves to an array of objects, each containing the line number,
31
+ * the EntryId or null if it was not a valid entry and the error if there was one.
32
+ */
33
+ export declare const processImportLines: (lines: string[], importFromUri: (uri: string) => Promise<EntryId>) => Promise<{
34
+ lineNr: number;
35
+ entryId: EntryId | null;
36
+ error: unknown;
37
+ }[]>;
38
+ /**
39
+ * Encrypts the given data using OpenPGP.
40
+ * @param openPgpLib - The OpenPGP library.
41
+ * @param data - The data to encrypt.
42
+ * @param password - The password to use for encryption.
43
+ * @returns A promise that resolves to the encrypted data.
44
+ */
45
+ export declare const encryptExport: (openPgpLib: typeof import("openpgp"), data: string, password: string) => Promise<string>;
46
+ /**
47
+ * Decrypts the given data using OpenPGP.
48
+ * @param openPgpLib - The OpenPGP library.
49
+ * @param data - The data to decrypt.
50
+ * @param password - The password to use for decryption.
51
+ * @returns A promise that resolves to the decrypted data.
52
+ */
53
+ export declare const decryptExport: (openPgpLib: typeof import("openpgp"), data: string, password: string) => Promise<string>;