matrix-js-sdk 41.3.0 → 41.4.0
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 +17 -0
- package/lib/@types/event.d.ts +9 -0
- package/lib/@types/event.d.ts.map +1 -1
- package/lib/@types/event.js.map +1 -1
- package/lib/crypto-api/index.d.ts +27 -5
- package/lib/crypto-api/index.d.ts.map +1 -1
- package/lib/crypto-api/index.js +22 -3
- package/lib/crypto-api/index.js.map +1 -1
- package/lib/embedded.js +1 -1
- package/lib/embedded.js.map +1 -1
- package/lib/matrixrtc/MatrixRTCSession.js +2 -1
- package/lib/matrixrtc/MatrixRTCSession.js.map +1 -1
- package/lib/matrixrtc/membershipData/rtc.d.ts.map +1 -1
- package/lib/matrixrtc/membershipData/rtc.js +5 -4
- package/lib/matrixrtc/membershipData/rtc.js.map +1 -1
- package/lib/oidc/authorize.d.ts +8 -4
- package/lib/oidc/authorize.d.ts.map +1 -1
- package/lib/oidc/authorize.js +18 -6
- package/lib/oidc/authorize.js.map +1 -1
- package/lib/oidc/discovery.js +1 -1
- package/lib/oidc/discovery.js.map +1 -1
- package/lib/rust-crypto/backup.d.ts +6 -2
- package/lib/rust-crypto/backup.d.ts.map +1 -1
- package/lib/rust-crypto/backup.js +30 -10
- package/lib/rust-crypto/backup.js.map +1 -1
- package/lib/rust-crypto/rust-crypto.d.ts +16 -11
- package/lib/rust-crypto/rust-crypto.d.ts.map +1 -1
- package/lib/rust-crypto/rust-crypto.js +38 -21
- package/lib/rust-crypto/rust-crypto.js.map +1 -1
- package/lib/store/indexeddb-local-backend.d.ts.map +1 -1
- package/lib/store/indexeddb-local-backend.js +4 -2
- package/lib/store/indexeddb-local-backend.js.map +1 -1
- package/package.json +14 -10
- package/src/@types/event.ts +14 -2
- package/src/crypto-api/index.ts +30 -5
- package/src/embedded.ts +1 -1
- package/src/matrixrtc/MatrixRTCSession.ts +2 -1
- package/src/matrixrtc/membershipData/rtc.ts +5 -4
- package/src/oidc/authorize.ts +25 -6
- package/src/oidc/discovery.ts +1 -1
- package/src/rust-crypto/backup.ts +31 -10
- package/src/rust-crypto/rust-crypto.ts +28 -13
- package/src/store/indexeddb-local-backend.ts +2 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"indexeddb-local-backend.d.ts","sourceRoot":"","sources":["../../src/store/indexeddb-local-backend.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAsC,KAAK,aAAa,EAAmB,MAAM,wBAAwB,CAAC;AAIjH,OAAO,EAAE,KAAK,qBAAqB,EAAE,KAAK,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAClF,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAChF,OAAO,EAAE,KAAK,oBAAoB,EAAE,KAAK,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"indexeddb-local-backend.d.ts","sourceRoot":"","sources":["../../src/store/indexeddb-local-backend.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAsC,KAAK,aAAa,EAAmB,MAAM,wBAAwB,CAAC;AAIjH,OAAO,EAAE,KAAK,qBAAqB,EAAE,KAAK,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAClF,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAChF,OAAO,EAAE,KAAK,oBAAoB,EAAE,KAAK,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAmGtG,qBAAa,0BAA2B,YAAW,iBAAiB;IAyB5D,OAAO,CAAC,QAAQ,CAAC,SAAS;WAxBhB,MAAM,CAAC,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAK7E,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkB;IAClD,OAAO,CAAC,EAAE,CAAC,CAAc;IACzB,OAAO,CAAC,YAAY,CAAQ;IAC5B,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,qBAAqB,CAAC,CAAgB;IAC9C,OAAO,CAAC,uBAAuB,CAAmB;IAElD;;;;;;;;;OASG;gBAEkB,SAAS,EAAE,UAAU,EACtC,MAAM,SAAY;IAMtB;;;;OAIG;IACI,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAiDnD,8EAA8E;IACvE,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;IAIzC;;;OAGG;IACH,OAAO,CAAC,IAAI;IAgBZ;;;;;OAKG;IACI,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,EAAE,GAAG,IAAI,CAAC;IA0CnF;;;;;OAKG;IACU,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAsB7F,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgCjE;;;;OAIG;IACI,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IA4BrC;;;;;;;;OAQG;IACI,YAAY,CAAC,IAAI,UAAO,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAYrD,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC;IAIpC,WAAW,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAM1D;;;;;;OAMG;IACU,cAAc,CAAC,UAAU,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;YAWrD,gBAAgB;IAa9B;;;;;OAKG;IACH,OAAO,CAAC,eAAe;IAgBvB;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;IAW1B;;;;;;;OAOG;IACH,OAAO,CAAC,yBAAyB;IAcjC;;;;;OAKG;IACI,qBAAqB,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAUpD;;;OAGG;IACH,OAAO,CAAC,eAAe;IAcvB;;;OAGG;IACH,OAAO,CAAC,YAAY;IAiBb,gBAAgB,IAAI,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC;IAUpD,kBAAkB,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAU7D,mBAAmB,CAAC,OAAO,EAAE,sBAAsB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IASrE,sBAAsB,IAAI,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAgB9D,mBAAmB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAU9C,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAGxC"}
|
|
@@ -63,14 +63,16 @@ var VERSION = DB_MIGRATIONS.length;
|
|
|
63
63
|
* Return the data you want to keep.
|
|
64
64
|
* @returns Promise which resolves to an array of whatever you returned from
|
|
65
65
|
* resultMapper.
|
|
66
|
+
* @throws If there was an error completing the query.
|
|
66
67
|
*/
|
|
67
68
|
function selectQuery(store, keyRange, resultMapper) {
|
|
68
69
|
var query = store.openCursor(keyRange);
|
|
69
70
|
return new Promise((resolve, reject) => {
|
|
70
71
|
var results = [];
|
|
71
72
|
query.onerror = () => {
|
|
72
|
-
|
|
73
|
-
|
|
73
|
+
reject(new Error("selectQuery failed for ".concat(store.name), {
|
|
74
|
+
cause: query.error
|
|
75
|
+
}));
|
|
74
76
|
};
|
|
75
77
|
// collect results
|
|
76
78
|
query.onsuccess = () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"indexeddb-local-backend.js","names":["SyncAccumulator","deepCopy","promiseTry","exists","idbExists","logger","DB_MIGRATIONS","db","createObjectStore","keyPath","oobMembersStore","createIndex","autoIncrement","VERSION","length","selectQuery","store","keyRange","resultMapper","query","openCursor","Promise","resolve","reject","results","onerror","_query$error","Error","error","name","onsuccess","cursor","result","push","continue","txnAsPromise","txn","oncomplete","event","reqAsEventPromise","req","reqAsPromise","err","reqAsCursorPromise","then","LocalIndexedDBStoreBackend","indexedDB","dbName","constructor","arguments","undefined","_defineProperty","syncAccumulator","connect","onClose","_this","disconnected","log","open","onupgradeneeded","ev","oldVersion","concat","_isNewlyCreated","forEach","migration","index","onblocked","_asyncToGenerator","onversionchange","_this$db","close","onclose","init","isNewlyCreated","all","loadAccountData","loadSyncData","_ref2","accountData","syncData","accumulate","next_batch","nextBatch","rooms","roomsData","account_data","events","getOutOfBandMembers","roomId","tx","transaction","objectStore","roomIndex","range","IDBKeyRange","only","request","membershipEvents","oobWritten","record","value","oob_written","setOutOfBandMembers","_this2","e","put","markerObject","room_id","state_key","clearOutOfBandMembers","_this3","readTx","roomRange","minStateKeyProm","openKeyCursor","primaryKey","maxStateKeyProm","minStateKey","maxStateKey","writeTx","writeStore","membersKeyRange","bound","delete","clearDatabase","_this$db2","deleteDatabase","_req$error","warn","getSavedSync","copy","data","getJSON","getNextBatchToken","setSyncData","syncToDatabase","userTuples","_this4","syncToDatabasePromise","pendingUserPresenceData","unshift","doSyncToDatabase","_this5","persistUserPresenceEvents","persistAccountData","persistSyncData","clobber","tuples","tuple","userId","getUserPresenceEvents","getClientOptions","_cursor$value","options","storeClientOptions","_this6","saveToDeviceBatches","batches","_this7","batch","add","getOldestToDeviceBatch","_this8","resultBatch","id","key","txnId","eventType","removeToDeviceBatch","_this9","destroy","_this0","_this0$db"],"sources":["../../src/store/indexeddb-local-backend.ts"],"sourcesContent":["/*\nCopyright 2017 - 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { type IMinimalEvent, type ISyncData, type ISyncResponse, SyncAccumulator } from \"../sync-accumulator.ts\";\nimport { deepCopy, promiseTry } from \"../utils.ts\";\nimport { exists as idbExists } from \"../indexeddb-helpers.ts\";\nimport { logger } from \"../logger.ts\";\nimport { type IStateEventWithRoomId, type IStoredClientOpts } from \"../matrix.ts\";\nimport { type ISavedSync } from \"./index.ts\";\nimport { type IIndexedDBBackend, type UserTuple } from \"./indexeddb-backend.ts\";\nimport { type IndexedToDeviceBatch, type ToDeviceBatchWithTxnId } from \"../models/ToDeviceMessage.ts\";\n\ntype DbMigration = (db: IDBDatabase) => void;\nconst DB_MIGRATIONS: DbMigration[] = [\n (db): void => {\n // Make user store, clobber based on user ID. (userId property of User objects)\n db.createObjectStore(\"users\", { keyPath: [\"userId\"] });\n\n // Make account data store, clobber based on event type.\n // (event.type property of MatrixEvent objects)\n db.createObjectStore(\"accountData\", { keyPath: [\"type\"] });\n\n // Make /sync store (sync tokens, room data, etc), always clobber (const key).\n db.createObjectStore(\"sync\", { keyPath: [\"clobber\"] });\n },\n (db): void => {\n const oobMembersStore = db.createObjectStore(\"oob_membership_events\", {\n keyPath: [\"room_id\", \"state_key\"],\n });\n oobMembersStore.createIndex(\"room\", \"room_id\");\n },\n (db): void => {\n db.createObjectStore(\"client_options\", { keyPath: [\"clobber\"] });\n },\n (db): void => {\n db.createObjectStore(\"to_device_queue\", { autoIncrement: true });\n },\n // Expand as needed.\n];\nconst VERSION = DB_MIGRATIONS.length;\n\n/**\n * Helper method to collect results from a Cursor and promiseify it.\n * @param store - The store to perform openCursor on.\n * @param keyRange - Optional key range to apply on the cursor.\n * @param resultMapper - A function which is repeatedly called with a\n * Cursor.\n * Return the data you want to keep.\n * @returns Promise which resolves to an array of whatever you returned from\n * resultMapper.\n */\nfunction selectQuery<T>(\n store: IDBObjectStore,\n keyRange: IDBKeyRange | IDBValidKey | undefined,\n resultMapper: (cursor: IDBCursorWithValue) => T,\n): Promise<T[]> {\n const query = store.openCursor(keyRange);\n return new Promise((resolve, reject) => {\n const results: T[] = [];\n query.onerror = (): void => {\n reject(new Error(\"Query failed: \" + query.error?.name));\n };\n // collect results\n query.onsuccess = (): void => {\n const cursor = query.result;\n if (!cursor) {\n resolve(results);\n return; // end of results\n }\n results.push(resultMapper(cursor));\n cursor.continue();\n };\n });\n}\n\nfunction txnAsPromise(txn: IDBTransaction): Promise<Event> {\n return new Promise((resolve, reject) => {\n txn.oncomplete = function (event): void {\n resolve(event);\n };\n txn.onerror = function (): void {\n reject(txn.error);\n };\n });\n}\n\nfunction reqAsEventPromise(req: IDBRequest): Promise<Event> {\n return new Promise((resolve, reject) => {\n req.onsuccess = function (event): void {\n resolve(event);\n };\n req.onerror = function (): void {\n reject(req.error);\n };\n });\n}\n\nfunction reqAsPromise(req: IDBRequest): Promise<IDBRequest> {\n return new Promise((resolve, reject) => {\n req.onsuccess = (): void => resolve(req);\n req.onerror = (err): void => reject(err);\n });\n}\n\nfunction reqAsCursorPromise<T>(req: IDBRequest<T>): Promise<T> {\n return reqAsEventPromise(req).then((event) => req.result);\n}\n\nexport class LocalIndexedDBStoreBackend implements IIndexedDBBackend {\n public static exists(indexedDB: IDBFactory, dbName: string): Promise<boolean> {\n dbName = \"matrix-js-sdk:\" + (dbName || \"default\");\n return idbExists(indexedDB, dbName);\n }\n\n private readonly dbName: string;\n private readonly syncAccumulator: SyncAccumulator;\n private db?: IDBDatabase;\n private disconnected = true;\n private _isNewlyCreated = false;\n private syncToDatabasePromise?: Promise<void>;\n private pendingUserPresenceData: UserTuple[] = [];\n\n /**\n * Does the actual reading from and writing to the indexeddb\n *\n * Construct a new Indexed Database store backend. This requires a call to\n * `connect()` before this store can be used.\n * @param indexedDB - The Indexed DB interface e.g\n * `window.indexedDB`\n * @param dbName - Optional database name. The same name must be used\n * to open the same database.\n */\n public constructor(\n private readonly indexedDB: IDBFactory,\n dbName = \"default\",\n ) {\n this.dbName = \"matrix-js-sdk:\" + dbName;\n this.syncAccumulator = new SyncAccumulator();\n }\n\n /**\n * Attempt to connect to the database. This can fail if the user does not\n * grant permission.\n * @returns Promise which resolves if successfully connected.\n */\n public connect(onClose?: () => void): Promise<void> {\n if (!this.disconnected) {\n logger.log(`LocalIndexedDBStoreBackend.connect: already connected or connecting`);\n return Promise.resolve();\n }\n\n this.disconnected = false;\n\n logger.log(`LocalIndexedDBStoreBackend.connect: connecting...`);\n const req = this.indexedDB.open(this.dbName, VERSION);\n req.onupgradeneeded = (ev): void => {\n const db = req.result;\n const oldVersion = ev.oldVersion;\n logger.log(`LocalIndexedDBStoreBackend.connect: upgrading from ${oldVersion}`);\n if (oldVersion < 1) {\n // The database did not previously exist\n this._isNewlyCreated = true;\n }\n DB_MIGRATIONS.forEach((migration, index) => {\n if (oldVersion <= index) migration(db);\n });\n };\n\n req.onblocked = (): void => {\n logger.log(`can't yet open LocalIndexedDBStoreBackend because it is open elsewhere`);\n };\n\n logger.log(`LocalIndexedDBStoreBackend.connect: awaiting connection...`);\n return reqAsEventPromise(req).then(async () => {\n logger.log(`LocalIndexedDBStoreBackend.connect: connected`);\n this.db = req.result;\n\n // add a poorly-named listener for when deleteDatabase is called\n // so we can close our db connections.\n this.db.onversionchange = (): void => {\n this.db?.close(); // this does not call onclose\n this.disconnected = true;\n this.db = undefined;\n };\n this.db.onclose = (): void => {\n this.disconnected = true;\n this.db = undefined;\n onClose?.();\n };\n\n await this.init();\n });\n }\n\n /** @returns whether or not the database was newly created in this session. */\n public isNewlyCreated(): Promise<boolean> {\n return Promise.resolve(this._isNewlyCreated);\n }\n\n /**\n * Having connected, load initial data from the database and prepare for use\n * @returns Promise which resolves on success\n */\n private init(): Promise<unknown> {\n return Promise.all([this.loadAccountData(), this.loadSyncData()]).then(([accountData, syncData]) => {\n logger.log(`LocalIndexedDBStoreBackend: loaded initial data`);\n this.syncAccumulator.accumulate(\n {\n next_batch: syncData.nextBatch,\n rooms: syncData.roomsData,\n account_data: {\n events: accountData,\n },\n },\n true,\n );\n });\n }\n\n /**\n * Returns the out-of-band membership events for this room that\n * were previously loaded.\n * @returns the events, potentially an empty array if OOB loading didn't yield any new members\n * @returns in case the members for this room haven't been stored yet\n */\n public getOutOfBandMembers(roomId: string): Promise<IStateEventWithRoomId[] | null> {\n return new Promise<IStateEventWithRoomId[] | null>((resolve, reject) => {\n const tx = this.db!.transaction([\"oob_membership_events\"], \"readonly\");\n const store = tx.objectStore(\"oob_membership_events\");\n const roomIndex = store.index(\"room\");\n const range = IDBKeyRange.only(roomId);\n const request = roomIndex.openCursor(range);\n\n const membershipEvents: IStateEventWithRoomId[] = [];\n // did we encounter the oob_written marker object\n // amongst the results? That means OOB member\n // loading already happened for this room\n // but there were no members to persist as they\n // were all known already\n let oobWritten = false;\n\n request.onsuccess = (): void => {\n const cursor = request.result;\n if (!cursor) {\n // Unknown room\n if (!membershipEvents.length && !oobWritten) {\n return resolve(null);\n }\n return resolve(membershipEvents);\n }\n const record = cursor.value;\n if (record.oob_written) {\n oobWritten = true;\n } else {\n membershipEvents.push(record);\n }\n cursor.continue();\n };\n request.onerror = (err): void => {\n reject(err);\n };\n }).then((events) => {\n logger.log(`LL: got ${events?.length} membershipEvents from storage for room ${roomId} ...`);\n return events;\n });\n }\n\n /**\n * Stores the out-of-band membership events for this room. Note that\n * it still makes sense to store an empty array as the OOB status for the room is\n * marked as fetched, and getOutOfBandMembers will return an empty array instead of null\n * @param membershipEvents - the membership events to store\n */\n public async setOutOfBandMembers(roomId: string, membershipEvents: IStateEventWithRoomId[]): Promise<void> {\n logger.log(`LL: backend about to store ${membershipEvents.length}` + ` members for ${roomId}`);\n const tx = this.db!.transaction([\"oob_membership_events\"], \"readwrite\");\n const store = tx.objectStore(\"oob_membership_events\");\n membershipEvents.forEach((e) => {\n store.put(e);\n });\n // aside from all the events, we also write a marker object to the store\n // to mark the fact that OOB members have been written for this room.\n // It's possible that 0 members need to be written as all where previously know\n // but we still need to know whether to return null or [] from getOutOfBandMembers\n // where null means out of band members haven't been stored yet for this room\n const markerObject = {\n room_id: roomId,\n oob_written: true,\n state_key: 0,\n };\n store.put(markerObject);\n await txnAsPromise(tx);\n logger.log(`LL: backend done storing for ${roomId}!`);\n }\n\n public async clearOutOfBandMembers(roomId: string): Promise<void> {\n // the approach to delete all members for a room\n // is to get the min and max state key from the index\n // for that room, and then delete between those\n // keys in the store.\n // this should be way faster than deleting every member\n // individually for a large room.\n const readTx = this.db!.transaction([\"oob_membership_events\"], \"readonly\");\n const store = readTx.objectStore(\"oob_membership_events\");\n const roomIndex = store.index(\"room\");\n const roomRange = IDBKeyRange.only(roomId);\n\n const minStateKeyProm = reqAsCursorPromise(roomIndex.openKeyCursor(roomRange, \"next\")).then(\n (cursor) => (<IDBValidKey[]>cursor?.primaryKey)[1],\n );\n const maxStateKeyProm = reqAsCursorPromise(roomIndex.openKeyCursor(roomRange, \"prev\")).then(\n (cursor) => (<IDBValidKey[]>cursor?.primaryKey)[1],\n );\n const [minStateKey, maxStateKey] = await Promise.all([minStateKeyProm, maxStateKeyProm]);\n\n const writeTx = this.db!.transaction([\"oob_membership_events\"], \"readwrite\");\n const writeStore = writeTx.objectStore(\"oob_membership_events\");\n const membersKeyRange = IDBKeyRange.bound([roomId, minStateKey], [roomId, maxStateKey]);\n\n logger.log(\n `LL: Deleting all users + marker in storage for room ${roomId}, with key range:`,\n [roomId, minStateKey],\n [roomId, maxStateKey],\n );\n await reqAsPromise(writeStore.delete(membersKeyRange));\n }\n\n /**\n * Clear the entire database. This should be used when logging out of a client\n * to prevent mixing data between accounts. Closes the database.\n * @returns Resolved when the database is cleared.\n */\n public clearDatabase(): Promise<void> {\n return new Promise((resolve) => {\n logger.log(`Removing indexeddb instance: ${this.dbName}`);\n\n // Close the database first to avoid firing unexpected close events\n this.db?.close();\n\n const req = this.indexedDB.deleteDatabase(this.dbName);\n\n req.onblocked = (): void => {\n logger.log(`can't yet delete indexeddb ${this.dbName} because it is open elsewhere`);\n };\n\n req.onerror = (): void => {\n // in firefox, with indexedDB disabled, this fails with a\n // DOMError. We treat this as non-fatal, so that we can still\n // use the app.\n logger.warn(`unable to delete js-sdk store indexeddb: ${req.error?.name}`);\n resolve();\n };\n\n req.onsuccess = (): void => {\n logger.log(`Removed indexeddb instance: ${this.dbName}`);\n resolve();\n };\n });\n }\n\n /**\n * @param copy - If false, the data returned is from internal\n * buffers and must not be mutated. Otherwise, a copy is made before\n * returning such that the data can be safely mutated. Default: true.\n *\n * @returns Promise which resolves with a sync response to restore the\n * client state to where it was at the last save, or null if there\n * is no saved sync data.\n */\n public getSavedSync(copy = true): Promise<ISavedSync | null> {\n const data = this.syncAccumulator.getJSON();\n if (!data.nextBatch) return Promise.resolve(null);\n if (copy) {\n // We must deep copy the stored data so that the /sync processing code doesn't\n // corrupt the internal state of the sync accumulator (it adds non-clonable keys)\n return Promise.resolve(deepCopy(data));\n } else {\n return Promise.resolve(data);\n }\n }\n\n public getNextBatchToken(): Promise<string> {\n return Promise.resolve(this.syncAccumulator.getNextBatchToken());\n }\n\n public setSyncData(syncData: ISyncResponse): Promise<void> {\n return Promise.resolve().then(() => {\n this.syncAccumulator.accumulate(syncData);\n });\n }\n\n /**\n * Sync users and all accumulated sync data to the database.\n * If a previous sync is in flight, the new data will be added to the\n * next sync and the current sync's promise will be returned.\n * @param userTuples - The user tuples\n * @returns Promise which resolves if the data was persisted.\n */\n public async syncToDatabase(userTuples: UserTuple[]): Promise<void> {\n if (this.syncToDatabasePromise) {\n logger.warn(\"Skipping syncToDatabase() as persist already in flight\");\n this.pendingUserPresenceData.push(...userTuples);\n return this.syncToDatabasePromise;\n }\n userTuples.unshift(...this.pendingUserPresenceData);\n this.syncToDatabasePromise = this.doSyncToDatabase(userTuples);\n return this.syncToDatabasePromise;\n }\n\n private async doSyncToDatabase(userTuples: UserTuple[]): Promise<void> {\n try {\n const syncData = this.syncAccumulator.getJSON(true);\n await Promise.all([\n this.persistUserPresenceEvents(userTuples),\n this.persistAccountData(syncData.accountData),\n this.persistSyncData(syncData.nextBatch, syncData.roomsData),\n ]);\n } finally {\n this.syncToDatabasePromise = undefined;\n }\n }\n\n /**\n * Persist rooms /sync data along with the next batch token.\n * @param nextBatch - The next_batch /sync value.\n * @param roomsData - The 'rooms' /sync data from a SyncAccumulator\n * @returns Promise which resolves if the data was persisted.\n */\n private persistSyncData(nextBatch: string, roomsData: ISyncResponse[\"rooms\"]): Promise<void> {\n logger.log(\"Persisting sync data up to\", nextBatch);\n return promiseTry<void>(() => {\n const txn = this.db!.transaction([\"sync\"], \"readwrite\");\n const store = txn.objectStore(\"sync\");\n store.put({\n clobber: \"-\", // constant key so will always clobber\n nextBatch,\n roomsData,\n }); // put == UPSERT\n return txnAsPromise(txn).then(() => {\n logger.log(\"Persisted sync data up to\", nextBatch);\n });\n });\n }\n\n /**\n * Persist a list of account data events. Events with the same 'type' will\n * be replaced.\n * @param accountData - An array of raw user-scoped account data events\n * @returns Promise which resolves if the events were persisted.\n */\n private persistAccountData(accountData: IMinimalEvent[]): Promise<void> {\n return promiseTry<void>(() => {\n const txn = this.db!.transaction([\"accountData\"], \"readwrite\");\n const store = txn.objectStore(\"accountData\");\n for (const event of accountData) {\n store.put(event); // put == UPSERT\n }\n return txnAsPromise(txn).then();\n });\n }\n\n /**\n * Persist a list of [user id, presence event] they are for.\n * Users with the same 'userId' will be replaced.\n * Presence events should be the event in its raw form (not the Event\n * object)\n * @param tuples - An array of [userid, event] tuples\n * @returns Promise which resolves if the users were persisted.\n */\n private persistUserPresenceEvents(tuples: UserTuple[]): Promise<void> {\n return promiseTry<void>(() => {\n const txn = this.db!.transaction([\"users\"], \"readwrite\");\n const store = txn.objectStore(\"users\");\n for (const tuple of tuples) {\n store.put({\n userId: tuple[0],\n event: tuple[1],\n }); // put == UPSERT\n }\n return txnAsPromise(txn).then();\n });\n }\n\n /**\n * Load all user presence events from the database. This is not cached.\n * FIXME: It would probably be more sensible to store the events in the\n * sync.\n * @returns A list of presence events in their raw form.\n */\n public getUserPresenceEvents(): Promise<UserTuple[]> {\n return promiseTry<UserTuple[]>(() => {\n const txn = this.db!.transaction([\"users\"], \"readonly\");\n const store = txn.objectStore(\"users\");\n return selectQuery(store, undefined, (cursor) => {\n return [cursor.value.userId, cursor.value.event];\n });\n });\n }\n\n /**\n * Load all the account data events from the database. This is not cached.\n * @returns A list of raw global account events.\n */\n private loadAccountData(): Promise<IMinimalEvent[]> {\n logger.log(`LocalIndexedDBStoreBackend: loading account data...`);\n return promiseTry<IMinimalEvent[]>(() => {\n const txn = this.db!.transaction([\"accountData\"], \"readonly\");\n const store = txn.objectStore(\"accountData\");\n return selectQuery(store, undefined, (cursor) => {\n return cursor.value;\n }).then((result: IMinimalEvent[]) => {\n logger.log(`LocalIndexedDBStoreBackend: loaded account data`);\n return result;\n });\n });\n }\n\n /**\n * Load the sync data from the database.\n * @returns An object with \"roomsData\" and \"nextBatch\" keys.\n */\n private loadSyncData(): Promise<ISyncData> {\n logger.log(`LocalIndexedDBStoreBackend: loading sync data...`);\n return promiseTry<ISyncData>(() => {\n const txn = this.db!.transaction([\"sync\"], \"readonly\");\n const store = txn.objectStore(\"sync\");\n return selectQuery(store, undefined, (cursor) => {\n return cursor.value;\n }).then((results: ISyncData[]) => {\n logger.log(`LocalIndexedDBStoreBackend: loaded sync data`);\n if (results.length > 1) {\n logger.warn(\"loadSyncData: More than 1 sync row found.\");\n }\n return results.length > 0 ? results[0] : ({} as ISyncData);\n });\n });\n }\n\n public getClientOptions(): Promise<IStoredClientOpts | undefined> {\n return Promise.resolve().then(() => {\n const txn = this.db!.transaction([\"client_options\"], \"readonly\");\n const store = txn.objectStore(\"client_options\");\n return selectQuery(store, undefined, (cursor) => {\n return cursor.value?.options;\n }).then((results) => results[0]);\n });\n }\n\n public async storeClientOptions(options: IStoredClientOpts): Promise<void> {\n const txn = this.db!.transaction([\"client_options\"], \"readwrite\");\n const store = txn.objectStore(\"client_options\");\n store.put({\n clobber: \"-\", // constant key so will always clobber\n options: options,\n }); // put == UPSERT\n await txnAsPromise(txn);\n }\n\n public async saveToDeviceBatches(batches: ToDeviceBatchWithTxnId[]): Promise<void> {\n const txn = this.db!.transaction([\"to_device_queue\"], \"readwrite\");\n const store = txn.objectStore(\"to_device_queue\");\n for (const batch of batches) {\n store.add(batch);\n }\n await txnAsPromise(txn);\n }\n\n public async getOldestToDeviceBatch(): Promise<IndexedToDeviceBatch | null> {\n const txn = this.db!.transaction([\"to_device_queue\"], \"readonly\");\n const store = txn.objectStore(\"to_device_queue\");\n const cursor = await reqAsCursorPromise(store.openCursor());\n if (!cursor) return null;\n\n const resultBatch = cursor.value as ToDeviceBatchWithTxnId;\n\n return {\n id: cursor.key as number,\n txnId: resultBatch.txnId,\n eventType: resultBatch.eventType,\n batch: resultBatch.batch,\n };\n }\n\n public async removeToDeviceBatch(id: number): Promise<void> {\n const txn = this.db!.transaction([\"to_device_queue\"], \"readwrite\");\n const store = txn.objectStore(\"to_device_queue\");\n store.delete(id);\n await txnAsPromise(txn);\n }\n\n /*\n * Close the database\n */\n public async destroy(): Promise<void> {\n this.db?.close();\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"indexeddb-local-backend.js","names":["SyncAccumulator","deepCopy","promiseTry","exists","idbExists","logger","DB_MIGRATIONS","db","createObjectStore","keyPath","oobMembersStore","createIndex","autoIncrement","VERSION","length","selectQuery","store","keyRange","resultMapper","query","openCursor","Promise","resolve","reject","results","onerror","Error","concat","name","cause","error","onsuccess","cursor","result","push","continue","txnAsPromise","txn","oncomplete","event","reqAsEventPromise","req","reqAsPromise","err","reqAsCursorPromise","then","LocalIndexedDBStoreBackend","indexedDB","dbName","constructor","arguments","undefined","_defineProperty","syncAccumulator","connect","onClose","_this","disconnected","log","open","onupgradeneeded","ev","oldVersion","_isNewlyCreated","forEach","migration","index","onblocked","_asyncToGenerator","onversionchange","_this$db","close","onclose","init","isNewlyCreated","all","loadAccountData","loadSyncData","_ref2","accountData","syncData","accumulate","next_batch","nextBatch","rooms","roomsData","account_data","events","getOutOfBandMembers","roomId","tx","transaction","objectStore","roomIndex","range","IDBKeyRange","only","request","membershipEvents","oobWritten","record","value","oob_written","setOutOfBandMembers","_this2","e","put","markerObject","room_id","state_key","clearOutOfBandMembers","_this3","readTx","roomRange","minStateKeyProm","openKeyCursor","primaryKey","maxStateKeyProm","minStateKey","maxStateKey","writeTx","writeStore","membersKeyRange","bound","delete","clearDatabase","_this$db2","deleteDatabase","_req$error","warn","getSavedSync","copy","data","getJSON","getNextBatchToken","setSyncData","syncToDatabase","userTuples","_this4","syncToDatabasePromise","pendingUserPresenceData","unshift","doSyncToDatabase","_this5","persistUserPresenceEvents","persistAccountData","persistSyncData","clobber","tuples","tuple","userId","getUserPresenceEvents","getClientOptions","_cursor$value","options","storeClientOptions","_this6","saveToDeviceBatches","batches","_this7","batch","add","getOldestToDeviceBatch","_this8","resultBatch","id","key","txnId","eventType","removeToDeviceBatch","_this9","destroy","_this0","_this0$db"],"sources":["../../src/store/indexeddb-local-backend.ts"],"sourcesContent":["/*\nCopyright 2017 - 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { type IMinimalEvent, type ISyncData, type ISyncResponse, SyncAccumulator } from \"../sync-accumulator.ts\";\nimport { deepCopy, promiseTry } from \"../utils.ts\";\nimport { exists as idbExists } from \"../indexeddb-helpers.ts\";\nimport { logger } from \"../logger.ts\";\nimport { type IStateEventWithRoomId, type IStoredClientOpts } from \"../matrix.ts\";\nimport { type ISavedSync } from \"./index.ts\";\nimport { type IIndexedDBBackend, type UserTuple } from \"./indexeddb-backend.ts\";\nimport { type IndexedToDeviceBatch, type ToDeviceBatchWithTxnId } from \"../models/ToDeviceMessage.ts\";\n\ntype DbMigration = (db: IDBDatabase) => void;\nconst DB_MIGRATIONS: DbMigration[] = [\n (db): void => {\n // Make user store, clobber based on user ID. (userId property of User objects)\n db.createObjectStore(\"users\", { keyPath: [\"userId\"] });\n\n // Make account data store, clobber based on event type.\n // (event.type property of MatrixEvent objects)\n db.createObjectStore(\"accountData\", { keyPath: [\"type\"] });\n\n // Make /sync store (sync tokens, room data, etc), always clobber (const key).\n db.createObjectStore(\"sync\", { keyPath: [\"clobber\"] });\n },\n (db): void => {\n const oobMembersStore = db.createObjectStore(\"oob_membership_events\", {\n keyPath: [\"room_id\", \"state_key\"],\n });\n oobMembersStore.createIndex(\"room\", \"room_id\");\n },\n (db): void => {\n db.createObjectStore(\"client_options\", { keyPath: [\"clobber\"] });\n },\n (db): void => {\n db.createObjectStore(\"to_device_queue\", { autoIncrement: true });\n },\n // Expand as needed.\n];\nconst VERSION = DB_MIGRATIONS.length;\n\n/**\n * Helper method to collect results from a Cursor and promiseify it.\n * @param store - The store to perform openCursor on.\n * @param keyRange - Optional key range to apply on the cursor.\n * @param resultMapper - A function which is repeatedly called with a\n * Cursor.\n * Return the data you want to keep.\n * @returns Promise which resolves to an array of whatever you returned from\n * resultMapper.\n * @throws If there was an error completing the query.\n */\nfunction selectQuery<T>(\n store: IDBObjectStore,\n keyRange: IDBKeyRange | IDBValidKey | undefined,\n resultMapper: (cursor: IDBCursorWithValue) => T,\n): Promise<T[]> {\n const query = store.openCursor(keyRange);\n return new Promise((resolve, reject) => {\n const results: T[] = [];\n query.onerror = (): void => {\n reject(new Error(`selectQuery failed for ${store.name}`, { cause: query.error }));\n };\n // collect results\n query.onsuccess = (): void => {\n const cursor = query.result;\n if (!cursor) {\n resolve(results);\n return; // end of results\n }\n results.push(resultMapper(cursor));\n cursor.continue();\n };\n });\n}\n\nfunction txnAsPromise(txn: IDBTransaction): Promise<Event> {\n return new Promise((resolve, reject) => {\n txn.oncomplete = function (event): void {\n resolve(event);\n };\n txn.onerror = function (): void {\n reject(txn.error);\n };\n });\n}\n\nfunction reqAsEventPromise(req: IDBRequest): Promise<Event> {\n return new Promise((resolve, reject) => {\n req.onsuccess = function (event): void {\n resolve(event);\n };\n req.onerror = function (): void {\n reject(req.error);\n };\n });\n}\n\nfunction reqAsPromise(req: IDBRequest): Promise<IDBRequest> {\n return new Promise((resolve, reject) => {\n req.onsuccess = (): void => resolve(req);\n req.onerror = (err): void => reject(err);\n });\n}\n\nfunction reqAsCursorPromise<T>(req: IDBRequest<T>): Promise<T> {\n return reqAsEventPromise(req).then((event) => req.result);\n}\n\nexport class LocalIndexedDBStoreBackend implements IIndexedDBBackend {\n public static exists(indexedDB: IDBFactory, dbName: string): Promise<boolean> {\n dbName = \"matrix-js-sdk:\" + (dbName || \"default\");\n return idbExists(indexedDB, dbName);\n }\n\n private readonly dbName: string;\n private readonly syncAccumulator: SyncAccumulator;\n private db?: IDBDatabase;\n private disconnected = true;\n private _isNewlyCreated = false;\n private syncToDatabasePromise?: Promise<void>;\n private pendingUserPresenceData: UserTuple[] = [];\n\n /**\n * Does the actual reading from and writing to the indexeddb\n *\n * Construct a new Indexed Database store backend. This requires a call to\n * `connect()` before this store can be used.\n * @param indexedDB - The Indexed DB interface e.g\n * `window.indexedDB`\n * @param dbName - Optional database name. The same name must be used\n * to open the same database.\n */\n public constructor(\n private readonly indexedDB: IDBFactory,\n dbName = \"default\",\n ) {\n this.dbName = \"matrix-js-sdk:\" + dbName;\n this.syncAccumulator = new SyncAccumulator();\n }\n\n /**\n * Attempt to connect to the database. This can fail if the user does not\n * grant permission.\n * @returns Promise which resolves if successfully connected.\n */\n public connect(onClose?: () => void): Promise<void> {\n if (!this.disconnected) {\n logger.log(`LocalIndexedDBStoreBackend.connect: already connected or connecting`);\n return Promise.resolve();\n }\n\n this.disconnected = false;\n\n logger.log(`LocalIndexedDBStoreBackend.connect: connecting...`);\n const req = this.indexedDB.open(this.dbName, VERSION);\n req.onupgradeneeded = (ev): void => {\n const db = req.result;\n const oldVersion = ev.oldVersion;\n logger.log(`LocalIndexedDBStoreBackend.connect: upgrading from ${oldVersion}`);\n if (oldVersion < 1) {\n // The database did not previously exist\n this._isNewlyCreated = true;\n }\n DB_MIGRATIONS.forEach((migration, index) => {\n if (oldVersion <= index) migration(db);\n });\n };\n\n req.onblocked = (): void => {\n logger.log(`can't yet open LocalIndexedDBStoreBackend because it is open elsewhere`);\n };\n\n logger.log(`LocalIndexedDBStoreBackend.connect: awaiting connection...`);\n return reqAsEventPromise(req).then(async () => {\n logger.log(`LocalIndexedDBStoreBackend.connect: connected`);\n this.db = req.result;\n\n // add a poorly-named listener for when deleteDatabase is called\n // so we can close our db connections.\n this.db.onversionchange = (): void => {\n this.db?.close(); // this does not call onclose\n this.disconnected = true;\n this.db = undefined;\n };\n this.db.onclose = (): void => {\n this.disconnected = true;\n this.db = undefined;\n onClose?.();\n };\n\n await this.init();\n });\n }\n\n /** @returns whether or not the database was newly created in this session. */\n public isNewlyCreated(): Promise<boolean> {\n return Promise.resolve(this._isNewlyCreated);\n }\n\n /**\n * Having connected, load initial data from the database and prepare for use\n * @returns Promise which resolves on success\n */\n private init(): Promise<unknown> {\n return Promise.all([this.loadAccountData(), this.loadSyncData()]).then(([accountData, syncData]) => {\n logger.log(`LocalIndexedDBStoreBackend: loaded initial data`);\n this.syncAccumulator.accumulate(\n {\n next_batch: syncData.nextBatch,\n rooms: syncData.roomsData,\n account_data: {\n events: accountData,\n },\n },\n true,\n );\n });\n }\n\n /**\n * Returns the out-of-band membership events for this room that\n * were previously loaded.\n * @returns the events, potentially an empty array if OOB loading didn't yield any new members\n * @returns in case the members for this room haven't been stored yet\n */\n public getOutOfBandMembers(roomId: string): Promise<IStateEventWithRoomId[] | null> {\n return new Promise<IStateEventWithRoomId[] | null>((resolve, reject) => {\n const tx = this.db!.transaction([\"oob_membership_events\"], \"readonly\");\n const store = tx.objectStore(\"oob_membership_events\");\n const roomIndex = store.index(\"room\");\n const range = IDBKeyRange.only(roomId);\n const request = roomIndex.openCursor(range);\n\n const membershipEvents: IStateEventWithRoomId[] = [];\n // did we encounter the oob_written marker object\n // amongst the results? That means OOB member\n // loading already happened for this room\n // but there were no members to persist as they\n // were all known already\n let oobWritten = false;\n\n request.onsuccess = (): void => {\n const cursor = request.result;\n if (!cursor) {\n // Unknown room\n if (!membershipEvents.length && !oobWritten) {\n return resolve(null);\n }\n return resolve(membershipEvents);\n }\n const record = cursor.value;\n if (record.oob_written) {\n oobWritten = true;\n } else {\n membershipEvents.push(record);\n }\n cursor.continue();\n };\n request.onerror = (err): void => {\n reject(err);\n };\n }).then((events) => {\n logger.log(`LL: got ${events?.length} membershipEvents from storage for room ${roomId} ...`);\n return events;\n });\n }\n\n /**\n * Stores the out-of-band membership events for this room. Note that\n * it still makes sense to store an empty array as the OOB status for the room is\n * marked as fetched, and getOutOfBandMembers will return an empty array instead of null\n * @param membershipEvents - the membership events to store\n */\n public async setOutOfBandMembers(roomId: string, membershipEvents: IStateEventWithRoomId[]): Promise<void> {\n logger.log(`LL: backend about to store ${membershipEvents.length}` + ` members for ${roomId}`);\n const tx = this.db!.transaction([\"oob_membership_events\"], \"readwrite\");\n const store = tx.objectStore(\"oob_membership_events\");\n membershipEvents.forEach((e) => {\n store.put(e);\n });\n // aside from all the events, we also write a marker object to the store\n // to mark the fact that OOB members have been written for this room.\n // It's possible that 0 members need to be written as all where previously know\n // but we still need to know whether to return null or [] from getOutOfBandMembers\n // where null means out of band members haven't been stored yet for this room\n const markerObject = {\n room_id: roomId,\n oob_written: true,\n state_key: 0,\n };\n store.put(markerObject);\n await txnAsPromise(tx);\n logger.log(`LL: backend done storing for ${roomId}!`);\n }\n\n public async clearOutOfBandMembers(roomId: string): Promise<void> {\n // the approach to delete all members for a room\n // is to get the min and max state key from the index\n // for that room, and then delete between those\n // keys in the store.\n // this should be way faster than deleting every member\n // individually for a large room.\n const readTx = this.db!.transaction([\"oob_membership_events\"], \"readonly\");\n const store = readTx.objectStore(\"oob_membership_events\");\n const roomIndex = store.index(\"room\");\n const roomRange = IDBKeyRange.only(roomId);\n\n const minStateKeyProm = reqAsCursorPromise(roomIndex.openKeyCursor(roomRange, \"next\")).then(\n (cursor) => (<IDBValidKey[]>cursor?.primaryKey)[1],\n );\n const maxStateKeyProm = reqAsCursorPromise(roomIndex.openKeyCursor(roomRange, \"prev\")).then(\n (cursor) => (<IDBValidKey[]>cursor?.primaryKey)[1],\n );\n const [minStateKey, maxStateKey] = await Promise.all([minStateKeyProm, maxStateKeyProm]);\n\n const writeTx = this.db!.transaction([\"oob_membership_events\"], \"readwrite\");\n const writeStore = writeTx.objectStore(\"oob_membership_events\");\n const membersKeyRange = IDBKeyRange.bound([roomId, minStateKey], [roomId, maxStateKey]);\n\n logger.log(\n `LL: Deleting all users + marker in storage for room ${roomId}, with key range:`,\n [roomId, minStateKey],\n [roomId, maxStateKey],\n );\n await reqAsPromise(writeStore.delete(membersKeyRange));\n }\n\n /**\n * Clear the entire database. This should be used when logging out of a client\n * to prevent mixing data between accounts. Closes the database.\n * @returns Resolved when the database is cleared.\n */\n public clearDatabase(): Promise<void> {\n return new Promise((resolve) => {\n logger.log(`Removing indexeddb instance: ${this.dbName}`);\n\n // Close the database first to avoid firing unexpected close events\n this.db?.close();\n\n const req = this.indexedDB.deleteDatabase(this.dbName);\n\n req.onblocked = (): void => {\n logger.log(`can't yet delete indexeddb ${this.dbName} because it is open elsewhere`);\n };\n\n req.onerror = (): void => {\n // in firefox, with indexedDB disabled, this fails with a\n // DOMError. We treat this as non-fatal, so that we can still\n // use the app.\n logger.warn(`unable to delete js-sdk store indexeddb: ${req.error?.name}`);\n resolve();\n };\n\n req.onsuccess = (): void => {\n logger.log(`Removed indexeddb instance: ${this.dbName}`);\n resolve();\n };\n });\n }\n\n /**\n * @param copy - If false, the data returned is from internal\n * buffers and must not be mutated. Otherwise, a copy is made before\n * returning such that the data can be safely mutated. Default: true.\n *\n * @returns Promise which resolves with a sync response to restore the\n * client state to where it was at the last save, or null if there\n * is no saved sync data.\n */\n public getSavedSync(copy = true): Promise<ISavedSync | null> {\n const data = this.syncAccumulator.getJSON();\n if (!data.nextBatch) return Promise.resolve(null);\n if (copy) {\n // We must deep copy the stored data so that the /sync processing code doesn't\n // corrupt the internal state of the sync accumulator (it adds non-clonable keys)\n return Promise.resolve(deepCopy(data));\n } else {\n return Promise.resolve(data);\n }\n }\n\n public getNextBatchToken(): Promise<string> {\n return Promise.resolve(this.syncAccumulator.getNextBatchToken());\n }\n\n public setSyncData(syncData: ISyncResponse): Promise<void> {\n return Promise.resolve().then(() => {\n this.syncAccumulator.accumulate(syncData);\n });\n }\n\n /**\n * Sync users and all accumulated sync data to the database.\n * If a previous sync is in flight, the new data will be added to the\n * next sync and the current sync's promise will be returned.\n * @param userTuples - The user tuples\n * @returns Promise which resolves if the data was persisted.\n */\n public async syncToDatabase(userTuples: UserTuple[]): Promise<void> {\n if (this.syncToDatabasePromise) {\n logger.warn(\"Skipping syncToDatabase() as persist already in flight\");\n this.pendingUserPresenceData.push(...userTuples);\n return this.syncToDatabasePromise;\n }\n userTuples.unshift(...this.pendingUserPresenceData);\n this.syncToDatabasePromise = this.doSyncToDatabase(userTuples);\n return this.syncToDatabasePromise;\n }\n\n private async doSyncToDatabase(userTuples: UserTuple[]): Promise<void> {\n try {\n const syncData = this.syncAccumulator.getJSON(true);\n await Promise.all([\n this.persistUserPresenceEvents(userTuples),\n this.persistAccountData(syncData.accountData),\n this.persistSyncData(syncData.nextBatch, syncData.roomsData),\n ]);\n } finally {\n this.syncToDatabasePromise = undefined;\n }\n }\n\n /**\n * Persist rooms /sync data along with the next batch token.\n * @param nextBatch - The next_batch /sync value.\n * @param roomsData - The 'rooms' /sync data from a SyncAccumulator\n * @returns Promise which resolves if the data was persisted.\n */\n private persistSyncData(nextBatch: string, roomsData: ISyncResponse[\"rooms\"]): Promise<void> {\n logger.log(\"Persisting sync data up to\", nextBatch);\n return promiseTry<void>(() => {\n const txn = this.db!.transaction([\"sync\"], \"readwrite\");\n const store = txn.objectStore(\"sync\");\n store.put({\n clobber: \"-\", // constant key so will always clobber\n nextBatch,\n roomsData,\n }); // put == UPSERT\n return txnAsPromise(txn).then(() => {\n logger.log(\"Persisted sync data up to\", nextBatch);\n });\n });\n }\n\n /**\n * Persist a list of account data events. Events with the same 'type' will\n * be replaced.\n * @param accountData - An array of raw user-scoped account data events\n * @returns Promise which resolves if the events were persisted.\n */\n private persistAccountData(accountData: IMinimalEvent[]): Promise<void> {\n return promiseTry<void>(() => {\n const txn = this.db!.transaction([\"accountData\"], \"readwrite\");\n const store = txn.objectStore(\"accountData\");\n for (const event of accountData) {\n store.put(event); // put == UPSERT\n }\n return txnAsPromise(txn).then();\n });\n }\n\n /**\n * Persist a list of [user id, presence event] they are for.\n * Users with the same 'userId' will be replaced.\n * Presence events should be the event in its raw form (not the Event\n * object)\n * @param tuples - An array of [userid, event] tuples\n * @returns Promise which resolves if the users were persisted.\n */\n private persistUserPresenceEvents(tuples: UserTuple[]): Promise<void> {\n return promiseTry<void>(() => {\n const txn = this.db!.transaction([\"users\"], \"readwrite\");\n const store = txn.objectStore(\"users\");\n for (const tuple of tuples) {\n store.put({\n userId: tuple[0],\n event: tuple[1],\n }); // put == UPSERT\n }\n return txnAsPromise(txn).then();\n });\n }\n\n /**\n * Load all user presence events from the database. This is not cached.\n * FIXME: It would probably be more sensible to store the events in the\n * sync.\n * @returns A list of presence events in their raw form.\n */\n public getUserPresenceEvents(): Promise<UserTuple[]> {\n return promiseTry<UserTuple[]>(() => {\n const txn = this.db!.transaction([\"users\"], \"readonly\");\n const store = txn.objectStore(\"users\");\n return selectQuery(store, undefined, (cursor) => {\n return [cursor.value.userId, cursor.value.event];\n });\n });\n }\n\n /**\n * Load all the account data events from the database. This is not cached.\n * @returns A list of raw global account events.\n */\n private loadAccountData(): Promise<IMinimalEvent[]> {\n logger.log(`LocalIndexedDBStoreBackend: loading account data...`);\n return promiseTry<IMinimalEvent[]>(() => {\n const txn = this.db!.transaction([\"accountData\"], \"readonly\");\n const store = txn.objectStore(\"accountData\");\n return selectQuery(store, undefined, (cursor) => {\n return cursor.value;\n }).then((result: IMinimalEvent[]) => {\n logger.log(`LocalIndexedDBStoreBackend: loaded account data`);\n return result;\n });\n });\n }\n\n /**\n * Load the sync data from the database.\n * @returns An object with \"roomsData\" and \"nextBatch\" keys.\n */\n private loadSyncData(): Promise<ISyncData> {\n logger.log(`LocalIndexedDBStoreBackend: loading sync data...`);\n return promiseTry<ISyncData>(() => {\n const txn = this.db!.transaction([\"sync\"], \"readonly\");\n const store = txn.objectStore(\"sync\");\n return selectQuery(store, undefined, (cursor) => {\n return cursor.value;\n }).then((results: ISyncData[]) => {\n logger.log(`LocalIndexedDBStoreBackend: loaded sync data`);\n if (results.length > 1) {\n logger.warn(\"loadSyncData: More than 1 sync row found.\");\n }\n return results.length > 0 ? results[0] : ({} as ISyncData);\n });\n });\n }\n\n public getClientOptions(): Promise<IStoredClientOpts | undefined> {\n return Promise.resolve().then(() => {\n const txn = this.db!.transaction([\"client_options\"], \"readonly\");\n const store = txn.objectStore(\"client_options\");\n return selectQuery(store, undefined, (cursor) => {\n return cursor.value?.options;\n }).then((results) => results[0]);\n });\n }\n\n public async storeClientOptions(options: IStoredClientOpts): Promise<void> {\n const txn = this.db!.transaction([\"client_options\"], \"readwrite\");\n const store = txn.objectStore(\"client_options\");\n store.put({\n clobber: \"-\", // constant key so will always clobber\n options: options,\n }); // put == UPSERT\n await txnAsPromise(txn);\n }\n\n public async saveToDeviceBatches(batches: ToDeviceBatchWithTxnId[]): Promise<void> {\n const txn = this.db!.transaction([\"to_device_queue\"], \"readwrite\");\n const store = txn.objectStore(\"to_device_queue\");\n for (const batch of batches) {\n store.add(batch);\n }\n await txnAsPromise(txn);\n }\n\n public async getOldestToDeviceBatch(): Promise<IndexedToDeviceBatch | null> {\n const txn = this.db!.transaction([\"to_device_queue\"], \"readonly\");\n const store = txn.objectStore(\"to_device_queue\");\n const cursor = await reqAsCursorPromise(store.openCursor());\n if (!cursor) return null;\n\n const resultBatch = cursor.value as ToDeviceBatchWithTxnId;\n\n return {\n id: cursor.key as number,\n txnId: resultBatch.txnId,\n eventType: resultBatch.eventType,\n batch: resultBatch.batch,\n };\n }\n\n public async removeToDeviceBatch(id: number): Promise<void> {\n const txn = this.db!.transaction([\"to_device_queue\"], \"readwrite\");\n const store = txn.objectStore(\"to_device_queue\");\n store.delete(id);\n await txnAsPromise(txn);\n }\n\n /*\n * Close the database\n */\n public async destroy(): Promise<void> {\n this.db?.close();\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "matrix-js-sdk",
|
|
3
|
-
"version": "41.
|
|
3
|
+
"version": "41.4.0",
|
|
4
4
|
"description": "Matrix Client-Server SDK for Javascript",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=22.0.0"
|
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
"lint:types": "tsc --noEmit",
|
|
19
19
|
"lint:workflows": "find .github/workflows -type f \\( -iname '*.yaml' -o -iname '*.yml' \\) | xargs -I {} sh -c 'echo \"Linting {}\"; action-validator \"{}\"'",
|
|
20
20
|
"lint:knip": "knip",
|
|
21
|
-
"test": "vitest",
|
|
22
|
-
"test:watch": "vitest
|
|
21
|
+
"test": "vitest run",
|
|
22
|
+
"test:watch": "vitest watch",
|
|
23
23
|
"coverage": "pnpm test --coverage"
|
|
24
24
|
},
|
|
25
25
|
"repository": {
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
],
|
|
49
49
|
"dependencies": {
|
|
50
50
|
"@babel/runtime": "^7.12.5",
|
|
51
|
-
"@matrix-org/matrix-sdk-crypto-wasm": "^18.
|
|
51
|
+
"@matrix-org/matrix-sdk-crypto-wasm": "^18.1.0",
|
|
52
52
|
"another-json": "^0.2.0",
|
|
53
53
|
"bs58": "^6.0.0",
|
|
54
54
|
"content-type": "^1.0.4",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"matrix-events-sdk": "0.0.1",
|
|
58
58
|
"matrix-widget-api": "^1.16.1",
|
|
59
59
|
"oidc-client-ts": "^3.0.1",
|
|
60
|
-
"p-retry": "
|
|
60
|
+
"p-retry": "8",
|
|
61
61
|
"sdp-transform": "^3.0.0",
|
|
62
62
|
"unhomoglyph": "^1.0.6",
|
|
63
63
|
"uuid": "13"
|
|
@@ -109,7 +109,7 @@
|
|
|
109
109
|
"knip": "^6.0.0",
|
|
110
110
|
"lint-staged": "^16.0.0",
|
|
111
111
|
"matrix-mock-request": "^2.5.0",
|
|
112
|
-
"prettier": "3.8.
|
|
112
|
+
"prettier": "3.8.3",
|
|
113
113
|
"typedoc": "^0.28.1",
|
|
114
114
|
"typedoc-plugin-coverage": "^4.0.0",
|
|
115
115
|
"typedoc-plugin-mdn-links": "^5.0.0",
|
|
@@ -118,9 +118,6 @@
|
|
|
118
118
|
"vitest": "^4.0.17",
|
|
119
119
|
"vitest-sonar-reporter": "^3.0.0"
|
|
120
120
|
},
|
|
121
|
-
"resolutions": {
|
|
122
|
-
"expect": "30.3.0"
|
|
123
|
-
},
|
|
124
121
|
"pnpm": {
|
|
125
122
|
"peerDependencyRules": {
|
|
126
123
|
"allowedVersions": {
|
|
@@ -129,7 +126,14 @@
|
|
|
129
126
|
},
|
|
130
127
|
"allowedDeprecatedVersions": {
|
|
131
128
|
"eslint": "8"
|
|
129
|
+
},
|
|
130
|
+
"overrides": {
|
|
131
|
+
"expect": "30.3.0",
|
|
132
|
+
"flatted@<=3.4.1": "^3.4.2",
|
|
133
|
+
"picomatch@>=4.0.0 <4.0.4": "^4.0.4",
|
|
134
|
+
"yaml@>=2.0.0 <2.8.3": "^2.8.3",
|
|
135
|
+
"vite": "7.3.2"
|
|
132
136
|
}
|
|
133
137
|
},
|
|
134
|
-
"packageManager": "pnpm@10.
|
|
138
|
+
"packageManager": "pnpm@10.33.0+sha512.10568bb4a6afb58c9eb3630da90cc9516417abebd3fabbe6739f0ae795728da1491e9db5a544c76ad8eb7570f5c4bb3d6c637b2cb41bfdcdb47fa823c8649319"
|
|
135
139
|
}
|
package/src/@types/event.ts
CHANGED
|
@@ -416,9 +416,12 @@ export interface AccountDataEvents extends SecretStorageAccountDataEvents {
|
|
|
416
416
|
[EventType.Direct]: { [userId: string]: string[] };
|
|
417
417
|
[EventType.IgnoredUserList]: { ignored_users: { [userId: string]: EmptyObject } };
|
|
418
418
|
"m.secret_storage.default_key": { key: string };
|
|
419
|
-
|
|
420
|
-
//
|
|
419
|
+
|
|
420
|
+
// MSC4287: Sharing key backup preference between clients - used to mark that the user opted out of key storage
|
|
421
|
+
"m.key_backup": { enabled: boolean };
|
|
422
|
+
// MSC4287 unstable prefix (note the boolean property has the opposite sense)
|
|
421
423
|
"m.org.matrix.custom.backup_disabled": { disabled: boolean };
|
|
424
|
+
|
|
422
425
|
"m.identity_server": { base_url: string | null };
|
|
423
426
|
[key: `${typeof LOCAL_NOTIFICATION_SETTINGS_PREFIX.name}.${string}`]: LocalNotificationSettings;
|
|
424
427
|
[key: `m.secret_storage.key.${string}`]: SecretStorageKeyDescription;
|
|
@@ -428,6 +431,15 @@ export interface AccountDataEvents extends SecretStorageAccountDataEvents {
|
|
|
428
431
|
[POLICIES_ACCOUNT_EVENT_TYPE.altName]: { [key: string]: any };
|
|
429
432
|
|
|
430
433
|
[EventType.InvitePermissionConfig]: { default_action?: string };
|
|
434
|
+
|
|
435
|
+
// List of recently used reaction emojis
|
|
436
|
+
// https://spec.matrix.org/v1.18/client-server-api/#mrecent_emoji
|
|
437
|
+
"m.recent_emoji": {
|
|
438
|
+
recent_emoji: Array<{
|
|
439
|
+
emoji: string;
|
|
440
|
+
total: number;
|
|
441
|
+
}>;
|
|
442
|
+
};
|
|
431
443
|
}
|
|
432
444
|
|
|
433
445
|
/**
|
package/src/crypto-api/index.ts
CHANGED
|
@@ -188,7 +188,9 @@ export interface CryptoApi {
|
|
|
188
188
|
/**
|
|
189
189
|
* Check if the given user has published cross-signing keys.
|
|
190
190
|
*
|
|
191
|
-
* - If the user is
|
|
191
|
+
* - If the user is this user, a `/keys/query` request is made to update locally the cross signing keys.
|
|
192
|
+
* - If the user is tracked, any current `/keys/query` requests are awaited (with a timeout) and then
|
|
193
|
+
* the locally cached information is used.
|
|
192
194
|
* - If the user is not tracked locally and downloadUncached is set to true,
|
|
193
195
|
* a `/keys/query` request is made to the server to retrieve the cross signing keys.
|
|
194
196
|
* - Otherwise, return false
|
|
@@ -205,7 +207,10 @@ export interface CryptoApi {
|
|
|
205
207
|
* Get the device information for the given list of users.
|
|
206
208
|
*
|
|
207
209
|
* For any users whose device lists are cached (due to sharing an encrypted room with the user), the
|
|
208
|
-
* cached device data is returned.
|
|
210
|
+
* cached device data is returned, unless it is stale.
|
|
211
|
+
*
|
|
212
|
+
* If there are users with stale cached entries, wait (with some timeout) for any in-progress
|
|
213
|
+
* `/keys/query` request to complete.
|
|
209
214
|
*
|
|
210
215
|
* If there are uncached users, and the `downloadUncached` parameter is set to `true`,
|
|
211
216
|
* a `/keys/query` request is made to the server to retrieve these devices.
|
|
@@ -626,7 +631,6 @@ export interface CryptoApi {
|
|
|
626
631
|
* * Disables 4S, deleting the info for the default key, the default key pointer itself and any
|
|
627
632
|
* known 4S data (cross-signing keys and the megolm key backup key).
|
|
628
633
|
* * Deletes any dehydrated devices.
|
|
629
|
-
* * Sets the "m.org.matrix.custom.backup_disabled" account data flag to indicate that the user has disabled backups.
|
|
630
634
|
*/
|
|
631
635
|
disableKeyStorage(): Promise<void>;
|
|
632
636
|
|
|
@@ -857,6 +861,25 @@ export interface BootstrapCrossSigningOpts {
|
|
|
857
861
|
* Represents the ways in which we trust a user
|
|
858
862
|
*/
|
|
859
863
|
export class UserVerificationStatus {
|
|
864
|
+
/**
|
|
865
|
+
* Indicates if we have saved a known identity for this user. Typically, this means that we share a
|
|
866
|
+
* room with them (or have done in the past).
|
|
867
|
+
*
|
|
868
|
+
* If this is `false`, then the other flags ({@link isCrossSigningVerified}, {@link wasCrossSigningVerified},
|
|
869
|
+
* {@link needsUserApproval}) will also be `false`. This means that we haven't seen this user before.
|
|
870
|
+
*
|
|
871
|
+
* If this is `true`, then there are further possibilities:
|
|
872
|
+
*
|
|
873
|
+
* - If {@link isCrossSigningVerified} returns `true`, then we have cryptographically verified the current
|
|
874
|
+
* identity of this user: that is the highest form of trust we have.
|
|
875
|
+
*
|
|
876
|
+
* - If {@link needsUserApproval} is `true`, that means that the user has changed their identity.
|
|
877
|
+
*
|
|
878
|
+
* - Otherwise, the user is "TOFU trusted": we have a record of their identity, and, typically, will share
|
|
879
|
+
* encrypted content with them as long as they retain that identity.
|
|
880
|
+
*/
|
|
881
|
+
public readonly known: boolean;
|
|
882
|
+
|
|
860
883
|
/**
|
|
861
884
|
* Indicates if the identity has changed in a way that needs user approval.
|
|
862
885
|
*
|
|
@@ -872,12 +895,14 @@ export class UserVerificationStatus {
|
|
|
872
895
|
*/
|
|
873
896
|
public readonly needsUserApproval: boolean;
|
|
874
897
|
|
|
898
|
+
/** @internal */
|
|
875
899
|
public constructor(
|
|
876
900
|
private readonly crossSigningVerified: boolean,
|
|
877
901
|
private readonly crossSigningVerifiedBefore: boolean,
|
|
878
|
-
|
|
902
|
+
known: boolean,
|
|
879
903
|
needsUserApproval: boolean = false,
|
|
880
904
|
) {
|
|
905
|
+
this.known = known;
|
|
881
906
|
this.needsUserApproval = needsUserApproval;
|
|
882
907
|
}
|
|
883
908
|
|
|
@@ -909,7 +934,7 @@ export class UserVerificationStatus {
|
|
|
909
934
|
* @deprecated No longer supported, with the Rust crypto stack.
|
|
910
935
|
*/
|
|
911
936
|
public isTofu(): boolean {
|
|
912
|
-
return
|
|
937
|
+
return false;
|
|
913
938
|
}
|
|
914
939
|
}
|
|
915
940
|
|
package/src/embedded.ts
CHANGED
|
@@ -806,7 +806,7 @@ export class RoomWidgetClient extends MatrixClient {
|
|
|
806
806
|
// Sliding Sync
|
|
807
807
|
await this.syncApi!.injectRoomEvents(this.room!, [event]);
|
|
808
808
|
}
|
|
809
|
-
logger.
|
|
809
|
+
logger.debug(`Updated state entry ${event.getType()} ${event.getStateKey()} to ${event.getId()}`);
|
|
810
810
|
} else {
|
|
811
811
|
const { event_id: eventId, room_id: roomId } = ev.detail.data;
|
|
812
812
|
logger.info(`Received state entry ${eventId} for a different room ${roomId}; discarding`);
|
|
@@ -863,7 +863,8 @@ function quickFilterNonRelevantContents(content: IContent, logger: Logger): bool
|
|
|
863
863
|
// We have a MSC4143 event membership event with a proper joined content
|
|
864
864
|
return true;
|
|
865
865
|
} else if (eventKeysCount === 1 && "memberships" in content) {
|
|
866
|
-
|
|
866
|
+
// Events used to have this format in the past, but are now deprecated.
|
|
867
|
+
// Given that state events ~cannot be deleted, there can be some remaining events in the room, just ignore them.
|
|
867
868
|
return false;
|
|
868
869
|
} else {
|
|
869
870
|
// Invalid or left content
|
|
@@ -20,7 +20,7 @@ import type { RelationType } from "../../types.ts";
|
|
|
20
20
|
import { type RtcSlotEventContent, type Transport } from "../types.ts";
|
|
21
21
|
import { MatrixRTCMembershipParseError } from "./common.ts";
|
|
22
22
|
import { sha256 } from "../../digest.ts";
|
|
23
|
-
import {
|
|
23
|
+
import { encodeUnpaddedBase64 } from "../../base64.ts";
|
|
24
24
|
import { slotIdToDescription } from "../utils.ts";
|
|
25
25
|
|
|
26
26
|
/**
|
|
@@ -149,8 +149,9 @@ export const checkRtcMembershipData = (data: IContent, sender: string): data is
|
|
|
149
149
|
};
|
|
150
150
|
|
|
151
151
|
export async function computeRtcIdentityRaw(userId: string, deviceId: string, memberId: string): Promise<string> {
|
|
152
|
-
|
|
153
|
-
const
|
|
154
|
-
const
|
|
152
|
+
// canonical JSON serialization (Matrix canonical JSON for arrays)
|
|
153
|
+
const jsonStr = JSON.stringify([userId, deviceId, memberId]);
|
|
154
|
+
const hashBuffer = await sha256(jsonStr);
|
|
155
|
+
const hashedString = encodeUnpaddedBase64(hashBuffer);
|
|
155
156
|
return hashedString;
|
|
156
157
|
}
|
package/src/oidc/authorize.ts
CHANGED
|
@@ -14,7 +14,15 @@ See the License for the specific language governing permissions and
|
|
|
14
14
|
limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
type IdTokenClaims,
|
|
19
|
+
Log,
|
|
20
|
+
OidcClient,
|
|
21
|
+
type SigninRequestCreateArgs,
|
|
22
|
+
SigninResponse,
|
|
23
|
+
SigninState,
|
|
24
|
+
WebStorageStateStore,
|
|
25
|
+
} from "oidc-client-ts";
|
|
18
26
|
|
|
19
27
|
import { logger } from "../logger.ts";
|
|
20
28
|
import { secureRandomString } from "../randomstring.ts";
|
|
@@ -127,6 +135,8 @@ export const generateAuthorizationUrl = async (
|
|
|
127
135
|
* @param urlState - value to append to the opaque state identifier to uniquely identify the callback
|
|
128
136
|
* @param loginHint - value to send as the `login_hint` to the OP, giving a hint about the login identifier the user might use to log in.
|
|
129
137
|
* See {@link https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest OIDC core 3.1.2.1}.
|
|
138
|
+
* @param responseMode - value to send as the `response_mode` to the OP, selecting how auth is passed back during redirect.
|
|
139
|
+
* See {@link https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest OIDC core 3.1.2.1}.
|
|
130
140
|
* @returns a Promise with the url as a string
|
|
131
141
|
*/
|
|
132
142
|
export const generateOidcAuthorizationUrl = async ({
|
|
@@ -139,6 +149,7 @@ export const generateOidcAuthorizationUrl = async ({
|
|
|
139
149
|
prompt,
|
|
140
150
|
urlState,
|
|
141
151
|
loginHint,
|
|
152
|
+
responseMode = "query",
|
|
142
153
|
}: {
|
|
143
154
|
clientId: string;
|
|
144
155
|
metadata: ValidatedAuthMetadata;
|
|
@@ -149,6 +160,7 @@ export const generateOidcAuthorizationUrl = async ({
|
|
|
149
160
|
prompt?: string;
|
|
150
161
|
urlState?: string;
|
|
151
162
|
loginHint?: string;
|
|
163
|
+
responseMode?: SigninRequestCreateArgs["response_mode"];
|
|
152
164
|
}): Promise<string> => {
|
|
153
165
|
const scope = generateScope();
|
|
154
166
|
const oidcClient = new OidcClient({
|
|
@@ -156,7 +168,7 @@ export const generateOidcAuthorizationUrl = async ({
|
|
|
156
168
|
client_id: clientId,
|
|
157
169
|
redirect_uri: redirectUri,
|
|
158
170
|
authority: metadata.issuer,
|
|
159
|
-
response_mode:
|
|
171
|
+
response_mode: responseMode,
|
|
160
172
|
response_type: "code",
|
|
161
173
|
scope,
|
|
162
174
|
stateStore: new WebStorageStateStore({ prefix: "mx_oidc_", store: window.sessionStorage }),
|
|
@@ -200,7 +212,8 @@ const normalizeBearerTokenResponseTokenType = (response: SigninResponse): Bearer
|
|
|
200
212
|
* request to the Token Endpoint, to obtain the access token, refresh token, etc.
|
|
201
213
|
*
|
|
202
214
|
* @param code - authorization code as returned by OP during authorization
|
|
203
|
-
* @param
|
|
215
|
+
* @param state - authorization state param as returned by OP during authorization
|
|
216
|
+
* @param responseMode - the response mode used for authentication
|
|
204
217
|
* @returns valid bearer token response
|
|
205
218
|
* @throws An `Error` with `message` set to an entry in {@link OidcError},
|
|
206
219
|
* when the request fails, or the returned token response is invalid.
|
|
@@ -208,6 +221,7 @@ const normalizeBearerTokenResponseTokenType = (response: SigninResponse): Bearer
|
|
|
208
221
|
export const completeAuthorizationCodeGrant = async (
|
|
209
222
|
code: string,
|
|
210
223
|
state: string,
|
|
224
|
+
responseMode: SigninRequestCreateArgs["response_mode"] = "query",
|
|
211
225
|
): Promise<{
|
|
212
226
|
oidcClientSettings: { clientId: string; issuer: string };
|
|
213
227
|
tokenResponse: BearerTokenResponse;
|
|
@@ -221,13 +235,18 @@ export const completeAuthorizationCodeGrant = async (
|
|
|
221
235
|
* so that oidc-client can parse it
|
|
222
236
|
*/
|
|
223
237
|
const reconstructedUrl = new URL(window.location.origin);
|
|
224
|
-
|
|
225
|
-
|
|
238
|
+
|
|
239
|
+
const params = new URLSearchParams({ code, state });
|
|
240
|
+
if (responseMode === "query") {
|
|
241
|
+
reconstructedUrl.search = params.toString();
|
|
242
|
+
} else {
|
|
243
|
+
reconstructedUrl.hash = `#${params.toString()}`;
|
|
244
|
+
}
|
|
226
245
|
|
|
227
246
|
// set oidc-client to use our logger
|
|
228
247
|
Log.setLogger(logger);
|
|
229
248
|
try {
|
|
230
|
-
const response = new SigninResponse(
|
|
249
|
+
const response = new SigninResponse(params);
|
|
231
250
|
|
|
232
251
|
const stateStore = new WebStorageStateStore({ prefix: "mx_oidc_", store: window.sessionStorage });
|
|
233
252
|
|
package/src/oidc/discovery.ts
CHANGED
|
@@ -62,6 +62,6 @@ export const validateAuthMetadataAndKeys = async (authMetadata: unknown): Promis
|
|
|
62
62
|
|
|
63
63
|
return {
|
|
64
64
|
...validatedIssuerConfig,
|
|
65
|
-
signingKeys: await metadataService.getSigningKeys(),
|
|
65
|
+
signingKeys: validatedIssuerConfig.jwks_uri ? await metadataService.getSigningKeys() : null,
|
|
66
66
|
};
|
|
67
67
|
};
|