add MFA, user web mail portal

This commit is contained in:
2026-08-13 08:07:19 +01:00
parent 70c05cc777
commit bc4bbe6e56
38 changed files with 1072 additions and 59 deletions
+13 -2
View File
@@ -22,7 +22,8 @@ CREATE TABLE IF NOT EXISTS esrv_domains (
verification_token TEXT NOT NULL DEFAULT '',
is_verified INTEGER NOT NULL DEFAULT 0,
verified_at DATETIME,
default_mailbox_quota_bytes INTEGER NOT NULL DEFAULT 5368709120
default_mailbox_quota_bytes INTEGER NOT NULL DEFAULT 5368709120,
mfa_exempt INTEGER NOT NULL DEFAULT 0
);
CREATE TABLE IF NOT EXISTS esrv_senders (
@@ -119,6 +120,7 @@ CREATE TABLE IF NOT EXISTS esrv_admin_users (
username TEXT NOT NULL UNIQUE,
password_hash TEXT NOT NULL,
must_change_password INTEGER NOT NULL DEFAULT 0,
must_change_username INTEGER NOT NULL DEFAULT 0,
totp_secret TEXT NOT NULL DEFAULT '',
totp_enabled INTEGER NOT NULL DEFAULT 0,
is_global_admin INTEGER NOT NULL DEFAULT 0,
@@ -171,7 +173,8 @@ CREATE TABLE IF NOT EXISTS esrv_mailboxes (
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
created_by INTEGER REFERENCES esrv_admin_users(id),
totp_secret TEXT NOT NULL DEFAULT '',
totp_enabled INTEGER NOT NULL DEFAULT 0
totp_enabled INTEGER NOT NULL DEFAULT 0,
mfa_exempt INTEGER NOT NULL DEFAULT 0
);
-- Self-service webmail portal sessions — deliberately a parallel schema to
@@ -286,10 +289,18 @@ func migrateAddedColumns(db *sql.DB) {
`ALTER TABLE esrv_mailboxes ADD COLUMN totp_secret TEXT NOT NULL DEFAULT ''`,
`ALTER TABLE esrv_mailboxes ADD COLUMN totp_enabled INTEGER NOT NULL DEFAULT 0`,
`ALTER TABLE esrv_mailbox_app_passwords ADD COLUMN expires_at DATETIME`,
`ALTER TABLE esrv_admin_users ADD COLUMN must_change_username INTEGER NOT NULL DEFAULT 0`,
`ALTER TABLE esrv_domains ADD COLUMN mfa_exempt INTEGER NOT NULL DEFAULT 0`,
`ALTER TABLE esrv_mailboxes ADD COLUMN mfa_exempt INTEGER NOT NULL DEFAULT 0`,
}
for _, stmt := range stmts {
db.Exec(stmt)
}
// Backfill for installs that already have a still-pending default admin (username
// "admin", never completed the forced first-login yet): must_change_username
// defaults to 0 for every pre-existing row above, which would otherwise let that
// account skip its username change entirely once it re-hits /first-login next.
db.Exec(`UPDATE esrv_admin_users SET must_change_username = 1 WHERE username = ? AND must_change_password = 1`, DefaultAdminUsername)
}
// DB wraps *sql.DB with the query helpers below.