mirror of
https://github.com/get-drexa/drive.git
synced 2026-02-02 11:51:17 +00:00
docs: add OpenAPI documentation with Scalar UI
- Add swaggo annotations to all HTTP handlers - Add Swagger/OpenAPI spec generation with swag - Create separate docs server binary (drexa-docs) - Add Makefile with build, run, and docs targets - Configure Scalar as the API documentation UI Run 'make docs' to regenerate, 'make run-docs' to serve.
This commit is contained in:
@@ -20,25 +20,42 @@ const (
|
||||
cookieKeyRefreshToken = "refresh_token"
|
||||
)
|
||||
|
||||
// loginRequest represents the login credentials
|
||||
// @Description Login request with email, password, and token delivery preference
|
||||
type loginRequest struct {
|
||||
Email string `json:"email"`
|
||||
Password string `json:"password"`
|
||||
TokenDelivery string `json:"tokenDelivery"`
|
||||
// User's email address
|
||||
Email string `json:"email" example:"user@example.com"`
|
||||
// User's password
|
||||
Password string `json:"password" example:"secretpassword123"`
|
||||
// How to deliver tokens: "cookie" (set HTTP-only cookies) or "body" (include in response)
|
||||
TokenDelivery string `json:"tokenDelivery" example:"body" enums:"cookie,body"`
|
||||
}
|
||||
|
||||
// loginResponse represents a successful login response
|
||||
// @Description Login response containing user info and optionally tokens
|
||||
type loginResponse struct {
|
||||
User user.User `json:"user"`
|
||||
AccessToken string `json:"accessToken,omitempty"`
|
||||
RefreshToken string `json:"refreshToken,omitempty"`
|
||||
// Authenticated user information
|
||||
User user.User `json:"user"`
|
||||
// JWT access token (only included when tokenDelivery is "body")
|
||||
AccessToken string `json:"accessToken,omitempty" example:"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1NTBlODQwMC1lMjliLTQxZDQtYTcxNi00NDY2NTU0NDAwMDAifQ.signature"`
|
||||
// Base64 URL encoded refresh token (only included when tokenDelivery is "body")
|
||||
RefreshToken string `json:"refreshToken,omitempty" example:"dR4nD0mUu1DkZXlCeXRlc0FuZFJhbmRvbURhdGFIZXJlMTIzNDU2Nzg5MGFi"`
|
||||
}
|
||||
|
||||
// refreshAccessTokenRequest represents a token refresh request
|
||||
// @Description Request to exchange a refresh token for new tokens
|
||||
type refreshAccessTokenRequest struct {
|
||||
RefreshToken string `json:"refreshToken"`
|
||||
// Base64 URL encoded refresh token
|
||||
RefreshToken string `json:"refreshToken" example:"dR4nD0mUu1DkZXlCeXRlc0FuZFJhbmRvbURhdGFIZXJlMTIzNDU2Nzg5MGFi"`
|
||||
}
|
||||
|
||||
// tokenResponse represents new access and refresh tokens
|
||||
// @Description Response containing new access token and refresh token
|
||||
type tokenResponse struct {
|
||||
AccessToken string `json:"accessToken"`
|
||||
RefreshToken string `json:"refreshToken"`
|
||||
// New JWT access token
|
||||
AccessToken string `json:"accessToken" example:"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1NTBlODQwMC1lMjliLTQxZDQtYTcxNi00NDY2NTU0NDAwMDAifQ.signature"`
|
||||
// New base64 URL encoded refresh token
|
||||
RefreshToken string `json:"refreshToken" example:"xK9mPqRsTuVwXyZ0AbCdEfGhIjKlMnOpQrStUvWxYz1234567890abcdefgh"`
|
||||
}
|
||||
|
||||
type HTTPHandler struct {
|
||||
@@ -57,6 +74,17 @@ func (h *HTTPHandler) RegisterRoutes(api fiber.Router) {
|
||||
auth.Post("/tokens", h.refreshAccessToken)
|
||||
}
|
||||
|
||||
// Login authenticates a user with email and password
|
||||
// @Summary User login
|
||||
// @Description Authenticate with email and password to receive JWT tokens. Tokens can be delivered via HTTP-only cookies or in the response body based on the tokenDelivery field.
|
||||
// @Tags auth
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param request body loginRequest true "Login credentials"
|
||||
// @Success 200 {object} loginResponse "Successful authentication"
|
||||
// @Failure 400 {object} map[string]string "Invalid request body or token delivery method"
|
||||
// @Failure 401 {object} map[string]string "Invalid email or password"
|
||||
// @Router /auth/login [post]
|
||||
func (h *HTTPHandler) Login(c *fiber.Ctx) error {
|
||||
req := new(loginRequest)
|
||||
if err := c.BodyParser(req); err != nil {
|
||||
@@ -100,6 +128,17 @@ func (h *HTTPHandler) Login(c *fiber.Ctx) error {
|
||||
}
|
||||
}
|
||||
|
||||
// refreshAccessToken exchanges a refresh token for new access and refresh tokens
|
||||
// @Summary Refresh access token
|
||||
// @Description Exchange a valid refresh token for a new pair of access and refresh tokens. The old refresh token is invalidated (rotation).
|
||||
// @Tags auth
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param request body refreshAccessTokenRequest true "Refresh token"
|
||||
// @Success 200 {object} tokenResponse "New tokens"
|
||||
// @Failure 400 {object} map[string]string "Invalid request body"
|
||||
// @Failure 401 {object} map[string]string "Invalid, expired, or reused refresh token"
|
||||
// @Router /auth/tokens [post]
|
||||
func (h *HTTPHandler) refreshAccessToken(c *fiber.Ctx) error {
|
||||
req := new(refreshAccessTokenRequest)
|
||||
if err := c.BodyParser(req); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user