mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-15 05:53:03 +00:00
Add XSRF support to uploader component
This commit is contained in:
@@ -18,6 +18,9 @@ import { UploaderOptions } from './uploader-options.model';
|
|||||||
import { hasValue, isNotEmpty, isUndefined } from '../empty.util';
|
import { hasValue, isNotEmpty, isUndefined } from '../empty.util';
|
||||||
import { UploaderService } from './uploader.service';
|
import { UploaderService } from './uploader.service';
|
||||||
import { UploaderProperties } from './uploader-properties.model';
|
import { UploaderProperties } from './uploader-properties.model';
|
||||||
|
import { HttpXsrfTokenExtractor } from '@angular/common/http';
|
||||||
|
import { XSRF_REQUEST_HEADER, XSRF_RESPONSE_HEADER, XSRF_COOKIE } from '../../core/xsrf/xsrf.interceptor';
|
||||||
|
import { CookieService } from '../../core/services/cookie.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-uploader',
|
selector: 'ds-uploader',
|
||||||
@@ -91,7 +94,9 @@ export class UploaderComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(private cdr: ChangeDetectorRef, private scrollToService: ScrollToService, private uploaderService: UploaderService) {
|
constructor(private cdr: ChangeDetectorRef, private scrollToService: ScrollToService,
|
||||||
|
private uploaderService: UploaderService, private tokenExtractor: HttpXsrfTokenExtractor,
|
||||||
|
private cookieService: CookieService) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -108,7 +113,9 @@ export class UploaderComponent {
|
|||||||
removeAfterUpload: true,
|
removeAfterUpload: true,
|
||||||
autoUpload: this.uploadFilesOptions.autoUpload,
|
autoUpload: this.uploadFilesOptions.autoUpload,
|
||||||
method: this.uploadFilesOptions.method,
|
method: this.uploadFilesOptions.method,
|
||||||
queueLimit: this.uploadFilesOptions.maxFileNumber
|
queueLimit: this.uploadFilesOptions.maxFileNumber,
|
||||||
|
// Ensure the current XSRF token is included in every upload request
|
||||||
|
headers: [{ name: XSRF_REQUEST_HEADER, value: this.tokenExtractor.getToken() }]
|
||||||
});
|
});
|
||||||
|
|
||||||
if (isUndefined(this.enableDragOverDocument)) {
|
if (isUndefined(this.enableDragOverDocument)) {
|
||||||
@@ -123,10 +130,6 @@ export class UploaderComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngAfterViewInit() {
|
ngAfterViewInit() {
|
||||||
// Maybe to remove: needed to avoid CORS issue with our temp upload server
|
|
||||||
this.uploader.onAfterAddingFile = ((item) => {
|
|
||||||
item.withCredentials = false;
|
|
||||||
});
|
|
||||||
this.uploader.onAfterAddingAll = ((items) => {
|
this.uploader.onAfterAddingAll = ((items) => {
|
||||||
this.onFileSelected.emit(items);
|
this.onFileSelected.emit(items);
|
||||||
});
|
});
|
||||||
@@ -153,11 +156,25 @@ export class UploaderComponent {
|
|||||||
}
|
}
|
||||||
this.uploader.onCompleteItem = (item: any, response: any, status: any, headers: any) => {
|
this.uploader.onCompleteItem = (item: any, response: any, status: any, headers: any) => {
|
||||||
if (isNotEmpty(response)) {
|
if (isNotEmpty(response)) {
|
||||||
|
// Check for a changed XSRF token in response & save new token if found
|
||||||
|
// NOTE: this is only necessary because ng2-file-upload doesn't use an Http service and therefore never
|
||||||
|
// triggers our xsrf.interceptor.ts. See this bug: https://github.com/valor-software/ng2-file-upload/issues/950
|
||||||
|
const token = headers[XSRF_RESPONSE_HEADER.toLowerCase()];
|
||||||
|
if (isNotEmpty(token)) {
|
||||||
|
this.saveXsrfToken(token);
|
||||||
|
}
|
||||||
const responsePath = JSON.parse(response);
|
const responsePath = JSON.parse(response);
|
||||||
this.onCompleteItem.emit(responsePath);
|
this.onCompleteItem.emit(responsePath);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
this.uploader.onErrorItem = (item: any, response: any, status: any, headers: any) => {
|
this.uploader.onErrorItem = (item: any, response: any, status: any, headers: any) => {
|
||||||
|
// Check for a changed XSRF token in response & save new token if found
|
||||||
|
// NOTE: this is only necessary because ng2-file-upload doesn't use an Http service and therefore never
|
||||||
|
// triggers our xsrf.interceptor.ts. See this bug: https://github.com/valor-software/ng2-file-upload/issues/950
|
||||||
|
const token = headers[XSRF_RESPONSE_HEADER.toLowerCase()];
|
||||||
|
if (isNotEmpty(token)) {
|
||||||
|
this.saveXsrfToken(token);
|
||||||
|
}
|
||||||
this.onUploadError.emit({ item: item, response: response, status: status, headers: headers });
|
this.onUploadError.emit({ item: item, response: response, status: status, headers: headers });
|
||||||
this.uploader.cancelAll();
|
this.uploader.cancelAll();
|
||||||
};
|
};
|
||||||
@@ -201,4 +218,18 @@ export class UploaderComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save XSRF token found in response. This is a temporary copy of the method in xsrf.interceptor.ts
|
||||||
|
* It can be removed once ng2-file-upload supports interceptors (see https://github.com/valor-software/ng2-file-upload/issues/950),
|
||||||
|
* or we switch to a new upload library (see https://github.com/DSpace/dspace-angular/issues/820)
|
||||||
|
* @param token token found
|
||||||
|
*/
|
||||||
|
private saveXsrfToken(token: string) {
|
||||||
|
// Save token value as a *new* value of our client-side XSRF-TOKEN cookie.
|
||||||
|
// This is the cookie that is parsed by Angular's tokenExtractor(),
|
||||||
|
// which we will send back in the X-XSRF-TOKEN header per Angular best practices.
|
||||||
|
this.cookieService.remove(XSRF_COOKIE);
|
||||||
|
this.cookieService.set(XSRF_COOKIE, token);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user