From 6355ef677d55924c36c47ea3d053fcefa7feb0f7 Mon Sep 17 00:00:00 2001 From: EnixCoda Date: Thu, 9 Apr 2020 15:03:12 +0800 Subject: [PATCH] refactor: use server for oauth --- src/components/SideBar.tsx | 26 +++++++++++------------- src/platforms/GitHub/API.ts | 37 +++++++++++++++++++++++++++++++++-- src/platforms/GitHub/index.ts | 16 ++------------- src/platforms/Gitee/API.ts | 32 ++++++++++-------------------- src/platforms/Gitee/index.ts | 16 ++------------- 5 files changed, 60 insertions(+), 67 deletions(-) diff --git a/src/components/SideBar.tsx b/src/components/SideBar.tsx index 9a999cb..16eec4f 100644 --- a/src/components/SideBar.tsx +++ b/src/components/SideBar.tsx @@ -1,4 +1,3 @@ -import { raiseError } from 'analytics' import { AccessDeniedDescription } from 'components/AccessDeniedDescription' import { FileExplorer } from 'components/FileExplorer' import { MetaBar } from 'components/MetaBar' @@ -32,7 +31,7 @@ const RawGitako: React.FC = function RawGitako(props) { React.useEffect(() => { const { init } = props - ;(async function() { + ;(async function () { if (!accessToken) { const accessToken = await trySetUpAccessTokenWithCode() configContext.set({ access_token: accessToken || undefined }) @@ -146,18 +145,15 @@ function AccessDeniedError({ hasToken }: { hasToken: boolean }) { } async function trySetUpAccessTokenWithCode() { - try { - const search = parseURLSearch() - if ('code' in search) { - const accessToken = await platform.setOAuth(search.code) - window.history.replaceState( - {}, - 'removed search param', - window.location.pathname.replace(window.location.search, ''), - ) - return accessToken - } - } catch (err) { - raiseError(err) + const search = parseURLSearch() + if ('code' in search) { + const accessToken = await platform.setOAuth(search.code) + if (!accessToken) alert(`Gitako: The OAuth token has expired, please try again.`) + window.history.replaceState( + {}, + 'removed search param', + window.location.pathname.replace(window.location.search, ''), + ) + return accessToken } } diff --git a/src/platforms/GitHub/API.ts b/src/platforms/GitHub/API.ts index 3777146..a7b47fe 100644 --- a/src/platforms/GitHub/API.ts +++ b/src/platforms/GitHub/API.ts @@ -1,3 +1,4 @@ +import { raiseError } from 'analytics' import { GITHUB_OAUTH } from 'env' import { errors } from 'platforms' import { JSONRequest } from 'utils/general' @@ -82,10 +83,42 @@ export async function getBlobData( return await request(url, { accessToken }) } -export async function OAuth(code: string): Promise { - return await JSONRequest('https://github.com/login/oauth/access_token', { +export async function OAuth(code: string): Promise { + try { + // TODO: deprecate legacy OAuth + if (+Date.now() < +new Date(2020, 5, 1)) return legacyOAuth(code) + else return safeOAuth(code) + } catch (err) { + return null + } +} + +async function safeOAuth(code: string) { + const endpoint = `https://gitako.now.sh/oauth/github?` + const res = await fetch(endpoint + new URLSearchParams({ code }).toString(), { + method: 'post', + }) + if (res.ok) { + const body = await res.json() + const accessToken = body?.accessToken + if (typeof accessToken === 'string') return accessToken + } + return null +} + +async function legacyOAuth(code: string) { + const res = await JSONRequest('https://github.com/login/oauth/access_token', { code, client_id: GITHUB_OAUTH.clientId, client_secret: GITHUB_OAUTH.clientSecret, }) + + const { access_token: accessToken, scope, error_description: errorDescription } = res + if (errorDescription) { + raiseError(new Error(errorDescription)) + } else if (scope !== 'repo' || !accessToken) { + raiseError(new Error(`Cannot resolve token response: '${JSON.stringify(res)}'`)) + } else { + return accessToken + } } diff --git a/src/platforms/GitHub/index.ts b/src/platforms/GitHub/index.ts index 4d0eb22..d13a62a 100644 --- a/src/platforms/GitHub/index.ts +++ b/src/platforms/GitHub/index.ts @@ -138,20 +138,8 @@ export const GitHub: Platform = { getCurrentPath(branchName) { return URLHelper.getCurrentPath(branchName) }, - async setOAuth(code) { - const res = await API.OAuth(code) - const { access_token: accessToken, scope, error_description: errorDescription } = res - if (errorDescription) { - if (errorDescription === `The code passed is incorrect or expired.`) { - alert(`Gitako: The OAuth token has expired, please try again.`) - return null - } else { - throw new Error(errorDescription) - } - } else if (scope !== 'repo' || !accessToken) { - throw new Error(`Cannot resolve token response: '${JSON.stringify(res)}'`) - } - return accessToken + setOAuth(code) { + return API.OAuth(code) }, getOAuthLink() { const params = new URLSearchParams({ diff --git a/src/platforms/Gitee/API.ts b/src/platforms/Gitee/API.ts index 139bc3a..9864c33 100644 --- a/src/platforms/Gitee/API.ts +++ b/src/platforms/Gitee/API.ts @@ -1,5 +1,4 @@ import { raiseError } from 'analytics' -import { GITEE_OAUTH } from 'env' import { errors } from 'platforms' function isEmptyProject(content: any /* safe any */) { @@ -85,27 +84,16 @@ export async function getBlobData( return await request(url, { accessToken }) } -export async function OAuth(code: string): Promise { - if (!GITEE_OAUTH.clientId || !GITEE_OAUTH.clientSecret) - throw new Error(`No Gitee OAuth credientials`) - const params = new URLSearchParams({ - grant_type: 'authorization_code', - code: code, - client_id: GITEE_OAUTH.clientId, - client_secret: GITEE_OAUTH.clientSecret, - }) - - const res = await fetch('https://gitee.com/oauth/token?' + params.toString(), { - mode: 'cors', - cache: 'no-cache', - credentials: 'same-origin', - headers: { - 'Content-Type': 'application/json', - Accept: 'application/json', - }, - redirect: 'follow', - referrerPolicy: 'no-referrer', +export async function OAuth(code: string): Promise { + const endpoint = 'https://gitako.now.sh/oauth/gitee?' + const res = await fetch(endpoint + new URLSearchParams({ code }).toString(), { method: 'post', }) - return res.json() + + if (res.ok) { + const body = await res.json() + const accessToken = body?.accessToken + if (typeof accessToken === 'string') return accessToken + } + return null } diff --git a/src/platforms/Gitee/index.ts b/src/platforms/Gitee/index.ts index 13b2d8d..5bafafd 100644 --- a/src/platforms/Gitee/index.ts +++ b/src/platforms/Gitee/index.ts @@ -149,20 +149,8 @@ export const Gitee: Platform = { }) return `https://gitee.com/oauth/authorize?` + params.toString() }, - async setOAuth(code) { - const res = await API.OAuth(code) - const { access_token: accessToken, scope, error_description: errorDescription } = res - if (errorDescription) { - if (errorDescription === `The code passed is incorrect or expired.`) { - alert(`Gitako: The OAuth token has expired, please try again.`) - return null - } else { - throw new Error(errorDescription) - } - } else if (scope !== 'repo' || !accessToken) { - throw new Error(`Cannot resolve token response: '${JSON.stringify(res)}'`) - } - return accessToken + setOAuth(code) { + return API.OAuth(code) }, }