feat(PROJ-70): Self-Service IMAP-Rückholung (Backend)
Neuer Opt-in-Endpunkt, mit dem User archivierte Mails per IMAP APPEND
zurück in ihr eigenes externes Postfach (INBOX) kopieren können. Das
Archiv selbst bleibt read-only (nur storage.Load(), kein Schreibzugriff
auf internal/imapserver).
- PATCH /api/auth/imap-restore: Opt-in-Flag umschalten, Aktivierung
erfordert Passwort-Reverifikation.
- POST /api/mails/{id}/restore: lädt Mail lesend, prüft Mail- und
Account-Ownership in restoreAccessAllowed() (PROJ-61-Muster), APPEND
via neuer internal/imap/append.go, kein Admin-Override.
- Audit-Log-Eintrag (EventRestore) pro Versuch, erfolgreich und
fehlgeschlagen.
- imap_restore_enabled-Spalte (default false) via idempotenter
initSchema-Migration.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
7aa63e30ca
commit
da79a56b3e
@@ -144,9 +144,38 @@ func (s *Store) initSchema(ctx context.Context) error {
|
||||
_, err = s.pool.Exec(ctx, `
|
||||
ALTER TABLE users ADD COLUMN IF NOT EXISTS tokens_valid_after TIMESTAMPTZ;
|
||||
`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// PROJ-70: Opt-in-Flag für die Self-Service-IMAP-Rückholung (Archiv-Mail zurück
|
||||
// ins eigene Postfach). Default false — der Nutzer muss die Funktion selbst per
|
||||
// Schieberegler mit Passwort-Bestätigung freischalten.
|
||||
_, err = s.pool.Exec(ctx, `
|
||||
ALTER TABLE users ADD COLUMN IF NOT EXISTS imap_restore_enabled BOOLEAN NOT NULL DEFAULT false;
|
||||
`)
|
||||
return err
|
||||
}
|
||||
|
||||
// GetRestoreEnabled reports whether the user has opted in to the self-service
|
||||
// IMAP restore feature (PROJ-70).
|
||||
func (s *Store) GetRestoreEnabled(ctx context.Context, userID int64) (bool, error) {
|
||||
var enabled bool
|
||||
err := s.pool.QueryRow(ctx, `SELECT imap_restore_enabled FROM users WHERE id = $1`, userID).Scan(&enabled)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("userstore: get restore enabled: %w", err)
|
||||
}
|
||||
return enabled, nil
|
||||
}
|
||||
|
||||
// SetRestoreEnabled toggles the self-service IMAP restore opt-in flag (PROJ-70).
|
||||
func (s *Store) SetRestoreEnabled(ctx context.Context, userID int64, enabled bool) error {
|
||||
_, err := s.pool.Exec(ctx, `UPDATE users SET imap_restore_enabled = $1 WHERE id = $2`, enabled, userID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("userstore: set restore enabled: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Close closes the underlying connection pool.
|
||||
func (s *Store) Close() error {
|
||||
s.pool.Close()
|
||||
|
||||
Reference in New Issue
Block a user