[ADF-3938] support for XMLHttpRequest.withCredentials flag (#4190)

* support XMLHttpRequest.withCredentials

* proper defaults and json schema updates

* remove outdated docs

* remove empty declaration from app config

* fix blob support
This commit is contained in:
Denys Vuika
2019-01-25 12:12:06 +00:00
committed by Eugenio Romano
parent 08c9b6d117
commit 5887fa1052
6 changed files with 69 additions and 32 deletions

View File

@@ -3,12 +3,14 @@
"ecmHost": "{protocol}//{hostname}{:port}", "ecmHost": "{protocol}//{hostname}{:port}",
"bpmHost": "{protocol}//{hostname}{:port}", "bpmHost": "{protocol}//{hostname}{:port}",
"identityHost": "{protocol}//{hostname}{:port}/auth/realms/alfresco", "identityHost": "{protocol}//{hostname}{:port}/auth/realms/alfresco",
"baseShareUrl": null,
"loginRoute": "login", "loginRoute": "login",
"providers": "ALL", "providers": "ALL",
"contextRootBpm": "activiti-app", "contextRootBpm": "activiti-app",
"authType" : "BASIC", "authType" : "BASIC",
"locale" : "en", "locale" : "en",
"auth": {
"withCredentials": false
},
"oauth2": { "oauth2": {
"host": "{protocol}//{hostname}{:port}/auth/realms/alfresco", "host": "{protocol}//{hostname}{:port}/auth/realms/alfresco",
"clientId": "alfresco", "clientId": "alfresco",

View File

@@ -66,22 +66,6 @@ Example of the default settings file content:
Note that the settings in the example above are the default ones supplied with the server. Note that the settings in the example above are the default ones supplied with the server.
You can override the values in your custom `app.config.json` file if necessary. You can override the values in your custom `app.config.json` file if necessary.
You can change the path or name of the configuration file when importing the [`CoreModule`](../../lib/core/core.module.ts) in your main application.
```ts
...
@NgModule({
imports: [
...
CoreModule.forRoot({
appConfigFile: 'app.production.config.json'
})
],
...
}
export class AppModule { }
```
Below is a simple example of using the [`AppConfigService`](../core/app-config.service.md) in practice. Below is a simple example of using the [`AppConfigService`](../core/app-config.service.md) in practice.
**[app.component](../../demo-shell/src/app/app.component.ts).ts** **[app.component](../../demo-shell/src/app/app.component.ts).ts**
@@ -156,3 +140,16 @@ of a property when the app config is loaded:
console.log(logLevelValue); //this will be 'trace'; console.log(logLevelValue); //this will be 'trace';
}); });
``` ```
## XMLHttpRequest.withCredentials
In the configuration file, you can enable [XMLHttpRequest.withCredentials](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials)
for @alfresco/js-api calls and PDF Viewer.
```json
{
"auth": {
"withCredentials": true
}
}
```

View File

@@ -36,7 +36,8 @@ export enum AppConfigValues {
ALFRESCO_REPOSITORY_NAME = 'alfrescoRepositoryName', ALFRESCO_REPOSITORY_NAME = 'alfrescoRepositoryName',
LOG_LEVEL = 'logLevel', LOG_LEVEL = 'logLevel',
LOGIN_ROUTE = 'loginRoute', LOGIN_ROUTE = 'loginRoute',
DISABLECSRF = 'disableCSRF' DISABLECSRF = 'disableCSRF',
AUTH_WITH_CREDENTIALS = 'auth.withCredentials'
} }
export enum Status { export enum Status {

View File

@@ -833,6 +833,24 @@
"OAUTH" "OAUTH"
] ]
}, },
"baseShareUrl": {
"description": "Custom url for shared links",
"type": "string"
},
"locale": {
"description": "Default application locale",
"type": "string"
},
"auth": {
"description": "Custom authentication settings",
"type": "object",
"properties": {
"withCredentials": {
"description": "Toggle XMLHttpRequest.withCredentials for @alfresco/js-api and PDF Viewer",
"type": "boolean"
}
}
},
"oauth2": { "oauth2": {
"description": "AUTH configuration parameters", "description": "AUTH configuration parameters",
"type": "object", "type": "object",

View File

@@ -117,7 +117,7 @@ export class AlfrescoApiService {
oauth.redirectUriLogout = window.location.origin + (oauth.redirectUriLogout || '/'); oauth.redirectUriLogout = window.location.origin + (oauth.redirectUriLogout || '/');
} }
const config = { const config = new AlfrescoApiConfig({
provider: this.appConfig.get<string>(AppConfigValues.PROVIDERS), provider: this.appConfig.get<string>(AppConfigValues.PROVIDERS),
hostEcm: this.appConfig.get<string>(AppConfigValues.ECMHOST), hostEcm: this.appConfig.get<string>(AppConfigValues.ECMHOST),
hostBpm: this.appConfig.get<string>(AppConfigValues.BPMHOST), hostBpm: this.appConfig.get<string>(AppConfigValues.BPMHOST),
@@ -125,8 +125,9 @@ export class AlfrescoApiService {
contextRootBpm: this.appConfig.get<string>(AppConfigValues.CONTEXTROOTBPM), contextRootBpm: this.appConfig.get<string>(AppConfigValues.CONTEXTROOTBPM),
contextRoot: this.appConfig.get<string>(AppConfigValues.CONTEXTROOTECM), contextRoot: this.appConfig.get<string>(AppConfigValues.CONTEXTROOTECM),
disableCsrf: this.appConfig.get<boolean>(AppConfigValues.DISABLECSRF), disableCsrf: this.appConfig.get<boolean>(AppConfigValues.DISABLECSRF),
withCredentials: this.appConfig.get<boolean>(AppConfigValues.AUTH_WITH_CREDENTIALS, false),
oauth2: oauth oauth2: oauth
}; });
if (this.alfrescoApi && this.isDifferentConfig(this.lastConfig, config)) { if (this.alfrescoApi && this.isDifferentConfig(this.lastConfig, config)) {
this.lastConfig = config; this.lastConfig = config;
@@ -135,6 +136,7 @@ export class AlfrescoApiService {
this.lastConfig = config; this.lastConfig = config;
this.alfrescoApi = new AlfrescoApiCompatibility(config); this.alfrescoApi = new AlfrescoApiCompatibility(config);
} }
} }
isDifferentConfig(lastConfig: AlfrescoApiConfig, newConfig: AlfrescoApiConfig) { isDifferentConfig(lastConfig: AlfrescoApiConfig, newConfig: AlfrescoApiConfig) {

View File

@@ -24,16 +24,24 @@ import {
OnChanges, OnChanges,
OnDestroy, OnDestroy,
ViewEncapsulation, ViewEncapsulation,
EventEmitter EventEmitter,
SimpleChanges
} from '@angular/core'; } from '@angular/core';
import { MatDialog } from '@angular/material';
import { LogService } from '../../services/log.service'; import { LogService } from '../../services/log.service';
import { RenderingQueueServices } from '../services/rendering-queue.services'; import { RenderingQueueServices } from '../services/rendering-queue.services';
import { PdfPasswordDialogComponent } from './pdfViewer-password-dialog'; import { PdfPasswordDialogComponent } from './pdfViewer-password-dialog';
import { MatDialog } from '@angular/material'; import { AppConfigService } from './../../app-config/app-config.service';
declare const pdfjsLib: any; declare const pdfjsLib: any;
declare const pdfjsViewer: any; declare const pdfjsViewer: any;
export interface PdfDocumentOptions {
url?: string;
data?: any;
withCredentials?: boolean;
}
@Component({ @Component({
selector: 'adf-pdf-viewer', selector: 'adf-pdf-viewer',
templateUrl: './pdfViewer.component.html', templateUrl: './pdfViewer.component.html',
@@ -99,7 +107,8 @@ export class PdfViewerComponent implements OnChanges, OnDestroy {
constructor( constructor(
private dialog: MatDialog, private dialog: MatDialog,
private renderingQueueServices: RenderingQueueServices, private renderingQueueServices: RenderingQueueServices,
private logService: LogService) { private logService: LogService,
private appConfigService: AppConfigService) {
// needed to preserve "this" context // needed to preserve "this" context
this.onPageChange = this.onPageChange.bind(this); this.onPageChange = this.onPageChange.bind(this);
this.onPagesLoaded = this.onPagesLoaded.bind(this); this.onPagesLoaded = this.onPagesLoaded.bind(this);
@@ -107,20 +116,28 @@ export class PdfViewerComponent implements OnChanges, OnDestroy {
this.randomPdfId = this.generateUuid(); this.randomPdfId = this.generateUuid();
} }
ngOnChanges(changes) { ngOnChanges(changes: SimpleChanges) {
let blobFile = changes['blobFile']; const blobFile = changes['blobFile'];
if (blobFile && blobFile.currentValue) { if (blobFile && blobFile.currentValue) {
let reader = new FileReader(); const reader = new FileReader();
reader.onload = () => { reader.onload = () => {
this.executePdf(reader.result); const options = {
data: reader.result,
withCredentials: this.appConfigService.get<boolean>('auth.withCredentials', undefined)
};
this.executePdf(options);
}; };
reader.readAsArrayBuffer(blobFile.currentValue); reader.readAsArrayBuffer(blobFile.currentValue);
} }
let urlFile = changes['urlFile']; const urlFile = changes['urlFile'];
if (urlFile && urlFile.currentValue) { if (urlFile && urlFile.currentValue) {
this.executePdf(urlFile.currentValue); const options = {
url: urlFile.currentValue,
withCredentials: this.appConfigService.get<boolean>('auth.withCredentials', undefined)
};
this.executePdf(options);
} }
if (!this.urlFile && !this.blobFile) { if (!this.urlFile && !this.blobFile) {
@@ -128,10 +145,10 @@ export class PdfViewerComponent implements OnChanges, OnDestroy {
} }
} }
executePdf(src) { executePdf(pdfOptions: PdfDocumentOptions) {
pdfjsLib.GlobalWorkerOptions.workerSrc = 'pdf.worker.min.js'; pdfjsLib.GlobalWorkerOptions.workerSrc = 'pdf.worker.min.js';
this.loadingTask = pdfjsLib.getDocument(src);
this.loadingTask = pdfjsLib.getDocument(pdfOptions);
this.loadingTask.onPassword = (callback, reason) => { this.loadingTask.onPassword = (callback, reason) => {
this.onPdfPassword(callback, reason); this.onPdfPassword(callback, reason);