forked from nixcn/nixcn-cms
8
service/auth/handler.go
Normal file
8
service/auth/handler.go
Normal file
@@ -0,0 +1,8 @@
|
||||
package auth
|
||||
|
||||
import "github.com/gin-gonic/gin"
|
||||
|
||||
func Handler(r *gin.RouterGroup) {
|
||||
r.POST("/magic", RequestMagicLink)
|
||||
r.GET("/magic/verify", VerifyMagicLink)
|
||||
}
|
||||
80
service/auth/magic.go
Normal file
80
service/auth/magic.go
Normal file
@@ -0,0 +1,80 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"nixcn-cms/internal/crypto/jwt"
|
||||
"nixcn-cms/pkgs/magiclink"
|
||||
"nixcn-cms/pkgs/turnstile"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
type MagicLinkRequest struct {
|
||||
Email string `json:"email" binding:"required,email"`
|
||||
TurnstileToken string `json:"turnstile_token" binding:"required"`
|
||||
}
|
||||
|
||||
func RequestMagicLink(c *gin.Context) {
|
||||
// Parse request
|
||||
var req MagicLinkRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(400, gin.H{"error": "invalid request"})
|
||||
return
|
||||
}
|
||||
|
||||
// Cloudflare turnstile
|
||||
ok, err := turnstile.VerifyTurnstile(req.TurnstileToken, c.ClientIP())
|
||||
if err != nil || !ok {
|
||||
c.JSON(403, gin.H{"error": "turnstile failed"})
|
||||
return
|
||||
}
|
||||
|
||||
// Generate magic token
|
||||
token, err := magiclink.NewMagicToken(req.Email, 15*time.Minute)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"error": "internal error"})
|
||||
return
|
||||
}
|
||||
|
||||
link, err := url.JoinPath(viper.GetString("server.external_url"), "/api/v1/auth/magic/verify?token="+token)
|
||||
if err != nil {
|
||||
log.Error("Magic link join failed!")
|
||||
c.JSON(500, gin.H{"message": "magic link join failed"})
|
||||
return
|
||||
}
|
||||
|
||||
// TODO Send EMail
|
||||
log.Info("Magic link:", link)
|
||||
|
||||
c.JSON(200, gin.H{"message": "magic link sent"})
|
||||
}
|
||||
|
||||
func VerifyMagicLink(c *gin.Context) {
|
||||
// Get token from url
|
||||
token := c.Query("token")
|
||||
if token == "" {
|
||||
c.JSON(400, gin.H{"error": "missing token"})
|
||||
return
|
||||
}
|
||||
|
||||
// Verify email token
|
||||
email, ok := magiclink.VerifyMagicToken(token)
|
||||
if !ok {
|
||||
c.JSON(401, gin.H{"error": "invalid or expired token"})
|
||||
return
|
||||
}
|
||||
|
||||
// Generate jwt
|
||||
uuid, _ := uuid.NewUUID()
|
||||
jwtToken, _ := jwt.GenerateToken(uuid, "application")
|
||||
|
||||
c.JSON(200, gin.H{
|
||||
"jwt_token": jwtToken,
|
||||
"email": email,
|
||||
})
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
package check
|
||||
|
||||
func Checkin() {
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package check
|
||||
package checkin
|
||||
|
||||
import (
|
||||
"nixcn-cms/internal/crypto/jwt"
|
||||
@@ -8,7 +8,4 @@ import (
|
||||
|
||||
func Handler(r *gin.RouterGroup) {
|
||||
r.Use(jwt.JWTAuth())
|
||||
r.GET("/test", func(ctx *gin.Context) {
|
||||
ctx.JSON(200, gin.H{"Test": "Test"})
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user