Add HTTP /v1 MVC, TCP send path, groups with server-side member-avatar collage, object-storage upload, and friends/favorites around the architecture-v3 layout. Co-authored-by: Cursor <cursoragent@cursor.com>
58 lines
1.3 KiB
Go
58 lines
1.3 KiB
Go
package model
|
|
|
|
import (
|
|
"context"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
type MemoryCodes struct {
|
|
mu sync.Mutex
|
|
codes map[string]codeEntry
|
|
cooldowns map[string]time.Time
|
|
}
|
|
|
|
type codeEntry struct {
|
|
code string
|
|
exp time.Time
|
|
}
|
|
|
|
func NewMemoryCodes() *MemoryCodes {
|
|
return &MemoryCodes{codes: make(map[string]codeEntry), cooldowns: make(map[string]time.Time)}
|
|
}
|
|
|
|
func (m *MemoryCodes) Put(_ context.Context, email, code string, ttlSeconds int) error {
|
|
m.mu.Lock()
|
|
defer m.mu.Unlock()
|
|
m.codes[email] = codeEntry{code: code, exp: time.Now().Add(time.Duration(ttlSeconds) * time.Second)}
|
|
return nil
|
|
}
|
|
|
|
func (m *MemoryCodes) Get(_ context.Context, email string) (string, error) {
|
|
m.mu.Lock()
|
|
defer m.mu.Unlock()
|
|
e, ok := m.codes[email]
|
|
if !ok || time.Now().After(e.exp) {
|
|
delete(m.codes, email)
|
|
return "", nil
|
|
}
|
|
return e.code, nil
|
|
}
|
|
|
|
func (m *MemoryCodes) Del(_ context.Context, email string) error {
|
|
m.mu.Lock()
|
|
defer m.mu.Unlock()
|
|
delete(m.codes, email)
|
|
return nil
|
|
}
|
|
|
|
func (m *MemoryCodes) SetCooldown(_ context.Context, email string, ttlSeconds int) (bool, error) {
|
|
m.mu.Lock()
|
|
defer m.mu.Unlock()
|
|
if exp, ok := m.cooldowns[email]; ok && time.Now().Before(exp) {
|
|
return false, nil
|
|
}
|
|
m.cooldowns[email] = time.Now().Add(time.Duration(ttlSeconds) * time.Second)
|
|
return true, nil
|
|
}
|