@@ -23,10 +23,16 @@ import {
23
23
} from '../../model/popup_redirect' ;
24
24
import { AUTH_ERROR_FACTORY , AuthErrorCode } from '../errors' ;
25
25
26
+ // The amount of time to store the UIDs of seen events; this is
27
+ // set to 10 min by default
28
+ const EVENT_DUPLICATION_CACHE_DURATION_MS = 10 * 60 * 1000 ;
29
+
26
30
export class AuthEventManager implements EventManager {
31
+ private readonly cachedEventUids : Set < string > = new Set ( ) ;
27
32
private readonly consumers : Set < AuthEventConsumer > = new Set ( ) ;
28
33
private queuedRedirectEvent : AuthEvent | null = null ;
29
34
private hasHandledPotentialRedirect = false ;
35
+ private lastProcessedEventTime = Date . now ( ) ;
30
36
31
37
constructor ( private readonly appName : string ) { }
32
38
@@ -38,6 +44,7 @@ export class AuthEventManager implements EventManager {
38
44
this . isEventForConsumer ( this . queuedRedirectEvent , authEventConsumer )
39
45
) {
40
46
this . sendToConsumer ( this . queuedRedirectEvent , authEventConsumer ) ;
47
+ this . saveEventToCache ( this . queuedRedirectEvent ) ;
41
48
this . queuedRedirectEvent = null ;
42
49
}
43
50
}
@@ -47,11 +54,17 @@ export class AuthEventManager implements EventManager {
47
54
}
48
55
49
56
onEvent ( event : AuthEvent ) : boolean {
57
+ // Check if the event has already been handled
58
+ if ( this . hasEventBeenHandled ( event ) ) {
59
+ return false ;
60
+ }
61
+
50
62
let handled = false ;
51
63
this . consumers . forEach ( consumer => {
52
64
if ( this . isEventForConsumer ( event , consumer ) ) {
53
65
handled = true ;
54
66
this . sendToConsumer ( event , consumer ) ;
67
+ this . saveEventToCache ( event ) ;
55
68
}
56
69
} ) ;
57
70
@@ -96,6 +109,26 @@ export class AuthEventManager implements EventManager {
96
109
( ! ! event . eventId && event . eventId === consumer . eventId ) ;
97
110
return consumer . filter . includes ( event . type ) && eventIdMatches ;
98
111
}
112
+
113
+ private hasEventBeenHandled ( event : AuthEvent ) : boolean {
114
+ if (
115
+ Date . now ( ) - this . lastProcessedEventTime >=
116
+ EVENT_DUPLICATION_CACHE_DURATION_MS
117
+ ) {
118
+ this . cachedEventUids . clear ( ) ;
119
+ }
120
+
121
+ return this . cachedEventUids . has ( eventUid ( event ) ) ;
122
+ }
123
+
124
+ private saveEventToCache ( event : AuthEvent ) : void {
125
+ this . cachedEventUids . add ( eventUid ( event ) ) ;
126
+ this . lastProcessedEventTime = Date . now ( ) ;
127
+ }
128
+ }
129
+
130
+ function eventUid ( e : AuthEvent ) : string {
131
+ return [ e . type , e . eventId , e . sessionId , e . tenantId ] . filter ( v => v ) . join ( '-' ) ;
99
132
}
100
133
101
134
function isNullRedirectEvent ( { type, error } : AuthEvent ) : boolean {
0 commit comments