Merge pull request #15626 from abpframework/auto-merge/rel-7-0/1703

Merge branch dev with rel-7.0
pull/15627/head
Mahmut Gundogdu 3 years ago committed by GitHub
commit 3e27cea16e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -298,3 +298,15 @@ export function handleHttpErrors(injector: Injector, httpError: HttpErrorRespons
return throwError(httpError)
}
```
### How to Skip HTTP interceptors and ABP headers
The ABP Framework adds several HTTP headers to the HttpClient, such as the "Auth token" or "tenant Id".
The ABP Server must possess the information but the ABP user may not want to send this informations to an external server.
ExternalHttpClient and IS EXTERNAL REQUEST HttpContext Token were added in V6.0.4.
The ABP Http interceptors check the value of the `IS_EXTERNAL_REQUEST` token. If the token is True then ABP-specific headers won't be added to Http Request.
The `ExternalHttpClient` extends from `HTTPClient` and sets the `IS_EXTERNAL_REQUEST` context token to true.
When you are using `ExternalHttpClient` as HttpClient in your components, it does not add ABP-specific headers.
Note: With `IS_EXTERNAL_REQUEST` or without it, ABP loading service works.

@ -57,7 +57,7 @@ You can add the `abp-modal` to your component very quickly. See an example:
@Component(/* component metadata */)
export class SampleComponent {
isModelOpen = false
isModalOpen = false
}
```

@ -267,11 +267,11 @@ public class AngularSourceCodeAdder : ITransientDependency
var fileContent = File.ReadAllText(filePath);
fileContent = "import { "+moduleName.Split(".").Last()+"Module } from '@"+moduleName.Split(".").Last().ToKebabCase()+"/config';" + Environment.NewLine + fileContent;
fileContent = "import { "+moduleName.Split(".").Last()+"ConfigModule } from '@"+moduleName.Split(".").Last().ToKebabCase()+"/config';" + Environment.NewLine + fileContent;
fileContent = Regex.Replace(fileContent, "imports\\s*:\\s*\\[",
"imports: ["+ Environment.NewLine +
" " + moduleName.Split(".").Last() + "Module.forRoot(),");
" " + moduleName.Split(".").Last() + "ConfigModule.forRoot(),");
File.WriteAllText(filePath, fileContent);
}

@ -0,0 +1,30 @@
import { HttpClient, HttpContext, HttpRequest } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { IS_EXTERNAL_REQUEST } from '../tokens/http-context.token';
// source : https://github.com/armanozak/demo-angular-server-specific-interceptors
@Injectable({
providedIn: 'root',
})
export class ExternalHttpClient extends HttpClient {
override request(
first: string | HttpRequest<any>,
url?: string,
options: RequestOptions = {},
): Observable<any> {
if (typeof first === 'string') {
this.#setPlaceholderContext(options);
return super.request(first, url, options);
}
this.#setPlaceholderContext(first);
return super.request(first);
}
#setPlaceholderContext(optionsOrRequest: { context?: HttpContext }) {
optionsOrRequest.context ??= new HttpContext();
optionsOrRequest.context.set(IS_EXTERNAL_REQUEST, true);
}
}
type RequestOptions = Parameters<HttpClient['request']>[2];

@ -0,0 +1 @@
export * from './http.client';

@ -1,8 +1,7 @@
import { Provider } from "@angular/core";
import { INCUDE_LOCALIZATION_RESOURCES_TOKEN } from "../tokens/include-localization-resources.token";
import { Provider } from '@angular/core';
import { INCUDE_LOCALIZATION_RESOURCES_TOKEN } from '../tokens/include-localization-resources.token';
export const IncludeLocalizationResourcesProvider: Provider = {
provide: INCUDE_LOCALIZATION_RESOURCES_TOKEN,
useValue: false,
};
provide: INCUDE_LOCALIZATION_RESOURCES_TOKEN,
useValue: false,
};

@ -1,3 +1,3 @@
export * from './cookie-language.provider';
export * from './locale.provider';
export * from './include-localization-resources.provider';
export * from './include-localization-resources.provider';

@ -0,0 +1,3 @@
import { HttpContextToken } from '@angular/common/http';
export const IS_EXTERNAL_REQUEST = new HttpContextToken<boolean>(() => false);

@ -1,3 +1,5 @@
import { InjectionToken } from "@angular/core";
import { InjectionToken } from '@angular/core';
export const INCUDE_LOCALIZATION_RESOURCES_TOKEN = new InjectionToken<boolean>('INCUDE_LOCALIZATION_RESOURCES_TOKEN');
export const INCUDE_LOCALIZATION_RESOURCES_TOKEN = new InjectionToken<boolean>(
'INCUDE_LOCALIZATION_RESOURCES_TOKEN',
);

@ -11,3 +11,4 @@ export * from './include-localization-resources.token';
export * from './pipe-to-login.token';
export * from './set-token-response-to-storage.token';
export * from './check-authentication-state';
export * from './http-context.token';

@ -23,3 +23,4 @@ export * from './lib/tokens';
export * from './lib/utils';
export * from './lib/validators';
export * from './lib/interceptors';
export * from './lib/clients';

@ -7,34 +7,37 @@ import { Injectable } from '@angular/core';
})
export class FeaturesService {
apiName = 'AbpFeatureManagement';
delete = (providerName: string, providerKey: string) =>
this.restService.request<any, void>({
method: 'DELETE',
url: '/api/feature-management/features',
params: { providerName, providerKey },
},
{ apiName: this.apiName });
this.restService.request<any, void>(
{
method: 'DELETE',
url: '/api/feature-management/features',
params: { providerName, providerKey },
},
{ apiName: this.apiName },
);
get = (providerName: string, providerKey: string) =>
this.restService.request<any, GetFeatureListResultDto>({
method: 'GET',
url: '/api/feature-management/features',
params: { providerName, providerKey },
},
{ apiName: this.apiName });
this.restService.request<any, GetFeatureListResultDto>(
{
method: 'GET',
url: '/api/feature-management/features',
params: { providerName, providerKey },
},
{ apiName: this.apiName },
);
update = (providerName: string, providerKey: string, input: UpdateFeaturesDto) =>
this.restService.request<any, void>({
method: 'PUT',
url: '/api/feature-management/features',
params: { providerName, providerKey },
body: input,
},
{ apiName: this.apiName });
this.restService.request<any, void>(
{
method: 'PUT',
url: '/api/feature-management/features',
params: { providerName, providerKey },
body: input,
},
{ apiName: this.apiName },
);
constructor(private restService: RestService) {}
}

@ -2,7 +2,13 @@ import { HttpHandler, HttpHeaders, HttpRequest } from '@angular/common/http';
import { Inject, Injectable } from '@angular/core';
import { OAuthService } from 'angular-oauth2-oidc';
import { finalize } from 'rxjs/operators';
import { SessionStateService, HttpWaitService, TENANT_KEY, IApiInterceptor } from '@abp/ng.core';
import {
SessionStateService,
HttpWaitService,
TENANT_KEY,
IApiInterceptor,
IS_EXTERNAL_REQUEST,
} from '@abp/ng.core';
@Injectable({
providedIn: 'root',
@ -17,12 +23,15 @@ export class OAuthApiInterceptor implements IApiInterceptor {
intercept(request: HttpRequest<any>, next: HttpHandler) {
this.httpWaitService.addRequest(request);
return next
.handle(
request.clone({
const isExternalRequest = request.context?.get(IS_EXTERNAL_REQUEST);
const newRequest = isExternalRequest
? request
: request.clone({
setHeaders: this.getAdditionalHeaders(request.headers),
}),
)
});
return next
.handle(newRequest)
.pipe(finalize(() => this.httpWaitService.deleteRequest(request)));
}

@ -1,13 +1,13 @@
import { ConfigStateService, CurrentUserDto } from "@abp/ng.core";
import { ConfigStateService, CurrentUserDto } from '@abp/ng.core';
import {
GetPermissionListResultDto,
PermissionGrantInfoDto,
PermissionGroupDto,
PermissionsService,
ProviderInfoDto,
UpdatePermissionDto
} from "@abp/ng.permission-management/proxy";
import { LocaleDirection } from "@abp/ng.theme.shared";
UpdatePermissionDto,
} from '@abp/ng.permission-management/proxy';
import { LocaleDirection } from '@abp/ng.theme.shared';
import {
Component,
ElementRef,
@ -16,11 +16,11 @@ import {
Output,
QueryList,
TrackByFunction,
ViewChildren
} from "@angular/core";
import { concat, of } from "rxjs";
import { finalize, switchMap, take, tap } from "rxjs/operators";
import { PermissionManagement } from "../models/permission-management";
ViewChildren,
} from '@angular/core';
import { concat, of } from 'rxjs';
import { finalize, switchMap, take, tap } from 'rxjs/operators';
import { PermissionManagement } from '../models/permission-management';
type PermissionWithStyle = PermissionGrantInfoDto & {
style: string;

@ -246,4 +246,3 @@ export function addRoutingToAppRoutingModule(workspace: WorkspaceDefinition, pac
return;
};
}

@ -45,9 +45,13 @@ abstract class TypeRef {
get default() {
return this._default;
}
set default(value: string) {
set default(value: any) {
if (!value) return;
this._default = ` = ${value}`;
if (typeof value === 'string') {
this._default = ` = "${value}"`;
} else {
this._default = ` = ${value}`;
}
}
constructor(options: TypeRefOptions) {

@ -48,7 +48,7 @@ export function generateFromFiles(
validateClassName(strings.classify(options.name));
const templateSource = apply(url('./files'), [
options.skipTests ? filter((path) => !path.endsWith('.spec.ts.template')) : noop(),
options.skipTests ? filter(path => !path.endsWith('.spec.ts.template')) : noop(),
applyTemplates({
...strings,
...options,

Loading…
Cancel
Save