@metamask-previews/profile-sync-controller 28.0.2-preview-8daaa5a40 → 28.0.2-preview-ae9b6b322
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/CHANGELOG.md +14 -2
- package/dist/controllers/authentication/AuthenticationController-method-action-types.cjs.map +1 -1
- package/dist/controllers/authentication/AuthenticationController-method-action-types.d.cts +52 -6
- package/dist/controllers/authentication/AuthenticationController-method-action-types.d.cts.map +1 -1
- package/dist/controllers/authentication/AuthenticationController-method-action-types.d.mts +52 -6
- package/dist/controllers/authentication/AuthenticationController-method-action-types.d.mts.map +1 -1
- package/dist/controllers/authentication/AuthenticationController-method-action-types.mjs.map +1 -1
- package/dist/controllers/authentication/AuthenticationController.cjs +143 -6
- package/dist/controllers/authentication/AuthenticationController.cjs.map +1 -1
- package/dist/controllers/authentication/AuthenticationController.d.cts +66 -7
- package/dist/controllers/authentication/AuthenticationController.d.cts.map +1 -1
- package/dist/controllers/authentication/AuthenticationController.d.mts +66 -7
- package/dist/controllers/authentication/AuthenticationController.d.mts.map +1 -1
- package/dist/controllers/authentication/AuthenticationController.mjs +143 -6
- package/dist/controllers/authentication/AuthenticationController.mjs.map +1 -1
- package/dist/controllers/authentication/index.cjs.map +1 -1
- package/dist/controllers/authentication/index.d.cts +1 -1
- package/dist/controllers/authentication/index.d.cts.map +1 -1
- package/dist/controllers/authentication/index.d.mts +1 -1
- package/dist/controllers/authentication/index.d.mts.map +1 -1
- package/dist/controllers/authentication/index.mjs.map +1 -1
- package/dist/controllers/authentication/mocks/mockResponses.cjs +10 -1
- package/dist/controllers/authentication/mocks/mockResponses.cjs.map +1 -1
- package/dist/controllers/authentication/mocks/mockResponses.d.cts +17 -32
- package/dist/controllers/authentication/mocks/mockResponses.d.cts.map +1 -1
- package/dist/controllers/authentication/mocks/mockResponses.d.mts +17 -32
- package/dist/controllers/authentication/mocks/mockResponses.d.mts.map +1 -1
- package/dist/controllers/authentication/mocks/mockResponses.mjs +9 -1
- package/dist/controllers/authentication/mocks/mockResponses.mjs.map +1 -1
- package/dist/sdk/authentication-jwt-bearer/flow-srp.cjs +28 -1
- package/dist/sdk/authentication-jwt-bearer/flow-srp.cjs.map +1 -1
- package/dist/sdk/authentication-jwt-bearer/flow-srp.d.cts +2 -0
- package/dist/sdk/authentication-jwt-bearer/flow-srp.d.cts.map +1 -1
- package/dist/sdk/authentication-jwt-bearer/flow-srp.d.mts +2 -0
- package/dist/sdk/authentication-jwt-bearer/flow-srp.d.mts.map +1 -1
- package/dist/sdk/authentication-jwt-bearer/flow-srp.mjs +29 -2
- package/dist/sdk/authentication-jwt-bearer/flow-srp.mjs.map +1 -1
- package/dist/sdk/authentication-jwt-bearer/services.cjs +58 -1
- package/dist/sdk/authentication-jwt-bearer/services.cjs.map +1 -1
- package/dist/sdk/authentication-jwt-bearer/services.d.cts +17 -1
- package/dist/sdk/authentication-jwt-bearer/services.d.cts.map +1 -1
- package/dist/sdk/authentication-jwt-bearer/services.d.mts +17 -1
- package/dist/sdk/authentication-jwt-bearer/services.d.mts.map +1 -1
- package/dist/sdk/authentication-jwt-bearer/services.mjs +55 -0
- package/dist/sdk/authentication-jwt-bearer/services.mjs.map +1 -1
- package/dist/sdk/authentication-jwt-bearer/types.cjs.map +1 -1
- package/dist/sdk/authentication-jwt-bearer/types.d.cts +20 -1
- package/dist/sdk/authentication-jwt-bearer/types.d.cts.map +1 -1
- package/dist/sdk/authentication-jwt-bearer/types.d.mts +20 -1
- package/dist/sdk/authentication-jwt-bearer/types.d.mts.map +1 -1
- package/dist/sdk/authentication-jwt-bearer/types.mjs.map +1 -1
- package/dist/sdk/authentication-jwt-bearer/utils/identifier.cjs +27 -0
- package/dist/sdk/authentication-jwt-bearer/utils/identifier.cjs.map +1 -0
- package/dist/sdk/authentication-jwt-bearer/utils/identifier.d.cts +13 -0
- package/dist/sdk/authentication-jwt-bearer/utils/identifier.d.cts.map +1 -0
- package/dist/sdk/authentication-jwt-bearer/utils/identifier.d.mts +13 -0
- package/dist/sdk/authentication-jwt-bearer/utils/identifier.d.mts.map +1 -0
- package/dist/sdk/authentication-jwt-bearer/utils/identifier.mjs +23 -0
- package/dist/sdk/authentication-jwt-bearer/utils/identifier.mjs.map +1 -0
- package/dist/sdk/authentication.cjs +4 -0
- package/dist/sdk/authentication.cjs.map +1 -1
- package/dist/sdk/authentication.d.cts +2 -0
- package/dist/sdk/authentication.d.cts.map +1 -1
- package/dist/sdk/authentication.d.mts +2 -0
- package/dist/sdk/authentication.d.mts.map +1 -1
- package/dist/sdk/authentication.mjs +4 -0
- package/dist/sdk/authentication.mjs.map +1 -1
- package/dist/sdk/mocks/auth.cjs +11 -1
- package/dist/sdk/mocks/auth.cjs.map +1 -1
- package/dist/sdk/mocks/auth.d.cts +10 -0
- package/dist/sdk/mocks/auth.d.cts.map +1 -1
- package/dist/sdk/mocks/auth.d.mts +10 -0
- package/dist/sdk/mocks/auth.d.mts.map +1 -1
- package/dist/sdk/mocks/auth.mjs +11 -1
- package/dist/sdk/mocks/auth.mjs.map +1 -1
- package/dist/sdk/user-storage.cjs +26 -3
- package/dist/sdk/user-storage.cjs.map +1 -1
- package/dist/sdk/user-storage.d.cts +7 -0
- package/dist/sdk/user-storage.d.cts.map +1 -1
- package/dist/sdk/user-storage.d.mts +7 -0
- package/dist/sdk/user-storage.d.mts.map +1 -1
- package/dist/sdk/user-storage.mjs +26 -3
- package/dist/sdk/user-storage.mjs.map +1 -1
- package/dist/sdk/utils/validate-pair-response.cjs +29 -0
- package/dist/sdk/utils/validate-pair-response.cjs.map +1 -0
- package/dist/sdk/utils/validate-pair-response.d.cts +26 -0
- package/dist/sdk/utils/validate-pair-response.d.cts.map +1 -0
- package/dist/sdk/utils/validate-pair-response.d.mts +26 -0
- package/dist/sdk/utils/validate-pair-response.d.mts.map +1 -0
- package/dist/sdk/utils/validate-pair-response.mjs +25 -0
- package/dist/sdk/utils/validate-pair-response.mjs.map +1 -0
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.mjs","sourceRoot":"","sources":["../../../src/sdk/mocks/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,6BAAyB;AACjD,OAAO,EACL,SAAS,EACT,cAAc,EACd,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,mBAAmB,EACpB,kDAA8C;AAE/C,MAAM,CAAC,MAAM,cAAc,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACjD,MAAM,CAAC,MAAM,kBAAkB,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACzD,MAAM,CAAC,MAAM,mBAAmB,GAAG,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAC3D,MAAM,CAAC,MAAM,mBAAmB,GAAG,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAC3D,MAAM,CAAC,MAAM,yBAAyB,GAAG,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACnE,MAAM,CAAC,MAAM,wBAAwB,GAAG,mBAAmB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAErE,MAAM,CAAC,MAAM,QAAQ,GACnB,opBAAopB,CAAC;AAEvpB,MAAM,CAAC,MAAM,eAAe,GAC1B,mLAAmL,CAAC;AAEtL,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,KAAK,EAAE,kBAAkB;IACzB,UAAU,EAAE,4CAA4C;IACxD,UAAU,EAAE,GAAG;CAChB,CAAC;AAEF,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,KAAK,EAAE,QAAQ;IACf,UAAU,EAAE,IAAI;IAChB,OAAO,EAAE;QACP,UAAU,EAAE,sCAAsC;QAClD,cAAc,EAAE,sCAAsC;QACtD,aAAa,EACX,kEAAkE;QACpE,eAAe,EAAE,MAAM;QACvB,qBAAqB,EAAE,iCAAiC;KACzD;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,KAAK,EAAE,QAAQ;IACf,UAAU,EAAE,IAAI;IAChB,OAAO,EAAE;QACP,UAAU,EAAE,sCAAsC;QAClD,cAAc,EAAE,sCAAsC;QACtD,aAAa,EACX,kEAAkE;QACpE,eAAe,EAAE,KAAK;QACtB,qBAAqB,EAAE,4BAA4B;KACpD;
|
|
1
|
+
{"version":3,"file":"auth.mjs","sourceRoot":"","sources":["../../../src/sdk/mocks/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,6BAAyB;AACjD,OAAO,EACL,SAAS,EACT,cAAc,EACd,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACpB,kDAA8C;AAE/C,MAAM,CAAC,MAAM,cAAc,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACjD,MAAM,CAAC,MAAM,kBAAkB,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACzD,MAAM,CAAC,MAAM,mBAAmB,GAAG,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAC3D,MAAM,CAAC,MAAM,mBAAmB,GAAG,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAC3D,MAAM,CAAC,MAAM,yBAAyB,GAAG,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACnE,MAAM,CAAC,MAAM,sBAAsB,GAAG,iBAAiB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACjE,MAAM,CAAC,MAAM,wBAAwB,GAAG,mBAAmB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAErE,MAAM,CAAC,MAAM,QAAQ,GACnB,opBAAopB,CAAC;AAEvpB,MAAM,CAAC,MAAM,eAAe,GAC1B,mLAAmL,CAAC;AAEtL,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,KAAK,EAAE,kBAAkB;IACzB,UAAU,EAAE,4CAA4C;IACxD,UAAU,EAAE,GAAG;CAChB,CAAC;AAEF,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,KAAK,EAAE,QAAQ;IACf,UAAU,EAAE,IAAI;IAChB,OAAO,EAAE;QACP,UAAU,EAAE,sCAAsC;QAClD,cAAc,EAAE,sCAAsC;QACtD,aAAa,EACX,kEAAkE;QACpE,eAAe,EAAE,MAAM;QACvB,qBAAqB,EAAE,iCAAiC;KACzD;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,KAAK,EAAE,QAAQ;IACf,UAAU,EAAE,IAAI;IAChB,OAAO,EAAE;QACP,UAAU,EAAE,sCAAsC;QAClD,cAAc,EAAE,sCAAsC;QACtD,aAAa,EACX,kEAAkE;QACpE,eAAe,EAAE,KAAK;QACtB,qBAAqB,EAAE,4BAA4B;KACpD;IACD,eAAe,EAAE,EAAE;CACpB,CAAC;AAEF,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,YAAY,EAAE,eAAe;IAC7B,UAAU,EAAE,IAAI;CACjB,CAAC;AAEF,MAAM,CAAC,MAAM,2BAA2B,GAAG;IACzC,OAAO,EAAE;QACP,aAAa,EAAE,uBAAuB,CAAC,OAAO,CAAC,aAAa;QAC5D,cAAc,EAAE,uBAAuB,CAAC,OAAO,CAAC,cAAc;QAC9D,UAAU,EAAE,uBAAuB,CAAC,OAAO,CAAC,UAAU;KACvD;IACD,eAAe,EAAE,EAAE;CACpB,CAAC;AAEF,MAAM,CAAC,MAAM,kCAAkC,GAAG;IAChD,UAAU,EAAE,sCAAsC;IAClD,UAAU,EAAE,sBAAsB;IAClC,OAAO,EAAE;QACP;YACE,cAAc,EAAE,sCAAsC;YACtD,KAAK,EAAE,QAAQ,CAAC,MAAM;YACtB,UAAU,EAAE,sBAAsB;YAClC,UAAU,EAAE,sBAAsB;YAClC,OAAO,EAAE,CAAC;SACX;QACD;YACE,cAAc,EAAE,sCAAsC;YACtD,KAAK,EAAE,QAAQ,CAAC,SAAS;YACzB,UAAU,EAAE,sBAAsB;YAClC,UAAU,EAAE,sBAAsB;YAClC,OAAO,EAAE,CAAC;SACX;KACF;CACF,CAAC","sourcesContent":["import { Env, Platform } from '../../shared/env';\nimport {\n NONCE_URL,\n SIWE_LOGIN_URL,\n SRP_LOGIN_URL,\n OIDC_TOKEN_URL,\n PAIR_IDENTIFIERS,\n PAIR_PROFILES_URL,\n PROFILE_LINEAGE_URL,\n} from '../authentication-jwt-bearer/services';\n\nexport const MOCK_NONCE_URL = NONCE_URL(Env.PRD);\nexport const MOCK_SRP_LOGIN_URL = SRP_LOGIN_URL(Env.PRD);\nexport const MOCK_OIDC_TOKEN_URL = OIDC_TOKEN_URL(Env.PRD);\nexport const MOCK_SIWE_LOGIN_URL = SIWE_LOGIN_URL(Env.PRD);\nexport const MOCK_PAIR_IDENTIFIERS_URL = PAIR_IDENTIFIERS(Env.PRD);\nexport const MOCK_PAIR_PROFILES_URL = PAIR_PROFILES_URL(Env.PRD);\nexport const MOCK_PROFILE_LINEAGE_URL = PROFILE_LINEAGE_URL(Env.PRD);\n\nexport const MOCK_JWT =\n 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImIwNzE2N2U2LWJjNWUtNDgyZC1hNjRhLWU1MjQ0MjY2MGU3NyJ9.eyJzdWIiOiI1MzE0ODc5YWM2NDU1OGI3OTQ5ZmI4NWIzMjg2ZjZjNjUwODAzYmFiMTY0Y2QyOWNmMmM3YzdmMjMzMWMwZTRlIiwiaWF0IjoxNzA2MTEzMDYyLCJleHAiOjE3NjkxODUwNjMsImlzcyI6ImF1dGgubWV0YW1hc2suaW8iLCJhdWQiOiJwb3J0Zm9saW8ubWV0YW1hc2suaW8ifQ.E5UL6oABNweS8t5a6IBTqTf7NLOJbrhJSmEcsr7kwLp4bGvcENJzACwnsHDkA6PlzfDV09ZhAGU_F3hlS0j-erbY0k0AFR-GAtyS7E9N02D8RgUDz5oDR65CKmzM8JilgFA8UvruJ6OJGogroaOSOqzRES_s8MjHpP47RJ9lXrUesajsbOudXbuksXWg5QmWip6LLvjwr8UUzcJzNQilyIhiEpo4WdzWM4R3VtTwr4rHnWEvtYnYCov1jmI2w3YQ48y0M-3Y9IOO0ov_vlITRrOnR7Y7fRUGLUFmU5msD8mNWRywjQFLHfJJ1yNP5aJ8TkuCK3sC6kcUH335IVvukQ';\n\nexport const MOCK_ACCESS_JWT =\n 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjQxMDI0NDQ4MDB9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c';\n\nexport const MOCK_NONCE_RESPONSE = {\n nonce: 'xGMm9SoihEKeAEfV',\n identifier: '0xd8641601Cb79a94FD872fE42d5b4a067A44a7e88',\n expires_in: 300,\n};\n\nexport const MOCK_SIWE_LOGIN_RESPONSE = {\n token: MOCK_JWT,\n expires_in: 3600,\n profile: {\n profile_id: 'fa2bbf82-bd9a-4e6b-aabc-9ca0d0319b6e',\n metametrics_id: 'de742679-4960-4977-a415-4718b5f8e86c',\n identifier_id:\n 'ec9a4e9906836497efad2fd4d4290b34d2c6a2c0d93eb174aa3cd88a133adbaf',\n identifier_type: 'SIWE',\n encrypted_storage_key: '2c6a2c0d93eb174aa3cd88a133adbaf',\n },\n};\n\nexport const MOCK_SRP_LOGIN_RESPONSE = {\n token: MOCK_JWT,\n expires_in: 3600,\n profile: {\n profile_id: 'f88227bd-b615-41a3-b0be-467dd781a4ad',\n metametrics_id: '561ec651-a844-4b36-a451-04d6eac35740',\n identifier_id:\n 'da9a9fc7b09edde9cc23cec9b7e11a71fb0ab4d2ddd8af8af905306f3e1456fb',\n identifier_type: 'SRP',\n encrypted_storage_key: 'd2ddd8af8af905306f3e1456fb',\n },\n profile_aliases: [],\n};\n\nexport const MOCK_OIDC_TOKEN_RESPONSE = {\n access_token: MOCK_ACCESS_JWT,\n expires_in: 3600,\n};\n\nexport const MOCK_PAIR_PROFILES_RESPONSE = {\n profile: {\n identifier_id: MOCK_SRP_LOGIN_RESPONSE.profile.identifier_id,\n metametrics_id: MOCK_SRP_LOGIN_RESPONSE.profile.metametrics_id,\n profile_id: MOCK_SRP_LOGIN_RESPONSE.profile.profile_id,\n },\n profile_aliases: [],\n};\n\nexport const MOCK_USER_PROFILE_LINEAGE_RESPONSE = {\n profile_id: 'f88227bd-b615-41a3-b0be-467dd781a4ad',\n created_at: '2025-10-01T12:00:00Z',\n lineage: [\n {\n metametrics_id: '561ec651-a844-4b36-a451-04d6eac35740',\n agent: Platform.MOBILE,\n created_at: '2025-10-01T12:00:00Z',\n updated_at: '2025-10-01T12:00:00Z',\n counter: 1,\n },\n {\n metametrics_id: 'de742679-4960-4977-a415-4718b5f8e86c',\n agent: Platform.EXTENSION,\n created_at: '2025-10-01T12:00:00Z',\n updated_at: '2025-10-01T12:00:00Z',\n counter: 2,\n },\n ],\n};\n"]}
|
|
@@ -27,7 +27,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
27
27
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
28
28
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
29
29
|
};
|
|
30
|
-
var _UserStorage_instances, _UserStorage_upsertUserStorage, _UserStorage_batchUpsertUserStorage, _UserStorage_batchUpsertUserStorageWithAlreadyHashedAndEncryptedEntries, _UserStorage_getUserStorage, _UserStorage_getUserStorageAllFeatureEntries, _UserStorage_deleteUserStorage, _UserStorage_deleteUserStorageAllFeatureEntries, _UserStorage_batchDeleteUserStorage, _UserStorage_createEntryKey, _UserStorage_getAuthorizationHeader;
|
|
30
|
+
var _UserStorage_instances, _UserStorage_upsertUserStorage, _UserStorage_batchUpsertUserStorage, _UserStorage_batchUpsertUserStorageWithAlreadyHashedAndEncryptedEntries, _UserStorage_getUserStorage, _UserStorage_getUserStorageAllFeatureEntries, _UserStorage_deleteUserStorage, _UserStorage_deleteUserStorageAllFeatureEntries, _UserStorage_batchDeleteUserStorage, _UserStorage_createEntryKey, _UserStorage_getAuthorizationHeader, _UserStorage_getProfileScopeHeader;
|
|
31
31
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
32
32
|
exports.UserStorage = exports.STORAGE_URL = void 0;
|
|
33
33
|
const encryption_1 = __importStar(require("../shared/encryption/index.cjs"));
|
|
@@ -83,6 +83,7 @@ _UserStorage_instances = new WeakSet(), _UserStorage_upsertUserStorage = async f
|
|
|
83
83
|
const entropySourceId = options?.entropySourceId;
|
|
84
84
|
try {
|
|
85
85
|
const headers = await __classPrivateFieldGet(this, _UserStorage_instances, "m", _UserStorage_getAuthorizationHeader).call(this, entropySourceId);
|
|
86
|
+
const profileScopeHeader = await __classPrivateFieldGet(this, _UserStorage_instances, "m", _UserStorage_getProfileScopeHeader).call(this, entropySourceId, options?.useCanonicalScope);
|
|
86
87
|
const storageKey = await this.getStorageKey(entropySourceId);
|
|
87
88
|
const encryptedData = await encryption_1.default.encryptString(data, storageKey, options?.nativeScryptCrypto);
|
|
88
89
|
const encryptedPath = (0, storage_schema_1.createEntryPath)(path, storageKey);
|
|
@@ -92,6 +93,7 @@ _UserStorage_instances = new WeakSet(), _UserStorage_upsertUserStorage = async f
|
|
|
92
93
|
headers: {
|
|
93
94
|
'Content-Type': 'application/json',
|
|
94
95
|
...headers,
|
|
96
|
+
...profileScopeHeader,
|
|
95
97
|
},
|
|
96
98
|
body: JSON.stringify({ data: encryptedData }),
|
|
97
99
|
});
|
|
@@ -115,6 +117,7 @@ _UserStorage_instances = new WeakSet(), _UserStorage_upsertUserStorage = async f
|
|
|
115
117
|
return;
|
|
116
118
|
}
|
|
117
119
|
const headers = await __classPrivateFieldGet(this, _UserStorage_instances, "m", _UserStorage_getAuthorizationHeader).call(this, entropySourceId);
|
|
120
|
+
const profileScopeHeader = await __classPrivateFieldGet(this, _UserStorage_instances, "m", _UserStorage_getProfileScopeHeader).call(this, entropySourceId, options?.useCanonicalScope);
|
|
118
121
|
const storageKey = await this.getStorageKey(entropySourceId);
|
|
119
122
|
const encryptedData = await Promise.all(data.map(async (d) => {
|
|
120
123
|
return [
|
|
@@ -128,6 +131,7 @@ _UserStorage_instances = new WeakSet(), _UserStorage_upsertUserStorage = async f
|
|
|
128
131
|
headers: {
|
|
129
132
|
'Content-Type': 'application/json',
|
|
130
133
|
...headers,
|
|
134
|
+
...profileScopeHeader,
|
|
131
135
|
},
|
|
132
136
|
body: JSON.stringify({ data: Object.fromEntries(encryptedData) }),
|
|
133
137
|
});
|
|
@@ -144,15 +148,17 @@ _UserStorage_instances = new WeakSet(), _UserStorage_upsertUserStorage = async f
|
|
|
144
148
|
const errorMessage = e instanceof Error ? e.message : JSON.stringify(e ?? '');
|
|
145
149
|
throw new errors_1.UserStorageError(`failed to batch upsert user storage for path '${path}'. ${errorMessage}`);
|
|
146
150
|
}
|
|
147
|
-
}, _UserStorage_batchUpsertUserStorageWithAlreadyHashedAndEncryptedEntries = async function _UserStorage_batchUpsertUserStorageWithAlreadyHashedAndEncryptedEntries(path, encryptedData, entropySourceId) {
|
|
151
|
+
}, _UserStorage_batchUpsertUserStorageWithAlreadyHashedAndEncryptedEntries = async function _UserStorage_batchUpsertUserStorageWithAlreadyHashedAndEncryptedEntries(path, encryptedData, entropySourceId, useCanonicalScope) {
|
|
148
152
|
try {
|
|
149
153
|
const headers = await __classPrivateFieldGet(this, _UserStorage_instances, "m", _UserStorage_getAuthorizationHeader).call(this, entropySourceId);
|
|
154
|
+
const profileScopeHeader = await __classPrivateFieldGet(this, _UserStorage_instances, "m", _UserStorage_getProfileScopeHeader).call(this, entropySourceId, useCanonicalScope);
|
|
150
155
|
const url = new URL((0, exports.STORAGE_URL)(this.env, path));
|
|
151
156
|
const response = await fetch(url.toString(), {
|
|
152
157
|
method: 'PUT',
|
|
153
158
|
headers: {
|
|
154
159
|
'Content-Type': 'application/json',
|
|
155
160
|
...headers,
|
|
161
|
+
...profileScopeHeader,
|
|
156
162
|
},
|
|
157
163
|
body: JSON.stringify({ data: Object.fromEntries(encryptedData) }),
|
|
158
164
|
});
|
|
@@ -213,12 +219,14 @@ _UserStorage_instances = new WeakSet(), _UserStorage_upsertUserStorage = async f
|
|
|
213
219
|
const entropySourceId = options?.entropySourceId;
|
|
214
220
|
try {
|
|
215
221
|
const headers = await __classPrivateFieldGet(this, _UserStorage_instances, "m", _UserStorage_getAuthorizationHeader).call(this, entropySourceId);
|
|
222
|
+
const profileScopeHeader = await __classPrivateFieldGet(this, _UserStorage_instances, "m", _UserStorage_getProfileScopeHeader).call(this, entropySourceId, options?.useCanonicalScope);
|
|
216
223
|
const storageKey = await this.getStorageKey(entropySourceId);
|
|
217
224
|
const url = new URL((0, exports.STORAGE_URL)(this.env, path));
|
|
218
225
|
const response = await fetch(url.toString(), {
|
|
219
226
|
headers: {
|
|
220
227
|
'Content-Type': 'application/json',
|
|
221
228
|
...headers,
|
|
229
|
+
...profileScopeHeader,
|
|
222
230
|
},
|
|
223
231
|
});
|
|
224
232
|
if (response.status === 404) {
|
|
@@ -256,7 +264,7 @@ _UserStorage_instances = new WeakSet(), _UserStorage_upsertUserStorage = async f
|
|
|
256
264
|
}
|
|
257
265
|
// Re-upload the re-encrypted entries
|
|
258
266
|
if (reEncryptedEntries.length) {
|
|
259
|
-
await __classPrivateFieldGet(this, _UserStorage_instances, "m", _UserStorage_batchUpsertUserStorageWithAlreadyHashedAndEncryptedEntries).call(this, path, reEncryptedEntries, entropySourceId);
|
|
267
|
+
await __classPrivateFieldGet(this, _UserStorage_instances, "m", _UserStorage_batchUpsertUserStorageWithAlreadyHashedAndEncryptedEntries).call(this, path, reEncryptedEntries, entropySourceId, options?.useCanonicalScope);
|
|
260
268
|
}
|
|
261
269
|
return decryptedData;
|
|
262
270
|
}
|
|
@@ -299,12 +307,14 @@ _UserStorage_instances = new WeakSet(), _UserStorage_upsertUserStorage = async f
|
|
|
299
307
|
try {
|
|
300
308
|
const entropySourceId = options?.entropySourceId;
|
|
301
309
|
const headers = await __classPrivateFieldGet(this, _UserStorage_instances, "m", _UserStorage_getAuthorizationHeader).call(this, entropySourceId);
|
|
310
|
+
const profileScopeHeader = await __classPrivateFieldGet(this, _UserStorage_instances, "m", _UserStorage_getProfileScopeHeader).call(this, entropySourceId, options?.useCanonicalScope);
|
|
302
311
|
const url = new URL((0, exports.STORAGE_URL)(this.env, path));
|
|
303
312
|
const response = await fetch(url.toString(), {
|
|
304
313
|
method: 'DELETE',
|
|
305
314
|
headers: {
|
|
306
315
|
'Content-Type': 'application/json',
|
|
307
316
|
...headers,
|
|
317
|
+
...profileScopeHeader,
|
|
308
318
|
},
|
|
309
319
|
});
|
|
310
320
|
if (response.status === 404) {
|
|
@@ -359,5 +369,18 @@ _UserStorage_instances = new WeakSet(), _UserStorage_upsertUserStorage = async f
|
|
|
359
369
|
}, _UserStorage_getAuthorizationHeader = async function _UserStorage_getAuthorizationHeader(entropySourceId) {
|
|
360
370
|
const accessToken = await this.config.auth.getAccessToken(entropySourceId);
|
|
361
371
|
return { Authorization: `Bearer ${accessToken}` };
|
|
372
|
+
}, _UserStorage_getProfileScopeHeader = async function _UserStorage_getProfileScopeHeader(entropySourceId, useCanonicalScope) {
|
|
373
|
+
if (useCanonicalScope) {
|
|
374
|
+
return {};
|
|
375
|
+
}
|
|
376
|
+
const profile = await this.config.auth.getUserProfile(entropySourceId);
|
|
377
|
+
if (profile.profileId !== profile.canonicalProfileId) {
|
|
378
|
+
// After SRP pairing the JWT `sub` is the canonical profile id, but
|
|
379
|
+
// user storage data is still keyed by the original per-SRP profileId.
|
|
380
|
+
// The `x-profile-id` header tells the backend to scope reads/writes to
|
|
381
|
+
// that alias partition until ADR 0005 migrates storage keys to canonical.
|
|
382
|
+
return { 'x-profile-id': profile.profileId };
|
|
383
|
+
}
|
|
384
|
+
return {};
|
|
362
385
|
};
|
|
363
386
|
//# sourceMappingURL=user-storage.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-storage.cjs","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 UserStorageGenericFeatureKey,\n UserStorageGenericFeatureName,\n UserStorageGenericPathWithFeatureAndKey,\n UserStorageGenericPathWithFeatureOnly,\n} from '../shared/storage-schema';\nimport { createEntryPath } from '../shared/storage-schema';\nimport type { NativeScrypt } from '../shared/types/encryption';\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: (message: `metamask:${string}`) => Promise<string | null>;\n setStorageKey: (message: `metamask:${string}`, val: string) => Promise<void>;\n};\n\nexport type UserStorageOptions = {\n storage?: StorageOptions;\n};\n\nexport type GetUserStorageAllFeatureEntriesResponse = {\n HashedKey: string;\n\n Data: string;\n}[];\n\nexport type UserStorageMethodOptions = {\n nativeScryptCrypto?: NativeScrypt;\n entropySourceId?: string;\n};\n\ntype ErrorMessage = {\n message: string;\n error: string;\n};\n\nexport class UserStorage {\n protected config: UserStorageConfig;\n\n public 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: UserStorageGenericPathWithFeatureAndKey,\n value: string,\n options?: UserStorageMethodOptions,\n ): Promise<void> {\n await this.#upsertUserStorage(path, value, options);\n }\n\n async batchSetItems(\n path: UserStorageGenericFeatureName,\n values: [UserStorageGenericFeatureKey, string][],\n options?: UserStorageMethodOptions,\n ) {\n await this.#batchUpsertUserStorage(path, values, options);\n }\n\n async getItem(\n path: UserStorageGenericPathWithFeatureAndKey,\n options?: UserStorageMethodOptions,\n ): Promise<string | null> {\n return this.#getUserStorage(path, options);\n }\n\n async getAllFeatureItems(\n path: UserStorageGenericFeatureName,\n options?: UserStorageMethodOptions,\n ): Promise<string[] | null> {\n return this.#getUserStorageAllFeatureEntries(path, options);\n }\n\n async deleteItem(\n path: UserStorageGenericPathWithFeatureAndKey,\n options?: UserStorageMethodOptions,\n ): Promise<void> {\n return this.#deleteUserStorage(path, options);\n }\n\n async deleteAllFeatureItems(\n path: UserStorageGenericFeatureName,\n options?: UserStorageMethodOptions,\n ): Promise<void> {\n return this.#deleteUserStorageAllFeatureEntries(path, options);\n }\n\n async batchDeleteItems(\n path: UserStorageGenericFeatureName,\n values: UserStorageGenericFeatureKey[],\n options?: UserStorageMethodOptions,\n ) {\n return this.#batchDeleteUserStorage(path, values, options);\n }\n\n async getStorageKey(entropySourceId?: string): Promise<string> {\n const userProfile = await this.config.auth.getUserProfile(entropySourceId);\n const message = `metamask:${userProfile.profileId}` as const;\n\n const storageKey = await this.options.storage?.getStorageKey(message);\n if (storageKey) {\n return storageKey;\n }\n\n const storageKeySignature = await this.config.auth.signMessage(\n message,\n entropySourceId,\n );\n const hashedStorageKeySignature = createSHA256Hash(storageKeySignature);\n await this.options.storage?.setStorageKey(\n message,\n hashedStorageKeySignature,\n );\n return hashedStorageKeySignature;\n }\n\n async #upsertUserStorage(\n path: UserStorageGenericPathWithFeatureAndKey,\n data: string,\n options?: UserStorageMethodOptions,\n ): Promise<void> {\n const entropySourceId = options?.entropySourceId;\n try {\n const headers = await this.#getAuthorizationHeader(entropySourceId);\n const storageKey = await this.getStorageKey(entropySourceId);\n const encryptedData = await encryption.encryptString(\n data,\n storageKey,\n options?.nativeScryptCrypto,\n );\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: UserStorageGenericPathWithFeatureOnly,\n data: [string, string][],\n options?: UserStorageMethodOptions,\n ): Promise<void> {\n const entropySourceId = options?.entropySourceId;\n try {\n if (!data.length) {\n return;\n }\n\n const headers = await this.#getAuthorizationHeader(entropySourceId);\n const storageKey = await this.getStorageKey(entropySourceId);\n\n const encryptedData = await Promise.all(\n data.map(async (d) => {\n return [\n this.#createEntryKey(d[0], storageKey),\n await encryption.encryptString(\n d[1],\n storageKey,\n options?.nativeScryptCrypto,\n ),\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: UserStorageGenericPathWithFeatureOnly,\n encryptedData: [string, string][],\n entropySourceId?: string,\n ): Promise<void> {\n try {\n const headers = await this.#getAuthorizationHeader(entropySourceId);\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 // istanbul ignore next\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 // istanbul ignore next\n throw new UserStorageError(\n `failed to batch upsert user storage for path '${path}'. ${errorMessage}`,\n );\n }\n }\n\n async #getUserStorage(\n path: UserStorageGenericPathWithFeatureAndKey,\n options?: UserStorageMethodOptions,\n ): Promise<string | null> {\n const entropySourceId = options?.entropySourceId;\n try {\n const headers = await this.#getAuthorizationHeader(entropySourceId);\n const storageKey = await this.getStorageKey(entropySourceId);\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 return null;\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 = await response.json();\n const encryptedData = userStorage?.Data ?? null;\n\n if (!encryptedData) {\n return null;\n }\n\n const decryptedData = await encryption.decryptString(\n encryptedData,\n storageKey,\n options?.nativeScryptCrypto,\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, options);\n }\n\n return decryptedData;\n } catch (e) {\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: UserStorageGenericPathWithFeatureOnly,\n options?: UserStorageMethodOptions,\n ): Promise<string[] | null> {\n const entropySourceId = options?.entropySourceId;\n try {\n const headers = await this.#getAuthorizationHeader(entropySourceId);\n const storageKey = await this.getStorageKey(entropySourceId);\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 return null;\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(\n entry.Data,\n storageKey,\n options?.nativeScryptCrypto,\n );\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(\n data,\n storageKey,\n options?.nativeScryptCrypto,\n ),\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 entropySourceId,\n );\n }\n\n return decryptedData;\n } catch (e) {\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: UserStorageGenericPathWithFeatureAndKey,\n options?: UserStorageMethodOptions,\n ): Promise<void> {\n const entropySourceId = options?.entropySourceId;\n try {\n const headers = await this.#getAuthorizationHeader(entropySourceId);\n const storageKey = await this.getStorageKey(entropySourceId);\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: UserStorageGenericPathWithFeatureOnly,\n options?: UserStorageMethodOptions,\n ): Promise<void> {\n try {\n const entropySourceId = options?.entropySourceId;\n const headers = await this.#getAuthorizationHeader(entropySourceId);\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: UserStorageGenericPathWithFeatureOnly,\n keysToDelete: string[],\n options?: UserStorageMethodOptions,\n ): Promise<void> {\n try {\n if (!keysToDelete.length) {\n return;\n }\n\n const entropySourceId = options?.entropySourceId;\n const headers = await this.#getAuthorizationHeader(entropySourceId);\n const storageKey = await this.getStorageKey(entropySourceId);\n\n const rawEntryKeys = keysToDelete.map((d) =>\n 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\n body: JSON.stringify({ batch_delete: rawEntryKeys }),\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 return createSHA256Hash(key + storageKey);\n }\n\n async #getAuthorizationHeader(\n entropySourceId?: string,\n ): Promise<{ Authorization: string }> {\n const accessToken = await this.config.auth.getAccessToken(entropySourceId);\n return { Authorization: `Bearer ${accessToken}` };\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"user-storage.cjs","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 UserStorageGenericFeatureKey,\n UserStorageGenericFeatureName,\n UserStorageGenericPathWithFeatureAndKey,\n UserStorageGenericPathWithFeatureOnly,\n} from '../shared/storage-schema';\nimport { createEntryPath } from '../shared/storage-schema';\nimport type { NativeScrypt } from '../shared/types/encryption';\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: (message: `metamask:${string}`) => Promise<string | null>;\n setStorageKey: (message: `metamask:${string}`, val: string) => Promise<void>;\n};\n\nexport type UserStorageOptions = {\n storage?: StorageOptions;\n};\n\nexport type GetUserStorageAllFeatureEntriesResponse = {\n HashedKey: string;\n\n Data: string;\n}[];\n\nexport type UserStorageMethodOptions = {\n nativeScryptCrypto?: NativeScrypt;\n entropySourceId?: string;\n /**\n * When true, skip the `x-profile-id` header on feature-scoped requests,\n * letting the server default to the JWT `sub` (canonical profile ID).\n * Useful during canonical storage migration (ADR 0005) to read/verify\n * data stored under the canonical key.\n */\n useCanonicalScope?: boolean;\n};\n\ntype ErrorMessage = {\n message: string;\n error: string;\n};\n\nexport class UserStorage {\n protected config: UserStorageConfig;\n\n public 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: UserStorageGenericPathWithFeatureAndKey,\n value: string,\n options?: UserStorageMethodOptions,\n ): Promise<void> {\n await this.#upsertUserStorage(path, value, options);\n }\n\n async batchSetItems(\n path: UserStorageGenericFeatureName,\n values: [UserStorageGenericFeatureKey, string][],\n options?: UserStorageMethodOptions,\n ) {\n await this.#batchUpsertUserStorage(path, values, options);\n }\n\n async getItem(\n path: UserStorageGenericPathWithFeatureAndKey,\n options?: UserStorageMethodOptions,\n ): Promise<string | null> {\n return this.#getUserStorage(path, options);\n }\n\n async getAllFeatureItems(\n path: UserStorageGenericFeatureName,\n options?: UserStorageMethodOptions,\n ): Promise<string[] | null> {\n return this.#getUserStorageAllFeatureEntries(path, options);\n }\n\n async deleteItem(\n path: UserStorageGenericPathWithFeatureAndKey,\n options?: UserStorageMethodOptions,\n ): Promise<void> {\n return this.#deleteUserStorage(path, options);\n }\n\n async deleteAllFeatureItems(\n path: UserStorageGenericFeatureName,\n options?: UserStorageMethodOptions,\n ): Promise<void> {\n return this.#deleteUserStorageAllFeatureEntries(path, options);\n }\n\n async batchDeleteItems(\n path: UserStorageGenericFeatureName,\n values: UserStorageGenericFeatureKey[],\n options?: UserStorageMethodOptions,\n ) {\n return this.#batchDeleteUserStorage(path, values, options);\n }\n\n async getStorageKey(entropySourceId?: string): Promise<string> {\n const userProfile = await this.config.auth.getUserProfile(entropySourceId);\n const message = `metamask:${userProfile.profileId}` as const;\n\n const storageKey = await this.options.storage?.getStorageKey(message);\n if (storageKey) {\n return storageKey;\n }\n\n const storageKeySignature = await this.config.auth.signMessage(\n message,\n entropySourceId,\n );\n const hashedStorageKeySignature = createSHA256Hash(storageKeySignature);\n await this.options.storage?.setStorageKey(\n message,\n hashedStorageKeySignature,\n );\n return hashedStorageKeySignature;\n }\n\n async #upsertUserStorage(\n path: UserStorageGenericPathWithFeatureAndKey,\n data: string,\n options?: UserStorageMethodOptions,\n ): Promise<void> {\n const entropySourceId = options?.entropySourceId;\n try {\n const headers = await this.#getAuthorizationHeader(entropySourceId);\n const profileScopeHeader = await this.#getProfileScopeHeader(\n entropySourceId,\n options?.useCanonicalScope,\n );\n const storageKey = await this.getStorageKey(entropySourceId);\n const encryptedData = await encryption.encryptString(\n data,\n storageKey,\n options?.nativeScryptCrypto,\n );\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 ...profileScopeHeader,\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: UserStorageGenericPathWithFeatureOnly,\n data: [string, string][],\n options?: UserStorageMethodOptions,\n ): Promise<void> {\n const entropySourceId = options?.entropySourceId;\n try {\n if (!data.length) {\n return;\n }\n\n const headers = await this.#getAuthorizationHeader(entropySourceId);\n const profileScopeHeader = await this.#getProfileScopeHeader(\n entropySourceId,\n options?.useCanonicalScope,\n );\n const storageKey = await this.getStorageKey(entropySourceId);\n\n const encryptedData = await Promise.all(\n data.map(async (d) => {\n return [\n this.#createEntryKey(d[0], storageKey),\n await encryption.encryptString(\n d[1],\n storageKey,\n options?.nativeScryptCrypto,\n ),\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 ...profileScopeHeader,\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: UserStorageGenericPathWithFeatureOnly,\n encryptedData: [string, string][],\n entropySourceId?: string,\n useCanonicalScope?: boolean,\n ): Promise<void> {\n try {\n const headers = await this.#getAuthorizationHeader(entropySourceId);\n const profileScopeHeader = await this.#getProfileScopeHeader(\n entropySourceId,\n useCanonicalScope,\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 ...profileScopeHeader,\n },\n body: JSON.stringify({ data: Object.fromEntries(encryptedData) }),\n });\n\n // istanbul ignore next\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 // istanbul ignore next\n throw new UserStorageError(\n `failed to batch upsert user storage for path '${path}'. ${errorMessage}`,\n );\n }\n }\n\n async #getUserStorage(\n path: UserStorageGenericPathWithFeatureAndKey,\n options?: UserStorageMethodOptions,\n ): Promise<string | null> {\n const entropySourceId = options?.entropySourceId;\n try {\n const headers = await this.#getAuthorizationHeader(entropySourceId);\n const storageKey = await this.getStorageKey(entropySourceId);\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 return null;\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 = await response.json();\n const encryptedData = userStorage?.Data ?? null;\n\n if (!encryptedData) {\n return null;\n }\n\n const decryptedData = await encryption.decryptString(\n encryptedData,\n storageKey,\n options?.nativeScryptCrypto,\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, options);\n }\n\n return decryptedData;\n } catch (e) {\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: UserStorageGenericPathWithFeatureOnly,\n options?: UserStorageMethodOptions,\n ): Promise<string[] | null> {\n const entropySourceId = options?.entropySourceId;\n try {\n const headers = await this.#getAuthorizationHeader(entropySourceId);\n const profileScopeHeader = await this.#getProfileScopeHeader(\n entropySourceId,\n options?.useCanonicalScope,\n );\n const storageKey = await this.getStorageKey(entropySourceId);\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 ...profileScopeHeader,\n },\n });\n\n if (response.status === 404) {\n return null;\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(\n entry.Data,\n storageKey,\n options?.nativeScryptCrypto,\n );\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(\n data,\n storageKey,\n options?.nativeScryptCrypto,\n ),\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 entropySourceId,\n options?.useCanonicalScope,\n );\n }\n\n return decryptedData;\n } catch (e) {\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: UserStorageGenericPathWithFeatureAndKey,\n options?: UserStorageMethodOptions,\n ): Promise<void> {\n const entropySourceId = options?.entropySourceId;\n try {\n const headers = await this.#getAuthorizationHeader(entropySourceId);\n const storageKey = await this.getStorageKey(entropySourceId);\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: UserStorageGenericPathWithFeatureOnly,\n options?: UserStorageMethodOptions,\n ): Promise<void> {\n try {\n const entropySourceId = options?.entropySourceId;\n const headers = await this.#getAuthorizationHeader(entropySourceId);\n const profileScopeHeader = await this.#getProfileScopeHeader(\n entropySourceId,\n options?.useCanonicalScope,\n );\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 ...profileScopeHeader,\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: UserStorageGenericPathWithFeatureOnly,\n keysToDelete: string[],\n options?: UserStorageMethodOptions,\n ): Promise<void> {\n try {\n if (!keysToDelete.length) {\n return;\n }\n\n const entropySourceId = options?.entropySourceId;\n const headers = await this.#getAuthorizationHeader(entropySourceId);\n const storageKey = await this.getStorageKey(entropySourceId);\n\n const rawEntryKeys = keysToDelete.map((d) =>\n 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\n body: JSON.stringify({ batch_delete: rawEntryKeys }),\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 return createSHA256Hash(key + storageKey);\n }\n\n async #getAuthorizationHeader(\n entropySourceId?: string,\n ): Promise<{ Authorization: string }> {\n const accessToken = await this.config.auth.getAccessToken(entropySourceId);\n return { Authorization: `Bearer ${accessToken}` };\n }\n\n async #getProfileScopeHeader(\n entropySourceId?: string,\n useCanonicalScope?: boolean,\n ): Promise<Record<string, string>> {\n if (useCanonicalScope) {\n return {};\n }\n const profile = await this.config.auth.getUserProfile(entropySourceId);\n if (profile.profileId !== profile.canonicalProfileId) {\n // After SRP pairing the JWT `sub` is the canonical profile id, but\n // user storage data is still keyed by the original per-SRP profileId.\n // The `x-profile-id` header tells the backend to scope reads/writes to\n // that alias partition until ADR 0005 migrates storage keys to canonical.\n return { 'x-profile-id': profile.profileId };\n }\n return {};\n }\n}\n"]}
|
|
@@ -21,6 +21,13 @@ export type GetUserStorageAllFeatureEntriesResponse = {
|
|
|
21
21
|
export type UserStorageMethodOptions = {
|
|
22
22
|
nativeScryptCrypto?: NativeScrypt;
|
|
23
23
|
entropySourceId?: string;
|
|
24
|
+
/**
|
|
25
|
+
* When true, skip the `x-profile-id` header on feature-scoped requests,
|
|
26
|
+
* letting the server default to the JWT `sub` (canonical profile ID).
|
|
27
|
+
* Useful during canonical storage migration (ADR 0005) to read/verify
|
|
28
|
+
* data stored under the canonical key.
|
|
29
|
+
*/
|
|
30
|
+
useCanonicalScope?: boolean;
|
|
24
31
|
};
|
|
25
32
|
export declare class UserStorage {
|
|
26
33
|
#private;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-storage.d.cts","sourceRoot":"","sources":["../../src/sdk/user-storage.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,GAAG,EAAE,0BAAsB;AAEzC,OAAO,KAAK,EACV,4BAA4B,EAC5B,6BAA6B,EAC7B,uCAAuC,EAExC,qCAAiC;AAElC,OAAO,KAAK,EAAE,YAAY,EAAE,uCAAmC;AAC/D,OAAO,KAAK,EAAE,SAAS,EAAE,8CAA0C;AAGnE,eAAO,MAAM,WAAW,QAAS,GAAG,iBAAiB,MAAM,WACiB,CAAC;AAE7E,MAAM,MAAM,iBAAiB,GAAG;IAC9B,GAAG,EAAE,GAAG,CAAC;IACT,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,gBAAgB,GAAG,gBAAgB,GAAG,aAAa,CAAC,CAAC;CAC5E,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,aAAa,EAAE,CAAC,OAAO,EAAE,YAAY,MAAM,EAAE,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACzE,aAAa,EAAE,CAAC,OAAO,EAAE,YAAY,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9E,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,uCAAuC,GAAG;IACpD,SAAS,EAAE,MAAM,CAAC;IAElB,IAAI,EAAE,MAAM,CAAC;CACd,EAAE,CAAC;AAEJ,MAAM,MAAM,wBAAwB,GAAG;IACrC,kBAAkB,CAAC,EAAE,YAAY,CAAC;IAClC,eAAe,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"user-storage.d.cts","sourceRoot":"","sources":["../../src/sdk/user-storage.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,GAAG,EAAE,0BAAsB;AAEzC,OAAO,KAAK,EACV,4BAA4B,EAC5B,6BAA6B,EAC7B,uCAAuC,EAExC,qCAAiC;AAElC,OAAO,KAAK,EAAE,YAAY,EAAE,uCAAmC;AAC/D,OAAO,KAAK,EAAE,SAAS,EAAE,8CAA0C;AAGnE,eAAO,MAAM,WAAW,QAAS,GAAG,iBAAiB,MAAM,WACiB,CAAC;AAE7E,MAAM,MAAM,iBAAiB,GAAG;IAC9B,GAAG,EAAE,GAAG,CAAC;IACT,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,gBAAgB,GAAG,gBAAgB,GAAG,aAAa,CAAC,CAAC;CAC5E,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,aAAa,EAAE,CAAC,OAAO,EAAE,YAAY,MAAM,EAAE,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACzE,aAAa,EAAE,CAAC,OAAO,EAAE,YAAY,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9E,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,uCAAuC,GAAG;IACpD,SAAS,EAAE,MAAM,CAAC;IAElB,IAAI,EAAE,MAAM,CAAC;CACd,EAAE,CAAC;AAEJ,MAAM,MAAM,wBAAwB,GAAG;IACrC,kBAAkB,CAAC,EAAE,YAAY,CAAC;IAClC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B,CAAC;AAOF,qBAAa,WAAW;;IACtB,SAAS,CAAC,MAAM,EAAE,iBAAiB,CAAC;IAE7B,OAAO,EAAE,kBAAkB,CAAC;IAEnC,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC;gBAEP,MAAM,EAAE,iBAAiB,EAAE,OAAO,EAAE,kBAAkB;IAM5D,OAAO,CACX,IAAI,EAAE,uCAAuC,EAC7C,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,wBAAwB,GACjC,OAAO,CAAC,IAAI,CAAC;IAIV,aAAa,CACjB,IAAI,EAAE,6BAA6B,EACnC,MAAM,EAAE,CAAC,4BAA4B,EAAE,MAAM,CAAC,EAAE,EAChD,OAAO,CAAC,EAAE,wBAAwB;IAK9B,OAAO,CACX,IAAI,EAAE,uCAAuC,EAC7C,OAAO,CAAC,EAAE,wBAAwB,GACjC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAInB,kBAAkB,CACtB,IAAI,EAAE,6BAA6B,EACnC,OAAO,CAAC,EAAE,wBAAwB,GACjC,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC;IAIrB,UAAU,CACd,IAAI,EAAE,uCAAuC,EAC7C,OAAO,CAAC,EAAE,wBAAwB,GACjC,OAAO,CAAC,IAAI,CAAC;IAIV,qBAAqB,CACzB,IAAI,EAAE,6BAA6B,EACnC,OAAO,CAAC,EAAE,wBAAwB,GACjC,OAAO,CAAC,IAAI,CAAC;IAIV,gBAAgB,CACpB,IAAI,EAAE,6BAA6B,EACnC,MAAM,EAAE,4BAA4B,EAAE,EACtC,OAAO,CAAC,EAAE,wBAAwB;IAK9B,aAAa,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CA6f/D"}
|
|
@@ -21,6 +21,13 @@ export type GetUserStorageAllFeatureEntriesResponse = {
|
|
|
21
21
|
export type UserStorageMethodOptions = {
|
|
22
22
|
nativeScryptCrypto?: NativeScrypt;
|
|
23
23
|
entropySourceId?: string;
|
|
24
|
+
/**
|
|
25
|
+
* When true, skip the `x-profile-id` header on feature-scoped requests,
|
|
26
|
+
* letting the server default to the JWT `sub` (canonical profile ID).
|
|
27
|
+
* Useful during canonical storage migration (ADR 0005) to read/verify
|
|
28
|
+
* data stored under the canonical key.
|
|
29
|
+
*/
|
|
30
|
+
useCanonicalScope?: boolean;
|
|
24
31
|
};
|
|
25
32
|
export declare class UserStorage {
|
|
26
33
|
#private;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-storage.d.mts","sourceRoot":"","sources":["../../src/sdk/user-storage.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,GAAG,EAAE,0BAAsB;AAEzC,OAAO,KAAK,EACV,4BAA4B,EAC5B,6BAA6B,EAC7B,uCAAuC,EAExC,qCAAiC;AAElC,OAAO,KAAK,EAAE,YAAY,EAAE,uCAAmC;AAC/D,OAAO,KAAK,EAAE,SAAS,EAAE,8CAA0C;AAGnE,eAAO,MAAM,WAAW,QAAS,GAAG,iBAAiB,MAAM,WACiB,CAAC;AAE7E,MAAM,MAAM,iBAAiB,GAAG;IAC9B,GAAG,EAAE,GAAG,CAAC;IACT,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,gBAAgB,GAAG,gBAAgB,GAAG,aAAa,CAAC,CAAC;CAC5E,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,aAAa,EAAE,CAAC,OAAO,EAAE,YAAY,MAAM,EAAE,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACzE,aAAa,EAAE,CAAC,OAAO,EAAE,YAAY,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9E,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,uCAAuC,GAAG;IACpD,SAAS,EAAE,MAAM,CAAC;IAElB,IAAI,EAAE,MAAM,CAAC;CACd,EAAE,CAAC;AAEJ,MAAM,MAAM,wBAAwB,GAAG;IACrC,kBAAkB,CAAC,EAAE,YAAY,CAAC;IAClC,eAAe,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"user-storage.d.mts","sourceRoot":"","sources":["../../src/sdk/user-storage.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,GAAG,EAAE,0BAAsB;AAEzC,OAAO,KAAK,EACV,4BAA4B,EAC5B,6BAA6B,EAC7B,uCAAuC,EAExC,qCAAiC;AAElC,OAAO,KAAK,EAAE,YAAY,EAAE,uCAAmC;AAC/D,OAAO,KAAK,EAAE,SAAS,EAAE,8CAA0C;AAGnE,eAAO,MAAM,WAAW,QAAS,GAAG,iBAAiB,MAAM,WACiB,CAAC;AAE7E,MAAM,MAAM,iBAAiB,GAAG;IAC9B,GAAG,EAAE,GAAG,CAAC;IACT,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,gBAAgB,GAAG,gBAAgB,GAAG,aAAa,CAAC,CAAC;CAC5E,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,aAAa,EAAE,CAAC,OAAO,EAAE,YAAY,MAAM,EAAE,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACzE,aAAa,EAAE,CAAC,OAAO,EAAE,YAAY,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9E,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,uCAAuC,GAAG;IACpD,SAAS,EAAE,MAAM,CAAC;IAElB,IAAI,EAAE,MAAM,CAAC;CACd,EAAE,CAAC;AAEJ,MAAM,MAAM,wBAAwB,GAAG;IACrC,kBAAkB,CAAC,EAAE,YAAY,CAAC;IAClC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B,CAAC;AAOF,qBAAa,WAAW;;IACtB,SAAS,CAAC,MAAM,EAAE,iBAAiB,CAAC;IAE7B,OAAO,EAAE,kBAAkB,CAAC;IAEnC,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC;gBAEP,MAAM,EAAE,iBAAiB,EAAE,OAAO,EAAE,kBAAkB;IAM5D,OAAO,CACX,IAAI,EAAE,uCAAuC,EAC7C,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,wBAAwB,GACjC,OAAO,CAAC,IAAI,CAAC;IAIV,aAAa,CACjB,IAAI,EAAE,6BAA6B,EACnC,MAAM,EAAE,CAAC,4BAA4B,EAAE,MAAM,CAAC,EAAE,EAChD,OAAO,CAAC,EAAE,wBAAwB;IAK9B,OAAO,CACX,IAAI,EAAE,uCAAuC,EAC7C,OAAO,CAAC,EAAE,wBAAwB,GACjC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAInB,kBAAkB,CACtB,IAAI,EAAE,6BAA6B,EACnC,OAAO,CAAC,EAAE,wBAAwB,GACjC,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC;IAIrB,UAAU,CACd,IAAI,EAAE,uCAAuC,EAC7C,OAAO,CAAC,EAAE,wBAAwB,GACjC,OAAO,CAAC,IAAI,CAAC;IAIV,qBAAqB,CACzB,IAAI,EAAE,6BAA6B,EACnC,OAAO,CAAC,EAAE,wBAAwB,GACjC,OAAO,CAAC,IAAI,CAAC;IAIV,gBAAgB,CACpB,IAAI,EAAE,6BAA6B,EACnC,MAAM,EAAE,4BAA4B,EAAE,EACtC,OAAO,CAAC,EAAE,wBAAwB;IAK9B,aAAa,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CA6f/D"}
|
|
@@ -3,7 +3,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
3
3
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
4
4
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
5
5
|
};
|
|
6
|
-
var _UserStorage_instances, _UserStorage_upsertUserStorage, _UserStorage_batchUpsertUserStorage, _UserStorage_batchUpsertUserStorageWithAlreadyHashedAndEncryptedEntries, _UserStorage_getUserStorage, _UserStorage_getUserStorageAllFeatureEntries, _UserStorage_deleteUserStorage, _UserStorage_deleteUserStorageAllFeatureEntries, _UserStorage_batchDeleteUserStorage, _UserStorage_createEntryKey, _UserStorage_getAuthorizationHeader;
|
|
6
|
+
var _UserStorage_instances, _UserStorage_upsertUserStorage, _UserStorage_batchUpsertUserStorage, _UserStorage_batchUpsertUserStorageWithAlreadyHashedAndEncryptedEntries, _UserStorage_getUserStorage, _UserStorage_getUserStorageAllFeatureEntries, _UserStorage_deleteUserStorage, _UserStorage_deleteUserStorageAllFeatureEntries, _UserStorage_batchDeleteUserStorage, _UserStorage_createEntryKey, _UserStorage_getAuthorizationHeader, _UserStorage_getProfileScopeHeader;
|
|
7
7
|
import encryption, { createSHA256Hash } from "../shared/encryption/index.mjs";
|
|
8
8
|
import { SHARED_SALT } from "../shared/encryption/constants.mjs";
|
|
9
9
|
import { getEnvUrls } from "../shared/env.mjs";
|
|
@@ -55,6 +55,7 @@ _UserStorage_instances = new WeakSet(), _UserStorage_upsertUserStorage = async f
|
|
|
55
55
|
const entropySourceId = options?.entropySourceId;
|
|
56
56
|
try {
|
|
57
57
|
const headers = await __classPrivateFieldGet(this, _UserStorage_instances, "m", _UserStorage_getAuthorizationHeader).call(this, entropySourceId);
|
|
58
|
+
const profileScopeHeader = await __classPrivateFieldGet(this, _UserStorage_instances, "m", _UserStorage_getProfileScopeHeader).call(this, entropySourceId, options?.useCanonicalScope);
|
|
58
59
|
const storageKey = await this.getStorageKey(entropySourceId);
|
|
59
60
|
const encryptedData = await encryption.encryptString(data, storageKey, options?.nativeScryptCrypto);
|
|
60
61
|
const encryptedPath = createEntryPath(path, storageKey);
|
|
@@ -64,6 +65,7 @@ _UserStorage_instances = new WeakSet(), _UserStorage_upsertUserStorage = async f
|
|
|
64
65
|
headers: {
|
|
65
66
|
'Content-Type': 'application/json',
|
|
66
67
|
...headers,
|
|
68
|
+
...profileScopeHeader,
|
|
67
69
|
},
|
|
68
70
|
body: JSON.stringify({ data: encryptedData }),
|
|
69
71
|
});
|
|
@@ -87,6 +89,7 @@ _UserStorage_instances = new WeakSet(), _UserStorage_upsertUserStorage = async f
|
|
|
87
89
|
return;
|
|
88
90
|
}
|
|
89
91
|
const headers = await __classPrivateFieldGet(this, _UserStorage_instances, "m", _UserStorage_getAuthorizationHeader).call(this, entropySourceId);
|
|
92
|
+
const profileScopeHeader = await __classPrivateFieldGet(this, _UserStorage_instances, "m", _UserStorage_getProfileScopeHeader).call(this, entropySourceId, options?.useCanonicalScope);
|
|
90
93
|
const storageKey = await this.getStorageKey(entropySourceId);
|
|
91
94
|
const encryptedData = await Promise.all(data.map(async (d) => {
|
|
92
95
|
return [
|
|
@@ -100,6 +103,7 @@ _UserStorage_instances = new WeakSet(), _UserStorage_upsertUserStorage = async f
|
|
|
100
103
|
headers: {
|
|
101
104
|
'Content-Type': 'application/json',
|
|
102
105
|
...headers,
|
|
106
|
+
...profileScopeHeader,
|
|
103
107
|
},
|
|
104
108
|
body: JSON.stringify({ data: Object.fromEntries(encryptedData) }),
|
|
105
109
|
});
|
|
@@ -116,15 +120,17 @@ _UserStorage_instances = new WeakSet(), _UserStorage_upsertUserStorage = async f
|
|
|
116
120
|
const errorMessage = e instanceof Error ? e.message : JSON.stringify(e ?? '');
|
|
117
121
|
throw new UserStorageError(`failed to batch upsert user storage for path '${path}'. ${errorMessage}`);
|
|
118
122
|
}
|
|
119
|
-
}, _UserStorage_batchUpsertUserStorageWithAlreadyHashedAndEncryptedEntries = async function _UserStorage_batchUpsertUserStorageWithAlreadyHashedAndEncryptedEntries(path, encryptedData, entropySourceId) {
|
|
123
|
+
}, _UserStorage_batchUpsertUserStorageWithAlreadyHashedAndEncryptedEntries = async function _UserStorage_batchUpsertUserStorageWithAlreadyHashedAndEncryptedEntries(path, encryptedData, entropySourceId, useCanonicalScope) {
|
|
120
124
|
try {
|
|
121
125
|
const headers = await __classPrivateFieldGet(this, _UserStorage_instances, "m", _UserStorage_getAuthorizationHeader).call(this, entropySourceId);
|
|
126
|
+
const profileScopeHeader = await __classPrivateFieldGet(this, _UserStorage_instances, "m", _UserStorage_getProfileScopeHeader).call(this, entropySourceId, useCanonicalScope);
|
|
122
127
|
const url = new URL(STORAGE_URL(this.env, path));
|
|
123
128
|
const response = await fetch(url.toString(), {
|
|
124
129
|
method: 'PUT',
|
|
125
130
|
headers: {
|
|
126
131
|
'Content-Type': 'application/json',
|
|
127
132
|
...headers,
|
|
133
|
+
...profileScopeHeader,
|
|
128
134
|
},
|
|
129
135
|
body: JSON.stringify({ data: Object.fromEntries(encryptedData) }),
|
|
130
136
|
});
|
|
@@ -185,12 +191,14 @@ _UserStorage_instances = new WeakSet(), _UserStorage_upsertUserStorage = async f
|
|
|
185
191
|
const entropySourceId = options?.entropySourceId;
|
|
186
192
|
try {
|
|
187
193
|
const headers = await __classPrivateFieldGet(this, _UserStorage_instances, "m", _UserStorage_getAuthorizationHeader).call(this, entropySourceId);
|
|
194
|
+
const profileScopeHeader = await __classPrivateFieldGet(this, _UserStorage_instances, "m", _UserStorage_getProfileScopeHeader).call(this, entropySourceId, options?.useCanonicalScope);
|
|
188
195
|
const storageKey = await this.getStorageKey(entropySourceId);
|
|
189
196
|
const url = new URL(STORAGE_URL(this.env, path));
|
|
190
197
|
const response = await fetch(url.toString(), {
|
|
191
198
|
headers: {
|
|
192
199
|
'Content-Type': 'application/json',
|
|
193
200
|
...headers,
|
|
201
|
+
...profileScopeHeader,
|
|
194
202
|
},
|
|
195
203
|
});
|
|
196
204
|
if (response.status === 404) {
|
|
@@ -228,7 +236,7 @@ _UserStorage_instances = new WeakSet(), _UserStorage_upsertUserStorage = async f
|
|
|
228
236
|
}
|
|
229
237
|
// Re-upload the re-encrypted entries
|
|
230
238
|
if (reEncryptedEntries.length) {
|
|
231
|
-
await __classPrivateFieldGet(this, _UserStorage_instances, "m", _UserStorage_batchUpsertUserStorageWithAlreadyHashedAndEncryptedEntries).call(this, path, reEncryptedEntries, entropySourceId);
|
|
239
|
+
await __classPrivateFieldGet(this, _UserStorage_instances, "m", _UserStorage_batchUpsertUserStorageWithAlreadyHashedAndEncryptedEntries).call(this, path, reEncryptedEntries, entropySourceId, options?.useCanonicalScope);
|
|
232
240
|
}
|
|
233
241
|
return decryptedData;
|
|
234
242
|
}
|
|
@@ -271,12 +279,14 @@ _UserStorage_instances = new WeakSet(), _UserStorage_upsertUserStorage = async f
|
|
|
271
279
|
try {
|
|
272
280
|
const entropySourceId = options?.entropySourceId;
|
|
273
281
|
const headers = await __classPrivateFieldGet(this, _UserStorage_instances, "m", _UserStorage_getAuthorizationHeader).call(this, entropySourceId);
|
|
282
|
+
const profileScopeHeader = await __classPrivateFieldGet(this, _UserStorage_instances, "m", _UserStorage_getProfileScopeHeader).call(this, entropySourceId, options?.useCanonicalScope);
|
|
274
283
|
const url = new URL(STORAGE_URL(this.env, path));
|
|
275
284
|
const response = await fetch(url.toString(), {
|
|
276
285
|
method: 'DELETE',
|
|
277
286
|
headers: {
|
|
278
287
|
'Content-Type': 'application/json',
|
|
279
288
|
...headers,
|
|
289
|
+
...profileScopeHeader,
|
|
280
290
|
},
|
|
281
291
|
});
|
|
282
292
|
if (response.status === 404) {
|
|
@@ -331,5 +341,18 @@ _UserStorage_instances = new WeakSet(), _UserStorage_upsertUserStorage = async f
|
|
|
331
341
|
}, _UserStorage_getAuthorizationHeader = async function _UserStorage_getAuthorizationHeader(entropySourceId) {
|
|
332
342
|
const accessToken = await this.config.auth.getAccessToken(entropySourceId);
|
|
333
343
|
return { Authorization: `Bearer ${accessToken}` };
|
|
344
|
+
}, _UserStorage_getProfileScopeHeader = async function _UserStorage_getProfileScopeHeader(entropySourceId, useCanonicalScope) {
|
|
345
|
+
if (useCanonicalScope) {
|
|
346
|
+
return {};
|
|
347
|
+
}
|
|
348
|
+
const profile = await this.config.auth.getUserProfile(entropySourceId);
|
|
349
|
+
if (profile.profileId !== profile.canonicalProfileId) {
|
|
350
|
+
// After SRP pairing the JWT `sub` is the canonical profile id, but
|
|
351
|
+
// user storage data is still keyed by the original per-SRP profileId.
|
|
352
|
+
// The `x-profile-id` header tells the backend to scope reads/writes to
|
|
353
|
+
// that alias partition until ADR 0005 migrates storage keys to canonical.
|
|
354
|
+
return { 'x-profile-id': profile.profileId };
|
|
355
|
+
}
|
|
356
|
+
return {};
|
|
334
357
|
};
|
|
335
358
|
//# sourceMappingURL=user-storage.mjs.map
|