@@ -32,10 +32,23 @@ export const collectStrategyName = (strategy: unknown): string => {
3232 return 'allDevices' ;
3333} ;
3434
35- // Wasm accessors live on the prototype, so JSON would carry only the internal pointer, and a
36- // dropped `sharingStrategy` silently means "share room keys with every device".
3735const num = ( value : unknown ) => ( typeof value === 'bigint' ? Number ( value ) : value ) ;
3836
37+ // Read wasm prototype getters before crossing the JSON boundary.
38+ export const encodeRoomSettings = ( settings : unknown ) : Record < string , unknown > | null => {
39+ if ( settings === null || typeof settings !== 'object' ) return null ;
40+ const s = settings as Record < string , unknown > ;
41+ return {
42+ algorithm : s . algorithm ,
43+ encryptStateEvents : s . encryptStateEvents ,
44+ onlyAllowTrustedDevices : s . onlyAllowTrustedDevices ,
45+ sessionRotationPeriodMs : num ( s . sessionRotationPeriodMs ) ,
46+ sessionRotationPeriodMessages : num ( s . sessionRotationPeriodMessages ) ,
47+ } ;
48+ } ;
49+
50+ // Wasm accessors live on the prototype, so JSON would carry only the internal pointer, and a
51+ // dropped `sharingStrategy` silently means "share room keys with every device".
3952export const encodeEncryptionSettings = ( settings : unknown ) : Record < string , unknown > | null => {
4053 if ( settings === null || typeof settings !== 'object' ) return null ;
4154 const s = settings as Record < string , unknown > ;
@@ -53,6 +66,28 @@ export const encodeDecryptionSettings = (settings: unknown): Record<string, unkn
5366 return { senderDeviceTrustRequirement : typeof trust === 'number' ? trust : 0 } ;
5467} ;
5568
69+ const errorMessage = ( error : unknown ) : string =>
70+ error instanceof Error ? error . message : String ( error ) ;
71+
72+ export const toMegolmDecryptionError = ( error : unknown ) : unknown => {
73+ const description = errorMessage ( error ) ;
74+ const codes = RustSdkCryptoJs . DecryptionErrorCode ;
75+ let code = codes . UnableToDecrypt ;
76+
77+ if ( description . includes ( 'MissingRoomKey' ) ) code = codes . MissingRoomKey ;
78+ else if ( description . includes ( 'UnknownMessageIndex' ) ) code = codes . UnknownMessageIndex ;
79+ else if ( description . includes ( 'MismatchedIdentityKeys' ) ) code = codes . MismatchedIdentityKeys ;
80+ else if ( description . includes ( 'VerificationViolation' ) ) {
81+ code = codes . SenderIdentityVerificationViolation ;
82+ } else if ( description . includes ( 'UnsignedDevice' ) ) code = codes . UnsignedSenderDevice ;
83+ else if ( description . includes ( 'SenderIdentityNotTrusted(None' ) ) code = codes . UnknownSenderDevice ;
84+ else if ( description . includes ( 'MismatchedSender' ) ) code = codes . MismatchedSender ;
85+
86+ const wrapped = { code, description, maybe_withheld : undefined } ;
87+ Object . setPrototypeOf ( wrapped , RustSdkCryptoJs . MegolmDecryptionError . prototype ) ;
88+ return wrapped ;
89+ } ;
90+
5691const hasOwnPrototype = ( name : string ) : boolean => {
5792 const candidate = ( RustSdkCryptoJs as Record < string , unknown > ) [ name ] ;
5893 return typeof candidate === 'function' && 'prototype' in candidate ;
0 commit comments