@@ -56,7 +56,7 @@ export class RoomEncryption {
56
56
this . _sessionBackup = sessionBackup ;
57
57
}
58
58
59
- async restoreMissingSessionsFromBackup ( entries ) {
59
+ async restoreMissingSessionsFromBackup ( entries , log ) {
60
60
const events = entries . filter ( e => e . isEncrypted && ! e . isDecrypted && e . event ) . map ( e => e . event ) ;
61
61
const eventsBySession = groupEventsBySession ( events ) ;
62
62
const groups = Array . from ( eventsBySession . values ( ) ) ;
@@ -69,7 +69,7 @@ export class RoomEncryption {
69
69
// start with last sessions which should be for the last items in the timeline
70
70
for ( var i = missingSessions . length - 1 ; i >= 0 ; i -- ) {
71
71
const session = missingSessions [ i ] ;
72
- await this . _requestMissingSessionFromBackup ( session . senderKey , session . sessionId ) ;
72
+ await log . wrap ( "session" , log => this . _requestMissingSessionFromBackup ( session . senderKey , session . sessionId , log ) ) ;
73
73
}
74
74
}
75
75
}
@@ -98,9 +98,6 @@ export class RoomEncryption {
98
98
return shouldFlush ;
99
99
}
100
100
101
- // this happens before entries exists, as they are created by the syncwriter
102
- // but we want to be able to map it back to something in the timeline easily
103
- // when retrying decryption.
104
101
async prepareDecryptAll ( events , newKeys , source , txn ) {
105
102
const errors = new Map ( ) ;
106
103
const validEvents = [ ] ;
@@ -137,47 +134,50 @@ export class RoomEncryption {
137
134
return new DecryptionPreparation ( preparation , errors , source , this , events ) ;
138
135
}
139
136
140
- async _processDecryptionResults ( events , results , errors , source , txn ) {
137
+ async _processDecryptionResults ( events , results , errors , source , txn , log ) {
141
138
const missingSessionEvents = events . filter ( event => {
142
139
const error = errors . get ( event . event_id ) ;
143
140
return error ?. code === "MEGOLM_NO_SESSION" ;
144
141
} ) ;
145
142
if ( ! missingSessionEvents . length ) {
146
143
return ;
147
144
}
148
- const eventsBySession = groupEventsBySession ( events ) ;
145
+ // store missing event ids if received from sync
146
+ const missingEventsBySession = groupEventsBySession ( missingSessionEvents ) ;
149
147
if ( source === DecryptionSource . Sync ) {
150
- await Promise . all ( Array . from ( eventsBySession . values ( ) ) . map ( async group => {
148
+ await Promise . all ( Array . from ( missingEventsBySession . values ( ) ) . map ( async group => {
151
149
const eventIds = group . events . map ( e => e . event_id ) ;
152
150
return this . _megolmDecryption . addMissingKeyEventIds (
153
151
this . _room . id , group . senderKey , group . sessionId , eventIds , txn ) ;
154
152
} ) ) ;
155
153
}
154
+
155
+ if ( ! this . _sessionBackup ) {
156
+ return ;
157
+ }
156
158
157
- // TODO: do proper logging here
158
- // run detached
159
- Promise . resolve ( ) . then ( async ( ) => {
159
+ log . wrapDetached ( "check key backup" , async log => {
160
160
// if the message came from sync, wait 10s to see if the room key arrives late,
161
161
// and only after that proceed to request from backup
162
+ log . set ( "source" , source ) ;
163
+ log . set ( "events" , missingSessionEvents . length ) ;
164
+ log . set ( "sessions" , missingEventsBySession . size ) ;
162
165
if ( source === DecryptionSource . Sync ) {
163
166
await this . _clock . createTimeout ( 10000 ) . elapsed ( ) ;
164
167
if ( this . _disposed ) {
165
168
return ;
166
169
}
167
170
// now check which sessions have been received already
168
171
const txn = await this . _storage . readTxn ( [ this . _storage . storeNames . inboundGroupSessions ] ) ;
169
- await Promise . all ( Array . from ( eventsBySession ) . map ( async ( [ key , group ] ) => {
172
+ await Promise . all ( Array . from ( missingEventsBySession ) . map ( async ( [ key , group ] ) => {
170
173
if ( await this . _megolmDecryption . hasSession ( this . _room . id , group . senderKey , group . sessionId , txn ) ) {
171
- eventsBySession . delete ( key ) ;
174
+ missingEventsBySession . delete ( key ) ;
172
175
}
173
176
} ) ) ;
174
177
}
175
- await Promise . all ( Array . from ( eventsBySession . values ( ) ) . map ( group => {
176
- return this . _requestMissingSessionFromBackup ( group . senderKey , group . sessionId ) ;
178
+ await Promise . all ( Array . from ( missingEventsBySession . values ( ) ) . map ( group => {
179
+ return log . wrap ( "session" , log => this . _requestMissingSessionFromBackup ( group . senderKey , group . sessionId , log ) ) ;
177
180
} ) ) ;
178
- } ) . catch ( err => {
179
- console . log ( "failed to fetch missing session from key backup" ) ;
180
- console . error ( err ) ;
181
181
} ) ;
182
182
}
183
183
@@ -194,18 +194,21 @@ export class RoomEncryption {
194
194
}
195
195
}
196
196
197
- async _requestMissingSessionFromBackup ( senderKey , sessionId ) {
197
+ async _requestMissingSessionFromBackup ( senderKey , sessionId , log ) {
198
198
// show prompt to enable secret storage
199
199
if ( ! this . _sessionBackup ) {
200
+ log . set ( "enabled" , false ) ;
200
201
this . _notifyMissingMegolmSession ( ) ;
201
202
return ;
202
203
}
203
-
204
+ log . set ( "id" , sessionId ) ;
205
+ log . set ( "senderKey" , senderKey ) ;
204
206
try {
205
- const session = await this . _sessionBackup . getSession ( this . _room . id , sessionId ) ;
207
+ const session = await this . _sessionBackup . getSession ( this . _room . id , sessionId , log ) ;
206
208
if ( session ?. algorithm === MEGOLM_ALGORITHM ) {
207
209
if ( session [ "sender_key" ] !== senderKey ) {
208
- console . warn ( "Got session key back from backup with different sender key, ignoring" , { session, senderKey} ) ;
210
+ log . set ( "wrong_sender_key" , session [ "sender_key" ] ) ;
211
+ log . logLevel = log . level . Warn ;
209
212
return ;
210
213
}
211
214
let roomKey = this . _megolmDecryption . roomKeyFromBackup ( this . _room . id , sessionId , session ) ;
@@ -216,6 +219,7 @@ export class RoomEncryption {
216
219
const txn = await this . _storage . readWriteTxn ( [ this . _storage . storeNames . inboundGroupSessions ] ) ;
217
220
try {
218
221
keyIsBestOne = await this . _megolmDecryption . writeRoomKey ( roomKey , txn ) ;
222
+ log . set ( "isBetter" , keyIsBestOne ) ;
219
223
if ( keyIsBestOne ) {
220
224
retryEventIds = roomKey . eventIds ;
221
225
}
@@ -230,15 +234,18 @@ export class RoomEncryption {
230
234
roomKey . dispose ( ) ;
231
235
}
232
236
if ( keyIsBestOne ) {
233
- await this . _room . notifyRoomKey ( roomKey , retryEventIds || [ ] ) ;
237
+ await log . wrap ( "retryDecryption" , log => this . _room . notifyRoomKey ( roomKey , retryEventIds || [ ] , log ) ) ;
234
238
}
235
239
}
236
240
} else if ( session ?. algorithm ) {
237
- console . info ( `Backed-up session of unknown algorithm: ${ session . algorithm } ` ) ;
241
+ log . set ( " unknown algorithm" , session . algorithm ) ;
238
242
}
239
243
} catch ( err ) {
240
244
if ( ! ( err . name === "HomeServerError" && err . errcode === "M_NOT_FOUND" ) ) {
241
- console . error ( `Could not get session ${ sessionId } from backup` , err ) ;
245
+ log . set ( "not_found" , true ) ;
246
+ } else {
247
+ log . error = err ;
248
+ log . logLevel = log . level . Error ;
242
249
}
243
250
}
244
251
}
@@ -485,10 +492,10 @@ class DecryptionChanges {
485
492
this . _events = events ;
486
493
}
487
494
488
- async write ( txn ) {
495
+ async write ( txn , log ) {
489
496
const { results, errors} = await this . _megolmDecryptionChanges . write ( txn ) ;
490
497
mergeMap ( this . _extraErrors , errors ) ;
491
- await this . _roomEncryption . _processDecryptionResults ( this . _events , results , errors , this . _source , txn ) ;
498
+ await this . _roomEncryption . _processDecryptionResults ( this . _events , results , errors , this . _source , txn , log ) ;
492
499
return new BatchDecryptionResult ( results , errors , this . _roomEncryption ) ;
493
500
}
494
501
}
0 commit comments