(core) disentangle some server tests, release to core, add GRIST_PROXY_AUTH_HEADER test

Summary:
This shuffles some server tests to make them available in grist-core,
and adds a test for the `GRIST_PROXY_AUTH_HEADER` feature added in
https://github.com/gristlabs/grist-core/pull/165

It includes a fix for a header normalization issue for websocket connections.

Test Plan: added test

Reviewers: georgegevoian

Reviewed By: georgegevoian

Differential Revision: https://phab.getgrist.com/D3326
This commit is contained in:
Paul Fitzpatrick
2022-03-24 13:11:26 -04:00
parent 64c9717ac1
commit de703343d0
15 changed files with 4151 additions and 7 deletions

8
app/server/declarations/tmp.d.ts vendored Normal file
View File

@@ -0,0 +1,8 @@
import {Options, SimpleOptions} from "tmp";
// Add declarations of the promisifies methods of tmp.
declare module "tmp" {
function dirAsync(config?: Options): Promise<string>;
function fileAsync(config?: Options): Promise<string>;
function tmpNameAsync(config?: SimpleOptions): Promise<string>;
}

View File

@@ -17,6 +17,7 @@ import {IPermitStore, Permit} from 'app/server/lib/Permit';
import {allowHost, optStringParam} from 'app/server/lib/requestUtils';
import * as cookie from 'cookie';
import {NextFunction, Request, RequestHandler, Response} from 'express';
import {IncomingMessage} from 'http';
import * as onHeaders from 'on-headers';
export interface RequestWithLogin extends Request {
@@ -95,12 +96,14 @@ export function isSingleUserMode(): boolean {
* header to specify the users' email address. The header to set comes from the
* environment variable GRIST_PROXY_AUTH_HEADER.
*/
export function getRequestProfile(req: Request): UserProfile|undefined {
export function getRequestProfile(req: Request|IncomingMessage): UserProfile|undefined {
const header = process.env.GRIST_PROXY_AUTH_HEADER;
let profile: UserProfile|undefined;
if (header && req.headers && req.headers[header]) {
const headerContent = req.headers[header];
if (header) {
// Careful reading headers. If we have an IncomingMessage, there is no
// get() function, and header names are lowercased.
const headerContent = ('get' in req) ? req.get(header) : req.headers[header.toLowerCase()];
if (headerContent) {
const userEmail = headerContent.toString();
const [userName] = userEmail.split("@", 1);
@@ -543,7 +546,7 @@ export function getTransitiveHeaders(req: Request): {[key: string]: string} {
const XRequestedWith = req.get('X-Requested-With');
const Origin = req.get('Origin'); // Pass along the original Origin since it may
// play a role in granular access control.
return {
const result: Record<string, string> = {
...(Authorization ? { Authorization } : undefined),
...(Cookie ? { Cookie } : undefined),
...(Organization ? { Organization } : undefined),
@@ -551,6 +554,12 @@ export function getTransitiveHeaders(req: Request): {[key: string]: string} {
...(XRequestedWith ? { 'X-Requested-With': XRequestedWith } : undefined),
...(Origin ? { Origin } : undefined),
};
const extraHeader = process.env.GRIST_PROXY_AUTH_HEADER;
const extraHeaderValue = extraHeader && req.get(extraHeader);
if (extraHeader && extraHeaderValue) {
result[extraHeader] = extraHeaderValue;
}
return result;
}
export const signInStatusCookieName = sessionCookieName + '_status';