summaryrefslogtreecommitdiff
path: root/handlers
diff options
context:
space:
mode:
Diffstat (limited to 'handlers')
-rw-r--r--handlers/admin.go19
-rw-r--r--handlers/auth_login.go11
-rw-r--r--handlers/auth_token.go8
-rw-r--r--handlers/php_proxy.go2
-rw-r--r--handlers/user.go22
5 files changed, 22 insertions, 40 deletions
diff --git a/handlers/admin.go b/handlers/admin.go
index 8413ac9..a568ac5 100644
--- a/handlers/admin.go
+++ b/handlers/admin.go
@@ -11,7 +11,6 @@ import (
"encoding/json"
"fmt"
"net/http"
- "strconv"
"sync"
"time"
)
@@ -43,8 +42,6 @@ func AdminPageHandler(w http.ResponseWriter, r *http.Request) {
}
}
-
-
// GetUsersHandler returns a list of all users with enriched information.
// It uses a worker pool to calculate extra information for each user in parallel.
func GetUsersHandler(w http.ResponseWriter, r *http.Request) {
@@ -71,8 +68,8 @@ func GetUsersHandler(w http.ResponseWriter, r *http.Request) {
time.Sleep(5 * time.Millisecond)
timeSinceLogin := "N/A"
- if userCopy.LastLoginAt.Valid {
- timeSinceLogin = fmt.Sprintf("%.0fm ago", time.Since(userCopy.LastLoginAt.Time).Minutes())
+ if userCopy.LastLoginAt != nil {
+ timeSinceLogin = fmt.Sprintf("%.0fm ago", time.Since(*userCopy.LastLoginAt).Minutes())
}
enrichedUsers[index] = types.EnrichedUser{
@@ -103,8 +100,8 @@ func UpdateUserRoleHandler(w http.ResponseWriter, r *http.Request) {
}
adminUsername := adminUser.Username
- id, err := strconv.ParseInt(r.URL.Path[len(config.Paths.AdminUsersAPI+"/"):len(r.URL.Path)-len("/role")], 10, 64)
- if err != nil {
+ id := r.URL.Path[len(config.Paths.AdminUsersAPI+"/") : len(r.URL.Path)-len("/role")]
+ if id == "" {
logging.AppLog.Warn("Invalid user ID in request", "path", r.URL.Path, "ip", ip)
http.Error(w, "Invalid user ID", http.StatusBadRequest)
return
@@ -148,8 +145,8 @@ func DeleteUserHandler(w http.ResponseWriter, r *http.Request) {
}
adminUsername := adminUser.Username
- id, err := strconv.ParseInt(r.URL.Path[len(config.Paths.AdminUsersAPI+"/"):], 10, 64)
- if err != nil {
+ id := r.URL.Path[len(config.Paths.AdminUsersAPI+"/"):]
+ if id == "" {
logging.AppLog.Warn("Invalid user ID in request", "path", r.URL.Path, "ip", ip)
http.Error(w, "Invalid user ID", http.StatusBadRequest)
return
@@ -177,8 +174,8 @@ func SetUserActiveStatusHandler(w http.ResponseWriter, r *http.Request) {
}
adminUsername := adminUser.Username
- id, err := strconv.ParseInt(r.URL.Path[len(config.Paths.AdminUsersAPI+"/"):len(r.URL.Path)-len("/status")], 10, 64)
- if err != nil {
+ id := r.URL.Path[len(config.Paths.AdminUsersAPI+"/") : len(r.URL.Path)-len("/status")]
+ if id == "" {
logging.AppLog.Warn("Invalid user ID in request", "path", r.URL.Path, "ip", ip)
http.Error(w, "Invalid user ID", http.StatusBadRequest)
return
diff --git a/handlers/auth_login.go b/handlers/auth_login.go
index 33a3482..b0a288a 100644
--- a/handlers/auth_login.go
+++ b/handlers/auth_login.go
@@ -50,8 +50,8 @@ func authenticateUser(username, password, ip string) (*types.User, error) {
}
}
- // Step 2: If the account is active, validate credentials.
- if !models.CheckPasswordHash(password, user.PasswordHash) {
+ // Step 2: If the account is active, validate credentials against PocketBase.
+ if _, err := models.AuthenticateWithPassword(username, password); err != nil {
// Record the failure
if err := models.RecordLoginFailure(user.ID); err != nil {
logging.AppLog.Error("Failed to record login failure", "error", err, "user_id", user.ID, "ip", ip)
@@ -62,7 +62,7 @@ func authenticateUser(username, password, ip string) (*types.User, error) {
maxAttempts := config.Paths.MaxLoginAttempts
// Lock the account if max attempts are exceeded
- if maxAttempts > 0 && updatedUser.FailedLogins >= maxAttempts {
+ if updatedUser != nil && maxAttempts > 0 && updatedUser.FailedLogins >= maxAttempts {
if err := models.SetUserActiveStatus(user.ID, false); err != nil {
logging.AppLog.Error("Failed to lock account", "error", err, "user_id", user.ID, "ip", ip)
}
@@ -77,6 +77,9 @@ func authenticateUser(username, password, ip string) (*types.User, error) {
if err := models.RecordLoginSuccess(user.ID); err != nil {
logging.AppLog.Error("Failed to record login success", "error", err, "user_id", user.ID, "ip", ip)
}
+ if refreshedUser, refreshErr := models.GetUserByID(user.ID); refreshErr == nil && refreshedUser != nil {
+ user = refreshedUser
+ }
logging.SecurityLog.Info("AUTH SUCCESS", "username", user.Username, "ip", ip)
return user, nil
@@ -148,7 +151,7 @@ func LoginHandler(w http.ResponseWriter, r *http.Request) {
// --- Create Session Cookie ---
duration := time.Duration(config.Paths.TokenDurationHours) * time.Hour
- token, err := models.CreateAuthToken(user.ID, duration)
+ token, err := models.CreateAuthToken(user, duration)
if err != nil {
logging.AppLog.Error("Failed to create auth token", "error", err, "username", user.Username, "ip", ip)
renderLoginWithError(w, r, "Could not create session.")
diff --git a/handlers/auth_token.go b/handlers/auth_token.go
index 7ea7ef6..a35a23b 100644
--- a/handlers/auth_token.go
+++ b/handlers/auth_token.go
@@ -49,7 +49,7 @@ func RefreshTokenHandler(w http.ResponseWriter, r *http.Request) {
}
// 4. Issue a new access token
- newAccessToken, err := utils.GenerateJWT(user, time.Duration(config.Paths.AccessTokenDurationMinutes)*time.Minute)
+ newAccessToken, err := utils.GenerateJWT(user, time.Duration(config.Paths.AccessTokenDurationMinutes)*time.Minute, "access")
if err != nil {
logging.AppLog.Error("Failed to generate new access token", "error", err, "username", user.Username, "ip", ip)
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
@@ -64,7 +64,7 @@ func RefreshTokenHandler(w http.ResponseWriter, r *http.Request) {
}
// 6. Issue a new refresh token
- newRefreshToken, err := models.CreateRefreshToken(user.ID, time.Duration(config.Paths.RefreshTokenDurationDays)*24*time.Hour)
+ newRefreshToken, err := models.CreateRefreshToken(user, time.Duration(config.Paths.RefreshTokenDurationDays)*24*time.Hour)
if err != nil {
logging.AppLog.Error("Failed to create new refresh token", "error", err, "username", user.Username, "ip", ip)
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
@@ -111,7 +111,7 @@ func TokenHandler(w http.ResponseWriter, r *http.Request) {
// --- Issue Tokens ---
// Access Token
- accessToken, err := utils.GenerateJWT(user, time.Duration(config.Paths.AccessTokenDurationMinutes)*time.Minute)
+ accessToken, err := utils.GenerateJWT(user, time.Duration(config.Paths.AccessTokenDurationMinutes)*time.Minute, "access")
if err != nil {
logging.AppLog.Error("Failed to generate access token", "error", err, "username", user.Username, "ip", ip)
http.Error(w, "Failed to generate access token", http.StatusInternalServerError)
@@ -119,7 +119,7 @@ func TokenHandler(w http.ResponseWriter, r *http.Request) {
}
// Refresh Token
- refreshToken, err := models.CreateRefreshToken(user.ID, time.Duration(config.Paths.RefreshTokenDurationDays)*24*time.Hour)
+ refreshToken, err := models.CreateRefreshToken(user, time.Duration(config.Paths.RefreshTokenDurationDays)*24*time.Hour)
if err != nil {
logging.AppLog.Error("Failed to create refresh token", "error", err, "username", user.Username, "ip", ip)
http.Error(w, "Failed to create refresh token", http.StatusInternalServerError)
diff --git a/handlers/php_proxy.go b/handlers/php_proxy.go
index 3c6c597..1a394f7 100644
--- a/handlers/php_proxy.go
+++ b/handlers/php_proxy.go
@@ -143,4 +143,4 @@ func NewPhpProxyHandler(scriptName string) http.Handler {
logging.AppLog.Error("Failed to copy response body from PHP-FPM", "error", err)
}
})
-} \ No newline at end of file
+}
diff --git a/handlers/user.go b/handlers/user.go
index 65ebe83..ad68f6f 100644
--- a/handlers/user.go
+++ b/handlers/user.go
@@ -83,16 +83,7 @@ func ChangePasswordHandler(w http.ResponseWriter, r *http.Request) {
return
}
- dbUser, err := models.GetUserByID(user.ID)
- if err != nil || dbUser == nil {
- w.WriteHeader(http.StatusInternalServerError)
- if err := json.NewEncoder(w).Encode(map[string]string{"error": "Could not retrieve user data."}); err != nil {
- logging.AppLog.Error("Failed to encode json error response", "error", err)
- }
- return
- }
-
- if !models.CheckPasswordHash(currentPassword, dbUser.PasswordHash) {
+ if _, err := models.AuthenticateWithPassword(user.Username, currentPassword); err != nil {
w.WriteHeader(http.StatusUnauthorized)
if err := json.NewEncoder(w).Encode(map[string]string{"error": "Current password is incorrect."}); err != nil {
logging.AppLog.Error("Failed to encode json error response", "error", err)
@@ -100,16 +91,7 @@ func ChangePasswordHandler(w http.ResponseWriter, r *http.Request) {
return
}
- newPasswordHash, err := models.HashPassword(newPassword)
- if err != nil {
- w.WriteHeader(http.StatusInternalServerError)
- if err := json.NewEncoder(w).Encode(map[string]string{"error": "Failed to process new password."}); err != nil {
- logging.AppLog.Error("Failed to encode json error response", "error", err)
- }
- return
- }
-
- if err := models.UpdateUserPassword(dbUser.ID, newPasswordHash); err != nil {
+ if err := models.ChangeUserPassword(user.ID, currentPassword, newPassword); err != nil {
w.WriteHeader(http.StatusInternalServerError)
if err := json.NewEncoder(w).Encode(map[string]string{"error": "Failed to update password."}); err != nil {
logging.AppLog.Error("Failed to encode json error response", "error", err)