@gryt/core 0.16.1 → 0.16.2

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.
@@ -155,7 +155,8 @@ export class FakeDeliveryService {
155
155
  if (conversationId === undefined) {
156
156
  const devices = this.devicesOf([me]).map((d) => {
157
157
  const at = this.deviceAddedAt.get(d.deviceId);
158
- return at ? { ...d, createdAt: at, lastSeenAt: at } : d;
158
+ const lastResort = [...this.keyPackages].reverse().find((k) => k.deviceId === d.deviceId && k.lastResort)?.data ?? null;
159
+ return { ...d, ...(at ? { createdAt: at, lastSeenAt: at } : {}), lastResortKeyPackage: lastResort };
159
160
  });
160
161
  return { ok: true, devices };
161
162
  }
@@ -730,8 +730,10 @@ export function createMlsDmDriver(options) {
730
730
  });
731
731
  }
732
732
  }
733
- /** Names from certificates under your own person key: this device's, then your leaves in each group. */
734
- async function ownDeviceNames(d, wanted) {
733
+ /** Names from certificates under your own person key: this device's, your leaves in each group,
734
+ then the last-resort KeyPackage the server lists with each of your devices. */
735
+ async function ownDeviceNames(d, listed) {
736
+ const wanted = new Set(listed.map((x) => x.deviceId));
735
737
  const mine = readDeviceCertificate(d.certificate, scope);
736
738
  const names = new Map([[mine.deviceId, mine.deviceName]]);
737
739
  const unnamed = () => [...wanted].some((id) => !names.has(id));
@@ -751,6 +753,20 @@ export function createMlsDmDriver(options) {
751
753
  }
752
754
  }
753
755
  }
756
+ // Checked here, not trusted: a package that doesn't verify, or isn't under your person key, names nothing.
757
+ for (const x of listed) {
758
+ if (names.has(x.deviceId) || !x.lastResortKeyPackage)
759
+ continue;
760
+ try {
761
+ const bytes = x.lastResortKeyPackage instanceof Uint8Array ? x.lastResortKeyPackage : new Uint8Array(x.lastResortKeyPackage);
762
+ const { certificate: c } = await readMlsKeyPackage(bytes, scope);
763
+ if (c.deviceId === x.deviceId && sameBytes(c.personPublicKey, mine.personPublicKey))
764
+ names.set(x.deviceId, c.deviceName);
765
+ }
766
+ catch {
767
+ // Expired or malformed: the device stays unnamed rather than misnamed.
768
+ }
769
+ }
754
770
  return names;
755
771
  }
756
772
  async function ownDevices() {
@@ -759,7 +775,7 @@ export function createMlsDmDriver(options) {
759
775
  throw refused("Listing devices", r);
760
776
  const d = await ownDevice();
761
777
  const listed = r.devices.filter((x) => x.serverUserId === self);
762
- const names = await ownDeviceNames(d, new Set(listed.map((x) => x.deviceId)));
778
+ const names = await ownDeviceNames(d, listed);
763
779
  return listed.map((x) => ({
764
780
  serverUserId: x.serverUserId,
765
781
  deviceId: x.deviceId,
@@ -17,6 +17,8 @@ export interface MlsDeviceRef {
17
17
  export interface MlsListedDevice extends MlsDeviceRef {
18
18
  createdAt?: string;
19
19
  lastSeenAt?: string;
20
+ /** On your own list: the device's last-resort KeyPackage, whose certificate names it (GRYT-1764). */
21
+ lastResortKeyPackage?: Uint8Array | ArrayBuffer | null;
20
22
  }
21
23
  /** The server's view of a group. `groupId` is lower-case hex. */
22
24
  export interface MlsGroupView {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gryt/core",
3
- "version": "0.16.1",
3
+ "version": "0.16.2",
4
4
  "description": "Gryt's shared application logic: one implementation of the things the desktop and mobile apps both do.",
5
5
  "license": "AGPL-3.0-only",
6
6
  "repository": {