@@ -248,6 +248,7 @@ export class Crypto extends EventEmitter {
248248
249249 private oneTimeKeyCount : number ;
250250 private needsNewFallback : boolean ;
251+ private fallbackCleanup ?: number ; // setTimeout ID
251252
252253 /**
253254 * Cryptography bits
@@ -1850,8 +1851,23 @@ export class Crypto extends EventEmitter {
18501851 }
18511852
18521853 if ( this . getNeedsNewFallback ( ) ) {
1853- logger . info ( "generating fallback key" ) ;
1854- await this . olmDevice . generateFallbackKey ( ) ;
1854+ const fallbackKeys = await this . olmDevice . getFallbackKey ( ) ;
1855+ // if fallbackKeys is non-empty, we've already generated a
1856+ // fallback key, but it hasn't been published yet, so we
1857+ // can use that instead of generating a new one
1858+ if ( ! fallbackKeys . curve25519 ||
1859+ Object . keys ( fallbackKeys . curve25519 ) . length == 0 ) {
1860+ logger . info ( "generating fallback key" ) ;
1861+ if ( this . fallbackCleanup ) {
1862+ // cancel any pending fallback cleanup because generating
1863+ // a new fallback key will already drop the old fallback
1864+ // that would have been dropped, and we don't want to kill
1865+ // the current key
1866+ clearTimeout ( this . fallbackCleanup ) ;
1867+ delete this . fallbackCleanup ;
1868+ }
1869+ await this . olmDevice . generateFallbackKey ( ) ;
1870+ }
18551871 }
18561872
18571873 logger . info ( "calling uploadOneTimeKeys" ) ;
@@ -1898,8 +1914,9 @@ export class Crypto extends EventEmitter {
18981914 private async uploadOneTimeKeys ( ) {
18991915 const promises = [ ] ;
19001916
1901- const fallbackJson : Record < string , IOneTimeKey > = { } ;
1917+ let fallbackJson : Record < string , IOneTimeKey > ;
19021918 if ( this . getNeedsNewFallback ( ) ) {
1919+ fallbackJson = { } ;
19031920 const fallbackKeys = await this . olmDevice . getFallbackKey ( ) ;
19041921 for ( const [ keyId , key ] of Object . entries ( fallbackKeys . curve25519 ) ) {
19051922 const k = { key, fallback : true } ;
@@ -1924,10 +1941,23 @@ export class Crypto extends EventEmitter {
19241941
19251942 await Promise . all ( promises ) ;
19261943
1927- const res = await this . baseApis . uploadKeysRequest ( {
1944+ const requestBody : Record < string , any > = {
19281945 "one_time_keys" : oneTimeJson ,
1929- "org.matrix.msc2732.fallback_keys" : fallbackJson ,
1930- } ) ;
1946+ } ;
1947+
1948+ if ( fallbackJson ) {
1949+ requestBody [ "org.matrix.msc2732.fallback_keys" ] = fallbackJson ;
1950+ requestBody [ "fallback_keys" ] = fallbackJson ;
1951+ }
1952+
1953+ const res = await this . baseApis . uploadKeysRequest ( requestBody ) ;
1954+
1955+ if ( fallbackJson ) {
1956+ this . fallbackCleanup = setTimeout ( ( ) => {
1957+ delete this . fallbackCleanup ;
1958+ this . olmDevice . forgetOldFallbackKey ( ) ;
1959+ } , 60 * 60 * 1000 ) ;
1960+ }
19311961
19321962 await this . olmDevice . markKeysAsPublished ( ) ;
19331963 return res ;
0 commit comments