Skip to content

Commit

Permalink
[web/native/keyserver] Start using new url facts
Browse files Browse the repository at this point in the history
Summary:
Part of [ENG-5153](https://linear.app/comm/issue/ENG-5153)
Depends on D9398

Now we can start using the new `/webapp/` and `/keyserver` urls in other places.
This also brings back the option of testing the web app with "staging" keyserver because it sets the `urlPrefix` to the one specified in the url facts (passed as a variable in html) (more context in D9145).

Test Plan:
- check that web and native migrations work
- check that uploading a new image works
- test that navigating to `https://localhost:3000/comm/chat/thread/256%7C83932/` redirects to `/webapp/`
- I run the keyserver docs according to the instructions in the `nix_keyserver_deployment.md` to check if both new web app and keyserver endpoints work:
 - The webapp successfully loaded under `http://localhost:3000/webapp/`
 - In the network inspector I could see a successful request to the keyserver (`http://localhost:3000/keyserver/get_initial_redux_state`)

Reviewers: inka, kamil, atul, ashoat

Reviewed By: kamil, ashoat

Subscribers: ashoat, tomek, wyilio

Differential Revision: https://phab.comm.dev/D9451
  • Loading branch information
MichalGniadek committed Oct 31, 2023
1 parent c9bae03 commit 5c2682a
Show file tree
Hide file tree
Showing 16 changed files with 111 additions and 55 deletions.
2 changes: 1 addition & 1 deletion desktop/src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import {
} from './push-notifications.js';

const isDev = process.env.ENV === 'dev';
const url = isDev ? 'http://localhost:3000/comm/' : 'https://web.comm.app';
const url = isDev ? 'http://localhost:3000/webapp/' : 'https://web.comm.app';
const isMac = process.platform === 'darwin';

const scrollbarCSS = fs.promises.readFile(
Expand Down
12 changes: 6 additions & 6 deletions docs/dev_environment.md
Original file line number Diff line number Diff line change
Expand Up @@ -366,16 +366,16 @@ The keyserver needs to know some info about paths in order to properly construct

```
mkdir -p keyserver/facts
vim keyserver/facts/commapp_url.json
vim keyserver/facts/webapp_url.json
```

Your `commapp_url.json` file should look like this:
Your `webapp_url.json` file should look like this:

```json
{
"baseDomain": "http://localhost:3000",
"basePath": "/comm/",
"baseRoutePath": "/comm/",
"basePath": "/webapp/",
"baseRoutePath": "/webapp/",
"https": false,
"proxy": "none"
}
Expand Down Expand Up @@ -506,7 +506,7 @@ cd web
yarn dev
```

You should now be able to load the web app in your web browser at http://localhost/comm/.
You should now be able to load the web app in your web browser at http://localhost/webapp/.

This command will start two processes. One is `webpack-dev-server`, which will serve the JS files. `webpack-dev-server` also makes sure the website automatically hot-reloads whenever any of the source files change. The other process is `webpack --watch`, which will build the `app.build.cjs` file, as well as rebuilding it whenever any of the source files change. The `app.build.cjs` file is consumed by the Node server in order to pre-render the initial HTML from the web source (“Server-Side Rendering”).

Expand Down Expand Up @@ -675,7 +675,7 @@ Finally, we need to direct the mobile app to use your local keyserver instance.
3. Finally, you should be able to navigate to Profile → Developer tools in the app and set the address of the local server. It should look something like this:

```
http://w.x.y.z/comm
http://w.x.y.z/webapp
```
Where `w.x.y.z` is the local IP address you found earlier.
Expand Down
5 changes: 3 additions & 2 deletions docs/linux_dev_environment.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,9 @@ Add the content below, but make sure to replace “ashoat” with your username.
<VirtualHost *:80>
ProxyRequests on
ProxyPass /comm/ws ws://localhost:3000/ws
ProxyPass /comm/ http://localhost:3000/
ProxyPass /keyserver/ http://localhost:3000/keyserver/
ProxyPass /keyserver/ws ws://localhost:3000/keyserver/ws
ProxyPass /webapp/ http://localhost:3000/webapp/
ProxyPass /commlanding/ http://localhost:3000/commlanding/
RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
Expand Down
5 changes: 3 additions & 2 deletions docs/nix_keyserver_deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ COMM_DATABASE_USER=<MariaDB user>
COMM_DATABASE_PASSWORD=<MariaDB password>
COMM_JSONCONFIG_secrets_user_credentials='{"username":"<user>","password":"<password>"}'
COMM_JSONCONFIG_facts_landing_url='{"baseDomain":"http://localhost","basePath":"/commlanding/","baseRoutePath":"/commlanding/","https":false}'
COMM_JSONCONFIG_facts_commapp_url='{"baseDomain":"http://localhost:3000","basePath":"/comm/","https":false,"baseRoutePath":"/comm/","proxy":"none"}'
COMM_JSONCONFIG_facts_webapp_url='{"baseDomain":"http://localhost:3000","basePath":"/webapp/","https":false,"baseRoutePath":"/webapp/","proxy":"none"}'
COMM_JSONCONFIG_facts_keyserver_url='{"baseDomain":"http://localhost:3000","basePath":"/keyserver/","baseRoutePath":"/keyserver/","https":false,"proxy":"none"}'
COMM_JSONCONFIG_facts_webapp_cors='{"domain": "http://localhost:3000"}'
# Required to connect to production Identity service
Expand Down Expand Up @@ -45,7 +46,7 @@ COMM_JSONCONFIG_facts_backups='{"enabled":true,"directory":"/home/comm/backups",

### URL configuration

- `COMM_JSONCONFIG_facts_commapp_url`: Your keyserver needs to know what its externally-facing URL is in order to construct links. It also needs to know if it’s being proxied to that externally-facing URL, and what the internal route path is.
- `COMM_JSONCONFIG_facts_keyserver_url`: Your keyserver needs to know what its externally-facing URL is in order to construct links. It also needs to know if it’s being proxied to that externally-facing URL, and what the internal route path is.
- `baseDomain`: Externally-facing domain. Used for constructing links.
- `basePath`: Externally-facing path. Used for constructing links.
- `baseRoutePath`: Internally-facing path. Same as basePath if no proxy. If there’s a proxy, this is the local path (e.g. http://localhost:3000/landing would correspond with /landing/)
Expand Down
2 changes: 1 addition & 1 deletion docs/nix_web_workflows.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ cd web
yarn dev
```

You should now be able to load the web app in your web browser at http://localhost:3000/comm/.
You should now be able to load the web app in your web browser at http://localhost:3000/webapp/.

This command will start two processes. One is `webpack-dev-server`, which will serve the JS files. `webpack-dev-server` also makes sure the website automatically hot-reloads whenever any of the source files change. The other process is `webpack --watch`, which will build the `app.build.cjs` file, as well as rebuilding it whenever any of the source files change. The `app.build.cjs` file is consumed by the Node server in order to pre-render the initial HTML from the web source (“Server-Side Rendering”).

Expand Down
4 changes: 2 additions & 2 deletions keyserver/icons/site.webmanifest
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
"short_name": "SquadCal",
"icons": [
{
"src": "/android-chrome-192x192.png",
"src": "android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/android-chrome-512x512.png",
"src": "android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
Expand Down
4 changes: 2 additions & 2 deletions keyserver/src/creators/report-creator.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import { fetchUsername } from '../fetchers/user-fetchers.js';
import { handleAsyncPromise } from '../responders/handlers.js';
import { createBotViewer } from '../session/bots.js';
import type { Viewer } from '../session/viewer.js';
import { getAndAssertCommAppURLFacts } from '../utils/urls.js';
import { getAndAssertKeyserverURLFacts } from '../utils/urls.js';

const { commbot } = bots;

Expand Down Expand Up @@ -144,7 +144,7 @@ function getCommbotMessage(
const { platform, codeVersion } = platformDetails;
const platformString = codeVersion ? `${platform} v${codeVersion}` : platform;
if (request.type === reportTypes.ERROR) {
const { baseDomain, basePath } = getAndAssertCommAppURLFacts();
const { baseDomain, basePath } = getAndAssertKeyserverURLFacts();
return (
`${name} got an error :(\n` +
`using ${platformString}\n` +
Expand Down
4 changes: 2 additions & 2 deletions keyserver/src/fetchers/upload-fetchers.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { ServerError } from 'lib/utils/errors.js';

import { dbQuery, SQL } from '../database/database.js';
import type { Viewer } from '../session/viewer.js';
import { getAndAssertCommAppURLFacts } from '../utils/urls.js';
import { getAndAssertKeyserverURLFacts } from '../utils/urls.js';

type UploadInfo = {
content: Buffer,
Expand Down Expand Up @@ -104,7 +104,7 @@ async function getUploadSize(id: string, secret: string): Promise<number> {
}

function getUploadURL(id: string, secret: string): string {
const { baseDomain, basePath } = getAndAssertCommAppURLFacts();
const { baseDomain, basePath } = getAndAssertKeyserverURLFacts();
const uploadPath = `${basePath}upload/${id}/${secret}`;
if (isDev) {
const ipV4 = ip.v4.sync() || 'localhost';
Expand Down
28 changes: 20 additions & 8 deletions keyserver/src/keyserver.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ import cookieParser from 'cookie-parser';
import cors from 'cors';
import crypto from 'crypto';
import express from 'express';
import type { $Request, $Response } from 'express';
import expressWs from 'express-ws';
import os from 'os';
import qrcode from 'qrcode';

import './cron/cron.js';
import { qrCodeLinkURL } from 'lib/facts/links.js';
import { isDev } from 'lib/utils/dev-utils.js';

import { migrate } from './database/migrations.js';
import { jsonEndpoints } from './endpoints.js';
Expand Down Expand Up @@ -44,9 +46,9 @@ import { initENSCache } from './utils/ens-cache.js';
import { getContentSigningKey } from './utils/olm-utils.js';
import {
prefetchAllURLFacts,
getSquadCalURLFacts,
getKeyserverURLFacts,
getLandingURLFacts,
getCommAppURLFacts,
getWebAppURLFacts,
getWebAppCorsConfig,
} from './utils/urls.js';

Expand All @@ -60,9 +62,10 @@ const shouldDisplayQRCodeInTerminal = false;
initENSCache(),
]);

const squadCalBaseRoutePath = getSquadCalURLFacts()?.baseRoutePath;
const keyserverBaseRoutePath = getKeyserverURLFacts()?.baseRoutePath;
const landingBaseRoutePath = getLandingURLFacts()?.baseRoutePath;
const commAppBaseRoutePath = getCommAppURLFacts()?.baseRoutePath;
const webAppURLFacts = getWebAppURLFacts();
const webAppBaseRoutePath = webAppURLFacts?.baseRoutePath;

const compiledFolderOptions =
process.env.NODE_ENV === 'development'
Expand Down Expand Up @@ -233,19 +236,28 @@ const shouldDisplayQRCodeInTerminal = false;
server.use(landingBaseRoutePath, landingRouter);
}

if (commAppBaseRoutePath) {
if (webAppBaseRoutePath) {
const commAppRouter = express.Router();
setupAppRouter(commAppRouter);
server.use(commAppBaseRoutePath, commAppRouter);
server.use(webAppBaseRoutePath, commAppRouter);
}

if (squadCalBaseRoutePath) {
if (keyserverBaseRoutePath) {
const squadCalRouter = express.Router();
if (keyserverCorsOptions) {
squadCalRouter.use(cors(keyserverCorsOptions));
}
setupAppRouter(squadCalRouter);
server.use(squadCalBaseRoutePath, squadCalRouter);
server.use(keyserverBaseRoutePath, squadCalRouter);
}

if (isDev && webAppURLFacts) {
const oldPath = '/comm/';
server.all(`${oldPath}*`, (req: $Request, res: $Response) => {
const endpoint = req.url.slice(oldPath.length);
const newURL = `${webAppURLFacts.baseDomain}${webAppURLFacts.basePath}${endpoint}`;
res.redirect(newURL);
});
}

const listenAddress = (() => {
Expand Down
17 changes: 14 additions & 3 deletions keyserver/src/responders/website-responders.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ import getTitle from 'web/title/getTitle.js';

import { waitForStream } from '../utils/json-stream.js';
import {
getAndAssertKeyserverURLFacts,
getAppURLFactsFromRequestURL,
getCommAppURLFacts,
getWebAppURLFacts,
} from '../utils/urls.js';

const { renderToNodeStream } = ReactDOMServer;
Expand Down Expand Up @@ -110,9 +111,18 @@ async function getWebpackCompiledRootComponentForSSR() {
}
}

function stripLastSlash(input: string): string {
return input.replace(/\/$/, '');
}

async function websiteResponder(req: $Request, res: $Response): Promise<void> {
const { basePath } = getAppURLFactsFromRequestURL(req.originalUrl);
const baseURL = basePath.replace(/\/$/, '');
const baseURL = stripLastSlash(basePath);

const keyserverURLFacts = getAndAssertKeyserverURLFacts();
const keyserverURL = `${keyserverURLFacts.baseDomain}${stripLastSlash(
keyserverURLFacts.basePath,
)}`;

const loadingPromise = getWebpackCompiledRootComponentForSSR();

Expand Down Expand Up @@ -171,6 +181,7 @@ async function websiteResponder(req: $Request, res: $Response): Promise<void> {
res.end(html`
</div>
<script>
var keyserverURL = "${keyserverURL}";
var baseURL = "${baseURL}";
var olmFilename = "${olmFilename}";
var commQueryExecutorFilename = "${commQueryExecutorFilename}";
Expand Down Expand Up @@ -202,7 +213,7 @@ async function inviteResponder(req: $Request, res: $Response): Promise<void> {
res.end();
return;
} else if (detectionResult.os !== 'iOS') {
const urlFacts = getCommAppURLFacts();
const urlFacts = getWebAppURLFacts();
const baseDomain = urlFacts?.baseDomain ?? '';
const basePath = urlFacts?.basePath ?? '/';
const redirectUrl = `${baseDomain}${basePath}handle/invite/${secret}`;
Expand Down
36 changes: 18 additions & 18 deletions keyserver/src/utils/urls.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ export type AppURLFacts = {
const validProxies = new Set(['apache', 'none']);
const sitesObj = Object.freeze({
a: 'landing',
b: 'commapp',
c: 'squadcal',
b: 'webapp',
c: 'keyserver',
});
export type Site = $Values<typeof sitesObj>;
const sites: $ReadOnlyArray<Site> = values(sitesObj);
Expand Down Expand Up @@ -46,30 +46,30 @@ async function prefetchAllURLFacts() {
await Promise.all(sites.map(fetchURLFacts));
}

function getSquadCalURLFacts(): ?AppURLFacts {
return cachedURLFacts.get('squadcal');
function getKeyserverURLFacts(): ?AppURLFacts {
return cachedURLFacts.get('keyserver');
}

function getCommAppURLFacts(): ?AppURLFacts {
return cachedURLFacts.get('commapp');
function getWebAppURLFacts(): ?AppURLFacts {
return cachedURLFacts.get('webapp');
}

function getAndAssertCommAppURLFacts(): AppURLFacts {
const urlFacts = getCommAppURLFacts();
invariant(urlFacts, 'keyserver/facts/commapp_url.json missing');
function getAndAssertKeyserverURLFacts(): AppURLFacts {
const urlFacts = getKeyserverURLFacts();
invariant(urlFacts, 'keyserver/facts/keyserver_url.json missing');
return urlFacts;
}

// ESLint doesn't recognize that invariant always throws
// eslint-disable-next-line consistent-return
function getAppURLFactsFromRequestURL(url: string): AppURLFacts {
const commURLFacts = getCommAppURLFacts();
if (commURLFacts && url.startsWith(commURLFacts.baseRoutePath)) {
return commURLFacts;
const webAppURLFacts = getWebAppURLFacts();
if (webAppURLFacts && url.startsWith(webAppURLFacts.baseRoutePath)) {
return webAppURLFacts;
}
const squadCalURLFacts = getSquadCalURLFacts();
if (squadCalURLFacts) {
return squadCalURLFacts;
const keyserverURLFacts = getKeyserverURLFacts();
if (keyserverURLFacts && url.startsWith(keyserverURLFacts.baseRoutePath)) {
return keyserverURLFacts;
}
invariant(false, 'request received but no URL facts are present');
}
Expand All @@ -95,9 +95,9 @@ async function getWebAppCorsConfig(): Promise<?WebAppCorsConfig> {

export {
prefetchAllURLFacts,
getSquadCalURLFacts,
getCommAppURLFacts,
getAndAssertCommAppURLFacts,
getKeyserverURLFacts,
getWebAppURLFacts,
getAndAssertKeyserverURLFacts,
getLandingURLFacts,
getAndAssertLandingURLFacts,
getAppURLFactsFromRequestURL,
Expand Down
19 changes: 18 additions & 1 deletion native/redux/persist.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ import { updateRolesAndPermissions } from './update-roles-and-permissions.js';
import { commCoreModule } from '../native-modules.js';
import { defaultDeviceCameraInfo } from '../types/camera.js';
import { isTaskCancelledError } from '../utils/error-handling.js';
import { defaultURLPrefix } from '../utils/url-utils.js';

const migrations = {
[1]: (state: AppState) => ({
Expand Down Expand Up @@ -836,6 +837,22 @@ const migrations = {
},
};
},
[55]: async state =>
__DEV__
? {
...state,
keyserverStore: {
...state.keyserverStore,
keyserverInfos: {
...state.keyserverStore.keyserverInfos,
[ashoatKeyserverID]: {
...state.keyserverStore.keyserverInfos[ashoatKeyserverID],
urlPrefix: defaultURLPrefix,
},
},
},
}
: state,
};

// After migration 31, we'll no longer want to persist `messageStore.messages`
Expand Down Expand Up @@ -965,7 +982,7 @@ const persistConfig = {
'connection',
],
debug: __DEV__,
version: 54,
version: 55,
transforms: [
messageStoreMessagesBlocklistTransform,
reportStoreTransform,
Expand Down
2 changes: 1 addition & 1 deletion native/utils/url-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ function getDevServerHostname(): string {
}

function getDevNodeServerURLFromHostname(hostname: string): string {
return `http://${hostname}:3000/comm`;
return `http://${hostname}:3000/keyserver`;
}

function getDevLandingURLFromHostname(hostname: string): string {
Expand Down
2 changes: 1 addition & 1 deletion web/push-notif/service-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ self.addEventListener('notificationclick', (event: NotificationEvent) => {
const url =
(process.env.NODE_ENV === 'production'
? 'https://web.comm.app'
: 'http://localhost:3000/comm') + `/chat/thread/${threadID}/`;
: 'http://localhost:3000/webapp') + `/chat/thread/${threadID}/`;
clients.openWindow(url);
}
})(),
Expand Down
Loading

0 comments on commit 5c2682a

Please sign in to comment.