Browse Source

Merge pull request #15417 from abpframework/auto-merge/rel-7-0/1654

Merge branch dev with rel-7.0
pull/15423/head
maliming 4 years ago
committed by GitHub
parent
commit
ae4736152a
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      docs/en/Migration-Guides/OpenIddict-Angular.md
  2. 2
      docs/en/Migration-Guides/OpenIddict-Blazor-Server.md
  3. 2
      docs/en/Migration-Guides/OpenIddict-Blazor.md
  4. 2
      docs/en/Migration-Guides/OpenIddict-Mvc.md
  5. 2
      docs/en/Migration-Guides/OpenIddict-Step-by-Step.md
  6. 78
      modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/UserManagement.razor
  7. 2
      modules/openiddict/src/Volo.Abp.OpenIddict.MongoDB/Volo/Abp/OpenIddict/Authorizations/MongoOpenIddictAuthorizationRepository.cs
  8. 7
      npm/ng-packs/packages/core/src/lib/core.module.ts
  9. 6
      npm/ng-packs/packages/core/src/lib/directives/permission.directive.ts
  10. 11
      npm/ng-packs/packages/core/src/lib/tests/initial-utils.spec.ts
  11. 1
      npm/ng-packs/packages/core/src/lib/tokens/index.ts
  12. 4
      npm/ng-packs/packages/core/src/lib/tokens/queue.token.ts
  13. 1
      npm/ng-packs/packages/core/src/lib/utils/index.ts
  14. 48
      npm/ng-packs/packages/core/src/lib/utils/queue.ts
  15. 3
      npm/ng-packs/packages/oauth/src/lib/tests/api.interceptor.spec.ts
  16. 29
      npm/ng-packs/packages/oauth/src/lib/tests/initial-utils.spec.ts

2
docs/en/Migration-Guides/OpenIddict-Angular.md

@ -112,7 +112,7 @@
## IdentityServer ## IdentityServer
This project is renamed to **AuthServer** after v6.0.0-rc1. You can also refactor and rename your project to *AuthServer* for easier updates in the future. This project is renamed to **AuthServer** after v6.0.0. You can also refactor and rename your project to *AuthServer* for easier updates in the future.
- In **MyApplication.IdentityServer.csproj** replace **project references**: - In **MyApplication.IdentityServer.csproj** replace **project references**:

2
docs/en/Migration-Guides/OpenIddict-Blazor-Server.md

@ -103,7 +103,7 @@
## IdentityServer ## IdentityServer
This project is renamed to **AuthServer** after v6.0.0-rc1. You can also refactor and rename your project to *AuthServer* for easier updates in the future. This project is renamed to **AuthServer** after v6.0.0. You can also refactor and rename your project to *AuthServer* for easier updates in the future.
- In **MyApplication.IdentityServer.csproj** replace **project references**: - In **MyApplication.IdentityServer.csproj** replace **project references**:

2
docs/en/Migration-Guides/OpenIddict-Blazor.md

@ -131,7 +131,7 @@
## IdentityServer ## IdentityServer
This project is renamed to **AuthServer** after v6.0.0-rc1. You can also refactor and rename your project to *AuthServer* for easier updates in the future. This project is renamed to **AuthServer** after v6.0.0. You can also refactor and rename your project to *AuthServer* for easier updates in the future.
- In **MyApplication.IdentityServer.csproj** replace **project references**: - In **MyApplication.IdentityServer.csproj** replace **project references**:

2
docs/en/Migration-Guides/OpenIddict-Mvc.md

@ -111,7 +111,7 @@ Replace role scope to **roles** and add **UsePkce** and **SignoutScheme** option
## IdentityServer ## IdentityServer
This project is renamed to **AuthServer** after v6.0.0-rc1. You can also refactor and rename your project to *AuthServer* for easier updates in the future. This project is renamed to **AuthServer** after v6.0.0. You can also refactor and rename your project to *AuthServer* for easier updates in the future.
- In **MyApplication.IdentityServer.csproj** replace **project references**: - In **MyApplication.IdentityServer.csproj** replace **project references**:

2
docs/en/Migration-Guides/OpenIddict-Step-by-Step.md

@ -1,6 +1,6 @@
# Migrating from IdentityServer to OpenIddict Step by Step Guide # Migrating from IdentityServer to OpenIddict Step by Step Guide
This guide provides layer-by-layer guidance for migrating your existing application to [OpenIddict](https://github.com/openiddict/openiddict-core) from IdentityServer. ABP startup templates use `OpenIddict` OpenId provider from v6.0.0-rc1 by default and `IdentityServer` projects are renamed to `AuthServer` in tiered/separated solutions. Since OpenIddict is only available with ABP v6.0, you will need to update your existing application in order to apply OpenIddict changes. This guide provides layer-by-layer guidance for migrating your existing application to [OpenIddict](https://github.com/openiddict/openiddict-core) from IdentityServer. ABP startup templates use `OpenIddict` OpenId provider from v6.0.0 by default and `IdentityServer` projects are renamed to `AuthServer` in tiered/separated solutions. Since OpenIddict is only available with ABP v6.0, you will need to update your existing application in order to apply OpenIddict changes.
## History ## History
We are not removing Identity Server packages and we will continue to release new versions of IdentityServer-related NuGet/NPM packages. That means you won't have an issue while upgrading to v6.0 when the stable version releases. We will continue to fix bugs in our packages for a while. ABP 7.0 will be based on .NET 7. If Identity Server continues to work with .NET 7, we will also continue to ship NuGet packages for our IDS integration. We are not removing Identity Server packages and we will continue to release new versions of IdentityServer-related NuGet/NPM packages. That means you won't have an issue while upgrading to v6.0 when the stable version releases. We will continue to fix bugs in our packages for a while. ABP 7.0 will be based on .NET 7. If Identity Server continues to work with .NET 7, we will also continue to ship NuGet packages for our IDS integration.

78
modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/UserManagement.razor

@ -16,15 +16,17 @@
BreadcrumbItems="@BreadcrumbItems" BreadcrumbItems="@BreadcrumbItems"
Toolbar="@Toolbar" /> Toolbar="@Toolbar" />
</CardHeader> </CardHeader>
<CardBody> <CardBody class="row">
<Row>
<Column ColumnSize="ColumnSize.Is3"> <Column ColumnSize="ColumnSize.Is8">
<Field> </Column>
<FieldLabel>@L["Search"]</FieldLabel> <Column ColumnSize="ColumnSize.Is4" class="form-group row" style="text-align:right;">
<TextEdit Size="Size.Small" Text="@GetListInput.Filter" TextChanged="@OnSearchTextChanged" /> <label for="inputPassword" class="col-sm-4 col-form-label pt-1"> @L["Search"] </label>
</Field> <div class="col-sm-8">
</Column> <TextEdit class="form-control-sm" id="inputPassword" Text="@GetListInput.Filter" TextChanged="@OnSearchTextChanged" />
</Row> </div>
</Column>
@* ************************* DATA GRID ************************* *@ @* ************************* DATA GRID ************************* *@
<AbpExtensibleDataGrid TItem="IdentityUserDto" <AbpExtensibleDataGrid TItem="IdentityUserDto"
Data="Entities" Data="Entities"
@ -39,14 +41,14 @@
</Card> </Card>
@* ************************* CREATE MODAL ************************* *@ @* ************************* CREATE MODAL ************************* *@
@if ( HasCreatePermission ) @if (HasCreatePermission)
{ {
<Modal @ref="CreateModal" Closing="@ClosingCreateModal"> <Modal @ref="CreateModal" Closing="@ClosingCreateModal">
<ModalContent Centered="true"> <ModalContent Centered="true">
<Form> <Form>
<ModalHeader> <ModalHeader>
<ModalTitle>@L["NewUser"]</ModalTitle> <ModalTitle>@L["NewUser"]</ModalTitle>
<CloseButton Clicked="CloseCreateModalAsync"/> <CloseButton Clicked="CloseCreateModalAsync" />
</ModalHeader> </ModalHeader>
<ModalBody> <ModalBody>
<Validations @ref="@CreateValidationsRef" Model="@NewEntity" ValidateOnLoad="false"> <Validations @ref="@CreateValidationsRef" Model="@NewEntity" ValidateOnLoad="false">
@ -62,7 +64,7 @@
<FieldLabel>@L["DisplayName:UserName"] *</FieldLabel> <FieldLabel>@L["DisplayName:UserName"] *</FieldLabel>
<TextEdit @bind-Text="NewEntity.UserName" Autofocus="true"> <TextEdit @bind-Text="NewEntity.UserName" Autofocus="true">
<Feedback> <Feedback>
<ValidationError/> <ValidationError />
</Feedback> </Feedback>
</TextEdit> </TextEdit>
</Field> </Field>
@ -72,7 +74,7 @@
<FieldLabel>@L["DisplayName:Name"]</FieldLabel> <FieldLabel>@L["DisplayName:Name"]</FieldLabel>
<TextEdit @bind-Text="NewEntity.Name"> <TextEdit @bind-Text="NewEntity.Name">
<Feedback> <Feedback>
<ValidationError/> <ValidationError />
</Feedback> </Feedback>
</TextEdit> </TextEdit>
</Field> </Field>
@ -82,7 +84,7 @@
<FieldLabel>@L["DisplayName:Surname"]</FieldLabel> <FieldLabel>@L["DisplayName:Surname"]</FieldLabel>
<TextEdit @bind-Text="NewEntity.Surname"> <TextEdit @bind-Text="NewEntity.Surname">
<Feedback> <Feedback>
<ValidationError/> <ValidationError />
</Feedback> </Feedback>
</TextEdit> </TextEdit>
</Field> </Field>
@ -101,7 +103,7 @@
</Button> </Button>
</Addon> </Addon>
</Addons> </Addons>
<ValidationError Style="display: block"/> <ValidationError Style="display: block" />
</Field> </Field>
</Validation> </Validation>
<Validation MessageLocalizer="@LH.Localize"> <Validation MessageLocalizer="@LH.Localize">
@ -109,7 +111,7 @@
<FieldLabel>@L["DisplayName:Email"] *</FieldLabel> <FieldLabel>@L["DisplayName:Email"] *</FieldLabel>
<TextEdit @bind-Text="NewEntity.Email"> <TextEdit @bind-Text="NewEntity.Email">
<Feedback> <Feedback>
<ValidationError/> <ValidationError />
</Feedback> </Feedback>
</TextEdit> </TextEdit>
</Field> </Field>
@ -119,7 +121,7 @@
<FieldLabel>@L["DisplayName:PhoneNumber"]</FieldLabel> <FieldLabel>@L["DisplayName:PhoneNumber"]</FieldLabel>
<TextEdit @bind-Text="NewEntity.PhoneNumber"> <TextEdit @bind-Text="NewEntity.PhoneNumber">
<Feedback> <Feedback>
<ValidationError/> <ValidationError />
</Feedback> </Feedback>
</TextEdit> </TextEdit>
</Field> </Field>
@ -130,15 +132,15 @@
<Field> <Field>
<Check TValue="bool" @bind-Checked="@NewEntity.LockoutEnabled">@L["DisplayName:LockoutEnabled"]</Check> <Check TValue="bool" @bind-Checked="@NewEntity.LockoutEnabled">@L["DisplayName:LockoutEnabled"]</Check>
</Field> </Field>
<ExtensionProperties TEntityType="IdentityUserCreateDto" TResourceType="IdentityResource" Entity="@NewEntity" LH="@LH"/> <ExtensionProperties TEntityType="IdentityUserCreateDto" TResourceType="IdentityResource" Entity="@NewEntity" LH="@LH" />
</TabPanel> </TabPanel>
<TabPanel Name="Roles"> <TabPanel Name="Roles">
@if ( NewUserRoles != null ) @if (NewUserRoles != null)
{ {
@foreach ( var role in NewUserRoles ) @foreach (var role in NewUserRoles)
{ {
<Field> <Field>
<input type="hidden" @bind-value="@role.Name"/> <input type="hidden" @bind-value="@role.Name" />
<Check TValue="bool" @bind-Checked="@role.IsAssigned">@role.Name</Check> <Check TValue="bool" @bind-Checked="@role.IsAssigned">@role.Name</Check>
</Field> </Field>
} }
@ -150,7 +152,7 @@
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
<Button Color="Color.Secondary" Clicked="CloseCreateModalAsync">@L["Cancel"]</Button> <Button Color="Color.Secondary" Clicked="CloseCreateModalAsync">@L["Cancel"]</Button>
<SubmitButton Clicked="@CreateEntityAsync"/> <SubmitButton Clicked="@CreateEntityAsync" />
</ModalFooter> </ModalFooter>
</Form> </Form>
</ModalContent> </ModalContent>
@ -158,18 +160,18 @@
} }
@* ************************* EDIT MODAL ************************* *@ @* ************************* EDIT MODAL ************************* *@
@if ( HasUpdatePermission ) @if (HasUpdatePermission)
{ {
<Modal @ref="EditModal" Closing="@ClosingEditModal"> <Modal @ref="EditModal" Closing="@ClosingEditModal">
<ModalContent Centered="true"> <ModalContent Centered="true">
<Form> <Form>
<ModalHeader> <ModalHeader>
<ModalTitle>@L["Edit"]</ModalTitle> <ModalTitle>@L["Edit"]</ModalTitle>
<CloseButton Clicked="CloseEditModalAsync"/> <CloseButton Clicked="CloseEditModalAsync" />
</ModalHeader> </ModalHeader>
<ModalBody> <ModalBody>
<Validations @ref="@EditValidationsRef" Model="@EditingEntity" ValidateOnLoad="false"> <Validations @ref="@EditValidationsRef" Model="@EditingEntity" ValidateOnLoad="false">
<input type="hidden" name="ConcurrencyStamp" @bind-value="EditingEntity.ConcurrencyStamp"/> <input type="hidden" name="ConcurrencyStamp" @bind-value="EditingEntity.ConcurrencyStamp" />
<Tabs @bind-SelectedTab="@EditModalSelectedTab"> <Tabs @bind-SelectedTab="@EditModalSelectedTab">
<Items> <Items>
@ -183,7 +185,7 @@
<FieldLabel>@L["DisplayName:UserName"] *</FieldLabel> <FieldLabel>@L["DisplayName:UserName"] *</FieldLabel>
<TextEdit @bind-Text="EditingEntity.UserName" Autofocus="true"> <TextEdit @bind-Text="EditingEntity.UserName" Autofocus="true">
<Feedback> <Feedback>
<ValidationError/> <ValidationError />
</Feedback> </Feedback>
</TextEdit> </TextEdit>
</Field> </Field>
@ -193,7 +195,7 @@
<FieldLabel>@L["DisplayName:Name"]</FieldLabel> <FieldLabel>@L["DisplayName:Name"]</FieldLabel>
<TextEdit @bind-Text="EditingEntity.Name"> <TextEdit @bind-Text="EditingEntity.Name">
<Feedback> <Feedback>
<ValidationError/> <ValidationError />
</Feedback> </Feedback>
</TextEdit> </TextEdit>
</Field> </Field>
@ -203,7 +205,7 @@
<FieldLabel>@L["DisplayName:Surname"]</FieldLabel> <FieldLabel>@L["DisplayName:Surname"]</FieldLabel>
<TextEdit @bind-Text="EditingEntity.Surname"> <TextEdit @bind-Text="EditingEntity.Surname">
<Feedback> <Feedback>
<ValidationError/> <ValidationError />
</Feedback> </Feedback>
</TextEdit> </TextEdit>
</Field> </Field>
@ -222,7 +224,7 @@
</Button> </Button>
</Addon> </Addon>
</Addons> </Addons>
<ValidationError Style="display: block"/> <ValidationError Style="display: block" />
</Field> </Field>
</Validation> </Validation>
<Validation MessageLocalizer="@LH.Localize"> <Validation MessageLocalizer="@LH.Localize">
@ -230,7 +232,7 @@
<FieldLabel>@L["DisplayName:Email"] *</FieldLabel> <FieldLabel>@L["DisplayName:Email"] *</FieldLabel>
<TextEdit @bind-Text="EditingEntity.Email"> <TextEdit @bind-Text="EditingEntity.Email">
<Feedback> <Feedback>
<ValidationError/> <ValidationError />
</Feedback> </Feedback>
</TextEdit> </TextEdit>
</Field> </Field>
@ -240,7 +242,7 @@
<FieldLabel>@L["DisplayName:PhoneNumber"]</FieldLabel> <FieldLabel>@L["DisplayName:PhoneNumber"]</FieldLabel>
<TextEdit @bind-Text="EditingEntity.PhoneNumber"> <TextEdit @bind-Text="EditingEntity.PhoneNumber">
<Feedback> <Feedback>
<ValidationError/> <ValidationError />
</Feedback> </Feedback>
</TextEdit> </TextEdit>
</Field> </Field>
@ -251,15 +253,15 @@
<Field> <Field>
<Check TValue="bool" @bind-Checked="EditingEntity.LockoutEnabled">@L["DisplayName:LockoutEnabled"]</Check> <Check TValue="bool" @bind-Checked="EditingEntity.LockoutEnabled">@L["DisplayName:LockoutEnabled"]</Check>
</Field> </Field>
<ExtensionProperties TEntityType="IdentityUserUpdateDto" TResourceType="IdentityResource" Entity="@EditingEntity" LH="@LH"/> <ExtensionProperties TEntityType="IdentityUserUpdateDto" TResourceType="IdentityResource" Entity="@EditingEntity" LH="@LH" />
</TabPanel> </TabPanel>
<TabPanel Name="Roles"> <TabPanel Name="Roles">
@if ( EditUserRoles != null ) @if (EditUserRoles != null)
{ {
@foreach ( var role in EditUserRoles ) @foreach (var role in EditUserRoles)
{ {
<Field> <Field>
<input type="hidden" @bind-value="@role.Name"/> <input type="hidden" @bind-value="@role.Name" />
<Check TValue="bool" @bind-Checked="@role.IsAssigned">@role.Name</Check> <Check TValue="bool" @bind-Checked="@role.IsAssigned">@role.Name</Check>
</Field> </Field>
} }
@ -271,14 +273,14 @@
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
<Button Color="Color.Secondary" Clicked="CloseEditModalAsync">@L["Cancel"]</Button> <Button Color="Color.Secondary" Clicked="CloseEditModalAsync">@L["Cancel"]</Button>
<SubmitButton Clicked="@UpdateEntityAsync"/> <SubmitButton Clicked="@UpdateEntityAsync" />
</ModalFooter> </ModalFooter>
</Form> </Form>
</ModalContent> </ModalContent>
</Modal> </Modal>
} }
@if ( HasManagePermissionsPermission ) @if (HasManagePermissionsPermission)
{ {
<PermissionManagementModal @ref="PermissionManagementModal"/> <PermissionManagementModal @ref="PermissionManagementModal" />
} }

2
modules/openiddict/src/Volo.Abp.OpenIddict.MongoDB/Volo/Abp/OpenIddict/Authorizations/MongoOpenIddictAuthorizationRepository.cs

@ -74,7 +74,7 @@ public class MongoOpenIddictAuthorizationRepository : MongoDbRepository<OpenIddi
await DeleteManyAsync(await (await GetMongoQueryableAsync(cancellationToken)) await DeleteManyAsync(await (await GetMongoQueryableAsync(cancellationToken))
.Where(x => x.CreationDate < date) .Where(x => x.CreationDate < date)
.Where(x => x.Status == OpenIddictConstants.Statuses.Valid || (x.Type == OpenIddictConstants.AuthorizationTypes.AdHoc && !tokens.Contains(x.Id))) .Where(x => x.Status != OpenIddictConstants.Statuses.Valid || (x.Type == OpenIddictConstants.AuthorizationTypes.AdHoc && !tokens.Contains(x.Id)))
.ToListAsync(cancellationToken: cancellationToken), cancellationToken: cancellationToken); .ToListAsync(cancellationToken: cancellationToken), cancellationToken: cancellationToken);
} }
} }

7
npm/ng-packs/packages/core/src/lib/core.module.ts

@ -33,8 +33,9 @@ import { getInitialData, localeInitializer } from './utils/initial-utils';
import { ShortDateTimePipe } from './pipes/short-date-time.pipe'; import { ShortDateTimePipe } from './pipes/short-date-time.pipe';
import { ShortTimePipe } from './pipes/short-time.pipe'; import { ShortTimePipe } from './pipes/short-time.pipe';
import { ShortDatePipe } from './pipes/short-date.pipe'; import { ShortDatePipe } from './pipes/short-date.pipe';
import { QUEUE_MANAGER } from './tokens/queue.token';
import { DefaultQueueManager } from './utils/queue';
import { IncludeLocalizationResourcesProvider } from './providers/include-localization-resources.provider'; import { IncludeLocalizationResourcesProvider } from './providers/include-localization-resources.provider';
import { AuthGuard } from './abstracts/auth.guard';
/** /**
* BaseCoreModule is the module that holds * BaseCoreModule is the module that holds
@ -171,6 +172,10 @@ export class CoreModule {
useValue: localizationContributor(options.localizations), useValue: localizationContributor(options.localizations),
deps: [LocalizationService], deps: [LocalizationService],
}, },
{
provide: QUEUE_MANAGER,
useClass: DefaultQueueManager,
},
IncludeLocalizationResourcesProvider, IncludeLocalizationResourcesProvider,
], ],
}; };

6
npm/ng-packs/packages/core/src/lib/directives/permission.directive.ts

@ -2,6 +2,7 @@ import {
AfterViewInit, AfterViewInit,
ChangeDetectorRef, ChangeDetectorRef,
Directive, Directive,
Inject,
Input, Input,
OnChanges, OnChanges,
OnDestroy, OnDestroy,
@ -12,6 +13,8 @@ import {
import { ReplaySubject, Subscription } from 'rxjs'; import { ReplaySubject, Subscription } from 'rxjs';
import { distinctUntilChanged, take } from 'rxjs/operators'; import { distinctUntilChanged, take } from 'rxjs/operators';
import { PermissionService } from '../services/permission.service'; import { PermissionService } from '../services/permission.service';
import { QUEUE_MANAGER } from '../tokens/queue.token';
import { QueueManager } from '../utils/queue';
@Directive({ @Directive({
selector: '[abpPermission]', selector: '[abpPermission]',
@ -32,6 +35,7 @@ export class PermissionDirective implements OnDestroy, OnChanges, AfterViewInit
private vcRef: ViewContainerRef, private vcRef: ViewContainerRef,
private permissionService: PermissionService, private permissionService: PermissionService,
private cdRef: ChangeDetectorRef, private cdRef: ChangeDetectorRef,
@Inject(QUEUE_MANAGER) public queue: QueueManager,
) {} ) {}
private check() { private check() {
@ -66,7 +70,7 @@ export class PermissionDirective implements OnDestroy, OnChanges, AfterViewInit
} }
ngAfterViewInit() { ngAfterViewInit() {
this.cdrSubject.pipe(take(1)).subscribe(() => this.cdRef.detectChanges()); this.cdrSubject.pipe(take(1)).subscribe(() => this.queue.add(() => this.cdRef.detectChanges()));
this.rendered = true; this.rendered = true;
} }
} }

11
npm/ng-packs/packages/core/src/lib/tests/initial-utils.spec.ts

@ -12,6 +12,7 @@ import { getInitialData, localeInitializer } from '../utils/initial-utils';
import * as environmentUtils from '../utils/environment-utils'; import * as environmentUtils from '../utils/environment-utils';
import * as multiTenancyUtils from '../utils/multi-tenancy-utils'; import * as multiTenancyUtils from '../utils/multi-tenancy-utils';
import { RestService } from '../services/rest.service'; import { RestService } from '../services/rest.service';
import { CHECK_AUTHENTICATION_STATE_FN_KEY } from '../tokens/check-authentication-state';
const environment = { oAuthConfig: { issuer: 'test' } }; const environment = { oAuthConfig: { issuer: 'test' } };
@ -41,6 +42,10 @@ describe('InitialUtils', () => {
registerLocaleFn: () => Promise.resolve(), registerLocaleFn: () => Promise.resolve(),
}, },
}, },
{
provide: CHECK_AUTHENTICATION_STATE_FN_KEY,
useValue: () => {},
},
], ],
}); });
@ -51,6 +56,9 @@ describe('InitialUtils', () => {
const environmentService = spectator.inject(EnvironmentService); const environmentService = spectator.inject(EnvironmentService);
const configStateService = spectator.inject(ConfigStateService); const configStateService = spectator.inject(ConfigStateService);
const sessionStateService = spectator.inject(SessionStateService); const sessionStateService = spectator.inject(SessionStateService);
//const checkAuthenticationState = spectator.inject(CHECK_AUTHENTICATION_STATE_FN_KEY);
const authService = spectator.inject(AuthService);
const parseTenantFromUrlSpy = jest.spyOn(multiTenancyUtils, 'parseTenantFromUrl'); const parseTenantFromUrlSpy = jest.spyOn(multiTenancyUtils, 'parseTenantFromUrl');
const getRemoteEnvSpy = jest.spyOn(environmentUtils, 'getRemoteEnv'); const getRemoteEnvSpy = jest.spyOn(environmentUtils, 'getRemoteEnv');
@ -65,7 +73,7 @@ describe('InitialUtils', () => {
const configRefreshAppStateSpy = jest.spyOn(configStateService, 'refreshAppState'); const configRefreshAppStateSpy = jest.spyOn(configStateService, 'refreshAppState');
configRefreshAppStateSpy.mockReturnValue(of(appConfigRes)); configRefreshAppStateSpy.mockReturnValue(of(appConfigRes));
const sessionSetTenantSpy = jest.spyOn(sessionStateService, 'setTenant'); const sessionSetTenantSpy = jest.spyOn(sessionStateService, 'setTenant');
const authServiceInitSpy = jest.spyOn(authService, 'init');
const configStateGetOneSpy = jest.spyOn(configStateService, 'getOne'); const configStateGetOneSpy = jest.spyOn(configStateService, 'getOne');
configStateGetOneSpy.mockReturnValue(appConfigRes.currentTenant); configStateGetOneSpy.mockReturnValue(appConfigRes.currentTenant);
@ -79,6 +87,7 @@ describe('InitialUtils', () => {
expect(configRefreshAppStateSpy).toHaveBeenCalled(); expect(configRefreshAppStateSpy).toHaveBeenCalled();
expect(environmentSetStateSpy).toHaveBeenCalledWith(environment); expect(environmentSetStateSpy).toHaveBeenCalledWith(environment);
expect(sessionSetTenantSpy).toHaveBeenCalledWith(appConfigRes.currentTenant); expect(sessionSetTenantSpy).toHaveBeenCalledWith(appConfigRes.currentTenant);
expect(authServiceInitSpy).toHaveBeenCalled();
}); });
}); });

1
npm/ng-packs/packages/core/src/lib/tokens/index.ts

@ -5,6 +5,7 @@ export * from './localization.token';
export * from './lodaer-delay.token'; export * from './lodaer-delay.token';
export * from './manage-profile.token'; export * from './manage-profile.token';
export * from './options.token'; export * from './options.token';
export * from './queue.token';
export * from './tenant-key.token'; export * from './tenant-key.token';
export * from './include-localization-resources.token'; export * from './include-localization-resources.token';
export * from './pipe-to-login.token'; export * from './pipe-to-login.token';

4
npm/ng-packs/packages/core/src/lib/tokens/queue.token.ts

@ -0,0 +1,4 @@
import { QueueManager } from "../utils/queue";
import { InjectionToken } from "@angular/core";
export const QUEUE_MANAGER = new InjectionToken<QueueManager>("QUEUE_MANAGER");

1
npm/ng-packs/packages/core/src/lib/utils/index.ts

@ -14,6 +14,7 @@ export * from './localization-utils';
export * from './multi-tenancy-utils'; export * from './multi-tenancy-utils';
export * from './number-utils'; export * from './number-utils';
export * from './object-utils'; export * from './object-utils';
export * from './queue';
export * from './route-utils'; export * from './route-utils';
export * from './string-utils'; export * from './string-utils';
export * from './tree-utils'; export * from './tree-utils';

48
npm/ng-packs/packages/core/src/lib/utils/queue.ts

@ -0,0 +1,48 @@
export interface QueueManager {
add(fn: () => void): void;
init(interval: number, stackSize: number): void;
}
export class DefaultQueueManager implements QueueManager {
private queue: Array<() => void> = [];
private isRunning = false;
private stack = 0;
private interval = 0;
private stackSize = 100;
public init(interval: number, stackSize: number) {
this.interval = interval;
this.stackSize = stackSize;
}
public add(fn: () => void) {
this.queue.push(fn);
this.run();
}
private run() {
if (this.isRunning) return;
this.stack++;
this.isRunning = true;
const fn = this.queue.shift();
if (!fn) {
this.isRunning = false;
return;
}
fn();
if (this.stack > this.stackSize) {
setTimeout(() => {
this.isRunning = false;
this.run();
this.stack = 0;
}, this.interval);
} else {
this.isRunning = false;
this.run();
}
}
}

3
npm/ng-packs/packages/oauth/src/lib/tests/api.interceptor.spec.ts

@ -3,8 +3,7 @@ import { SpyObject } from '@ngneat/spectator';
import { createServiceFactory, SpectatorService } from '@ngneat/spectator/jest'; import { createServiceFactory, SpectatorService } from '@ngneat/spectator/jest';
import { OAuthService } from 'angular-oauth2-oidc'; import { OAuthService } from 'angular-oauth2-oidc';
import { Subject, timer } from 'rxjs'; import { Subject, timer } from 'rxjs';
import { ApiInterceptor } from '../interceptors/api.interceptor'; import { ApiInterceptor, HttpWaitService, SessionStateService, TENANT_KEY } from '@abp/ng.core';
import { HttpWaitService, SessionStateService, TENANT_KEY } from '@abp/ng.core';
describe('ApiInterceptor', () => { describe('ApiInterceptor', () => {
let spectator: SpectatorService<ApiInterceptor>; let spectator: SpectatorService<ApiInterceptor>;

29
npm/ng-packs/packages/oauth/src/lib/tests/initial-utils.spec.ts

@ -9,10 +9,8 @@ import {
ConfigStateService, ConfigStateService,
AbpApplicationConfigurationService, AbpApplicationConfigurationService,
SessionStateService, SessionStateService,
ApplicationConfigurationDto,
} from '@abp/ng.core'; } from '@abp/ng.core';
import * as clearOAuthStorageDefault from '../utils/clear-o-auth-storage'; import * as clearOAuthStorageDefault from '../utils/clear-o-auth-storage';
import { of } from 'rxjs';
import { checkAccessToken } from '../utils/check-access-token'; import { checkAccessToken } from '../utils/check-access-token';
const environment = { oAuthConfig: { issuer: 'test' } }; const environment = { oAuthConfig: { issuer: 'test' } };
@ -49,33 +47,6 @@ describe('InitialUtils', () => {
beforeEach(() => (spectator = createComponent())); beforeEach(() => (spectator = createComponent()));
describe('#getInitialData', () => {
let mockInjector;
let configStateService;
let authService;
beforeEach(() => {
mockInjector = {
get: spectator.inject,
};
configStateService = spectator.inject(ConfigStateService);
authService = spectator.inject(AuthService);
});
test('should called configStateService.refreshAppState', async () => {
const configRefreshAppStateSpy = jest.spyOn(configStateService, 'refreshAppState');
const appConfigRes = {
currentTenant: { id: 'test', name: 'testing' },
} as ApplicationConfigurationDto;
configRefreshAppStateSpy.mockReturnValue(of(appConfigRes));
// Todo: refactor it
// await initFactory(mockInjector)();
expect(configRefreshAppStateSpy).toHaveBeenCalled();
});
});
describe('#checkAccessToken', () => { describe('#checkAccessToken', () => {
let injector; let injector;
let injectorSpy; let injectorSpy;

Loading…
Cancel
Save