@@ -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 {
@@ -85,11 +93,13 @@ export default class Contentpass implements ContentpassInterface {
8593
8694 throw err ;
8795 }
96+ logger . info ( 'Authentication flow finished, checking subscription...' ) ;
8897
8998 await this . onNewAuthState ( result ) ;
9099 } ;
91100
92101 public registerObserver ( observer : ContentpassObserver ) {
102+ logger . info ( 'Registering observer' ) ;
93103 if ( this . contentpassStateObservers . includes ( observer ) ) {
94104 return ;
95105 }
@@ -99,12 +109,14 @@ export default class Contentpass implements ContentpassInterface {
99109 }
100110
101111 public unregisterObserver ( observer : ContentpassObserver ) {
112+ logger . info ( 'Unregistering observer' ) ;
102113 this . contentpassStateObservers = this . contentpassStateObservers . filter (
103114 ( o ) => o !== observer
104115 ) ;
105116 }
106117
107118 public logout = async ( ) => {
119+ logger . info ( 'Logging out and clearing auth state' ) ;
108120 await this . authStateStorage . clearOidcAuthState ( ) ;
109121 this . changeContentpassState ( {
110122 state : ContentpassStateType . UNAUTHENTICATED ,
@@ -113,6 +125,7 @@ export default class Contentpass implements ContentpassInterface {
113125 } ;
114126
115127 public recoverFromError = async ( ) => {
128+ logger . info ( 'Recovering from error' ) ;
116129 this . changeContentpassState ( {
117130 state : ContentpassStateType . INITIALISING ,
118131 } ) ;
@@ -137,6 +150,7 @@ export default class Contentpass implements ContentpassInterface {
137150 } ;
138151
139152 private countPaidImpression = async ( ) => {
153+ logger . info ( 'Counting paid impression' ) ;
140154 const impressionId = uuid . v4 ( ) ;
141155
142156 await sendPageViewEvent ( this . config . apiUrl , {
@@ -154,6 +168,7 @@ export default class Contentpass implements ContentpassInterface {
154168 return ;
155169 }
156170
171+ logger . info ( 'Counting sampled impression' ) ;
157172 await sendStats ( this . config . apiUrl , {
158173 ea : 'load' ,
159174 ec : 'tcf-sampled' ,
@@ -166,38 +181,49 @@ export default class Contentpass implements ContentpassInterface {
166181 private initialiseAuthState = async ( ) => {
167182 const authState = await this . authStateStorage . getOidcAuthState ( ) ;
168183 if ( authState ) {
184+ logger . debug ( 'Found auth state in storage, initialising with it' ) ;
169185 await this . onNewAuthState ( authState ) ;
170186 return ;
171187 }
172188
189+ logger . debug (
190+ 'No auth state found in storage, initialising unauthenticated'
191+ ) ;
173192 this . changeContentpassState ( {
174193 state : ContentpassStateType . UNAUTHENTICATED ,
175194 hasValidSubscription : false ,
176195 } ) ;
177196 } ;
178197
179198 private onNewAuthState = async ( authState : OidcAuthState ) => {
199+ logger . debug ( 'New auth state received' ) ;
180200 this . oidcAuthState = authState ;
181201 await this . authStateStorage . storeOidcAuthState ( authState ) ;
182202
183203 const strategy = this . setupRefreshTimer ( ) ;
184204 // if instant refresh, no need to check subscription as it will happen in the refresh
185205 if ( strategy === RefreshTokenStrategy . INSTANTLY ) {
206+ logger . debug ( 'Instant refresh, skipping subscription check' ) ;
186207 return ;
187208 }
188209
189210 try {
211+ logger . info ( 'Checking subscription' ) ;
190212 const contentpassToken = await fetchContentpassToken ( {
191213 issuer : this . config . issuer ,
192214 propertyId : this . config . propertyId ,
193215 idToken : this . oidcAuthState . idToken ,
194216 } ) ;
195217 const hasValidSubscription = validateSubscription ( contentpassToken ) ;
218+ logger . info ( { hasValidSubscription } , 'Subscription check successful' ) ;
196219 this . changeContentpassState ( {
197220 state : ContentpassStateType . AUTHENTICATED ,
198221 hasValidSubscription,
199222 } ) ;
200223 } catch ( err : any ) {
224+ reportError ( err , {
225+ msg : 'Failed to fetch contentpass token and validate subscription' ,
226+ } ) ;
201227 this . changeContentpassState ( {
202228 state : ContentpassStateType . ERROR ,
203229 error : err ,
@@ -210,13 +236,15 @@ export default class Contentpass implements ContentpassInterface {
210236 this . oidcAuthState ?. accessTokenExpirationDate ;
211237
212238 if ( ! accessTokenExpirationDate ) {
239+ logger . warn ( 'No access token expiration date provided' ) ;
213240 return RefreshTokenStrategy . NO_REFRESH ;
214241 }
215242
216243 const now = new Date ( ) ;
217244 const expirationDate = new Date ( accessTokenExpirationDate ) ;
218245 const timeDiff = expirationDate . getTime ( ) - now . getTime ( ) ;
219246 if ( timeDiff <= 0 ) {
247+ logger . debug ( 'Access token expired, refreshing instantly' ) ;
220248 this . refreshToken ( 0 ) ;
221249 return RefreshTokenStrategy . INSTANTLY ;
222250 }
@@ -225,6 +253,7 @@ export default class Contentpass implements ContentpassInterface {
225253 clearTimeout ( this . refreshTimer ) ;
226254 }
227255
256+ logger . debug ( { timeDiff } , 'Setting up refresh timer' ) ;
228257 this . refreshTimer = setTimeout ( async ( ) => {
229258 await this . refreshToken ( 0 ) ;
230259 } , timeDiff ) ;
@@ -239,6 +268,7 @@ export default class Contentpass implements ContentpassInterface {
239268 }
240269
241270 try {
271+ logger . info ( 'Refreshing token' ) ;
242272 const refreshResult = await refresh (
243273 {
244274 clientId : this . config . propertyId ,
@@ -251,23 +281,26 @@ export default class Contentpass implements ContentpassInterface {
251281 }
252282 ) ;
253283 await this . onNewAuthState ( refreshResult ) ;
284+ logger . info ( 'Token refreshed successfully' ) ;
254285 } catch ( err : any ) {
255286 await this . onRefreshTokenError ( counter , err ) ;
256287 }
257288 } ;
258289
259290 private onRefreshTokenError = async ( counter : number , err : Error ) => {
260- reportError ( err , {
261- msg : `Failed to refresh token after ${ counter } retries` ,
262- } ) ;
263291 // FIXME: add handling for specific error to not retry in every case
264292 if ( counter < REFRESH_TOKEN_RETRIES ) {
293+ logger . warn ( { err, counter } , 'Failed to refresh token, retrying' ) ;
265294 const delay = counter * 1000 * 10 ;
266295 await new Promise ( ( resolve ) => setTimeout ( resolve , delay ) ) ;
267296 await this . refreshToken ( counter + 1 ) ;
268297 return ;
269298 }
270299
300+ reportError ( err , {
301+ msg : `Failed to refresh token after ${ counter } retries` ,
302+ } ) ;
303+
271304 await this . logout ( ) ;
272305 } ;
273306
0 commit comments