-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b5c7faa
commit 0992743
Showing
6 changed files
with
144 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package controllers | ||
|
||
import ( | ||
"net/http" | ||
"app.myriadflow.com/utils" | ||
"app.myriadflow.com/models" | ||
"github.com/gin-gonic/gin" | ||
) | ||
|
||
func SendOTPHandler(c *gin.Context) { | ||
var request struct { | ||
Email string `json:"email"` | ||
} | ||
|
||
if err := c.BindJSON(&request); err != nil { | ||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request"}) | ||
return | ||
} | ||
|
||
// Generate OTP and expiration time | ||
otp, expiration := utils.GenerateOTP() | ||
|
||
// Send OTP via email | ||
if err := utils.SendOTP(request.Email, otp); err != nil { | ||
c.JSON(http.StatusInternalServerError, gin.H{"error": err}) | ||
return | ||
} | ||
|
||
// Save OTP and expiration in the store (model) | ||
models.SaveOTP(request.Email, otp, expiration) | ||
|
||
c.JSON(http.StatusOK, gin.H{"message": "OTP sent successfully"}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package controllers | ||
|
||
import ( | ||
"net/http" | ||
"app.myriadflow.com/models" | ||
"github.com/gin-gonic/gin" | ||
) | ||
|
||
func VerifyOTPHandler(c *gin.Context) { | ||
var request struct { | ||
Email string `json:"email"` | ||
OTP string `json:"otp"` | ||
} | ||
|
||
if err := c.BindJSON(&request); err != nil { | ||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request"}) | ||
return | ||
} | ||
|
||
// Verify OTP from the store (model) | ||
if models.VerifyOTP(request.Email, request.OTP) { | ||
c.JSON(http.StatusOK, gin.H{"message": "OTP verified successfully"}) | ||
} else { | ||
c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid or expired OTP"}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package models | ||
|
||
import ( | ||
"sync" | ||
"time" | ||
) | ||
|
||
type OTPData struct { | ||
otp string | ||
expiration time.Time | ||
} | ||
|
||
type OTPStore struct { | ||
data map[string]OTPData | ||
mu sync.RWMutex | ||
} | ||
|
||
var store = OTPStore{ | ||
data: make(map[string]OTPData), | ||
} | ||
|
||
func SaveOTP(email, otp string, expiration time.Time) { | ||
store.mu.Lock() | ||
defer store.mu.Unlock() | ||
store.data[email] = OTPData{ | ||
otp: otp, | ||
expiration: expiration, | ||
} | ||
} | ||
|
||
func VerifyOTP(email, otp string) bool { | ||
store.mu.RLock() | ||
defer store.mu.RUnlock() | ||
|
||
// Fetch the stored OTP data for the email | ||
data, exists := store.data[email] | ||
|
||
// Return false if the OTP doesn't exist or if it has expired | ||
if !exists || time.Now().After(data.expiration) { | ||
return false | ||
} | ||
|
||
// Return true if the OTP matches | ||
return data.otp == otp | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package utils | ||
|
||
import ( | ||
"crypto/rand" | ||
"time" | ||
) | ||
|
||
func GenerateOTP() (string, time.Time) { | ||
otp := make([]byte, 6) | ||
rand.Read(otp) | ||
for i := range otp { | ||
otp[i] = (otp[i] % 10) + '0' // generates numbers 0-9 | ||
} | ||
// OTP valid for 5 minutes | ||
expiration := time.Now().Add(5 * time.Minute) | ||
return string(otp), expiration | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package utils | ||
|
||
import ( | ||
"fmt" | ||
"net/smtp" | ||
) | ||
|
||
func SendOTP(email, otp string) error { | ||
from := "contact@myriadflow.com" | ||
// password := os.Getenv("SMTP_PASSWORD") | ||
password := "" | ||
smtpHost := "smtp.zoho.com" | ||
smtpPort := "587" | ||
|
||
msg := []byte(fmt.Sprintf("Subject: OTP Verification\n\nYour OTP is: %s ", otp)) | ||
|
||
auth := smtp.PlainAuth("", from, password, smtpHost) | ||
return smtp.SendMail(smtpHost+":"+smtpPort, auth, from, []string{email}, msg) | ||
} |