feat: add upload policies, daily limits, and storage quotas
All checks were successful
Build and Publish Docker Image / deploy (push) Successful in 1m8s
All checks were successful
Build and Publish Docker Image / deploy (push) Successful in 1m8s
- Add environment variables to configure anonymous uploads, daily upload caps, and default user storage limits. - Update config loader to parse and validate the new settings. - Implement backend logic to track daily usage and active storage per user. - Update README and `.env.example` to document the new settings and admin panels.
This commit is contained in:
@@ -29,17 +29,17 @@ func (a *App) Register(w http.ResponseWriter, r *http.Request) {
|
||||
http.Redirect(w, r, "/login", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
a.renderAuth(w, http.StatusOK, authPageData{Mode: "register"})
|
||||
a.renderAuth(w, r, http.StatusOK, authPageData{Mode: "register"})
|
||||
}
|
||||
|
||||
func (a *App) RegisterPost(w http.ResponseWriter, r *http.Request) {
|
||||
if err := r.ParseForm(); err != nil {
|
||||
a.renderAuth(w, http.StatusBadRequest, authPageData{Mode: "register", Error: "Unable to read form."})
|
||||
a.renderAuth(w, r, http.StatusBadRequest, authPageData{Mode: "register", Error: "Unable to read form."})
|
||||
return
|
||||
}
|
||||
user, err := a.authService.CreateBootstrapUser(r.FormValue("username"), r.FormValue("email"), r.FormValue("password"))
|
||||
if err != nil {
|
||||
a.renderAuth(w, http.StatusBadRequest, authPageData{Mode: "register", Error: err.Error()})
|
||||
a.renderAuth(w, r, http.StatusBadRequest, authPageData{Mode: "register", Error: err.Error()})
|
||||
return
|
||||
}
|
||||
a.logger.Info("first admin created", "source", "auth", "severity", "user_activity", "code", 2401, "user_id", user.ID)
|
||||
@@ -51,12 +51,12 @@ func (a *App) Login(w http.ResponseWriter, r *http.Request) {
|
||||
http.Redirect(w, r, "/app", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
a.renderAuth(w, http.StatusOK, authPageData{Mode: "login", ReturnPath: r.URL.Query().Get("next")})
|
||||
a.renderAuth(w, r, http.StatusOK, authPageData{Mode: "login", ReturnPath: r.URL.Query().Get("next")})
|
||||
}
|
||||
|
||||
func (a *App) LoginPost(w http.ResponseWriter, r *http.Request) {
|
||||
if err := r.ParseForm(); err != nil {
|
||||
a.renderAuth(w, http.StatusBadRequest, authPageData{Mode: "login", Error: "Unable to read form."})
|
||||
a.renderAuth(w, r, http.StatusBadRequest, authPageData{Mode: "login", Error: "Unable to read form."})
|
||||
return
|
||||
}
|
||||
next := r.FormValue("next")
|
||||
@@ -66,7 +66,7 @@ func (a *App) LoginPost(w http.ResponseWriter, r *http.Request) {
|
||||
user, token, err := a.authService.Login(r.FormValue("email"), r.FormValue("password"))
|
||||
if err != nil {
|
||||
a.logger.Warn("login failed", "source", "auth", "severity", "warn", "code", 4401, "email", r.FormValue("email"))
|
||||
a.renderAuth(w, http.StatusUnauthorized, authPageData{Mode: "login", Error: "Invalid email or password.", ReturnPath: next})
|
||||
a.renderAuth(w, r, http.StatusUnauthorized, authPageData{Mode: "login", Error: "Invalid email or password.", ReturnPath: next})
|
||||
return
|
||||
}
|
||||
a.setUserSessionCookie(w, r, token)
|
||||
@@ -85,26 +85,26 @@ func (a *App) Logout(w http.ResponseWriter, r *http.Request) {
|
||||
func (a *App) Invite(w http.ResponseWriter, r *http.Request) {
|
||||
invite, err := a.authService.InviteByToken(r.PathValue("token"))
|
||||
if err != nil || invite.UsedAt != nil || time.Now().UTC().After(invite.ExpiresAt) {
|
||||
a.renderAuth(w, http.StatusNotFound, authPageData{Mode: "invite", Error: "This invite is invalid or expired."})
|
||||
a.renderAuth(w, r, http.StatusNotFound, authPageData{Mode: "invite", Error: "This invite is invalid or expired."})
|
||||
return
|
||||
}
|
||||
a.renderAuth(w, http.StatusOK, authPageData{Mode: "invite", Token: r.PathValue("token"), Email: invite.Email, IsReset: invite.UserID != ""})
|
||||
a.renderAuth(w, r, http.StatusOK, authPageData{Mode: "invite", Token: r.PathValue("token"), Email: invite.Email, IsReset: invite.UserID != ""})
|
||||
}
|
||||
|
||||
func (a *App) InvitePost(w http.ResponseWriter, r *http.Request) {
|
||||
token := r.PathValue("token")
|
||||
invite, err := a.authService.InviteByToken(token)
|
||||
if err != nil {
|
||||
a.renderAuth(w, http.StatusNotFound, authPageData{Mode: "invite", Error: "This invite is invalid or expired."})
|
||||
a.renderAuth(w, r, http.StatusNotFound, authPageData{Mode: "invite", Error: "This invite is invalid or expired."})
|
||||
return
|
||||
}
|
||||
if err := r.ParseForm(); err != nil {
|
||||
a.renderAuth(w, http.StatusBadRequest, authPageData{Mode: "invite", Token: token, Email: invite.Email, IsReset: invite.UserID != "", Error: "Unable to read form."})
|
||||
a.renderAuth(w, r, http.StatusBadRequest, authPageData{Mode: "invite", Token: token, Email: invite.Email, IsReset: invite.UserID != "", Error: "Unable to read form."})
|
||||
return
|
||||
}
|
||||
user, err := a.authService.AcceptInvite(token, r.FormValue("username"), r.FormValue("password"))
|
||||
if err != nil {
|
||||
a.renderAuth(w, http.StatusBadRequest, authPageData{Mode: "invite", Token: token, Email: invite.Email, IsReset: invite.UserID != "", Error: err.Error()})
|
||||
a.renderAuth(w, r, http.StatusBadRequest, authPageData{Mode: "invite", Token: token, Email: invite.Email, IsReset: invite.UserID != "", Error: err.Error()})
|
||||
return
|
||||
}
|
||||
a.logger.Info("invite accepted", "source", "auth", "severity", "user_activity", "code", 2403, "user_id", user.ID)
|
||||
@@ -116,7 +116,7 @@ func (a *App) AccountSettings(w http.ResponseWriter, r *http.Request) {
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
a.renderer.Render(w, http.StatusOK, "account.html", web.PageData{
|
||||
a.renderPage(w, r, http.StatusOK, "account.html", web.PageData{
|
||||
Title: "Account settings",
|
||||
Description: "Manage your Warpbox account.",
|
||||
CurrentUser: a.authService.PublicUser(user),
|
||||
@@ -144,8 +144,8 @@ func (a *App) ChangePassword(w http.ResponseWriter, r *http.Request) {
|
||||
http.Redirect(w, r, "/account/settings", http.StatusSeeOther)
|
||||
}
|
||||
|
||||
func (a *App) renderAuth(w http.ResponseWriter, status int, data authPageData) {
|
||||
a.renderer.Render(w, status, "auth.html", web.PageData{
|
||||
func (a *App) renderAuth(w http.ResponseWriter, r *http.Request, status int, data authPageData) {
|
||||
a.renderPage(w, r, status, "auth.html", web.PageData{
|
||||
Title: "Account",
|
||||
Description: "Sign in to Warpbox.",
|
||||
Data: data,
|
||||
|
||||
Reference in New Issue
Block a user