Skip to content
This repository has been archived by the owner on May 7, 2024. It is now read-only.

Commit

Permalink
use a netlify function to handle redirect using state
Browse files Browse the repository at this point in the history
  • Loading branch information
znck committed May 11, 2022
1 parent fcd9322 commit 7b38d14
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 6 deletions.
5 changes: 3 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,18 @@
"editor.formatOnSave": true,
"cSpell.words": [
"AUTOCORRECT",
"Emogenie",
"Grammarly",
"capi",
"docid",
"Emogenie",
"errored",
"freews",
"gnar",
"Grammarly",
"heatmap",
"inversify",
"languageclient",
"minicard",
"reqid",
"subalerts",
"textdocument"
],
Expand Down
15 changes: 11 additions & 4 deletions extension/src/GrammarlyClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,10 +148,17 @@ export class GrammarlyClient implements Registerable {
await this.client.protocol.dismissSuggestion(options)
}),
commands.registerCommand('grammarly.login', async () => {
const uri = await env.asExternalUri(Uri.parse(`${env.uriScheme}://znck.grammarly/auth/callback`))
const redirectUri = `${uri.scheme}://${uri.authority}${uri.path}?${uri.query}`
const url = await this.client.protocol.getOAuthUrl(redirectUri)
if (!(await env.openExternal(Uri.parse(url)))) {
const internalRedirectUri = Uri.parse(`${env.uriScheme}://znck.grammarly/auth/callback`, true)
const externalRedirectUri = await env.asExternalUri(internalRedirectUri)

const redirectUri =
internalRedirectUri.toString(true) === externalRedirectUri.toString(true)
? internalRedirectUri.toString(true)
: 'https://{...}.netlify.app/redirect'
const url = new URL(await this.client.protocol.getOAuthUrl(redirectUri))
url.searchParams.set('state', Buffer.from(redirectUri, 'utf-8').toString('base64url'))

if (!(await env.openExternal(Uri.parse(url.toString(), true)))) {
await window.showErrorMessage('Failed to open login page.')
}
}),
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
},
"devDependencies": {
"@changesets/cli": "^2.22.0",
"@netlify/functions": "^1.0.0",
"@rollup/plugin-alias": "^3.1.9",
"@rollup/plugin-commonjs": "^22.0.0",
"@rollup/plugin-node-resolve": "^13.2.1",
Expand Down
13 changes: 13 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 34 additions & 0 deletions redirect/functions/redirect.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
const schemes = new Set(['vscode', 'vscode-insiders', 'vscodium'])

/**
* Handle redirect url web extension
*
* @param {import('@netlify/functions').HandlerEvent} event
* @param {import('@netlify/functions').HandlerContext} context
* @returns {import('@netlify/functions').HandlerResponse}
*/
exports.handler = async function redirect(event) {
const { state, code } = event.queryStringParameters
if (state == null) return { statusCode: 400, body: 'Missing "state"' }
const uri = new URL(Buffer.from(state, 'base64url').toString('utf-8'))
// https://github.dev/?vscode-scheme=vscode-insiders&vscode-authority=znck.grammarly&vscode-path=/auth/callback&vscode-reqid=*
const reqid = uri.searchParams.get('vscode-reqid')
const scheme = uri.searchParams.get('vscode-scheme')
const authority = uri.searchParams.get('vscode-authority')
const path = uri.searchParams.get('vscode-path')

if (authority !== 'znck.grammarly' || path !== '/auth/callback' || !schemes.has(scheme)) {
return { statusCode: 400, body: `Invalid "state"` }
}

const redirectUri = new URL(uri.pathname, uri.origin)

redirectUri.searchParams.set('vscode-reqid', reqid)
redirectUri.searchParams.set('vscode-scheme', scheme)
redirectUri.searchParams.set('vscode-authority', authority)
redirectUri.searchParams.set('vscode-path', path)
redirectUri.searchParams.set('code', code)
redirectUri.searchParams.set('state', state)

return { statusCode: 302, headers: { Location: redirectUri.toString() } }
}

0 comments on commit 7b38d14

Please sign in to comment.