Skip to content

Commit db0ccb2

Browse files
committed
Ensure we are no longer using/trusting "Host" HTTP Header. Require setting existing environment.ui.baseUrl. Replace ServerHardRedirectService.getCurrentOrigin() with getBaseUrl() to read this setting.
1 parent 0cc300c commit db0ccb2

15 files changed

Lines changed: 74 additions & 34 deletions

config/config.example.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ ui:
88
ssl: false
99
host: localhost
1010
port: 4000
11+
# Specify the public URL that this user interface responds to. This corresponds to the "dspace.ui.url" property in your backend's local.cfg.
12+
# SSR is only enabled when the client's "Host" HTTP header matches this baseUrl. The baseUrl is also used for redirects and SEO links (in robots.txt).
13+
baseUrl: http://localhost:4000
1114
# NOTE: Space is capitalized because 'namespace' is a reserved string in TypeScript
1215
nameSpace: /
1316
# The rateLimiter settings limit each IP to a 'limit' of 500 requests per 'windowMs' (1 minute).

server.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ export function app() {
145145
server.get('/robots.txt', (req, res) => {
146146
res.setHeader('content-type', 'text/plain');
147147
res.render('assets/robots.txt.ejs', {
148-
'origin': req.protocol + '://' + req.headers.host,
148+
'origin': environment.ui.baseUrl,
149149
});
150150
});
151151

src/app/bitstream-page/legacy-bitstream-url-redirect.guard.spec.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { RouterStub } from '@dspace/core/testing/router.stub';
99
import { cold } from 'jasmine-marbles';
1010
import { EMPTY } from 'rxjs';
1111

12+
import { environment } from '../../environments/environment';
1213
import { legacyBitstreamURLRedirectGuard } from './legacy-bitstream-url-redirect.guard';
1314

1415
describe('legacyBitstreamURLRedirectGuard', () => {
@@ -150,7 +151,7 @@ describe('legacyBitstreamURLRedirectGuard', () => {
150151
}));
151152
resolver(route, state, bitstreamDataService, hardRedirectService, router).subscribe(() => {
152153
expect(bitstreamDataService.findByItemHandle).toHaveBeenCalled();
153-
expect(hardRedirectService.redirect).toHaveBeenCalledWith(new URL(`/bitstreams/${bitstream.uuid}/download`, window.location.origin).href, 301);
154+
expect(hardRedirectService.redirect).toHaveBeenCalledWith(new URL(`/bitstreams/${bitstream.uuid}/download`, environment.ui.baseUrl).href, 301);
154155
});
155156
});
156157
});

src/app/bitstream-page/legacy-bitstream-url-redirect.guard.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
import { BitstreamDataService } from '@dspace/core/data/bitstream-data.service';
1010
import { RemoteData } from '@dspace/core/data/remote-data';
1111
import { PAGE_NOT_FOUND_PATH } from '@dspace/core/router/core-routing-paths';
12+
import { getBitstreamDownloadRoute } from '@dspace/core/router/utils/dso-route.utils';
1213
import { HardRedirectService } from '@dspace/core/services/hard-redirect.service';
1314
import { Bitstream } from '@dspace/core/shared/bitstream.model';
1415
import { getFirstCompletedRemoteData } from '@dspace/core/shared/operators';
@@ -46,7 +47,7 @@ export const legacyBitstreamURLRedirectGuard: CanActivateFn = (
4647
getFirstCompletedRemoteData(),
4748
map((rd: RemoteData<Bitstream>) => {
4849
if (rd.hasSucceeded && !rd.hasNoContent) {
49-
serverHardRedirectService.redirect(new URL(`/bitstreams/${rd.payload.uuid}/download`, serverHardRedirectService.getCurrentOrigin()).href, 301);
50+
serverHardRedirectService.redirect(new URL(getBitstreamDownloadRoute(rd.payload), serverHardRedirectService.getBaseUrl()).href, 301);
5051
return false;
5152
} else {
5253
return router.createUrlTree([PAGE_NOT_FOUND_PATH]);

src/app/core/metadata/head-tag.service.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ describe('HeadTagService', () => {
9696
},
9797
} as any as Router;
9898
hardRedirectService = jasmine.createSpyObj( {
99-
getCurrentOrigin: 'https://request.org',
99+
getBaseUrl: 'https://request.org',
100100
});
101101
authorizationService = jasmine.createSpyObj('authorizationService', {
102102
isAuthorized: of(true),

src/app/core/metadata/head-tag.service.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ export class HeadTagService {
324324
if (this.currentObject.value instanceof Item) {
325325
let url = this.getMetaTagValue('dc.identifier.uri');
326326
if (hasNoValue(url)) {
327-
url = new URLCombiner(this.hardRedirectService.getCurrentOrigin(), this.router.url).toString();
327+
url = new URLCombiner(this.hardRedirectService.getBaseUrl(), this.router.url).toString();
328328
}
329329
this.addMetaTag('citation_abstract_html_url', url);
330330
}
@@ -407,7 +407,7 @@ export class HeadTagService {
407407
// Use the found link to set the <meta> tag
408408
this.addMetaTag(
409409
'citation_pdf_url',
410-
new URLCombiner(this.hardRedirectService.getCurrentOrigin(), link).toString(),
410+
new URLCombiner(this.hardRedirectService.getBaseUrl(), link).toString(),
411411
);
412412
});
413413
}

src/app/core/services/browser-hard-redirect.service.spec.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import { TestBed } from '@angular/core/testing';
22

3+
import { environment } from '../../../environments/environment';
34
import { BrowserHardRedirectService } from './browser-hard-redirect.service';
45

56
describe('BrowserHardRedirectService', () => {
67
let origin: string;
78
let mockLocation: Location;
89
let service: BrowserHardRedirectService;
10+
let originalBaseUrl;
911

1012
beforeEach(() => {
1113
origin = 'https://test-host.com:4000';
@@ -20,11 +22,22 @@ describe('BrowserHardRedirectService', () => {
2022
} as Location;
2123
spyOn(mockLocation, 'replace');
2224

25+
// Store original environment variable to restore after tests
26+
originalBaseUrl = environment.ui.baseUrl;
27+
28+
// Set environment variable to match our mock location origin for testing
29+
environment.ui.baseUrl = origin;
30+
2331
service = new BrowserHardRedirectService(mockLocation);
2432

2533
TestBed.configureTestingModule({});
2634
});
2735

36+
afterEach(() => {
37+
// Restore original environment variable after tests
38+
environment.ui.baseUrl = originalBaseUrl;
39+
});
40+
2841
it('should be created', () => {
2942
expect(service).toBeTruthy();
3043
});
@@ -52,7 +65,7 @@ describe('BrowserHardRedirectService', () => {
5265
describe('when requesting the origin', () => {
5366

5467
it('should return the location origin', () => {
55-
expect(service.getCurrentOrigin()).toEqual(origin);
68+
expect(service.getBaseUrl()).toEqual(origin);
5669
});
5770
});
5871

src/app/core/services/browser-hard-redirect.service.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
InjectionToken,
55
} from '@angular/core';
66

7+
import { environment } from '../../../environments/environment';
78
import { HardRedirectService } from './hard-redirect.service';
89

910
export const LocationToken = new InjectionToken('Location');
@@ -41,12 +42,11 @@ export class BrowserHardRedirectService extends HardRedirectService {
4142
}
4243

4344
/**
44-
* Get the origin of the current URL
45+
* Get the base public URL of our application.
46+
* This is used as the base URL for redirects, and should be in the format of
4547
* i.e. <scheme> "://" <hostname> [ ":" <port> ]
46-
* e.g. if the URL is https://demo.dspace.org/search?query=test,
47-
* the origin would be https://demo.dspace.org
4848
*/
49-
getCurrentOrigin(): string {
50-
return this.location.origin;
49+
getBaseUrl(): string {
50+
return environment.ui.baseUrl;
5151
}
5252
}

src/app/core/services/browser.referrer.service.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ describe(`BrowserReferrerService`, () => {
1616
service = new BrowserReferrerService(
1717
{ referrer: documentReferrer },
1818
routeService,
19-
{ getCurrentOrigin: () => origin } as any,
19+
{ getBaseUrl: () => origin } as any,
2020
);
2121
});
2222

src/app/core/services/browser.referrer.service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export class BrowserReferrerService extends ReferrerService {
5050
const reversedHistory = [...history].reverse();
5151
// and find the first URL that differs from the current one
5252
const prevUrl = reversedHistory.find((url: string) => url !== currentURL);
53-
return new URLCombiner(this.hardRedirectService.getCurrentOrigin(), prevUrl).toString();
53+
return new URLCombiner(this.hardRedirectService.getBaseUrl(), prevUrl).toString();
5454
}
5555
}),
5656
);

0 commit comments

Comments
 (0)