| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 | package commonimport (	"github.com/google/uuid"	"strings"	"sync"	"time")type verificationValue struct {	code string	time time.Time}const (	EmailVerificationPurpose = "v"	PasswordResetPurpose     = "r")var verificationMutex sync.Mutexvar verificationMap map[string]verificationValuevar verificationMapMaxSize = 10var VerificationValidMinutes = 10func GenerateVerificationCode(length int) string {	code := uuid.New().String()	code = strings.Replace(code, "-", "", -1)	if length == 0 {		return code	}	return code[:length]}func RegisterVerificationCodeWithKey(key string, code string, purpose string) {	verificationMutex.Lock()	defer verificationMutex.Unlock()	verificationMap[purpose+key] = verificationValue{		code: code,		time: time.Now(),	}	if len(verificationMap) > verificationMapMaxSize {		removeExpiredPairs()	}}func VerifyCodeWithKey(key string, code string, purpose string) bool {	verificationMutex.Lock()	defer verificationMutex.Unlock()	value, okay := verificationMap[purpose+key]	now := time.Now()	if !okay || int(now.Sub(value.time).Seconds()) >= VerificationValidMinutes*60 {		return false	}	return code == value.code}func DeleteKey(key string, purpose string) {	verificationMutex.Lock()	defer verificationMutex.Unlock()	delete(verificationMap, purpose+key)}// no lock inside, so the caller must lock the verificationMap before calling!func removeExpiredPairs() {	now := time.Now()	for key := range verificationMap {		if int(now.Sub(verificationMap[key].time).Seconds()) >= VerificationValidMinutes*60 {			delete(verificationMap, key)		}	}}func init() {	verificationMutex.Lock()	defer verificationMutex.Unlock()	verificationMap = make(map[string]verificationValue)}
 |