@metamask-previews/profile-sync-controller 3.0.0-preview-9cfbf21f → 3.0.0-preview-73fa7bfb
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/dist/controllers/user-storage/__fixtures__/mockResponses.cjs +6 -7
- package/dist/controllers/user-storage/__fixtures__/mockResponses.cjs.map +1 -1
- package/dist/controllers/user-storage/__fixtures__/mockResponses.d.cts.map +1 -1
- package/dist/controllers/user-storage/__fixtures__/mockResponses.d.mts.map +1 -1
- package/dist/controllers/user-storage/__fixtures__/mockResponses.mjs +6 -7
- package/dist/controllers/user-storage/__fixtures__/mockResponses.mjs.map +1 -1
- package/dist/controllers/user-storage/services.cjs +1 -47
- package/dist/controllers/user-storage/services.cjs.map +1 -1
- package/dist/controllers/user-storage/services.d.cts +0 -8
- package/dist/controllers/user-storage/services.d.cts.map +1 -1
- package/dist/controllers/user-storage/services.d.mts +0 -8
- package/dist/controllers/user-storage/services.d.mts.map +1 -1
- package/dist/controllers/user-storage/services.mjs +0 -45
- package/dist/controllers/user-storage/services.mjs.map +1 -1
- package/dist/sdk/__fixtures__/mock-userstorage.cjs +6 -29
- package/dist/sdk/__fixtures__/mock-userstorage.cjs.map +1 -1
- package/dist/sdk/__fixtures__/mock-userstorage.d.cts +6 -4
- package/dist/sdk/__fixtures__/mock-userstorage.d.cts.map +1 -1
- package/dist/sdk/__fixtures__/mock-userstorage.d.mts +6 -4
- package/dist/sdk/__fixtures__/mock-userstorage.d.mts.map +1 -1
- package/dist/sdk/__fixtures__/mock-userstorage.mjs +6 -6
- package/dist/sdk/__fixtures__/mock-userstorage.mjs.map +1 -1
- package/dist/sdk/user-storage.cjs +9 -62
- package/dist/sdk/user-storage.cjs.map +1 -1
- package/dist/sdk/user-storage.d.cts +1 -5
- package/dist/sdk/user-storage.d.cts.map +1 -1
- package/dist/sdk/user-storage.d.mts +1 -5
- package/dist/sdk/user-storage.d.mts.map +1 -1
- package/dist/sdk/user-storage.mjs +9 -62
- package/dist/sdk/user-storage.mjs.map +1 -1
- package/dist/shared/encryption/cache.cjs +14 -12
- package/dist/shared/encryption/cache.cjs.map +1 -1
- package/dist/shared/encryption/cache.d.cts +3 -4
- package/dist/shared/encryption/cache.d.cts.map +1 -1
- package/dist/shared/encryption/cache.d.mts +3 -4
- package/dist/shared/encryption/cache.d.mts.map +1 -1
- package/dist/shared/encryption/cache.mjs +13 -11
- package/dist/shared/encryption/cache.mjs.map +1 -1
- package/dist/shared/encryption/encryption.cjs +25 -49
- package/dist/shared/encryption/encryption.cjs.map +1 -1
- package/dist/shared/encryption/encryption.d.cts +0 -2
- package/dist/shared/encryption/encryption.d.cts.map +1 -1
- package/dist/shared/encryption/encryption.d.mts +0 -2
- package/dist/shared/encryption/encryption.d.mts.map +1 -1
- package/dist/shared/encryption/encryption.mjs +14 -38
- package/dist/shared/encryption/encryption.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/shared/encryption/constants.cjs +0 -18
- package/dist/shared/encryption/constants.cjs.map +0 -1
- package/dist/shared/encryption/constants.d.cts +0 -8
- package/dist/shared/encryption/constants.d.cts.map +0 -1
- package/dist/shared/encryption/constants.d.mts +0 -8
- package/dist/shared/encryption/constants.d.mts.map +0 -1
- package/dist/shared/encryption/constants.mjs +0 -15
- package/dist/shared/encryption/constants.mjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-storage.mjs","sourceRoot":"","sources":["../../src/sdk/user-storage.ts"],"names":[],"mappings":"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","sourcesContent":["import encryption, { createSHA256Hash } from '../shared/encryption';\nimport { SHARED_SALT } from '../shared/encryption/constants';\nimport type { Env } from '../shared/env';\nimport { getEnvUrls } from '../shared/env';\nimport type {\n UserStorageFeatureKeys,\n UserStorageFeatureNames,\n UserStoragePathWithFeatureAndKey,\n UserStoragePathWithFeatureOnly,\n} from '../shared/storage-schema';\nimport { createEntryPath } from '../shared/storage-schema';\nimport type { IBaseAuth } from './authentication-jwt-bearer/types';\nimport { NotFoundError, UserStorageError } from './errors';\n\nexport const STORAGE_URL = (env: Env, encryptedPath: string) =>\n `${getEnvUrls(env).userStorageApiUrl}/api/v1/userstorage/${encryptedPath}`;\n\nexport type UserStorageConfig = {\n env: Env;\n auth: Pick<IBaseAuth, 'getAccessToken' | 'getUserProfile' | 'signMessage'>;\n};\n\nexport type StorageOptions = {\n getStorageKey: () => Promise<string | null>;\n setStorageKey: (val: string) => Promise<void>;\n};\n\nexport type UserStorageOptions = {\n storage?: StorageOptions;\n};\n\nexport type GetUserStorageAllFeatureEntriesResponse = {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n HashedKey: string;\n // eslint-disable-next-line @typescript-eslint/naming-convention\n Data: string;\n}[];\n\ntype ErrorMessage = {\n message: string;\n error: string;\n};\n\nexport class UserStorage {\n protected config: UserStorageConfig;\n\n protected options: UserStorageOptions;\n\n protected env: Env;\n\n constructor(config: UserStorageConfig, options: UserStorageOptions) {\n this.env = config.env;\n this.config = config;\n this.options = options;\n }\n\n async setItem(\n path: UserStoragePathWithFeatureAndKey,\n value: string,\n ): Promise<void> {\n await this.#upsertUserStorage(path, value);\n }\n\n async batchSetItems<FeatureName extends UserStorageFeatureNames>(\n path: FeatureName,\n values: [UserStorageFeatureKeys<FeatureName>, string][],\n ) {\n await this.#batchUpsertUserStorage(path, values);\n }\n\n async getItem(path: UserStoragePathWithFeatureAndKey): Promise<string> {\n return this.#getUserStorage(path);\n }\n\n async getAllFeatureItems(\n path: UserStoragePathWithFeatureOnly,\n ): Promise<string[] | null> {\n return this.#getUserStorageAllFeatureEntries(path);\n }\n\n async deleteItem(path: UserStoragePathWithFeatureAndKey): Promise<void> {\n return this.#deleteUserStorage(path);\n }\n\n async deleteAllFeatureItems(\n path: UserStoragePathWithFeatureOnly,\n ): Promise<void> {\n return this.#deleteUserStorageAllFeatureEntries(path);\n }\n\n async batchDeleteItems(\n path: UserStoragePathWithFeatureOnly,\n values: string[],\n ) {\n return this.#batchDeleteUserStorage(path, values);\n }\n\n async getStorageKey(): Promise<string> {\n const storageKey = await this.options.storage?.getStorageKey();\n if (storageKey) {\n return storageKey;\n }\n\n const userProfile = await this.config.auth.getUserProfile();\n const storageKeySignature = await this.config.auth.signMessage(\n `metamask:${userProfile.profileId}`,\n );\n const hashedStorageKeySignature = createSHA256Hash(storageKeySignature);\n await this.options.storage?.setStorageKey(hashedStorageKeySignature);\n return hashedStorageKeySignature;\n }\n\n async #upsertUserStorage(\n path: UserStoragePathWithFeatureAndKey,\n data: string,\n ): Promise<void> {\n try {\n const headers = await this.#getAuthorizationHeader();\n const storageKey = await this.getStorageKey();\n const encryptedData = await encryption.encryptString(data, storageKey);\n const encryptedPath = createEntryPath(path, storageKey);\n\n const url = new URL(STORAGE_URL(this.env, encryptedPath));\n\n const response = await fetch(url.toString(), {\n method: 'PUT',\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n body: JSON.stringify({ data: encryptedData }),\n });\n\n if (!response.ok) {\n const responseBody: ErrorMessage = await response.json().catch(() => ({\n message: 'unknown',\n error: 'unknown',\n }));\n throw new Error(\n `HTTP error message: ${responseBody.message}, error: ${responseBody.error}`,\n );\n }\n } catch (e) {\n /* istanbul ignore next */\n const errorMessage =\n e instanceof Error ? e.message : JSON.stringify(e ?? '');\n throw new UserStorageError(\n `failed to upsert user storage for path '${path}'. ${errorMessage}`,\n );\n }\n }\n\n async #batchUpsertUserStorage(\n path: UserStoragePathWithFeatureOnly,\n data: [string, string][],\n ): Promise<void> {\n try {\n if (!data.length) {\n return;\n }\n\n const headers = await this.#getAuthorizationHeader();\n const storageKey = await this.getStorageKey();\n\n const encryptedData = await Promise.all(\n data.map(async (d) => {\n return [\n this.#createEntryKey(d[0], storageKey),\n await encryption.encryptString(d[1], storageKey),\n ];\n }),\n );\n\n const url = new URL(STORAGE_URL(this.env, path));\n\n const response = await fetch(url.toString(), {\n method: 'PUT',\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n body: JSON.stringify({ data: Object.fromEntries(encryptedData) }),\n });\n\n if (!response.ok) {\n const responseBody: ErrorMessage = await response.json().catch(() => ({\n message: 'unknown',\n error: 'unknown',\n }));\n throw new Error(\n `HTTP error message: ${responseBody.message}, error: ${responseBody.error}`,\n );\n }\n } catch (e) {\n /* istanbul ignore next */\n const errorMessage =\n e instanceof Error ? e.message : JSON.stringify(e ?? '');\n throw new UserStorageError(\n `failed to batch upsert user storage for path '${path}'. ${errorMessage}`,\n );\n }\n }\n\n async #batchUpsertUserStorageWithAlreadyHashedAndEncryptedEntries(\n path: UserStoragePathWithFeatureOnly,\n encryptedData: [string, string][],\n ): Promise<void> {\n try {\n if (!encryptedData.length) {\n return;\n }\n\n const headers = await this.#getAuthorizationHeader();\n\n const url = new URL(STORAGE_URL(this.env, path));\n\n const response = await fetch(url.toString(), {\n method: 'PUT',\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n body: JSON.stringify({ data: Object.fromEntries(encryptedData) }),\n });\n\n if (!response.ok) {\n const responseBody: ErrorMessage = await response.json().catch(() => ({\n message: 'unknown',\n error: 'unknown',\n }));\n throw new Error(\n `HTTP error message: ${responseBody.message}, error: ${responseBody.error}`,\n );\n }\n } catch (e) {\n /* istanbul ignore next */\n const errorMessage =\n e instanceof Error ? e.message : JSON.stringify(e ?? '');\n throw new UserStorageError(\n `failed to batch upsert user storage for path '${path}'. ${errorMessage}`,\n );\n }\n }\n\n async #getUserStorage(\n path: UserStoragePathWithFeatureAndKey,\n ): Promise<string> {\n try {\n const headers = await this.#getAuthorizationHeader();\n const storageKey = await this.getStorageKey();\n const encryptedPath = createEntryPath(path, storageKey);\n\n const url = new URL(STORAGE_URL(this.env, encryptedPath));\n\n const response = await fetch(url.toString(), {\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n });\n\n if (response.status === 404) {\n throw new NotFoundError(\n `feature/key set not found for path '${path}'.`,\n );\n }\n\n if (!response.ok) {\n const responseBody = (await response.json()) as ErrorMessage;\n throw new Error(\n `HTTP error message: ${responseBody.message}, error: ${responseBody.error}`,\n );\n }\n\n const { Data: encryptedData } = await response.json();\n const decryptedData = await encryption.decryptString(\n encryptedData,\n storageKey,\n );\n\n // Re-encrypt the entry if it was encrypted with a random salt\n const salt = encryption.getSalt(encryptedData);\n if (salt.toString() !== SHARED_SALT.toString()) {\n await this.#upsertUserStorage(path, decryptedData);\n }\n\n return decryptedData;\n } catch (e) {\n if (e instanceof NotFoundError) {\n throw e;\n }\n\n /* istanbul ignore next */\n const errorMessage =\n e instanceof Error ? e.message : JSON.stringify(e ?? '');\n\n throw new UserStorageError(\n `failed to get user storage for path '${path}'. ${errorMessage}`,\n );\n }\n }\n\n async #getUserStorageAllFeatureEntries(\n path: UserStoragePathWithFeatureOnly,\n ): Promise<string[] | null> {\n try {\n const headers = await this.#getAuthorizationHeader();\n const storageKey = await this.getStorageKey();\n\n const url = new URL(STORAGE_URL(this.env, path));\n\n const response = await fetch(url.toString(), {\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n });\n\n if (response.status === 404) {\n throw new NotFoundError(`feature not found for path '${path}'.`);\n }\n\n if (!response.ok) {\n const responseBody = (await response.json()) as ErrorMessage;\n throw new Error(\n `HTTP error message: ${responseBody.message}, error: ${responseBody.error}`,\n );\n }\n\n const userStorage: GetUserStorageAllFeatureEntriesResponse | null =\n await response.json();\n\n if (!Array.isArray(userStorage)) {\n return null;\n }\n\n const decryptedData: string[] = [];\n const reEncryptedEntries: [string, string][] = [];\n\n for (const entry of userStorage) {\n if (!entry.Data) {\n continue;\n }\n\n try {\n const data = await encryption.decryptString(entry.Data, storageKey);\n decryptedData.push(data);\n\n // Re-encrypt the entry was encrypted with a random salt\n const salt = encryption.getSalt(entry.Data);\n if (salt.toString() !== SHARED_SALT.toString()) {\n reEncryptedEntries.push([\n entry.HashedKey,\n await encryption.encryptString(data, storageKey),\n ]);\n }\n } catch {\n // do nothing\n }\n }\n\n // Re-upload the re-encrypted entries\n if (reEncryptedEntries.length) {\n await this.#batchUpsertUserStorageWithAlreadyHashedAndEncryptedEntries(\n path,\n reEncryptedEntries,\n );\n }\n\n return decryptedData;\n } catch (e) {\n if (e instanceof NotFoundError) {\n throw e;\n }\n\n /* istanbul ignore next */\n const errorMessage =\n e instanceof Error ? e.message : JSON.stringify(e ?? '');\n\n throw new UserStorageError(\n `failed to get user storage for path '${path}'. ${errorMessage}`,\n );\n }\n }\n\n async #deleteUserStorage(\n path: UserStoragePathWithFeatureAndKey,\n ): Promise<void> {\n try {\n const headers = await this.#getAuthorizationHeader();\n const storageKey = await this.getStorageKey();\n const encryptedPath = createEntryPath(path, storageKey);\n\n const url = new URL(STORAGE_URL(this.env, encryptedPath));\n\n const response = await fetch(url.toString(), {\n method: 'DELETE',\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n });\n\n if (response.status === 404) {\n throw new NotFoundError(\n `feature/key set not found for path '${path}'.`,\n );\n }\n\n if (!response.ok) {\n const responseBody = (await response.json()) as ErrorMessage;\n throw new Error(\n `HTTP error message: ${responseBody.message}, error: ${responseBody.error}`,\n );\n }\n } catch (e) {\n if (e instanceof NotFoundError) {\n throw e;\n }\n\n /* istanbul ignore next */\n const errorMessage =\n e instanceof Error ? e.message : JSON.stringify(e ?? '');\n\n throw new UserStorageError(\n `failed to delete user storage for path '${path}'. ${errorMessage}`,\n );\n }\n }\n\n async #deleteUserStorageAllFeatureEntries(\n path: UserStoragePathWithFeatureOnly,\n ): Promise<void> {\n try {\n const headers = await this.#getAuthorizationHeader();\n\n const url = new URL(STORAGE_URL(this.env, path));\n\n const response = await fetch(url.toString(), {\n method: 'DELETE',\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n });\n\n if (response.status === 404) {\n throw new NotFoundError(`feature not found for path '${path}'.`);\n }\n\n if (!response.ok) {\n const responseBody = (await response.json()) as ErrorMessage;\n throw new Error(\n `HTTP error message: ${responseBody.message}, error: ${responseBody.error}`,\n );\n }\n } catch (e) {\n if (e instanceof NotFoundError) {\n throw e;\n }\n\n /* istanbul ignore next */\n const errorMessage =\n e instanceof Error ? e.message : JSON.stringify(e ?? '');\n\n throw new UserStorageError(\n `failed to delete user storage for path '${path}'. ${errorMessage}`,\n );\n }\n }\n\n async #batchDeleteUserStorage(\n path: UserStoragePathWithFeatureOnly,\n data: string[],\n ): Promise<void> {\n try {\n if (!data.length) {\n return;\n }\n\n const headers = await this.#getAuthorizationHeader();\n const storageKey = await this.getStorageKey();\n\n const encryptedData = await Promise.all(\n data.map(async (d) => this.#createEntryKey(d, storageKey)),\n );\n\n const url = new URL(STORAGE_URL(this.env, path));\n\n const response = await fetch(url.toString(), {\n method: 'PUT',\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n // eslint-disable-next-line @typescript-eslint/naming-convention\n body: JSON.stringify({ batch_delete: encryptedData }),\n });\n\n if (!response.ok) {\n const responseBody: ErrorMessage = await response.json().catch(() => ({\n message: 'unknown',\n error: 'unknown',\n }));\n throw new Error(\n `HTTP error message: ${responseBody.message}, error: ${responseBody.error}`,\n );\n }\n } catch (e) {\n /* istanbul ignore next */\n const errorMessage =\n e instanceof Error ? e.message : JSON.stringify(e ?? '');\n throw new UserStorageError(\n `failed to batch delete user storage for path '${path}'. ${errorMessage}`,\n );\n }\n }\n\n #createEntryKey(key: string, storageKey: string): string {\n const hashedKey = createSHA256Hash(key + storageKey);\n return hashedKey;\n }\n\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n async #getAuthorizationHeader(): Promise<{ Authorization: string }> {\n const accessToken = await this.config.auth.getAccessToken();\n return { Authorization: `Bearer ${accessToken}` };\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"user-storage.mjs","sourceRoot":"","sources":["../../src/sdk/user-storage.ts"],"names":[],"mappings":"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","sourcesContent":["import encryption, { createSHA256Hash } from '../shared/encryption';\nimport type { Env } from '../shared/env';\nimport { getEnvUrls } from '../shared/env';\nimport type {\n UserStorageFeatureKeys,\n UserStorageFeatureNames,\n UserStoragePathWithFeatureAndKey,\n UserStoragePathWithFeatureOnly,\n} from '../shared/storage-schema';\nimport { createEntryPath } from '../shared/storage-schema';\nimport type { IBaseAuth } from './authentication-jwt-bearer/types';\nimport { NotFoundError, UserStorageError } from './errors';\n\nexport const STORAGE_URL = (env: Env, encryptedPath: string) =>\n `${getEnvUrls(env).userStorageApiUrl}/api/v1/userstorage/${encryptedPath}`;\n\nexport type UserStorageConfig = {\n env: Env;\n auth: Pick<IBaseAuth, 'getAccessToken' | 'getUserProfile' | 'signMessage'>;\n};\n\nexport type StorageOptions = {\n getStorageKey: () => Promise<string | null>;\n setStorageKey: (val: string) => Promise<void>;\n};\n\nexport type UserStorageOptions = {\n storage?: StorageOptions;\n};\n\ntype GetUserStorageAllFeatureEntriesResponse = {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n HashedKey: string;\n // eslint-disable-next-line @typescript-eslint/naming-convention\n Data: string;\n}[];\n\ntype ErrorMessage = {\n message: string;\n error: string;\n};\n\nexport class UserStorage {\n protected config: UserStorageConfig;\n\n protected options: UserStorageOptions;\n\n protected env: Env;\n\n constructor(config: UserStorageConfig, options: UserStorageOptions) {\n this.env = config.env;\n this.config = config;\n this.options = options;\n }\n\n async setItem(\n path: UserStoragePathWithFeatureAndKey,\n value: string,\n ): Promise<void> {\n await this.#upsertUserStorage(path, value);\n }\n\n async batchSetItems<FeatureName extends UserStorageFeatureNames>(\n path: FeatureName,\n values: [UserStorageFeatureKeys<FeatureName>, string][],\n ) {\n await this.#batchUpsertUserStorage(path, values);\n }\n\n async getItem(path: UserStoragePathWithFeatureAndKey): Promise<string> {\n return this.#getUserStorage(path);\n }\n\n async getAllFeatureItems(\n path: UserStoragePathWithFeatureOnly,\n ): Promise<string[] | null> {\n return this.#getUserStorageAllFeatureEntries(path);\n }\n\n async deleteItem(path: UserStoragePathWithFeatureAndKey): Promise<void> {\n return this.#deleteUserStorage(path);\n }\n\n async deleteAllFeatureItems(\n path: UserStoragePathWithFeatureOnly,\n ): Promise<void> {\n return this.#deleteUserStorageAllFeatureEntries(path);\n }\n\n async batchDeleteItems<FeatureName extends UserStorageFeatureNames>(\n path: FeatureName,\n values: UserStorageFeatureKeys<FeatureName>[],\n ) {\n return this.#batchDeleteUserStorage(path, values);\n }\n\n async getStorageKey(): Promise<string> {\n const storageKey = await this.options.storage?.getStorageKey();\n if (storageKey) {\n return storageKey;\n }\n\n const userProfile = await this.config.auth.getUserProfile();\n const storageKeySignature = await this.config.auth.signMessage(\n `metamask:${userProfile.profileId}`,\n );\n const hashedStorageKeySignature = createSHA256Hash(storageKeySignature);\n await this.options.storage?.setStorageKey(hashedStorageKeySignature);\n return hashedStorageKeySignature;\n }\n\n async #upsertUserStorage(\n path: UserStoragePathWithFeatureAndKey,\n data: string,\n ): Promise<void> {\n try {\n const headers = await this.#getAuthorizationHeader();\n const storageKey = await this.getStorageKey();\n const encryptedData = await encryption.encryptString(data, storageKey);\n const encryptedPath = createEntryPath(path, storageKey);\n\n const url = new URL(STORAGE_URL(this.env, encryptedPath));\n\n const response = await fetch(url.toString(), {\n method: 'PUT',\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n body: JSON.stringify({ data: encryptedData }),\n });\n\n if (!response.ok) {\n const responseBody: ErrorMessage = await response.json().catch(() => ({\n message: 'unknown',\n error: 'unknown',\n }));\n throw new Error(\n `HTTP error message: ${responseBody.message}, error: ${responseBody.error}`,\n );\n }\n } catch (e) {\n /* istanbul ignore next */\n const errorMessage =\n e instanceof Error ? e.message : JSON.stringify(e ?? '');\n throw new UserStorageError(\n `failed to upsert user storage for path '${path}'. ${errorMessage}`,\n );\n }\n }\n\n async #batchUpsertUserStorage<FeatureName extends UserStorageFeatureNames>(\n path: FeatureName,\n data: [UserStorageFeatureKeys<FeatureName>, string][],\n ): Promise<void> {\n try {\n if (!data.length) {\n return;\n }\n\n const headers = await this.#getAuthorizationHeader();\n const storageKey = await this.getStorageKey();\n\n const encryptedData = await Promise.all(\n data.map(async (d) => {\n return [\n this.#createEntryKey(d[0], storageKey),\n await encryption.encryptString(d[1], storageKey),\n ];\n }),\n );\n\n const url = new URL(STORAGE_URL(this.env, path));\n\n const response = await fetch(url.toString(), {\n method: 'PUT',\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n body: JSON.stringify({ data: Object.fromEntries(encryptedData) }),\n });\n\n if (!response.ok) {\n const responseBody: ErrorMessage = await response.json().catch(() => ({\n message: 'unknown',\n error: 'unknown',\n }));\n throw new Error(\n `HTTP error message: ${responseBody.message}, error: ${responseBody.error}`,\n );\n }\n } catch (e) {\n /* istanbul ignore next */\n const errorMessage =\n e instanceof Error ? e.message : JSON.stringify(e ?? '');\n throw new UserStorageError(\n `failed to batch upsert user storage for path '${path}'. ${errorMessage}`,\n );\n }\n }\n\n async #getUserStorage(\n path: UserStoragePathWithFeatureAndKey,\n ): Promise<string> {\n try {\n const headers = await this.#getAuthorizationHeader();\n const storageKey = await this.getStorageKey();\n const encryptedPath = createEntryPath(path, storageKey);\n\n const url = new URL(STORAGE_URL(this.env, encryptedPath));\n\n const response = await fetch(url.toString(), {\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n });\n\n if (response.status === 404) {\n throw new NotFoundError(\n `feature/key set not found for path '${path}'.`,\n );\n }\n\n if (!response.ok) {\n const responseBody = (await response.json()) as ErrorMessage;\n throw new Error(\n `HTTP error message: ${responseBody.message}, error: ${responseBody.error}`,\n );\n }\n\n const { Data: encryptedData } = await response.json();\n return encryption.decryptString(encryptedData, storageKey);\n } catch (e) {\n if (e instanceof NotFoundError) {\n throw e;\n }\n\n /* istanbul ignore next */\n const errorMessage =\n e instanceof Error ? e.message : JSON.stringify(e ?? '');\n\n throw new UserStorageError(\n `failed to get user storage for path '${path}'. ${errorMessage}`,\n );\n }\n }\n\n async #getUserStorageAllFeatureEntries(\n path: UserStoragePathWithFeatureOnly,\n ): Promise<string[] | null> {\n try {\n const headers = await this.#getAuthorizationHeader();\n const storageKey = await this.getStorageKey();\n\n const url = new URL(STORAGE_URL(this.env, path));\n\n const response = await fetch(url.toString(), {\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n });\n\n if (response.status === 404) {\n throw new NotFoundError(`feature not found for path '${path}'.`);\n }\n\n if (!response.ok) {\n const responseBody = (await response.json()) as ErrorMessage;\n throw new Error(\n `HTTP error message: ${responseBody.message}, error: ${responseBody.error}`,\n );\n }\n\n const userStorage: GetUserStorageAllFeatureEntriesResponse | null =\n await response.json();\n\n if (!Array.isArray(userStorage)) {\n return null;\n }\n\n const decryptedData = userStorage.flatMap((entry) => {\n if (!entry.Data) {\n return [];\n }\n\n return encryption.decryptString(entry.Data, storageKey);\n });\n\n return (await Promise.allSettled(decryptedData))\n .map((d) => (d.status === 'fulfilled' ? d.value : undefined))\n .filter((d): d is string => d !== undefined);\n } catch (e) {\n if (e instanceof NotFoundError) {\n throw e;\n }\n\n /* istanbul ignore next */\n const errorMessage =\n e instanceof Error ? e.message : JSON.stringify(e ?? '');\n\n throw new UserStorageError(\n `failed to get user storage for path '${path}'. ${errorMessage}`,\n );\n }\n }\n\n async #deleteUserStorage(\n path: UserStoragePathWithFeatureAndKey,\n ): Promise<void> {\n try {\n const headers = await this.#getAuthorizationHeader();\n const storageKey = await this.getStorageKey();\n const encryptedPath = createEntryPath(path, storageKey);\n\n const url = new URL(STORAGE_URL(this.env, encryptedPath));\n\n const response = await fetch(url.toString(), {\n method: 'DELETE',\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n });\n\n if (response.status === 404) {\n throw new NotFoundError(\n `feature/key set not found for path '${path}'.`,\n );\n }\n\n if (!response.ok) {\n const responseBody = (await response.json()) as ErrorMessage;\n throw new Error(\n `HTTP error message: ${responseBody.message}, error: ${responseBody.error}`,\n );\n }\n } catch (e) {\n if (e instanceof NotFoundError) {\n throw e;\n }\n\n /* istanbul ignore next */\n const errorMessage =\n e instanceof Error ? e.message : JSON.stringify(e ?? '');\n\n throw new UserStorageError(\n `failed to delete user storage for path '${path}'. ${errorMessage}`,\n );\n }\n }\n\n async #deleteUserStorageAllFeatureEntries(\n path: UserStoragePathWithFeatureOnly,\n ): Promise<void> {\n try {\n const headers = await this.#getAuthorizationHeader();\n\n const url = new URL(STORAGE_URL(this.env, path));\n\n const response = await fetch(url.toString(), {\n method: 'DELETE',\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n });\n\n if (response.status === 404) {\n throw new NotFoundError(`feature not found for path '${path}'.`);\n }\n\n if (!response.ok) {\n const responseBody = (await response.json()) as ErrorMessage;\n throw new Error(\n `HTTP error message: ${responseBody.message}, error: ${responseBody.error}`,\n );\n }\n } catch (e) {\n if (e instanceof NotFoundError) {\n throw e;\n }\n\n /* istanbul ignore next */\n const errorMessage =\n e instanceof Error ? e.message : JSON.stringify(e ?? '');\n\n throw new UserStorageError(\n `failed to delete user storage for path '${path}'. ${errorMessage}`,\n );\n }\n }\n\n async #batchDeleteUserStorage<FeatureName extends UserStorageFeatureNames>(\n path: FeatureName,\n data: UserStorageFeatureKeys<FeatureName>[],\n ): Promise<void> {\n try {\n if (!data.length) {\n return;\n }\n\n const headers = await this.#getAuthorizationHeader();\n const storageKey = await this.getStorageKey();\n\n const encryptedData = await Promise.all(\n data.map(async (d) => this.#createEntryKey(d, storageKey)),\n );\n\n const url = new URL(STORAGE_URL(this.env, path));\n\n const response = await fetch(url.toString(), {\n method: 'PUT',\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n // eslint-disable-next-line @typescript-eslint/naming-convention\n body: JSON.stringify({ batch_delete: encryptedData }),\n });\n\n if (!response.ok) {\n const responseBody: ErrorMessage = await response.json().catch(() => ({\n message: 'unknown',\n error: 'unknown',\n }));\n throw new Error(\n `HTTP error message: ${responseBody.message}, error: ${responseBody.error}`,\n );\n }\n } catch (e) {\n /* istanbul ignore next */\n const errorMessage =\n e instanceof Error ? e.message : JSON.stringify(e ?? '');\n throw new UserStorageError(\n `failed to batch delete user storage for path '${path}'. ${errorMessage}`,\n );\n }\n }\n\n #createEntryKey(key: string, storageKey: string): string {\n const hashedKey = createSHA256Hash(key + storageKey);\n return hashedKey;\n }\n\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n async #getAuthorizationHeader(): Promise<{ Authorization: string }> {\n const accessToken = await this.config.auth.getAccessToken();\n return { Authorization: `Bearer ${accessToken}` };\n }\n}\n"]}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.setCachedKey = exports.
|
|
4
|
-
const constants_1 = require("./constants.cjs");
|
|
3
|
+
exports.setCachedKey = exports.getAnyCachedKey = exports.getCachedKeyBySalt = void 0;
|
|
5
4
|
const utils_1 = require("./utils.cjs");
|
|
6
5
|
const MAX_PASSWORD_CACHES = 100;
|
|
7
6
|
const MAX_SALT_CACHES = 100;
|
|
@@ -32,26 +31,29 @@ function getCachedKeyBySalt(hashedPassword, salt) {
|
|
|
32
31
|
}
|
|
33
32
|
exports.getCachedKeyBySalt = getCachedKeyBySalt;
|
|
34
33
|
/**
|
|
35
|
-
* Gets
|
|
36
|
-
* This is unique per hashed password.
|
|
34
|
+
* Gets any cached key for a given hashed password
|
|
37
35
|
*
|
|
38
36
|
* @param hashedPassword - hashed password for cache lookup
|
|
39
|
-
* @returns the cached key
|
|
37
|
+
* @returns any (the first) cached key
|
|
40
38
|
*/
|
|
41
|
-
function
|
|
39
|
+
function getAnyCachedKey(hashedPassword) {
|
|
42
40
|
const cache = getPasswordCache(hashedPassword);
|
|
43
|
-
|
|
44
|
-
const
|
|
45
|
-
|
|
41
|
+
// Takes 1 item from an Iterator via Map.entries()
|
|
42
|
+
const cachedEntry = cache
|
|
43
|
+
.entries()
|
|
44
|
+
.next().value;
|
|
45
|
+
if (!cachedEntry) {
|
|
46
46
|
return undefined;
|
|
47
47
|
}
|
|
48
|
+
const base64Salt = cachedEntry[0];
|
|
49
|
+
const bytesSalt = (0, utils_1.base64ToByteArray)(base64Salt);
|
|
48
50
|
return {
|
|
49
|
-
salt:
|
|
51
|
+
salt: bytesSalt,
|
|
50
52
|
base64Salt,
|
|
51
|
-
key:
|
|
53
|
+
key: cachedEntry[1],
|
|
52
54
|
};
|
|
53
55
|
}
|
|
54
|
-
exports.
|
|
56
|
+
exports.getAnyCachedKey = getAnyCachedKey;
|
|
55
57
|
/**
|
|
56
58
|
* Sets a key to the in memory cache.
|
|
57
59
|
* We have set an arbitrary size of 10 cached keys per hashed password.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.cjs","sourceRoot":"","sources":["../../../src/shared/encryption/cache.ts"],"names":[],"mappings":";;;AAAA
|
|
1
|
+
{"version":3,"file":"cache.cjs","sourceRoot":"","sources":["../../../src/shared/encryption/cache.ts"],"names":[],"mappings":";;;AAAA,uCAA+D;AAQ/D,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAChC,MAAM,eAAe,GAAG,GAAG,CAAC;AAQ5B,IAAI,cAAc,GAAyB,EAAE,CAAC;AAC9C,MAAM,gBAAgB,GAAG,CAAC,cAAsB,EAAE,EAAE;IAClD,cAAc,CAAC,cAAc,MAA7B,cAAc,CAAC,cAAc,IAAM,IAAI,GAAG,EAAE,EAAC;IAC7C,OAAO,cAAc,CAAC,cAAc,CAAC,CAAC;AACxC,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,SAAgB,kBAAkB,CAChC,cAAsB,EACtB,IAAgB;IAEhB,MAAM,KAAK,GAAG,gBAAgB,CAAC,cAAc,CAAC,CAAC;IAC/C,MAAM,UAAU,GAAG,IAAA,yBAAiB,EAAC,IAAI,CAAC,CAAC;IAC3C,MAAM,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACxC,IAAI,CAAC,SAAS,EAAE;QACd,OAAO,SAAS,CAAC;KAClB;IAED,OAAO;QACL,IAAI;QACJ,UAAU;QACV,GAAG,EAAE,SAAS;KACf,CAAC;AACJ,CAAC;AAhBD,gDAgBC;AAED;;;;;GAKG;AACH,SAAgB,eAAe,CAC7B,cAAsB;IAEtB,MAAM,KAAK,GAAG,gBAAgB,CAAC,cAAc,CAAC,CAAC;IAE/C,kDAAkD;IAClD,MAAM,WAAW,GAAqC,KAAK;SACxD,OAAO,EAAE;SACT,IAAI,EAAE,CAAC,KAAK,CAAC;IAEhB,IAAI,CAAC,WAAW,EAAE;QAChB,OAAO,SAAS,CAAC;KAClB;IAED,MAAM,UAAU,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;IAClC,MAAM,SAAS,GAAG,IAAA,yBAAiB,EAAC,UAAU,CAAC,CAAC;IAChD,OAAO;QACL,IAAI,EAAE,SAAS;QACf,UAAU;QACV,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC;KACpB,CAAC;AACJ,CAAC;AArBD,0CAqBC;AAED;;;;;;;GAOG;AACH,SAAgB,YAAY,CAC1B,cAAsB,EACtB,IAAgB,EAChB,GAAe;IAEf,sBAAsB;IACtB,IAAI,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,MAAM,GAAG,mBAAmB,EAAE;QAC5D,cAAc,GAAG,EAAE,CAAC;KACrB;IAED,MAAM,KAAK,GAAG,gBAAgB,CAAC,cAAc,CAAC,CAAC;IAC/C,MAAM,UAAU,GAAG,IAAA,yBAAiB,EAAC,IAAI,CAAC,CAAC;IAE3C,kBAAkB;IAClB,IAAI,KAAK,CAAC,IAAI,GAAG,eAAe,EAAE;QAChC,KAAK,CAAC,KAAK,EAAE,CAAC;KACf;IAED,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;AAC7B,CAAC;AAnBD,oCAmBC","sourcesContent":["import { base64ToByteArray, byteArrayToBase64 } from './utils';\n\ntype CachedEntry = {\n salt: Uint8Array;\n base64Salt: string;\n key: Uint8Array;\n};\n\nconst MAX_PASSWORD_CACHES = 100;\nconst MAX_SALT_CACHES = 100;\n\n/**\n * In-Memory Caching derived keys based from a given salt and password.\n */\ntype PasswordMemCachedKDF = {\n [hashedPassword: string]: Map<string, Uint8Array>;\n};\nlet inMemCachedKDF: PasswordMemCachedKDF = {};\nconst getPasswordCache = (hashedPassword: string) => {\n inMemCachedKDF[hashedPassword] ??= new Map();\n return inMemCachedKDF[hashedPassword];\n};\n\n/**\n * Returns a given cached derived key from a hashed password and salt\n *\n * @param hashedPassword - hashed password for cache lookup\n * @param salt - provide salt to receive cached key\n * @returns cached key\n */\nexport function getCachedKeyBySalt(\n hashedPassword: string,\n salt: Uint8Array,\n): CachedEntry | undefined {\n const cache = getPasswordCache(hashedPassword);\n const base64Salt = byteArrayToBase64(salt);\n const cachedKey = cache.get(base64Salt);\n if (!cachedKey) {\n return undefined;\n }\n\n return {\n salt,\n base64Salt,\n key: cachedKey,\n };\n}\n\n/**\n * Gets any cached key for a given hashed password\n *\n * @param hashedPassword - hashed password for cache lookup\n * @returns any (the first) cached key\n */\nexport function getAnyCachedKey(\n hashedPassword: string,\n): CachedEntry | undefined {\n const cache = getPasswordCache(hashedPassword);\n\n // Takes 1 item from an Iterator via Map.entries()\n const cachedEntry: [string, Uint8Array] | undefined = cache\n .entries()\n .next().value;\n\n if (!cachedEntry) {\n return undefined;\n }\n\n const base64Salt = cachedEntry[0];\n const bytesSalt = base64ToByteArray(base64Salt);\n return {\n salt: bytesSalt,\n base64Salt,\n key: cachedEntry[1],\n };\n}\n\n/**\n * Sets a key to the in memory cache.\n * We have set an arbitrary size of 10 cached keys per hashed password.\n *\n * @param hashedPassword - hashed password for cache lookup\n * @param salt - salt to set new derived key\n * @param key - derived key we are setting\n */\nexport function setCachedKey(\n hashedPassword: string,\n salt: Uint8Array,\n key: Uint8Array,\n): void {\n // Max password caches\n if (Object.keys(inMemCachedKDF).length > MAX_PASSWORD_CACHES) {\n inMemCachedKDF = {};\n }\n\n const cache = getPasswordCache(hashedPassword);\n const base64Salt = byteArrayToBase64(salt);\n\n // Max salt caches\n if (cache.size > MAX_SALT_CACHES) {\n cache.clear();\n }\n\n cache.set(base64Salt, key);\n}\n"]}
|
|
@@ -12,13 +12,12 @@ type CachedEntry = {
|
|
|
12
12
|
*/
|
|
13
13
|
export declare function getCachedKeyBySalt(hashedPassword: string, salt: Uint8Array): CachedEntry | undefined;
|
|
14
14
|
/**
|
|
15
|
-
* Gets
|
|
16
|
-
* This is unique per hashed password.
|
|
15
|
+
* Gets any cached key for a given hashed password
|
|
17
16
|
*
|
|
18
17
|
* @param hashedPassword - hashed password for cache lookup
|
|
19
|
-
* @returns the cached key
|
|
18
|
+
* @returns any (the first) cached key
|
|
20
19
|
*/
|
|
21
|
-
export declare function
|
|
20
|
+
export declare function getAnyCachedKey(hashedPassword: string): CachedEntry | undefined;
|
|
22
21
|
/**
|
|
23
22
|
* Sets a key to the in memory cache.
|
|
24
23
|
* We have set an arbitrary size of 10 cached keys per hashed password.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.d.cts","sourceRoot":"","sources":["../../../src/shared/encryption/cache.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cache.d.cts","sourceRoot":"","sources":["../../../src/shared/encryption/cache.ts"],"names":[],"mappings":"AAEA,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,UAAU,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,UAAU,CAAC;CACjB,CAAC;AAiBF;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,cAAc,EAAE,MAAM,EACtB,IAAI,EAAE,UAAU,GACf,WAAW,GAAG,SAAS,CAazB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,cAAc,EAAE,MAAM,GACrB,WAAW,GAAG,SAAS,CAmBzB;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,cAAc,EAAE,MAAM,EACtB,IAAI,EAAE,UAAU,EAChB,GAAG,EAAE,UAAU,GACd,IAAI,CAeN"}
|
|
@@ -12,13 +12,12 @@ type CachedEntry = {
|
|
|
12
12
|
*/
|
|
13
13
|
export declare function getCachedKeyBySalt(hashedPassword: string, salt: Uint8Array): CachedEntry | undefined;
|
|
14
14
|
/**
|
|
15
|
-
* Gets
|
|
16
|
-
* This is unique per hashed password.
|
|
15
|
+
* Gets any cached key for a given hashed password
|
|
17
16
|
*
|
|
18
17
|
* @param hashedPassword - hashed password for cache lookup
|
|
19
|
-
* @returns the cached key
|
|
18
|
+
* @returns any (the first) cached key
|
|
20
19
|
*/
|
|
21
|
-
export declare function
|
|
20
|
+
export declare function getAnyCachedKey(hashedPassword: string): CachedEntry | undefined;
|
|
22
21
|
/**
|
|
23
22
|
* Sets a key to the in memory cache.
|
|
24
23
|
* We have set an arbitrary size of 10 cached keys per hashed password.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.d.mts","sourceRoot":"","sources":["../../../src/shared/encryption/cache.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cache.d.mts","sourceRoot":"","sources":["../../../src/shared/encryption/cache.ts"],"names":[],"mappings":"AAEA,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,UAAU,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,UAAU,CAAC;CACjB,CAAC;AAiBF;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,cAAc,EAAE,MAAM,EACtB,IAAI,EAAE,UAAU,GACf,WAAW,GAAG,SAAS,CAazB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,cAAc,EAAE,MAAM,GACrB,WAAW,GAAG,SAAS,CAmBzB;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,cAAc,EAAE,MAAM,EACtB,IAAI,EAAE,UAAU,EAChB,GAAG,EAAE,UAAU,GACd,IAAI,CAeN"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { byteArrayToBase64 } from "./utils.mjs";
|
|
1
|
+
import { base64ToByteArray, byteArrayToBase64 } from "./utils.mjs";
|
|
3
2
|
const MAX_PASSWORD_CACHES = 100;
|
|
4
3
|
const MAX_SALT_CACHES = 100;
|
|
5
4
|
let inMemCachedKDF = {};
|
|
@@ -28,23 +27,26 @@ export function getCachedKeyBySalt(hashedPassword, salt) {
|
|
|
28
27
|
};
|
|
29
28
|
}
|
|
30
29
|
/**
|
|
31
|
-
* Gets
|
|
32
|
-
* This is unique per hashed password.
|
|
30
|
+
* Gets any cached key for a given hashed password
|
|
33
31
|
*
|
|
34
32
|
* @param hashedPassword - hashed password for cache lookup
|
|
35
|
-
* @returns the cached key
|
|
33
|
+
* @returns any (the first) cached key
|
|
36
34
|
*/
|
|
37
|
-
export function
|
|
35
|
+
export function getAnyCachedKey(hashedPassword) {
|
|
38
36
|
const cache = getPasswordCache(hashedPassword);
|
|
39
|
-
|
|
40
|
-
const
|
|
41
|
-
|
|
37
|
+
// Takes 1 item from an Iterator via Map.entries()
|
|
38
|
+
const cachedEntry = cache
|
|
39
|
+
.entries()
|
|
40
|
+
.next().value;
|
|
41
|
+
if (!cachedEntry) {
|
|
42
42
|
return undefined;
|
|
43
43
|
}
|
|
44
|
+
const base64Salt = cachedEntry[0];
|
|
45
|
+
const bytesSalt = base64ToByteArray(base64Salt);
|
|
44
46
|
return {
|
|
45
|
-
salt:
|
|
47
|
+
salt: bytesSalt,
|
|
46
48
|
base64Salt,
|
|
47
|
-
key:
|
|
49
|
+
key: cachedEntry[1],
|
|
48
50
|
};
|
|
49
51
|
}
|
|
50
52
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.mjs","sourceRoot":"","sources":["../../../src/shared/encryption/cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"cache.mjs","sourceRoot":"","sources":["../../../src/shared/encryption/cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,oBAAgB;AAQ/D,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAChC,MAAM,eAAe,GAAG,GAAG,CAAC;AAQ5B,IAAI,cAAc,GAAyB,EAAE,CAAC;AAC9C,MAAM,gBAAgB,GAAG,CAAC,cAAsB,EAAE,EAAE;IAClD,cAAc,CAAC,cAAc,MAA7B,cAAc,CAAC,cAAc,IAAM,IAAI,GAAG,EAAE,EAAC;IAC7C,OAAO,cAAc,CAAC,cAAc,CAAC,CAAC;AACxC,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAChC,cAAsB,EACtB,IAAgB;IAEhB,MAAM,KAAK,GAAG,gBAAgB,CAAC,cAAc,CAAC,CAAC;IAC/C,MAAM,UAAU,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAC3C,MAAM,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACxC,IAAI,CAAC,SAAS,EAAE;QACd,OAAO,SAAS,CAAC;KAClB;IAED,OAAO;QACL,IAAI;QACJ,UAAU;QACV,GAAG,EAAE,SAAS;KACf,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAC7B,cAAsB;IAEtB,MAAM,KAAK,GAAG,gBAAgB,CAAC,cAAc,CAAC,CAAC;IAE/C,kDAAkD;IAClD,MAAM,WAAW,GAAqC,KAAK;SACxD,OAAO,EAAE;SACT,IAAI,EAAE,CAAC,KAAK,CAAC;IAEhB,IAAI,CAAC,WAAW,EAAE;QAChB,OAAO,SAAS,CAAC;KAClB;IAED,MAAM,UAAU,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;IAClC,MAAM,SAAS,GAAG,iBAAiB,CAAC,UAAU,CAAC,CAAC;IAChD,OAAO;QACL,IAAI,EAAE,SAAS;QACf,UAAU;QACV,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC;KACpB,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAC1B,cAAsB,EACtB,IAAgB,EAChB,GAAe;IAEf,sBAAsB;IACtB,IAAI,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,MAAM,GAAG,mBAAmB,EAAE;QAC5D,cAAc,GAAG,EAAE,CAAC;KACrB;IAED,MAAM,KAAK,GAAG,gBAAgB,CAAC,cAAc,CAAC,CAAC;IAC/C,MAAM,UAAU,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAE3C,kBAAkB;IAClB,IAAI,KAAK,CAAC,IAAI,GAAG,eAAe,EAAE;QAChC,KAAK,CAAC,KAAK,EAAE,CAAC;KACf;IAED,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;AAC7B,CAAC","sourcesContent":["import { base64ToByteArray, byteArrayToBase64 } from './utils';\n\ntype CachedEntry = {\n salt: Uint8Array;\n base64Salt: string;\n key: Uint8Array;\n};\n\nconst MAX_PASSWORD_CACHES = 100;\nconst MAX_SALT_CACHES = 100;\n\n/**\n * In-Memory Caching derived keys based from a given salt and password.\n */\ntype PasswordMemCachedKDF = {\n [hashedPassword: string]: Map<string, Uint8Array>;\n};\nlet inMemCachedKDF: PasswordMemCachedKDF = {};\nconst getPasswordCache = (hashedPassword: string) => {\n inMemCachedKDF[hashedPassword] ??= new Map();\n return inMemCachedKDF[hashedPassword];\n};\n\n/**\n * Returns a given cached derived key from a hashed password and salt\n *\n * @param hashedPassword - hashed password for cache lookup\n * @param salt - provide salt to receive cached key\n * @returns cached key\n */\nexport function getCachedKeyBySalt(\n hashedPassword: string,\n salt: Uint8Array,\n): CachedEntry | undefined {\n const cache = getPasswordCache(hashedPassword);\n const base64Salt = byteArrayToBase64(salt);\n const cachedKey = cache.get(base64Salt);\n if (!cachedKey) {\n return undefined;\n }\n\n return {\n salt,\n base64Salt,\n key: cachedKey,\n };\n}\n\n/**\n * Gets any cached key for a given hashed password\n *\n * @param hashedPassword - hashed password for cache lookup\n * @returns any (the first) cached key\n */\nexport function getAnyCachedKey(\n hashedPassword: string,\n): CachedEntry | undefined {\n const cache = getPasswordCache(hashedPassword);\n\n // Takes 1 item from an Iterator via Map.entries()\n const cachedEntry: [string, Uint8Array] | undefined = cache\n .entries()\n .next().value;\n\n if (!cachedEntry) {\n return undefined;\n }\n\n const base64Salt = cachedEntry[0];\n const bytesSalt = base64ToByteArray(base64Salt);\n return {\n salt: bytesSalt,\n base64Salt,\n key: cachedEntry[1],\n };\n}\n\n/**\n * Sets a key to the in memory cache.\n * We have set an arbitrary size of 10 cached keys per hashed password.\n *\n * @param hashedPassword - hashed password for cache lookup\n * @param salt - salt to set new derived key\n * @param key - derived key we are setting\n */\nexport function setCachedKey(\n hashedPassword: string,\n salt: Uint8Array,\n key: Uint8Array,\n): void {\n // Max password caches\n if (Object.keys(inMemCachedKDF).length > MAX_PASSWORD_CACHES) {\n inMemCachedKDF = {};\n }\n\n const cache = getPasswordCache(hashedPassword);\n const base64Salt = byteArrayToBase64(salt);\n\n // Max salt caches\n if (cache.size > MAX_SALT_CACHES) {\n cache.clear();\n }\n\n cache.set(base64Salt, key);\n}\n"]}
|
|
@@ -13,8 +13,18 @@ const scrypt_1 = require("@noble/hashes/scrypt");
|
|
|
13
13
|
const sha256_1 = require("@noble/hashes/sha256");
|
|
14
14
|
const utils_1 = require("@noble/hashes/utils");
|
|
15
15
|
const cache_1 = require("./cache.cjs");
|
|
16
|
-
const constants_1 = require("./constants.cjs");
|
|
17
16
|
const utils_2 = require("./utils.cjs");
|
|
17
|
+
// Nonce/Key Sizes
|
|
18
|
+
const ALGORITHM_NONCE_SIZE = 12; // 12 bytes
|
|
19
|
+
const ALGORITHM_KEY_SIZE = 16; // 16 bytes
|
|
20
|
+
// Scrypt settings
|
|
21
|
+
// see: https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#scrypt
|
|
22
|
+
const SCRYPT_SALT_SIZE = 16; // 16 bytes
|
|
23
|
+
const SCRYPT_N = 2 ** 17; // CPU/memory cost parameter (must be a power of 2, > 1)
|
|
24
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
25
|
+
const SCRYPT_r = 8; // Block size parameter
|
|
26
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
27
|
+
const SCRYPT_p = 1; // Parallelization parameter
|
|
18
28
|
class EncryptorDecryptor {
|
|
19
29
|
constructor() {
|
|
20
30
|
_EncryptorDecryptor_instances.add(this);
|
|
@@ -43,47 +53,13 @@ class EncryptorDecryptor {
|
|
|
43
53
|
throw new Error(`Unable to decrypt string - ${errorMessage}`);
|
|
44
54
|
}
|
|
45
55
|
}
|
|
46
|
-
getSalt(encryptedDataStr) {
|
|
47
|
-
try {
|
|
48
|
-
const encryptedData = JSON.parse(encryptedDataStr);
|
|
49
|
-
if (encryptedData.v === '1') {
|
|
50
|
-
if (encryptedData.t === 'scrypt') {
|
|
51
|
-
const { d: base64CiphertextAndNonceAndSalt, saltLen } = encryptedData;
|
|
52
|
-
// Decode the base64.
|
|
53
|
-
const ciphertextAndNonceAndSalt = (0, utils_2.base64ToByteArray)(base64CiphertextAndNonceAndSalt);
|
|
54
|
-
// Create buffers of salt and ciphertextAndNonce.
|
|
55
|
-
const salt = ciphertextAndNonceAndSalt.slice(0, saltLen);
|
|
56
|
-
return salt;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
throw new Error(`Unsupported encrypted data payload - ${encryptedDataStr}`);
|
|
60
|
-
}
|
|
61
|
-
catch (e) {
|
|
62
|
-
const errorMessage = e instanceof Error ? e.message : JSON.stringify(e);
|
|
63
|
-
throw new Error(`Unable to get salt - ${errorMessage}`);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
getIfEntriesHaveDifferentSalts(entries) {
|
|
67
|
-
const salts = entries
|
|
68
|
-
.map((e) => {
|
|
69
|
-
try {
|
|
70
|
-
return this.getSalt(e);
|
|
71
|
-
}
|
|
72
|
-
catch {
|
|
73
|
-
return undefined;
|
|
74
|
-
}
|
|
75
|
-
})
|
|
76
|
-
.filter((s) => s !== undefined);
|
|
77
|
-
const strSet = new Set(salts.map((arr) => arr.toString()));
|
|
78
|
-
return strSet.size === salts.length;
|
|
79
|
-
}
|
|
80
56
|
}
|
|
81
57
|
_EncryptorDecryptor_instances = new WeakSet(), _EncryptorDecryptor_encryptStringV1 = async function _EncryptorDecryptor_encryptStringV1(plaintext, password, nativeScryptCrypto) {
|
|
82
58
|
const { key, salt } = await __classPrivateFieldGet(this, _EncryptorDecryptor_instances, "m", _EncryptorDecryptor_getOrGenerateScryptKey).call(this, password, {
|
|
83
|
-
N:
|
|
84
|
-
r:
|
|
85
|
-
p:
|
|
86
|
-
dkLen:
|
|
59
|
+
N: SCRYPT_N,
|
|
60
|
+
r: SCRYPT_r,
|
|
61
|
+
p: SCRYPT_p,
|
|
62
|
+
dkLen: ALGORITHM_KEY_SIZE,
|
|
87
63
|
}, undefined, nativeScryptCrypto);
|
|
88
64
|
// Encrypt and prepend salt.
|
|
89
65
|
const plaintextRaw = (0, utils_1.utf8ToBytes)(plaintext);
|
|
@@ -95,12 +71,12 @@ _EncryptorDecryptor_instances = new WeakSet(), _EncryptorDecryptor_encryptString
|
|
|
95
71
|
t: 'scrypt',
|
|
96
72
|
d: encryptedData,
|
|
97
73
|
o: {
|
|
98
|
-
N:
|
|
99
|
-
r:
|
|
100
|
-
p:
|
|
101
|
-
dkLen:
|
|
74
|
+
N: SCRYPT_N,
|
|
75
|
+
r: SCRYPT_r,
|
|
76
|
+
p: SCRYPT_p,
|
|
77
|
+
dkLen: ALGORITHM_KEY_SIZE,
|
|
102
78
|
},
|
|
103
|
-
saltLen:
|
|
79
|
+
saltLen: SCRYPT_SALT_SIZE,
|
|
104
80
|
};
|
|
105
81
|
return JSON.stringify(encryptedPayload);
|
|
106
82
|
}, _EncryptorDecryptor_decryptStringV1 = async function _EncryptorDecryptor_decryptStringV1(data, password, nativeScryptCrypto) {
|
|
@@ -120,28 +96,28 @@ _EncryptorDecryptor_instances = new WeakSet(), _EncryptorDecryptor_encryptString
|
|
|
120
96
|
// Decrypt and return result.
|
|
121
97
|
return (0, utils_2.bytesToUtf8)(__classPrivateFieldGet(this, _EncryptorDecryptor_instances, "m", _EncryptorDecryptor_decrypt).call(this, ciphertextAndNonce, key));
|
|
122
98
|
}, _EncryptorDecryptor_encrypt = function _EncryptorDecryptor_encrypt(plaintext, key) {
|
|
123
|
-
const nonce = (0, webcrypto_1.randomBytes)(
|
|
99
|
+
const nonce = (0, webcrypto_1.randomBytes)(ALGORITHM_NONCE_SIZE);
|
|
124
100
|
// Encrypt and prepend nonce.
|
|
125
101
|
const ciphertext = (0, aes_1.gcm)(key, nonce).encrypt(plaintext);
|
|
126
102
|
return (0, utils_1.concatBytes)(nonce, ciphertext);
|
|
127
103
|
}, _EncryptorDecryptor_decrypt = function _EncryptorDecryptor_decrypt(ciphertextAndNonce, key) {
|
|
128
104
|
// Create buffers of nonce and ciphertext.
|
|
129
|
-
const nonce = ciphertextAndNonce.slice(0,
|
|
130
|
-
const ciphertext = ciphertextAndNonce.slice(
|
|
105
|
+
const nonce = ciphertextAndNonce.slice(0, ALGORITHM_NONCE_SIZE);
|
|
106
|
+
const ciphertext = ciphertextAndNonce.slice(ALGORITHM_NONCE_SIZE, ciphertextAndNonce.length);
|
|
131
107
|
// Decrypt and return result.
|
|
132
108
|
return (0, aes_1.gcm)(key, nonce).decrypt(ciphertext);
|
|
133
109
|
}, _EncryptorDecryptor_getOrGenerateScryptKey = async function _EncryptorDecryptor_getOrGenerateScryptKey(password, o, salt, nativeScryptCrypto) {
|
|
134
110
|
const hashedPassword = createSHA256Hash(password);
|
|
135
111
|
const cachedKey = salt
|
|
136
112
|
? (0, cache_1.getCachedKeyBySalt)(hashedPassword, salt)
|
|
137
|
-
: (0, cache_1.
|
|
113
|
+
: (0, cache_1.getAnyCachedKey)(hashedPassword);
|
|
138
114
|
if (cachedKey) {
|
|
139
115
|
return {
|
|
140
116
|
key: cachedKey.key,
|
|
141
117
|
salt: cachedKey.salt,
|
|
142
118
|
};
|
|
143
119
|
}
|
|
144
|
-
const newSalt = salt ??
|
|
120
|
+
const newSalt = salt ?? (0, webcrypto_1.randomBytes)(SCRYPT_SALT_SIZE);
|
|
145
121
|
let newKey;
|
|
146
122
|
if (nativeScryptCrypto) {
|
|
147
123
|
newKey = await nativeScryptCrypto((0, utils_2.stringToByteArray)(password), newSalt, o.N, o.r, o.p, o.dkLen);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encryption.cjs","sourceRoot":"","sources":["../../../src/shared/encryption/encryption.ts"],"names":[],"mappings":"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","sourcesContent":["import { gcm } from '@noble/ciphers/aes';\nimport { randomBytes } from '@noble/ciphers/webcrypto';\nimport { scryptAsync } from '@noble/hashes/scrypt';\nimport { sha256 } from '@noble/hashes/sha256';\nimport { utf8ToBytes, concatBytes, bytesToHex } from '@noble/hashes/utils';\n\nimport type { NativeScrypt } from '../types/encryption';\nimport {\n getCachedKeyBySalt,\n getCachedKeyGeneratedWithSharedSalt,\n setCachedKey,\n} from './cache';\nimport {\n ALGORITHM_KEY_SIZE,\n ALGORITHM_NONCE_SIZE,\n SCRYPT_N,\n SCRYPT_p,\n SCRYPT_r,\n SCRYPT_SALT_SIZE,\n SHARED_SALT,\n} from './constants';\nimport {\n base64ToByteArray,\n byteArrayToBase64,\n bytesToUtf8,\n stringToByteArray,\n} from './utils';\n\nexport type EncryptedPayload = {\n // version\n v: '1';\n\n // key derivation function algorithm - scrypt\n t: 'scrypt';\n\n // data\n d: string;\n\n // encryption options - scrypt\n o: {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n N: number;\n r: number;\n p: number;\n dkLen: number;\n };\n\n // Salt options\n saltLen: number;\n};\n\nclass EncryptorDecryptor {\n async encryptString(\n plaintext: string,\n password: string,\n nativeScryptCrypto?: NativeScrypt,\n ): Promise<string> {\n try {\n return await this.#encryptStringV1(\n plaintext,\n password,\n nativeScryptCrypto,\n );\n } catch (e) {\n const errorMessage = e instanceof Error ? e.message : JSON.stringify(e);\n throw new Error(`Unable to encrypt string - ${errorMessage}`);\n }\n }\n\n async decryptString(\n encryptedDataStr: string,\n password: string,\n nativeScryptCrypto?: NativeScrypt,\n ): Promise<string> {\n try {\n const encryptedData: EncryptedPayload = JSON.parse(encryptedDataStr);\n if (encryptedData.v === '1') {\n if (encryptedData.t === 'scrypt') {\n return await this.#decryptStringV1(\n encryptedData,\n password,\n nativeScryptCrypto,\n );\n }\n }\n throw new Error(\n `Unsupported encrypted data payload - ${encryptedDataStr}`,\n );\n } catch (e) {\n const errorMessage = e instanceof Error ? e.message : JSON.stringify(e);\n throw new Error(`Unable to decrypt string - ${errorMessage}`);\n }\n }\n\n async #encryptStringV1(\n plaintext: string,\n password: string,\n nativeScryptCrypto?: NativeScrypt,\n ): Promise<string> {\n const { key, salt } = await this.#getOrGenerateScryptKey(\n password,\n {\n N: SCRYPT_N,\n r: SCRYPT_r,\n p: SCRYPT_p,\n dkLen: ALGORITHM_KEY_SIZE,\n },\n undefined,\n nativeScryptCrypto,\n );\n\n // Encrypt and prepend salt.\n const plaintextRaw = utf8ToBytes(plaintext);\n const ciphertextAndNonceAndSalt = concatBytes(\n salt,\n this.#encrypt(plaintextRaw, key),\n );\n\n // Convert to Base64\n const encryptedData = byteArrayToBase64(ciphertextAndNonceAndSalt);\n\n const encryptedPayload: EncryptedPayload = {\n v: '1',\n t: 'scrypt',\n d: encryptedData,\n o: {\n N: SCRYPT_N,\n r: SCRYPT_r,\n p: SCRYPT_p,\n dkLen: ALGORITHM_KEY_SIZE,\n },\n saltLen: SCRYPT_SALT_SIZE,\n };\n\n return JSON.stringify(encryptedPayload);\n }\n\n async #decryptStringV1(\n data: EncryptedPayload,\n password: string,\n nativeScryptCrypto?: NativeScrypt,\n ): Promise<string> {\n const { o, d: base64CiphertextAndNonceAndSalt, saltLen } = data;\n\n // Decode the base64.\n const ciphertextAndNonceAndSalt = base64ToByteArray(\n base64CiphertextAndNonceAndSalt,\n );\n\n // Create buffers of salt and ciphertextAndNonce.\n const salt = ciphertextAndNonceAndSalt.slice(0, saltLen);\n const ciphertextAndNonce = ciphertextAndNonceAndSalt.slice(\n saltLen,\n ciphertextAndNonceAndSalt.length,\n );\n\n // Derive the key.\n const { key } = await this.#getOrGenerateScryptKey(\n password,\n {\n N: o.N,\n r: o.r,\n p: o.p,\n dkLen: o.dkLen,\n },\n salt,\n nativeScryptCrypto,\n );\n\n // Decrypt and return result.\n return bytesToUtf8(this.#decrypt(ciphertextAndNonce, key));\n }\n\n getSalt(encryptedDataStr: string) {\n try {\n const encryptedData: EncryptedPayload = JSON.parse(encryptedDataStr);\n if (encryptedData.v === '1') {\n if (encryptedData.t === 'scrypt') {\n const { d: base64CiphertextAndNonceAndSalt, saltLen } = encryptedData;\n\n // Decode the base64.\n const ciphertextAndNonceAndSalt = base64ToByteArray(\n base64CiphertextAndNonceAndSalt,\n );\n\n // Create buffers of salt and ciphertextAndNonce.\n const salt = ciphertextAndNonceAndSalt.slice(0, saltLen);\n return salt;\n }\n }\n throw new Error(\n `Unsupported encrypted data payload - ${encryptedDataStr}`,\n );\n } catch (e) {\n const errorMessage = e instanceof Error ? e.message : JSON.stringify(e);\n throw new Error(`Unable to get salt - ${errorMessage}`);\n }\n }\n\n getIfEntriesHaveDifferentSalts(entries: string[]): boolean {\n const salts = entries\n .map((e) => {\n try {\n return this.getSalt(e);\n } catch {\n return undefined;\n }\n })\n .filter((s): s is Uint8Array => s !== undefined);\n\n const strSet = new Set(salts.map((arr) => arr.toString()));\n return strSet.size === salts.length;\n }\n\n #encrypt(plaintext: Uint8Array, key: Uint8Array): Uint8Array {\n const nonce = randomBytes(ALGORITHM_NONCE_SIZE);\n\n // Encrypt and prepend nonce.\n const ciphertext = gcm(key, nonce).encrypt(plaintext);\n\n return concatBytes(nonce, ciphertext);\n }\n\n #decrypt(ciphertextAndNonce: Uint8Array, key: Uint8Array): Uint8Array {\n // Create buffers of nonce and ciphertext.\n const nonce = ciphertextAndNonce.slice(0, ALGORITHM_NONCE_SIZE);\n const ciphertext = ciphertextAndNonce.slice(\n ALGORITHM_NONCE_SIZE,\n ciphertextAndNonce.length,\n );\n\n // Decrypt and return result.\n return gcm(key, nonce).decrypt(ciphertext);\n }\n\n async #getOrGenerateScryptKey(\n password: string,\n o: EncryptedPayload['o'],\n salt?: Uint8Array,\n nativeScryptCrypto?: NativeScrypt,\n ) {\n const hashedPassword = createSHA256Hash(password);\n const cachedKey = salt\n ? getCachedKeyBySalt(hashedPassword, salt)\n : getCachedKeyGeneratedWithSharedSalt(hashedPassword);\n\n if (cachedKey) {\n return {\n key: cachedKey.key,\n salt: cachedKey.salt,\n };\n }\n\n const newSalt = salt ?? SHARED_SALT;\n\n let newKey: Uint8Array;\n\n if (nativeScryptCrypto) {\n newKey = await nativeScryptCrypto(\n stringToByteArray(password),\n newSalt,\n o.N,\n o.r,\n o.p,\n o.dkLen,\n );\n } else {\n newKey = await scryptAsync(password, newSalt, {\n N: o.N,\n r: o.r,\n p: o.p,\n dkLen: o.dkLen,\n });\n }\n\n setCachedKey(hashedPassword, newSalt, newKey);\n\n return {\n key: newKey,\n salt: newSalt,\n };\n }\n}\n\nconst encryption = new EncryptorDecryptor();\nexport default encryption;\n\n/**\n * Receive a SHA256 hash from a given string\n * @param data - input\n * @returns sha256 hash\n */\nexport function createSHA256Hash(data: string): string {\n const hashedData = sha256(data);\n return bytesToHex(hashedData);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"encryption.cjs","sourceRoot":"","sources":["../../../src/shared/encryption/encryption.ts"],"names":[],"mappings":"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","sourcesContent":["import { gcm } from '@noble/ciphers/aes';\nimport { randomBytes } from '@noble/ciphers/webcrypto';\nimport { scryptAsync } from '@noble/hashes/scrypt';\nimport { sha256 } from '@noble/hashes/sha256';\nimport { utf8ToBytes, concatBytes, bytesToHex } from '@noble/hashes/utils';\n\nimport type { NativeScrypt } from '../types/encryption';\nimport { getAnyCachedKey, getCachedKeyBySalt, setCachedKey } from './cache';\nimport {\n base64ToByteArray,\n byteArrayToBase64,\n bytesToUtf8,\n stringToByteArray,\n} from './utils';\n\nexport type EncryptedPayload = {\n // version\n v: '1';\n\n // key derivation function algorithm - scrypt\n t: 'scrypt';\n\n // data\n d: string;\n\n // encryption options - scrypt\n o: {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n N: number;\n r: number;\n p: number;\n dkLen: number;\n };\n\n // Salt options\n saltLen: number;\n};\n\n// Nonce/Key Sizes\nconst ALGORITHM_NONCE_SIZE = 12; // 12 bytes\nconst ALGORITHM_KEY_SIZE = 16; // 16 bytes\n\n// Scrypt settings\n// see: https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#scrypt\nconst SCRYPT_SALT_SIZE = 16; // 16 bytes\nconst SCRYPT_N = 2 ** 17; // CPU/memory cost parameter (must be a power of 2, > 1)\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst SCRYPT_r = 8; // Block size parameter\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst SCRYPT_p = 1; // Parallelization parameter\n\nclass EncryptorDecryptor {\n async encryptString(\n plaintext: string,\n password: string,\n nativeScryptCrypto?: NativeScrypt,\n ): Promise<string> {\n try {\n return await this.#encryptStringV1(\n plaintext,\n password,\n nativeScryptCrypto,\n );\n } catch (e) {\n const errorMessage = e instanceof Error ? e.message : JSON.stringify(e);\n throw new Error(`Unable to encrypt string - ${errorMessage}`);\n }\n }\n\n async decryptString(\n encryptedDataStr: string,\n password: string,\n nativeScryptCrypto?: NativeScrypt,\n ): Promise<string> {\n try {\n const encryptedData: EncryptedPayload = JSON.parse(encryptedDataStr);\n if (encryptedData.v === '1') {\n if (encryptedData.t === 'scrypt') {\n return await this.#decryptStringV1(\n encryptedData,\n password,\n nativeScryptCrypto,\n );\n }\n }\n throw new Error(\n `Unsupported encrypted data payload - ${encryptedDataStr}`,\n );\n } catch (e) {\n const errorMessage = e instanceof Error ? e.message : JSON.stringify(e);\n throw new Error(`Unable to decrypt string - ${errorMessage}`);\n }\n }\n\n async #encryptStringV1(\n plaintext: string,\n password: string,\n nativeScryptCrypto?: NativeScrypt,\n ): Promise<string> {\n const { key, salt } = await this.#getOrGenerateScryptKey(\n password,\n {\n N: SCRYPT_N,\n r: SCRYPT_r,\n p: SCRYPT_p,\n dkLen: ALGORITHM_KEY_SIZE,\n },\n undefined,\n nativeScryptCrypto,\n );\n\n // Encrypt and prepend salt.\n const plaintextRaw = utf8ToBytes(plaintext);\n const ciphertextAndNonceAndSalt = concatBytes(\n salt,\n this.#encrypt(plaintextRaw, key),\n );\n\n // Convert to Base64\n const encryptedData = byteArrayToBase64(ciphertextAndNonceAndSalt);\n\n const encryptedPayload: EncryptedPayload = {\n v: '1',\n t: 'scrypt',\n d: encryptedData,\n o: {\n N: SCRYPT_N,\n r: SCRYPT_r,\n p: SCRYPT_p,\n dkLen: ALGORITHM_KEY_SIZE,\n },\n saltLen: SCRYPT_SALT_SIZE,\n };\n\n return JSON.stringify(encryptedPayload);\n }\n\n async #decryptStringV1(\n data: EncryptedPayload,\n password: string,\n nativeScryptCrypto?: NativeScrypt,\n ): Promise<string> {\n const { o, d: base64CiphertextAndNonceAndSalt, saltLen } = data;\n\n // Decode the base64.\n const ciphertextAndNonceAndSalt = base64ToByteArray(\n base64CiphertextAndNonceAndSalt,\n );\n\n // Create buffers of salt and ciphertextAndNonce.\n const salt = ciphertextAndNonceAndSalt.slice(0, saltLen);\n const ciphertextAndNonce = ciphertextAndNonceAndSalt.slice(\n saltLen,\n ciphertextAndNonceAndSalt.length,\n );\n\n // Derive the key.\n const { key } = await this.#getOrGenerateScryptKey(\n password,\n {\n N: o.N,\n r: o.r,\n p: o.p,\n dkLen: o.dkLen,\n },\n salt,\n nativeScryptCrypto,\n );\n\n // Decrypt and return result.\n return bytesToUtf8(this.#decrypt(ciphertextAndNonce, key));\n }\n\n #encrypt(plaintext: Uint8Array, key: Uint8Array): Uint8Array {\n const nonce = randomBytes(ALGORITHM_NONCE_SIZE);\n\n // Encrypt and prepend nonce.\n const ciphertext = gcm(key, nonce).encrypt(plaintext);\n\n return concatBytes(nonce, ciphertext);\n }\n\n #decrypt(ciphertextAndNonce: Uint8Array, key: Uint8Array): Uint8Array {\n // Create buffers of nonce and ciphertext.\n const nonce = ciphertextAndNonce.slice(0, ALGORITHM_NONCE_SIZE);\n const ciphertext = ciphertextAndNonce.slice(\n ALGORITHM_NONCE_SIZE,\n ciphertextAndNonce.length,\n );\n\n // Decrypt and return result.\n return gcm(key, nonce).decrypt(ciphertext);\n }\n\n async #getOrGenerateScryptKey(\n password: string,\n o: EncryptedPayload['o'],\n salt?: Uint8Array,\n nativeScryptCrypto?: NativeScrypt,\n ) {\n const hashedPassword = createSHA256Hash(password);\n const cachedKey = salt\n ? getCachedKeyBySalt(hashedPassword, salt)\n : getAnyCachedKey(hashedPassword);\n\n if (cachedKey) {\n return {\n key: cachedKey.key,\n salt: cachedKey.salt,\n };\n }\n\n const newSalt = salt ?? randomBytes(SCRYPT_SALT_SIZE);\n\n let newKey: Uint8Array;\n\n if (nativeScryptCrypto) {\n newKey = await nativeScryptCrypto(\n stringToByteArray(password),\n newSalt,\n o.N,\n o.r,\n o.p,\n o.dkLen,\n );\n } else {\n newKey = await scryptAsync(password, newSalt, {\n N: o.N,\n r: o.r,\n p: o.p,\n dkLen: o.dkLen,\n });\n }\n setCachedKey(hashedPassword, newSalt, newKey);\n\n return {\n key: newKey,\n salt: newSalt,\n };\n }\n}\n\nconst encryption = new EncryptorDecryptor();\nexport default encryption;\n\n/**\n * Receive a SHA256 hash from a given string\n * @param data - input\n * @returns sha256 hash\n */\nexport function createSHA256Hash(data: string): string {\n const hashedData = sha256(data);\n return bytesToHex(hashedData);\n}\n"]}
|
|
@@ -15,8 +15,6 @@ declare class EncryptorDecryptor {
|
|
|
15
15
|
#private;
|
|
16
16
|
encryptString(plaintext: string, password: string, nativeScryptCrypto?: NativeScrypt): Promise<string>;
|
|
17
17
|
decryptString(encryptedDataStr: string, password: string, nativeScryptCrypto?: NativeScrypt): Promise<string>;
|
|
18
|
-
getSalt(encryptedDataStr: string): Uint8Array;
|
|
19
|
-
getIfEntriesHaveDifferentSalts(entries: string[]): boolean;
|
|
20
18
|
}
|
|
21
19
|
declare const encryption: EncryptorDecryptor;
|
|
22
20
|
export default encryption;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encryption.d.cts","sourceRoot":"","sources":["../../../src/shared/encryption/encryption.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAE,gCAA4B;
|
|
1
|
+
{"version":3,"file":"encryption.d.cts","sourceRoot":"","sources":["../../../src/shared/encryption/encryption.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAE,gCAA4B;AASxD,MAAM,MAAM,gBAAgB,GAAG;IAE7B,CAAC,EAAE,GAAG,CAAC;IAGP,CAAC,EAAE,QAAQ,CAAC;IAGZ,CAAC,EAAE,MAAM,CAAC;IAGV,CAAC,EAAE;QAED,CAAC,EAAE,MAAM,CAAC;QACV,CAAC,EAAE,MAAM,CAAC;QACV,CAAC,EAAE,MAAM,CAAC;QACV,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IAGF,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAeF,cAAM,kBAAkB;;IAChB,aAAa,CACjB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,kBAAkB,CAAC,EAAE,YAAY,GAChC,OAAO,CAAC,MAAM,CAAC;IAaZ,aAAa,CACjB,gBAAgB,EAAE,MAAM,EACxB,QAAQ,EAAE,MAAM,EAChB,kBAAkB,CAAC,EAAE,YAAY,GAChC,OAAO,CAAC,MAAM,CAAC;CAuKnB;AAED,QAAA,MAAM,UAAU,oBAA2B,CAAC;AAC5C,eAAe,UAAU,CAAC;AAE1B;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGrD"}
|
|
@@ -15,8 +15,6 @@ declare class EncryptorDecryptor {
|
|
|
15
15
|
#private;
|
|
16
16
|
encryptString(plaintext: string, password: string, nativeScryptCrypto?: NativeScrypt): Promise<string>;
|
|
17
17
|
decryptString(encryptedDataStr: string, password: string, nativeScryptCrypto?: NativeScrypt): Promise<string>;
|
|
18
|
-
getSalt(encryptedDataStr: string): Uint8Array;
|
|
19
|
-
getIfEntriesHaveDifferentSalts(entries: string[]): boolean;
|
|
20
18
|
}
|
|
21
19
|
declare const encryption: EncryptorDecryptor;
|
|
22
20
|
export default encryption;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encryption.d.mts","sourceRoot":"","sources":["../../../src/shared/encryption/encryption.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAE,gCAA4B;
|
|
1
|
+
{"version":3,"file":"encryption.d.mts","sourceRoot":"","sources":["../../../src/shared/encryption/encryption.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAE,gCAA4B;AASxD,MAAM,MAAM,gBAAgB,GAAG;IAE7B,CAAC,EAAE,GAAG,CAAC;IAGP,CAAC,EAAE,QAAQ,CAAC;IAGZ,CAAC,EAAE,MAAM,CAAC;IAGV,CAAC,EAAE;QAED,CAAC,EAAE,MAAM,CAAC;QACV,CAAC,EAAE,MAAM,CAAC;QACV,CAAC,EAAE,MAAM,CAAC;QACV,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IAGF,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAeF,cAAM,kBAAkB;;IAChB,aAAa,CACjB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,kBAAkB,CAAC,EAAE,YAAY,GAChC,OAAO,CAAC,MAAM,CAAC;IAaZ,aAAa,CACjB,gBAAgB,EAAE,MAAM,EACxB,QAAQ,EAAE,MAAM,EAChB,kBAAkB,CAAC,EAAE,YAAY,GAChC,OAAO,CAAC,MAAM,CAAC;CAuKnB;AAED,QAAA,MAAM,UAAU,oBAA2B,CAAC;AAC5C,eAAe,UAAU,CAAC;AAE1B;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGrD"}
|