From 291bcd17fffd4cf99840b687b1dfa83e55bf2454 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaros=C5=82aw=20Sadzi=C5=84ski?= Date: Wed, 21 Jul 2021 18:38:57 +0200 Subject: [PATCH] (core) Google auth endpoint has not responded with auth code Summary: Google Auth popup wasn't able to resolve origin from gristConfig. Moving this reponsability to server side, where it gets calculated from initial request. Test Plan: n/a Reviewers: dsagal, paulfitz Reviewed By: paulfitz Differential Revision: https://phab.getgrist.com/D2935 --- app/server/lib/ExportXLSX.ts | 2 +- app/server/lib/FlexServer.ts | 2 +- app/server/lib/GoogleAuth.ts | 25 ++++++++++++++++--------- app/server/lib/sendAppPage.ts | 4 +--- static/message.html | 5 +---- 5 files changed, 20 insertions(+), 18 deletions(-) diff --git a/app/server/lib/ExportXLSX.ts b/app/server/lib/ExportXLSX.ts index 122b9e4b..04693d58 100644 --- a/app/server/lib/ExportXLSX.ts +++ b/app/server/lib/ExportXLSX.ts @@ -11,7 +11,7 @@ export async function makeXLSX( activeDoc: ActiveDoc, req: express.Request): Promise { const content = await exportDoc(activeDoc, req); - const data = await convertToExcel(content, req.host === 'localhost'); + const data = await convertToExcel(content, req.hostname === 'localhost'); return data; } diff --git a/app/server/lib/FlexServer.ts b/app/server/lib/FlexServer.ts index d44614a6..90c7d984 100644 --- a/app/server/lib/FlexServer.ts +++ b/app/server/lib/FlexServer.ts @@ -1232,7 +1232,7 @@ export class FlexServer implements GristServer { public addGoogleAuthEndpoint() { if (this._check('google-auth')) { return; } - const messagePage = makeMessagePage(this, getAppPathTo(this.appRoot, 'static')); + const messagePage = makeMessagePage(getAppPathTo(this.appRoot, 'static')); addGoogleAuthEndpoint(this.app, messagePage); } diff --git a/app/server/lib/GoogleAuth.ts b/app/server/lib/GoogleAuth.ts index 6879697f..65142d03 100644 --- a/app/server/lib/GoogleAuth.ts +++ b/app/server/lib/GoogleAuth.ts @@ -1,10 +1,10 @@ -import {auth} from '@googleapis/oauth2'; -import {ApiError} from 'app/common/ApiError'; -import {parseSubdomain} from 'app/common/gristUrls'; -import {expressWrap} from 'app/server/lib/expressWrap'; +import { auth } from '@googleapis/oauth2'; +import { ApiError } from 'app/common/ApiError'; +import { parseSubdomain } from 'app/common/gristUrls'; +import { expressWrap } from 'app/server/lib/expressWrap'; import * as log from 'app/server/lib/log'; import * as express from 'express'; -import {URL} from 'url'; +import { URL } from 'url'; /** * Google Auth Endpoint for performing server side authentication. More information can be found @@ -130,15 +130,18 @@ export function addGoogleAuthEndpoint( log.info(`GoogleAuth - auth handler at ${getFullAuthEndpointUrl()}`); expressApp.get(authHandlerPath, expressWrap(async (req: express.Request, res: express.Response) => { + // Test if the code is in a query string. Google sends it back after user has given a concent for // our request. It is encrypted (with CLIENT_SECRET) and signed with redirect url. + // In state query parameter we will receive an url that was send as part of the request to Google. + if (req.query.code) { log.debug("GoogleAuth - response from Google with valid code"); - messagePage(req, res, { code: req.query.code }); + messagePage(req, res, { code: req.query.code, origin: req.query.state }); } else if (req.query.error) { log.debug("GoogleAuth - response from Google with error code", req.query.error); if (req.query.error === "access_denied") { - messagePage(req, res, { error: req.query.error }); + messagePage(req, res, { error: req.query.error, origin: req.query.state }); } else { // This should not happen, either code or error is a mandatory query parameter. throw new ApiError("Error authenticating with Google", 500); @@ -146,13 +149,17 @@ export function addGoogleAuthEndpoint( } else { const oAuth2Client = _googleAuthClient(); const scope = req.query.scope || DRIVE_SCOPE; + // Create url for origin parameter for a popup window. + const origin = `${req.protocol}://${req.headers.host}`; const authUrl = oAuth2Client.generateAuthUrl({ scope, - prompt: 'select_account' + prompt: 'select_account', + state: origin }); log.debug(`GoogleAuth - redirecting to Google consent screen`, { authUrl, - scope + scope, + state: origin }); res.redirect(authUrl); } diff --git a/app/server/lib/sendAppPage.ts b/app/server/lib/sendAppPage.ts index 55b3d219..dd87ff5e 100644 --- a/app/server/lib/sendAppPage.ts +++ b/app/server/lib/sendAppPage.ts @@ -51,12 +51,10 @@ export function makeGristConfig(homeUrl: string|null, extra: Partial { - const config = server.getGristConfig(); const fileContent = await fse.readFile(path.join(staticDir, "message.html"), 'utf8'); const content = fileContent - .replace("", ``) .replace("", ``); resp.status(200).type('html').send(content); }; diff --git a/static/message.html b/static/message.html index 0c59bd66..fefb12b2 100644 --- a/static/message.html +++ b/static/message.html @@ -4,12 +4,9 @@ -