diff --git a/doc.go b/doc.go index 5549a26..cd87e2f 100644 --- a/doc.go +++ b/doc.go @@ -937,6 +937,8 @@ Remove an account and reload the configuration. Email addresses for this account will also be removed, and incoming email for these addresses will be rejected. +All data for the account will be removed. + usage: mox config account rm account # mox config address add diff --git a/main.go b/main.go index 5d6a7cf..e416697 100644 --- a/main.go +++ b/main.go @@ -890,6 +890,8 @@ func cmdConfigAccountRemove(c *cmd) { Email addresses for this account will also be removed, and incoming email for these addresses will be rejected. + +All data for the account will be removed. ` args := c.Parse() if len(args) != 1 { diff --git a/mox-/admin.go b/mox-/admin.go index db33420..d36cf44 100644 --- a/mox-/admin.go +++ b/mox-/admin.go @@ -1024,6 +1024,18 @@ func AccountRemove(ctx context.Context, account string) (rerr error) { if err := writeDynamic(ctx, log, nc); err != nil { return fmt.Errorf("writing domains.conf: %w", err) } + + odir := filepath.Join(DataDirPath("accounts"), account) + tmpdir := filepath.Join(DataDirPath("tmp"), "oldaccount-"+account) + if err := os.Rename(odir, tmpdir); err != nil { + log.Errorx("moving old account data directory out of the way", err, slog.String("account", account)) + return fmt.Errorf("account removed, but account data directory %q could not be moved out of the way: %v", odir, err) + } + if err := os.RemoveAll(tmpdir); err != nil { + log.Errorx("removing old account data directory", err, slog.String("account", account)) + return fmt.Errorf("account removed, its data directory moved to %q, but removing failed: %v", odir, err) + } + log.Info("account removed", slog.String("account", account)) return nil } diff --git a/webadmin/admin.js b/webadmin/admin.js index 147bffa..7a5cb42 100644 --- a/webadmin/admin.js +++ b/webadmin/admin.js @@ -2194,7 +2194,7 @@ const account = async (name) => { formPassword.reset(); }), dom.br(), RoutesEditor('account-specific', transports, config.Routes || [], async (routes) => await client.AccountRoutesSave(name, routes)), dom.br(), dom.h2('Danger'), dom.clickbutton('Remove account', async function click(e) { e.preventDefault(); - if (!window.confirm('Are you sure you want to remove this account?')) { + if (!window.confirm('Are you sure you want to remove this account? All account data, including messages will be removed.')) { return; } await check(e.target, client.AccountRemove(name)); diff --git a/webadmin/admin.ts b/webadmin/admin.ts index 8e62c26..1294af3 100644 --- a/webadmin/admin.ts +++ b/webadmin/admin.ts @@ -999,7 +999,7 @@ const account = async (name: string) => { dom.h2('Danger'), dom.clickbutton('Remove account', async function click(e: MouseEvent) { e.preventDefault() - if (!window.confirm('Are you sure you want to remove this account?')) { + if (!window.confirm('Are you sure you want to remove this account? All account data, including messages will be removed.')) { return } await check(e.target! as HTMLButtonElement, client.AccountRemove(name))