package main import ( "errors" "math/rand" "time" ) type Code struct { Code string Valid time.Time } type Auth struct { codes map[string]Code mailer Mailer } var letterRunes = []rune("ABCDEFGHIJKLMNOPQRSTUVWXYZ") func randString(n int) string { b := make([]rune, n) for i := range b { b[i] = letterRunes[rand.Intn(len(letterRunes))] } return string(b) } func (a *Auth) CreateCode(email string) error { code := randString(10) if err := a.mailer.SendCode(email, code); err != nil { return err } a.codes[email] = Code{ Code: code, Valid: time.Now().Add(time.Minute), } return nil } func (a *Auth) IsCodeValid(email string, code string) bool { existingCode, exists := a.codes[email] if !exists { return false } return existingCode.Valid.After(time.Now()) && existingCode.Code == code } func (a *Auth) UseCode(email string, code string) error { if valid := a.IsCodeValid(email, code); !valid { return errors.New("This code is invalid.") } delete(a.codes, email) return nil } func CreateAuth(mailer Mailer) Auth { return Auth{ codes: make(map[string]Code), mailer: mailer, } }