|
|
|
@ -8,7 +8,6 @@ import {RequestWithGrist} from 'app/server/lib/GristServer';
|
|
|
|
|
import log from 'app/server/lib/log';
|
|
|
|
|
import {Permit} from 'app/server/lib/Permit';
|
|
|
|
|
import {Request, Response} from 'express';
|
|
|
|
|
import _ from 'lodash';
|
|
|
|
|
import {Writable} from 'stream';
|
|
|
|
|
|
|
|
|
|
// log api details outside of dev environment (when GRIST_HOSTED_VERSION is set)
|
|
|
|
@ -87,7 +86,7 @@ export function trustOrigin(req: Request, resp: Response): boolean {
|
|
|
|
|
const origin = req.get('origin');
|
|
|
|
|
if (!origin) { return true; } // Not a CORS request.
|
|
|
|
|
if (process.env.GRIST_HOST && req.hostname === process.env.GRIST_HOST) { return true; }
|
|
|
|
|
if (!allowHost(req, new URL(origin)) && !isEnvironmentAllowedHost(new URL(origin))) { return false; }
|
|
|
|
|
if (!allowHost(req, new URL(origin))) { return false; }
|
|
|
|
|
|
|
|
|
|
// For a request to a custom domain, the full hostname must match.
|
|
|
|
|
resp.header("Access-Control-Allow-Origin", origin);
|
|
|
|
@ -104,14 +103,14 @@ export function allowHost(req: Request, allowedHost: string|URL) {
|
|
|
|
|
const allowedUrl = (typeof allowedHost === 'string') ? new URL(`${proto}://${allowedHost}`) : allowedHost;
|
|
|
|
|
if (mreq.isCustomHost) {
|
|
|
|
|
// For a request to a custom domain, the full hostname must match.
|
|
|
|
|
return actualUrl.hostname === allowedUrl.hostname;
|
|
|
|
|
return actualUrl.hostname === allowedUrl.hostname;
|
|
|
|
|
} else {
|
|
|
|
|
// For requests to a native subdomains, only the base domain needs to match.
|
|
|
|
|
const allowedDomain = parseSubdomain(allowedUrl.hostname);
|
|
|
|
|
const actualDomain = parseSubdomain(actualUrl.hostname);
|
|
|
|
|
return (!_.isEmpty(actualDomain) ?
|
|
|
|
|
return actualDomain.base ?
|
|
|
|
|
actualDomain.base === allowedDomain.base :
|
|
|
|
|
allowedUrl.hostname === actualUrl.hostname);
|
|
|
|
|
actualUrl.hostname === allowedUrl.hostname;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -119,13 +118,6 @@ export function matchesBaseDomain(domain: string, baseDomain: string) {
|
|
|
|
|
return domain === baseDomain || domain.endsWith("." + baseDomain);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function isEnvironmentAllowedHost(url: string|URL) {
|
|
|
|
|
const urlHost = (typeof url === 'string') ? url : url.hostname;
|
|
|
|
|
return (process.env.GRIST_ALLOWED_HOSTS || "").split(",").some(domain =>
|
|
|
|
|
domain && matchesBaseDomain(urlHost, domain)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function isParameterOn(parameter: any): boolean {
|
|
|
|
|
return gutil.isAffirmative(parameter);
|
|
|
|
|
}
|
|
|
|
|