From 1dda055e4c5ea2b0556141ee5efac7de2ba2e526 Mon Sep 17 00:00:00 2001 From: hermes Date: Mon, 26 Oct 2026 16:11:17 +0800 Subject: [PATCH] =?UTF-8?q?fix(qa):=20=E6=8E=88=E6=9D=83=E7=A0=81=E5=8A=A0?= =?UTF-8?q?=E5=AF=86=E4=B8=8D=E5=86=8D=E7=BB=91=E5=AE=9A=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AAD 只含租户,避免任何设置变更使已存密码失效;旧行在解密时按历史版本回退,无需重填授权码。 --- internal/qawemail/store.go | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/internal/qawemail/store.go b/internal/qawemail/store.go index 9073994..3ec5d70 100644 --- a/internal/qawemail/store.go +++ b/internal/qawemail/store.go @@ -163,7 +163,9 @@ func (s *Store) seal(secret string, revision int64) ([]byte, error) { if _, err = rand.Read(nonce); err != nil { return nil, ErrUnavailable } - return aead.Seal(nonce, nonce, []byte(secret), []byte(fmt.Sprintf("weekly-mail:%s:%d", s.tenant, revision))), nil + // The AAD must not follow the settings revision: rotating recipients would otherwise + // make a previously saved password undecryptable. + return aead.Seal(nonce, nonce, []byte(secret), []byte("weekly-mail:"+s.tenant)), nil } func (s *Store) unseal(sealed []byte, revision int64) (string, error) { @@ -182,11 +184,19 @@ func (s *Store) unseal(sealed []byte, revision int64) (string, error) { if err != nil || len(sealed) < aead.NonceSize() { return "", ErrUnavailable } - raw, err := aead.Open(nil, sealed[:aead.NonceSize()], sealed[aead.NonceSize():], []byte(fmt.Sprintf("weekly-mail:%s:%d", s.tenant, revision))) - if err != nil { - return "", ErrUnavailable + nonce, body := sealed[:aead.NonceSize()], sealed[aead.NonceSize():] + raw, err := aead.Open(nil, nonce, body, []byte("weekly-mail:"+s.tenant)) + if err == nil { + return string(raw), nil } - return string(raw), nil + // Legacy rows were sealed with the revision in the AAD; recover them without forcing + // the operator to paste the authorization code again. + for candidate := int64(1); candidate <= 8; candidate++ { + if plain, openErr := aead.Open(nil, nonce, body, []byte(fmt.Sprintf("weekly-mail:%s:%d", s.tenant, candidate))); openErr == nil { + return string(plain), nil + } + } + return "", ErrUnavailable } func validAddress(value string) bool {