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