Repository navigation
v13.0.0
Breaking
-
A linked store that holds group state is refused.
linkHostedRelayDevicelists the linked device's group store before any
write. When the store lists a group that the link did not write, the call
throwsHostedRelayDeviceLinkErrorwith codeDEVICE_LINK_STORE_NOT_EMPTY.
The linked device's group store isgroups.store, or the SDK group store on
the linked store. Link the device again with a new, empty store. -
A custom identity store must accept an overwrite of its own identity
record.linkHostedRelayDevicegives the linked device its own
registration ID with the same identity keys. It callsstoreIdentityKeyand
thensetLocalRegistrationIdfor an identity type that the linked store
already holds. After both calls, both reads of that type must give the new
ID, and the other identity type must stay unchanged. Every store that the SDK
ships does this. A customSignalProtocolLocalStoremust pass this check:const identity = await store.getIdentityKey('aci'); await store.storeIdentityKey({ ...identity!, registrationId: 4321 }, 'aci'); await store.setLocalRegistrationId(4321, 'aci'); (await store.getIdentityKey('aci'))!.registrationId; // 4321 await store.getLocalRegistrationId('aci'); // 4321
-
A SQLite store name that ends in
.oe2e-convertis refused. The
conversion uses that name for its temporary file.nodeStore,expoStore,
reactNativeStore,webSqliteStore, and their resets fail with
INVALID_STATEfor such a name.
Added
-
getGroupInitStatusand theonGroupInitStatushook.
DefaultSignalProtocolClient.getGroupInitStatus(groupId)gives the
GroupInitStatusof a group on this device:'ready','stale',
'pending','no-key', or'denied'. It gives null when the device has no
record of the group.'no-key'means that the device knows the group but
holds no group key.onGroupInitStatus(groupId, status)runs when a client
write to the record of a group changes its status. It does not run when the
status stays the same. -
activeGroupStoreinHostedRelayManagedDeviceLinkOptions. It is the
group store that the link copies from. The default is the SDK group store on
activeDeviceStorage. If a client runs on the active device during the
link, pass that client's group store, or stop that client first. -
Progress phase
'copying'for'device-link'.linkHostedRelayDevice
reports it before it copies the group master keys. -
SQLite stores accept
convertPlaintext: true. An encrypted open then
converts a database thatencryptionAtRest: falsecreated, and keeps every
row and its schema version. The removal of the plaintext file is the commit
point. A crash before it keeps the plaintext file, and a crash after it
leaves a store that the next encrypted open finishes. Each store guide has a
"Convert a plaintext store" section. -
HostedRelayHttpErroris exported from the root entry and theclient
entry. A customHostedRelayManagedDeviceLinkAdaptercan throw it when
the Relay refuses the link. Give it the Relay's status,code, message,
andretryable. A refusal withretryablefalse and the code
KEY_PROOF_INVALIDorCONFLICTthen rolls the link back. The
linkHostedRelayDevicecall keeps the link state for an error of any other
class, also when the error has the samecode. -
Added: the local/store/conformance subpath exports runLocalStoreConformance and assertLocalStoreConformance. A custom local store can check identity overwrite, atomic commits, compare-and-set, receive work, durability, and its protection declaration.
Changed
-
The link copies each group master key.
linkHostedRelayDevicecopies
the master key of each group that the active device's group store lists into
the linked device's group store, in the calling process. No master key
crosses the Relay. A client withgroupson the linked device then fetches
each copied group, so the application no longer brings each master key and
callssyncGroup(). A group record that a release before 12.0.0 wrote, and
that the active device has not read since, is not copied. Read each group
once on the active device before the link to copy it. A link that stops
during the copy copies again on the next call. A link that the Relay refuses
removes its copied groups. -
The SQLite key mismatch error names
convertPlaintext. An encrypted open
of a plaintext file fails withSqliteKeyMismatchError, and its message
gives the option as a way to keep the data. -
An open or a reset with
encryptionAtRest: falserefuses an incomplete
conversion. While the temporary file of a conversion exists, it fails with
INVALID_STATEand changes nothing. -
Each linked device gets its own registration ID.
linkHostedRelayDevice
writes a fresh registration ID into the linked store before it registers.
The ID differs from the ID of the active device. A held PNI record gets a
separate fresh ID. A device that a 12.0.x release linked keeps the ID that it
has. A link that a 12.0.x release began and that stopped before it completed
keeps its stored ID, so it registers the same device. -
A linked store with a device-authentication key and no registration of the
link is refused.linkHostedRelayDevicethrows
HostedRelayDeviceLinkErrorwith codeDEVICE_LINK_STORE_NOT_EMPTYbefore
any write. Link the device again with a new, empty store. -
A refused link rolls back. When the Relay refuses a link with
KEY_PROOF_INVALIDorCONFLICTand the refusal is not retryable, the call
removes the link state and rethrows. It keeps the identity records and the
registration, so the next call sends the same registration ID. Every other
error keeps the link state, and the next call resumes the link.
Fixed
-
Hosted identity docs. The quickstart and API reference describe both
Production modes: application-bound and device-owned.
hostedRelaySandboxIdentityremains limited to Sandbox. The key-label note
states the session interoperability limit. -
A link whose first sync fails rejects and can resume.
linkHostedRelayDevicestops the client and rejects with
OpenE2EE Signal Protocol Relay initial synchronization failedwhen the
client's first sync fails. In 12.0.1 and earlier, it returned the client with
syncStatus'failed'. The next call with the same stores resumes the link
and gets the same device. -
Fixed: removing a web SQLite file also removes its OPFS pool directory.
-
A received message gets one delivery receipt. When the Relay accepted
or refused a delivery receipt, the receive queue completed its record
outside the queue's passes. A pass that read the record before that
completion could put the receipt in the batch again after it. In 12.0.1
and earlier, the sender could then get a second delivery receipt for the
same message. The completion now runs between passes. -
Fixed: the web SQLite store retries a transient OPFS failure of its
open. WebKit can reject an access handle withUnknownErrorunder load,
and the store then rejected the open withOPFS_FILE_BUSY. Now the store
attaches the pool of the file again, up to four attempts, 100 ms apart. It
retries only before the first statement of the request, so the file stays
unchanged. It does not retry a full quota or any other error. After the
fourth attempt the store rejects withOPFS_FILE_BUSYas before.