Skip to content

fix: stop writing E2EE key files to a missing data/data folder - #277

Open
clins1994 wants to merge 1 commit into
beeper:mainfrom
clins1994:fix/secure-file-path
Open

clins1994 wants to merge 1 commit into
beeper:mainfrom
clins1994:fix/secure-file-path

Conversation

@clins1994

@clins1994 clins1994 commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Every login logs failed to save E2EE secure data, because the bridge writes a key file that it does not need to data/data/, a folder that does not exist. Please review this change, which stops writing that file, and say if the file reading must go too.

Chaque connexion affiche failed to save E2EE secure data, car le bridge écrit un fichier de clés dont il n'a pas besoin dans data/data/, un dossier qui n'existe pas. Merci de relire ce changement, qui arrête d'écrire ce fichier, et de dire si la lecture du fichier doit aussi disparaître.


🇬🇧 More details · 3 min read

Summary

The bridge no longer writes lcs_secure_<id>.json. It still reads an old file if one exists. The E2EE key map stays in the user login metadata, as before.

Why

pkg/e2ee/manager.go builds the path as filepath.Join("data", ...). This path is relative to the working directory. The Docker image starts the bridge in /data (Dockerfile: WORKDIR /data, docker-run.sh: cd /data). The README's native steps also run cd data first. So the write goes one folder too deep:

Started from Path that the bridge writes Result
repo root beeper-line/data/lcs_secure_<id>.json saved
data/ (Docker, README native steps) data/data/lcs_secure_<id>.json no such file or directory

Log from a fresh Docker setup on 72c7a51, at QR login:

WRN Login: failed to save E2EE secure data error="open data/lcs_secure_<id>.json: no such file or directory"

Messages still decrypt, because the key map is also in the login metadata. connect loads the metadata last, so it wins over the file (pkg/connector/client.go):

// DB metadata reflects the latest login, even if writing the secure file failed.
// Load it last so an older file cannot replace the freshly verified key.

So the file is a second copy of the key that nothing needs.

Changes

  • pkg/connector/connector.go: remove the file write after a new login, and remove loginSecureDataID, which only the writes used.
  • pkg/connector/client.go: remove the file writes after a re-login and in refreshLoginE2EEKeys.
  • pkg/e2ee/manager.go: remove SaveSecureDataToFile and EncryptSecureBlob. Keep LoadSecureDataFromFile as a fallback for files from older versions.
  • pkg/connector/login_keys_test.go: remove the test for loginSecureDataID.

Another option is to remove LoadSecureDataFromFile and its call too. That is cleaner, but a login from before the metadata copy existed (July 2026) can depend on its file. I kept the fallback for that case. I can remove it if you prefer.

How it was tested

In a golang:1.26-alpine3.23 container with olm-dev, because the host has no libolm:

  • gofmt -l pkg cmd: no output.
  • go build ./...: passed.
  • go vet $(go list ./... | grep -v /ltsm): passed.
  • go test ./pkg/connector/... ./pkg/e2ee/...: passed.
  • goimports -local github.com/beeper/line -l pkg cmd: no output.
  • staticcheck $(go list ./... | grep -v /ltsm): one finding, in pkg/line/password/password.go:27. This PR does not change that file.

Live, on the same Docker setup and data/ folder:

  • 72c7a51: a QR login logged the failed to save E2EE secure data warning.
  • This branch (2990e09): a QR login over the existing login logged no warning or error. bbctl whoami shows the bridge CONNECTED, and no lcs_secure_*.json file exists in /data.

Not tested (and why)

  • Loading an old key file. No file exists in my Docker setup, because the write always failed there.
🇫🇷 Plus de détails · 3 min de lecture

Résumé

Le bridge n'écrit plus lcs_secure_<id>.json. Il lit encore un ancien fichier s'il en existe un. La table des clés E2EE reste dans les métadonnées de connexion, comme avant.

Pourquoi

pkg/e2ee/manager.go construit le chemin avec filepath.Join("data", ...). Ce chemin est relatif au dossier de travail. L'image Docker lance le bridge dans /data (Dockerfile : WORKDIR /data, docker-run.sh : cd /data). Les étapes natives du README font aussi cd data d'abord. L'écriture va donc un dossier trop loin :

Lancé depuis Chemin écrit par le bridge Résultat
racine du dépôt beeper-line/data/lcs_secure_<id>.json enregistré
data/ (Docker, étapes natives du README) data/data/lcs_secure_<id>.json no such file or directory

Log d'une installation Docker neuve sur 72c7a51, à la connexion par QR code :

WRN Login: failed to save E2EE secure data error="open data/lcs_secure_<id>.json: no such file or directory"

Les messages se déchiffrent quand même, car la table des clés est aussi dans les métadonnées de connexion. connect charge les métadonnées en dernier, donc elles l'emportent sur le fichier (pkg/connector/client.go) :

// DB metadata reflects the latest login, even if writing the secure file failed.
// Load it last so an older file cannot replace the freshly verified key.

Le fichier est donc une deuxième copie de la clé dont rien n'a besoin.

Modifications

  • pkg/connector/connector.go : supprime l'écriture du fichier après une nouvelle connexion, et supprime loginSecureDataID, utilisé seulement par les écritures.
  • pkg/connector/client.go : supprime les écritures du fichier après une reconnexion et dans refreshLoginE2EEKeys.
  • pkg/e2ee/manager.go : supprime SaveSecureDataToFile et EncryptSecureBlob. Garde LoadSecureDataFromFile comme solution de repli pour les fichiers des anciennes versions.
  • pkg/connector/login_keys_test.go : supprime le test de loginSecureDataID.

Une autre option est de supprimer aussi LoadSecureDataFromFile et son appel. C'est plus propre, mais une connexion d'avant la copie dans les métadonnées (juillet 2026) peut dépendre de son fichier. J'ai gardé la solution de repli pour ce cas. Je peux la supprimer si vous préférez.

Tests effectués

Dans un conteneur golang:1.26-alpine3.23 avec olm-dev, car l'hôte n'a pas libolm :

  • gofmt -l pkg cmd : aucune sortie.
  • go build ./... : réussi.
  • go vet $(go list ./... | grep -v /ltsm) : réussi.
  • go test ./pkg/connector/... ./pkg/e2ee/... : réussi.
  • goimports -local github.com/beeper/line -l pkg cmd : aucune sortie.
  • staticcheck $(go list ./... | grep -v /ltsm) : un résultat, dans pkg/line/password/password.go:27. Cette PR ne modifie pas ce fichier.

En direct, avec la même installation Docker et le même dossier data/ :

  • 72c7a51 : une connexion par QR code a affiché l'avertissement failed to save E2EE secure data.
  • Cette branche (2990e09) : une connexion par QR code sur la connexion existante n'a affiché aucun avertissement ni aucune erreur. bbctl whoami montre le bridge CONNECTED, et aucun fichier lcs_secure_*.json n'existe dans /data.

Non testé (et pourquoi)

  • Le chargement d'un ancien fichier de clés. Aucun fichier n'existe dans mon installation Docker, car l'écriture y échouait toujours.

🤖 Generated with Claude Code using clins:create-pr

The bridge saved an encrypted copy of the login key map to
data/lcs_secure_<id>.json, relative to its working directory. Docker
and the README's native steps both start the bridge inside data/, so
the write targeted data/data/ and failed on every login with
"failed to save E2EE secure data". The key map is already stored in the
user login metadata, which is loaded last and wins, so the file was
never needed.

Stop writing the file and keep reading old files as a fallback.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YLetjAVceT9hFiBGm9qiTG

@highesttt highesttt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two nitpicks: every connect still decrypts the old key file, and the old files are left on disk.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants