1
1
import { version } from '../package.json' ;
2
- import { Uid2Identity } from './Uid2Identity' ;
2
+ import { OptoutIdentity , Uid2Identity , isOptoutIdentity } from './Uid2Identity' ;
3
3
import { IdentityStatus , notifyInitCallback } from './Uid2InitCallbacks' ;
4
4
import { Uid2Options , isUID2OptionsOrThrow } from './Uid2Options' ;
5
5
import { Logger , MakeLogger } from './sdk/logger' ;
@@ -56,7 +56,7 @@ export abstract class UID2SdkBase {
56
56
// State
57
57
private _product : ProductDetails ;
58
58
private _opts : Uid2Options = { } ;
59
- private _identity : Uid2Identity | null | undefined ;
59
+ private _identity : Uid2Identity | OptoutIdentity | null | undefined ;
60
60
private _initComplete = false ;
61
61
62
62
// Sets up nearly everything, but does not run SdkLoaded callbacks - derived classes must run them.
@@ -112,17 +112,23 @@ export abstract class UID2SdkBase {
112
112
await this . callCstgAndSetIdentity ( { emailHash : emailHash } , opts ) ;
113
113
}
114
114
115
- public setIdentity ( identity : Uid2Identity ) {
115
+ public setIdentity ( identity : Uid2Identity | OptoutIdentity ) {
116
116
if ( this . _apiClient ) this . _apiClient . abortActiveRequests ( ) ;
117
117
const validatedIdentity = this . validateAndSetIdentity ( identity ) ;
118
118
if ( validatedIdentity ) {
119
- this . triggerRefreshOrSetTimer ( validatedIdentity ) ;
119
+ if ( isOptoutIdentity ( validatedIdentity ) ) {
120
+ this . _callbackManager . runCallbacks ( EventType . OptoutReceived , { } ) ;
121
+ } else {
122
+ this . triggerRefreshOrSetTimer ( validatedIdentity ) ;
123
+ }
120
124
this . _callbackManager . runCallbacks ( EventType . IdentityUpdated , { } ) ;
121
125
}
122
126
}
123
127
124
128
public getIdentity ( ) : Uid2Identity | null {
125
- return this . _identity && ! this . temporarilyUnavailable ( ) ? this . _identity : null ;
129
+ return this . _identity && ! this . temporarilyUnavailable ( ) && ! isOptoutIdentity ( this . _identity )
130
+ ? this . _identity
131
+ : null ;
126
132
}
127
133
// When the SDK has been initialized, this function should return the token
128
134
// from the most recent refresh request, if there is a request, wait for the
@@ -144,6 +150,11 @@ export abstract class UID2SdkBase {
144
150
return ! ( this . isLoggedIn ( ) || this . _apiClient ?. hasActiveRequests ( ) ) ;
145
151
}
146
152
153
+ public hasOptedOut ( ) {
154
+ if ( ! this . _initComplete ) return undefined ;
155
+ return isOptoutIdentity ( this . _identity ) ;
156
+ }
157
+
147
158
public disconnect ( ) {
148
159
this . abort ( `${ this . _product . name } SDK disconnected.` ) ;
149
160
// Note: This silently fails to clear the cookie if init hasn't been called and a cookieDomain is used!
@@ -196,9 +207,11 @@ export abstract class UID2SdkBase {
196
207
identity = this . _storageManager . loadIdentityWithFallback ( ) ;
197
208
}
198
209
const validatedIdentity = this . validateAndSetIdentity ( identity ) ;
199
- if ( validatedIdentity ) this . triggerRefreshOrSetTimer ( validatedIdentity ) ;
210
+ if ( validatedIdentity && ! isOptoutIdentity ( validatedIdentity ) )
211
+ this . triggerRefreshOrSetTimer ( validatedIdentity ) ;
200
212
this . _initComplete = true ;
201
213
this . _callbackManager ?. runCallbacks ( EventType . InitCompleted , { } ) ;
214
+ if ( this . hasOptedOut ( ) ) this . _callbackManager . runCallbacks ( EventType . OptoutReceived , { } ) ;
202
215
}
203
216
204
217
private isLoggedIn ( ) {
@@ -216,7 +229,7 @@ export abstract class UID2SdkBase {
216
229
return false ;
217
230
}
218
231
219
- private getIdentityStatus ( identity : Uid2Identity | null ) :
232
+ private getIdentityStatus ( identity : Uid2Identity | OptoutIdentity | null ) :
220
233
| {
221
234
valid : true ;
222
235
identity : Uid2Identity ;
@@ -227,7 +240,7 @@ export abstract class UID2SdkBase {
227
240
valid : false ;
228
241
errorMessage : string ;
229
242
status : IdentityStatus ;
230
- identity : null ;
243
+ identity : OptoutIdentity | null ;
231
244
} {
232
245
if ( ! identity ) {
233
246
return {
@@ -237,6 +250,14 @@ export abstract class UID2SdkBase {
237
250
identity : null ,
238
251
} ;
239
252
}
253
+ if ( isOptoutIdentity ( identity ) ) {
254
+ return {
255
+ valid : false ,
256
+ errorMessage : 'User has opted out' ,
257
+ status : IdentityStatus . OPTOUT ,
258
+ identity : identity ,
259
+ } ;
260
+ }
240
261
if ( ! identity . advertising_token ) {
241
262
return {
242
263
valid : false ,
@@ -285,21 +306,25 @@ export abstract class UID2SdkBase {
285
306
}
286
307
287
308
private validateAndSetIdentity (
288
- identity : Uid2Identity | null ,
309
+ identity : Uid2Identity | OptoutIdentity | null ,
289
310
status ?: IdentityStatus ,
290
311
statusText ?: string
291
- ) : Uid2Identity | null {
312
+ ) : Uid2Identity | OptoutIdentity | null {
292
313
if ( ! this . _storageManager ) throw new Error ( 'Cannot set identity before calling init.' ) ;
293
314
const validity = this . getIdentityStatus ( identity ) ;
294
315
if (
316
+ validity . valid &&
295
317
validity . identity &&
318
+ ! isOptoutIdentity ( this . _identity ) &&
296
319
validity . identity ?. advertising_token === this . _identity ?. advertising_token
297
320
)
298
321
return validity . identity ;
299
322
300
323
this . _identity = validity . identity ;
301
- if ( validity . identity ) {
302
- this . _storageManager . setValue ( validity . identity ) ;
324
+ if ( validity . valid && validity . identity ) {
325
+ this . _storageManager . setIdentity ( validity . identity ) ;
326
+ } else if ( validity . status === IdentityStatus . OPTOUT || status === IdentityStatus . OPTOUT ) {
327
+ this . _storageManager . setOptout ( ) ;
303
328
} else {
304
329
this . abort ( ) ;
305
330
this . _storageManager . removeValues ( ) ;
@@ -334,7 +359,8 @@ export abstract class UID2SdkBase {
334
359
const validatedIdentity = this . validateAndSetIdentity (
335
360
this . _storageManager ?. loadIdentity ( ) ?? null
336
361
) ;
337
- if ( validatedIdentity ) this . triggerRefreshOrSetTimer ( validatedIdentity ) ;
362
+ if ( validatedIdentity && ! isOptoutIdentity ( validatedIdentity ) )
363
+ this . triggerRefreshOrSetTimer ( validatedIdentity ) ;
338
364
this . _refreshTimerId = null ;
339
365
} , timeout ) ;
340
366
}
@@ -358,6 +384,7 @@ export abstract class UID2SdkBase {
358
384
break ;
359
385
case 'optout' :
360
386
this . validateAndSetIdentity ( null , IdentityStatus . OPTOUT , 'User opted out' ) ;
387
+ this . _callbackManager . runCallbacks ( EventType . OptoutReceived , { } ) ;
361
388
break ;
362
389
case 'expired_token' :
363
390
this . validateAndSetIdentity (
@@ -387,8 +414,17 @@ export abstract class UID2SdkBase {
387
414
opts : ClientSideIdentityOptions
388
415
) {
389
416
const cstgResult = await this . _apiClient ! . callCstgApi ( request , opts ) ;
390
-
391
- this . setIdentity ( cstgResult . identity ) ;
417
+ if ( cstgResult . status == 'success' ) {
418
+ this . setIdentity ( cstgResult . identity ) ;
419
+ } else if ( cstgResult . status === 'optout' ) {
420
+ this . validateAndSetIdentity ( null , IdentityStatus . OPTOUT ) ;
421
+ this . _callbackManager . runCallbacks ( EventType . OptoutReceived , { } ) ;
422
+ this . _callbackManager . runCallbacks ( EventType . IdentityUpdated , { } ) ;
423
+ } else {
424
+ const errorText = 'Unexpected status received from CSTG endpoint.' ;
425
+ this . _logger . warn ( errorText ) ;
426
+ throw new Error ( errorText ) ;
427
+ }
392
428
}
393
429
394
430
protected throwIfInitNotComplete ( message : string ) {
0 commit comments