Merge pull request #1207 from trheyi/main
Add OTP resend functionality for user verification
This commit is contained in:
commit
63ff2943f5
3 changed files with 81 additions and 0 deletions
|
|
@ -561,6 +561,80 @@ func validatePassword(password string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GinSendOTP handles resending OTP verification code
|
||||||
|
func GinSendOTP(c *gin.Context) {
|
||||||
|
// Get authorized info from the temporary token
|
||||||
|
authInfo := oauth.GetAuthorizedInfo(c)
|
||||||
|
if authInfo == nil || authInfo.Scope != ScopeEntryVerification {
|
||||||
|
errorResp := &response.ErrorResponse{
|
||||||
|
Code: response.ErrAccessDenied.Code,
|
||||||
|
ErrorDescription: "Invalid or missing entry verification token",
|
||||||
|
}
|
||||||
|
response.RespondWithError(c, response.StatusUnauthorized, errorResp)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get username and username_type from token claims
|
||||||
|
username, _ := c.Get("__username")
|
||||||
|
usernameType, _ := c.Get("__username_type")
|
||||||
|
|
||||||
|
usernameStr, ok := username.(string)
|
||||||
|
if !ok || usernameStr == "" {
|
||||||
|
errorResp := &response.ErrorResponse{
|
||||||
|
Code: response.ErrInvalidRequest.Code,
|
||||||
|
ErrorDescription: "Username not found in token",
|
||||||
|
}
|
||||||
|
response.RespondWithError(c, response.StatusBadRequest, errorResp)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
usernameTypeStr, ok := usernameType.(string)
|
||||||
|
if !ok || usernameTypeStr == "" {
|
||||||
|
errorResp := &response.ErrorResponse{
|
||||||
|
Code: response.ErrInvalidRequest.Code,
|
||||||
|
ErrorDescription: "Username type not found in token",
|
||||||
|
}
|
||||||
|
response.RespondWithError(c, response.StatusBadRequest, errorResp)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get locale from query parameter
|
||||||
|
locale := c.Query("locale")
|
||||||
|
|
||||||
|
// Get entry configuration
|
||||||
|
config := GetEntryConfig(locale)
|
||||||
|
if config == nil {
|
||||||
|
errorResp := &response.ErrorResponse{
|
||||||
|
Code: response.ErrInvalidRequest.Code,
|
||||||
|
ErrorDescription: "Entry configuration not found",
|
||||||
|
}
|
||||||
|
response.RespondWithError(c, response.StatusNotFound, errorResp)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate new OTP
|
||||||
|
otpID, verificationCode := generateEntryOTP()
|
||||||
|
|
||||||
|
// Send verification message asynchronously
|
||||||
|
go func() {
|
||||||
|
ctx := context.Background()
|
||||||
|
err := sendVerificationMessage(ctx, config, usernameTypeStr, usernameStr, verificationCode, locale)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Failed to resend verification code to %s: %v", usernameStr, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Info("Verification code resent to %s (OTP ID: %s)", usernameStr, otpID)
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Prepare response
|
||||||
|
otpResponse := EntrySendOTPResponse{
|
||||||
|
OtpID: otpID,
|
||||||
|
ExpiresIn: 600, // 10 minutes
|
||||||
|
}
|
||||||
|
|
||||||
|
response.RespondWithSuccess(c, response.StatusOK, otpResponse)
|
||||||
|
}
|
||||||
|
|
||||||
// GinEntryRegister handles user registration
|
// GinEntryRegister handles user registration
|
||||||
func GinEntryRegister(c *gin.Context) {
|
func GinEntryRegister(c *gin.Context) {
|
||||||
// Get authorized info from the temporary token
|
// Get authorized info from the temporary token
|
||||||
|
|
|
||||||
|
|
@ -290,6 +290,12 @@ type EntryLoginRequest struct {
|
||||||
Locale string `json:"locale,omitempty"`
|
Locale string `json:"locale,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EntrySendOTPResponse represents the response for sending OTP verification code
|
||||||
|
type EntrySendOTPResponse struct {
|
||||||
|
OtpID string `json:"otp_id"` // OTP ID for verification
|
||||||
|
ExpiresIn int `json:"expires_in,omitempty"` // OTP expiration in seconds
|
||||||
|
}
|
||||||
|
|
||||||
// Built-in preset mapping types
|
// Built-in preset mapping types
|
||||||
const (
|
const (
|
||||||
MappingGoogle = "google"
|
MappingGoogle = "google"
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ func Attach(group *gin.RouterGroup, oauth types.OAuth) {
|
||||||
// Register a new user
|
// Register a new user
|
||||||
group.POST("/entry/register", oauth.Guard, GinEntryRegister) // Register a new user
|
group.POST("/entry/register", oauth.Guard, GinEntryRegister) // Register a new user
|
||||||
group.POST("/entry/login", oauth.Guard, GinEntryLogin) // Login a user
|
group.POST("/entry/login", oauth.Guard, GinEntryLogin) // Login a user
|
||||||
|
group.POST("/entry/otp", oauth.Guard, GinSendOTP) // Send OTP
|
||||||
group.POST("/logout", oauth.Guard, placeholder) // User logout
|
group.POST("/logout", oauth.Guard, placeholder) // User logout
|
||||||
|
|
||||||
// Logined User Settings
|
// Logined User Settings
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue