@chisquare-tech/yan-ngx-apps-messages 0.1.1 → 0.2.0

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chisquare-tech-yan-ngx-apps-messages-chisquare-tech-yan-ngx-apps-messages-BBsDA0CG.mjs","sources":["../../../projects/messages/src/lib/routes.ts","../../../projects/messages/src/lib/dm-socket.ts","../../../projects/messages/src/lib/e2ee.ts","../../../projects/messages/src/lib/idb-store.ts","../../../projects/messages/src/lib/labels.ts","../../../projects/messages/src/lib/tokens.ts","../../../projects/messages/src/lib/messaging-api.ts","../../../projects/messages/src/lib/messages.store.ts","../../../projects/messages/src/chisquare-tech-yan-ngx-apps-messages.ts"],"sourcesContent":["import { Routes } from '@angular/router';\n\n/** Mounted at `messages`. `to/:userId` opens (or starts) the direct conversation with someone, then replaces itself. */\nexport const MESSAGES_ROUTES: Routes = [\n { path: '', pathMatch: 'full', loadComponent: () => import('./messages.page').then((m) => m.MessagesPage) },\n { path: 'requests', loadComponent: () => import('./messages.page').then((m) => m.MessagesPage) },\n { path: 'to/:userId', loadComponent: () => import('./start.page').then((m) => m.StartPage) },\n { path: ':id', loadComponent: () => import('./messages.page').then((m) => m.MessagesPage) },\n];\n","// The `dm` channel of Yan's one WebSocket (/ws, cloud/server/realtime): auth with an access token in the first frame\n// (never in the URL), subscribe, answer pings, and on a drop reconnect with backoff and resume from the last seq.\n// Frames carry ids, never content.\n\nexport interface DmEvent {\n t: 'message' | 'to-device' | 'receipt' | 'typing' | 'membership' | string;\n id?: string;\n d?: Record<string, unknown>;\n}\n\ninterface Frame {\n v?: number;\n ch?: string;\n t: string;\n id?: string;\n seq?: number;\n d?: Record<string, unknown>;\n}\n\nexport interface DmSocketOptions {\n url: () => string;\n token: () => Promise<string | null>;\n device: () => string;\n onEvent: (e: DmEvent) => void;\n /** after a reconnect that may have missed events (resync or a gap): reload what's on screen */\n onResync: () => void;\n}\n\nexport class DmSocket {\n private ws: WebSocket | null = null;\n private seq: number | undefined;\n private attempt = 0;\n private timer: ReturnType<typeof setTimeout> | null = null;\n private closed = false;\n private readonly o: DmSocketOptions;\n\n constructor(o: DmSocketOptions) {\n this.o = o;\n }\n\n start(): void {\n this.closed = false;\n void this.connect();\n }\n\n stop(): void {\n this.closed = true;\n if (this.timer) clearTimeout(this.timer);\n this.ws?.close();\n this.ws = null;\n }\n\n private async connect(): Promise<void> {\n if (this.closed) return;\n const token = await this.o.token().catch(() => null);\n if (!token || this.closed) return this.retry();\n let ws: WebSocket;\n try {\n ws = new WebSocket(this.o.url());\n } catch {\n return this.retry();\n }\n this.ws = ws;\n ws.onopen = () => ws.send(JSON.stringify({ v: 1, t: 'auth', token, device: this.o.device() }));\n ws.onmessage = (e) => {\n let f: Frame;\n try {\n f = JSON.parse(String(e.data)) as Frame;\n } catch {\n return;\n }\n if (f.t === 'ping') return ws.send(JSON.stringify({ v: 1, t: 'pong' }));\n if (f.t === 'ready') {\n const since = this.seq;\n return ws.send(JSON.stringify(since === undefined ? { v: 1, t: 'sub', ch: 'dm' } : { v: 1, t: 'sub', ch: 'dm', since }));\n }\n if (f.ch !== 'dm') return;\n if (f.t === 'subscribed') {\n this.attempt = 0;\n const cur = f.seq ?? 0;\n if (this.seq === undefined) this.seq = cur; // first time: from now on\n else if (cur < this.seq) {\n // the server restarted and its numbering with it: what we missed can't be replayed\n this.seq = cur;\n this.o.onResync();\n }\n // otherwise the frames after our seq are replayed next\n return;\n }\n if (f.t === 'resync') {\n this.seq = f.seq;\n return this.o.onResync();\n }\n if (f.t === 'error') return;\n if (typeof f.seq === 'number') {\n if (this.seq !== undefined && f.seq > this.seq + 1) this.o.onResync();\n this.seq = Math.max(this.seq ?? 0, f.seq);\n }\n this.o.onEvent({ t: f.t, id: f.id, d: f.d });\n };\n ws.onclose = () => {\n if (this.ws === ws) this.ws = null;\n this.retry();\n };\n }\n\n private retry(): void {\n if (this.closed || this.timer) return;\n const delay = Math.min(30_000, 1000 * 2 ** this.attempt) * (0.5 + Math.random() / 2);\n this.attempt = Math.min(this.attempt + 1, 6);\n this.timer = setTimeout(() => {\n this.timer = null;\n void this.connect();\n }, delay);\n }\n}\n","// End-to-end encryption for Yan's DMs (PLAN P1.7, TRD §5.8; owner decision 2026-11-06: Olm/Megolm via vodozemac,\n// @chisquare-tech/yan-e2ee). Framework-free, so the same code runs in the browser and in node tests: the wasm module,\n// storage, the server API and the lock are all passed in.\n//\n// The model is Matrix's:\n// - Each device has an Olm account. It publishes signed identity keys, signed one-time keys and a fallback key.\n// - Each device sending to a conversation has a Megolm group session per epoch (the server bumps the epoch on every\n// membership change), rotated after ROTATE_AFTER messages. Its key goes to every member device over Olm, through\n// that device's to-device inbox, before the first message that device should read.\n// - Messages are Megolm ciphertext. The server stores and relays what it can't read.\n//\n// Envelopes (version 1). The Android and iOS clients must produce exactly these:\n// - to-device body: JSON {\"v\":1,\"type\":0|1,\"body\":\"<olm ciphertext>\"} (type 0 is a pre-key message)\n// - its plaintext: {\"t\":\"yan.room_key\",\"conversationId\",\"epoch\",\"sessionId\",\"sessionKey\",\n// \"sender\":{\"userId\",\"deviceId\",\"ed25519\"},\"recipient\":{\"userId\",\"deviceId\",\"ed25519\"}}\n// - a message's Megolm plaintext: {\"v\":1,\"conversationId\",\"kind\",\"text\"}\n// - history for a new device of yours (owner-approved, \"Verifying a new device\" in the yan-e2ee README):\n// new → old {\"t\":\"yan.history_request\",\"requestId\",\"commitment\":sha256(n2),\"requester\":Party}\n// old → new {\"t\":\"yan.history_challenge\",\"requestId\",\"nonce\":n1,\"approver\":Party,\"recipient\":Party}\n// new → old {\"t\":\"yan.history_reveal\",\"requestId\",\"nonce\":n2,\"requester\":Party,\"recipient\":Party}\n// both show verification_code(\"yan.verify.v1|user|newDevice|newEd|oldDevice|oldEd|n1|n2\"); the person allows\n// it on the old device, which then sends\n// old → new {\"t\":\"yan.forwarded_room_keys\",\"requestId\",\"keys\":[{conversationId,sessionId,senderUserId,\n// senderDeviceId,exported}],\"sender\":Party,\"recipient\":Party}\n// The commitment means neither side (nor a server posing as one) can steer the code.\n// A room key is accepted only when it names this device as the recipient and its sender matches the device that\n// sent it (its keys as the server published them, signed by itself). A message is shown only when its session's\n// conversation and sender match the message's own.\n\nimport type * as YanE2ee from '@chisquare-tech/yan-e2ee';\n\nexport type Wasm = Pick<typeof YanE2ee, 'Account' | 'Session' | 'GroupSession' | 'InboundGroupSession' | 'verify_ed25519' | 'sha256_base64' | 'verification_code'>;\ntype Account = YanE2ee.Account;\ntype OlmSession = YanE2ee.Session;\n\nexport const OLM = 'm.olm.v1.curve25519-aes-sha2';\nexport const MEGOLM = 'm.megolm.v1.aes-sha2';\n/** One-time keys a device keeps on the server; topped up when it falls below half. */\nexport const KEY_TARGET = 50;\n/** Messages per group session before a new one (Matrix's default is 100 too). */\nexport const ROTATE_AFTER = 100;\n\n// ---- what the server says (yan-gox-apps/libs/messaging) ----\n\nexport interface DeviceKeys {\n userId: string;\n deviceId: string;\n curve25519: string;\n ed25519: string;\n signature: string;\n name?: string;\n}\n\nexport interface SignedKey {\n keyId: string;\n key: string;\n signature: string;\n}\n\nexport interface ClaimedKey extends SignedKey {\n userId: string;\n deviceId: string;\n fallback?: boolean;\n}\n\nexport interface ToDeviceOut {\n userId: string;\n deviceId: string;\n type: string;\n body: string;\n}\n\nexport interface ToDeviceIn {\n id: number;\n senderUserId: string;\n senderDeviceId: string;\n type: string;\n body: string;\n}\n\nexport interface KeyCount {\n oneTimeKeys: number;\n fallback: boolean;\n}\n\n/** The messaging API calls the machine needs. */\nexport interface E2eeTransport {\n /** Resolves false when the server refuses the device id (revoked, or other keys): the machine starts a new one. */\n registerDevice(deviceId: string, body: { curve25519: string; ed25519: string; signature: string; name: string }): Promise<boolean>;\n uploadKeys(deviceId: string, body: { oneTimeKeys: SignedKey[]; fallbackKey?: SignedKey }): Promise<KeyCount>;\n /** null when the server doesn't know the device (revoked: signed out from another device) */\n keyCount(deviceId: string): Promise<KeyCount | null>;\n devices(userId: string): Promise<DeviceKeys[]>;\n claim(devices: { userId: string; deviceId: string }[]): Promise<ClaimedKey[]>;\n sendToDevice(senderDevice: string, messages: ToDeviceOut[]): Promise<number>;\n inbox(deviceId: string, after: number): Promise<ToDeviceIn[]>;\n ackInbox(deviceId: string, upTo: number): Promise<void>;\n}\n\n/** String storage for one person on one device (IndexedDB in the browser). Pickles are already encrypted. */\nexport interface E2eeStore {\n get(key: string): Promise<string | undefined>;\n set(key: string, value: string): Promise<void>;\n del(key: string): Promise<void>;\n /** every key starting with prefix */\n keys(prefix: string): Promise<string[]>;\n}\n\n/** Runs fn exclusively across everything sharing the store (navigator.locks across tabs in the browser). */\nexport type Lock = <T>(fn: () => Promise<T>) => Promise<T>;\n\n/** A lock for one process. */\nexport function localLock(): Lock {\n let tail: Promise<unknown> = Promise.resolve();\n return <T>(fn: () => Promise<T>) => {\n const run = tail.then(fn, fn);\n tail = run.catch(() => undefined);\n return run;\n };\n}\n\n// ---- what a conversation and a message look like to the machine ----\n\nexport interface ConversationKeys {\n id: string;\n epoch: number;\n /** Everyone who should read: active members and those with it in Requests. Left and declined ones get no keys. */\n members: { userId: string; state: string }[];\n}\n\nexport interface Encrypted {\n senderDevice: string;\n algorithm: string;\n sessionId: string;\n ciphertext: string;\n}\n\nexport interface SealedMessage {\n id: string;\n conversationId: string;\n senderId: string;\n senderDeviceId: string;\n algorithm: string;\n sessionId: string;\n ciphertext: string;\n}\n\nexport interface Plain {\n kind: string;\n text: string;\n}\n\nexport type Opened = ({ ok: true } & Plain) | { ok: false; reason: 'missing-key' | 'invalid' };\n\n// ---- pure rules (also used by tests) ----\n\nexport const deviceSigningText = (userId: string, deviceId: string, curve: string, ed: string) =>\n `yan.device.v1|${userId}|${deviceId}|${curve}|${ed}`;\n\nexport const keySigningText = (userId: string, deviceId: string, keyId: string, key: string, fallback: boolean) =>\n `yan.${fallback ? 'fallback' : 'otk'}.v1|${userId}|${deviceId}|${keyId}|${key}`;\n\ninterface Party {\n userId: string;\n deviceId: string;\n ed25519: string;\n}\n\nexport interface RoomKey {\n t: 'yan.room_key';\n conversationId: string;\n epoch: number;\n sessionId: string;\n sessionKey: string;\n sender: Party;\n recipient: Party;\n}\n\n/** A room key that arrived from `from` is for `me` and really from that device. */\nexport function roomKeyProblem(k: unknown, me: Party, from: Party): string | null {\n const r = k as RoomKey;\n if (!r || r.t !== 'yan.room_key') return 'not a room key';\n if (typeof r.conversationId !== 'string' || typeof r.sessionId !== 'string' || typeof r.sessionKey !== 'string') return 'malformed';\n if (!same(r.recipient, me)) return 'meant for another device';\n if (!same(r.sender, from)) return 'sender mismatch';\n return null;\n}\n\nconst same = (a: Party | undefined, b: Party) => !!a && a.userId === b.userId && a.deviceId === b.deviceId && a.ed25519 === b.ed25519;\n\n/** Keys to generate so the server holds about KEY_TARGET: none until it falls below half. */\nexport function keysToGenerate(onServer: number, target = KEY_TARGET): number {\n return onServer >= target / 2 ? 0 : target - onServer;\n}\n\n// ---- storage records ----\n\ninterface DeviceRecord {\n deviceId: string;\n account: string; // pickle\n registered: boolean;\n}\n\ninterface OutboundRecord {\n epoch: number;\n sessionId: string;\n pickle: string;\n sent: number;\n /** user|device|curve25519 of every device that has its key */\n shared: string[];\n}\n\ninterface InboundRecord {\n pickle: string;\n conversationId: string;\n senderUserId: string;\n senderDeviceId: string;\n firstIndex: number;\n}\n\ninterface OlmRecord {\n /** newest first */\n sessions: { id: string; pickle: string }[];\n}\n\nconst MAX_OLM_PER_PEER = 5;\n/** forwarded sessions per to-device message (each well under the server's 64 KB) */\nconst KEYS_PER_MESSAGE = 40;\n\n/** On a new device: its request for history, and the code each of your other devices agreed with it. */\ninterface OutgoingHistory {\n requestId: string;\n nonce: string; // n2, revealed once a device answers\n startedAt: string;\n asked: string[]; // device ids\n codes: Record<string, string>; // approver device id → code\n received: number;\n /** a device you allowed has sent what it had */\n done?: boolean;\n}\n\n/** On an existing device: a new device of yours asking for history. */\ninterface IncomingHistory {\n requestId: string;\n requester: Party;\n commitment: string;\n nonce: string; // n1\n code?: string; // once revealed\n state: 'challenged' | 'ready' | 'sent' | 'denied';\n createdAt: string;\n}\n\n/** A new device of yours waiting for you to allow it here. */\nexport interface HistoryApproval {\n requestId: string;\n deviceId: string;\n deviceName: string;\n code: string;\n createdAt: string;\n}\n\n/** On a new device: where its request for history stands. */\nexport interface HistoryStatus {\n /** none: never asked; alone: you have no other device to ask */\n state: 'none' | 'alone' | 'asked' | 'received';\n /** what each answering device should show, to check before allowing */\n codes: { deviceId: string; deviceName: string; code: string }[];\n received: number;\n}\n\nconst verifyText = (userId: string, requester: Party, approver: Party, n1: string, n2: string) =>\n `yan.verify.v1|${userId}|${requester.deviceId}|${requester.ed25519}|${approver.deviceId}|${approver.ed25519}|${n1}|${n2}`;\n\nexport interface MachineOptions {\n wasm: Wasm;\n transport: E2eeTransport;\n store: E2eeStore;\n /** 32 bytes that never leave the device: every pickle is encrypted with it */\n pickleKey: Uint8Array;\n userId: string;\n deviceName: string;\n lock?: Lock;\n newDeviceId?: () => string;\n log?: (msg: string) => void;\n}\n\n/** One person's encryption on one device. */\nexport class E2eeMachine {\n private readonly w: Wasm;\n private readonly api: E2eeTransport;\n private readonly store: E2eeStore;\n private readonly key: Uint8Array;\n private readonly lock: Lock;\n private readonly log: (msg: string) => void;\n private readonly newId: () => string;\n readonly userId: string;\n private readonly deviceName: string;\n private dev!: DeviceRecord;\n private ed!: string;\n private curve!: string;\n /** devices as the server published them and we checked them, per user, for this page's life */\n private readonly deviceCache = new Map<string, Promise<DeviceKeys[]>>();\n /** sessionId → message index → message id: a reused index is a replay */\n private readonly seen = new Map<string, Map<number, string>>();\n\n private constructor(o: MachineOptions) {\n this.w = o.wasm;\n this.api = o.transport;\n this.store = o.store;\n this.key = o.pickleKey;\n this.lock = o.lock ?? localLock();\n this.log = o.log ?? (() => undefined);\n this.userId = o.userId;\n this.deviceName = o.deviceName;\n this.newId = o.newDeviceId ?? randomDeviceId;\n }\n\n /** Loads this device's account, or makes and publishes a new one; then makes sure the server has its keys. */\n static async open(o: MachineOptions): Promise<E2eeMachine> {\n const m = new E2eeMachine(o);\n await m.lock(() => m.boot());\n return m;\n }\n\n get deviceId(): string {\n return this.dev.deviceId;\n }\n\n get ed25519(): string {\n return this.ed;\n }\n\n private async boot(): Promise<void> {\n const raw = await this.store.get('device');\n this.dev = raw ? (JSON.parse(raw) as DeviceRecord) : this.fresh();\n for (let attempt = 0; ; attempt++) {\n const acct = this.account();\n this.ed = acct.ed25519;\n this.curve = acct.curve25519;\n if (!this.dev.registered) {\n const ok = await this.api.registerDevice(this.dev.deviceId, {\n curve25519: this.curve,\n ed25519: this.ed,\n signature: acct.sign(deviceSigningText(this.userId, this.dev.deviceId, this.curve, this.ed)),\n name: this.deviceName,\n });\n if (!ok) {\n acct.free();\n if (attempt > 0) throw new Error('the server refused this device');\n this.log('device refused; starting a new one');\n await this.wipe();\n this.dev = this.fresh();\n continue;\n }\n this.dev.registered = true;\n await this.saveDevice(acct);\n }\n acct.free();\n const count = await this.api.keyCount(this.dev.deviceId);\n if (!count) {\n if (attempt > 0) throw new Error('the server forgot this device');\n this.log('device unknown to the server; starting a new one');\n await this.wipe();\n this.dev = this.fresh();\n continue;\n }\n await this.topUp(count);\n break;\n }\n }\n\n private fresh(): DeviceRecord {\n const acct = new this.w.Account();\n const rec = { deviceId: this.newId(), account: acct.pickle(this.key), registered: false };\n acct.free();\n return rec;\n }\n\n private async wipe(): Promise<void> {\n await this.store.del('device');\n await this.store.del('inboxAfter');\n }\n\n private account(): Account {\n return this.w.Account.from_pickle(this.dev.account, this.key);\n }\n\n private async saveDevice(acct: Account): Promise<void> {\n this.dev.account = acct.pickle(this.key);\n await this.store.set('device', JSON.stringify(this.dev));\n }\n\n /** Publishes one-time keys when the server is running low, and a fallback key when it has none. */\n private async topUp(count?: KeyCount): Promise<void> {\n const c = count ?? (await this.api.keyCount(this.dev.deviceId));\n if (!c) return;\n const n = keysToGenerate(c.oneTimeKeys);\n if (!n && c.fallback) return;\n const acct = this.account();\n try {\n if (n) acct.generate_one_time_keys(Math.min(n, acct.max_one_time_keys()));\n if (!c.fallback) acct.generate_fallback_key();\n const sign = (fallback: boolean) => ([keyId, key]: [string, string]): SignedKey => ({\n keyId,\n key,\n signature: acct.sign(keySigningText(this.userId, this.dev.deviceId, keyId, key, fallback)),\n });\n const otks = Object.entries(acct.one_time_keys() as Record<string, string>).map(sign(false));\n const [fallbackKey] = Object.entries(acct.fallback_key() as Record<string, string>).map(sign(true));\n if (!otks.length && !fallbackKey) return;\n // saved before upload: if the upload is lost, the same keys go next time (the server ignores repeats)\n await this.saveDevice(acct);\n await this.api.uploadKeys(this.dev.deviceId, { oneTimeKeys: otks, fallbackKey });\n acct.mark_keys_as_published();\n await this.saveDevice(acct);\n } finally {\n acct.free();\n }\n }\n\n // ---- devices ----\n\n /** A user's devices whose keys are signed by themselves and match what this device saw before (trust on first use). */\n private devicesOf(userId: string): Promise<DeviceKeys[]> {\n let p = this.deviceCache.get(userId);\n if (!p) {\n p = this.loadDevices(userId);\n this.deviceCache.set(userId, p);\n p.catch(() => this.deviceCache.delete(userId));\n }\n return p;\n }\n\n private async loadDevices(userId: string): Promise<DeviceKeys[]> {\n const out: DeviceKeys[] = [];\n for (const d of await this.api.devices(userId)) {\n if (d.userId !== userId) continue;\n if (!this.w.verify_ed25519(d.ed25519, deviceSigningText(userId, d.deviceId, d.curve25519, d.ed25519), d.signature)) {\n this.log(`device ${userId}/${d.deviceId}: bad signature`);\n continue;\n }\n const pinKey = `pin:${userId}|${d.deviceId}`;\n const pinned = await this.store.get(pinKey);\n const now = `${d.curve25519}|${d.ed25519}`;\n if (pinned && pinned !== now) {\n this.log(`device ${userId}/${d.deviceId}: keys changed`);\n continue;\n }\n if (!pinned) await this.store.set(pinKey, now);\n out.push(d);\n }\n return out;\n }\n\n /** Forget cached device lists (someone signed in on a new device, or a membership changed). */\n forgetDevices(userId?: string): void {\n if (userId) this.deviceCache.delete(userId);\n else this.deviceCache.clear();\n }\n\n // ---- Olm sessions ----\n\n private async olmSessions(curve: string): Promise<OlmRecord> {\n const raw = await this.store.get(`olm:${curve}`);\n return raw ? (JSON.parse(raw) as OlmRecord) : { sessions: [] };\n }\n\n private async saveOlm(curve: string, s: OlmSession, rec?: OlmRecord): Promise<void> {\n const r = rec ?? (await this.olmSessions(curve));\n const id = s.session_id;\n const rest = r.sessions.filter((x) => x.id !== id);\n r.sessions = [{ id, pickle: s.pickle(this.key) }, ...rest].slice(0, MAX_OLM_PER_PEER);\n await this.store.set(`olm:${curve}`, JSON.stringify(r));\n }\n\n /** Olm sessions to each device, opening new ones from claimed one-time keys where there are none yet. */\n private async olmTo(devices: DeviceKeys[]): Promise<Map<string, OlmSession>> {\n const out = new Map<string, OlmSession>();\n const need: DeviceKeys[] = [];\n for (const d of devices) {\n const rec = await this.olmSessions(d.curve25519);\n if (rec.sessions.length) out.set(d.curve25519, this.w.Session.from_pickle(rec.sessions[0].pickle, this.key));\n else need.push(d);\n }\n if (!need.length) return out;\n const claimed = await this.api.claim(need.map((d) => ({ userId: d.userId, deviceId: d.deviceId })));\n const acct = this.account();\n try {\n for (const k of claimed) {\n const d = need.find((x) => x.userId === k.userId && x.deviceId === k.deviceId);\n if (!d) continue;\n if (!this.w.verify_ed25519(d.ed25519, keySigningText(d.userId, d.deviceId, k.keyId, k.key, !!k.fallback), k.signature)) {\n this.log(`claimed key for ${d.userId}/${d.deviceId}: bad signature`);\n continue;\n }\n const s = acct.create_outbound_session(d.curve25519, k.key);\n await this.saveOlm(d.curve25519, s);\n out.set(d.curve25519, s);\n }\n } finally {\n acct.free();\n }\n return out;\n }\n\n // ---- sending ----\n\n /** Encrypts a message for a conversation, first sending the group session's key to every device that lacks it. */\n encrypt(conv: ConversationKeys, plain: Plain): Promise<Encrypted> {\n return this.lock(async () => {\n const outKey = `out:${conv.id}`;\n const raw = await this.store.get(outKey);\n let rec = raw ? (JSON.parse(raw) as OutboundRecord) : null;\n if (!rec || rec.epoch !== conv.epoch || rec.sent >= ROTATE_AFTER) rec = await this.newOutbound(conv);\n const group = this.w.GroupSession.from_pickle(rec.pickle, this.key);\n try {\n await this.share(conv, group, rec);\n const ciphertext = group.encrypt(JSON.stringify({ v: 1, conversationId: conv.id, kind: plain.kind, text: plain.text }));\n rec.sent++;\n rec.pickle = group.pickle(this.key);\n await this.store.set(outKey, JSON.stringify(rec));\n return { senderDevice: this.dev.deviceId, algorithm: MEGOLM, sessionId: rec.sessionId, ciphertext };\n } finally {\n group.free();\n }\n });\n }\n\n private async newOutbound(conv: ConversationKeys): Promise<OutboundRecord> {\n const g = new this.w.GroupSession();\n // our own copy, so this device reads what it sent\n const ib = new this.w.InboundGroupSession(g.session_key);\n const mine: InboundRecord = { pickle: ib.pickle(this.key), conversationId: conv.id, senderUserId: this.userId, senderDeviceId: this.dev.deviceId, firstIndex: ib.first_known_index };\n await this.store.set(`in:${g.session_id}`, JSON.stringify(mine));\n const rec = { epoch: conv.epoch, sessionId: g.session_id, pickle: g.pickle(this.key), sent: 0, shared: [] };\n ib.free();\n g.free();\n return rec;\n }\n\n private async share(conv: ConversationKeys, group: YanE2ee.GroupSession, rec: OutboundRecord): Promise<void> {\n const readers = [...new Set(conv.members.filter((m) => m.state === 'active' || m.state === 'request').map((m) => m.userId))];\n if (!readers.includes(this.userId)) readers.push(this.userId); // our other devices\n const targets: DeviceKeys[] = [];\n for (const u of readers) {\n for (const d of await this.devicesOf(u)) {\n if (u === this.userId && d.deviceId === this.dev.deviceId) continue;\n if (!rec.shared.includes(`${u}|${d.deviceId}|${d.curve25519}`)) targets.push(d);\n }\n }\n if (!targets.length) return;\n const sessions = await this.olmTo(targets);\n const sessionKey = group.session_key; // from the current index: a new reader can't open what came before\n const messages: ToDeviceOut[] = [];\n const done: string[] = [];\n for (const d of targets) {\n const s = sessions.get(d.curve25519);\n if (!s) continue; // no keys to claim: that device reads nothing until it publishes some\n const k: RoomKey = {\n t: 'yan.room_key',\n conversationId: conv.id,\n epoch: conv.epoch,\n sessionId: rec.sessionId,\n sessionKey,\n sender: { userId: this.userId, deviceId: this.dev.deviceId, ed25519: this.ed },\n recipient: { userId: d.userId, deviceId: d.deviceId, ed25519: d.ed25519 },\n };\n const sealed = s.encrypt(JSON.stringify(k));\n await this.saveOlm(d.curve25519, s);\n s.free();\n messages.push({ userId: d.userId, deviceId: d.deviceId, type: OLM, body: JSON.stringify({ v: 1, type: sealed.message_type, body: sealed.body }) });\n done.push(`${d.userId}|${d.deviceId}|${d.curve25519}`);\n }\n for (let i = 0; i < messages.length; i += 200) await this.api.sendToDevice(this.dev.deviceId, messages.slice(i, i + 200));\n rec.shared.push(...done);\n }\n\n // ---- receiving ----\n\n /** Reads this device's to-device inbox: room keys from other devices. Answers how many new keys arrived. */\n sync(): Promise<number> {\n return this.lock(() => this.syncLocked());\n }\n\n private async syncLocked(): Promise<number> {\n let after = Number((await this.store.get('inboxAfter')) ?? 0);\n let added = 0;\n let usedOneTimeKey = false;\n for (;;) {\n const items = await this.api.inbox(this.dev.deviceId, after);\n if (!items.length) break;\n for (const it of items) {\n try {\n const r = await this.receive(it);\n added += r.added;\n usedOneTimeKey ||= r.newSession;\n } catch (e) {\n this.log(`to-device ${it.id} from ${it.senderUserId}/${it.senderDeviceId}: ${(e as Error).message}`);\n }\n after = Math.max(after, it.id);\n }\n await this.store.set('inboxAfter', String(after));\n await this.api.ackInbox(this.dev.deviceId, after);\n }\n if (usedOneTimeKey) await this.topUp();\n return added;\n }\n\n private async receive(it: ToDeviceIn): Promise<{ added: number; newSession: boolean }> {\n if (it.type !== OLM) return { added: 0, newSession: false };\n const { from, plaintext, newSession } = await this.openOlm(it);\n const msg = JSON.parse(plaintext) as { t?: string };\n const me: Party = { userId: this.userId, deviceId: this.dev.deviceId, ed25519: this.ed };\n const sender: Party = { userId: from.userId, deviceId: from.deviceId, ed25519: from.ed25519 };\n switch (msg.t) {\n case 'yan.room_key':\n return { added: await this.roomKey(msg as RoomKey, me, sender), newSession };\n case 'yan.history_request':\n case 'yan.history_challenge':\n case 'yan.history_reveal':\n case 'yan.forwarded_room_keys':\n // only between your own devices\n if (from.userId !== this.userId || from.deviceId === this.dev.deviceId) throw new Error('history from someone else');\n return { added: await this.history(msg as Record<string, unknown> & { t: string }, me, sender, from), newSession };\n default:\n throw new Error('unknown payload');\n }\n }\n\n /** Decrypts an Olm to-device payload from a device whose keys check out. */\n private async openOlm(it: ToDeviceIn): Promise<{ from: DeviceKeys; plaintext: string; newSession: boolean }> {\n const env = JSON.parse(it.body) as { v: number; type: number; body: string };\n if (env.v !== 1) throw new Error('unknown envelope');\n const find = async () => (await this.devicesOf(it.senderUserId)).find((d) => d.deviceId === it.senderDeviceId);\n let from = await find();\n if (!from) {\n // a device that signed in after we last looked\n this.forgetDevices(it.senderUserId);\n from = await find();\n }\n if (!from) throw new Error('unknown sender device');\n\n const rec = await this.olmSessions(from.curve25519);\n for (const s of rec.sessions) {\n const sess = this.w.Session.from_pickle(s.pickle, this.key);\n try {\n const plaintext = sess.decrypt(env.type, env.body);\n await this.saveOlm(from.curve25519, sess, rec);\n return { from, plaintext, newSession: false };\n } catch {\n // not this session\n } finally {\n sess.free();\n }\n }\n if (env.type !== 0) throw new Error('no session for this message');\n const acct = this.account();\n try {\n const inbound = acct.create_inbound_session(from.curve25519, env.type, env.body);\n const plaintext = inbound.plaintext;\n const sess = inbound.take_session();\n await this.saveDevice(acct); // its one-time key is spent\n await this.saveOlm(from.curve25519, sess, rec);\n sess.free();\n return { from, plaintext, newSession: true };\n } finally {\n acct.free();\n }\n }\n\n private async roomKey(k: RoomKey, me: Party, from: Party): Promise<number> {\n const problem = roomKeyProblem(k, me, from);\n if (problem) throw new Error(problem);\n const ib = new this.w.InboundGroupSession(k.sessionKey);\n try {\n if (ib.session_id !== k.sessionId) throw new Error('session id mismatch');\n return await this.keep(ib, k.conversationId, from.userId, from.deviceId);\n } finally {\n ib.free();\n }\n }\n\n /** Stores an inbound session unless we hold one that opens as much or more. */\n private async keep(ib: YanE2ee.InboundGroupSession, conversationId: string, senderUserId: string, senderDeviceId: string): Promise<number> {\n const id = ib.session_id;\n const existing = await this.store.get(`in:${id}`);\n if (existing) {\n const e = JSON.parse(existing) as InboundRecord;\n if (e.senderUserId !== senderUserId || e.senderDeviceId !== senderDeviceId || e.conversationId !== conversationId) throw new Error('session claimed by another sender');\n if (e.firstIndex <= ib.first_known_index) return 0;\n }\n const r: InboundRecord = { pickle: ib.pickle(this.key), conversationId, senderUserId, senderDeviceId, firstIndex: ib.first_known_index };\n await this.store.set(`in:${id}`, JSON.stringify(r));\n return 1;\n }\n\n // ---- history for a new device of yours ----\n\n private async sendOlm(to: DeviceKeys[], payload: (d: DeviceKeys) => object): Promise<string[]> {\n const sessions = await this.olmTo(to);\n const messages: ToDeviceOut[] = [];\n const sent: string[] = [];\n for (const d of to) {\n const s = sessions.get(d.curve25519);\n if (!s) continue;\n const sealed = s.encrypt(JSON.stringify(payload(d)));\n await this.saveOlm(d.curve25519, s);\n s.free();\n messages.push({ userId: d.userId, deviceId: d.deviceId, type: OLM, body: JSON.stringify({ v: 1, type: sealed.message_type, body: sealed.body }) });\n sent.push(d.deviceId);\n }\n for (let i = 0; i < messages.length; i += 200) await this.api.sendToDevice(this.dev.deviceId, messages.slice(i, i + 200));\n return sent;\n }\n\n private party(d: DeviceKeys): Party {\n return { userId: d.userId, deviceId: d.deviceId, ed25519: d.ed25519 };\n }\n\n /**\n * Asks your other devices for the keys to messages sent before this one was set up. Each that answers agrees a code\n * with this device; you allow it there after checking the codes match. Answers false when there's nobody to ask.\n */\n requestHistory(): Promise<boolean> {\n return this.lock(async () => {\n this.forgetDevices(this.userId);\n const mine = (await this.devicesOf(this.userId)).filter((d) => d.deviceId !== this.dev.deviceId);\n if (!mine.length) {\n await this.store.set('history:out', JSON.stringify({ requestId: '', nonce: '', startedAt: new Date().toISOString(), asked: [], codes: {}, received: 0 } satisfies OutgoingHistory));\n return false;\n }\n const req: OutgoingHistory = { requestId: 'h_' + randomB64(12), nonce: randomB64(16), startedAt: new Date().toISOString(), asked: [], codes: {}, received: 0 };\n const me: Party = { userId: this.userId, deviceId: this.dev.deviceId, ed25519: this.ed };\n req.asked = await this.sendOlm(mine, () => ({ t: 'yan.history_request', requestId: req.requestId, commitment: this.w.sha256_base64(req.nonce), requester: me }));\n await this.store.set('history:out', JSON.stringify(req));\n return req.asked.length > 0;\n });\n }\n\n /** Where this device's request for history stands. */\n historyStatus(): Promise<HistoryStatus> {\n return this.lock(async () => {\n const raw = await this.store.get('history:out');\n if (!raw) return { state: 'none', codes: [], received: 0 };\n const r = JSON.parse(raw) as OutgoingHistory;\n if (!r.requestId) return { state: 'alone', codes: [], received: 0 };\n const names = new Map((await this.devicesOf(this.userId)).map((d) => [d.deviceId, d.name || 'Another device']));\n return {\n state: r.done ? 'received' : 'asked',\n codes: Object.entries(r.codes).map(([deviceId, code]) => ({ deviceId, deviceName: names.get(deviceId) ?? 'Another device', code })),\n received: r.received,\n };\n });\n }\n\n /** New devices of yours waiting for you to allow them here, each with the code it should be showing. */\n pendingApprovals(): Promise<HistoryApproval[]> {\n return this.lock(async () => {\n const out: HistoryApproval[] = [];\n const devices = await this.devicesOf(this.userId);\n for (const k of await this.store.keys('history:in:')) {\n const r = JSON.parse((await this.store.get(k))!) as IncomingHistory;\n if (r.state !== 'ready' || !r.code) continue;\n const d = devices.find((x) => x.deviceId === r.requester.deviceId && x.ed25519 === r.requester.ed25519);\n if (!d) continue; // signed out since\n out.push({ requestId: r.requestId, deviceId: d.deviceId, deviceName: d.name || 'A new device', code: r.code, createdAt: r.createdAt });\n }\n return out;\n });\n }\n\n /** You checked the codes match: send that device every session key this one holds. Answers how many. */\n approveHistory(requestId: string): Promise<number> {\n return this.lock(async () => {\n const key = `history:in:${requestId}`;\n const raw = await this.store.get(key);\n if (!raw) throw new Error('no such request');\n const r = JSON.parse(raw) as IncomingHistory;\n if (r.state !== 'ready') throw new Error('this request is not waiting');\n const d = (await this.devicesOf(this.userId)).find((x) => x.deviceId === r.requester.deviceId && x.ed25519 === r.requester.ed25519);\n if (!d) throw new Error('that device is gone');\n const keys: { conversationId: string; sessionId: string; senderUserId: string; senderDeviceId: string; exported: string }[] = [];\n for (const k of await this.store.keys('in:')) {\n const rec = JSON.parse((await this.store.get(k))!) as InboundRecord;\n const ib = this.w.InboundGroupSession.from_pickle(rec.pickle, this.key);\n keys.push({ conversationId: rec.conversationId, sessionId: ib.session_id, senderUserId: rec.senderUserId, senderDeviceId: rec.senderDeviceId, exported: ib.export() });\n ib.free();\n }\n const me: Party = { userId: this.userId, deviceId: this.dev.deviceId, ed25519: this.ed };\n // at least one message, so the new device hears back even when there's nothing to forward\n for (let i = 0; i === 0 || i < keys.length; i += KEYS_PER_MESSAGE) {\n await this.sendOlm([d], () => ({ t: 'yan.forwarded_room_keys', requestId, keys: keys.slice(i, i + KEYS_PER_MESSAGE), sender: me, recipient: this.party(d) }));\n }\n r.state = 'sent';\n await this.store.set(key, JSON.stringify(r));\n return keys.length;\n });\n }\n\n /** Not yours, or you don't want it to read your history: nothing is sent. */\n denyHistory(requestId: string): Promise<void> {\n return this.lock(async () => {\n const key = `history:in:${requestId}`;\n const raw = await this.store.get(key);\n if (!raw) return;\n await this.store.set(key, JSON.stringify({ ...(JSON.parse(raw) as IncomingHistory), state: 'denied' }));\n });\n }\n\n private async history(m: Record<string, unknown> & { t: string }, me: Party, sender: Party, from: DeviceKeys): Promise<number> {\n const requestId = typeof m['requestId'] === 'string' ? (m['requestId'] as string) : '';\n if (!/^h_[A-Za-z0-9+/]{16}$/.test(requestId)) throw new Error('bad request id');\n switch (m.t) {\n case 'yan.history_request': {\n // an existing device: a new one of yours asks; answer with our nonce, then wait for theirs\n if (!same(m['requester'] as Party, sender)) throw new Error('requester mismatch');\n const key = `history:in:${requestId}`;\n if (await this.store.get(key)) return 0;\n const r: IncomingHistory = { requestId, requester: sender, commitment: String(m['commitment'] ?? ''), nonce: randomB64(16), state: 'challenged', createdAt: new Date().toISOString() };\n await this.store.set(key, JSON.stringify(r));\n await this.sendOlm([from], () => ({ t: 'yan.history_challenge', requestId, nonce: r.nonce, approver: me, recipient: sender }));\n return 0;\n }\n case 'yan.history_challenge': {\n // the new device: an existing one answered; reveal our nonce, and show the code\n if (!same(m['approver'] as Party, sender) || !same(m['recipient'] as Party, me)) throw new Error('challenge mismatch');\n const raw = await this.store.get('history:out');\n const out = raw ? (JSON.parse(raw) as OutgoingHistory) : null;\n if (!out || out.requestId !== requestId || out.codes[sender.deviceId]) return 0;\n out.codes[sender.deviceId] = this.w.verification_code(verifyText(this.userId, me, sender, String(m['nonce']), out.nonce));\n await this.store.set('history:out', JSON.stringify(out));\n await this.sendOlm([from], () => ({ t: 'yan.history_reveal', requestId, nonce: out.nonce, requester: me, recipient: sender }));\n return 0;\n }\n case 'yan.history_reveal': {\n // an existing device: check the nonce against the commitment; the request now waits for you to allow it\n if (!same(m['requester'] as Party, sender) || !same(m['recipient'] as Party, me)) throw new Error('reveal mismatch');\n const key = `history:in:${requestId}`;\n const raw = await this.store.get(key);\n const r = raw ? (JSON.parse(raw) as IncomingHistory) : null;\n if (!r || r.state !== 'challenged' || !same(r.requester, sender)) return 0;\n const n2 = String(m['nonce'] ?? '');\n if (this.w.sha256_base64(n2) !== r.commitment) {\n r.state = 'denied';\n await this.store.set(key, JSON.stringify(r));\n throw new Error('the nonce does not match its commitment');\n }\n r.code = this.w.verification_code(verifyText(this.userId, sender, me, r.nonce, n2));\n r.state = 'ready';\n await this.store.set(key, JSON.stringify(r));\n return 0;\n }\n case 'yan.forwarded_room_keys': {\n // the new device: only from a device we agreed a code with, for our request\n if (!same(m['sender'] as Party, sender) || !same(m['recipient'] as Party, me)) throw new Error('forward mismatch');\n const raw = await this.store.get('history:out');\n const out = raw ? (JSON.parse(raw) as OutgoingHistory) : null;\n if (!out || out.requestId !== requestId || !out.codes[sender.deviceId]) throw new Error('keys nobody asked for');\n let added = 0;\n for (const k of (m['keys'] as { conversationId: string; sessionId: string; senderUserId: string; senderDeviceId: string; exported: string }[]) ?? []) {\n let ib: YanE2ee.InboundGroupSession | null = null;\n try {\n ib = this.w.InboundGroupSession.import(k.exported);\n if (ib.session_id !== k.sessionId) continue;\n added += await this.keep(ib, k.conversationId, k.senderUserId, k.senderDeviceId);\n } catch (e) {\n this.log(`forwarded key ${k.sessionId}: ${(e as Error).message}`);\n } finally {\n ib?.free();\n }\n }\n out.received += added;\n out.done = true;\n await this.store.set('history:out', JSON.stringify(out));\n return added;\n }\n }\n return 0;\n }\n\n /** Decrypts a message; when its key hasn't arrived, reads the inbox once and tries again. */\n decrypt(msg: SealedMessage): Promise<Opened> {\n return this.lock(async () => {\n let raw = await this.store.get(`in:${msg.sessionId}`);\n if (!raw) {\n await this.syncLocked();\n raw = await this.store.get(`in:${msg.sessionId}`);\n }\n if (!raw) return { ok: false, reason: 'missing-key' };\n const rec = JSON.parse(raw) as InboundRecord;\n if (msg.algorithm !== MEGOLM || rec.conversationId !== msg.conversationId || rec.senderUserId !== msg.senderId || rec.senderDeviceId !== msg.senderDeviceId) {\n return { ok: false, reason: 'invalid' };\n }\n const ib = this.w.InboundGroupSession.from_pickle(rec.pickle, this.key);\n try {\n const d = ib.decrypt(msg.ciphertext);\n const seen = this.seen.get(msg.sessionId) ?? new Map<number, string>();\n this.seen.set(msg.sessionId, seen);\n const prior = seen.get(d.message_index);\n if (prior && prior !== msg.id) return { ok: false, reason: 'invalid' };\n seen.set(d.message_index, msg.id);\n const p = JSON.parse(d.plaintext) as { v: number; conversationId: string; kind: string; text: string };\n if (p.v !== 1 || p.conversationId !== msg.conversationId || typeof p.text !== 'string') return { ok: false, reason: 'invalid' };\n return { ok: true, kind: p.kind || 'text', text: p.text };\n } catch {\n return { ok: false, reason: 'invalid' };\n } finally {\n ib.free();\n }\n });\n }\n}\n\nfunction randomB64(bytes: number): string {\n const b = new Uint8Array(bytes);\n crypto.getRandomValues(b);\n return btoa(String.fromCharCode(...b)).replace(/=+$/, '');\n}\n\n/** web_ + 16 random hex characters. */\nexport function randomDeviceId(): string {\n const b = new Uint8Array(8);\n crypto.getRandomValues(b);\n return 'web_' + [...b].map((x) => x.toString(16).padStart(2, '0')).join('');\n}\n","import type { E2eeStore, Lock } from './e2ee';\n\n// The browser side of the encryption's storage: one IndexedDB database, keys prefixed by the person's id (several\n// people can use one browser). Every pickle is already encrypted by vodozemac with a 32-byte pickle key; that key is\n// stored wrapped by a non-extractable AES-GCM key, so its bytes never sit in storage in the clear.\n\nconst DB = 'yan-e2ee';\nconst KV = 'kv';\nconst KEYS = 'keys';\n\nlet dbp: Promise<IDBDatabase> | null = null;\n\nfunction db(): Promise<IDBDatabase> {\n dbp ??= new Promise((resolve, reject) => {\n const r = indexedDB.open(DB, 1);\n r.onupgradeneeded = () => {\n r.result.createObjectStore(KV);\n r.result.createObjectStore(KEYS);\n };\n r.onsuccess = () => resolve(r.result);\n r.onerror = () => reject(r.error);\n });\n dbp.catch(() => (dbp = null));\n return dbp;\n}\n\nfunction req<T>(store: string, mode: IDBTransactionMode, fn: (s: IDBObjectStore) => IDBRequest): Promise<T> {\n return db().then(\n (d) =>\n new Promise<T>((resolve, reject) => {\n const tx = d.transaction(store, mode);\n const r = fn(tx.objectStore(store));\n tx.oncomplete = () => resolve(r.result as T);\n tx.onerror = () => reject(tx.error);\n tx.onabort = () => reject(tx.error);\n }),\n );\n}\n\n/** One person's encryption storage. */\nexport function idbStore(userId: string): E2eeStore {\n const k = (key: string) => `${userId}/${key}`;\n return {\n get: (key) => req<string | undefined>(KV, 'readonly', (s) => s.get(k(key))),\n set: (key, value) => req<void>(KV, 'readwrite', (s) => s.put(value, k(key))),\n del: (key) => req<void>(KV, 'readwrite', (s) => s.delete(k(key))),\n keys: async (prefix) => {\n const all = await req<IDBValidKey[]>(KV, 'readonly', (s) => s.getAllKeys(IDBKeyRange.bound(k(prefix), k(prefix) + '\\uffff')));\n return all.map((x) => String(x).slice(userId.length + 1));\n },\n };\n}\n\ninterface WrappedKey {\n wrapper: CryptoKey;\n iv: Uint8Array;\n sealed: ArrayBuffer;\n}\n\n/** This person's pickle key on this browser, made on first use. */\nexport async function pickleKey(userId: string): Promise<Uint8Array> {\n const have = await req<WrappedKey | undefined>(KEYS, 'readonly', (s) => s.get(userId));\n if (have) return new Uint8Array(await crypto.subtle.decrypt({ name: 'AES-GCM', iv: have.iv as BufferSource }, have.wrapper, have.sealed));\n const raw = crypto.getRandomValues(new Uint8Array(32));\n const wrapper = await crypto.subtle.generateKey({ name: 'AES-GCM', length: 256 }, false, ['encrypt', 'decrypt']);\n const iv = crypto.getRandomValues(new Uint8Array(12));\n const sealed = await crypto.subtle.encrypt({ name: 'AES-GCM', iv }, wrapper, raw);\n await req<void>(KEYS, 'readwrite', (s) => s.put({ wrapper, iv, sealed } satisfies WrappedKey, userId));\n return raw;\n}\n\n/** Everything this browser holds for a person (signing out of messaging here). */\nexport async function forget(userId: string): Promise<void> {\n const d = await db();\n await new Promise<void>((resolve, reject) => {\n const tx = d.transaction([KV, KEYS], 'readwrite');\n tx.objectStore(KV).delete(IDBKeyRange.bound(`${userId}/`, `${userId}/￿`));\n tx.objectStore(KEYS).delete(userId);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n}\n\n/** One operation at a time across every tab of this person (a ratchet must never fork); in-tab only without Web Locks. */\nexport function tabLock(userId: string, fallback: Lock): Lock {\n const locks = (navigator as Navigator & { locks?: LockManager }).locks;\n if (!locks) return fallback;\n return <T>(fn: () => Promise<T>) => locks.request(`yan-e2ee:${userId}`, fn) as Promise<T>;\n}\n","// Pure display rules for Messages (prototype Messages screen, PRD DM-1–8). No Angular, so node tests run them.\n\nexport interface PersonLike {\n userId: string;\n username: string;\n displayName: string;\n}\n\nexport interface MemberLike {\n userId: string;\n state: string;\n lastReadMessageId?: string;\n}\n\nexport interface ConversationLike {\n kind: 'direct' | 'group';\n title?: string;\n members: MemberLike[];\n myState: string;\n}\n\n/** How a person is shown: display name, else @username, else \"Someone\". */\nexport function personName(p: PersonLike | undefined): string {\n if (!p) return 'Someone';\n return p.displayName || (p.username ? '@' + p.username : 'Someone');\n}\n\n/** The other people in a conversation who are still in it. */\nexport function others(c: ConversationLike, me: string): MemberLike[] {\n return c.members.filter((m) => m.userId !== me && (m.state === 'active' || m.state === 'request'));\n}\n\n/** A direct conversation is named after the other person; a group by its title, else its members. */\nexport function conversationName(c: ConversationLike, me: string, people: Record<string, PersonLike>): string {\n if (c.kind === 'group' && c.title) return c.title;\n const names = others(c, me).map((m) => personName(people[m.userId]));\n if (!names.length) return c.kind === 'group' ? 'Group' : 'Just you';\n if (c.kind === 'direct') return names[0];\n return names.length <= 3 ? names.join(', ') : `${names.slice(0, 2).join(', ')} and ${names.length - 2} others`;\n}\n\n/** The prototype's kind eyebrow. */\nexport function kindLabel(c: ConversationLike): string {\n return c.kind === 'group' ? 'Group' : 'Direct';\n}\n\n/** Every DM and group is end-to-end encrypted (the email and community rows, which aren't, come with P2). */\nexport const E2EE_LABEL = { cls: 'yan-security--e2ee', icon: 'shield-lock', text: 'End-to-end encrypted' } as const;\n\n/** The Requests row's second line. */\nexport function requestsLine(count: number, firstFrom: string | undefined): string {\n if (!count) return 'No requests';\n return `${count} waiting · ${firstFrom ?? 'Someone'}`;\n}\n\n/** Who will see your messages under Requests, until they accept (DM-3). */\nexport function pendingFor(c: ConversationLike, me: string, people: Record<string, PersonLike>): string | null {\n const waiting = c.members.filter((m) => m.userId !== me && m.state === 'request');\n if (!waiting.length) return null;\n if (c.kind === 'direct') return `${personName(people[waiting[0].userId])} isn't in your network yet. Your messages go to their Requests until they accept.`;\n return waiting.length === 1\n ? `${personName(people[waiting[0].userId])} hasn't accepted yet and sees this under Requests.`\n : `${waiting.length} people haven't accepted yet and see this under Requests.`;\n}\n\n/** Days left on a request (DM-3: 7), for \"Expires in 3 days\". */\nexport function expiresIn(until: string | undefined, now = Date.now()): string {\n if (!until) return '';\n const ms = new Date(until).getTime() - now;\n if (ms <= 0) return 'Expired';\n const h = Math.ceil(ms / 3_600_000);\n if (h < 24) return `Expires in ${h} hour${h === 1 ? '' : 's'}`;\n const d = Math.ceil(h / 24);\n return `Expires in ${d} day${d === 1 ? '' : 's'}`;\n}\n\n/**\n * \"Seen\" under your last message, when everyone else has read up to it or later. `order` is the thread's message\n * ids, oldest first.\n */\nexport function seen(c: ConversationLike, me: string, order: string[], lastMine: string | undefined): boolean {\n if (!lastMine) return false;\n const at = order.indexOf(lastMine);\n if (at < 0) return false;\n const rest = others(c, me).filter((m) => m.state === 'active');\n if (!rest.length) return false;\n return rest.every((m) => !!m.lastReadMessageId && order.indexOf(m.lastReadMessageId) >= at);\n}\n\n/** What a message that can't be shown says instead. */\nexport function unreadableText(reason: 'missing-key' | 'invalid'): string {\n return reason === 'missing-key' ? \"Can't be read on this device\" : \"Couldn't be verified, so it isn't shown\";\n}\n\n/** A preview line for the list: the text, else a word for the kind. */\nexport function previewText(kind: string, text: string): string {\n if (text) return text;\n const words: Record<string, string> = { image: 'Photo', video: 'Video', file: 'File', voice: 'Voice message', link: 'Link', reaction: 'Reaction' };\n return words[kind] ?? 'Message';\n}\n","import { InjectionToken } from '@angular/core';\n\n/** What the host app gives Messages: who is signed in, a fresh access token for the WebSocket, and where things are. */\nexport interface MessagesHost {\n /** current user id, or null for a guest */\n userId(): string | null;\n /** a usable access token (renewed when it's about to run out), or null when signed out */\n accessToken(): Promise<string | null>;\n /** send a guest to sign in, coming back to `next` */\n requestSignIn(next: string): void;\n /** the WebSocket address, e.g. wss://yansocial.com/ws */\n wsUrl(): string;\n /** this device's name as other devices list it, e.g. \"Chrome on Mac\" */\n deviceName(): string;\n}\n\nexport const MESSAGES_HOST = new InjectionToken<MessagesHost>('MESSAGES_HOST', {\n providedIn: 'root',\n factory: () => ({\n userId: () => null,\n accessToken: async () => null,\n requestSignIn: () => undefined,\n wsUrl: () => location.origin.replace(/^http/, 'ws') + '/ws',\n deviceName: () => 'Web',\n }),\n});\n\n/** Host-provided: base URL of the messaging API. */\nexport const MESSAGES_API_BASE = new InjectionToken<string>('MESSAGES_API_BASE', {\n providedIn: 'root',\n factory: () => '/api/apps/messaging',\n});\n\n/** Host-provided: base URL of the social API (names for people known only by id). */\nexport const MESSAGES_SOCIAL_BASE = new InjectionToken<string>('MESSAGES_SOCIAL_BASE', {\n providedIn: 'root',\n factory: () => '/api/apps/social',\n});\n\n/** Host-provided: where the encryption module (yan_e2ee_bg.wasm from @chisquare-tech/yan-e2ee) is served. */\nexport const MESSAGES_E2EE_WASM = new InjectionToken<string>('MESSAGES_E2EE_WASM', {\n providedIn: 'root',\n factory: () => '/e2ee/yan_e2ee_bg.wasm',\n});\n","import { HttpClient, HttpErrorResponse } from '@angular/common/http';\nimport { Injectable, inject } from '@angular/core';\nimport { firstValueFrom } from 'rxjs';\nimport type { ClaimedKey, DeviceKeys, E2eeTransport, KeyCount, SealedMessage, SignedKey, ToDeviceIn, ToDeviceOut } from './e2ee';\nimport { MESSAGES_API_BASE, MESSAGES_SOCIAL_BASE } from './tokens';\n\ninterface Envelope<T> {\n data: T;\n}\n\nexport interface Member {\n userId: string;\n role: 'owner' | 'admin' | 'member';\n state: 'active' | 'request' | 'declined' | 'left';\n lastReadMessageId?: string;\n lastReadAt?: string;\n}\n\nexport interface Conversation {\n id: string;\n kind: 'direct' | 'group';\n title?: string;\n epoch: number;\n members: Member[];\n myState: 'active' | 'request';\n myRole: string;\n unread: number;\n lastMessageId?: string;\n lastMessageAt?: string;\n requestUntil?: string;\n createdAt: string;\n}\n\nexport interface Message extends SealedMessage {\n clientMsgId: string;\n epoch: number;\n kind: string;\n replyToId?: string;\n createdAt: string;\n}\n\nexport interface Page<T> {\n items: T[];\n next?: string;\n}\n\nexport interface Person {\n userId: string;\n username: string;\n displayName: string;\n}\n\nexport interface SendBody {\n clientMsgId: string;\n senderDevice: string;\n algorithm: string;\n sessionId: string;\n kind: string;\n ciphertext: string;\n}\n\n/** yan-gox-apps/libs/messaging over HTTP: the conversation API, and the device-key API the encryption needs. */\n@Injectable({ providedIn: 'root' })\nexport class MessagingApi implements E2eeTransport {\n private readonly http = inject(HttpClient);\n private readonly base = inject(MESSAGES_API_BASE);\n private readonly social = inject(MESSAGES_SOCIAL_BASE);\n\n private async get<T>(path: string, params?: Record<string, string | number | undefined>): Promise<T> {\n const p: Record<string, string> = {};\n for (const [k, v] of Object.entries(params ?? {})) if (v !== undefined && v !== '') p[k] = String(v);\n return (await firstValueFrom(this.http.get<Envelope<T>>(this.base + path, { params: p }))).data;\n }\n\n private async send<T>(method: 'POST' | 'PUT' | 'DELETE', path: string, body?: unknown): Promise<T> {\n return (await firstValueFrom(this.http.request<Envelope<T>>(method, this.base + path, { body }))).data;\n }\n\n // ---- conversations ----\n\n conversations(box: 'inbox' | 'requests' = 'inbox'): Promise<Conversation[]> {\n return this.get('/conversations', { box: box === 'inbox' ? undefined : box });\n }\n\n conversation(id: string): Promise<Conversation> {\n return this.get(`/conversations/${encodeURIComponent(id)}`);\n }\n\n startDirect(userId: string): Promise<Conversation> {\n return this.send('POST', '/conversations', { kind: 'direct', userId });\n }\n\n accept(id: string): Promise<Conversation> {\n return this.send('POST', `/conversations/${encodeURIComponent(id)}/accept`, {});\n }\n\n decline(id: string): Promise<unknown> {\n return this.send('POST', `/conversations/${encodeURIComponent(id)}/decline`, {});\n }\n\n messages(id: string, before?: string, limit = 50): Promise<Page<Message>> {\n return this.get(`/conversations/${encodeURIComponent(id)}/messages`, { before, limit });\n }\n\n sendMessage(id: string, body: SendBody): Promise<Message> {\n return this.send('POST', `/conversations/${encodeURIComponent(id)}/messages`, body);\n }\n\n markRead(id: string, messageId: string): Promise<unknown> {\n return this.send('PUT', `/conversations/${encodeURIComponent(id)}/read`, { messageId });\n }\n\n typing(id: string): Promise<unknown> {\n return this.send('POST', `/conversations/${encodeURIComponent(id)}/typing`, {});\n }\n\n /** Names for people known only by id; an empty list asks nothing. */\n async people(ids: string[]): Promise<Person[]> {\n const unique = [...new Set(ids)].slice(0, 100);\n if (!unique.length) return [];\n return (await firstValueFrom(this.http.get<Envelope<Person[]>>(`${this.social}/people`, { params: { ids: unique.join(',') } }))).data;\n }\n\n // ---- E2eeTransport ----\n\n async registerDevice(deviceId: string, body: { curve25519: string; ed25519: string; signature: string; name: string }): Promise<boolean> {\n try {\n await this.send('PUT', `/devices/${encodeURIComponent(deviceId)}`, body);\n return true;\n } catch (e) {\n if (e instanceof HttpErrorResponse && e.status === 409) return false;\n throw e;\n }\n }\n\n uploadKeys(deviceId: string, body: { oneTimeKeys: SignedKey[]; fallbackKey?: SignedKey }): Promise<KeyCount> {\n return this.send('POST', `/devices/${encodeURIComponent(deviceId)}/keys`, body);\n }\n\n /** Signs this device out of messaging: its keys and inbox go from the server. */\n async revokeDevice(deviceId: string): Promise<void> {\n await this.send('DELETE', `/devices/${encodeURIComponent(deviceId)}`);\n }\n\n async keyCount(deviceId: string): Promise<KeyCount | null> {\n try {\n return await this.get<KeyCount>(`/devices/${encodeURIComponent(deviceId)}/keys/count`);\n } catch (e) {\n if (e instanceof HttpErrorResponse && e.status === 404) return null;\n throw e;\n }\n }\n\n devices(userId: string): Promise<DeviceKeys[]> {\n return this.get(`/users/${encodeURIComponent(userId)}/devices`);\n }\n\n claim(devices: { userId: string; deviceId: string }[]): Promise<ClaimedKey[]> {\n return this.send('POST', '/keys/claim', { devices });\n }\n\n async sendToDevice(senderDevice: string, messages: ToDeviceOut[]): Promise<number> {\n return (await this.send<{ sent: number }>('POST', '/to-device', { senderDevice, messages })).sent;\n }\n\n inbox(deviceId: string, after: number): Promise<ToDeviceIn[]> {\n return this.get(`/devices/${encodeURIComponent(deviceId)}/inbox`, { after, limit: 100 });\n }\n\n async ackInbox(deviceId: string, upTo: number): Promise<void> {\n await this.send('POST', `/devices/${encodeURIComponent(deviceId)}/inbox/ack`, { upTo });\n }\n}\n\n/** A server error's message for people, or a fallback. */\nexport function errorText(e: unknown, fallback: string): string {\n const m = (e as { error?: { message?: string } })?.error?.message;\n return m && m.length < 200 ? m : fallback;\n}\n\n/** An error's code from the server (e.g. cant_message), if any. */\nexport function errorCode(e: unknown): string | undefined {\n return (e as { error?: { code?: string } })?.error?.code;\n}\n","import { Injectable, NgZone, WritableSignal, computed, inject, signal } from '@angular/core';\nimport { DmSocket, type DmEvent } from './dm-socket';\nimport { E2eeMachine, localLock, type ConversationKeys, type HistoryApproval, type HistoryStatus, type Opened } from './e2ee';\nimport { forget, idbStore, pickleKey, tabLock } from './idb-store';\nimport { previewText, unreadableText } from './labels';\nimport { MessagingApi, errorCode, errorText, type Conversation, type Message, type Person, type SendBody } from './messaging-api';\nimport { MESSAGES_E2EE_WASM, MESSAGES_HOST } from './tokens';\n\nexport type BubbleState = 'ok' | 'pending' | 'failed' | 'unreadable';\n\nexport interface Bubble {\n /** the server's id; a pending message has its clientMsgId here until it's sent */\n id: string;\n clientMsgId?: string;\n senderId: string;\n mine: boolean;\n kind: string;\n text: string;\n state: BubbleState;\n /** why an unreadable message can't be shown */\n unreadable?: 'missing-key' | 'invalid';\n /** why a message failed to send, for the retry line */\n error?: string;\n createdAt: string;\n sealed?: Message;\n /** a send that failed after encryption keeps its ciphertext, so the retry is the same message */\n outgoing?: { kind: string; text: string; body?: SendBody };\n}\n\nexport interface Thread {\n conv: Conversation | null;\n items: Bubble[];\n next?: string;\n loading: boolean;\n failed: boolean;\n missing: boolean;\n}\n\nexport type CryptoState = 'idle' | 'starting' | 'ready' | 'failed';\n\nconst PREVIEW_LIMIT = 30;\n\n/**\n * Messages for the signed-in person: the lists, each open thread (decrypted on this device), sending, Requests, and\n * live updates over the dm WebSocket channel. The server only ever sees ciphertext.\n */\n@Injectable({ providedIn: 'root' })\nexport class MessagesStore {\n private readonly api = inject(MessagingApi);\n private readonly host = inject(MESSAGES_HOST);\n private readonly wasmUrl = inject(MESSAGES_E2EE_WASM);\n private readonly zone = inject(NgZone);\n\n readonly inbox = signal<Conversation[]>([]);\n readonly requests = signal<Conversation[]>([]);\n readonly loaded = signal(false);\n readonly failed = signal(false);\n readonly people = signal<Record<string, Person>>({});\n readonly previews = signal<Record<string, string>>({});\n /** conversation id → who is typing there */\n readonly typing = signal<Record<string, string>>({});\n readonly crypto = signal<CryptoState>('idle');\n /** New devices of yours asking, here, for your message history. */\n readonly approvals = signal<HistoryApproval[]>([]);\n /** This device's request for history (when it can't read older messages). */\n readonly history = signal<HistoryStatus>({ state: 'none', codes: [], received: 0 });\n /** For the nav badge: unread conversations, waiting requests, and devices asking for your history. */\n readonly badge = computed(() => this.inbox().reduce((n, c) => n + (c.unread > 0 ? 1 : 0), 0) + this.requests().length + this.approvals().length);\n\n private readonly threads = new Map<string, WritableSignal<Thread>>();\n private machine: Promise<E2eeMachine> | null = null;\n private machineUser: string | null = null;\n private socket: DmSocket | null = null;\n private refreshTimer: ReturnType<typeof setTimeout> | null = null;\n private readonly typingTimers = new Map<string, ReturnType<typeof setTimeout>>();\n private lastTypingSent = new Map<string, number>();\n\n me(): string | null {\n return this.host.userId();\n }\n\n // ---- lifecycle ----\n\n /** Loads the lists (enough for the nav badge). */\n async loadLists(): Promise<void> {\n if (!this.me()) return;\n try {\n const [inbox, requests] = await Promise.all([this.api.conversations('inbox'), this.api.conversations('requests')]);\n this.inbox.set(inbox);\n this.requests.set(requests);\n this.failed.set(false);\n this.loaded.set(true);\n await this.loadPeople([...inbox, ...requests].flatMap((c) => c.members.map((m) => m.userId)));\n void this.loadPreviews([...requests, ...inbox]);\n } catch {\n this.failed.set(true);\n }\n }\n\n /** Everything Messages needs: the lists, this device's encryption, and live updates. */\n async start(): Promise<void> {\n const me = this.me();\n if (!me) return;\n if (this.machineUser && this.machineUser !== me) this.stop();\n void this.loadLists();\n void this.ensureMachine().then(\n async (m) => {\n this.openSocket();\n // what arrived while this device was away (room keys, history requests)\n await m.sync().catch(() => 0);\n await this.refreshHistory();\n },\n () => undefined,\n );\n }\n\n /**\n * Signing out on purpose: this device leaves messaging (the server drops its keys and inbox) and the browser forgets\n * its keys, so nobody using it next can read your messages. Signing in again makes a new device, which reads older\n * messages once you allow it from another device.\n */\n async signOutDevice(): Promise<void> {\n const me = this.me();\n if (!me) return;\n this.stop();\n try {\n const raw = await idbStore(me).get('device');\n const id = raw ? (JSON.parse(raw) as { deviceId?: string }).deviceId : undefined;\n if (id) await this.api.revokeDevice(id).catch(() => undefined);\n await forget(me);\n } catch {\n // storage unavailable: nothing was kept here\n }\n }\n\n /** Signing out, or another person signing in. */\n stop(): void {\n this.socket?.stop();\n this.socket = null;\n this.machine = null;\n this.machineUser = null;\n this.crypto.set('idle');\n this.threads.clear();\n this.inbox.set([]);\n this.requests.set([]);\n this.previews.set({});\n this.approvals.set([]);\n this.history.set({ state: 'none', codes: [], received: 0 });\n this.loaded.set(false);\n }\n\n /** This device's encryption: loads the wasm module, then opens (or makes and publishes) the device's keys. */\n ensureMachine(): Promise<E2eeMachine> {\n const me = this.me();\n if (!me) return Promise.reject(new Error('signed out'));\n if (this.machine && this.machineUser === me) return this.machine;\n this.machineUser = me;\n this.crypto.set('starting');\n this.machine = (async () => {\n const wasm = await import('@chisquare-tech/yan-e2ee');\n await wasm.default({ module_or_path: this.wasmUrl });\n return E2eeMachine.open({\n wasm,\n transport: this.api,\n store: idbStore(me),\n pickleKey: await pickleKey(me),\n userId: me,\n deviceName: this.host.deviceName(),\n lock: tabLock(me, localLock()),\n log: (m) => console.debug('[yan-e2ee]', m),\n });\n })();\n this.machine.then(\n () => this.crypto.set('ready'),\n (e) => {\n console.warn('[yan-e2ee] could not start', e);\n this.machine = null;\n this.crypto.set('failed');\n },\n );\n return this.machine;\n }\n\n retryCrypto(): void {\n void this.start();\n }\n\n private openSocket(): void {\n if (this.socket) return;\n const machine = this.machine;\n if (!machine) return;\n let device = '';\n void machine.then((m) => (device = m.deviceId));\n this.zone.runOutsideAngular(() => {\n this.socket = new DmSocket({\n url: () => this.host.wsUrl(),\n token: () => this.host.accessToken(),\n device: () => device,\n onEvent: (e) => this.zone.run(() => void this.onEvent(e)),\n onResync: () => this.zone.run(() => void this.resync()),\n });\n this.socket.start();\n });\n }\n\n // ---- people and previews ----\n\n private async loadPeople(ids: string[]): Promise<void> {\n const have = this.people();\n const missing = [...new Set(ids)].filter((id) => !have[id]);\n if (!missing.length) return;\n try {\n const got = await this.api.people(missing);\n this.people.update((p) => ({ ...p, ...Object.fromEntries(got.map((x) => [x.userId, x])) }));\n } catch {\n // names fall back to \"Someone\"\n }\n }\n\n private async loadPreviews(convs: Conversation[]): Promise<void> {\n let machine: E2eeMachine;\n try {\n machine = await this.ensureMachine();\n } catch {\n return;\n }\n const want = convs.filter((c) => c.lastMessageId && this.previews()[c.id + '|' + c.lastMessageId] === undefined).slice(0, PREVIEW_LIMIT);\n await Promise.all(\n want.map(async (c) => {\n try {\n const page = await this.api.messages(c.id, undefined, 1);\n const m = page.items[0];\n if (!m) return;\n const o = await machine.decrypt(m);\n const line = o.ok ? previewText(o.kind, o.text) : 'Encrypted message';\n const mine = m.senderId === this.me();\n this.previews.update((p) => ({ ...p, [c.id + '|' + c.lastMessageId]: (mine ? 'You: ' : '') + line }));\n } catch {\n // no preview\n }\n }),\n );\n }\n\n preview(c: Conversation): string {\n if (!c.lastMessageId) return 'No messages yet';\n return this.previews()[c.id + '|' + c.lastMessageId] ?? '';\n }\n\n // ---- threads ----\n\n thread(id: string): WritableSignal<Thread> {\n let t = this.threads.get(id);\n if (!t) {\n t = signal<Thread>({ conv: this.known(id), items: [], loading: true, failed: false, missing: false });\n this.threads.set(id, t);\n }\n return t;\n }\n\n private known(id: string): Conversation | null {\n return this.inbox().find((c) => c.id === id) ?? this.requests().find((c) => c.id === id) ?? null;\n }\n\n /** Loads a conversation and its newest messages, decrypted. */\n async openThread(id: string): Promise<void> {\n const t = this.thread(id);\n t.update((s) => ({ ...s, loading: true, failed: false }));\n try {\n const [conv, page] = await Promise.all([this.api.conversation(id), this.api.messages(id)]);\n void this.loadPeople(conv.members.map((m) => m.userId));\n const items = await this.open(page.items.slice().reverse());\n t.set({ conv, items: this.keepPending(t().items, items), next: page.next, loading: false, failed: false, missing: false });\n this.markRead(conv, items);\n if (items.some((b) => b.unreadable === 'missing-key')) void this.askForHistory();\n } catch (e) {\n const status = (e as { status?: number }).status;\n t.update((s) => ({ ...s, loading: false, failed: status !== 404, missing: status === 404 }));\n }\n }\n\n async loadOlder(id: string): Promise<void> {\n const t = this.thread(id);\n const s = t();\n if (!s.next || s.loading) return;\n t.update((x) => ({ ...x, loading: true }));\n try {\n const page = await this.api.messages(id, s.next);\n const older = await this.open(page.items.slice().reverse());\n t.update((x) => ({ ...x, items: [...older, ...x.items], next: page.next, loading: false }));\n } catch {\n t.update((x) => ({ ...x, loading: false }));\n }\n }\n\n /** Pending sends survive a reload of the thread. */\n private keepPending(before: Bubble[], now: Bubble[]): Bubble[] {\n const sent = new Set(now.map((b) => b.sealed?.clientMsgId));\n return [...now, ...before.filter((b) => (b.state === 'pending' || b.state === 'failed') && !sent.has(b.clientMsgId))];\n }\n\n private async open(msgs: Message[]): Promise<Bubble[]> {\n let machine: E2eeMachine | null = null;\n try {\n machine = await this.ensureMachine();\n } catch {\n // shown as unreadable until encryption starts\n }\n const me = this.me();\n const out: Bubble[] = [];\n for (const m of msgs) {\n const o: Opened = machine ? await machine.decrypt(m) : { ok: false, reason: 'missing-key' };\n out.push({\n id: m.id,\n senderId: m.senderId,\n mine: m.senderId === me,\n kind: o.ok ? o.kind : m.kind,\n text: o.ok ? o.text : unreadableText(o.reason),\n state: o.ok ? 'ok' : 'unreadable',\n unreadable: o.ok ? undefined : o.reason,\n createdAt: m.createdAt,\n sealed: m,\n });\n }\n return out;\n }\n\n private markRead(conv: Conversation, items: Bubble[]): void {\n const last = [...items].reverse().find((b) => b.state !== 'pending' && b.state !== 'failed');\n if (!last || conv.myState !== 'active') return;\n const mine = conv.members.find((m) => m.userId === this.me());\n if (mine?.lastReadMessageId === last.id && !conv.unread) return;\n void this.api.markRead(conv.id, last.id).then(() => {\n this.inbox.update((l) => l.map((c) => (c.id === conv.id ? { ...c, unread: 0 } : c)));\n }, () => undefined);\n }\n\n // ---- sending ----\n\n async send(id: string, text: string): Promise<void> {\n const body = text.trim();\n if (!body) return;\n const t = this.thread(id);\n const conv = t().conv;\n if (!conv) return;\n const clientMsgId = 'c_' + randomHex(12);\n const bubble: Bubble = { id: clientMsgId, clientMsgId, senderId: this.me() ?? '', mine: true, kind: 'text', text: body, state: 'pending', createdAt: new Date().toISOString(), outgoing: { kind: 'text', text: body } };\n t.update((s) => ({ ...s, items: [...s.items, bubble] }));\n await this.deliver(id, bubble);\n }\n\n retry(id: string, b: Bubble): Promise<void> {\n this.thread(id).update((s) => ({ ...s, items: s.items.map((x) => (x.clientMsgId === b.clientMsgId ? { ...x, state: 'pending' as const, error: undefined } : x)) }));\n return this.deliver(id, b);\n }\n\n private async deliver(id: string, b: Bubble): Promise<void> {\n const t = this.thread(id);\n const patch = (p: Partial<Bubble>) => t.update((s) => ({ ...s, items: s.items.map((x) => (x.clientMsgId === b.clientMsgId ? { ...x, ...p } : x)) }));\n let body = b.outgoing?.body;\n try {\n if (!body) {\n // fresh members and epoch: someone added a moment ago must get this session's key\n const conv = await this.api.conversation(id);\n t.update((s) => ({ ...s, conv }));\n const machine = await this.ensureMachine();\n const enc = await machine.encrypt(keysOf(conv), { kind: b.outgoing?.kind ?? 'text', text: b.outgoing?.text ?? b.text });\n body = { clientMsgId: b.clientMsgId!, kind: b.outgoing?.kind ?? 'text', ...enc };\n patch({ outgoing: { ...b.outgoing!, body } });\n }\n const sent = await this.api.sendMessage(id, body);\n // the push for it may have arrived first\n t.update((s) => {\n const already = s.items.some((x) => x.id === sent.id && x.clientMsgId !== b.clientMsgId);\n const items = already\n ? s.items.filter((x) => x.clientMsgId !== b.clientMsgId)\n : s.items.map((x) => (x.clientMsgId === b.clientMsgId ? { ...x, id: sent.id, state: 'ok' as const, sealed: sent, createdAt: sent.createdAt, outgoing: undefined } : x));\n return { ...s, items };\n });\n this.bump(id, sent.id, 'You: ' + previewText(body.kind, b.outgoing?.text ?? b.text));\n } catch (e) {\n const code = errorCode(e);\n patch({ state: 'failed', error: code === 'cant_message' ? \"You can't message this person.\" : this.crypto() === 'failed' ? \"Messages can't be encrypted in this browser.\" : errorText(e, 'Not sent.') });\n }\n }\n\n private bump(id: string, messageId: string, line: string): void {\n const now = new Date().toISOString();\n this.previews.update((p) => ({ ...p, [id + '|' + messageId]: line }));\n this.inbox.update((l) => {\n const c = l.find((x) => x.id === id);\n if (!c) return l;\n return [{ ...c, lastMessageId: messageId, lastMessageAt: now }, ...l.filter((x) => x.id !== id)];\n });\n }\n\n /** Starts (or finds) the direct conversation with someone. */\n async startDirect(userId: string): Promise<Conversation> {\n const c = await this.api.startDirect(userId);\n if (!this.inbox().some((x) => x.id === c.id)) this.inbox.update((l) => [c, ...l]);\n this.thread(c.id).update((s) => ({ ...s, conv: c }));\n void this.loadPeople(c.members.map((m) => m.userId));\n return c;\n }\n\n // ---- requests ----\n\n async accept(id: string): Promise<void> {\n const c = await this.api.accept(id);\n this.requests.update((l) => l.filter((x) => x.id !== id));\n this.inbox.update((l) => [c, ...l.filter((x) => x.id !== id)]);\n this.thread(id).update((s) => ({ ...s, conv: c }));\n }\n\n async decline(id: string): Promise<void> {\n await this.api.decline(id);\n this.requests.update((l) => l.filter((x) => x.id !== id));\n this.threads.delete(id);\n }\n\n // ---- history for a new device ----\n\n /** Asks your other devices for older messages' keys, once per page load unless you ask again. */\n async askForHistory(again = false): Promise<void> {\n const m = await this.machine?.catch(() => null);\n if (!m) return;\n const st = await m.historyStatus();\n if (!again && st.state !== 'none') return void this.history.set(st);\n await m.requestHistory().catch(() => false);\n await this.refreshHistory();\n }\n\n async approve(requestId: string): Promise<void> {\n const m = await this.ensureMachine();\n await m.approveHistory(requestId);\n await this.refreshHistory();\n }\n\n async deny(requestId: string): Promise<void> {\n const m = await this.ensureMachine();\n await m.denyHistory(requestId);\n await this.refreshHistory();\n }\n\n private async refreshHistory(): Promise<void> {\n const m = await this.machine?.catch(() => null);\n if (!m) return;\n this.approvals.set(await m.pendingApprovals().catch(() => []));\n this.history.set(await m.historyStatus().catch(() => this.history()));\n }\n\n // ---- typing ----\n\n typed(id: string): void {\n const now = Date.now();\n if (now - (this.lastTypingSent.get(id) ?? 0) < 4000) return;\n this.lastTypingSent.set(id, now);\n void this.api.typing(id).catch(() => undefined);\n }\n\n // ---- live ----\n\n private async onEvent(e: DmEvent): Promise<void> {\n const conv = typeof e.d?.['conversationId'] === 'string' ? (e.d['conversationId'] as string) : undefined;\n switch (e.t) {\n case 'message':\n if (conv) {\n // their message is here: they've stopped typing\n this.typing.update((t) => { const { [conv]: _, ...rest } = t; return rest; });\n await this.newer(conv);\n }\n this.refreshSoon();\n break;\n case 'to-device':\n await this.keysArrived();\n break;\n case 'membership':\n (await this.machine)?.forgetDevices();\n if (conv) await this.reloadConversation(conv);\n this.refreshSoon();\n break;\n case 'receipt':\n if (conv && e.d?.['userId'] !== this.me()) await this.reloadConversation(conv);\n break;\n case 'typing': {\n const who = e.d?.['userId'];\n if (!conv || typeof who !== 'string' || who === this.me()) break;\n this.typing.update((t) => ({ ...t, [conv]: who }));\n clearTimeout(this.typingTimers.get(conv));\n this.typingTimers.set(conv, setTimeout(() => this.typing.update((t) => { const { [conv]: _, ...rest } = t; return rest; }), 5000));\n break;\n }\n }\n }\n\n /** New messages in a loaded thread. */\n private async newer(id: string): Promise<void> {\n const t = this.threads.get(id);\n if (!t || t().loading && !t().items.length) return;\n try {\n const page = await this.api.messages(id, undefined, 20);\n const have = new Set(t().items.map((b) => b.id));\n const fresh = await this.open(page.items.filter((m) => !have.has(m.id)).reverse());\n if (!fresh.length) return;\n t.update((s) => {\n const byClient = new Map(fresh.filter((f) => f.mine).map((f) => [f.sealed?.clientMsgId, f]));\n const items = s.items.filter((b) => !(b.clientMsgId && byClient.has(b.clientMsgId)));\n const insertAt = items.findIndex((b) => b.state === 'pending' || b.state === 'failed');\n if (insertAt < 0) return { ...s, items: [...items, ...fresh] };\n return { ...s, items: [...items.slice(0, insertAt), ...fresh, ...items.slice(insertAt)] };\n });\n const c = t().conv;\n if (c) this.markRead(c, t().items);\n } catch {\n // the next event or a reload catches up\n }\n }\n\n /** Room keys arrived: messages that couldn't be read may open now. */\n private async keysArrived(): Promise<void> {\n const m = await this.machine?.catch(() => null);\n if (!m) return;\n await m.sync().catch(() => 0);\n await this.refreshHistory();\n for (const t of this.threads.values()) {\n if (!t().items.some((b) => b.state === 'unreadable')) continue;\n const items = await Promise.all(\n t().items.map(async (b) => {\n if (b.state !== 'unreadable' || !b.sealed) return b;\n const o = await m.decrypt(b.sealed);\n return o.ok ? { ...b, state: 'ok' as const, unreadable: undefined, kind: o.kind, text: o.text } : b;\n }),\n );\n t.update((s) => ({ ...s, items }));\n }\n void this.loadPreviews([...this.requests(), ...this.inbox()]);\n }\n\n private async reloadConversation(id: string): Promise<void> {\n const t = this.threads.get(id);\n if (!t) return;\n try {\n const conv = await this.api.conversation(id);\n t.update((s) => ({ ...s, conv }));\n } catch {\n // keep what we have\n }\n }\n\n private async resync(): Promise<void> {\n await this.loadLists();\n await this.keysArrived();\n for (const id of this.threads.keys()) await this.newer(id);\n }\n\n private refreshSoon(): void {\n if (this.refreshTimer) return;\n this.refreshTimer = setTimeout(() => {\n this.refreshTimer = null;\n void this.loadLists();\n }, 400);\n }\n}\n\n/** What the encryption needs to know about a conversation. */\nexport function keysOf(c: Conversation): ConversationKeys {\n return { id: c.id, epoch: c.epoch, members: c.members.map((m) => ({ userId: m.userId, state: m.state })) };\n}\n\nfunction randomHex(n: number): string {\n const b = new Uint8Array(Math.ceil(n / 2));\n crypto.getRandomValues(b);\n return [...b].map((x) => x.toString(16).padStart(2, '0')).join('').slice(0, n);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -2,7 +2,7 @@ import * as i0 from '@angular/core';
2
2
  import { inject, viewChild, signal, computed, effect, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
3
3
  import { Router, ActivatedRoute } from '@angular/router';
4
4
  import { ToastService, hueOf, initials, timeAgo } from '@chisquare-tech/yan-ngx-ui';
5
- import { M as MessagesStore, a as MESSAGES_HOST, E as E2EE_LABEL, r as requestsLine, s as seen, p as pendingFor, b as personName, c as conversationName, k as kindLabel, o as others, e as expiresIn, d as errorText } from './chisquare-tech-yan-ngx-apps-messages-chisquare-tech-yan-ngx-apps-messages-BYCxC81Q.mjs';
5
+ import { M as MessagesStore, a as MESSAGES_HOST, E as E2EE_LABEL, r as requestsLine, s as seen, p as pendingFor, b as personName, c as conversationName, k as kindLabel, o as others, e as expiresIn, d as errorText } from './chisquare-tech-yan-ngx-apps-messages-chisquare-tech-yan-ngx-apps-messages-BBsDA0CG.mjs';
6
6
 
7
7
  /** The prototype's Messages layout (prototype.css .msg-list, .pane, .thread-head, .composer) on yan-design. */
8
8
  const MESSAGES_STYLES = `
@@ -39,7 +39,9 @@ const MESSAGES_STYLES = `
39
39
  .yan-msgs__placeholder { margin: auto; max-width: 360px; padding: 24px; }
40
40
  .yan-msgs__older { align-self: center; }
41
41
  .yan-msgs__start { align-self: center; text-align: center; max-width: 360px; }
42
- .yan-msgs__lost { align-self: center; text-align: center; max-width: 420px; }
42
+ .yan-msgs__lost { align-self: stretch; display: flex; flex-direction: column; gap: 8px; align-items: flex-start; font: var(--yan-text-body-sm); }
43
+ .yan-msgs__approve { margin: 0 16px 12px; display: flex; flex-direction: column; gap: 8px; font: var(--yan-text-body-sm); }
44
+ .yan-msgs__code { font-family: var(--yan-font-mono, ui-monospace, monospace); font-size: 22px; letter-spacing: 0.08em; font-weight: 600; }
43
45
  .yan-msgs__from { font: var(--yan-text-micro); color: var(--yan-color-ink-muted); margin: 4px 0 -6px 4px; }
44
46
  .yan-msgs__unreadable { font-style: italic; color: var(--yan-color-ink-muted); }
45
47
  .yan-bubble--me.yan-msgs__unreadable { color: var(--yan-color-accent-on-accent); opacity: 0.8; }
@@ -227,6 +229,33 @@ class MessagesPage {
227
229
  this.busy.set(false);
228
230
  }
229
231
  }
232
+ async approve(requestId) {
233
+ if (this.busy())
234
+ return;
235
+ this.busy.set(true);
236
+ try {
237
+ await this.store.approve(requestId);
238
+ this.toast.show('Your earlier messages are on their way to that device');
239
+ }
240
+ catch (e) {
241
+ this.toast.show(errorText(e, "Couldn't send them. Try again."));
242
+ }
243
+ finally {
244
+ this.busy.set(false);
245
+ }
246
+ }
247
+ async deny(requestId) {
248
+ if (this.busy())
249
+ return;
250
+ this.busy.set(true);
251
+ try {
252
+ await this.store.deny(requestId);
253
+ this.toast.show("Nothing was sent. If you don't recognise that device, change your password.");
254
+ }
255
+ finally {
256
+ this.busy.set(false);
257
+ }
258
+ }
230
259
  onScroll() {
231
260
  const el = this.scroller()?.nativeElement;
232
261
  if (el)
@@ -256,6 +285,16 @@ class MessagesPage {
256
285
  <div class="yan-row yan-msgs__row" aria-hidden="true"><span class="yan-avatar yan-avatar--lg yan-skeleton"></span><span class="yan-row__body"><span class="yan-skeleton yan-msgs__sk1"></span><span class="yan-skeleton yan-msgs__sk2"></span></span></div>
257
286
  }
258
287
  } @else {
288
+ @for (ap of store.approvals(); track ap.requestId) {
289
+ <div class="yan-card yan-card--tight yan-msgs__approve" role="alert">
290
+ <div><b>{{ ap.deviceName }}</b> wants to read your earlier messages. Allow it only if it's your device and it shows this code:</div>
291
+ <div class="yan-msgs__code">{{ ap.code }}</div>
292
+ <div class="yan-cluster">
293
+ <button type="button" class="yan-btn yan-btn--sm" [attr.aria-disabled]="busy()" (click)="approve(ap.requestId)">Allow</button>
294
+ <button type="button" class="yan-btn yan-btn--sm yan-btn--secondary" [attr.aria-disabled]="busy()" (click)="deny(ap.requestId)">Not mine</button>
295
+ </div>
296
+ </div>
297
+ }
259
298
  <button type="button" class="yan-row yan-row--interactive yan-msgs__row" [class.yan-row--selected]="sel() === 'requests'" (click)="go(['requests'])">
260
299
  <span class="yan-avatar yan-avatar--lg yan-avatar--square" style="--yan-avatar-hue:80"><span class="yi yi-inbox" aria-hidden="true"></span></span>
261
300
  <span class="yan-row__body">
@@ -331,7 +370,21 @@ class MessagesPage {
331
370
  } @else if (!t.items.length) {
332
371
  <div class="yan-msgs__cap yan-msgs__start">Messages here are end-to-end encrypted. Only the people in this conversation can read them.</div>
333
372
  } @else if (hasUnreadable()) {
334
- <div class="yan-msgs__cap yan-msgs__lost">Messages sent before you set up this device can't be read here. They're still on the devices you had then.</div>
373
+ @let h = store.history();
374
+ <div class="yan-card yan-card--tight yan-msgs__lost" role="status">
375
+ @if (h.state === 'alone') {
376
+ <div>Messages sent before you set up this device can't be read here: none of your other devices has messages set up to send them.</div>
377
+ } @else if (h.state === 'received') {
378
+ <div>Some earlier messages weren't on the device you allowed, so they can't be read here.</div>
379
+ <button type="button" class="yan-btn yan-btn--sm yan-btn--ghost" (click)="store.askForHistory(true)">Ask again</button>
380
+ } @else if (h.codes.length) {
381
+ <div>To read earlier messages here, open Messages on <b>{{ h.codes[0].deviceName }}</b> and allow this device. Check it shows this code:</div>
382
+ @for (c of h.codes; track c.deviceId) {<div class="yan-msgs__code" [attr.aria-label]="'Code ' + c.code">{{ c.code }}</div>}
383
+ } @else {
384
+ <div>Messages sent before you set up this device can't be read here yet. Open Messages on another of your devices to send them here.</div>
385
+ <button type="button" class="yan-btn yan-btn--sm yan-btn--ghost" (click)="store.askForHistory(true)">Ask again</button>
386
+ }
387
+ </div>
335
388
  }
336
389
  @for (m of t.items; track m.clientMsgId || m.id) {
337
390
  @if (showSender(m, $index)) {<div class="yan-msgs__from">{{ who(m.senderId) }}</div>}
@@ -363,7 +416,7 @@ class MessagesPage {
363
416
  }
364
417
  </div>
365
418
  </div>
366
- `, isInline: true, styles: [".yan-shell__scroller:has(>.yan-shell__col>yan-messages-page){overflow:hidden}.yan-shell__col:has(>yan-messages-page){max-width:none;padding:0;height:100%}yan-messages-page{display:block;height:100%}.yan-msgs{display:flex;height:100%}.yan-msgs__list{flex:none;width:100%;overflow-y:auto}.yan-msgs__pane{flex:1;min-width:0;display:none;flex-direction:column}.yan-msgs--open .yan-msgs__list{display:none}.yan-msgs--open .yan-msgs__pane{display:flex}@media(min-width:820px){.yan-msgs__list{width:340px;border-right:1px solid var(--yan-color-border-default)}.yan-msgs--open .yan-msgs__list{display:block}.yan-msgs__pane{display:flex}.yan-msgs__back{display:none}}.yan-msgs__title{font:var(--yan-text-title-lg);letter-spacing:var(--yan-text-title-lg-tracking);font-size:22px;padding:18px 16px 10px;margin:0}.yan-msgs__row{padding:12px 16px;font:inherit}.yan-msgs__line{display:flex;align-items:center;gap:6px;min-width:0}.yan-msgs__name{font-size:15px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.yan-msgs__last{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.yan-msgs__empty,.yan-msgs__err{margin:16px}.yan-msgs__sk1{display:block;height:12px;width:40%;border-radius:6px;margin-bottom:6px}.yan-msgs__sk2{display:block;height:10px;width:70%;border-radius:6px}.yan-msgs__head{flex:none;display:flex;align-items:center;gap:10px;padding:12px 16px;border-bottom:1px solid var(--yan-color-border-default)}.yan-msgs__headname{font-weight:600}.yan-msgs__grow{flex:1;min-width:0}.yan-msgs__scroll{flex:1;min-height:0;overflow-y:auto}.yan-msgs__placeholder{margin:auto;max-width:360px;padding:24px}.yan-msgs__older{align-self:center}.yan-msgs__start{align-self:center;text-align:center;max-width:360px}.yan-msgs__lost{align-self:center;text-align:center;max-width:420px}.yan-msgs__from{font:var(--yan-text-micro);color:var(--yan-color-ink-muted);margin:4px 0 -6px 4px}.yan-msgs__unreadable{font-style:italic;color:var(--yan-color-ink-muted)}.yan-bubble--me.yan-msgs__unreadable{color:var(--yan-color-accent-on-accent);opacity:.8}.yan-msgs__pending{opacity:.6}.yan-msgs__failed{align-self:flex-end;font:var(--yan-text-caption);color:var(--yan-color-danger-default);margin-top:-6px}.yan-msgs__seen{align-self:flex-end;font:var(--yan-text-micro);color:var(--yan-color-ink-muted);margin-top:-6px}.yan-msgs__typing{align-self:flex-start}.yan-msgs__skb{width:50%;height:36px}.yan-msgs__cap{font:var(--yan-text-caption);color:var(--yan-color-ink-muted)}.yan-msgs__note{flex:none;padding:8px 16px 0}.yan-msgs__banner{flex:none;margin:8px 16px 0}.yan-msgs__reqbar{flex:none;display:flex;flex-direction:column;gap:8px;padding:12px 16px;border-top:1px solid var(--yan-color-border-default)}.yan-msgs__reqtext{display:block;width:100%;margin:10px 0;padding:0;border:0;background:none;text-align:left;font:inherit;color:inherit;cursor:pointer;overflow-wrap:anywhere}.yan-msgs__reqacts{margin-top:10px}.yan-msgs__composer{flex:none;display:flex;gap:8px;padding:12px 16px;border-top:1px solid var(--yan-color-border-default)}.yan-msgs__composer .yan-input{flex:1;min-width:0;border-radius:var(--yan-radius-pill)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
419
+ `, isInline: true, styles: [".yan-shell__scroller:has(>.yan-shell__col>yan-messages-page){overflow:hidden}.yan-shell__col:has(>yan-messages-page){max-width:none;padding:0;height:100%}yan-messages-page{display:block;height:100%}.yan-msgs{display:flex;height:100%}.yan-msgs__list{flex:none;width:100%;overflow-y:auto}.yan-msgs__pane{flex:1;min-width:0;display:none;flex-direction:column}.yan-msgs--open .yan-msgs__list{display:none}.yan-msgs--open .yan-msgs__pane{display:flex}@media(min-width:820px){.yan-msgs__list{width:340px;border-right:1px solid var(--yan-color-border-default)}.yan-msgs--open .yan-msgs__list{display:block}.yan-msgs__pane{display:flex}.yan-msgs__back{display:none}}.yan-msgs__title{font:var(--yan-text-title-lg);letter-spacing:var(--yan-text-title-lg-tracking);font-size:22px;padding:18px 16px 10px;margin:0}.yan-msgs__row{padding:12px 16px;font:inherit}.yan-msgs__line{display:flex;align-items:center;gap:6px;min-width:0}.yan-msgs__name{font-size:15px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.yan-msgs__last{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.yan-msgs__empty,.yan-msgs__err{margin:16px}.yan-msgs__sk1{display:block;height:12px;width:40%;border-radius:6px;margin-bottom:6px}.yan-msgs__sk2{display:block;height:10px;width:70%;border-radius:6px}.yan-msgs__head{flex:none;display:flex;align-items:center;gap:10px;padding:12px 16px;border-bottom:1px solid var(--yan-color-border-default)}.yan-msgs__headname{font-weight:600}.yan-msgs__grow{flex:1;min-width:0}.yan-msgs__scroll{flex:1;min-height:0;overflow-y:auto}.yan-msgs__placeholder{margin:auto;max-width:360px;padding:24px}.yan-msgs__older{align-self:center}.yan-msgs__start{align-self:center;text-align:center;max-width:360px}.yan-msgs__lost{align-self:stretch;display:flex;flex-direction:column;gap:8px;align-items:flex-start;font:var(--yan-text-body-sm)}.yan-msgs__approve{margin:0 16px 12px;display:flex;flex-direction:column;gap:8px;font:var(--yan-text-body-sm)}.yan-msgs__code{font-family:var(--yan-font-mono, ui-monospace, monospace);font-size:22px;letter-spacing:.08em;font-weight:600}.yan-msgs__from{font:var(--yan-text-micro);color:var(--yan-color-ink-muted);margin:4px 0 -6px 4px}.yan-msgs__unreadable{font-style:italic;color:var(--yan-color-ink-muted)}.yan-bubble--me.yan-msgs__unreadable{color:var(--yan-color-accent-on-accent);opacity:.8}.yan-msgs__pending{opacity:.6}.yan-msgs__failed{align-self:flex-end;font:var(--yan-text-caption);color:var(--yan-color-danger-default);margin-top:-6px}.yan-msgs__seen{align-self:flex-end;font:var(--yan-text-micro);color:var(--yan-color-ink-muted);margin-top:-6px}.yan-msgs__typing{align-self:flex-start}.yan-msgs__skb{width:50%;height:36px}.yan-msgs__cap{font:var(--yan-text-caption);color:var(--yan-color-ink-muted)}.yan-msgs__note{flex:none;padding:8px 16px 0}.yan-msgs__banner{flex:none;margin:8px 16px 0}.yan-msgs__reqbar{flex:none;display:flex;flex-direction:column;gap:8px;padding:12px 16px;border-top:1px solid var(--yan-color-border-default)}.yan-msgs__reqtext{display:block;width:100%;margin:10px 0;padding:0;border:0;background:none;text-align:left;font:inherit;color:inherit;cursor:pointer;overflow-wrap:anywhere}.yan-msgs__reqacts{margin-top:10px}.yan-msgs__composer{flex:none;display:flex;gap:8px;padding:12px 16px;border-top:1px solid var(--yan-color-border-default)}.yan-msgs__composer .yan-input{flex:1;min-width:0;border-radius:var(--yan-radius-pill)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
367
420
  }
368
421
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: MessagesPage, decorators: [{
369
422
  type: Component,
@@ -385,6 +438,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
385
438
  <div class="yan-row yan-msgs__row" aria-hidden="true"><span class="yan-avatar yan-avatar--lg yan-skeleton"></span><span class="yan-row__body"><span class="yan-skeleton yan-msgs__sk1"></span><span class="yan-skeleton yan-msgs__sk2"></span></span></div>
386
439
  }
387
440
  } @else {
441
+ @for (ap of store.approvals(); track ap.requestId) {
442
+ <div class="yan-card yan-card--tight yan-msgs__approve" role="alert">
443
+ <div><b>{{ ap.deviceName }}</b> wants to read your earlier messages. Allow it only if it's your device and it shows this code:</div>
444
+ <div class="yan-msgs__code">{{ ap.code }}</div>
445
+ <div class="yan-cluster">
446
+ <button type="button" class="yan-btn yan-btn--sm" [attr.aria-disabled]="busy()" (click)="approve(ap.requestId)">Allow</button>
447
+ <button type="button" class="yan-btn yan-btn--sm yan-btn--secondary" [attr.aria-disabled]="busy()" (click)="deny(ap.requestId)">Not mine</button>
448
+ </div>
449
+ </div>
450
+ }
388
451
  <button type="button" class="yan-row yan-row--interactive yan-msgs__row" [class.yan-row--selected]="sel() === 'requests'" (click)="go(['requests'])">
389
452
  <span class="yan-avatar yan-avatar--lg yan-avatar--square" style="--yan-avatar-hue:80"><span class="yi yi-inbox" aria-hidden="true"></span></span>
390
453
  <span class="yan-row__body">
@@ -460,7 +523,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
460
523
  } @else if (!t.items.length) {
461
524
  <div class="yan-msgs__cap yan-msgs__start">Messages here are end-to-end encrypted. Only the people in this conversation can read them.</div>
462
525
  } @else if (hasUnreadable()) {
463
- <div class="yan-msgs__cap yan-msgs__lost">Messages sent before you set up this device can't be read here. They're still on the devices you had then.</div>
526
+ @let h = store.history();
527
+ <div class="yan-card yan-card--tight yan-msgs__lost" role="status">
528
+ @if (h.state === 'alone') {
529
+ <div>Messages sent before you set up this device can't be read here: none of your other devices has messages set up to send them.</div>
530
+ } @else if (h.state === 'received') {
531
+ <div>Some earlier messages weren't on the device you allowed, so they can't be read here.</div>
532
+ <button type="button" class="yan-btn yan-btn--sm yan-btn--ghost" (click)="store.askForHistory(true)">Ask again</button>
533
+ } @else if (h.codes.length) {
534
+ <div>To read earlier messages here, open Messages on <b>{{ h.codes[0].deviceName }}</b> and allow this device. Check it shows this code:</div>
535
+ @for (c of h.codes; track c.deviceId) {<div class="yan-msgs__code" [attr.aria-label]="'Code ' + c.code">{{ c.code }}</div>}
536
+ } @else {
537
+ <div>Messages sent before you set up this device can't be read here yet. Open Messages on another of your devices to send them here.</div>
538
+ <button type="button" class="yan-btn yan-btn--sm yan-btn--ghost" (click)="store.askForHistory(true)">Ask again</button>
539
+ }
540
+ </div>
464
541
  }
465
542
  @for (m of t.items; track m.clientMsgId || m.id) {
466
543
  @if (showSender(m, $index)) {<div class="yan-msgs__from">{{ who(m.senderId) }}</div>}
@@ -492,11 +569,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
492
569
  }
493
570
  </div>
494
571
  </div>
495
- `, styles: [".yan-shell__scroller:has(>.yan-shell__col>yan-messages-page){overflow:hidden}.yan-shell__col:has(>yan-messages-page){max-width:none;padding:0;height:100%}yan-messages-page{display:block;height:100%}.yan-msgs{display:flex;height:100%}.yan-msgs__list{flex:none;width:100%;overflow-y:auto}.yan-msgs__pane{flex:1;min-width:0;display:none;flex-direction:column}.yan-msgs--open .yan-msgs__list{display:none}.yan-msgs--open .yan-msgs__pane{display:flex}@media(min-width:820px){.yan-msgs__list{width:340px;border-right:1px solid var(--yan-color-border-default)}.yan-msgs--open .yan-msgs__list{display:block}.yan-msgs__pane{display:flex}.yan-msgs__back{display:none}}.yan-msgs__title{font:var(--yan-text-title-lg);letter-spacing:var(--yan-text-title-lg-tracking);font-size:22px;padding:18px 16px 10px;margin:0}.yan-msgs__row{padding:12px 16px;font:inherit}.yan-msgs__line{display:flex;align-items:center;gap:6px;min-width:0}.yan-msgs__name{font-size:15px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.yan-msgs__last{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.yan-msgs__empty,.yan-msgs__err{margin:16px}.yan-msgs__sk1{display:block;height:12px;width:40%;border-radius:6px;margin-bottom:6px}.yan-msgs__sk2{display:block;height:10px;width:70%;border-radius:6px}.yan-msgs__head{flex:none;display:flex;align-items:center;gap:10px;padding:12px 16px;border-bottom:1px solid var(--yan-color-border-default)}.yan-msgs__headname{font-weight:600}.yan-msgs__grow{flex:1;min-width:0}.yan-msgs__scroll{flex:1;min-height:0;overflow-y:auto}.yan-msgs__placeholder{margin:auto;max-width:360px;padding:24px}.yan-msgs__older{align-self:center}.yan-msgs__start{align-self:center;text-align:center;max-width:360px}.yan-msgs__lost{align-self:center;text-align:center;max-width:420px}.yan-msgs__from{font:var(--yan-text-micro);color:var(--yan-color-ink-muted);margin:4px 0 -6px 4px}.yan-msgs__unreadable{font-style:italic;color:var(--yan-color-ink-muted)}.yan-bubble--me.yan-msgs__unreadable{color:var(--yan-color-accent-on-accent);opacity:.8}.yan-msgs__pending{opacity:.6}.yan-msgs__failed{align-self:flex-end;font:var(--yan-text-caption);color:var(--yan-color-danger-default);margin-top:-6px}.yan-msgs__seen{align-self:flex-end;font:var(--yan-text-micro);color:var(--yan-color-ink-muted);margin-top:-6px}.yan-msgs__typing{align-self:flex-start}.yan-msgs__skb{width:50%;height:36px}.yan-msgs__cap{font:var(--yan-text-caption);color:var(--yan-color-ink-muted)}.yan-msgs__note{flex:none;padding:8px 16px 0}.yan-msgs__banner{flex:none;margin:8px 16px 0}.yan-msgs__reqbar{flex:none;display:flex;flex-direction:column;gap:8px;padding:12px 16px;border-top:1px solid var(--yan-color-border-default)}.yan-msgs__reqtext{display:block;width:100%;margin:10px 0;padding:0;border:0;background:none;text-align:left;font:inherit;color:inherit;cursor:pointer;overflow-wrap:anywhere}.yan-msgs__reqacts{margin-top:10px}.yan-msgs__composer{flex:none;display:flex;gap:8px;padding:12px 16px;border-top:1px solid var(--yan-color-border-default)}.yan-msgs__composer .yan-input{flex:1;min-width:0;border-radius:var(--yan-radius-pill)}\n"] }]
572
+ `, styles: [".yan-shell__scroller:has(>.yan-shell__col>yan-messages-page){overflow:hidden}.yan-shell__col:has(>yan-messages-page){max-width:none;padding:0;height:100%}yan-messages-page{display:block;height:100%}.yan-msgs{display:flex;height:100%}.yan-msgs__list{flex:none;width:100%;overflow-y:auto}.yan-msgs__pane{flex:1;min-width:0;display:none;flex-direction:column}.yan-msgs--open .yan-msgs__list{display:none}.yan-msgs--open .yan-msgs__pane{display:flex}@media(min-width:820px){.yan-msgs__list{width:340px;border-right:1px solid var(--yan-color-border-default)}.yan-msgs--open .yan-msgs__list{display:block}.yan-msgs__pane{display:flex}.yan-msgs__back{display:none}}.yan-msgs__title{font:var(--yan-text-title-lg);letter-spacing:var(--yan-text-title-lg-tracking);font-size:22px;padding:18px 16px 10px;margin:0}.yan-msgs__row{padding:12px 16px;font:inherit}.yan-msgs__line{display:flex;align-items:center;gap:6px;min-width:0}.yan-msgs__name{font-size:15px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.yan-msgs__last{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.yan-msgs__empty,.yan-msgs__err{margin:16px}.yan-msgs__sk1{display:block;height:12px;width:40%;border-radius:6px;margin-bottom:6px}.yan-msgs__sk2{display:block;height:10px;width:70%;border-radius:6px}.yan-msgs__head{flex:none;display:flex;align-items:center;gap:10px;padding:12px 16px;border-bottom:1px solid var(--yan-color-border-default)}.yan-msgs__headname{font-weight:600}.yan-msgs__grow{flex:1;min-width:0}.yan-msgs__scroll{flex:1;min-height:0;overflow-y:auto}.yan-msgs__placeholder{margin:auto;max-width:360px;padding:24px}.yan-msgs__older{align-self:center}.yan-msgs__start{align-self:center;text-align:center;max-width:360px}.yan-msgs__lost{align-self:stretch;display:flex;flex-direction:column;gap:8px;align-items:flex-start;font:var(--yan-text-body-sm)}.yan-msgs__approve{margin:0 16px 12px;display:flex;flex-direction:column;gap:8px;font:var(--yan-text-body-sm)}.yan-msgs__code{font-family:var(--yan-font-mono, ui-monospace, monospace);font-size:22px;letter-spacing:.08em;font-weight:600}.yan-msgs__from{font:var(--yan-text-micro);color:var(--yan-color-ink-muted);margin:4px 0 -6px 4px}.yan-msgs__unreadable{font-style:italic;color:var(--yan-color-ink-muted)}.yan-bubble--me.yan-msgs__unreadable{color:var(--yan-color-accent-on-accent);opacity:.8}.yan-msgs__pending{opacity:.6}.yan-msgs__failed{align-self:flex-end;font:var(--yan-text-caption);color:var(--yan-color-danger-default);margin-top:-6px}.yan-msgs__seen{align-self:flex-end;font:var(--yan-text-micro);color:var(--yan-color-ink-muted);margin-top:-6px}.yan-msgs__typing{align-self:flex-start}.yan-msgs__skb{width:50%;height:36px}.yan-msgs__cap{font:var(--yan-text-caption);color:var(--yan-color-ink-muted)}.yan-msgs__note{flex:none;padding:8px 16px 0}.yan-msgs__banner{flex:none;margin:8px 16px 0}.yan-msgs__reqbar{flex:none;display:flex;flex-direction:column;gap:8px;padding:12px 16px;border-top:1px solid var(--yan-color-border-default)}.yan-msgs__reqtext{display:block;width:100%;margin:10px 0;padding:0;border:0;background:none;text-align:left;font:inherit;color:inherit;cursor:pointer;overflow-wrap:anywhere}.yan-msgs__reqacts{margin-top:10px}.yan-msgs__composer{flex:none;display:flex;gap:8px;padding:12px 16px;border-top:1px solid var(--yan-color-border-default)}.yan-msgs__composer .yan-input{flex:1;min-width:0;border-radius:var(--yan-radius-pill)}\n"] }]
496
573
  }], ctorParameters: () => [], propDecorators: { scroller: [{ type: i0.ViewChild, args: ['scroller', { isSignal: true }] }] } });
497
574
  function firstName(n) {
498
575
  return n.startsWith('@') ? n : n.split(' ')[0];
499
576
  }
500
577
 
501
578
  export { MessagesPage };
502
- //# sourceMappingURL=chisquare-tech-yan-ngx-apps-messages-messages.page-Dy0RhQwj.mjs.map
579
+ //# sourceMappingURL=chisquare-tech-yan-ngx-apps-messages-messages.page-Dc4cpq4L.mjs.map