|
|
|
|
@@ -3,8 +3,8 @@ package auth
|
|
|
|
|
import (
|
|
|
|
|
"nixcn-cms/data"
|
|
|
|
|
"nixcn-cms/internal/cryptography"
|
|
|
|
|
"nixcn-cms/pkgs/authcode"
|
|
|
|
|
"nixcn-cms/pkgs/email"
|
|
|
|
|
"nixcn-cms/pkgs/magiclink"
|
|
|
|
|
"nixcn-cms/pkgs/turnstile"
|
|
|
|
|
|
|
|
|
|
"github.com/google/uuid"
|
|
|
|
|
@@ -15,14 +15,17 @@ import (
|
|
|
|
|
"github.com/spf13/viper"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type MagicLinkRequest struct {
|
|
|
|
|
Email string `json:"email" binding:"required,email"`
|
|
|
|
|
TurnstileToken string `json:"turnstile_token" binding:"required"`
|
|
|
|
|
type MagicRequest struct {
|
|
|
|
|
ClientId string `json:"client_id"`
|
|
|
|
|
RedirectUri string `json:"redirect_uri"`
|
|
|
|
|
State string `json:"state"`
|
|
|
|
|
Email string `json:"email"`
|
|
|
|
|
TurnstileToken string `json:"turnstile_token"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func RequestMagicLink(c *gin.Context) {
|
|
|
|
|
func Magic(c *gin.Context) {
|
|
|
|
|
// Parse request
|
|
|
|
|
var req MagicLinkRequest
|
|
|
|
|
var req MagicRequest
|
|
|
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
|
|
|
c.JSON(400, gin.H{"error": "invalid request"})
|
|
|
|
|
return
|
|
|
|
|
@@ -35,18 +38,20 @@ func RequestMagicLink(c *gin.Context) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Generate magic token
|
|
|
|
|
token, err := magiclink.NewMagicToken(req.Email)
|
|
|
|
|
code, err := authcode.NewAuthCode(req.Email)
|
|
|
|
|
if err != nil {
|
|
|
|
|
c.JSON(500, gin.H{"error": "internal error"})
|
|
|
|
|
return
|
|
|
|
|
c.JSON(500, gin.H{"status": "code gen failed"})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
link := viper.GetString("server.external_url") + "/login?ticket=" + token
|
|
|
|
|
uri := viper.GetString("server.external_url") +
|
|
|
|
|
"/api/v1/auth/redirect?" +
|
|
|
|
|
"code=" + code +
|
|
|
|
|
"&redirect_uri" + req.RedirectUri +
|
|
|
|
|
"&state" + req.State
|
|
|
|
|
|
|
|
|
|
debugMode := viper.GetString("server.debug_mode")
|
|
|
|
|
if debugMode == "true" {
|
|
|
|
|
log.Info("Magic link for " + req.Email + " : " + link)
|
|
|
|
|
log.Info("Magic link for " + req.Email + " : " + uri)
|
|
|
|
|
} else {
|
|
|
|
|
// Send email using resend
|
|
|
|
|
resend, err := email.NewResendClient()
|
|
|
|
|
@@ -58,7 +63,7 @@ func RequestMagicLink(c *gin.Context) {
|
|
|
|
|
resend.Send(
|
|
|
|
|
req.Email,
|
|
|
|
|
"NixCN CMS Email Verify",
|
|
|
|
|
"<p>Click the link below to verify your email. This link will expire in 10 minutes.</p><a href="+link+">"+link+"</a>",
|
|
|
|
|
"<p>Click the link below to verify your email. This link will expire in 10 minutes.</p><a href="+uri+">"+uri+"</a>",
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -74,7 +79,7 @@ func VerifyMagicLink(c *gin.Context) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Verify email token
|
|
|
|
|
email, ok := magiclink.VerifyMagicToken(magicToken)
|
|
|
|
|
email, ok := authcode.VerifyAuthCode(magicToken)
|
|
|
|
|
if !ok {
|
|
|
|
|
c.JSON(401, gin.H{"error": "invalid or expired token"})
|
|
|
|
|
return
|
|
|
|
|
|