@@ -7,10 +7,9 @@ import { sendToMatomo } from "../../lib/pluginActions";
77import { gitMatomoEventTypes } from "../../types" ;
88import { endpointUrls } from "@remix-endpoints-helper" ;
99import isElectron from "is-electron" ;
10- import { set } from "lodash" ;
11- import { use } from "chai" ;
10+ import { startGitHubLogin , getDeviceCodeFromGitHub , connectWithDeviceCode , disconnectFromGitHub } from "../../lib/gitLoginActions" ;
1211
13- export const GetDeviceCode = ( ) => {
12+ export const ConnectToGitHub = ( ) => {
1413 const context = React . useContext ( gitPluginContext )
1514 const actions = React . useContext ( gitActionsContext )
1615 const pluginActions = React . useContext ( pluginActionsContext )
@@ -21,119 +20,48 @@ export const GetDeviceCode = () => {
2120
2221 const popupRef = useRef < Window | null > ( null )
2322
24- // Dynamically select the GitHub OAuth client ID based on the hostname
25- const getClientId = async ( ) => {
26- const host = isElectron ( ) ? 'desktop' : window . location . hostname
27- // fetch it with axios from `${endpointUrls.gitHubLoginProxy}/client-id?host=${host}`
28- try {
29- const response = await axios . get ( `${ endpointUrls . gitHubLoginProxy } /client/${ host } ` , {
30- headers : {
31- 'Content-Type' : 'application/json' ,
32- 'Accept' : 'application/json'
33- }
34- } )
35- return response . data . client_id
36- }
37- catch ( error ) {
38- throw new Error ( 'Failed to fetch GitHub client ID' )
39- }
40-
41- }
42-
4323 const openPopupLogin = useCallback ( async ( ) => {
44-
45- if ( isElectron ( ) ) {
46- setDesktopIsLoading ( true )
47- pluginActions . loginWithGitHub ( )
48- return
49- }
50-
51- const clientId = await getClientId ( )
52- const redirectUri = `${ window . location . origin } /?source=github`
53- const scope = 'repo gist user:email read:user'
54-
55- const url = `https://github.com/login/oauth/authorize?client_id=${ clientId } &redirect_uri=${ encodeURIComponent ( redirectUri ) } &scope=${ encodeURIComponent ( scope ) } &response_type=code`
56-
57- const popup = window . open ( url , '_blank' , 'width=600,height=700' )
58- if ( ! popup ) {
59- console . warn ( 'Popup blocked or failed to open, falling back to device code flow.' )
60- await getDeviceCodeFromGitHub ( )
61- return
62- }
63- popupRef . current = popup
64-
65- const messageListener = async ( event : MessageEvent ) => {
66- if ( event . origin !== window . location . origin ) return
67-
68- if ( event . data . type === 'GITHUB_AUTH_SUCCESS' ) {
69- const token = event . data . token
70- await pluginActions . saveToken ( token )
71- await actions . loadGitHubUserFromToken ( )
24+ await sendToMatomo ( gitMatomoEventTypes . CONNECTTOGITHUBBUTTON )
25+ try {
26+ if ( isElectron ( ) ) {
27+ setDesktopIsLoading ( true )
28+ }
29+ await startGitHubLogin ( )
30+ if ( ! isElectron ( ) ) {
7231 setAuthorized ( true )
73- await sendToMatomo ( gitMatomoEventTypes . CONNECTTOGITHUBSUCCESS )
74- window . removeEventListener ( 'message' , messageListener )
75- popup ?. close ( )
76- } else if ( event . data . type === 'GITHUB_AUTH_FAILURE' ) {
32+ }
33+ } catch ( error ) {
34+ console . error ( 'GitHub login failed:' , error )
35+ if ( isElectron ( ) ) {
36+ setDesktopIsLoading ( false )
37+ } else {
7738 setPopupError ( true )
78- window . removeEventListener ( 'message' , messageListener )
79- popup ?. close ( )
39+ // Fallback to device code flow
40+ await handleGetDeviceCode ( )
8041 }
8142 }
43+ } , [ ] )
8244
83- window . addEventListener ( 'message' , messageListener )
84- } , [ actions , pluginActions ] )
85-
86- const getDeviceCodeFromGitHub = async ( ) => {
45+ const handleGetDeviceCode = async ( ) => {
8746 setDesktopIsLoading ( false )
8847 setPopupError ( false )
89- await sendToMatomo ( gitMatomoEventTypes . GETGITHUBDEVICECODE )
9048 setAuthorized ( false )
91- // Send a POST request
92- const response = await axios ( {
93- method : 'post' ,
94- url : `${ endpointUrls . github } /login/device/code` ,
95- data : {
96- client_id : '2795b4e41e7197d6ea11' ,
97- scope : 'repo gist user:email read:user'
98- } ,
99- headers : {
100- 'Content-Type' : 'application/json' ,
101- 'Accept' : 'application/json'
102- } ,
103- } ) ;
10449
105- // convert response to json
106- const githubrespone = await response . data ;
107-
108- setGitHubResponse ( githubrespone )
50+ try {
51+ const githubResponse = await getDeviceCodeFromGitHub ( )
52+ setGitHubResponse ( githubResponse )
53+ } catch ( error ) {
54+ console . error ( 'Failed to get device code:' , error )
55+ await sendToMatomo ( gitMatomoEventTypes . CONNECTTOGITHUBFAIL )
56+ }
10957 }
11058
11159 const connectApp = async ( ) => {
112- await sendToMatomo ( gitMatomoEventTypes . CONNECTTOGITHUB )
113- // poll https://github.com/login/oauth/access_token
114- const accestokenresponse = await axios ( {
115- method : 'post' ,
116- url : `${ endpointUrls . github } /login/oauth/access_token` ,
117- data : {
118- client_id : '2795b4e41e7197d6ea11' ,
119- device_code : gitHubResponse . device_code ,
120- grant_type : 'urn:ietf:params:oauth:grant-type:device_code'
121- } ,
122- headers : {
123- 'Content-Type' : 'application/json' ,
124- 'Accept' : 'application/json'
125- } ,
126- } ) ;
127-
128- // convert response to json
129- const response = await accestokenresponse . data ;
130-
131- if ( response . access_token ) {
60+ try {
61+ await connectWithDeviceCode ( gitHubResponse . device_code )
13262 setAuthorized ( true )
133- await sendToMatomo ( gitMatomoEventTypes . CONNECTTOGITHUBSUCCESS )
134- await pluginActions . saveToken ( response . access_token )
135- await actions . loadGitHubUserFromToken ( )
136- } else {
63+ } catch ( error ) {
64+ console . error ( 'Failed to connect with device code:' , error )
13765 await sendToMatomo ( gitMatomoEventTypes . CONNECTTOGITHUBFAIL )
13866 }
13967 }
@@ -144,12 +72,14 @@ export const GetDeviceCode = () => {
14472 }
14573 } , [ context . gitHubUser ] )
14674
147- const disconnect = async ( ) => {
148- await sendToMatomo ( gitMatomoEventTypes . DISCONNECTFROMGITHUB )
149- setAuthorized ( false )
150- setGitHubResponse ( null )
151- await pluginActions . saveToken ( null )
152- await actions . loadGitHubUserFromToken ( )
75+ const handleDisconnect = async ( ) => {
76+ try {
77+ await disconnectFromGitHub ( )
78+ setAuthorized ( false )
79+ setGitHubResponse ( null )
80+ } catch ( error ) {
81+ console . error ( 'Failed to disconnect from GitHub:' , error )
82+ }
15383 }
15484
15585 return (
@@ -162,7 +92,7 @@ export const GetDeviceCode = () => {
16292 { popupError && ! gitHubResponse && ! authorized && (
16393 < div className = "alert alert-warning mt-2" role = "alert" >
16494 GitHub login failed. You can continue using another method.
165- < button className = 'btn btn-outline-primary btn-sm mt-2 w-100' onClick = { getDeviceCodeFromGitHub } >
95+ < button className = 'btn btn-outline-primary btn-sm mt-2 w-100' onClick = { handleGetDeviceCode } >
16696 Use another method
16797 </ button >
16898 </ div >
@@ -171,7 +101,7 @@ export const GetDeviceCode = () => {
171101 < i className = "fas fa-spinner fa-spin fa-2x mt-1" > </ i >
172102 < div className = "alert alert-warning mt-2" role = "alert" >
173103 In case of issues, you can try another method.
174- < button className = 'btn btn-outline-primary btn-sm mt-2 w-100' onClick = { getDeviceCodeFromGitHub } >
104+ < button className = 'btn btn-outline-primary btn-sm mt-2 w-100' onClick = { handleGetDeviceCode } >
175105 Use another method
176106 </ button >
177107 </ div >
@@ -202,7 +132,7 @@ export const GetDeviceCode = () => {
202132 ( context . gitHubUser && context . gitHubUser . isConnected ) ?
203133 < div className = "pt-2" >
204134 < button data-id = 'disconnect-github' className = 'btn btn-primary mt-1 w-100' onClick = { async ( ) => {
205- disconnect ( )
135+ handleDisconnect ( )
206136 } } > Disconnect</ button >
207137 </ div > : null
208138 }
0 commit comments