@@ -176,8 +176,9 @@ export interface CheckEvent {
176176 missingContextFields ?: string [ ] ;
177177}
178178
179- const localStorageFetchedFlagsKey = `__reflag_fetched_flags` ;
180179const storageOverridesKey = `__reflag_overrides` ;
180+ const REFRESH_LIMIT_COUNT = 10 ;
181+ const REFRESH_LIMIT_WINDOW_MS = 5 * 60 * 1000 ;
181182
182183export type FlagOverrides = Record < string , boolean | undefined > ;
183184
@@ -205,6 +206,7 @@ export class FlagsClient {
205206 private flags : RawFlags = { } ;
206207 private fallbackFlags : FallbackFlags = { } ;
207208 private storage : StorageAdapter | null ;
209+ private refreshEvents : number [ ] = [ ] ;
208210
209211 private config : Config = DEFAULT_FLAGS_CONFIG ;
210212
@@ -232,7 +234,11 @@ export class FlagsClient {
232234 this . logger = loggerWithPrefix ( logger , "[Flags]" ) ;
233235 this . rateLimiter =
234236 rateLimiter ?? new RateLimiter ( FLAG_EVENTS_PER_MIN , this . logger ) ;
235- this . storage = resolveStorageAdapter ( cache ? undefined : storage ) ;
237+ const storageResolution = resolveStorageAdapter (
238+ cache ? undefined : storage ,
239+ ) ;
240+ this . storage = storageResolution . adapter ;
241+ this . logger . debug ( `storage adapter: ${ storageResolution . type } ` ) ;
236242 this . cache =
237243 cache ??
238244 this . setupCache ( this . config . staleTimeMs , this . config . expireTimeMs ) ;
@@ -416,6 +422,17 @@ export class FlagsClient {
416422 return ;
417423 }
418424
425+ // rate limit refreshes to prevent accidental abuse
426+ const now = Date . now ( ) ;
427+ this . refreshEvents = this . refreshEvents . filter (
428+ ( timestamp ) => now - timestamp < REFRESH_LIMIT_WINDOW_MS ,
429+ ) ;
430+ if ( this . refreshEvents . length >= REFRESH_LIMIT_COUNT ) {
431+ this . logger . warn ( "refresh rate limit exceeded" ) ;
432+ return ;
433+ }
434+ this . refreshEvents . push ( now ) ;
435+
419436 const flags = await this . fetchFlags ( ) ;
420437 if ( flags ) {
421438 this . setFetchedFlags ( flags ) ;
@@ -533,7 +550,6 @@ export class FlagsClient {
533550 private setupCache ( staleTimeMs = 0 , expireTimeMs = FLAGS_EXPIRE_MS ) {
534551 return new FlagCache ( {
535552 storage : this . storage ,
536- storageKey : localStorageFetchedFlagsKey ,
537553 staleTimeMs,
538554 expireTimeMs,
539555 } ) ;
0 commit comments