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/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, } from './utils/urls.js'; const shouldDisplayQRCodeInTerminal = false; @@ -54,10 +56,10 @@ (async () => { await Promise.all([olm.init(), prefetchAllURLFacts(), initENSCache()]); - const squadCalBaseRoutePath = getSquadCalURLFacts()?.baseRoutePath; + const keyserverBaseRoutePath = getKeyserverURLFacts()?.baseRoutePath; const landingBaseRoutePath = getLandingURLFacts()?.baseRoutePath; - const commAppURLFacts = getCommAppURLFacts(); - const commAppBaseRoutePath = commAppURLFacts?.baseRoutePath; + const webAppURLFacts = getWebAppURLFacts(); + const webAppBaseRoutePath = webAppURLFacts?.baseRoutePath; const compiledFolderOptions = process.env.NODE_ENV === 'development' @@ -65,7 +67,7 @@ : { maxAge: '1y', immutable: true }; const corsOptions = { - origin: commAppURLFacts?.baseDomain ?? 'https://web.comm.app', + origin: webAppURLFacts?.baseDomain ?? 'https://web.comm.app', methods: ['GET', 'POST'], }; @@ -228,16 +230,25 @@ 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(); 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<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(); @@ -171,6 +181,7 @@ res.end(html` </div> <script> + var keyserverURL = "${keyserverURL}"; var baseURL = "${baseURL}"; var olmFilename = "${olmFilename}"; var commQueryExecutorFilename = "${commQueryExecutorFilename}"; @@ -202,7 +213,7 @@ 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}`; diff --git a/keyserver/src/utils/urls.js b/keyserver/src/utils/urls.js --- a/keyserver/src/utils/urls.js +++ b/keyserver/src/utils/urls.js @@ -15,8 +15,8 @@ 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); @@ -46,30 +46,30 @@ 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'); } @@ -86,9 +86,9 @@ export { prefetchAllURLFacts, - getSquadCalURLFacts, - getCommAppURLFacts, - getAndAssertCommAppURLFacts, + getKeyserverURLFacts, + getWebAppURLFacts, + getAndAssertKeyserverURLFacts, getLandingURLFacts, getAndAssertLandingURLFacts, getAppURLFactsFromRequestURL, diff --git a/native/redux/persist.js b/native/redux/persist.js --- a/native/redux/persist.js +++ b/native/redux/persist.js @@ -92,6 +92,7 @@ import { defaultDeviceCameraInfo } from '../types/camera.js'; import { defaultGlobalThemeInfo } from '../types/themes.js'; import { isTaskCancelledError } from '../utils/error-handling.js'; +import { defaultURLPrefix } from '../utils/url-utils.js'; const migrations = { [1]: (state: AppState) => ({ @@ -783,6 +784,22 @@ threadHashingStatus: 'data_not_loaded', }, }), + [53]: async (state: AppState): Promise<AppState> => + __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` @@ -914,7 +931,7 @@ 'connection', ], debug: __DEV__, - version: 52, + version: 53, transforms: [ messageStoreMessagesBlocklistTransform, reportStoreTransform, diff --git a/native/utils/url-utils.js b/native/utils/url-utils.js --- a/native/utils/url-utils.js +++ b/native/utils/url-utils.js @@ -32,7 +32,7 @@ } function getDevNodeServerURLFromHostname(hostname: string): string { - return `http://${hostname}:3000/comm`; + return `http://${hostname}:3000/keyserver`; } function getDevLandingURLFromHostname(hostname: string): string { diff --git a/web/push-notif/service-worker.js b/web/push-notif/service-worker.js --- a/web/push-notif/service-worker.js +++ b/web/push-notif/service-worker.js @@ -72,7 +72,7 @@ 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); } })(), diff --git a/web/redux/default-state.js b/web/redux/default-state.js --- a/web/redux/default-state.js +++ b/web/redux/default-state.js @@ -3,12 +3,13 @@ import { defaultEnabledApps } from 'lib/types/enabled-apps.js'; import { defaultCalendarFilters } from 'lib/types/filter-types.js'; import { defaultConnectionInfo } from 'lib/types/socket-types.js'; -import { isDev } from 'lib/utils/dev-utils.js'; import { defaultNotifPermissionAlertInfo } from 'lib/utils/push-alerts.js'; import { ashoatKeyserverID } from 'lib/utils/validation-utils.js'; import type { AppState } from './redux-setup.js'; +declare var keyserverURL: string; + const defaultWebState: AppState = Object.freeze({ navInfo: { activeChatThreadID: null, @@ -80,9 +81,7 @@ [ashoatKeyserverID]: { cookie: null, updatesCurrentAsOf: 0, - urlPrefix: isDev - ? 'http://localhost:3000/comm' - : 'https://web.comm.app', + urlPrefix: keyserverURL, connection: { ...defaultConnectionInfo }, lastCommunicatedPlatformDetails: null, }, diff --git a/web/redux/persist.js b/web/redux/persist.js --- a/web/redux/persist.js +++ b/web/redux/persist.js @@ -37,6 +37,8 @@ import { isSQLiteSupported } from '../database/utils/db-utils.js'; import { workerRequestMessageTypes } from '../types/worker-types.js'; +declare var keyserverURL: string; + const migrations = { [1]: async state => { const { @@ -159,6 +161,19 @@ }, }; }, + [8]: async state => ({ + ...state, + keyserverStore: { + ...state.keyserverStore, + keyserverInfos: { + ...state.keyserverStore.keyserverInfos, + [ashoatKeyserverID]: { + ...state.keyserverStore.keyserverInfos[ashoatKeyserverID], + urlPrefix: keyserverURL, + }, + }, + }, + }), }; const persistWhitelist = [ @@ -271,7 +286,7 @@ { debug: isDev }, migrateStorageToSQLite, ): any), - version: 7, + version: 8, transforms: [keyserverStoreTransform], };