@@ -19,6 +19,7 @@ import type { ContentpassConfig } from './types/ContentpassConfig';
1919import { reportError , setSentryExtraAttribute } from './sentryIntegration' ;
2020import sendStats from './countImpressionUtils/sendStats' ;
2121import sendPageViewEvent from './countImpressionUtils/sendPageViewEvent' ;
22+ import logger , { enableLogger } from './logger' ;
2223
2324const DEFAULT_SAMPLING_RATE = 0.05 ;
2425
@@ -47,10 +48,16 @@ export default class Contentpass implements ContentpassInterface {
4748 private refreshTimer : NodeJS . Timeout | null = null ;
4849
4950 constructor ( config : ContentpassConfig ) {
51+ if ( config . logLevel ) {
52+ enableLogger ( config . logLevel ) ;
53+ }
54+
55+ logger . debug ( 'Contentpass initialised with config' , config ) ;
5056 if (
5157 config . samplingRate &&
5258 ( config . samplingRate < 0 || config . samplingRate > 1 )
5359 ) {
60+ logger . error ( 'Sampling rate must be between 0 and 1' ) ;
5461 throw new Error ( 'Sampling rate must be between 0 and 1' ) ;
5562 }
5663 this . samplingRate = config . samplingRate || DEFAULT_SAMPLING_RATE ;
@@ -62,6 +69,7 @@ export default class Contentpass implements ContentpassInterface {
6269 }
6370
6471 public authenticate = async ( ) : Promise < void > => {
72+ logger . info ( 'Starting authentication flow' ) ;
6573 let result : AuthorizeResult ;
6674
6775 try {
@@ -86,11 +94,13 @@ export default class Contentpass implements ContentpassInterface {
8694
8795 throw err ;
8896 }
97+ logger . info ( 'Authentication flow finished, checking subscription...' ) ;
8998
9099 await this . onNewAuthState ( result ) ;
91100 } ;
92101
93102 public registerObserver ( observer : ContentpassObserver ) {
103+ logger . info ( 'Registering observer' ) ;
94104 if ( this . contentpassStateObservers . includes ( observer ) ) {
95105 return ;
96106 }
@@ -100,12 +110,14 @@ export default class Contentpass implements ContentpassInterface {
100110 }
101111
102112 public unregisterObserver ( observer : ContentpassObserver ) {
113+ logger . info ( 'Unregistering observer' ) ;
103114 this . contentpassStateObservers = this . contentpassStateObservers . filter (
104115 ( o ) => o !== observer
105116 ) ;
106117 }
107118
108119 public logout = async ( ) => {
120+ logger . info ( 'Logging out and clearing auth state' ) ;
109121 await this . authStateStorage . clearOidcAuthState ( ) ;
110122 this . changeContentpassState ( {
111123 state : ContentpassStateType . UNAUTHENTICATED ,
@@ -114,6 +126,7 @@ export default class Contentpass implements ContentpassInterface {
114126 } ;
115127
116128 public recoverFromError = async ( ) => {
129+ logger . info ( 'Recovering from error' ) ;
117130 this . changeContentpassState ( {
118131 state : ContentpassStateType . INITIALISING ,
119132 } ) ;
@@ -138,6 +151,7 @@ export default class Contentpass implements ContentpassInterface {
138151 } ;
139152
140153 private countPaidImpression = async ( ) => {
154+ logger . info ( 'Counting paid impression' ) ;
141155 const impressionId = uuid . v4 ( ) ;
142156
143157 await sendPageViewEvent ( this . config . apiUrl , {
@@ -155,6 +169,7 @@ export default class Contentpass implements ContentpassInterface {
155169 return ;
156170 }
157171
172+ logger . info ( 'Counting sampled impression' ) ;
158173 await sendStats ( this . config . apiUrl , {
159174 ea : 'load' ,
160175 ec : 'tcf-sampled' ,
@@ -167,38 +182,49 @@ export default class Contentpass implements ContentpassInterface {
167182 private initialiseAuthState = async ( ) => {
168183 const authState = await this . authStateStorage . getOidcAuthState ( ) ;
169184 if ( authState ) {
185+ logger . debug ( 'Found auth state in storage, initialising with it' ) ;
170186 await this . onNewAuthState ( authState ) ;
171187 return ;
172188 }
173189
190+ logger . debug (
191+ 'No auth state found in storage, initialising unauthenticated'
192+ ) ;
174193 this . changeContentpassState ( {
175194 state : ContentpassStateType . UNAUTHENTICATED ,
176195 hasValidSubscription : false ,
177196 } ) ;
178197 } ;
179198
180199 private onNewAuthState = async ( authState : OidcAuthState ) => {
200+ logger . debug ( 'New auth state received' ) ;
181201 this . oidcAuthState = authState ;
182202 await this . authStateStorage . storeOidcAuthState ( authState ) ;
183203
184204 const strategy = this . setupRefreshTimer ( ) ;
185205 // if instant refresh, no need to check subscription as it will happen in the refresh
186206 if ( strategy === RefreshTokenStrategy . INSTANTLY ) {
207+ logger . debug ( 'Instant refresh, skipping subscription check' ) ;
187208 return ;
188209 }
189210
190211 try {
212+ logger . info ( 'Checking subscription' ) ;
191213 const contentpassToken = await fetchContentpassToken ( {
192214 issuer : this . config . issuer ,
193215 propertyId : this . config . propertyId ,
194216 idToken : this . oidcAuthState . idToken ,
195217 } ) ;
196218 const hasValidSubscription = validateSubscription ( contentpassToken ) ;
219+ logger . info ( { hasValidSubscription } , 'Subscription check successful' ) ;
197220 this . changeContentpassState ( {
198221 state : ContentpassStateType . AUTHENTICATED ,
199222 hasValidSubscription,
200223 } ) ;
201224 } catch ( err : any ) {
225+ reportError ( err , {
226+ msg : 'Failed to fetch contentpass token and validate subscription' ,
227+ } ) ;
202228 this . changeContentpassState ( {
203229 state : ContentpassStateType . ERROR ,
204230 error : err ,
@@ -211,13 +237,15 @@ export default class Contentpass implements ContentpassInterface {
211237 this . oidcAuthState ?. accessTokenExpirationDate ;
212238
213239 if ( ! accessTokenExpirationDate ) {
240+ logger . warn ( 'No access token expiration date provided' ) ;
214241 return RefreshTokenStrategy . NO_REFRESH ;
215242 }
216243
217244 const now = new Date ( ) ;
218245 const expirationDate = new Date ( accessTokenExpirationDate ) ;
219246 const timeDiff = expirationDate . getTime ( ) - now . getTime ( ) ;
220247 if ( timeDiff <= 0 ) {
248+ logger . debug ( 'Access token expired, refreshing instantly' ) ;
221249 this . refreshToken ( 0 ) ;
222250 return RefreshTokenStrategy . INSTANTLY ;
223251 }
@@ -226,6 +254,7 @@ export default class Contentpass implements ContentpassInterface {
226254 clearTimeout ( this . refreshTimer ) ;
227255 }
228256
257+ logger . debug ( { timeDiff } , 'Setting up refresh timer' ) ;
229258 this . refreshTimer = setTimeout ( async ( ) => {
230259 await this . refreshToken ( 0 ) ;
231260 } , timeDiff ) ;
@@ -240,6 +269,7 @@ export default class Contentpass implements ContentpassInterface {
240269 }
241270
242271 try {
272+ logger . info ( 'Refreshing token' ) ;
243273 const refreshResult = await refresh (
244274 {
245275 clientId : this . config . propertyId ,
@@ -252,23 +282,26 @@ export default class Contentpass implements ContentpassInterface {
252282 }
253283 ) ;
254284 await this . onNewAuthState ( refreshResult ) ;
285+ logger . info ( 'Token refreshed successfully' ) ;
255286 } catch ( err : any ) {
256287 await this . onRefreshTokenError ( counter , err ) ;
257288 }
258289 } ;
259290
260291 private onRefreshTokenError = async ( counter : number , err : Error ) => {
261- reportError ( err , {
262- msg : `Failed to refresh token after ${ counter } retries` ,
263- } ) ;
264292 // FIXME: add handling for specific error to not retry in every case
265293 if ( counter < REFRESH_TOKEN_RETRIES ) {
294+ logger . warn ( { err, counter } , 'Failed to refresh token, retrying' ) ;
266295 const delay = counter * 1000 * 10 ;
267296 await new Promise ( ( resolve ) => setTimeout ( resolve , delay ) ) ;
268297 await this . refreshToken ( counter + 1 ) ;
269298 return ;
270299 }
271300
301+ reportError ( err , {
302+ msg : `Failed to refresh token after ${ counter } retries` ,
303+ } ) ;
304+
272305 await this . logout ( ) ;
273306 } ;
274307
0 commit comments