mirror of
https://github.com/valitydev/dashboard.git
synced 2024-11-06 02:25:23 +00:00
TD-666: New api keys protocol (#134)
This commit is contained in:
parent
08d5eb406d
commit
e4f63bacd6
22
package-lock.json
generated
22
package-lock.json
generated
@ -25,9 +25,9 @@
|
||||
"@sentry/angular": "^7.56.0",
|
||||
"@sentry/integrations": "^7.56.0",
|
||||
"@sentry/tracing": "^7.56.0",
|
||||
"@vality/ng-core": "^16.1.2-pr-28-02fc769.0",
|
||||
"@vality/ng-core": "^16.2.1-pr-33-42d91a3.0",
|
||||
"@vality/swag-anapi-v2": "2.0.0",
|
||||
"@vality/swag-api-keys": "1.0.1-55db9ab.0",
|
||||
"@vality/swag-api-keys-v2": "^0.1.2-be3bbdd.0",
|
||||
"@vality/swag-claim-management": "0.1.1-7a03f9b.0",
|
||||
"@vality/swag-organizations": "1.0.1-cd6cc10.0",
|
||||
"@vality/swag-payments": "0.1.1-01da4bb.0",
|
||||
@ -6866,9 +6866,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vality/ng-core": {
|
||||
"version": "16.1.2-pr-28-02fc769.0",
|
||||
"resolved": "https://registry.npmjs.org/@vality/ng-core/-/ng-core-16.1.2-pr-28-02fc769.0.tgz",
|
||||
"integrity": "sha512-OKr+iYvZoxV6JX2t68UtYlf+GV4S3e4aiJ0/tAbK2A5hKn+DmdxNhUG32dGhh12oDqGWodGSuiqS1HT62FLmBg==",
|
||||
"version": "16.2.1-pr-33-42d91a3.0",
|
||||
"resolved": "https://registry.npmjs.org/@vality/ng-core/-/ng-core-16.2.1-pr-33-42d91a3.0.tgz",
|
||||
"integrity": "sha512-Ags1PPyLkeHEmjRlh3hqgo8jR4dtLpnM9EmjZ3Qa33ayfI8cki+BQANRzaH2VOgjTLcwR54QOTxm012xui2SEQ==",
|
||||
"dependencies": {
|
||||
"@ng-matero/extensions": "^16.0.0",
|
||||
"@s-libs/js-core": "^16.0.0",
|
||||
@ -6970,16 +6970,16 @@
|
||||
"@angular/core": "^16.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@vality/swag-api-keys": {
|
||||
"version": "1.0.1-55db9ab.0",
|
||||
"resolved": "https://registry.npmjs.org/@vality/swag-api-keys/-/swag-api-keys-1.0.1-55db9ab.0.tgz",
|
||||
"integrity": "sha512-pafXHEIKv8o8GFQPA82PwQhy0XgWyHbrRqMnemyUyzLFFeTIJ/pwevfUGajzohUUg2I66mQ2utu8lVPw4485rg==",
|
||||
"node_modules/@vality/swag-api-keys-v2": {
|
||||
"version": "0.1.2-be3bbdd.0",
|
||||
"resolved": "https://registry.npmjs.org/@vality/swag-api-keys-v2/-/swag-api-keys-v2-0.1.2-be3bbdd.0.tgz",
|
||||
"integrity": "sha512-PD8nH0AqT/KjSFsEYrs27CAg0iN8VTjLxgjgkhnDeLy4V6AVqJ12MVHQeTGhmJTOnpQNp7sLHVPLSGYgzvvayg==",
|
||||
"dependencies": {
|
||||
"tslib": "^2.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/common": ">=14.0.0",
|
||||
"@angular/core": ">=14.0.0"
|
||||
"@angular/common": "^13.0.0",
|
||||
"@angular/core": "^13.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@vality/swag-claim-management": {
|
||||
|
@ -40,9 +40,9 @@
|
||||
"@sentry/angular": "^7.56.0",
|
||||
"@sentry/integrations": "^7.56.0",
|
||||
"@sentry/tracing": "^7.56.0",
|
||||
"@vality/ng-core": "^16.1.2-pr-28-02fc769.0",
|
||||
"@vality/ng-core": "^16.2.1-pr-33-42d91a3.0",
|
||||
"@vality/swag-anapi-v2": "2.0.0",
|
||||
"@vality/swag-api-keys": "1.0.1-55db9ab.0",
|
||||
"@vality/swag-api-keys-v2": "^0.1.2-be3bbdd.0",
|
||||
"@vality/swag-claim-management": "0.1.1-7a03f9b.0",
|
||||
"@vality/swag-organizations": "1.0.1-cd6cc10.0",
|
||||
"@vality/swag-payments": "0.1.1-01da4bb.0",
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { Configuration } from '@vality/swag-api-keys';
|
||||
import { Configuration } from '@vality/swag-api-keys-v2';
|
||||
|
||||
import { ConfigService } from '../../config';
|
||||
|
||||
@ -9,7 +9,7 @@ import { ConfigService } from '../../config';
|
||||
provide: Configuration,
|
||||
deps: [ConfigService],
|
||||
useFactory: (configService: ConfigService) =>
|
||||
new Configuration({ basePath: `${configService.apiEndpoint}/apikeys/v1` }),
|
||||
new Configuration({ basePath: `${configService.apiEndpoint}/apikeys/v2` }),
|
||||
},
|
||||
],
|
||||
})
|
||||
|
@ -1,10 +1,18 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ApiKeysService as ApiService } from '@vality/swag-api-keys';
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { ApiKeysService as ApiService } from '@vality/swag-api-keys-v2';
|
||||
|
||||
import { createApi } from '../utils';
|
||||
import { PartyIdExtension } from '../utils/extensions';
|
||||
import { PartyIdExtension, PartyIdPatchMethodService } from '../utils/extensions';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class ApiKeysService extends createApi(ApiService, [PartyIdExtension]) {}
|
||||
export class ApiKeysService extends createApi(ApiService, [PartyIdExtension]) {
|
||||
constructor(injector: Injector, partyIdPatchMethodService: PartyIdPatchMethodService) {
|
||||
super(injector);
|
||||
this.requestRevokeApiKey = partyIdPatchMethodService.patch(
|
||||
this.requestRevokeApiKey,
|
||||
(params, partyId) => (params.partyId = partyId)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { ApiKey } from '@vality/swag-api-keys';
|
||||
import { ApiKey } from '@vality/swag-api-keys-v2';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
import { ExpandedIdManager } from '@dsh/app/shared/services';
|
||||
import { ExpandedIdManager, Fragment } from '@dsh/app/shared/services';
|
||||
|
||||
import { FetchApiKeysService } from './fetch-api-keys.service';
|
||||
|
||||
@ -17,7 +17,15 @@ export class ApiKeysExpandedIdManager extends ExpandedIdManager<ApiKey> {
|
||||
super(route, router);
|
||||
}
|
||||
|
||||
protected toFragment(apiKey: ApiKey): Fragment {
|
||||
return apiKey.id;
|
||||
}
|
||||
|
||||
protected fragmentNotFound(): void {
|
||||
this.fetchApiKeysService.more();
|
||||
}
|
||||
|
||||
protected get dataSet$(): Observable<ApiKey[]> {
|
||||
return this.fetchApiKeysService.apiKeys$;
|
||||
return this.fetchApiKeysService.result$;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { UntilDestroy } from '@ngneat/until-destroy';
|
||||
import { DialogService } from '@vality/ng-core';
|
||||
import { ApiKey } from '@vality/swag-api-keys';
|
||||
import { ApiKey } from '@vality/swag-api-keys-v2';
|
||||
|
||||
import { ApiKeyDeleteDialogComponent } from './components/api-key-delete-dialog/api-key-delete-dialog.component';
|
||||
|
||||
|
@ -3,7 +3,7 @@ import { FlexModule } from '@angular/flex-layout';
|
||||
import { TranslocoModule } from '@ngneat/transloco';
|
||||
import { untilDestroyed, UntilDestroy } from '@ngneat/until-destroy';
|
||||
import { DialogSuperclass } from '@vality/ng-core';
|
||||
import { RequestRevokeApiKeyRequestParams } from '@vality/swag-api-keys';
|
||||
import { RequestRevokeApiKeyRequestParams } from '@vality/swag-api-keys-v2';
|
||||
|
||||
import { ApiKeysService } from '@dsh/app/api/api-keys';
|
||||
import { BaseDialogModule } from '@dsh/app/shared/components/dialog/base-dialog';
|
||||
@ -34,7 +34,7 @@ export class ApiKeyDeleteDialogComponent extends DialogSuperclass<
|
||||
|
||||
confirm() {
|
||||
this.apiKeysService
|
||||
.requestRevokeApiKey(this.dialogData)
|
||||
.requestRevokeApiKey({ ...this.dialogData, status: 'Revoked' })
|
||||
.pipe(untilDestroyed(this))
|
||||
.subscribe({
|
||||
next: () => {
|
||||
|
@ -32,5 +32,6 @@
|
||||
*ngIf="(apiKeys$ | async)?.length === 0"
|
||||
[text]="t('emptyResult')"
|
||||
></dsh-empty-search-result>
|
||||
<dsh-show-more-panel *ngIf="hasMore$ | async" (showMore)="more()"></dsh-show-more-panel>
|
||||
</ng-template>
|
||||
</div>
|
||||
|
@ -1,13 +1,14 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
|
||||
import { DialogService } from '@vality/ng-core';
|
||||
import { ApiKeyStatus, ListApiKeysRequestParams } from '@vality/swag-api-keys';
|
||||
import { ApiKeyStatus } from '@vality/swag-api-keys-v2';
|
||||
|
||||
import { ApiKeyCreateDialogComponent } from '@dsh/app/sections/payment-section/integrations/api-keys/components/api-key-create-dialog/api-key-create-dialog.component';
|
||||
import { mapToTimestamp, shareReplayRefCount } from '@dsh/app/custom-operators';
|
||||
import { QueryParamsService } from '@dsh/app/shared';
|
||||
|
||||
import { ApiKeysExpandedIdManager } from './api-keys-expanded-id-manager.service';
|
||||
import { ApiKeyCreateDialogComponent } from './components/api-key-create-dialog/api-key-create-dialog.component';
|
||||
import { FetchApiKeysService } from './fetch-api-keys.service';
|
||||
import { QueryParamsService } from '../../../../shared';
|
||||
|
||||
@UntilDestroy()
|
||||
@Component({
|
||||
@ -17,20 +18,27 @@ import { QueryParamsService } from '../../../../shared';
|
||||
})
|
||||
export class ApiKeysComponent {
|
||||
showInactive = this.qp.params.showInactive;
|
||||
apiKeys$ = this.fetchApiKeysService.apiKeys$;
|
||||
apiKeys$ = this.fetchApiKeysService.result$;
|
||||
isLoading$ = this.fetchApiKeysService.isLoading$;
|
||||
hasMore$ = this.fetchApiKeysService.hasMore$;
|
||||
expandedId$ = this.apiKeysExpandedIdManager.expandedId$;
|
||||
lastUpdated$ = this.fetchApiKeysService.lastUpdated$;
|
||||
lastUpdated$ = this.fetchApiKeysService.result$.pipe(mapToTimestamp, shareReplayRefCount());
|
||||
|
||||
constructor(
|
||||
private qp: QueryParamsService<{ showInactive: boolean }>,
|
||||
private apiKeysExpandedIdManager: ApiKeysExpandedIdManager,
|
||||
private fetchApiKeysService: FetchApiKeysService,
|
||||
private dialogService: DialogService
|
||||
) {}
|
||||
) {
|
||||
this.update();
|
||||
}
|
||||
|
||||
update(params: Omit<ListApiKeysRequestParams, 'partyId' | 'xRequestID'> = {}) {
|
||||
this.fetchApiKeysService.update(Object.assign(params, !this.showInactive && { status: ApiKeyStatus.Active }));
|
||||
update() {
|
||||
this.fetchApiKeysService.load(Object.assign({}, !this.showInactive && { status: ApiKeyStatus.Active }));
|
||||
}
|
||||
|
||||
more() {
|
||||
this.fetchApiKeysService.more();
|
||||
}
|
||||
|
||||
create() {
|
||||
|
@ -10,6 +10,7 @@ import { ButtonModule } from '@dsh/components/buttons';
|
||||
import { EmptySearchResultModule } from '@dsh/components/empty-search-result';
|
||||
import { SpinnerModule } from '@dsh/components/indicators';
|
||||
import { CardModule } from '@dsh/components/layout';
|
||||
import { ShowMorePanelModule } from '@dsh/components/show-more-panel';
|
||||
|
||||
import { ApiKeysListModule } from './api-keys-list/api-keys-list.module';
|
||||
import { ApiKeysRoutingModule } from './api-keys-routing.module';
|
||||
@ -33,6 +34,7 @@ import { ApiKeyRevokeComponent } from './components/api-key-revoke/api-key-revok
|
||||
MatSlideToggleModule,
|
||||
ApiKeysListModule,
|
||||
ApiKeyCreateDialogComponent,
|
||||
ShowMorePanelModule,
|
||||
],
|
||||
})
|
||||
export class ApiKeysModule {}
|
||||
|
@ -50,11 +50,11 @@ export class ApiKeyCreateDialogComponent extends DialogSuperclass<ApiKeyCreateDi
|
||||
|
||||
confirm() {
|
||||
this.apiKeysService
|
||||
.issueApiKey()
|
||||
.issueApiKey({ apiKeyIssue: { name: this.form.value.name } })
|
||||
.pipe(untilDestroyed(this))
|
||||
.subscribe({
|
||||
next: (res) => {
|
||||
this.apiKey = res.accessToken;
|
||||
this.apiKey = res.apiKey;
|
||||
},
|
||||
error: (err) => {
|
||||
this.errorService.error(err);
|
||||
|
@ -1,37 +1,43 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ListApiKeysRequestParams } from '@vality/swag-api-keys';
|
||||
import { BehaviorSubject, Observable, defer, of } from 'rxjs';
|
||||
import { catchError, map, switchMap } from 'rxjs/operators';
|
||||
import { TranslocoService } from '@ngneat/transloco';
|
||||
import { FetchSuperclass, NotifyLogService, FetchResult, FetchOptions } from '@vality/ng-core';
|
||||
import { ListApiKeysRequestParams } from '@vality/swag-api-keys-v2';
|
||||
import { ApiKey } from '@vality/swag-api-keys-v2/lib/model/api-key';
|
||||
import { of, Observable } from 'rxjs';
|
||||
import { catchError, map } from 'rxjs/operators';
|
||||
|
||||
import { ApiKeysService } from '@dsh/app/api/api-keys';
|
||||
import { mapToTimestamp, shareReplayRefCount } from '@dsh/app/custom-operators';
|
||||
import { ErrorService } from '@dsh/app/shared/services';
|
||||
import { inProgressFrom, progressTo } from '@dsh/utils';
|
||||
|
||||
@Injectable()
|
||||
export class FetchApiKeysService {
|
||||
apiKeys$ = defer(() => this.fetchApiKeys$).pipe(
|
||||
switchMap((p) =>
|
||||
this.apiKeysService.listApiKeys(p).pipe(
|
||||
map((r) => r.results),
|
||||
progressTo(() => this.progress$),
|
||||
export class FetchApiKeysService extends FetchSuperclass<
|
||||
ApiKey,
|
||||
Omit<ListApiKeysRequestParams, 'partyId' | 'xRequestID' | 'limit'>
|
||||
> {
|
||||
constructor(
|
||||
private apiKeysService: ApiKeysService,
|
||||
private logService: NotifyLogService,
|
||||
private transloco: TranslocoService
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
protected fetch(
|
||||
params: Omit<ListApiKeysRequestParams, 'partyId' | 'xRequestID' | 'limit'>,
|
||||
options: FetchOptions
|
||||
): Observable<FetchResult<ApiKey>> {
|
||||
return this.apiKeysService
|
||||
.listApiKeys({ ...params, limit: options.size, continuationToken: options.continuationToken })
|
||||
.pipe(
|
||||
map((res) => ({
|
||||
result: res.results,
|
||||
continuationToken: res.continuationToken,
|
||||
})),
|
||||
catchError((err) => {
|
||||
this.errorService.error(err);
|
||||
return of([]);
|
||||
this.logService.error(err, this.transloco.translate('apiKeys.fetch.error', {}, 'payment-section'));
|
||||
return of({
|
||||
result: [],
|
||||
});
|
||||
})
|
||||
)
|
||||
),
|
||||
shareReplayRefCount()
|
||||
);
|
||||
isLoading$ = inProgressFrom(() => this.progress$, this.apiKeys$);
|
||||
lastUpdated$: Observable<string> = this.apiKeys$.pipe(mapToTimestamp, shareReplayRefCount());
|
||||
|
||||
private progress$ = new BehaviorSubject(0);
|
||||
private fetchApiKeys$ = new BehaviorSubject<Omit<ListApiKeysRequestParams, 'partyId' | 'xRequestID'>>({});
|
||||
|
||||
constructor(private apiKeysService: ApiKeysService, private errorService: ErrorService) {}
|
||||
|
||||
update(params: Omit<ListApiKeysRequestParams, 'partyId' | 'xRequestID'> = {}) {
|
||||
this.fetchApiKeys$.next(params);
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -38,6 +38,9 @@
|
||||
"title": "Key revocation request"
|
||||
},
|
||||
"emptyResult": "No keys released",
|
||||
"fetch": {
|
||||
"error": "Error loading keys"
|
||||
},
|
||||
"list": {
|
||||
"createdAt": "Created at",
|
||||
"delete": "Revoke key",
|
||||
|
@ -38,6 +38,9 @@
|
||||
"title": "Запрос на отзыв ключа"
|
||||
},
|
||||
"emptyResult": "Не выпущено ни одного ключа",
|
||||
"fetch": {
|
||||
"error": "Ошибка при загрузке ключей"
|
||||
},
|
||||
"list": {
|
||||
"createdAt": "Создан",
|
||||
"delete": "Удалить",
|
||||
|
Loading…
Reference in New Issue
Block a user