updated mailbox app password
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
package webui
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"mailgoserver/internal/db"
|
||||
)
|
||||
@@ -18,12 +20,50 @@ func (a *App) appPasswordsList(w http.ResponseWriter, r *http.Request) {
|
||||
if err != nil {
|
||||
setFlash(w, "error", "Error loading app passwords")
|
||||
}
|
||||
a.render(w, r, "mailbox_apppasswords.html", M{"active": "mailboxes", "mailbox": mailbox, "passwords": passwords})
|
||||
a.render(w, r, "mailbox_apppasswords.html", M{
|
||||
"active": "mailboxes", "mailbox": mailbox, "passwords": passwords,
|
||||
"reveal": popAppPasswordReveal(w, r),
|
||||
})
|
||||
}
|
||||
|
||||
// appPasswordExpiry turns the create form's preset select (plus an optional custom
|
||||
// date) into an expiry timestamp. Returns (nil, nil) for "never expires", the default.
|
||||
func appPasswordExpiry(preset, customDate string, loc *time.Location) (*time.Time, error) {
|
||||
now := time.Now()
|
||||
var t time.Time
|
||||
switch preset {
|
||||
case "", "never":
|
||||
return nil, nil
|
||||
case "1d":
|
||||
t = now.Add(24 * time.Hour)
|
||||
case "7d":
|
||||
t = now.Add(7 * 24 * time.Hour)
|
||||
case "30d":
|
||||
t = now.Add(30 * 24 * time.Hour)
|
||||
case "180d":
|
||||
t = now.Add(180 * 24 * time.Hour)
|
||||
case "365d":
|
||||
t = now.Add(365 * 24 * time.Hour)
|
||||
case "custom":
|
||||
if customDate == "" {
|
||||
return nil, fmt.Errorf("an expiration date is required")
|
||||
}
|
||||
d, err := time.ParseInLocation("2006-01-02", customDate, loc)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid expiration date")
|
||||
}
|
||||
// End of the chosen day, not midnight at its start, so the picked date is
|
||||
// still valid for its whole duration.
|
||||
t = d.Add(24*time.Hour - time.Second)
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid expiration option")
|
||||
}
|
||||
return &t, nil
|
||||
}
|
||||
|
||||
// addAppPassword generates a random secret (the only credential IMAP/SMTP clients ever
|
||||
// use for this mailbox — never the portal password), shows it once via flash, and
|
||||
// stores only its bcrypt hash.
|
||||
// use for this mailbox — never the portal password), reveals it once via a one-time
|
||||
// cookie the list page renders as a modal, and stores only its bcrypt hash.
|
||||
func (a *App) addAppPassword(w http.ResponseWriter, r *http.Request) {
|
||||
mailbox, ok := a.mailboxWithAccess(w, r)
|
||||
if !ok {
|
||||
@@ -34,6 +74,18 @@ func (a *App) addAppPassword(w http.ResponseWriter, r *http.Request) {
|
||||
label = "App password"
|
||||
}
|
||||
|
||||
tzName := a.Cfg.Section("Server").Key("time_zone").MustString("UTC")
|
||||
loc, err := time.LoadLocation(tzName)
|
||||
if err != nil {
|
||||
loc = time.UTC
|
||||
}
|
||||
expiresAt, err := appPasswordExpiry(r.FormValue("expires_preset"), r.FormValue("expires_custom"), loc)
|
||||
if err != nil {
|
||||
setFlash(w, "error", err.Error())
|
||||
http.Redirect(w, r, Prefix+"/mailboxes/"+idStr(r)+"/apppasswords", http.StatusFound)
|
||||
return
|
||||
}
|
||||
|
||||
minLen := a.Cfg.Section("Mailstore").Key("app_password_min_length").MustInt(25)
|
||||
secret := db.GenerateAppPassword(minLen)
|
||||
hash, err := db.HashPassword(secret)
|
||||
@@ -42,12 +94,12 @@ func (a *App) addAppPassword(w http.ResponseWriter, r *http.Request) {
|
||||
http.Redirect(w, r, Prefix+"/mailboxes/"+idStr(r)+"/apppasswords", http.StatusFound)
|
||||
return
|
||||
}
|
||||
if _, err := a.DB.CreateAppPassword(mailbox.ID, label, hash); err != nil {
|
||||
if _, err := a.DB.CreateAppPassword(mailbox.ID, label, hash, expiresAt); err != nil {
|
||||
setFlash(w, "error", "Error creating app password")
|
||||
http.Redirect(w, r, Prefix+"/mailboxes/"+idStr(r)+"/apppasswords", http.StatusFound)
|
||||
return
|
||||
}
|
||||
setFlash(w, "success", "App password created — copy it now, it will not be shown again: "+secret)
|
||||
setAppPasswordReveal(w, label, secret)
|
||||
http.Redirect(w, r, Prefix+"/mailboxes/"+idStr(r)+"/apppasswords", http.StatusFound)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user