mirror of
https://github.com/warmbly/warmbly.git
synced 2026-08-18 16:01:18 +00:00
68 lines
1.6 KiB
Go
68 lines
1.6 KiB
Go
package handler
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/warmbly/warmbly/internal/app/token"
|
|
"github.com/warmbly/warmbly/internal/errx"
|
|
)
|
|
|
|
type setupClaimRequest struct {
|
|
Token string `json:"token"`
|
|
Email string `json:"email"`
|
|
Password string `json:"password"`
|
|
FirstName string `json:"first_name"`
|
|
LastName string `json:"last_name"`
|
|
}
|
|
|
|
// SetupClaim exchanges the one-time link printed at first boot for the owner
|
|
// account, and signs them straight in.
|
|
//
|
|
// Public by necessity: there is no account to authenticate as yet. The token is
|
|
// the protection, and it is consumed atomically, refused once any user exists,
|
|
// and covered by the same per-IP limiter as the rest of the auth group.
|
|
func (h *Handler) SetupClaim(c *gin.Context) {
|
|
if h.BootstrapService == nil {
|
|
errx.Handle(c, errx.New(errx.NotFound, "Setup is not available on this deployment."))
|
|
return
|
|
}
|
|
|
|
var req setupClaimRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
errx.Handle(c, errx.ErrInvalid)
|
|
return
|
|
}
|
|
|
|
u, xerr := h.BootstrapService.Claim(
|
|
c.Request.Context(),
|
|
req.Token,
|
|
req.Email,
|
|
req.Password,
|
|
req.FirstName,
|
|
req.LastName,
|
|
)
|
|
if xerr != nil {
|
|
errx.Handle(c, xerr)
|
|
return
|
|
}
|
|
|
|
// Hand back a session rather than bouncing them to the login screen. They
|
|
// just proved ownership of the instance; asking them to type the password
|
|
// again immediately is friction with no security value.
|
|
session, terr := h.TokenService.GenerateSession(
|
|
c.Request.Context(),
|
|
u.ID,
|
|
u.Email,
|
|
c.ClientIP(),
|
|
c.Request.UserAgent(),
|
|
token.AuthProviderEmail,
|
|
)
|
|
if terr != nil {
|
|
errx.Handle(c, terr)
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, session)
|
|
}
|