package db import ( "database/sql" "path/filepath" "testing" "time" ) // TestSMIMEIdentityInsertWorksAfterLegacyColumnMigration reproduces a live bug: a DB // created before the S/MIME redesign (passphrase-wrapped key_ciphertext/key_nonce/ // key_salt, all NOT NULL) only ever got key_pem ADDed by migrateAddedColumns, never had // the old NOT-NULL columns removed — so CreateSMIMEIdentity (which only sets key_pem) // failed with "NOT NULL constraint failed: esrv_mailbox_smime_identities.key_ciphertext" // on any pre-existing installation, confirmed against a real user's database. func TestSMIMEIdentityInsertWorksAfterLegacyColumnMigration(t *testing.T) { path := filepath.Join(t.TempDir(), "test.db") raw, err := sql.Open("sqlite", path) if err != nil { t.Fatal(err) } if _, err := raw.Exec(` CREATE TABLE esrv_mailbox_smime_identities ( id INTEGER PRIMARY KEY AUTOINCREMENT, mailbox_id INTEGER NOT NULL, cert_pem TEXT NOT NULL, key_ciphertext BLOB NOT NULL, key_nonce BLOB NOT NULL, key_salt BLOB NOT NULL, not_after DATETIME NOT NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP ) `); err != nil { t.Fatal(err) } if err := raw.Close(); err != nil { t.Fatal(err) } database, err := Open(path) if err != nil { t.Fatal(err) } t.Cleanup(func() { database.Close() }) if _, err := database.CreateSMIMEIdentity(1, "cert-pem", "key-pem", time.Now().Add(365*24*time.Hour)); err != nil { t.Fatalf("CreateSMIMEIdentity after migrating a legacy DB: %v", err) } }