(core) when redirecting, use protocol in APP_HOME_URL if available

Summary:
Currently, Grist behind a reverse proxy will generate many
needless redirects via `http`, and can't be used with only
port 443. This diff centralizes generation of these redirects
and uses the protocol in APP_HOME_URL if it is set.

Test Plan:
manually tested by rebuilding grist-core and
doing a reverse proxy deployment that had no support for
port 80. Prior to this change, there are lots of problems;
after, the site works as expected.

Reviewers: jarek

Reviewed By: jarek

Differential Revision: https://phab.getgrist.com/D3400
This commit is contained in:
Paul Fitzpatrick
2022-04-27 12:07:08 -04:00
parent 6f00106d7c
commit 4de5928396
6 changed files with 31 additions and 14 deletions

View File

@@ -70,7 +70,7 @@ export function addOrgToPath(req: RequestWithOrg, path: string): string {
* Get url to the org associated with the request.
*/
export function getOrgUrl(req: Request, path: string = '/') {
return req.protocol + '://' + req.get('host') + addOrgToPathIfNeeded(req, path);
return getOriginUrl(req) + addOrgToPathIfNeeded(req, path);
}
/**
@@ -97,8 +97,8 @@ export function trustOrigin(req: Request, resp: Response): boolean {
// enough if only the base domains match. Differing ports are allowed, which helps in dev/testing.
export function allowHost(req: Request, allowedHost: string|URL) {
const mreq = req as RequestWithOrg;
const proto = req.protocol;
const actualUrl = new URL(`${proto}://${req.get('host')}`);
const proto = getEndUserProtocol(req);
const actualUrl = new URL(getOriginUrl(req));
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.
@@ -282,11 +282,24 @@ export interface RequestWithGristInfo extends Request {
* https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/x-forwarded-headers.html
*/
export function getOriginUrl(req: Request) {
const host = req.headers.host!;
const protocol = req.get("X-Forwarded-Proto") || req.protocol;
const host = req.get('host')!;
const protocol = getEndUserProtocol(req);
return `${protocol}://${host}`;
}
/**
* Get the protocol to use in Grist URLs that are intended to be reachable
* from a user's browser. Use the protocol in APP_HOME_URL if available,
* otherwise X-Forwarded-Proto is set on the provided request, otherwise
* the protocol of the request itself.
*/
export function getEndUserProtocol(req: Request) {
if (process.env.APP_HOME_URL) {
return new URL(process.env.APP_HOME_URL).protocol.replace(':', '');
}
return req.get("X-Forwarded-Proto") || req.protocol;
}
/**
* In some configurations, session information may be cached by the server.
* When session information changes, give the server a chance to clear its