From 932c50475decf41a77a80d0daece46a4b6896e56 Mon Sep 17 00:00:00 2001 From: netcon Date: Wed, 4 Dec 2024 01:45:49 +0800 Subject: [PATCH] deply on cloudflare (#597) * chore: cloudflare pages deploy * chore: cloudflare page functions * feat: use openvsx --- functions/api/github-auth-callback.ts | 68 +++++++++++++++++++++++ functions/api/gitlab-oauth-callback.ts | 76 ++++++++++++++++++++++++++ functions/tsconfig.json | 9 +++ package.json | 1 + src/index.ts | 2 +- src/product.ts | 14 ++--- webpack.config.js | 2 + yarn.lock | 5 ++ 8 files changed, 167 insertions(+), 10 deletions(-) create mode 100644 functions/api/github-auth-callback.ts create mode 100644 functions/api/gitlab-oauth-callback.ts create mode 100644 functions/tsconfig.json diff --git a/functions/api/github-auth-callback.ts b/functions/api/github-auth-callback.ts new file mode 100644 index 000000000..e58ec9da8 --- /dev/null +++ b/functions/api/github-auth-callback.ts @@ -0,0 +1,68 @@ +/** + * @file github auth callback + * @author netcon + */ + +const createResponseHtml = (text: string, script: string) => ` + + + + Connect to GitHub + + +

${text}

+ + + +`; + +// return the data to the opener window by postMessage API, +// and close current window if successfully connected +const createAuthorizeResultHtml = (data: Record, origins: string) => { + const errorText = 'Failed! You can close this window and retry.'; + const successText = 'Connected! You can now close this window.'; + const resultStr = `{ type: 'authorizing', payload: ${JSON.stringify(data)} }`; + const script = ` + '${origins}'.split(',').forEach(function(allowedOrigin) { + window.opener.postMessage(${resultStr}, allowedOrigin); + }); + ${data.error ? '' : 'setTimeout(() => window.close(), 50);'}`; + return createResponseHtml(data.error ? errorText : successText, script); +}; + +const MISSING_CODE_ERROR = { + error: 'request_invalid', + error_description: 'Missing code', +}; +const UNKNOWN_ERROR = { + error: 'internal_error', + error_description: 'Unknown error', +}; + +export const onRequest: PagesFunction<{ + GITHUB_OAUTH_ID: string; + GITHUB_OAUTH_SECRET: string; + GITHUB1S_ALLOWED_ORIGINS: string; +}> = async ({ request, env }) => { + const code = new URL(request.url).searchParams.get('code'); + + const createResponse = (status, data) => { + const body = createAuthorizeResultHtml(data, env.GITHUB1S_ALLOWED_ORIGINS); + return new Response(body, { status }); + }; + + if (!code) { + return createResponse(401, MISSING_CODE_ERROR); + } + + try { + // https://docs.github.com/en/developers/apps/authorizing-oauth-apps#2-users-are-redirected-back-to-your-site-by-github + const response = await fetch('https://github.com/login/oauth/access_token', { + method: 'POST', + body: JSON.stringify({ client_id: env.GITHUB_OAUTH_ID, client_secret: env.GITHUB_OAUTH_SECRET, code }), + }); + return response.json().then((result) => createResponse(response.status, result)); + } catch (e) { + return createResponse(500, UNKNOWN_ERROR); + } +}; diff --git a/functions/api/gitlab-oauth-callback.ts b/functions/api/gitlab-oauth-callback.ts new file mode 100644 index 000000000..8b2e80496 --- /dev/null +++ b/functions/api/gitlab-oauth-callback.ts @@ -0,0 +1,76 @@ +/** + * @file gitlab auth callback + * @author netcon + */ + +const AUTH_REDIRECT_URI = 'https://auth.gitlab1s.com/api/gitlab-auth-callback'; + +const createResponseHtml = (text: string, script: string) => ` + + + + Connect to GitLab + + +

${text}

+ + + +`; + +// return the data to the opener window by postMessage API, +// and close current window if successfully connected +const createAuthorizeResultHtml = (data: Record, origins: string) => { + const errorText = 'Failed! You can close this window and retry.'; + const successText = 'Connected! You can now close this window.'; + const resultStr = `{ type: 'authorizing', payload: ${JSON.stringify(data)} }`; + const script = ` + '${origins}'.split(',').forEach(function(allowedOrigin) { + window.opener.postMessage(${resultStr}, allowedOrigin); + }); + ${data.error ? '' : 'setTimeout(() => window.close(), 50);'}`; + return createResponseHtml(data.error ? errorText : successText, script); +}; + +const MISSING_CODE_ERROR = { + error: 'request_invalid', + error_description: 'Missing code', +}; +const UNKNOWN_ERROR = { + error: 'internal_error', + error_description: 'Unknown error', +}; + +export const onRequest: PagesFunction<{ + GITLAB_OAUTH_ID: string; + GITLAB_OAUTH_SECRET: string; + GITLAB1S_ALLOWED_ORIGINS: string; +}> = async ({ request, env }) => { + const code = new URL(request.url).searchParams.get('code'); + + const createResponse = (status, data) => { + const body = createAuthorizeResultHtml(data, env.GITLAB1S_ALLOWED_ORIGINS); + return new Response(body, { status }); + }; + + if (!code) { + return createResponse(401, MISSING_CODE_ERROR); + } + + try { + // https://docs.gitlab.com/ee/api/oauth2.html#authorization-code-flow + const response = await fetch('https://gitlab.com/oauth/token', { + method: 'POST', + body: JSON.stringify({ + code, + client_id: env.GITLAB_OAUTH_ID, + client_secret: env.GITLAB_OAUTH_SECRET, + redirect_uri: AUTH_REDIRECT_URI, + grant_type: 'authorization_code', + }), + }); + return response.json().then((result) => createResponse(response.status, result)); + } catch (e) { + return createResponse(500, UNKNOWN_ERROR); + } +}; diff --git a/functions/tsconfig.json b/functions/tsconfig.json new file mode 100644 index 000000000..c0677a5b4 --- /dev/null +++ b/functions/tsconfig.json @@ -0,0 +1,9 @@ +{ + "include": ["**/*"], + "compilerOptions": { + "target": "esnext", + "module": "esnext", + "lib": ["esnext"], + "types": ["@cloudflare/workers-types"] + } +} diff --git a/package.json b/package.json index a3cdbf485..b5db8875a 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ }, "devDependencies": { "@github1s/vscode-web": "0.22.0", + "@cloudflare/workers-types": "^4.20240722.0", "@typescript-eslint/eslint-plugin": "^5.40.1", "@typescript-eslint/parser": "^5.40.1", "clean-css": "^5.3.2", diff --git a/src/index.ts b/src/index.ts index d28a8a4bd..43c65faa0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -70,7 +70,7 @@ const resolvePlatformState = (): [Platform, string] => { (window as any).vscodeWeb = { commands: vscodeCommands, allowEditorLabelOverride: true, - additionalBuiltinExtensions: ['ms-vscode.anycode'], + additionalBuiltinExtensions: [], webviewEndpoint: staticAssetsPrefix + '/vscode/vs/workbench/contrib/webview/browser/pre', productConfiguration: createProductConfiguration(platform), initialColorTheme: { themeType: 'dark' as any }, diff --git a/src/product.ts b/src/product.ts index da7bf2e87..3085d7745 100644 --- a/src/product.ts +++ b/src/product.ts @@ -6,14 +6,10 @@ export const createProductConfiguration = (platform: Platform) => ({ applicationName: platform + '1s', reportIssueUrl: 'https://github.com/conwnet/github1s/issues/new', extensionsGallery: { - serviceUrl: 'https://marketplace.visualstudio.com/_apis/public/gallery', - cacheUrl: 'https://vscode.blob.core.windows.net/gallery/index', - itemUrl: 'https://marketplace.visualstudio.com/items', - resourceUrlTemplate: window.location.origin + '/api/vscode-unpkg/{publisher}/{name}/{version}/{path}', - controlUrl: 'https://az764295.vo.msecnd.net/extensions/marketplace.json', - recommendationsUrl: 'https://az764295.vo.msecnd.net/extensions/workspaceRecommendations.json.gz', - nlsBaseUrl: '', - publisherUrl: '', + resourceUrlTemplate: + 'https://open-vsx.org/vscode/asset/{publisher}/{name}/{version}/Microsoft.VisualStudio.Code.WebResources/{path}', + serviceUrl: 'https://open-vsx.org/vscode/gallery', + itemUrl: 'https://open-vsx.org/vscode/item', }, linkProtectionTrustedDomains: [ '*.github.com', @@ -27,8 +23,8 @@ export const createProductConfiguration = (platform: Platform) => ({ '*.microsoft.com', '*.vercel.com', '*.sourcegraph.com', - '*.gitpod.io', '*.ossinsight.io', + '*.open-vsx.org', ], extensionEnabledApiProposals: { 'ms-vscode.anycode': ['extensionsAny'] }, }); diff --git a/webpack.config.js b/webpack.config.js index c17499b33..9e67ac121 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -46,11 +46,13 @@ module.exports = (env, argv) => { !devVscode && { from: 'node_modules/@github1s/vscode-web/dist/vscode', to: `static-${STATIC_HASH}/vscode`, + globOptions: { ignore: ['**/*.js.map'] }, ...skipMinified, }, !devVscode && { from: 'node_modules/@github1s/vscode-web/dist/extensions', to: `static-${STATIC_HASH}/extensions`, + globOptions: { ignore: ['**/*.js.map'] }, ...skipMinified, }, !devVscode && { diff --git a/yarn.lock b/yarn.lock index b4f32ac36..79bb5ae41 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,11 @@ # yarn lockfile v1 +"@cloudflare/workers-types@^4.20240722.0": + version "4.20240722.0" + resolved "https://registry.yarnpkg.com/@cloudflare/workers-types/-/workers-types-4.20240722.0.tgz#f5b9579fe5ff14077ae425208af6dea74249d130" + integrity sha512-/N072r7w7jNCgciRtImOQnHODn8CNwl3NHGO2lmC5bCsgevTRNeNj6B2IjS+OgEfo0qFoBgLejISl6ot9QvGvA== + "@discoveryjs/json-ext@^0.5.0": version "0.5.7" resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70"