@@ -15,7 +15,7 @@ import type { OAuth2Tokens } from '../oauth2-client';
1515import OAuth2Client , { allowedErrors , ResponseType } from '../oauth2-client' ;
1616import type { StringDict , Tokens } from '../shared/interfaces' ;
1717import TokenStorage from '../token-storage' ;
18- import PKCE from '../util/ pkce' ;
18+ import { generateAndStoreAuthUrlValues , getStoredAuthUrlValues } from '../oauth2-client/state- pkce' ;
1919import { parseQuery } from '../util/url' ;
2020import { tokensWillExpireWithinThreshold } from './helpers' ;
2121
@@ -39,7 +39,7 @@ abstract class TokenManager {
3939 forceRenew: true, // If you want to get new tokens, despite existing ones
4040 login: 'embedded', // If user authentication is handled in-app
4141 serverConfig: {
42- timeout: 5000, // If using "legacy", use a short timeout to catch error
42+ timeout: 5000,
4343 },
4444 });
4545 ```
@@ -65,9 +65,11 @@ abstract class TokenManager {
6565 ```
6666 */
6767 public static async getTokens ( options ?: GetTokensOptions ) : Promise < OAuth2Tokens | void > {
68- const { clientId, oauthThreshold } = Config . get ( options as ConfigOptions ) ;
69- // const storageKey = `${Config.get().prefix}-authflow-${clientId}`;
70- const storageKey = `${ Config . get ( ) . prefix } -authflow-${ clientId } ` ;
68+ const { clientId, oauthThreshold, prefix } = Config . get ( options as ConfigOptions ) ;
69+
70+ if ( ! clientId ) {
71+ throw new Error ( 'Client ID is required' ) ;
72+ }
7173
7274 /**
7375 * First, let's see if tokens exist locally
@@ -105,33 +107,31 @@ abstract class TokenManager {
105107 * and return acquired tokens
106108 */
107109 if ( options ?. query ?. code && options ?. query ?. state ) {
108- const storedString = sessionStorage . getItem ( storageKey ) ;
109- sessionStorage . removeItem ( storageKey ) ;
110- const storedValues : { state : string ; verifier : string } = JSON . parse ( storedString as string ) ;
110+ const { state, verifier } = getStoredAuthUrlValues ( clientId , prefix ) ;
111111
112- return await this . tokenExchange ( options , storedValues ) ;
112+ if ( state === undefined || verifier === undefined ) {
113+ throw new Error (
114+ '`state` and/or `verifier` not found in sessionStorage. Debugging: sessionStorage is not accessible in separate tabs.' ,
115+ ) ;
116+ }
117+ return await this . tokenExchange ( options , { state, verifier } ) ;
113118 }
114119
115- /**
116- * If we are here, then we are just beginning the auth code flow,
117- * so let's generate authorize PKCE values and URL
118- */
119- const verifier = PKCE . createVerifier ( ) ;
120- const state = PKCE . createState ( ) ;
121-
122120 // so to not change the type of the above function
123121 // we assign it here if its undefined or null.
124-
125122 const config = Object . assign ( { } , options ) ;
126123 delete config . forceRenew ;
127- delete config . login ;
128124
129- const authorizeUrlOptions = {
125+ /**
126+ * Generate state and verifier for PKCE
127+ */
128+ const { authorizeUrlOptions } = generateAndStoreAuthUrlValues ( {
130129 ...config ,
130+ clientId,
131+ prefix,
131132 responseType : ResponseType . Code ,
132- state,
133- verifier,
134- } ;
133+ } ) ;
134+
135135 /**
136136 * Attempt to call the authorize URL to retrieve authorization code
137137 */
@@ -178,17 +178,17 @@ abstract class TokenManager {
178178 throw err ;
179179 }
180180
181- // Since `login` is configured for "redirect", store authorize values and redirect
182- sessionStorage . setItem ( storageKey , JSON . stringify ( authorizeUrlOptions ) ) ;
183-
184181 const authorizeUrl = await OAuth2Client . createAuthorizeUrl ( authorizeUrlOptions ) ;
185182
186183 return location . assign ( authorizeUrl ) ;
187184 }
188185 /**
189186 * Exchange authorization code for tokens
190187 */
191- return await this . tokenExchange ( options , { state, verifier } ) ;
188+ return await this . tokenExchange ( options , {
189+ state : authorizeUrlOptions . state ,
190+ verifier : authorizeUrlOptions . verifier ,
191+ } ) ;
192192 }
193193
194194 public static async deleteTokens ( ) : Promise < void > {
0 commit comments