diff --git a/desktop/src/main.js b/desktop/src/main.js --- a/desktop/src/main.js +++ b/desktop/src/main.js @@ -22,7 +22,7 @@ } 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( diff --git a/docs/dev_environment.md b/docs/dev_environment.md --- a/docs/dev_environment.md +++ b/docs/dev_environment.md @@ -366,16 +366,16 @@ ``` 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" } @@ -506,7 +506,7 @@ 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”). @@ -675,7 +675,7 @@ 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. diff --git a/docs/linux_dev_environment.md b/docs/linux_dev_environment.md --- a/docs/linux_dev_environment.md +++ b/docs/linux_dev_environment.md @@ -91,8 +91,9 @@ 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} diff --git a/docs/nix_keyserver_deployment.md b/docs/nix_keyserver_deployment.md --- a/docs/nix_keyserver_deployment.md +++ b/docs/nix_keyserver_deployment.md @@ -13,7 +13,8 @@ COMM_DATABASE_PASSWORD= COMM_JSONCONFIG_secrets_user_credentials='{"username":"","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 @@ -45,7 +46,7 @@ ### 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/) diff --git a/docs/nix_web_workflows.md b/docs/nix_web_workflows.md --- a/docs/nix_web_workflows.md +++ b/docs/nix_web_workflows.md @@ -42,7 +42,7 @@ 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”). diff --git a/keyserver/icons/site.webmanifest b/keyserver/icons/site.webmanifest --- a/keyserver/icons/site.webmanifest +++ b/keyserver/icons/site.webmanifest @@ -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" } diff --git a/keyserver/src/creators/report-creator.js b/keyserver/src/creators/report-creator.js --- a/keyserver/src/creators/report-creator.js +++ b/keyserver/src/creators/report-creator.js @@ -29,7 +29,7 @@ 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; @@ -144,7 +144,7 @@ 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` + diff --git a/keyserver/src/fetchers/upload-fetchers.js b/keyserver/src/fetchers/upload-fetchers.js --- a/keyserver/src/fetchers/upload-fetchers.js +++ b/keyserver/src/fetchers/upload-fetchers.js @@ -18,7 +18,7 @@ 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, @@ -104,7 +104,7 @@ } 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'; diff --git a/keyserver/src/keyserver.js b/keyserver/src/keyserver.js --- a/keyserver/src/keyserver.js +++ b/keyserver/src/keyserver.js @@ -7,12 +7,14 @@ 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'; @@ -44,9 +46,9 @@ import { getContentSigningKey } from './utils/olm-utils.js'; import { prefetchAllURLFacts, - getSquadCalURLFacts, + getKeyserverURLFacts, getLandingURLFacts, - getCommAppURLFacts, + getWebAppURLFacts, getWebAppCorsConfig, } from './utils/urls.js'; @@ -60,9 +62,10 @@ 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' @@ -233,19 +236,28 @@ 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 (corsOptions) { squadCalRouter.use(cors(corsOptions)); } 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 = (() => { diff --git a/keyserver/src/responders/website-responders.js b/keyserver/src/responders/website-responders.js --- a/keyserver/src/responders/website-responders.js +++ b/keyserver/src/responders/website-responders.js @@ -15,8 +15,9 @@ import { waitForStream } from '../utils/json-stream.js'; import { + getAndAssertKeyserverURLFacts, getAppURLFactsFromRequestURL, - getCommAppURLFacts, + getWebAppURLFacts, } from '../utils/urls.js'; const { renderToNodeStream } = ReactDOMServer; @@ -110,9 +111,18 @@ } } +function stripLastSlash(input: string): string { + return input.replace(/\/$/, ''); +} + async function websiteResponder(req: $Request, res: $Response): Promise { 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(); @@ -171,6 +181,7 @@ res.end(html`