1
+ /**
2
+ * Copyright (c) 2021 Gitpod GmbH. All rights reserved.
3
+ * Licensed under the GNU Affero General Public License (AGPL).
4
+ * See License-AGPL.txt in the project root for license information.
5
+ */
6
+
7
+ import { useLocation } from "react-router" ;
8
+ import Modal from "../components/Modal" ;
9
+ import { Deferred } from "@gitpod/gitpod-protocol/lib/util/deferred" ;
10
+ import { getGitpodService , gitpodHostUrl } from "../service/service" ;
11
+ import { useState } from "react" ;
12
+ import info from "../images/info.svg" ;
13
+
14
+ async function registerApp ( installationId : string , setModal : ( modal : 'done' | string | undefined ) => void ) {
15
+ try {
16
+ await getGitpodService ( ) . server . registerGithubApp ( installationId ) ;
17
+
18
+ const returnTo = encodeURIComponent ( gitpodHostUrl . with ( { pathname : `login-success` } ) . toString ( ) ) ;
19
+ const url = gitpodHostUrl . withApi ( {
20
+ pathname : '/authorize' ,
21
+ search : `returnTo=${ returnTo } &host=github.com&scopes=repo`
22
+ } ) . toString ( ) ;
23
+ window . open ( url , "gitpod-login" ) ;
24
+
25
+ const result = new Deferred < void > ( 1000 * 60 * 10 /* 10 min */ ) ;
26
+ result . promise . catch ( e => setModal ( 'error' ) ) ;
27
+ const listener = ( event : MessageEvent < any > ) => {
28
+ // todo: check event.origin
29
+ if ( event . data === "auth-success" ) {
30
+ if ( event . source && "close" in event . source && event . source . close ) {
31
+ console . log ( `try to close window` ) ;
32
+ event . source . close ( ) ;
33
+ } else {
34
+ // todo: not here, but add a button to the /login-success page to close, if this should not work as expected
35
+ }
36
+ window . removeEventListener ( "message" , listener ) ;
37
+ setModal ( 'done' ) ;
38
+ result . resolve ( ) ;
39
+ }
40
+ } ;
41
+ window . addEventListener ( "message" , listener ) ;
42
+ return result . promise ;
43
+ } catch ( e ) {
44
+ setModal ( e . message ) ;
45
+ }
46
+ }
47
+
48
+ export default function InstallGitHubApp ( ) {
49
+ const location = useLocation ( ) ;
50
+ const [ modal , setModal ] = useState < 'done' | string | undefined > ( ) ;
51
+ const params = new URLSearchParams ( location . search ) ;
52
+ const installationId = params . get ( "installation_id" ) || undefined ;
53
+ if ( ! installationId ) {
54
+ return < div className = "lg:px-28 px-10 flex flex-col space-y-2" >
55
+ < div className = "px-6 py-3 flex justify-between space-x-2 text-gray-400 border-t border-gray-200 h-96" >
56
+ < div className = "flex flex-col items-center w-96 m-auto" >
57
+ < h3 className = "text-center pb-3 text-gray-500" > No Installation ID Found</ h3 >
58
+ < div className = "text-center pb-6 text-gray-500" > Did you came here from the GitHub app's page?</ div >
59
+ </ div >
60
+ </ div >
61
+ </ div >
62
+ }
63
+
64
+ const goToApp = ( ) => window . location . href = gitpodHostUrl . toString ( ) ;
65
+
66
+ return < >
67
+ < div className = "lg:px-28 px-10 flex flex-col space-y-2" >
68
+ < div className = "px-6 py-3 flex justify-between space-x-2 text-gray-400" >
69
+ < div className = "flex flex-col items-center m-auto max-w-lg mt-40" >
70
+ < h3 className = "text-center pb-3 text-gray-500" > Install GitHub App</ h3 >
71
+ < div className = "text-center pb-6 text-gray-500" > You are about to install the GitHub app for Gitpod.</ div >
72
+ < div className = "flex rounded-md bg-gray-200 p-3" >
73
+ < img className = "w-4 h-4 ml-2 mr-3 mt-1" src = { info } alt = "info" />
74
+ < span className = "text-gray-500" > This action will also allow Gitpod to access private repositories. You can edit git provider permissions later in user settings.</ span >
75
+ </ div >
76
+ < div className = "mt-6" >
77
+ < button className = "secondary" > Cancel</ button >
78
+ < button className = "ml-2" onClick = { ( ) => registerApp ( installationId , setModal ) } > Install App</ button >
79
+ </ div >
80
+ </ div >
81
+ </ div >
82
+ </ div >
83
+ < Modal title = "Installation Successfull" visible = { modal === 'done' } onClose = { goToApp } buttons = { < button onClick = { goToApp } > Go to Dashboard</ button > } >
84
+ < div className = "pb-6 text-gray-500" > The GitHub app was installed successfully. Have a look at the < a className = "text-blue-500" href = "https://www.gitpod.io/docs/prebuilds/" rel = "noopener" > documentation</ a > to find out how to configure it.</ div >
85
+ </ Modal >
86
+ < Modal title = "Failed to Install" visible = { ! ! modal && modal !== 'done' } onClose = { goToApp } buttons = { [
87
+ < button className = "secondary" onClick = { goToApp } > Cancel</ button > ,
88
+ < button className = "" onClick = { ( ) => registerApp ( installationId , setModal ) } > Try Again</ button >
89
+ ] } >
90
+ < div className = "pb-6 text-gray-500" > Could not install the GitHub app.</ div >
91
+ < div className = "flex rounded-md bg-gray-200 p-3" >
92
+ < img className = "w-4 h-4 ml-2 mr-3 mt-1" src = { info } alt = "info" />
93
+ < span className = "text-gray-500" > { modal } </ span >
94
+ </ div >
95
+ </ Modal > </ > ;
96
+ }
0 commit comments