Added error 503 popup
This commit is contained in:
@@ -3,6 +3,7 @@ package handlers
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"projectreshoot/contexts"
|
||||
"projectreshoot/cookies"
|
||||
@@ -47,35 +48,41 @@ func HandleChangeUsername(
|
||||
) http.Handler {
|
||||
return http.HandlerFunc(
|
||||
func(w http.ResponseWriter, r *http.Request) {
|
||||
WithTransaction(w, r, logger, conn,
|
||||
func(ctx context.Context, tx *db.SafeTX, w http.ResponseWriter, r *http.Request) {
|
||||
r.ParseForm()
|
||||
newUsername := r.FormValue("username")
|
||||
unique, err := db.CheckUsernameUnique(ctx, tx, newUsername)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
logger.Error().Err(err).Msg("Error updating username")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
if !unique {
|
||||
tx.Rollback()
|
||||
account.ChangeUsername("Username is taken", newUsername).
|
||||
Render(r.Context(), w)
|
||||
return
|
||||
}
|
||||
user := contexts.GetUser(r.Context())
|
||||
err = user.ChangeUsername(ctx, tx, newUsername)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
logger.Error().Err(err).Msg("Error updating username")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
tx.Commit()
|
||||
w.Header().Set("HX-Refresh", "true")
|
||||
},
|
||||
)
|
||||
ctx, cancel := context.WithTimeout(r.Context(), 15*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// Start the transaction
|
||||
tx, err := conn.Begin(ctx)
|
||||
if err != nil {
|
||||
logger.Warn().Err(err).Msg("Error updating username")
|
||||
w.WriteHeader(http.StatusServiceUnavailable)
|
||||
return
|
||||
}
|
||||
r.ParseForm()
|
||||
newUsername := r.FormValue("username")
|
||||
unique, err := db.CheckUsernameUnique(ctx, tx, newUsername)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
logger.Error().Err(err).Msg("Error updating username")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
if !unique {
|
||||
tx.Rollback()
|
||||
account.ChangeUsername("Username is taken", newUsername).
|
||||
Render(r.Context(), w)
|
||||
return
|
||||
}
|
||||
user := contexts.GetUser(r.Context())
|
||||
err = user.ChangeUsername(ctx, tx, newUsername)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
logger.Error().Err(err).Msg("Error updating username")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
tx.Commit()
|
||||
w.Header().Set("HX-Refresh", "true")
|
||||
},
|
||||
)
|
||||
}
|
||||
@@ -87,29 +94,35 @@ func HandleChangeBio(
|
||||
) http.Handler {
|
||||
return http.HandlerFunc(
|
||||
func(w http.ResponseWriter, r *http.Request) {
|
||||
WithTransaction(w, r, logger, conn,
|
||||
func(ctx context.Context, tx *db.SafeTX, w http.ResponseWriter, r *http.Request) {
|
||||
r.ParseForm()
|
||||
newBio := r.FormValue("bio")
|
||||
leng := len([]rune(newBio))
|
||||
if leng > 128 {
|
||||
tx.Rollback()
|
||||
account.ChangeBio("Bio limited to 128 characters", newBio).
|
||||
Render(r.Context(), w)
|
||||
return
|
||||
}
|
||||
user := contexts.GetUser(r.Context())
|
||||
err := user.ChangeBio(ctx, tx, newBio)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
logger.Error().Err(err).Msg("Error updating bio")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
tx.Commit()
|
||||
w.Header().Set("HX-Refresh", "true")
|
||||
},
|
||||
)
|
||||
ctx, cancel := context.WithTimeout(r.Context(), 15*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// Start the transaction
|
||||
tx, err := conn.Begin(ctx)
|
||||
if err != nil {
|
||||
logger.Warn().Err(err).Msg("Error updating bio")
|
||||
w.WriteHeader(http.StatusServiceUnavailable)
|
||||
return
|
||||
}
|
||||
r.ParseForm()
|
||||
newBio := r.FormValue("bio")
|
||||
leng := len([]rune(newBio))
|
||||
if leng > 128 {
|
||||
tx.Rollback()
|
||||
account.ChangeBio("Bio limited to 128 characters", newBio).
|
||||
Render(r.Context(), w)
|
||||
return
|
||||
}
|
||||
user := contexts.GetUser(r.Context())
|
||||
err = user.ChangeBio(ctx, tx, newBio)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
logger.Error().Err(err).Msg("Error updating bio")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
tx.Commit()
|
||||
w.Header().Set("HX-Refresh", "true")
|
||||
},
|
||||
)
|
||||
}
|
||||
@@ -137,26 +150,32 @@ func HandleChangePassword(
|
||||
) http.Handler {
|
||||
return http.HandlerFunc(
|
||||
func(w http.ResponseWriter, r *http.Request) {
|
||||
WithTransaction(w, r, logger, conn,
|
||||
func(ctx context.Context, tx *db.SafeTX, w http.ResponseWriter, r *http.Request) {
|
||||
newPass, err := validateChangePassword(ctx, tx, r)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
account.ChangePassword(err.Error()).Render(r.Context(), w)
|
||||
return
|
||||
}
|
||||
user := contexts.GetUser(r.Context())
|
||||
err = user.SetPassword(ctx, tx, newPass)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
logger.Error().Err(err).Msg("Error updating password")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
tx.Commit()
|
||||
w.Header().Set("HX-Refresh", "true")
|
||||
},
|
||||
)
|
||||
ctx, cancel := context.WithTimeout(r.Context(), 15*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// Start the transaction
|
||||
tx, err := conn.Begin(ctx)
|
||||
if err != nil {
|
||||
logger.Warn().Err(err).Msg("Error updating password")
|
||||
w.WriteHeader(http.StatusServiceUnavailable)
|
||||
return
|
||||
}
|
||||
newPass, err := validateChangePassword(ctx, tx, r)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
account.ChangePassword(err.Error()).Render(r.Context(), w)
|
||||
return
|
||||
}
|
||||
user := contexts.GetUser(r.Context())
|
||||
err = user.SetPassword(ctx, tx, newPass)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
logger.Error().Err(err).Msg("Error updating password")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
tx.Commit()
|
||||
w.Header().Set("HX-Refresh", "true")
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package handlers
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"projectreshoot/config"
|
||||
"projectreshoot/cookies"
|
||||
@@ -55,34 +56,41 @@ func HandleLoginRequest(
|
||||
) http.Handler {
|
||||
return http.HandlerFunc(
|
||||
func(w http.ResponseWriter, r *http.Request) {
|
||||
WithTransaction(w, r, logger, conn,
|
||||
func(ctx context.Context, tx *db.SafeTX, w http.ResponseWriter, r *http.Request) {
|
||||
r.ParseForm()
|
||||
user, err := validateLogin(ctx, tx, r)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
if err.Error() != "Username or password incorrect" {
|
||||
logger.Warn().Caller().Err(err).Msg("Login request failed")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
} else {
|
||||
form.LoginForm(err.Error()).Render(r.Context(), w)
|
||||
}
|
||||
return
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(r.Context(), 15*time.Second)
|
||||
defer cancel()
|
||||
|
||||
rememberMe := checkRememberMe(r)
|
||||
err = cookies.SetTokenCookies(w, r, config, user, true, rememberMe)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
logger.Warn().Caller().Err(err).Msg("Failed to set token cookies")
|
||||
return
|
||||
}
|
||||
// Start the transaction
|
||||
tx, err := conn.Begin(ctx)
|
||||
if err != nil {
|
||||
logger.Warn().Err(err).Msg("Failed to set token cookies")
|
||||
w.WriteHeader(http.StatusServiceUnavailable)
|
||||
return
|
||||
}
|
||||
r.ParseForm()
|
||||
user, err := validateLogin(ctx, tx, r)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
if err.Error() != "Username or password incorrect" {
|
||||
logger.Warn().Caller().Err(err).Msg("Login request failed")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
} else {
|
||||
form.LoginForm(err.Error()).Render(r.Context(), w)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
tx.Commit()
|
||||
pageFrom := cookies.CheckPageFrom(w, r)
|
||||
w.Header().Set("HX-Redirect", pageFrom)
|
||||
})
|
||||
rememberMe := checkRememberMe(r)
|
||||
err = cookies.SetTokenCookies(w, r, config, user, true, rememberMe)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
logger.Warn().Caller().Err(err).Msg("Failed to set token cookies")
|
||||
return
|
||||
}
|
||||
|
||||
tx.Commit()
|
||||
pageFrom := cookies.CheckPageFrom(w, r)
|
||||
w.Header().Set("HX-Redirect", pageFrom)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"projectreshoot/config"
|
||||
"projectreshoot/cookies"
|
||||
@@ -86,20 +87,27 @@ func HandleLogout(
|
||||
) http.Handler {
|
||||
return http.HandlerFunc(
|
||||
func(w http.ResponseWriter, r *http.Request) {
|
||||
WithTransaction(w, r, logger, conn,
|
||||
func(ctx context.Context, tx *db.SafeTX, w http.ResponseWriter, r *http.Request) {
|
||||
err := revokeTokens(config, ctx, tx, r)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
logger.Error().Err(err).Msg("Error occured on user logout")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
tx.Commit()
|
||||
cookies.DeleteCookie(w, "access", "/")
|
||||
cookies.DeleteCookie(w, "refresh", "/")
|
||||
w.Header().Set("HX-Redirect", "/login")
|
||||
})
|
||||
ctx, cancel := context.WithTimeout(r.Context(), 15*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// Start the transaction
|
||||
tx, err := conn.Begin(ctx)
|
||||
if err != nil {
|
||||
logger.Warn().Err(err).Msg("Error occured on user logout")
|
||||
w.WriteHeader(http.StatusServiceUnavailable)
|
||||
return
|
||||
}
|
||||
err = revokeTokens(config, ctx, tx, r)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
logger.Error().Err(err).Msg("Error occured on user logout")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
tx.Commit()
|
||||
cookies.DeleteCookie(w, "access", "/")
|
||||
cookies.DeleteCookie(w, "refresh", "/")
|
||||
w.Header().Set("HX-Redirect", "/login")
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package handlers
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"projectreshoot/config"
|
||||
"projectreshoot/contexts"
|
||||
@@ -105,25 +106,32 @@ func HandleReauthenticate(
|
||||
) http.Handler {
|
||||
return http.HandlerFunc(
|
||||
func(w http.ResponseWriter, r *http.Request) {
|
||||
WithTransaction(w, r, logger, conn,
|
||||
func(ctx context.Context, tx *db.SafeTX, w http.ResponseWriter, r *http.Request) {
|
||||
err := validatePassword(r)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
w.WriteHeader(445)
|
||||
form.ConfirmPassword("Incorrect password").Render(r.Context(), w)
|
||||
return
|
||||
}
|
||||
err = refreshTokens(config, ctx, tx, w, r)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
logger.Error().Err(err).Msg("Failed to refresh user tokens")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
tx.Commit()
|
||||
w.WriteHeader(http.StatusOK)
|
||||
})
|
||||
ctx, cancel := context.WithTimeout(r.Context(), 15*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// Start the transaction
|
||||
tx, err := conn.Begin(ctx)
|
||||
if err != nil {
|
||||
logger.Warn().Err(err).Msg("Failed to refresh user tokens")
|
||||
w.WriteHeader(http.StatusServiceUnavailable)
|
||||
return
|
||||
}
|
||||
err = validatePassword(r)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
w.WriteHeader(445)
|
||||
form.ConfirmPassword("Incorrect password").Render(r.Context(), w)
|
||||
return
|
||||
}
|
||||
err = refreshTokens(config, ctx, tx, w, r)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
logger.Error().Err(err).Msg("Failed to refresh user tokens")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
tx.Commit()
|
||||
w.WriteHeader(http.StatusOK)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package handlers
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"projectreshoot/config"
|
||||
"projectreshoot/cookies"
|
||||
@@ -50,36 +51,42 @@ func HandleRegisterRequest(
|
||||
) http.Handler {
|
||||
return http.HandlerFunc(
|
||||
func(w http.ResponseWriter, r *http.Request) {
|
||||
WithTransaction(w, r, logger, conn,
|
||||
func(ctx context.Context, tx *db.SafeTX, w http.ResponseWriter, r *http.Request) {
|
||||
r.ParseForm()
|
||||
user, err := validateRegistration(ctx, tx, r)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
if err.Error() != "Username is taken" &&
|
||||
err.Error() != "Passwords do not match" &&
|
||||
err.Error() != "Password exceeds maximum length of 72 bytes" {
|
||||
logger.Warn().Caller().Err(err).Msg("Registration request failed")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
} else {
|
||||
form.RegisterForm(err.Error()).Render(r.Context(), w)
|
||||
}
|
||||
return
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(r.Context(), 15*time.Second)
|
||||
defer cancel()
|
||||
|
||||
rememberMe := checkRememberMe(r)
|
||||
err = cookies.SetTokenCookies(w, r, config, user, true, rememberMe)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
logger.Warn().Caller().Err(err).Msg("Failed to set token cookies")
|
||||
return
|
||||
}
|
||||
tx.Commit()
|
||||
pageFrom := cookies.CheckPageFrom(w, r)
|
||||
w.Header().Set("HX-Redirect", pageFrom)
|
||||
},
|
||||
)
|
||||
// Start the transaction
|
||||
tx, err := conn.Begin(ctx)
|
||||
if err != nil {
|
||||
logger.Warn().Err(err).Msg("Failed to set token cookies")
|
||||
w.WriteHeader(http.StatusServiceUnavailable)
|
||||
return
|
||||
}
|
||||
r.ParseForm()
|
||||
user, err := validateRegistration(ctx, tx, r)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
if err.Error() != "Username is taken" &&
|
||||
err.Error() != "Passwords do not match" &&
|
||||
err.Error() != "Password exceeds maximum length of 72 bytes" {
|
||||
logger.Warn().Caller().Err(err).Msg("Registration request failed")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
} else {
|
||||
form.RegisterForm(err.Error()).Render(r.Context(), w)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
rememberMe := checkRememberMe(r)
|
||||
err = cookies.SetTokenCookies(w, r, config, user, true, rememberMe)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
logger.Warn().Caller().Err(err).Msg("Failed to set token cookies")
|
||||
return
|
||||
}
|
||||
tx.Commit()
|
||||
pageFrom := cookies.CheckPageFrom(w, r)
|
||||
w.Header().Set("HX-Redirect", pageFrom)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -6,12 +6,11 @@ import (
|
||||
"time"
|
||||
|
||||
"projectreshoot/db"
|
||||
"projectreshoot/view/page"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
func WithTransaction(
|
||||
func removeme(
|
||||
w http.ResponseWriter,
|
||||
r *http.Request,
|
||||
logger *zerolog.Logger,
|
||||
@@ -22,6 +21,7 @@ func WithTransaction(
|
||||
w http.ResponseWriter,
|
||||
r *http.Request,
|
||||
),
|
||||
onfail func(err error),
|
||||
) {
|
||||
ctx, cancel := context.WithTimeout(r.Context(), 15*time.Second)
|
||||
defer cancel()
|
||||
@@ -29,13 +29,7 @@ func WithTransaction(
|
||||
// Start the transaction
|
||||
tx, err := conn.Begin(ctx)
|
||||
if err != nil {
|
||||
logger.Warn().Err(err).Msg("Request failed to start a transaction")
|
||||
w.WriteHeader(http.StatusServiceUnavailable)
|
||||
page.Error(
|
||||
"503",
|
||||
http.StatusText(503),
|
||||
"This service is currently unavailable. It could be down for maintenance").
|
||||
Render(r.Context(), w)
|
||||
onfail(err)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user