package authcode import ( "crypto/rand" "encoding/base64" "sync" "time" "github.com/spf13/viper" ) type Token struct { Email string ExpiresAt time.Time } var ( store = sync.Map{} ) // Generate magic token func NewAuthCode(email string) (string, error) { b := make([]byte, 32) if _, err := rand.Read(b); err != nil { return "", err } code := base64.RawURLEncoding.EncodeToString(b) store.Store(code, Token{ Email: email, ExpiresAt: time.Now().Add(viper.GetDuration("ttl.auth_code_ttl")), }) return code, nil } // Verify magic token func VerifyAuthCode(code string) (string, bool) { val, ok := store.Load(code) if !ok { return "", false } t := val.(Token) if time.Now().After(t.ExpiresAt) { store.Delete(code) return "", false } store.Delete(code) return t.Email, true }