Add bcrypt user file auth, JWT middleware on all write routes, Pinia authStore with localStorage persistence, login view with redirect support, and v-if guards on all CRUD controls and admin nav link. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
45 lines
1.2 KiB
Go
45 lines
1.2 KiB
Go
package handler
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"github.com/labstack/echo/v4"
|
|
|
|
"osdb/internal/auth"
|
|
)
|
|
|
|
// AuthHandler handles authentication endpoints.
|
|
type AuthHandler struct {
|
|
users map[string]string
|
|
jwtSecret string
|
|
}
|
|
|
|
// NewAuthHandler creates an AuthHandler with the given user map and JWT secret.
|
|
func NewAuthHandler(users map[string]string, jwtSecret string) *AuthHandler {
|
|
return &AuthHandler{users: users, jwtSecret: jwtSecret}
|
|
}
|
|
|
|
type loginRequest struct {
|
|
Username string `json:"username"`
|
|
Password string `json:"password"`
|
|
}
|
|
|
|
// Login handles POST /api/v1/auth/login.
|
|
func (h *AuthHandler) Login(c echo.Context) error {
|
|
var req loginRequest
|
|
if err := c.Bind(&req); err != nil || req.Username == "" {
|
|
return c.JSON(http.StatusUnauthorized, map[string]string{"error": "invalid credentials"})
|
|
}
|
|
|
|
if !auth.VerifyPassword(h.users, req.Username, req.Password) {
|
|
return c.JSON(http.StatusUnauthorized, map[string]string{"error": "invalid credentials"})
|
|
}
|
|
|
|
token, err := auth.GenerateJWT(req.Username, h.jwtSecret)
|
|
if err != nil {
|
|
return c.JSON(http.StatusInternalServerError, map[string]string{"error": "token generation failed"})
|
|
}
|
|
|
|
return c.JSON(http.StatusOK, map[string]string{"token": token})
|
|
}
|