Page MenuHomePhabricator

D9396.id32465.diff
No OneTemporary

D9396.id32465.diff

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
@@ -14,6 +14,7 @@
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_cors='{"domain": "http://localhost:3000"}'
# Required to connect to production Identity service
COMM_JSONCONFIG_secrets_identity_service_config="{\"identitySocketAddr\":\"https://identity.commtechnologies.org:50054\"}"
@@ -51,6 +52,11 @@
- `proxy`: `"none" | "apache"` Determines which request headers to use for HTTPS validation and IP address timezone detection.
- `https`: If true, checks request headers to validate that HTTPS is in use.
+### CORS configuration
+
+- `COMM_JSONCONFIG_facts_webapp_cors`: Your keyserver needs to be able to include CORS headers with the domain where the comm web application is hosted.
+ - `domain`: Domain where the web application is hosted.
+
### Backup configuration
- `COMM_JSONCONFIG_facts_backups`: Specifies whether to enable backups, where to store them, and the max size of the backups directory.
diff --git a/keyserver/flow-typed/npm/cors_v2.x.x.js b/keyserver/flow-typed/npm/cors_v2.x.x.js
new file mode 100644
--- /dev/null
+++ b/keyserver/flow-typed/npm/cors_v2.x.x.js
@@ -0,0 +1,26 @@
+// flow-typed signature: 425712a647645fb8847dbd9109337837
+// flow-typed version: c6154227d1/cors_v2.x.x/flow_>=v0.104.x
+
+// @flow
+
+type CustomOrigin = (
+ requestOrigin: string,
+ callback: (err: Error | null, allow?: boolean) => void
+) => void;
+
+type CorsOptions = {
+ origin?: boolean | string | RegExp | string[] | RegExp[] | CustomOrigin,
+ methods?: string | string[],
+ allowedHeaders?: string | string[],
+ exposedHeaders?: string | string[],
+ credentials?: boolean,
+ maxAge?: number,
+ preflightContinue?: boolean,
+ optionsSuccessStatus?: number,
+ ...
+}
+
+declare module "cors" {
+ import type { $Request as Request, $Response as Response, NextFunction } from "express";
+ declare module.exports: (options?: CorsOptions) => (req: Request, res: Response, next?: NextFunction) => mixed;
+}
diff --git a/keyserver/package.json b/keyserver/package.json
--- a/keyserver/package.json
+++ b/keyserver/package.json
@@ -21,6 +21,7 @@
"test": "jest"
},
"devDependencies": {
+ "0x": "^5.7.0",
"@babel/cli": "^7.13.14",
"@babel/core": "^7.13.14",
"@babel/node": "^7.13.13",
@@ -41,8 +42,7 @@
"flow-typed": "^3.2.1",
"internal-ip": "4.3.0",
"jest": "^26.6.3",
- "nodemon": "^2.0.4",
- "0x": "^5.7.0"
+ "nodemon": "^2.0.4"
},
"dependencies": {
"@babel/runtime": "^7.13.10",
@@ -54,6 +54,7 @@
"common-tags": "^1.7.2",
"compression": "^1.7.4",
"cookie-parser": "^1.4.3",
+ "cors": "^2.8.5",
"dateformat": "^3.0.3",
"detect-browser": "^4.0.4",
"ethers": "^5.7.2",
diff --git a/keyserver/src/database/migration-config.js b/keyserver/src/database/migration-config.js
--- a/keyserver/src/database/migration-config.js
+++ b/keyserver/src/database/migration-config.js
@@ -583,6 +583,18 @@
() =>
dbQuery(SQL`ALTER TABLE cookies MODIFY COLUMN hash char(64) NOT NULL`),
],
+ [
+ 48,
+ async () => {
+ if (isDockerEnvironment()) {
+ return;
+ }
+ const defaultCorsConfig = {
+ domain: 'http://localhost:3000',
+ };
+ writeJSONToFile(defaultCorsConfig, 'facts/webapp_cors.json');
+ },
+ ],
]);
const newDatabaseVersion: number = Math.max(...migrations.keys());
@@ -648,7 +660,7 @@
filePath: string,
routePath: string,
): Promise<void> {
- if (process.env.COMM_DATABASE_HOST) {
+ if (isDockerEnvironment()) {
return;
}
// Since the non-Apache config is so opinionated, just write expected config
@@ -664,7 +676,7 @@
}
async function writeSquadCalRoute(filePath: string): Promise<void> {
- if (process.env.COMM_DATABASE_HOST) {
+ if (isDockerEnvironment()) {
return;
}
// Since the non-Apache config is so opinionated, just write expected config
@@ -704,4 +716,8 @@
);
}
+function isDockerEnvironment(): boolean {
+ return !!process.env.COMM_DATABASE_HOST;
+}
+
export { migrations, newDatabaseVersion, createOlmAccounts };
diff --git a/keyserver/src/keyserver.js b/keyserver/src/keyserver.js
--- a/keyserver/src/keyserver.js
+++ b/keyserver/src/keyserver.js
@@ -4,6 +4,7 @@
import cluster from 'cluster';
import compression from 'compression';
import cookieParser from 'cookie-parser';
+import cors from 'cors';
import crypto from 'crypto';
import express from 'express';
import expressWs from 'express-ws';
@@ -46,12 +47,18 @@
getSquadCalURLFacts,
getLandingURLFacts,
getCommAppURLFacts,
+ getWebAppCorsConfig,
} from './utils/urls.js';
const shouldDisplayQRCodeInTerminal = false;
(async () => {
- await Promise.all([olm.init(), prefetchAllURLFacts(), initENSCache()]);
+ const [webAppCorsConfig] = await Promise.all([
+ getWebAppCorsConfig(),
+ olm.init(),
+ prefetchAllURLFacts(),
+ initENSCache(),
+ ]);
const squadCalBaseRoutePath = getSquadCalURLFacts()?.baseRoutePath;
const landingBaseRoutePath = getLandingURLFacts()?.baseRoutePath;
@@ -62,6 +69,14 @@
? undefined
: { maxAge: '1y', immutable: true };
+ let keyserverCorsOptions = null;
+ if (webAppCorsConfig) {
+ keyserverCorsOptions = {
+ origin: webAppCorsConfig.domain,
+ methods: ['GET', 'POST'],
+ };
+ }
+
const isCPUProfilingEnabled = process.env.KEYSERVER_CPU_PROFILING_ENABLED;
const areEndpointMetricsEnabled =
process.env.KEYSERVER_ENDPOINT_METRICS_ENABLED;
@@ -226,6 +241,9 @@
if (squadCalBaseRoutePath) {
const squadCalRouter = express.Router();
+ if (keyserverCorsOptions) {
+ squadCalRouter.use(cors(keyserverCorsOptions));
+ }
setupAppRouter(squadCalRouter);
server.use(squadCalBaseRoutePath, squadCalRouter);
}
diff --git a/keyserver/src/uploads/uploads.js b/keyserver/src/uploads/uploads.js
--- a/keyserver/src/uploads/uploads.js
+++ b/keyserver/src/uploads/uploads.js
@@ -172,12 +172,6 @@
const { content, mime } = await fetchUpload(viewer, uploadID, secret);
res.type(mime);
res.set('Cache-Control', 'public, max-age=31557600, immutable');
- if (process.env.NODE_ENV === 'development') {
- // Add a CORS header to allow local development using localhost
- const port = process.env.PORT || '3000';
- res.set('Access-Control-Allow-Origin', `http://localhost:${port}`);
- res.set('Access-Control-Allow-Methods', 'GET');
- }
res.send(content);
} else {
const totalUploadSize = await getUploadSize(uploadID, secret);
@@ -207,12 +201,6 @@
'Content-Type': mime,
'Content-Length': respWidth.toString(),
};
- if (process.env.NODE_ENV === 'development') {
- // Add a CORS header to allow local development using localhost
- const port = process.env.PORT || '3000';
- respHeaders['Access-Control-Allow-Origin'] = `http://localhost:${port}`;
- respHeaders['Access-Control-Allow-Methods'] = 'GET';
- }
// HTTP 206 Partial Content
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/206
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
@@ -84,6 +84,15 @@
return urlFacts;
}
+export type WebAppCorsConfig = { +domain: string };
+async function getWebAppCorsConfig(): Promise<?WebAppCorsConfig> {
+ const config = await getCommConfig<WebAppCorsConfig>({
+ folder: 'facts',
+ name: 'webapp_cors',
+ });
+ return config;
+}
+
export {
prefetchAllURLFacts,
getSquadCalURLFacts,
@@ -92,4 +101,5 @@
getLandingURLFacts,
getAndAssertLandingURLFacts,
getAppURLFactsFromRequestURL,
+ getWebAppCorsConfig,
};
diff --git a/scripts/create_url_facts.sh b/scripts/create_url_facts.sh
--- a/scripts/create_url_facts.sh
+++ b/scripts/create_url_facts.sh
@@ -8,6 +8,7 @@
COMMAPP_URL_PATH="${KEYSERVER_FACTS_DIR}/commapp_url.json"
LANDING_URL_PATH="${KEYSERVER_FACTS_DIR}/landing_url.json"
SQUADCAL_URL_PATH="${KEYSERVER_FACTS_DIR}/squadcal_url.json"
+WEBAPP_CORS_PATH="${KEYSERVER_FACTS_DIR}/webapp_cors.json"
if [[ ! -d "$KEYSERVER_FACTS_DIR" ]]; then
mkdir -p "$KEYSERVER_FACTS_DIR"
@@ -24,3 +25,7 @@
if [[ ! -f "$SQUADCAL_URL_PATH" ]]; then
cp "$SCRIPT_DIR/templates/squadcal_url.json" "$SQUADCAL_URL_PATH"
fi
+
+if [[ ! -f "$WEBAPP_CORS_PATH" ]]; then
+ cp "$SCRIPT_DIR/templates/webapp_cors.json" "$WEBAPP_CORS_PATH"
+fi
diff --git a/scripts/templates/webapp_cors.json b/scripts/templates/webapp_cors.json
new file mode 100644
--- /dev/null
+++ b/scripts/templates/webapp_cors.json
@@ -0,0 +1,3 @@
+{
+ "domain": "http://localhost:3000"
+}
diff --git a/yarn.lock b/yarn.lock
--- a/yarn.lock
+++ b/yarn.lock
@@ -13454,9 +13454,9 @@
integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
globals@^13.20.0, globals@^13.6.0, globals@^13.9.0:
- version "13.21.0"
- resolved "https://registry.yarnpkg.com/globals/-/globals-13.21.0.tgz#163aae12f34ef502f5153cfbdd3600f36c63c571"
- integrity sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==
+ version "13.22.0"
+ resolved "https://registry.yarnpkg.com/globals/-/globals-13.22.0.tgz#0c9fcb9c48a2494fbb5edbfee644285543eba9d8"
+ integrity sha512-H1Ddc/PbZHTDVJSnj8kWptIRSD6AM3pK+mKytuIVF4uoBV7rshFlhhvA58ceJ5wp3Er58w6zj7bykMpYXt3ETw==
dependencies:
type-fest "^0.20.2"

File Metadata

Mime Type
text/plain
Expires
Thu, Dec 26, 1:18 AM (8 h, 20 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2703500
Default Alt Text
D9396.id32465.diff (9 KB)

Event Timeline