Code change:
Describe the bug Just lost on two different NixOS machine my Signal Desktop history because of this faulty update... I don't know, probably doesn't make sense for people to downgrade who are already upgraded but for others it dataloss To Reproduce Steps to reproduce the behavior: Signal Desktop Signal Desktop you to delete db, if you interact in a wrong way it will delete your data Notify maintainers ( and
Sorry to hear that. I recently lost my history too... It's really frustrating! Yeah, unfortunately I don't think there's anything we can do about it (as downstream package maintainers). AFAIK the source of the bug is still unknown, it doesn't seem to affect all users, and all releases have a limited lifetime ("expire" 90 days after the release, see my comment in ). Thanks for saying that! This really bothered me too... I just didn't say anything because I was too angry to keep it nice enough. (I raged a bit here but after I realized that one cannot even import old backups I had to take a break.)
I just got hit by a similar issue by moving from Archlinux (encrypted database) to NixOS (non encrypted database). After many things, the easiest fix to ensure proper functionalities IMHO is installing: This will disable tracker3 and prevent SQLite to be loaded in the process which will replace SQLCipher and cause the SQLite3 API to be the original one (i.e. non-encrypted) and cause many issues down the road I guess. That might not fix everything though :upsidedownface: Opened a PR:
FYI, in case anyone has feedback/suggestions: We might merge soon and it should cause another "Database startup error: Error: SQLITE_NOTADB: file is not a database" error (which is really unfortunate but not easily avoidable).
Heads-up: I've just merged to hopefully resolve this once and for all and the Python wrapper script should take care of the database re-encryption when launching Signal-Desktop as usual but the user experience isn't that great and you probably want to backup first in case the script fails unexpectedly.
Thank you, I just upgraded Signal on my computer and the re-encryption did work as intended

Related discussion:
text: <ins> #!@PYTHON@ import json import os import re import shlex import sqlite3 import subprocess import sys DB_PATH = os.path.join(os.environ['HOME'], '.config/Signal/sql/db.sqlite') DB_COPY = os.path.join(os.environ['HOME'], '.config/Signal/sql/db.tmp') CONFIG_PATH = os.path.join(os.environ['HOME'], '.config/Signal/config.json') def zenity_askyesno(title, text): args = [ '@ZENITY@', '--question', '--title', shlex.quote(title), '--text', shlex.quote(text) ] return subprocess.run(args).returncode == 0 def start_signal(): os.execvp('@SIGNAL-DESKTOP@', ['@SIGNAL-DESKTOP@'] + sys.argv[1:]) def copy_pragma(name): result = subprocess.run([ '@SQLCIPHER@', DB_PATH, f"PRAGMA {name};" ], check=True, capture_output=True).stdout result = re.search(r'[0-9]+', result.decode()).group(0) subprocess.run([ '@SQLCIPHER@', DB_COPY, f"PRAGMA key = "x'{key}'"; PRAGMA {name} = {result};" ], check=True, capture_output=True) try: # Test if DB is encrypted: con = sqlite3.connect(f'file:{DB_PATH}?mode=ro', uri=True) cursor = con.cursor() cursor.execute("SELECT name FROM sqlite_master WHERE type='table';") con.close() except: # DB is encrypted, everything ok: start_signal() # DB is unencrypted! answer = zenity_askyesno( "Error: Signal-Desktop database is not encrypted", "Should we try to fix this automatically?" + "You likely want to backup ~/.config/Signal/ first." ) if not answer: answer = zenity_askyesno( "Launch Signal-Desktop", "DB is unencrypted, should we still launch Signal-Desktop?" + "Warning: This could result in data loss!" ) if not answer: print('Aborted') sys.exit(0) start_signal() # Re-encrypt the DB: with open(CONFIG_PATH) as json_file: key = json.load(json_file)['key'] result = subprocess.run([ '@SQLCIPHER@', DB_PATH, f" ATTACH DATABASE '{DB_COPY}' AS signal_db KEY "x'{key}'";" + " SELECT sqlcipher_export('signal_db');" + " DETACH DATABASE signal_db;" ]).returncode if result != 0: print('DB encryption failed') sys.exit(1) # Need to copy user_version and schema_version manually: copy_pragma('user_version') copy_pragma('schema_version') os.rename(DB_COPY, DB_PATH) start_signal() </ins>