From 7a053ce697751a7449bfff2b4fa1eb3926dee394 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Wed, 12 Oct 2022 11:11:18 +0200 Subject: [PATCH] fix: gitlab auth and compose reload --- apps/ui/src/lib/api.ts | 2 +- .../configuration/_GitlabRepositories.svelte | 2 +- .../[id]/configuration/buildpack.svelte | 103 +++++++++++++---- .../src/routes/applications/[id]/index.svelte | 105 ++++++++++++++---- 4 files changed, 167 insertions(+), 45 deletions(-) diff --git a/apps/ui/src/lib/api.ts b/apps/ui/src/lib/api.ts index ed781b8a7..7341d580b 100644 --- a/apps/ui/src/lib/api.ts +++ b/apps/ui/src/lib/api.ts @@ -110,7 +110,7 @@ async function send({ if ( response.status === 401 && !path.startsWith('https://api.github') && - !path.includes('/v4/user') + !path.includes('/v4/') ) { Cookies.remove('token'); } diff --git a/apps/ui/src/routes/applications/[id]/configuration/_GitlabRepositories.svelte b/apps/ui/src/routes/applications/[id]/configuration/_GitlabRepositories.svelte index 43c31fd01..94fc11885 100644 --- a/apps/ui/src/routes/applications/[id]/configuration/_GitlabRepositories.svelte +++ b/apps/ui/src/routes/applications/[id]/configuration/_GitlabRepositories.svelte @@ -95,7 +95,7 @@ if (newWindow?.closed) { clearInterval(timer); $appSession.tokens.gitlab = localStorage.getItem('gitLabToken'); - localStorage.removeItem('gitLabToken'); + // localStorage.removeItem('gitLabToken'); resolve(); } }, 100); diff --git a/apps/ui/src/routes/applications/[id]/configuration/buildpack.svelte b/apps/ui/src/routes/applications/[id]/configuration/buildpack.svelte index 30ec09fe9..da0b15974 100644 --- a/apps/ui/src/routes/applications/[id]/configuration/buildpack.svelte +++ b/apps/ui/src/routes/applications/[id]/configuration/buildpack.svelte @@ -37,7 +37,7 @@ import { onMount } from 'svelte'; import { page } from '$app/stores'; - import { get } from '$lib/api'; + import { get, getAPIUrl } from '$lib/api'; import { appSession } from '$lib/store'; import { t } from '$lib/translations'; import { buildPacks, findBuildPack, scanningTemplates } from '$lib/templates'; @@ -47,6 +47,8 @@ const { id } = $page.params; + let htmlUrl = application.gitSource.htmlUrl; + let scanning: boolean = true; let foundConfig: any = null; let packageManager: string = 'npm'; @@ -65,15 +67,47 @@ } } } + async function getGitlabToken() { + return await new Promise((resolve, reject) => { + const left = screen.width / 2 - 1020 / 2; + const top = screen.height / 2 - 618 / 2; + const newWindow = open( + `${htmlUrl}/oauth/authorize?client_id=${ + application.gitSource.gitlabApp.appId + }&redirect_uri=${getAPIUrl()}/webhooks/gitlab&response_type=code&scope=api+email+read_repository&state=${ + $page.params.id + }`, + 'GitLab', + 'resizable=1, scrollbars=1, fullscreen=0, height=618, width=1020,top=' + + top + + ', left=' + + left + + ', toolbar=0, menubar=0, status=0' + ); + const timer = setInterval(() => { + if (newWindow?.closed) { + clearInterval(timer); + $appSession.tokens.gitlab = localStorage.getItem('gitLabToken'); + localStorage.removeItem('gitLabToken'); + resolve(); + } + }, 100); + }); + } async function scanRepository(isPublicRepository: boolean): Promise { try { if (type === 'gitlab') { + const headers = isPublicRepository + ? {} + : { + Authorization: `Bearer ${$appSession.tokens.gitlab}` + }; if (isPublicRepository) { return; } const url = isPublicRepository ? `` : `/v4/projects/${projectId}/repository/tree`; const files = await get(`${apiUrl}${url}`, { - Authorization: `Bearer ${$appSession.tokens.gitlab}` + ...headers }); const packageJson = files.find( (file: { name: string; type: string }) => @@ -126,7 +160,19 @@ if (pnpmLock) packageManager = 'pnpm'; if (dockerComposeFileYml || dockerComposeFileYaml) { - foundConfig = findBuildPack('dockercompose', packageManager); + foundConfig = findBuildPack('compose', packageManager); + const id = dockerComposeFileYml.id || dockerComposeFileYaml.id; + const data = await get(`${apiUrl}/v4/projects/${projectId}/repository/blobs/${id}`, { + ...headers + }); + if (data?.content) { + const content = atob(data.content); + const dockerComposeJson = yaml.load(content) || null; + dockerComposeFile = JSON.stringify(dockerComposeJson); + dockerComposeFileLocation = dockerComposeFileYml + ? 'docker-compose.yml' + : 'docker-compose.yaml'; + } } else if (dockerfile) { foundConfig = findBuildPack('docker', packageManager); } else if (packageJson && !laravel) { @@ -236,7 +282,7 @@ foundConfig = findBuildPack('docker', packageManager); } else if (packageJson && !laravel) { const data: any = await get(`${packageJson.git_url}`, { - Authorization: `Bearer ${$appSession.tokens.github}`, + ...headers, Accept: 'application/vnd.github.v2.raw' }); const json = JSON.parse(data) || {}; @@ -264,27 +310,36 @@ error.message === '401 Unauthorized' ) { if (application.gitSource.gitlabAppId) { - let htmlUrl = application.gitSource.htmlUrl; - const left = screen.width / 2 - 1020 / 2; - const top = screen.height / 2 - 618 / 2; - const newWindow = open( - `${htmlUrl}/oauth/authorize?client_id=${application.gitSource.gitlabApp.appId}&redirect_uri=${window.location.origin}/webhooks/gitlab&response_type=code&scope=api+email+read_repository&state=${$page.params.id}`, - 'GitLab', - 'resizable=1, scrollbars=1, fullscreen=0, height=618, width=1020,top=' + - top + - ', left=' + - left + - ', toolbar=0, menubar=0, status=0' - ); - const timer = setInterval(() => { - if (newWindow?.closed) { - clearInterval(timer); - window.location.reload(); - } - }, 100); + if (!$appSession.tokens.gitlab) { + await getGitlabToken(); + } + scanRepository(isPublicRepository); + // let htmlUrl = application.gitSource.htmlUrl; + // const left = screen.width / 2 - 1020 / 2; + // const top = screen.height / 2 - 618 / 2; + // const newWindow = open( + // `${htmlUrl}/oauth/authorize?client_id=${ + // application.gitSource.gitlabApp.appId + // }&redirect_uri=${getAPIUrl()}/webhooks/gitlab&response_type=code&scope=api+email+read_repository&state=${ + // $page.params.id + // }`, + // 'GitLab', + // 'resizable=1, scrollbars=1, fullscreen=0, height=618, width=1020,top=' + + // top + + // ', left=' + + // left + + // ', toolbar=0, menubar=0, status=0' + // ); + // const timer = setInterval(() => { + // if (newWindow?.closed) { + // clearInterval(timer); + // $appSession.tokens.gitlab = localStorage.getItem('gitLabToken'); + // // localStorage.removeItem('gitLabToken' ); + + // } + // }, 100); } - } - if (error.message === 'Bad credentials') { + } else if (error.message === 'Bad credentials') { const { token } = await get(`/applications/${id}/configuration/githubToken`); $appSession.tokens.github = token; return await scanRepository(isPublicRepository); diff --git a/apps/ui/src/routes/applications/[id]/index.svelte b/apps/ui/src/routes/applications/[id]/index.svelte index 49edd971f..869c1488a 100644 --- a/apps/ui/src/routes/applications/[id]/index.svelte +++ b/apps/ui/src/routes/applications/[id]/index.svelte @@ -33,7 +33,7 @@ import { page } from '$app/stores'; import { onMount } from 'svelte'; import Select from 'svelte-select'; - import { get, post } from '$lib/api'; + import { get, getAPIUrl, post } from '$lib/api'; import cuid from 'cuid'; import { addToast, @@ -75,6 +75,7 @@ let autodeploy = application.settings.autodeploy; let isBot = application.settings.isBot; let isDBBranching = application.settings.isDBBranching; + let htmlUrl = application.gitSource.htmlUrl; let dockerComposeFile = JSON.parse(application.dockerComposeFile) || null; let dockerComposeServices: any[] = []; @@ -321,28 +322,94 @@ return false; } } + async function getGitlabToken() { + return await new Promise((resolve, reject) => { + const left = screen.width / 2 - 1020 / 2; + const top = screen.height / 2 - 618 / 2; + const newWindow = open( + `${htmlUrl}/oauth/authorize?client_id=${ + application.gitSource.gitlabApp.appId + }&redirect_uri=${getAPIUrl()}/webhooks/gitlab&response_type=code&scope=api+email+read_repository&state=${ + $page.params.id + }`, + 'GitLab', + 'resizable=1, scrollbars=1, fullscreen=0, height=618, width=1020,top=' + + top + + ', left=' + + left + + ', toolbar=0, menubar=0, status=0' + ); + const timer = setInterval(() => { + if (newWindow?.closed) { + clearInterval(timer); + $appSession.tokens.gitlab = localStorage.getItem('gitLabToken'); + localStorage.removeItem('gitLabToken'); + resolve(); + } + }, 100); + }); + } async function reloadCompose() { try { - const headers = isPublicRepository - ? {} - : { - Authorization: `token ${$appSession.tokens.github}` - }; - const data = await get( - `${apiUrl}/repos/${repository}/contents/${dockerComposeFileLocation}?ref=${branch}`, - { - ...headers, - Accept: 'application/vnd.github.v2.json' + if (application.gitSource.type === 'github') { + const headers = isPublicRepository + ? {} + : { + Authorization: `token ${$appSession.tokens.github}` + }; + const data = await get( + `${apiUrl}/repos/${repository}/contents/${dockerComposeFileLocation}?ref=${branch}`, + { + ...headers, + Accept: 'application/vnd.github.v2.json' + } + ); + if (data?.content) { + const content = atob(data.content); + let dockerComposeFileContent = JSON.stringify(yaml.load(content) || null); + let dockerComposeFileContentJSON = JSON.parse(dockerComposeFileContent); + dockerComposeServices = normalizeDockerServices(dockerComposeFileContentJSON?.services); + application.dockerComposeFile = dockerComposeFileContent; + await handleSubmit(false); } - ); - if (data?.content) { - const content = atob(data.content); - let dockerComposeFileContent = JSON.stringify(yaml.load(content) || null); - let dockerComposeFileContentJSON = JSON.parse(dockerComposeFileContent); - dockerComposeServices = normalizeDockerServices(dockerComposeFileContentJSON?.services); - application.dockerComposeFile = dockerComposeFileContent; - await handleSubmit(false); } + if (application.gitSource.type === 'gitlab') { + if (!$appSession.tokens.gitlab) { + await getGitlabToken(); + } + const headers = isPublicRepository + ? {} + : { + Authorization: `Bearer ${$appSession.tokens.gitlab}` + }; + const url = isPublicRepository + ? `` + : `/v4/projects/${application.projectId}/repository/tree`; + const files = await get(`${apiUrl}${url}`, { + ...headers + }); + const dockerComposeFileYml = files.find( + (file: { name: string; type: string }) => + file.name === dockerComposeFileLocation && file.type === 'blob' + ); + const id = dockerComposeFileYml.id; + + const data = await get( + `${apiUrl}/v4/projects/${application.projectId}/repository/blobs/${id}`, + { + ...headers + } + ); + if (data?.content) { + const content = atob(data.content); + let dockerComposeFileContent = JSON.stringify(yaml.load(content) || null); + let dockerComposeFileContentJSON = JSON.parse(dockerComposeFileContent); + dockerComposeServices = normalizeDockerServices(dockerComposeFileContentJSON?.services); + application.dockerComposeFile = dockerComposeFileContent; + await handleSubmit(false); + } + } + addToast({ message: 'Compose file reloaded.', type: 'success'