11import * as AuthSession from "expo-auth-session" ;
2- import * as Crypto from "expo-crypto" ;
32import * as WebBrowser from "expo-web-browser" ;
43import {
54 getCloudUrlFromRegion ,
@@ -14,26 +13,6 @@ import type {
1413// Required for web browser auth session to work properly
1514WebBrowser . maybeCompleteAuthSession ( ) ;
1615
17- // Generate PKCE code verifier and challenge
18- async function generateCodeVerifier ( ) : Promise < string > {
19- const randomBytes = await Crypto . getRandomBytesAsync ( 32 ) ;
20- return btoa ( String . fromCharCode ( ...randomBytes ) )
21- . replace ( / \+ / g, "-" )
22- . replace ( / \/ / g, "_" )
23- . replace ( / = / g, "" ) ;
24- }
25-
26- async function generateCodeChallenge ( verifier : string ) : Promise < string > {
27- const encoder = new TextEncoder ( ) ;
28- const data = encoder . encode ( verifier ) ;
29- const digest = await Crypto . digest ( Crypto . CryptoDigestAlgorithm . SHA256 , data ) ;
30-
31- return btoa ( String . fromCharCode ( ...new Uint8Array ( digest ) ) )
32- . replace ( / \+ / g, "-" )
33- . replace ( / \/ / g, "_" )
34- . replace ( / = / g, "" ) ;
35- }
36-
3716export function getRedirectUri ( ) : string {
3817 return AuthSession . makeRedirectUri ( {
3918 scheme : "posthog-mobile" ,
@@ -57,6 +36,10 @@ export async function exchangeCodeForToken(
5736 const cloudUrl = getCloudUrlFromRegion ( config . cloudRegion ) ;
5837 const redirectUri = getRedirectUri ( ) ;
5938
39+ console . log ( "[OAuth Token Exchange] URL:" , `${ cloudUrl } /oauth/token` ) ;
40+ console . log ( "[OAuth Token Exchange] Redirect URI:" , redirectUri ) ;
41+ console . log ( "[OAuth Token Exchange] Code:" , code ) ;
42+
6043 const response = await fetch ( `${ cloudUrl } /oauth/token` , {
6144 method : "POST" ,
6245 headers : {
@@ -116,29 +99,33 @@ export async function performOAuthFlow(
11699 config : OAuthConfig ,
117100) : Promise < OAuthFlowResult > {
118101 try {
119- const codeVerifier = await generateCodeVerifier ( ) ;
120- const codeChallenge = await generateCodeChallenge ( codeVerifier ) ;
121102 const redirectUri = getRedirectUri ( ) ;
122103 const clientId = getOauthClientIdFromRegion ( config . cloudRegion ) ;
123104
105+ console . log ( "[OAuth] Redirect URI:" , redirectUri ) ;
106+ console . log ( "[OAuth] Client ID:" , clientId ) ;
107+
124108 const discovery : AuthSession . DiscoveryDocument = {
125109 authorizationEndpoint : getAuthorizationEndpoint ( config . cloudRegion ) ,
126110 tokenEndpoint : getTokenEndpoint ( config . cloudRegion ) ,
127111 } ;
128112
113+ // Let expo-auth-session handle PKCE internally
129114 const authRequest = new AuthSession . AuthRequest ( {
130115 clientId,
131116 scopes : config . scopes ,
132117 redirectUri,
133- codeChallenge,
134- codeChallengeMethod : AuthSession . CodeChallengeMethod . S256 ,
118+ usePKCE : true ,
135119 extraParams : {
136120 required_access_level : "project" ,
137121 } ,
138122 } ) ;
139123
124+ // promptAsync will load the request internally and generate PKCE
140125 const authResult = await authRequest . promptAsync ( discovery ) ;
141126
127+ console . log ( "[OAuth] Code Verifier:" , authRequest . codeVerifier ) ;
128+
142129 if ( authResult . type === "cancel" || authResult . type === "dismiss" ) {
143130 return {
144131 success : false ,
@@ -160,9 +147,17 @@ export async function performOAuthFlow(
160147 } ;
161148 }
162149
150+ // Use the AuthRequest's codeVerifier for token exchange
151+ if ( ! authRequest . codeVerifier ) {
152+ return {
153+ success : false ,
154+ error : "PKCE code verifier not available" ,
155+ } ;
156+ }
157+
163158 const tokenResponse = await exchangeCodeForToken (
164159 authResult . params . code ,
165- codeVerifier ,
160+ authRequest . codeVerifier ,
166161 config ,
167162 ) ;
168163
0 commit comments