Add visitor phone lookup flow
This commit is contained in:
@@ -17,6 +17,52 @@ type loginLimiter struct {
|
||||
now func() time.Time
|
||||
}
|
||||
|
||||
type queryLimitEntry struct {
|
||||
windowStart time.Time
|
||||
count int
|
||||
}
|
||||
|
||||
// queryLimiter is deliberately small and in-memory for the temporary public
|
||||
// phone lookup. The production replacement will be an OTP or external
|
||||
// identity provider, so this limiter is only a safety net for the test flow.
|
||||
type queryLimiter struct {
|
||||
mu sync.Mutex
|
||||
entries map[string]queryLimitEntry
|
||||
now func() time.Time
|
||||
limit int
|
||||
window time.Duration
|
||||
}
|
||||
|
||||
func newQueryLimiter(now func() time.Time, limit int, window time.Duration) *queryLimiter {
|
||||
return &queryLimiter{
|
||||
entries: make(map[string]queryLimitEntry), now: now, limit: limit, window: window,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *queryLimiter) allow(key string) (bool, time.Duration) {
|
||||
if l == nil || l.limit <= 0 || l.window <= 0 {
|
||||
return true, 0
|
||||
}
|
||||
l.mu.Lock()
|
||||
defer l.mu.Unlock()
|
||||
|
||||
now := l.now()
|
||||
entry, ok := l.entries[key]
|
||||
if !ok || now.Sub(entry.windowStart) >= l.window {
|
||||
entry = queryLimitEntry{windowStart: now}
|
||||
}
|
||||
if entry.count >= l.limit {
|
||||
retry := l.window - now.Sub(entry.windowStart)
|
||||
if retry < 0 {
|
||||
retry = 0
|
||||
}
|
||||
return false, retry
|
||||
}
|
||||
entry.count++
|
||||
l.entries[key] = entry
|
||||
return true, 0
|
||||
}
|
||||
|
||||
func newLoginLimiter(now func() time.Time) *loginLimiter {
|
||||
return &loginLimiter{attempts: make(map[string]loginAttempt), now: now}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user