152 lines
3.6 KiB
Go
152 lines
3.6 KiB
Go
package signupHandler
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"github.com/fossyy/filekeeper/app"
|
|
"github.com/fossyy/filekeeper/utils"
|
|
"github.com/fossyy/filekeeper/view/client/email"
|
|
signupView "github.com/fossyy/filekeeper/view/client/signup"
|
|
"github.com/redis/go-redis/v9"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/fossyy/filekeeper/types"
|
|
"github.com/fossyy/filekeeper/types/models"
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
type UnverifiedUser struct {
|
|
User *models.User
|
|
Code string
|
|
CreateTime time.Time
|
|
}
|
|
|
|
func GET(w http.ResponseWriter, r *http.Request) {
|
|
component := signupView.Main("Filekeeper - Sign up Page", types.Message{
|
|
Code: 3,
|
|
Message: "",
|
|
})
|
|
err := component.Render(r.Context(), w)
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
app.Server.Logger.Error(err.Error())
|
|
return
|
|
}
|
|
}
|
|
|
|
func POST(w http.ResponseWriter, r *http.Request) {
|
|
err := r.ParseForm()
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
app.Server.Logger.Error(err.Error())
|
|
return
|
|
}
|
|
userEmail := r.Form.Get("email")
|
|
username := r.Form.Get("username")
|
|
password := r.Form.Get("password")
|
|
isValid := utils.ValidatePassword(password)
|
|
if !isValid {
|
|
component := signupView.Main("Filekeeper - Sign up Page", types.Message{
|
|
Code: 0,
|
|
Message: "Password is invalid",
|
|
})
|
|
err := component.Render(r.Context(), w)
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
app.Server.Logger.Error(err.Error())
|
|
return
|
|
}
|
|
return
|
|
}
|
|
hashedPassword, err := utils.HashPassword(password)
|
|
|
|
newUser := models.User{
|
|
UserID: uuid.New(),
|
|
Username: username,
|
|
Email: userEmail,
|
|
Password: hashedPassword,
|
|
}
|
|
|
|
if registered := app.Server.Database.IsUserRegistered(userEmail, username); registered {
|
|
component := signupView.Main("Filekeeper - Sign up Page", types.Message{
|
|
Code: 0,
|
|
Message: "Email or Username has been registered",
|
|
})
|
|
err = component.Render(r.Context(), w)
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
app.Server.Logger.Error(err.Error())
|
|
return
|
|
}
|
|
return
|
|
}
|
|
|
|
err = verifyEmail(&newUser)
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
app.Server.Logger.Error(err.Error())
|
|
return
|
|
}
|
|
|
|
component := signupView.EmailSend("Filekeeper - Sign up Page")
|
|
err = component.Render(r.Context(), w)
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
app.Server.Logger.Error(err.Error())
|
|
return
|
|
}
|
|
return
|
|
}
|
|
|
|
func verifyEmail(user *models.User) error {
|
|
var buffer bytes.Buffer
|
|
var code string
|
|
|
|
storedCode, err := app.Server.Cache.GetCache(context.Background(), "VerificationCode:"+user.Email)
|
|
if err != nil {
|
|
if errors.Is(err, redis.Nil) {
|
|
code = utils.GenerateRandomString(64)
|
|
} else {
|
|
return err
|
|
}
|
|
} else {
|
|
code = storedCode
|
|
}
|
|
|
|
err = emailView.RegistrationEmail(user.Username, fmt.Sprintf("https://%s/signup/verify/%s", utils.Getenv("DOMAIN"), code)).Render(context.Background(), &buffer)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
unverifiedUser := UnverifiedUser{
|
|
User: user,
|
|
Code: code,
|
|
CreateTime: time.Now(),
|
|
}
|
|
newUnverifiedUser, err := json.Marshal(unverifiedUser)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = app.Server.Cache.SetCache(context.Background(), "UnverifiedUser:"+code, newUnverifiedUser, 10*time.Minute)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = app.Server.Cache.SetCache(context.Background(), "VerificationCode:"+user.Email, code, 10*time.Minute)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = app.Server.Mail.Send(user.Email, "Account Registration Verification", buffer.String())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|