mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-09-17 14:21:29 +00:00
PoC: Make @alfresco/js-api to be compatible with angular's http client
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2019 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*tslint:disable*/ // => because of ADF file naming problems... Try to remove it, if you don't believe me :P
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { DiscoveryApi } from '@alfresco/js-api';
|
||||
import { AngularAlfrescoApi } from './angular-alfresco-api';
|
||||
|
||||
@Injectable()
|
||||
export class AlfrescoApiClientFactory {
|
||||
// Here we should all the APIs from js-api
|
||||
private discoveryApi: DiscoveryApi = null;
|
||||
|
||||
constructor(
|
||||
private angularAlfrescoApi?: AngularAlfrescoApi) {
|
||||
}
|
||||
|
||||
getDiscoveryApi() {
|
||||
// DiscoveryApi needs to rely on a lot thinner interface: JsApiHttpClient;
|
||||
this.discoveryApi = this.discoveryApi || new DiscoveryApi(this.angularAlfrescoApi as any);
|
||||
return this.discoveryApi;
|
||||
}
|
||||
|
||||
getNodesApi () {
|
||||
// TODO
|
||||
}
|
||||
|
||||
getSearchApi() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
// etc...
|
||||
}
|
@@ -0,0 +1,65 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2019 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { AlfrescoApi, AlfrescoApiConfig } from '@alfresco/js-api';
|
||||
import { AppConfigService, AppConfigValues } from '../../app-config/app-config.service';
|
||||
import { OauthConfigModel } from '../../models/oauth-config.model';
|
||||
import { StorageService } from '../../services/storage.service';
|
||||
import { AngularAlfrescoApi } from './angular-alfresco-api';
|
||||
|
||||
@Injectable()
|
||||
export class AngularAlfrescoApiLoaderService {
|
||||
|
||||
protected alfrescoApi: AlfrescoApi;
|
||||
|
||||
constructor(
|
||||
protected appConfig: AppConfigService,
|
||||
protected storageService: StorageService,
|
||||
private angularAlfrescoApi?: AngularAlfrescoApi) {
|
||||
}
|
||||
|
||||
async load() {
|
||||
await this.appConfig.load().then(() => {
|
||||
this.storageService.prefix = this.appConfig.get<string>(AppConfigValues.STORAGE_PREFIX, '');
|
||||
this.initAngularAlfrescoApi();
|
||||
});
|
||||
}
|
||||
|
||||
protected initAngularAlfrescoApi() {
|
||||
const oauth: OauthConfigModel = Object.assign({}, this.appConfig.get<OauthConfigModel>(AppConfigValues.OAUTHCONFIG, null));
|
||||
if (oauth) {
|
||||
oauth.redirectUri = window.location.origin + window.location.pathname;
|
||||
oauth.redirectUriLogout = window.location.origin + window.location.pathname;
|
||||
}
|
||||
|
||||
const config = new AlfrescoApiConfig({
|
||||
provider: this.appConfig.get<string>(AppConfigValues.PROVIDERS),
|
||||
hostEcm: this.appConfig.get<string>(AppConfigValues.ECMHOST),
|
||||
hostBpm: this.appConfig.get<string>(AppConfigValues.BPMHOST),
|
||||
authType: this.appConfig.get<string>(AppConfigValues.AUTHTYPE, 'BASIC'),
|
||||
contextRootBpm: this.appConfig.get<string>(AppConfigValues.CONTEXTROOTBPM),
|
||||
contextRoot: this.appConfig.get<string>(AppConfigValues.CONTEXTROOTECM),
|
||||
disableCsrf: this.appConfig.get<boolean>(AppConfigValues.DISABLECSRF),
|
||||
withCredentials: this.appConfig.get<boolean>(AppConfigValues.AUTH_WITH_CREDENTIALS, false),
|
||||
domainPrefix : this.appConfig.get<string>(AppConfigValues.STORAGE_PREFIX),
|
||||
oauth2: oauth
|
||||
});
|
||||
|
||||
this.angularAlfrescoApi.init(config);
|
||||
}
|
||||
}
|
85
lib/core/alfresco-api/services/angular-alfresco-api.ts
Normal file
85
lib/core/alfresco-api/services/angular-alfresco-api.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2019 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { AlfrescoApiConfig } from '@alfresco/js-api';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { JsApiHttpClient } from '../js-api/js-api-http-client';
|
||||
import { JsApiAngularHttpClient } from './js-api-angular-http-client';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
|
||||
@Injectable()
|
||||
export class AngularAlfrescoApi {
|
||||
public contentPrivateClient: JsApiHttpClient;
|
||||
public contentClient: JsApiHttpClient;
|
||||
public authClient: JsApiHttpClient;
|
||||
public searchClient: JsApiHttpClient;
|
||||
public discoveryClient: JsApiHttpClient;
|
||||
public gsClient: JsApiHttpClient;
|
||||
public processClient: JsApiHttpClient;
|
||||
|
||||
constructor(private httpClient: HttpClient) {}
|
||||
|
||||
init(config: AlfrescoApiConfig) {
|
||||
this.contentPrivateClient = new JsApiAngularHttpClient(
|
||||
config.hostEcm,
|
||||
config.contextRoot,
|
||||
`/api/${config.tenant}/private/alfresco/versions/1`,
|
||||
this.httpClient
|
||||
);
|
||||
|
||||
this.contentClient = new JsApiAngularHttpClient(
|
||||
config.hostEcm,
|
||||
config.contextRoot,
|
||||
`/api/${config.tenant}/public/alfresco/versions/1`,
|
||||
this.httpClient
|
||||
);
|
||||
|
||||
this.authClient = new JsApiAngularHttpClient(
|
||||
config.hostEcm,
|
||||
config.contextRoot,
|
||||
`/api/${config.tenant}/public/authentication/versions/1`,
|
||||
this.httpClient
|
||||
);
|
||||
|
||||
this.searchClient = new JsApiAngularHttpClient(
|
||||
config.hostEcm,
|
||||
config.contextRoot,
|
||||
`/api/${config.tenant}/public/search/versions/1`,
|
||||
this.httpClient
|
||||
);
|
||||
this.discoveryClient = new JsApiAngularHttpClient(
|
||||
config.hostEcm,
|
||||
config.contextRoot,
|
||||
`/api`,
|
||||
this.httpClient
|
||||
);
|
||||
|
||||
this.gsClient = new JsApiAngularHttpClient(
|
||||
config.hostEcm,
|
||||
config.contextRoot,
|
||||
`/api/${config.tenant}/public/gs/versions/1`,
|
||||
this.httpClient
|
||||
);
|
||||
|
||||
this.processClient = new JsApiAngularHttpClient(
|
||||
config.hostBpm,
|
||||
config.contextRootBpm,
|
||||
'',
|
||||
this.httpClient
|
||||
);
|
||||
}
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2019 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { AngularAlfrescoApiLoaderService } from './angular-alfresco-api-loader.service';
|
||||
|
||||
// eslint-disable-next-line prefer-arrow/prefer-arrow-functions
|
||||
export function createAngularAlfrescoApiService(angularAlfrescoApiService: AngularAlfrescoApiLoaderService) {
|
||||
return () => angularAlfrescoApiService.load();
|
||||
}
|
79
lib/core/alfresco-api/services/auth-bearer.interceptor.ts
Normal file
79
lib/core/alfresco-api/services/auth-bearer.interceptor.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2019 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { throwError as observableThrowError, Observable } from 'rxjs';
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import {
|
||||
HttpHandler, HttpInterceptor, HttpRequest,
|
||||
HttpSentEvent, HttpHeaderResponse, HttpProgressEvent, HttpResponse, HttpUserEvent, HttpHeaders
|
||||
} from '@angular/common/http';
|
||||
import { AuthenticationService } from '../../services/authentication.service';
|
||||
import { catchError, mergeMap } from 'rxjs/operators';
|
||||
|
||||
@Injectable()
|
||||
export class AuthBearerInterceptor implements HttpInterceptor {
|
||||
private excludedUrlsRegex: RegExp[];
|
||||
private authService: AuthenticationService;
|
||||
|
||||
constructor(private injector: Injector) { }
|
||||
|
||||
private loadExcludedUrlsRegex() {
|
||||
const excludedUrls: string[] = this.authService.getBearerExcludedUrls();
|
||||
this.excludedUrlsRegex = excludedUrls.map((urlPattern) => new RegExp(urlPattern, 'gi')) || [];
|
||||
|
||||
}
|
||||
|
||||
intercept(req: HttpRequest<any>, next: HttpHandler):
|
||||
Observable<HttpSentEvent | HttpHeaderResponse | HttpProgressEvent | HttpResponse<any> | HttpUserEvent<any>> {
|
||||
|
||||
this.authService = this.injector.get(AuthenticationService);
|
||||
|
||||
if (!this.authService || !this.authService.getBearerExcludedUrls()) {
|
||||
return next.handle(req);
|
||||
}
|
||||
|
||||
if (!this.excludedUrlsRegex) {
|
||||
this.loadExcludedUrlsRegex();
|
||||
}
|
||||
|
||||
const urlRequest = req.url;
|
||||
const shallPass: boolean = !!this.excludedUrlsRegex.find((regex) => regex.test(urlRequest));
|
||||
if (shallPass) {
|
||||
return next.handle(req)
|
||||
.pipe(
|
||||
catchError((error) => observableThrowError(error))
|
||||
);
|
||||
}
|
||||
|
||||
return this.authService.addTokenToHeader(req.headers)
|
||||
.pipe(
|
||||
mergeMap((headersWithBearer) => {
|
||||
const headerWithContentType = this.appendJsonContentType(headersWithBearer);
|
||||
const kcReq = req.clone({ headers: headerWithContentType});
|
||||
return next.handle(kcReq)
|
||||
.pipe(
|
||||
catchError((error) => observableThrowError(error))
|
||||
);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
private appendJsonContentType(headers: HttpHeaders): HttpHeaders {
|
||||
return headers.set('Content-Type', 'application/json;charset=UTF-8');
|
||||
}
|
||||
|
||||
}
|
190
lib/core/alfresco-api/services/js-api-angular-http-client.ts
Normal file
190
lib/core/alfresco-api/services/js-api-angular-http-client.ts
Normal file
@@ -0,0 +1,190 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2019 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
paramToString,
|
||||
RequestOptions
|
||||
} from '@alfresco/js-api';
|
||||
import { JsApiHttpClient } from '../js-api/js-api-http-client';
|
||||
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
|
||||
|
||||
/** tslint:disable-next line */
|
||||
export class JsApiAngularHttpClient implements JsApiHttpClient {
|
||||
public basePath: string;
|
||||
|
||||
constructor (
|
||||
private host: string,
|
||||
private contextRoot: string,
|
||||
private servicePath: string,
|
||||
private httpClient: HttpClient
|
||||
) {
|
||||
this.basePath = `${this.host}/${this.contextRoot}${this.servicePath}`;
|
||||
}
|
||||
|
||||
request<T = any>(options: RequestOptions): Promise<T> {
|
||||
|
||||
const responseType = this.getResponseType(options);
|
||||
|
||||
return this.httpClient.request(
|
||||
options.httpMethod,
|
||||
options.url,
|
||||
{
|
||||
...(options.bodyParam ? { body: options.bodyParam } : {}),
|
||||
...(options.headerParams ? { headers: new HttpHeaders(options.headerParams) } : {}),
|
||||
observe: 'body',
|
||||
...(options.queryParams ? { params: new HttpParams({ fromObject: options.queryParams })} : {}),
|
||||
...(responseType ? { responseType } : {}),
|
||||
}).toPromise() as unknown as Promise<T>;
|
||||
}
|
||||
|
||||
private getResponseType(options: RequestOptions): 'arraybuffer' | 'blob' | 'json' | 'text' {
|
||||
let responseType = null;
|
||||
|
||||
if (options.returnType?.toString().toLowerCase() === 'blob' || options.responseType?.toString().toLowerCase() === 'blob') {
|
||||
responseType = 'blob';
|
||||
} else if (options.returnType === 'String') {
|
||||
responseType = 'text';
|
||||
}
|
||||
|
||||
return responseType;
|
||||
}
|
||||
|
||||
post<T = any>(options: RequestOptions): Promise<T> {
|
||||
return this.request<T>({
|
||||
...options,
|
||||
httpMethod: 'POST',
|
||||
contentTypes: options.contentTypes || ['application/json'],
|
||||
accepts: options.accepts || ['application/json']
|
||||
});
|
||||
}
|
||||
|
||||
put<T = any>(options: RequestOptions): Promise<T> {
|
||||
return this.request<T>({
|
||||
...options,
|
||||
httpMethod: 'PUT',
|
||||
contentTypes: options.contentTypes || ['application/json'],
|
||||
accepts: options.accepts || ['application/json']
|
||||
});
|
||||
}
|
||||
|
||||
get<T = any>(options: RequestOptions): Promise<T> {
|
||||
return this.request<T>({
|
||||
...options,
|
||||
httpMethod: 'GET',
|
||||
contentTypes: options.contentTypes || ['application/json'],
|
||||
accepts: options.accepts || ['application/json']
|
||||
});
|
||||
}
|
||||
|
||||
delete<T = void>(options: RequestOptions): Promise<T> {
|
||||
return this.request<T>({
|
||||
...options,
|
||||
httpMethod: 'DELETE',
|
||||
contentTypes: options.contentTypes || ['application/json'],
|
||||
accepts: options.accepts || ['application/json']
|
||||
});
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
callApi(
|
||||
path: string,
|
||||
httpMethod: string,
|
||||
pathParams?: any,
|
||||
queryParams?: any,
|
||||
headerParams?: any,
|
||||
formParams?: any,
|
||||
bodyParam?: any,
|
||||
contentTypes?: string[],
|
||||
accepts?: string[],
|
||||
returnType?: any,
|
||||
contextRoot?: string,
|
||||
responseType?: string,
|
||||
url?: string
|
||||
): Promise<any> {
|
||||
|
||||
const basePath = contextRoot ? `${this.host}/${contextRoot}` : this.basePath;
|
||||
url = url ?? this.buildUrl(basePath, path, pathParams);
|
||||
|
||||
return this.request({
|
||||
path,
|
||||
httpMethod,
|
||||
pathParams,
|
||||
queryParams,
|
||||
headerParams,
|
||||
formParams,
|
||||
bodyParam,
|
||||
contentTypes,
|
||||
accepts,
|
||||
returnType,
|
||||
contextRoot,
|
||||
responseType,
|
||||
url
|
||||
});
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
callCustomApi(
|
||||
fullPath: string,
|
||||
httpMethod: string,
|
||||
pathParams?: any,
|
||||
queryParams?: any,
|
||||
headerParams?: any,
|
||||
formParams?: any,
|
||||
bodyParam?: any,
|
||||
contentTypes?: string[],
|
||||
accepts?: string[],
|
||||
returnType?: any,
|
||||
contextRoot?: string,
|
||||
responseType?: string
|
||||
): Promise<any> {
|
||||
const url = this.buildUrl(fullPath, '', pathParams);
|
||||
|
||||
return this.request({
|
||||
path: fullPath,
|
||||
httpMethod,
|
||||
pathParams,
|
||||
queryParams,
|
||||
headerParams,
|
||||
formParams,
|
||||
bodyParam,
|
||||
contentTypes,
|
||||
accepts,
|
||||
returnType,
|
||||
contextRoot,
|
||||
responseType,
|
||||
url
|
||||
});
|
||||
}
|
||||
|
||||
private buildUrl(basePath: string, path: string, pathParams: any): string {
|
||||
if (path && path !== '' && !path.match(/^\//)) {
|
||||
path = '/' + path;
|
||||
}
|
||||
let url = basePath + path;
|
||||
|
||||
url = url.replace(/\{([\w-]+)\}/g, function (fullMatch, key) {
|
||||
let value;
|
||||
if (pathParams.hasOwnProperty(key)) {
|
||||
value = paramToString(pathParams[key]);
|
||||
} else {
|
||||
value = fullMatch;
|
||||
}
|
||||
return encodeURIComponent(value);
|
||||
});
|
||||
return url;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user