diff --git a/deploy/app.js b/deploy/app.js index e2260239c9dc507b9079e7a510b2750c20c5d27d..bd6d3be4b0de6ce041fbafdb6f250d1b7d50d797 100644 --- a/deploy/app.js +++ b/deploy/app.js @@ -44,6 +44,11 @@ const PUBLIC_PATH = process.env.NODE_ENV === 'production' ? path.join(__dirname, 'public') : path.join(__dirname, '..', 'dist', 'aot') +app.use((_req, res, next) => { + res.setHeader('Referrer-Policy', 'origin-when-cross-origin') + next() +}) + app.use(express.static(PUBLIC_PATH)) app.use((req, res, next) => { diff --git a/src/atlasViewer/atlasViewer.constantService.service.ts b/src/atlasViewer/atlasViewer.constantService.service.ts index 47f220b7b59260a642d44bac283a1b8b704b12b3..cdcdbd71ed6b74084e717678edf0d7bd01a61b98 100644 --- a/src/atlasViewer/atlasViewer.constantService.service.ts +++ b/src/atlasViewer/atlasViewer.constantService.service.ts @@ -41,7 +41,7 @@ export class AtlasViewerConstantsServices{ * raceFetch */ public raceFetch = (url) => Promise.race([ - fetch(url), + fetch(url, this.getFetchOption()), new Promise((_, reject) => setTimeout(() => { reject(`fetch did not resolve under ${this.TIMEOUT} ms`) }, this.TIMEOUT)) as Promise<Response> @@ -58,7 +58,7 @@ export class AtlasViewerConstantsServices{ /* to be provided by KG in future */ public templateUrlsPr : Promise<string[]> = new Promise((resolve, reject) => { - fetch(`${this.backendUrl}templates`) + fetch(`${this.backendUrl}templates`, this.getFetchOption()) .then(res => res.json()) .then(arr => { this.templateUrls = arr @@ -155,6 +155,23 @@ Interactive atlas viewer requires **webgl2.0**, and the \`EXT_color_buffer_float public mobileWarningHeader = `Power and Network Usage warning` public mobileWarning = `It looks like you are on a mobile device. Please note that the atlas viewer is power and network usage intensive.` + /** + * When the selected regions becomes exceedingly many, referer header often gets too hard + * in nginx, it can result in 400 header to large + * as result, trim referer to only template and parcellation selected + */ + private getScopedReferer(): string{ + const url = new URL(window.location.href) + url.searchParams.delete('regionsSelected') + return url.toString() + } + + public getFetchOption() : RequestInit{ + return { + referrer: this.getScopedReferer() + } + } + get floatingWidgetStartingPos() : [number,number]{ return [400,100] } @@ -264,7 +281,7 @@ Interactive atlas viewer requires **webgl2.0**, and the \`EXT_color_buffer_float */ const meta = 'res/json/allAggregatedData.json' - fetch(meta) + fetch(meta, this.getFetchOption()) .then(res=>res.json()) .then(metadata=>{ const data = metadata.reduce((acc:[string,Map<string,{properties:Property}>][],curr:any)=>{ diff --git a/src/atlasViewer/atlasViewer.dataService.service.ts b/src/atlasViewer/atlasViewer.dataService.service.ts index b974d8536374bc1d38c467e935d5543ee2691352..e19a8c363580c18d47209bb8b79c7e98a619326a 100644 --- a/src/atlasViewer/atlasViewer.dataService.service.ts +++ b/src/atlasViewer/atlasViewer.dataService.service.ts @@ -56,6 +56,11 @@ export class AtlasViewerDataService implements OnDestroy{ } + /** + * TODO + * DEPRECATED + */ + /* all units in mm */ public spatialSearch(obj:any){ const {center,searchWidth,templateSpace,pageNo} = obj diff --git a/src/atlasViewer/atlasViewer.pluginService.service.ts b/src/atlasViewer/atlasViewer.pluginService.service.ts index 7adc864521c39d581871bd6be3b1a8172e065ed4..f7e2c5ef7414599ffe7029c97303d3eb1fba1655 100644 --- a/src/atlasViewer/atlasViewer.pluginService.service.ts +++ b/src/atlasViewer/atlasViewer.pluginService.service.ts @@ -44,17 +44,17 @@ export class PluginServices{ * PLUGINDEV should return an array of */ PLUGINDEV - ? fetch(PLUGINDEV).then(res => res.json()) + ? fetch(PLUGINDEV, this.constantService.getFetchOption()).then(res => res.json()) : Promise.resolve([]), new Promise(resolve => { - fetch(`${this.constantService.backendUrl}plugins`) + fetch(`${this.constantService.backendUrl}plugins`, this.constantService.getFetchOption()) .then(res => res.json()) .then(arr => Promise.all( arr.map(url => new Promise(rs => /** * instead of failing all promises when fetching manifests, only fail those that fails to fetch */ - fetch(url).then(res => res.json()).then(rs).catch(e => (console.log('fetching manifest error', e), rs(null)))) + fetch(url, this.constantService.getFetchOption()).then(res => res.json()).then(rs).catch(e => (console.log('fetching manifest error', e), rs(null)))) ) )) .then(manifests => resolve( @@ -67,7 +67,7 @@ export class PluginServices{ Promise.all( BUNDLEDPLUGINS .filter(v => typeof v === 'string') - .map(v => fetch(`res/plugin_examples/${v}/manifest.json`).then(res => res.json())) + .map(v => fetch(`res/plugin_examples/${v}/manifest.json`, this.constantService.getFetchOption()).then(res => res.json())) ) .then(arr => arr.reduce((acc,curr) => acc.concat(curr) ,[])) ]) @@ -94,14 +94,14 @@ export class PluginServices{ isDefined(plugin.template) ? Promise.resolve('template already provided') : isDefined(plugin.templateURL) ? - fetch(plugin.templateURL) + fetch(plugin.templateURL, this.constantService.getFetchOption()) .then(res=>res.text()) .then(template=>plugin.template = template) : Promise.reject('both template and templateURL are not defined') , isDefined(plugin.script) ? Promise.resolve('script already provided') : isDefined(plugin.scriptURL) ? - fetch(plugin.scriptURL) + fetch(plugin.scriptURL, this.constantService.getFetchOption()) .then(res=>res.text()) .then(script=>plugin.script = script) : Promise.reject('both script and scriptURL are not defined') diff --git a/src/atlasViewer/atlasViewer.urlService.service.ts b/src/atlasViewer/atlasViewer.urlService.service.ts index 77cfd7e1e5210ee4d8a8d63997c409ca676def96..ceeaa9fba07cdcc41a0700f30d74b6ada195f20b 100644 --- a/src/atlasViewer/atlasViewer.urlService.service.ts +++ b/src/atlasViewer/atlasViewer.urlService.service.ts @@ -209,7 +209,7 @@ export class AtlasViewerURLService{ const pluginStates = searchparams.get('pluginStates') if(pluginStates){ const arrPluginStates = pluginStates.split('__') - arrPluginStates.forEach(url => fetch(url).then(res => res.json()).then(json => this.pluginService.launchNewWidget(json)).catch(console.error)) + arrPluginStates.forEach(url => fetch(url, this.constantService.getFetchOption()).then(res => res.json()).then(json => this.pluginService.launchNewWidget(json)).catch(console.error)) } }) diff --git a/src/services/auth.service.ts b/src/services/auth.service.ts index 20a8f38d1fe204320dff0061d34d24497866783a..b3019e8bba440ad2c44dcc4d5cb518b02a43c693 100644 --- a/src/services/auth.service.ts +++ b/src/services/auth.service.ts @@ -1,4 +1,5 @@ import { Injectable } from "@angular/core"; +import { AtlasViewerConstantsServices } from "src/atlasViewer/atlasViewer.constantService.service"; const IV_REDIRECT_TOKEN = `IV_REDIRECT_TOKEN` @@ -19,8 +20,8 @@ export class AuthService{ href: 'hbp-oidc/auth' }] - constructor() { - fetch('user') + constructor(constantService: AtlasViewerConstantsServices) { + fetch('user', constantService.getFetchOption()) .then(res => res.json()) .then(user => this.user = user) .catch(e => { diff --git a/src/ui/databrowserModule/databrowser.service.ts b/src/ui/databrowserModule/databrowser.service.ts index 5baa496dc446a07906ffb41a99358a134d98a357..c01ece7f3b148384e4d700bec54ab00dfd904635 100644 --- a/src/ui/databrowserModule/databrowser.service.ts +++ b/src/ui/databrowserModule/databrowser.service.ts @@ -127,7 +127,7 @@ export class DatabrowserService implements OnDestroy{ const pt1 = center.map(v => (v - searchWidth).toFixed(SPATIAL_SEARCH_PRECISION)) const pt2 = center.map(v => (v + searchWidth).toFixed(SPATIAL_SEARCH_PRECISION)) - return from(fetch(`${this.constantService.backendUrl}datasets/spatialSearch/templateName/${encodedTemplateName}/bbox/${pt1.join('_')}__${pt2.join("_")}`) + return from(fetch(`${this.constantService.backendUrl}datasets/spatialSearch/templateName/${encodedTemplateName}/bbox/${pt1.join('_')}__${pt2.join("_")}`, this.constantService.getFetchOption()) .then(res => res.json())) }), catchError((err) => (console.log(err), of([]))) @@ -197,7 +197,7 @@ export class DatabrowserService implements OnDestroy{ public fetchPreviewData(datasetName: string){ const encodedDatasetName = encodeURI(datasetName) return new Promise((resolve, reject) => { - fetch(`${this.constantService.backendUrl}datasets/preview/${encodedDatasetName}`) + fetch(`${this.constantService.backendUrl}datasets/preview/${encodedDatasetName}`, this.constantService.getFetchOption()) .then(res => res.json()) .then(resolve) .catch(reject) @@ -235,9 +235,9 @@ export class DatabrowserService implements OnDestroy{ const encodedTemplateName = encodeURI(templateName) const encodedParcellationName = encodeURI(parcellationName) return Promise.all([ - fetch(`${this.constantService.backendUrl}datasets/templateName/${encodedTemplateName}`) + fetch(`${this.constantService.backendUrl}datasets/templateName/${encodedTemplateName}`, this.constantService.getFetchOption()) .then(res => res.json()), - fetch(`${this.constantService.backendUrl}datasets/parcellationName/${encodedParcellationName}`) + fetch(`${this.constantService.backendUrl}datasets/parcellationName/${encodedParcellationName}`, this.constantService.getFetchOption()) .then(res => res.json()) ]) .then(arr => [...arr[0], ...arr[1]]) diff --git a/src/util/worker.js b/src/util/worker.js index 44eeeeb5144cdee87833e80c3fb76c525551868d..dd374c4c0d5457ac97783d3e08f671b054e36678 100644 --- a/src/util/worker.js +++ b/src/util/worker.js @@ -18,7 +18,9 @@ const checkMeshes = (action) => { /* filtering now done on the angular level */ const baseUrl = action.baseUrl - fetch(`${baseUrl}/info`) + fetch(`${baseUrl}/info`, { + referrerPolicy: 'no-referrer' + }) .then(res => res.json()) .then(({mesh}) => { if (mesh) @@ -27,7 +29,9 @@ const checkMeshes = (action) => { throw new Error('mesh does not exist') }) .then(meshPath => action.indices.forEach(index => { - fetch(`${baseUrl}/${meshPath}/${index}:0`) + fetch(`${baseUrl}/${meshPath}/${index}:0`, { + referrerPolicy: 'no-referrer' + }) .then(res => res.json()) .then(json => { /* the perspectiveEvent only counts json that has fragments as a part of meshLoaded */ diff --git a/webpack.dev.js b/webpack.dev.js index 3fe037c472f808ff4a811607d1992412c5e30d72..d32be20fe85174ca5ae969f2d1b99ca43d87558b 100644 --- a/webpack.dev.js +++ b/webpack.dev.js @@ -20,5 +20,10 @@ module.exports = merge(common,ngAssets,staticAssets,{ new HtmlWebpackPlugin({ template : 'src/index.html' }) - ] + ], + devServer: { + headers: { + 'Referrer-Policy': 'origin-when-cross-origin' + } + } }) \ No newline at end of file