Skip to content

Commit 9a433b5

Browse files
author
William Welling
committed
support base path
1 parent 37ebe25 commit 9a433b5

File tree

18 files changed

+111
-38
lines changed

18 files changed

+111
-38
lines changed

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@
99
"start:dev": "nodemon --exec \"cross-env NODE_ENV=development yarn run serve\"",
1010
"start:prod": "yarn run build:prod && cross-env NODE_ENV=production yarn run serve:ssr",
1111
"start:mirador:prod": "yarn run build:mirador && yarn run start:prod",
12-
"serve": "ng serve -c development",
12+
"preserve": "yarn base-href",
13+
"serve": "ng serve --configuration development",
1314
"serve:ssr": "node dist/server/main",
1415
"analyze": "webpack-bundle-analyzer dist/browser/stats.json",
15-
"build": "ng build -c development",
16+
"build": "ng build --configuration development",
1617
"build:stats": "ng build --stats-json",
1718
"build:prod": "yarn run build:ssr",
1819
"build:ssr": "ng build --configuration production && ng run dspace-angular:server:production",
@@ -37,6 +38,7 @@
3738
"cypress:open": "cypress open",
3839
"cypress:run": "cypress run",
3940
"env:yaml": "ts-node --project ./tsconfig.ts-node.json scripts/env-to-yaml.ts",
41+
"base-href": "ts-node --project ./tsconfig.ts-node.json scripts/base-href.ts",
4042
"check-circ-deps": "npx madge --exclude '(bitstream|bundle|collection|config-submission-form|eperson|item|version)\\.model\\.ts$' --circular --extensions ts ./"
4143
},
4244
"browser": {

scripts/base-href.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import * as fs from 'fs';
2+
import { join } from 'path';
3+
4+
import { AppConfig } from '../src/config/app-config.interface';
5+
import { buildAppConfig } from '../src/config/config.server';
6+
7+
/**
8+
* Script to set baseHref as `ui.nameSpace` for development mode. Adds `baseHref` to angular.json build options.
9+
*
10+
* Usage (see package.json):
11+
*
12+
* yarn base-href
13+
*/
14+
15+
const appConfig: AppConfig = buildAppConfig();
16+
17+
const angularJsonPath = join(process.cwd(), 'angular.json');
18+
19+
if (!fs.existsSync(angularJsonPath)) {
20+
console.error(`Error:\n${angularJsonPath} does not exist\n`);
21+
process.exit(1);
22+
}
23+
24+
try {
25+
const angularJson = require(angularJsonPath);
26+
27+
const baseHref = `${appConfig.ui.nameSpace}${appConfig.ui.nameSpace.endsWith('/') ? '' : '/'}`;
28+
29+
console.log(`Setting baseHref to ${baseHref} in angular.json`);
30+
31+
angularJson.projects['dspace-angular'].architect.build.options.baseHref = baseHref;
32+
33+
fs.writeFileSync(angularJsonPath, JSON.stringify(angularJson, null, 2) + '\n');
34+
} catch (e) {
35+
console.error(e);
36+
}

server.ts

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ extendEnvironmentWithAppConfig(environment, appConfig);
6666
// The Express app is exported so that it can be used by serverless Functions.
6767
export function app() {
6868

69+
const router = express.Router();
70+
6971
/*
7072
* Create a new express application
7173
*/
@@ -133,7 +135,11 @@ export function app() {
133135
/**
134136
* Proxy the sitemaps
135137
*/
136-
server.use('/sitemap**', createProxyMiddleware({ target: `${environment.rest.baseUrl}/sitemaps`, changeOrigin: true }));
138+
router.use('/sitemap**', createProxyMiddleware({
139+
target: `${environment.rest.baseUrl}/sitemaps`,
140+
pathRewrite: path => path.replace(environment.ui.nameSpace, '/'),
141+
changeOrigin: true
142+
}));
137143

138144
/**
139145
* Checks if the rateLimiter property is present
@@ -151,14 +157,16 @@ export function app() {
151157
/*
152158
* Serve static resources (images, i18n messages, …)
153159
*/
154-
server.get('*.*', cacheControl, express.static(DIST_FOLDER, { index: false }));
160+
router.get('*.*', cacheControl, express.static(DIST_FOLDER, { index: false }));
155161
/*
156162
* Fallthrough to the IIIF viewer (must be included in the build).
157163
*/
158-
server.use('/iiif', express.static(IIIF_VIEWER, {index:false}));
164+
router.use('/iiif', express.static(IIIF_VIEWER, { index: false }));
159165

160166
// Register the ngApp callback function to handle incoming requests
161-
server.get('*', ngApp);
167+
router.get('*', ngApp);
168+
169+
server.use(environment.ui.nameSpace, router);
162170

163171
return server;
164172
}
@@ -191,13 +199,25 @@ function ngApp(req, res) {
191199
if (hasValue(err)) {
192200
console.warn('Error details : ', err);
193201
}
194-
res.sendFile(DIST_FOLDER + '/index.html');
202+
res.render(indexHtml, {
203+
req,
204+
providers: [{
205+
provide: APP_BASE_HREF,
206+
useValue: req.baseUrl
207+
}]
208+
});
195209
}
196210
});
197211
} else {
198212
// If preboot is disabled, just serve the client
199213
console.log('Universal off, serving for direct CSR');
200-
res.sendFile(DIST_FOLDER + '/index.html');
214+
res.render(indexHtml, {
215+
req,
216+
providers: [{
217+
provide: APP_BASE_HREF,
218+
useValue: req.baseUrl
219+
}]
220+
});
201221
}
202222
}
203223

src/app/app.component.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ describe('App component', () => {
187187
link.setAttribute('rel', 'stylesheet');
188188
link.setAttribute('type', 'text/css');
189189
link.setAttribute('class', 'theme-css');
190-
link.setAttribute('href', '/custom-theme.css');
190+
link.setAttribute('href', 'custom-theme.css');
191191

192192
expect(headSpy.appendChild).toHaveBeenCalledWith(link);
193193
});

src/app/app.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ export class AppComponent implements OnInit, AfterViewInit {
268268
link.setAttribute('rel', 'stylesheet');
269269
link.setAttribute('type', 'text/css');
270270
link.setAttribute('class', 'theme-css');
271-
link.setAttribute('href', `/${encodeURIComponent(themeName)}-theme.css`);
271+
link.setAttribute('href', `${encodeURIComponent(themeName)}-theme.css`);
272272
// wait for the new css to download before removing the old one to prevent a
273273
// flash of unstyled content
274274
link.onload = () => {

src/app/app.module.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { APP_BASE_HREF, CommonModule } from '@angular/common';
1+
import { APP_BASE_HREF, CommonModule, DOCUMENT } from '@angular/common';
22
import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
33
import { APP_INITIALIZER, NgModule } from '@angular/core';
44
import { AbstractControl } from '@angular/forms';
@@ -66,9 +66,11 @@ export function getConfig() {
6666
return environment;
6767
}
6868

69-
export function getBase(appConfig: AppConfig) {
70-
return appConfig.ui.nameSpace;
71-
}
69+
const getBaseHref = (document: Document, appConfig: AppConfig): string => {
70+
const baseTag = document.querySelector('head > base');
71+
baseTag.setAttribute('href', `${appConfig.ui.nameSpace}${appConfig.ui.nameSpace.endsWith('/') ? '' : '/'}`);
72+
return baseTag.getAttribute('href');
73+
};
7274

7375
export function getMetaReducers(appConfig: AppConfig): MetaReducer<AppState>[] {
7476
return appConfig.debug ? [...appMetaReducers, ...debugMetaReducers] : appMetaReducers;
@@ -107,8 +109,8 @@ const PROVIDERS = [
107109
},
108110
{
109111
provide: APP_BASE_HREF,
110-
useFactory: getBase,
111-
deps: [APP_CONFIG]
112+
useFactory: getBaseHref,
113+
deps: [DOCUMENT, APP_CONFIG]
112114
},
113115
{
114116
provide: USER_PROVIDED_META_REDUCERS,

src/app/core/auth/auth.service.spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -368,25 +368,25 @@ describe('AuthService test', () => {
368368
it('should redirect to reload with redirect url', () => {
369369
authService.navigateToRedirectUrl('/collection/123');
370370
// Reload with redirect URL set to /collection/123
371-
expect(hardRedirectService.redirect).toHaveBeenCalledWith(jasmine.stringMatching(new RegExp('/reload/[0-9]*\\?redirect=' + encodeURIComponent('/collection/123'))));
371+
expect(hardRedirectService.redirect).toHaveBeenCalledWith(jasmine.stringMatching(new RegExp('reload/[0-9]*\\?redirect=' + encodeURIComponent('/collection/123'))));
372372
});
373373

374374
it('should redirect to reload with /home', () => {
375375
authService.navigateToRedirectUrl('/home');
376376
// Reload with redirect URL set to /home
377-
expect(hardRedirectService.redirect).toHaveBeenCalledWith(jasmine.stringMatching(new RegExp('/reload/[0-9]*\\?redirect=' + encodeURIComponent('/home'))));
377+
expect(hardRedirectService.redirect).toHaveBeenCalledWith(jasmine.stringMatching(new RegExp('reload/[0-9]*\\?redirect=' + encodeURIComponent('/home'))));
378378
});
379379

380380
it('should redirect to regular reload and not to /login', () => {
381381
authService.navigateToRedirectUrl('/login');
382382
// Reload without a redirect URL
383-
expect(hardRedirectService.redirect).toHaveBeenCalledWith(jasmine.stringMatching(new RegExp('/reload/[0-9]*(?!\\?)$')));
383+
expect(hardRedirectService.redirect).toHaveBeenCalledWith(jasmine.stringMatching(new RegExp('reload/[0-9]*(?!\\?)$')));
384384
});
385385

386386
it('should redirect to regular reload when no redirect url is found', () => {
387387
authService.navigateToRedirectUrl(undefined);
388388
// Reload without a redirect URL
389-
expect(hardRedirectService.redirect).toHaveBeenCalledWith(jasmine.stringMatching(new RegExp('/reload/[0-9]*(?!\\?)$')));
389+
expect(hardRedirectService.redirect).toHaveBeenCalledWith(jasmine.stringMatching(new RegExp('reload/[0-9]*(?!\\?)$')));
390390
});
391391

392392
describe('impersonate', () => {

src/app/core/auth/auth.service.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -447,8 +447,8 @@ export class AuthService {
447447
*/
448448
public navigateToRedirectUrl(redirectUrl: string) {
449449
// Don't do redirect if already on reload url
450-
if (!hasValue(redirectUrl) || !redirectUrl.includes('/reload/')) {
451-
let url = `/reload/${new Date().getTime()}`;
450+
if (!hasValue(redirectUrl) || !redirectUrl.includes('reload/')) {
451+
let url = `reload/${new Date().getTime()}`;
452452
if (isNotEmpty(redirectUrl) && !redirectUrl.startsWith(LOGIN_ROUTE)) {
453453
url += `?redirect=${encodeURIComponent(redirectUrl)}`;
454454
}

src/app/core/locale/locale.service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ export class LocaleService {
192192
this.routeService.getCurrentUrl().pipe(take(1)).subscribe((currentURL) => {
193193
// Hard redirect to the reload page with a unique number behind it
194194
// so that all state is definitely lost
195-
this._window.nativeWindow.location.href = `/reload/${new Date().getTime()}?redirect=` + encodeURIComponent(currentURL);
195+
this._window.nativeWindow.location.href = `reload/${new Date().getTime()}?redirect=` + encodeURIComponent(currentURL);
196196
});
197197

198198
}

src/app/core/reload/reload.guard.spec.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
1-
import { ReloadGuard } from './reload.guard';
21
import { Router } from '@angular/router';
2+
import { AppConfig } from '../../../config/app-config.interface';
3+
import { DefaultAppConfig } from '../../../config/default-app-config';
4+
import { ReloadGuard } from './reload.guard';
35

46
describe('ReloadGuard', () => {
57
let guard: ReloadGuard;
68
let router: Router;
9+
let appConfig: AppConfig;
710

811
beforeEach(() => {
912
router = jasmine.createSpyObj('router', ['parseUrl', 'createUrlTree']);
10-
guard = new ReloadGuard(router);
13+
appConfig = new DefaultAppConfig();
14+
guard = new ReloadGuard(router, appConfig);
1115
});
1216

1317
describe('canActivate', () => {
@@ -27,7 +31,7 @@ describe('ReloadGuard', () => {
2731

2832
it('should create a UrlTree with the redirect URL', () => {
2933
guard.canActivate(route, undefined);
30-
expect(router.parseUrl).toHaveBeenCalledWith(redirectUrl);
34+
expect(router.parseUrl).toHaveBeenCalledWith(redirectUrl.substring(1));
3135
});
3236
});
3337

0 commit comments

Comments
 (0)