[AAE-10499] feat: create angular based custom http client for alfresco js api (#7800)

This commit is contained in:
Mikołaj Serwicki
2022-10-10 11:44:04 +02:00
committed by GitHub
parent f19c21fd24
commit 0e5f6372da
14 changed files with 953 additions and 82 deletions

View File

@@ -63,6 +63,8 @@ import { VersionCompatibilityService } from './services/version-compatibility.se
import { AlfrescoJsClientsModule } from '@alfresco/adf-core/api';
import { LegacyApiClientModule } from './api-factories/legacy-api-client.module';
import { RichTextEditorModule } from './rich-text-editor/rich-text-editor.module';
import { HttpClientModule, HttpClientXsrfModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { AuthBearerInterceptor } from './services/auth-bearer.interceptor';
@NgModule({
imports: [
@@ -101,7 +103,12 @@ import { RichTextEditorModule } from './rich-text-editor/rich-text-editor.module
BlankPageModule,
LegacyApiClientModule,
AlfrescoJsClientsModule,
RichTextEditorModule
RichTextEditorModule,
HttpClientModule,
HttpClientXsrfModule.withOptions({
cookieName: 'CSRF-TOKEN',
headerName: 'X-CSRF-TOKEN'
})
],
exports: [
AboutModule,
@@ -167,7 +174,8 @@ export class CoreModule {
useFactory: versionCompatibilityFactory,
deps: [ VersionCompatibilityService ],
multi: true
}
},
{ provide: HTTP_INTERCEPTORS, useClass: AuthBearerInterceptor, multi: true }
]
};
}

View File

@@ -27,14 +27,13 @@ import { catchError, mergeMap } from 'rxjs/operators';
@Injectable()
export class AuthBearerInterceptor implements HttpInterceptor {
private excludedUrlsRegex: RegExp[];
private authService: AuthenticationService;
constructor(private injector: Injector) { }
constructor(private injector: Injector, private authService: AuthenticationService) { }
private loadExcludedUrlsRegex() {
const excludedUrls: string[] = this.authService.getBearerExcludedUrls();
this.excludedUrlsRegex = excludedUrls.map((urlPattern) => new RegExp(urlPattern, 'gi')) || [];
this.excludedUrlsRegex = [...excludedUrls].map((urlPattern) => new RegExp(urlPattern, 'i')) || [];
}
intercept(req: HttpRequest<any>, next: HttpHandler):
@@ -51,7 +50,7 @@ export class AuthBearerInterceptor implements HttpInterceptor {
}
const urlRequest = req.url;
const shallPass: boolean = !!this.excludedUrlsRegex.find((regex) => regex.test(urlRequest));
const shallPass: boolean = this.excludedUrlsRegex.some((regex) => regex.test(urlRequest));
if (shallPass) {
return next.handle(req)
.pipe(
@@ -73,7 +72,19 @@ export class AuthBearerInterceptor implements HttpInterceptor {
}
private appendJsonContentType(headers: HttpHeaders): HttpHeaders {
return headers.set('Content-Type', 'application/json;charset=UTF-8');
// prevent adding any content type, to properly handle formData with boundary browser generated value,
// as adding any Content-Type its going to break the upload functionality
if (headers.get('Content-Type') === 'multipart/form-data') {
return headers.delete('Content-Type');
}
if (!headers.get('Content-Type')) {
return headers.set('Content-Type', 'application/json;charset=UTF-8');
}
return headers;
}
}

View File

@@ -246,7 +246,7 @@ export class AuthenticationService {
* @returns The ticket or `null` if none was found
*/
getTicketEcm(): string | null {
return this.alfrescoApi.getInstance().getTicketEcm();
return this.alfrescoApi.getInstance()?.getTicketEcm();
}
/**
@@ -255,7 +255,7 @@ export class AuthenticationService {
* @returns The ticket or `null` if none was found
*/
getTicketBpm(): string | null {
return this.alfrescoApi.getInstance().getTicketBpm();
return this.alfrescoApi.getInstance()?.getTicketBpm();
}
/**
@@ -264,7 +264,7 @@ export class AuthenticationService {
* @returns The ticket or `null` if none was found
*/
getTicketEcmBase64(): string | null {
const ticket = this.alfrescoApi.getInstance().getTicketEcm();
const ticket = this.alfrescoApi.getInstance()?.getTicketEcm();
if (ticket) {
return 'Basic ' + btoa(ticket);
}
@@ -395,13 +395,47 @@ export class AuthenticationService {
headers = new HttpHeaders();
}
try {
const token: string = this.getToken();
headers = headers.set('Authorization', 'bearer ' + token);
observer.next(headers);
const header = this.getAuthHeaders(headers);
observer.next(header);
observer.complete();
} catch (error) {
observer.error(error);
}
});
}
private getAuthHeaders(header: HttpHeaders): HttpHeaders {
const authType = this.appConfig.get<string>(AppConfigValues.AUTHTYPE, 'BASIC');
switch (authType) {
case 'OAUTH':
return this.addBearerToken(header);
case 'BASIC':
return this.addBasicAuth(header);
default:
return header;
}
}
private addBearerToken(header: HttpHeaders): HttpHeaders {
const token: string = this.getToken();
if (!token) {
return header;
}
return header.set('Authorization', 'bearer ' + token);
}
private addBasicAuth(header: HttpHeaders): HttpHeaders {
const ticket: string = this.getTicketEcmBase64();
if (!ticket) {
return header;
}
return header.set('Authorization', ticket);
}
}