Merge pull request #1850 from atmire/use-x-forwarded-for-redirect

Use values from x-forwarded headers in getOrigin server side
This commit is contained in:
Tim Donohue
2022-09-28 10:31:16 -05:00
committed by GitHub
7 changed files with 36 additions and 14 deletions

View File

@@ -76,6 +76,10 @@ export function app() {
*/ */
const server = express(); const server = express();
// Tell Express to trust X-FORWARDED-* headers from proxies
// See https://expressjs.com/en/guide/behind-proxies.html
server.set('trust proxy', environment.ui.useProxies);
/* /*
* If production mode is enabled in the environment file: * If production mode is enabled in the environment file:
* - Enable Angular's production mode * - Enable Angular's production mode

View File

@@ -2,17 +2,25 @@ import { TestBed } from '@angular/core/testing';
import { BrowserHardRedirectService } from './browser-hard-redirect.service'; import { BrowserHardRedirectService } from './browser-hard-redirect.service';
describe('BrowserHardRedirectService', () => { describe('BrowserHardRedirectService', () => {
const origin = 'https://test-host.com:4000'; let origin: string;
const mockLocation = { let mockLocation: Location;
href: undefined, let service: BrowserHardRedirectService;
pathname: '/pathname',
search: '/search',
origin
} as Location;
const service: BrowserHardRedirectService = new BrowserHardRedirectService(mockLocation);
beforeEach(() => { beforeEach(() => {
origin = 'https://test-host.com:4000';
mockLocation = {
href: undefined,
pathname: '/pathname',
search: '/search',
origin,
replace: (url: string) => {
mockLocation.href = url;
}
} as Location;
spyOn(mockLocation, 'replace');
service = new BrowserHardRedirectService(mockLocation);
TestBed.configureTestingModule({}); TestBed.configureTestingModule({});
}); });
@@ -28,8 +36,8 @@ describe('BrowserHardRedirectService', () => {
service.redirect(redirect); service.redirect(redirect);
}); });
it('should update the location', () => { it('should call location.replace with the new url', () => {
expect(mockLocation.href).toEqual(redirect); expect(mockLocation.replace).toHaveBeenCalledWith(redirect);
}); });
}); });

View File

@@ -24,7 +24,7 @@ export class BrowserHardRedirectService extends HardRedirectService {
* @param url * @param url
*/ */
redirect(url: string) { redirect(url: string) {
this.location.href = url; this.location.replace(url);
} }
/** /**

View File

@@ -10,6 +10,7 @@ describe('Config Util', () => {
expect(appConfig.cache.msToLive.default).toEqual(15 * 60 * 1000); // 15 minute expect(appConfig.cache.msToLive.default).toEqual(15 * 60 * 1000); // 15 minute
expect(appConfig.ui.rateLimiter.windowMs).toEqual(1 * 60 * 1000); // 1 minute expect(appConfig.ui.rateLimiter.windowMs).toEqual(1 * 60 * 1000); // 1 minute
expect(appConfig.ui.rateLimiter.max).toEqual(500); expect(appConfig.ui.rateLimiter.max).toEqual(500);
expect(appConfig.ui.useProxies).toEqual(true);
expect(appConfig.submission.autosave.metadata).toEqual([]); expect(appConfig.submission.autosave.metadata).toEqual([]);
@@ -25,6 +26,8 @@ describe('Config Util', () => {
}; };
appConfig.ui.rateLimiter = rateLimiter; appConfig.ui.rateLimiter = rateLimiter;
appConfig.ui.useProxies = false;
const autoSaveMetadata = [ const autoSaveMetadata = [
'dc.author', 'dc.author',
'dc.title' 'dc.title'
@@ -44,6 +47,7 @@ describe('Config Util', () => {
expect(environment.cache.msToLive.default).toEqual(msToLive); expect(environment.cache.msToLive.default).toEqual(msToLive);
expect(environment.ui.rateLimiter.windowMs).toEqual(rateLimiter.windowMs); expect(environment.ui.rateLimiter.windowMs).toEqual(rateLimiter.windowMs);
expect(environment.ui.rateLimiter.max).toEqual(rateLimiter.max); expect(environment.ui.rateLimiter.max).toEqual(rateLimiter.max);
expect(environment.ui.useProxies).toEqual(false);
expect(environment.submission.autosave.metadata[0]).toEqual(autoSaveMetadata[0]); expect(environment.submission.autosave.metadata[0]).toEqual(autoSaveMetadata[0]);
expect(environment.submission.autosave.metadata[1]).toEqual(autoSaveMetadata[1]); expect(environment.submission.autosave.metadata[1]).toEqual(autoSaveMetadata[1]);

View File

@@ -39,7 +39,10 @@ export class DefaultAppConfig implements AppConfig {
rateLimiter: { rateLimiter: {
windowMs: 1 * 60 * 1000, // 1 minute windowMs: 1 * 60 * 1000, // 1 minute
max: 500 // limit each IP to 500 requests per windowMs max: 500 // limit each IP to 500 requests per windowMs
} },
// Trust X-FORWARDED-* headers from proxies
useProxies: true,
}; };
// The REST API server settings // The REST API server settings

View File

@@ -11,4 +11,6 @@ export class UIServerConfig extends ServerConfig {
max: number; max: number;
}; };
// Trust X-FORWARDED-* headers from proxies
useProxies: boolean;
} }

View File

@@ -25,7 +25,8 @@ export const environment: BuildConfig = {
rateLimiter: { rateLimiter: {
windowMs: 1 * 60 * 1000, // 1 minute windowMs: 1 * 60 * 1000, // 1 minute
max: 500 // limit each IP to 500 requests per windowMs max: 500 // limit each IP to 500 requests per windowMs
} },
useProxies: true,
}, },
// The REST API server settings. // The REST API server settings.