mirror of
https://github.com/gabehf/Koito.git
synced 2026-03-15 10:25:55 -07:00
feat: v0.0.8
This commit is contained in:
parent
00e7782be2
commit
80b6f4deaa
66 changed files with 1559 additions and 916 deletions
|
|
@ -18,70 +18,62 @@ func LoginHandler(store db.DB) http.HandlerFunc {
|
|||
ctx := r.Context()
|
||||
l := logger.FromContext(ctx)
|
||||
|
||||
l.Debug().Msg("LoginHandler: Received login request")
|
||||
l.Debug().Msg("LoginHandler: Received request")
|
||||
|
||||
err := r.ParseForm()
|
||||
if err != nil {
|
||||
l.Debug().Msg("LoginHandler: Failed to parse request form")
|
||||
utils.WriteError(w, "failed to parse request", http.StatusInternalServerError)
|
||||
if err := r.ParseForm(); err != nil {
|
||||
l.Debug().AnErr("error", err).Msg("LoginHandler: Failed to parse form")
|
||||
utils.WriteError(w, "invalid request format", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
username := r.FormValue("username")
|
||||
password := r.FormValue("password")
|
||||
if username == "" || password == "" {
|
||||
l.Debug().Msg("LoginHandler: Missing username or password")
|
||||
utils.WriteError(w, "username and password are required", http.StatusBadRequest)
|
||||
l.Debug().Msg("LoginHandler: Missing credentials")
|
||||
utils.WriteError(w, "username and password required", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
l.Debug().Msgf("LoginHandler: Searching for user with username '%s'", username)
|
||||
user, err := store.GetUserByUsername(ctx, username)
|
||||
if err != nil {
|
||||
l.Err(err).Msg("LoginHandler: Error searching for user in database")
|
||||
utils.WriteError(w, "internal server error", http.StatusInternalServerError)
|
||||
l.Error().Err(err).Msg("LoginHandler: Database error fetching user")
|
||||
utils.WriteError(w, "authentication failed", http.StatusInternalServerError)
|
||||
return
|
||||
} else if user == nil {
|
||||
l.Debug().Msg("LoginHandler: Username or password is incorrect")
|
||||
utils.WriteError(w, "username or password is incorrect", http.StatusBadRequest)
|
||||
}
|
||||
if user == nil {
|
||||
l.Debug().Msg("LoginHandler: User not found")
|
||||
utils.WriteError(w, "invalid credentials", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
err = bcrypt.CompareHashAndPassword(user.Password, []byte(password))
|
||||
if err != nil {
|
||||
l.Debug().Msg("LoginHandler: Password comparison failed")
|
||||
utils.WriteError(w, "username or password is incorrect", http.StatusBadRequest)
|
||||
if err := bcrypt.CompareHashAndPassword(user.Password, []byte(password)); err != nil {
|
||||
l.Debug().Msg("LoginHandler: Invalid password")
|
||||
utils.WriteError(w, "invalid credentials", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
keepSignedIn := false
|
||||
expiresAt := time.Now().Add(1 * 24 * time.Hour)
|
||||
expiresAt := time.Now().Add(24 * time.Hour)
|
||||
if strings.ToLower(r.FormValue("remember_me")) == "true" {
|
||||
keepSignedIn = true
|
||||
expiresAt = time.Now().Add(30 * 24 * time.Hour)
|
||||
}
|
||||
|
||||
l.Debug().Msgf("LoginHandler: Creating session for user ID %d", user.ID)
|
||||
session, err := store.SaveSession(ctx, user.ID, expiresAt, keepSignedIn)
|
||||
session, err := store.SaveSession(ctx, user.ID, expiresAt, r.FormValue("remember_me") == "true")
|
||||
if err != nil {
|
||||
l.Err(err).Msg("LoginHandler: Failed to create session")
|
||||
utils.WriteError(w, "failed to create session", http.StatusInternalServerError)
|
||||
l.Error().Err(err).Msg("LoginHandler: Failed to create session")
|
||||
utils.WriteError(w, "authentication failed", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
cookie := &http.Cookie{
|
||||
http.SetCookie(w, &http.Cookie{
|
||||
Name: "koito_session",
|
||||
Value: session.ID.String(),
|
||||
Expires: expiresAt,
|
||||
Path: "/",
|
||||
HttpOnly: true,
|
||||
Secure: false,
|
||||
}
|
||||
})
|
||||
|
||||
if keepSignedIn {
|
||||
cookie.Expires = expiresAt
|
||||
}
|
||||
|
||||
l.Debug().Msgf("LoginHandler: Session created successfully for user ID %d", user.ID)
|
||||
http.SetCookie(w, cookie)
|
||||
l.Debug().Msgf("LoginHandler: User %d authenticated", user.ID)
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
}
|
||||
|
|
@ -91,34 +83,27 @@ func LogoutHandler(store db.DB) http.HandlerFunc {
|
|||
ctx := r.Context()
|
||||
l := logger.FromContext(ctx)
|
||||
|
||||
l.Debug().Msg("LogoutHandler: Received logout request")
|
||||
l.Debug().Msg("LogoutHandler: Received request")
|
||||
|
||||
cookie, err := r.Cookie("koito_session")
|
||||
if err == nil {
|
||||
l.Debug().Msg("LogoutHandler: Found session cookie")
|
||||
sid, err := uuid.Parse(cookie.Value)
|
||||
if err != nil {
|
||||
l.Debug().AnErr("error", err).Msg("LogoutHandler: Invalid session cookie")
|
||||
utils.WriteError(w, "session cookie is invalid", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
l.Debug().Msgf("LogoutHandler: Deleting session with ID %s", sid)
|
||||
err = store.DeleteSession(ctx, sid)
|
||||
if err != nil {
|
||||
l.Err(err).Msg("LogoutHandler: Failed to delete session")
|
||||
utils.WriteError(w, "internal server error", http.StatusInternalServerError)
|
||||
return
|
||||
l.Debug().AnErr("error", err).Msg("LogoutHandler: Invalid session ID")
|
||||
} else if err := store.DeleteSession(ctx, sid); err != nil {
|
||||
l.Error().Err(err).Msg("LogoutHandler: Failed to delete session")
|
||||
}
|
||||
}
|
||||
|
||||
l.Debug().Msg("LogoutHandler: Clearing session cookie")
|
||||
http.SetCookie(w, &http.Cookie{
|
||||
Name: "koito_session",
|
||||
Value: "",
|
||||
Path: "/",
|
||||
HttpOnly: true,
|
||||
MaxAge: -1, // expire immediately
|
||||
MaxAge: -1,
|
||||
})
|
||||
|
||||
l.Debug().Msg("LogoutHandler: Session terminated")
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
}
|
||||
|
|
@ -128,16 +113,17 @@ func MeHandler(store db.DB) http.HandlerFunc {
|
|||
ctx := r.Context()
|
||||
l := logger.FromContext(ctx)
|
||||
|
||||
l.Debug().Msg("MeHandler: Received request to retrieve user information")
|
||||
u := middleware.GetUserFromContext(ctx)
|
||||
if u == nil {
|
||||
l.Debug().Msg("MeHandler: Invalid user retrieved from context")
|
||||
l.Debug().Msg("MeHandler: Received request")
|
||||
|
||||
user := middleware.GetUserFromContext(ctx)
|
||||
if user == nil {
|
||||
l.Debug().Msg("MeHandler: Unauthorized access")
|
||||
utils.WriteError(w, "unauthorized", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
l.Debug().Msgf("MeHandler: Successfully retrieved user with ID %d", u.ID)
|
||||
utils.WriteJSON(w, http.StatusOK, u)
|
||||
l.Debug().Msgf("MeHandler: Returning user data for ID %d", user.ID)
|
||||
utils.WriteJSON(w, http.StatusOK, user)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -146,41 +132,42 @@ func UpdateUserHandler(store db.DB) http.HandlerFunc {
|
|||
ctx := r.Context()
|
||||
l := logger.FromContext(ctx)
|
||||
|
||||
l.Debug().Msg("UpdateUserHandler: Received request to update user information")
|
||||
u := middleware.GetUserFromContext(ctx)
|
||||
if u == nil {
|
||||
l.Debug().Msg("UpdateUserHandler: Unauthorized request (user context is nil)")
|
||||
l.Debug().Msg("UpdateUserHandler: Received request")
|
||||
|
||||
user := middleware.GetUserFromContext(ctx)
|
||||
if user == nil {
|
||||
l.Debug().Msg("UpdateUserHandler: Unauthorized access")
|
||||
utils.WriteError(w, "unauthorized", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
err := r.ParseForm()
|
||||
if err != nil {
|
||||
l.Err(err).Msg("UpdateUserHandler: Failed to parse request form")
|
||||
utils.WriteError(w, "failed to parse request", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
username := r.FormValue("username")
|
||||
password := r.FormValue("password")
|
||||
|
||||
if username == "" && password == "" {
|
||||
l.Debug().Msg("UpdateUserHandler: No parameters were recieved")
|
||||
utils.WriteError(w, "all parameters missing", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
l.Debug().Msgf("UpdateUserHandler: Updating user with ID %d", u.ID)
|
||||
err = store.UpdateUser(ctx, db.UpdateUserOpts{
|
||||
ID: u.ID,
|
||||
Username: username,
|
||||
Password: password,
|
||||
})
|
||||
if err != nil {
|
||||
l.Err(err).Msg("UpdateUserHandler: Failed to update user")
|
||||
utils.WriteError(w, err.Error(), http.StatusBadRequest)
|
||||
if err := r.ParseForm(); err != nil {
|
||||
l.Error().Err(err).Msg("UpdateUserHandler: Invalid form data")
|
||||
utils.WriteError(w, "invalid request", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
l.Debug().Msgf("UpdateUserHandler: Successfully updated user with ID %d", u.ID)
|
||||
opts := db.UpdateUserOpts{ID: user.ID}
|
||||
if username := r.FormValue("username"); username != "" {
|
||||
opts.Username = username
|
||||
}
|
||||
if password := r.FormValue("password"); password != "" {
|
||||
opts.Password = password
|
||||
}
|
||||
|
||||
if opts.Username == "" && opts.Password == "" {
|
||||
l.Debug().Msg("UpdateUserHandler: No update parameters provided")
|
||||
utils.WriteError(w, "no changes specified", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if err := store.UpdateUser(ctx, opts); err != nil {
|
||||
l.Error().Err(err).Msg("UpdateUserHandler: Update failed")
|
||||
utils.WriteError(w, "update failed", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
l.Debug().Msgf("UpdateUserHandler: User %d updated", user.ID)
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue