From ef10c8f6fdea6bf2de17a31565dca8f3f47f0409 Mon Sep 17 00:00:00 2001 From: Michal Gniadek Date: Mon, 21 Aug 2023 10:07:21 +0200 Subject: [PATCH] [keyserver] Convert urlInfo in website responders Summary: [ENG-4670](https://linear.app/comm/issue/ENG-4670) We also need to convert the urlInfo in the website responder so it works on link containing the new id schema. We can also handle the older links by not converting (the older link already contain schema that's inside the keyserver db). Depends on D8879 (moving stuff because of cyclic dependencies) Test Plan: Open links: - http://localhost:3000/comm/chat/thread/256%7C86139/ -> navigated to the `86139` - http://localhost:3000/comm/chat/thread/86139/ -> navigated to the `86139` thread, url was changed to match id schema after loading Try opening links to non-existant threads: - http://localhost:3000/comm/chat/thread/256%7C861392/ -> navigated to the thread at the top of the thread list - http://localhost:3000/comm/chat/thread/861392/ -> navigated to the thread at the top of the thread list Try navigating to settings and check if it worked correctly: http://localhost:3000/comm/settings/account/ Tried navigating to a pending (non-sidebar) threads with two users and was navigated correctly. Navigating to sidebar pending threads doesn't work but from analyzing the code and diffs it isn't supported by the keyserver anyway. Also opened landing to check if there are no weird cyclic dependecies errors there Reviewers: tomek, inka, kamil, ginsu Reviewed By: kamil Subscribers: ashoat Differential Revision: https://phab.comm.dev/D8880 --- keyserver/src/responders/website-responders.js | 15 ++++++++++++--- keyserver/src/utils/validation-utils.js | 6 ++++-- lib/utils/url-utils.js | 18 +++++++++++++++++- 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/keyserver/src/responders/website-responders.js b/keyserver/src/responders/website-responders.js index e4eb2bdfc1..b7607a5e5b 100644 --- a/keyserver/src/responders/website-responders.js +++ b/keyserver/src/responders/website-responders.js @@ -47,7 +47,7 @@ import { currentDateInTimeZone } from 'lib/utils/date-utils.js'; import { ServerError } from 'lib/utils/errors.js'; import { promiseAll } from 'lib/utils/promises.js'; import { defaultNotifPermissionAlertInfo } from 'lib/utils/push-alerts.js'; -import { infoFromURL } from 'lib/utils/url-utils.js'; +import { infoFromURL, urlInfoValidator } from 'lib/utils/url-utils.js'; import { tBool, tNumber, @@ -77,7 +77,7 @@ import { getAppURLFactsFromRequestURL, getCommAppURLFacts, } from '../utils/urls.js'; -import { validateOutput } from '../utils/validation-utils.js'; +import { validateOutput, validateInput } from '../utils/validation-utils.js'; const { renderToNodeStream } = ReactDOMServer; @@ -274,7 +274,16 @@ async function websiteResponder( const initialNavInfoPromise = (async () => { try { - const urlInfo = infoFromURL(req.url); + let urlInfo = infoFromURL(decodeURI(req.url)); + + try { + urlInfo = await validateInput(viewer, urlInfoValidator, urlInfo, true); + } catch (exc) { + // We should still be able to handle older links + if (exc.message !== 'invalid_client_id_prefix') { + throw exc; + } + } let backupInfo = { now: currentDateInTimeZone(viewer.timeZone), diff --git a/keyserver/src/utils/validation-utils.js b/keyserver/src/utils/validation-utils.js index 7844d75d1a..354febd5b7 100644 --- a/keyserver/src/utils/validation-utils.js +++ b/keyserver/src/utils/validation-utils.js @@ -31,8 +31,9 @@ async function validateInput( viewer: Viewer, inputValidator: TType, input: mixed, + ignoreViewerVersion?: boolean, ): Promise { - if (!viewer.isSocket) { + if (!ignoreViewerVersion && !viewer.isSocket) { await checkClientSupported(viewer, inputValidator, input); } const convertedInput = checkInputValidator(inputValidator, input); @@ -41,7 +42,8 @@ async function validateInput( hasMinStateVersion(viewer.platformDetails, { native: 43, web: 3, - }) + }) || + ignoreViewerVersion ) { try { return convertClientIDsToServerIDs( diff --git a/lib/utils/url-utils.js b/lib/utils/url-utils.js index dd97b7cc6a..8914404cc4 100644 --- a/lib/utils/url-utils.js +++ b/lib/utils/url-utils.js @@ -1,6 +1,8 @@ // @flow -import { idSchemaRegex } from './validation-utils.js'; +import t, { type TInterface } from 'tcomb'; + +import { idSchemaRegex, tID, tShape } from './validation-utils.js'; import { pendingThreadIDRegex } from '../shared/thread-utils.js'; export type URLInfo = { @@ -18,6 +20,20 @@ export type URLInfo = { ... }; +export const urlInfoValidator: TInterface = tShape({ + year: t.maybe(t.Number), + month: t.maybe(t.Number), + verify: t.maybe(t.String), + calendar: t.maybe(t.Boolean), + chat: t.maybe(t.Boolean), + thread: t.maybe(tID), + settings: t.maybe(t.enums.of(['account', 'danger-zone'])), + threadCreation: t.maybe(t.Boolean), + selectedUserList: t.maybe(t.list(t.String)), + inviteSecret: t.maybe(t.String), + qrCode: t.maybe(t.Boolean), +}); + // We use groups to capture parts of the URL and any changes // to regexes must be reflected in infoFromURL. const yearRegex = new RegExp('(/|^)year/([0-9]+)(/|$)', 'i');