From 3053414135e8d311707cb08d16b3354481212650 Mon Sep 17 00:00:00 2001 From: ropic Date: Thu, 18 Jun 2026 23:20:47 -0600 Subject: [PATCH] fix: use AppStateSyncKeyData.fromObject instead of .create for app-state keys MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When reading app-state-sync-key data from any auth-state provider (Prisma, Redis, files), the stored JSON is deserialized with BufferJSON.reviver which correctly restores Buffer objects. However, wrapping the result with AppStateSyncKeyData.create() does not coerce the restored Buffer fields to the Uint8Array types that the proto library expects for all downstream operations. This produces incorrect keyData in the HKDF derivation step, which in turn generates a wrong AES-256-CBC key and causes "error:1C800064:Provider routines::bad decrypt" on every attempt to decode app-state mutations (labels, archives, mutes, etc.). AppStateSyncKeyData.fromObject() performs full type conversion of all fields from a plain JS object, which is exactly what is needed after JSON deserialization. Affects all three auth-state providers: Prisma, Redis, and file-based. Tested with the Prisma provider — no app-state events fired before this fix; all events (labels.association, chats.update, etc.) fire correctly after. --- src/utils/use-multi-file-auth-state-prisma.ts | 2 +- src/utils/use-multi-file-auth-state-provider-files.ts | 2 +- src/utils/use-multi-file-auth-state-redis-db.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/utils/use-multi-file-auth-state-prisma.ts b/src/utils/use-multi-file-auth-state-prisma.ts index d090780234..bd11afa2fe 100644 --- a/src/utils/use-multi-file-auth-state-prisma.ts +++ b/src/utils/use-multi-file-auth-state-prisma.ts @@ -182,7 +182,7 @@ export default async function useMultiFileAuthStatePrisma( ids.map(async (id) => { let value = await readData(`${type}-${id}`); if (type === 'app-state-sync-key' && value) { - value = proto.Message.AppStateSyncKeyData.create(value); + value = proto.Message.AppStateSyncKeyData.fromObject(value); } data[id] = value; diff --git a/src/utils/use-multi-file-auth-state-provider-files.ts b/src/utils/use-multi-file-auth-state-provider-files.ts index eecc3100e5..157918169d 100644 --- a/src/utils/use-multi-file-auth-state-provider-files.ts +++ b/src/utils/use-multi-file-auth-state-provider-files.ts @@ -116,7 +116,7 @@ export class AuthStateProvider { ids.map(async (id) => { let value = await readData(`${type}-${id}`); if (type === 'app-state-sync-key' && value) { - value = proto.Message.AppStateSyncKeyData.create(value); + value = proto.Message.AppStateSyncKeyData.fromObject(value); } data[id] = value; diff --git a/src/utils/use-multi-file-auth-state-redis-db.ts b/src/utils/use-multi-file-auth-state-redis-db.ts index e0981c700c..4d5d5a5457 100644 --- a/src/utils/use-multi-file-auth-state-redis-db.ts +++ b/src/utils/use-multi-file-auth-state-redis-db.ts @@ -61,7 +61,7 @@ export async function useMultiFileAuthStateRedisDb( ids.map(async (id) => { let value = await readData(`${type}-${id}`); if (type === 'app-state-sync-key' && value) { - value = proto.Message.AppStateSyncKeyData.create(value); + value = proto.Message.AppStateSyncKeyData.fromObject(value); } data[id] = value;