97 lines
3.0 KiB
Go
97 lines
3.0 KiB
Go
package services
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
|
|
"git.solsynth.dev/hypernet/passport/pkg/authkit/models"
|
|
"git.solsynth.dev/hypernet/passport/pkg/internal/gap"
|
|
"git.solsynth.dev/hypernet/pusher/pkg/pushkit"
|
|
|
|
"git.solsynth.dev/hypernet/passport/pkg/internal/database"
|
|
"github.com/google/uuid"
|
|
"github.com/spf13/viper"
|
|
)
|
|
|
|
func ValidateMagicToken(code string, mode models.MagicTokenType) (models.MagicToken, error) {
|
|
var tk models.MagicToken
|
|
if err := database.C.Where(models.MagicToken{Code: code, Type: mode}).First(&tk).Error; err != nil {
|
|
return tk, err
|
|
} else if tk.ExpiredAt != nil && time.Now().Unix() >= tk.ExpiredAt.Unix() {
|
|
return tk, fmt.Errorf("token has been expired")
|
|
}
|
|
|
|
return tk, nil
|
|
}
|
|
|
|
func NewMagicToken(mode models.MagicTokenType, assignTo *models.Account, expiredAt *time.Time) (models.MagicToken, error) {
|
|
var uid uint
|
|
if assignTo != nil {
|
|
uid = assignTo.ID
|
|
}
|
|
|
|
token := models.MagicToken{
|
|
Code: strings.Replace(uuid.NewString(), "-", "", -1),
|
|
Type: mode,
|
|
AccountID: &uid,
|
|
ExpiredAt: expiredAt,
|
|
}
|
|
|
|
if err := database.C.Save(&token).Error; err != nil {
|
|
return token, err
|
|
} else {
|
|
return token, nil
|
|
}
|
|
}
|
|
|
|
func NotifyMagicToken(token models.MagicToken) error {
|
|
if token.AccountID == nil {
|
|
return fmt.Errorf("could notify a non-assign magic token")
|
|
}
|
|
|
|
var user models.Account
|
|
if err := database.C.Where(&models.Account{
|
|
BaseModel: models.BaseModel{ID: *token.AccountID},
|
|
}).Preload("Contacts").First(&user).Error; err != nil {
|
|
return err
|
|
}
|
|
|
|
var subject string
|
|
var content string
|
|
switch token.Type {
|
|
case models.ConfirmMagicToken:
|
|
link := fmt.Sprintf("%s/flow/accounts/confirm?code=%s", viper.GetString("frontend_app"), token.Code)
|
|
subject = fmt.Sprintf("[%s] %s", viper.GetString("name"), GetLocalizedString("subjectConfirmRegistration", user.Language))
|
|
content = RenderLocalizedTemplateHTML("register-confirm.tmpl", user.Language, map[string]any{
|
|
"User": user,
|
|
"Link": link,
|
|
})
|
|
case models.ResetPasswordMagicToken:
|
|
link := fmt.Sprintf("%s/flow/accounts/password-reset?code=%s", viper.GetString("frontend_app"), token.Code)
|
|
subject = fmt.Sprintf("[%s] %s", viper.GetString("name"), GetLocalizedString("subjectResetPassword", user.Language))
|
|
content = RenderLocalizedTemplateHTML("reset-password.tmpl", user.Language, map[string]any{
|
|
"User": user,
|
|
"Link": link,
|
|
})
|
|
case models.DeleteAccountMagicToken:
|
|
link := fmt.Sprintf("%s/flow/accounts/deletion?code=%s", viper.GetString("frontend_app"), token.Code)
|
|
subject = fmt.Sprintf("[%s] %s", viper.GetString("name"), GetLocalizedString("subjectDeleteAccount", user.Language))
|
|
content = RenderLocalizedTemplateHTML("confirm-deletion.tmpl", user.Language, map[string]any{
|
|
"User": user,
|
|
"Link": link,
|
|
})
|
|
default:
|
|
return fmt.Errorf("unsupported magic token type to notify")
|
|
}
|
|
|
|
err := gap.Px.PushEmail(pushkit.EmailDeliverRequest{
|
|
To: user.GetPrimaryEmail().Content,
|
|
Email: pushkit.EmailData{
|
|
Subject: subject,
|
|
Text: &content,
|
|
},
|
|
})
|
|
return err
|
|
}
|