[PM 2164] api-key component migration (#8562)
* api-key component migration * api-key component migration * api-key component migration * api-key component migration
This commit is contained in:
parent
24fb3f71f1
commit
1cec69e377
|
@ -216,31 +216,33 @@ export class AccountComponent {
|
||||||
};
|
};
|
||||||
|
|
||||||
async viewApiKey() {
|
async viewApiKey() {
|
||||||
await this.modalService.openViewRef(ApiKeyComponent, this.apiKeyModalRef, (comp) => {
|
await ApiKeyComponent.open(this.dialogService, {
|
||||||
comp.keyType = "organization";
|
data: {
|
||||||
comp.entityId = this.organizationId;
|
keyType: "organization",
|
||||||
comp.postKey = this.organizationApiService.getOrCreateApiKey.bind(
|
entityId: this.organizationId,
|
||||||
this.organizationApiService,
|
postKey: this.organizationApiService.getOrCreateApiKey.bind(this.organizationApiService),
|
||||||
);
|
scope: "api.organization",
|
||||||
comp.scope = "api.organization";
|
grantType: "client_credentials",
|
||||||
comp.grantType = "client_credentials";
|
apiKeyTitle: "apiKey",
|
||||||
comp.apiKeyTitle = "apiKey";
|
apiKeyWarning: "apiKeyWarning",
|
||||||
comp.apiKeyWarning = "apiKeyWarning";
|
apiKeyDescription: "apiKeyDesc",
|
||||||
comp.apiKeyDescription = "apiKeyDesc";
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async rotateApiKey() {
|
async rotateApiKey() {
|
||||||
await this.modalService.openViewRef(ApiKeyComponent, this.rotateApiKeyModalRef, (comp) => {
|
await ApiKeyComponent.open(this.dialogService, {
|
||||||
comp.keyType = "organization";
|
data: {
|
||||||
comp.isRotation = true;
|
keyType: "organization",
|
||||||
comp.entityId = this.organizationId;
|
isRotation: true,
|
||||||
comp.postKey = this.organizationApiService.rotateApiKey.bind(this.organizationApiService);
|
entityId: this.organizationId,
|
||||||
comp.scope = "api.organization";
|
postKey: this.organizationApiService.rotateApiKey.bind(this.organizationApiService),
|
||||||
comp.grantType = "client_credentials";
|
scope: "api.organization",
|
||||||
comp.apiKeyTitle = "apiKey";
|
grantType: "client_credentials",
|
||||||
comp.apiKeyWarning = "apiKeyWarning";
|
apiKeyTitle: "apiKey",
|
||||||
comp.apiKeyDescription = "apiKeyRotateDesc";
|
apiKeyWarning: "apiKeyWarning",
|
||||||
|
apiKeyDescription: "apiKeyRotateDesc",
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,72 +1,42 @@
|
||||||
<div class="modal fade" role="dialog" aria-modal="true" aria-labelledby="apiKeyTitle">
|
<form [formGroup]="formGroup" [bitSubmit]="submit">
|
||||||
<div class="modal-dialog modal-dialog-scrollable" role="document">
|
<bit-dialog>
|
||||||
<form
|
<span bitDialogTitle>{{ data.apiKeyTitle | i18n }}</span>
|
||||||
class="modal-content"
|
<div bitDialogContent>
|
||||||
#form
|
<p bitTypography="body1">{{ data.apiKeyDescription | i18n }}</p>
|
||||||
(ngSubmit)="submit()"
|
<app-user-verification-form-input formControlName="masterPassword" *ngIf="!clientSecret">
|
||||||
[appApiAction]="formPromise"
|
</app-user-verification-form-input>
|
||||||
ngNativeValidate
|
<app-callout type="warning" *ngIf="clientSecret">{{ data.apiKeyWarning | i18n }}</app-callout>
|
||||||
>
|
<app-callout
|
||||||
<div class="modal-header">
|
type="info"
|
||||||
<h1 class="modal-title" id="apiKeyTitle">{{ apiKeyTitle | i18n }}</h1>
|
title="{{ 'oauth2ClientCredentials' | i18n }}"
|
||||||
<button
|
icon="bwi bwi-key"
|
||||||
type="button"
|
*ngIf="clientSecret"
|
||||||
class="close"
|
>
|
||||||
data-dismiss="modal"
|
<p bitTypography="body1" class="tw-mb-1">
|
||||||
appA11yTitle="{{ 'close' | i18n }}"
|
<strong>client_id:</strong><br />
|
||||||
>
|
<code>{{ clientId }}</code>
|
||||||
<span aria-hidden="true">×</span>
|
</p>
|
||||||
</button>
|
<p bitTypography="body1" class="tw-mb-1">
|
||||||
</div>
|
<strong>client_secret:</strong><br />
|
||||||
<div class="modal-body">
|
<code>{{ clientSecret }}</code>
|
||||||
<p>{{ apiKeyDescription | i18n }}</p>
|
</p>
|
||||||
<app-user-verification
|
<p bitTypography="body1" class="tw-mb-1">
|
||||||
[(ngModel)]="masterPassword"
|
<strong>scope:</strong><br />
|
||||||
ngDefaultControl
|
<code>{{ data.scope }}</code>
|
||||||
name="secret"
|
</p>
|
||||||
*ngIf="!clientSecret"
|
<p bitTypography="body1" class="tw-mb-0">
|
||||||
>
|
<strong>grant_type:</strong><br />
|
||||||
</app-user-verification>
|
<code>{{ data.grantType }}</code>
|
||||||
|
</p>
|
||||||
<app-callout type="warning" *ngIf="clientSecret">{{ apiKeyWarning | i18n }}</app-callout>
|
</app-callout>
|
||||||
<app-callout
|
</div>
|
||||||
type="info"
|
<div bitDialogFooter>
|
||||||
title="{{ 'oauth2ClientCredentials' | i18n }}"
|
<button type="submit" buttonType="primary" *ngIf="!clientSecret" bitButton bitFormButton>
|
||||||
icon="bwi bwi-key"
|
<span>{{ (data.isRotation ? "rotateApiKey" : "viewApiKey") | i18n }}</span>
|
||||||
*ngIf="clientSecret"
|
</button>
|
||||||
>
|
<button type="button" bitButton bitFormButton bitDialogClose>
|
||||||
<p class="mb-1">
|
{{ "close" | i18n }}
|
||||||
<strong>client_id:</strong><br />
|
</button>
|
||||||
<code>{{ clientId }}</code>
|
</div>
|
||||||
</p>
|
</bit-dialog>
|
||||||
<p class="mb-1">
|
</form>
|
||||||
<strong>client_secret:</strong><br />
|
|
||||||
<code>{{ clientSecret }}</code>
|
|
||||||
</p>
|
|
||||||
<p class="mb-1">
|
|
||||||
<strong>scope:</strong><br />
|
|
||||||
<code>{{ scope }}</code>
|
|
||||||
</p>
|
|
||||||
<p class="mb-0">
|
|
||||||
<strong>grant_type:</strong><br />
|
|
||||||
<code>{{ grantType }}</code>
|
|
||||||
</p>
|
|
||||||
</app-callout>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button
|
|
||||||
type="submit"
|
|
||||||
class="btn btn-primary btn-submit"
|
|
||||||
[disabled]="form.loading"
|
|
||||||
*ngIf="!clientSecret"
|
|
||||||
>
|
|
||||||
<i class="bwi bwi-spinner bwi-spin" title="{{ 'loading' | i18n }}" aria-hidden="true"></i>
|
|
||||||
<span>{{ (isRotation ? "rotateApiKey" : "viewApiKey") | i18n }}</span>
|
|
||||||
</button>
|
|
||||||
<button type="button" class="btn btn-outline-secondary" data-dismiss="modal">
|
|
||||||
{{ "close" | i18n }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
|
@ -1,46 +1,58 @@
|
||||||
import { Component } from "@angular/core";
|
import { DIALOG_DATA, DialogConfig } from "@angular/cdk/dialog";
|
||||||
|
import { Component, Inject } from "@angular/core";
|
||||||
|
import { FormBuilder, Validators } from "@angular/forms";
|
||||||
|
|
||||||
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
|
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
|
||||||
import { SecretVerificationRequest } from "@bitwarden/common/auth/models/request/secret-verification.request";
|
import { SecretVerificationRequest } from "@bitwarden/common/auth/models/request/secret-verification.request";
|
||||||
import { ApiKeyResponse } from "@bitwarden/common/auth/models/response/api-key.response";
|
import { ApiKeyResponse } from "@bitwarden/common/auth/models/response/api-key.response";
|
||||||
import { Verification } from "@bitwarden/common/auth/types/verification";
|
import { Verification } from "@bitwarden/common/auth/types/verification";
|
||||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
import { DialogService } from "@bitwarden/components";
|
||||||
|
|
||||||
@Component({
|
export type ApiKeyDialogData = {
|
||||||
selector: "app-api-key",
|
|
||||||
templateUrl: "api-key.component.html",
|
|
||||||
})
|
|
||||||
export class ApiKeyComponent {
|
|
||||||
keyType: string;
|
keyType: string;
|
||||||
isRotation: boolean;
|
isRotation?: boolean;
|
||||||
postKey: (entityId: string, request: SecretVerificationRequest) => Promise<ApiKeyResponse>;
|
|
||||||
entityId: string;
|
entityId: string;
|
||||||
|
postKey: (entityId: string, request: SecretVerificationRequest) => Promise<ApiKeyResponse>;
|
||||||
scope: string;
|
scope: string;
|
||||||
grantType: string;
|
grantType: string;
|
||||||
apiKeyTitle: string;
|
apiKeyTitle: string;
|
||||||
apiKeyWarning: string;
|
apiKeyWarning: string;
|
||||||
apiKeyDescription: string;
|
apiKeyDescription: string;
|
||||||
|
};
|
||||||
masterPassword: Verification;
|
@Component({
|
||||||
formPromise: Promise<ApiKeyResponse>;
|
selector: "app-api-key",
|
||||||
|
templateUrl: "api-key.component.html",
|
||||||
|
})
|
||||||
|
export class ApiKeyComponent {
|
||||||
clientId: string;
|
clientId: string;
|
||||||
clientSecret: string;
|
clientSecret: string;
|
||||||
|
|
||||||
|
formGroup = this.formBuilder.group({
|
||||||
|
masterPassword: [null as Verification, [Validators.required]],
|
||||||
|
});
|
||||||
constructor(
|
constructor(
|
||||||
|
@Inject(DIALOG_DATA) protected data: ApiKeyDialogData,
|
||||||
|
private formBuilder: FormBuilder,
|
||||||
private userVerificationService: UserVerificationService,
|
private userVerificationService: UserVerificationService,
|
||||||
private logService: LogService,
|
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async submit() {
|
submit = async () => {
|
||||||
try {
|
if (this.formGroup.invalid) {
|
||||||
this.formPromise = this.userVerificationService
|
this.formGroup.markAllAsTouched();
|
||||||
.buildRequest(this.masterPassword)
|
return;
|
||||||
.then((request) => this.postKey(this.entityId, request));
|
|
||||||
const response = await this.formPromise;
|
|
||||||
this.clientSecret = response.apiKey;
|
|
||||||
this.clientId = `${this.keyType}.${this.entityId}`;
|
|
||||||
} catch (e) {
|
|
||||||
this.logService.error(e);
|
|
||||||
}
|
}
|
||||||
}
|
const response = await this.userVerificationService
|
||||||
|
.buildRequest(this.formGroup.value.masterPassword)
|
||||||
|
.then((request) => this.data.postKey(this.data.entityId, request));
|
||||||
|
this.clientSecret = response.apiKey;
|
||||||
|
this.clientId = `${this.data.keyType}.${this.data.entityId}`;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Strongly typed helper to open a ApiKeyComponent
|
||||||
|
* @param dialogService Instance of the dialog service that will be used to open the dialog
|
||||||
|
* @param config Configuration for the dialog
|
||||||
|
*/
|
||||||
|
static open = (dialogService: DialogService, config: DialogConfig<ApiKeyDialogData>) => {
|
||||||
|
return dialogService.open(ApiKeyComponent, config);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { Component, OnInit, ViewChild, ViewContainerRef } from "@angular/core";
|
import { Component, OnInit, ViewChild, ViewContainerRef } from "@angular/core";
|
||||||
|
|
||||||
import { ModalService } from "@bitwarden/angular/services/modal.service";
|
|
||||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||||
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
|
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
|
||||||
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
|
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
|
||||||
|
import { DialogService } from "@bitwarden/components";
|
||||||
|
|
||||||
import { ApiKeyComponent } from "./api-key.component";
|
import { ApiKeyComponent } from "./api-key.component";
|
||||||
|
|
||||||
|
@ -22,8 +22,8 @@ export class SecurityKeysComponent implements OnInit {
|
||||||
constructor(
|
constructor(
|
||||||
private userVerificationService: UserVerificationService,
|
private userVerificationService: UserVerificationService,
|
||||||
private stateService: StateService,
|
private stateService: StateService,
|
||||||
private modalService: ModalService,
|
|
||||||
private apiService: ApiService,
|
private apiService: ApiService,
|
||||||
|
private dialogService: DialogService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
|
@ -32,30 +32,34 @@ export class SecurityKeysComponent implements OnInit {
|
||||||
|
|
||||||
async viewUserApiKey() {
|
async viewUserApiKey() {
|
||||||
const entityId = await this.stateService.getUserId();
|
const entityId = await this.stateService.getUserId();
|
||||||
await this.modalService.openViewRef(ApiKeyComponent, this.viewUserApiKeyModalRef, (comp) => {
|
await ApiKeyComponent.open(this.dialogService, {
|
||||||
comp.keyType = "user";
|
data: {
|
||||||
comp.entityId = entityId;
|
keyType: "user",
|
||||||
comp.postKey = this.apiService.postUserApiKey.bind(this.apiService);
|
entityId: entityId,
|
||||||
comp.scope = "api";
|
postKey: this.apiService.postUserApiKey.bind(this.apiService),
|
||||||
comp.grantType = "client_credentials";
|
scope: "api",
|
||||||
comp.apiKeyTitle = "apiKey";
|
grantType: "client_credentials",
|
||||||
comp.apiKeyWarning = "userApiKeyWarning";
|
apiKeyTitle: "apiKey",
|
||||||
comp.apiKeyDescription = "userApiKeyDesc";
|
apiKeyWarning: "userApiKeyWarning",
|
||||||
|
apiKeyDescription: "userApiKeyDesc",
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async rotateUserApiKey() {
|
async rotateUserApiKey() {
|
||||||
const entityId = await this.stateService.getUserId();
|
const entityId = await this.stateService.getUserId();
|
||||||
await this.modalService.openViewRef(ApiKeyComponent, this.rotateUserApiKeyModalRef, (comp) => {
|
await ApiKeyComponent.open(this.dialogService, {
|
||||||
comp.keyType = "user";
|
data: {
|
||||||
comp.isRotation = true;
|
keyType: "user",
|
||||||
comp.entityId = entityId;
|
isRotation: true,
|
||||||
comp.postKey = this.apiService.postUserRotateApiKey.bind(this.apiService);
|
entityId: entityId,
|
||||||
comp.scope = "api";
|
postKey: this.apiService.postUserRotateApiKey.bind(this.apiService),
|
||||||
comp.grantType = "client_credentials";
|
scope: "api",
|
||||||
comp.apiKeyTitle = "apiKey";
|
grantType: "client_credentials",
|
||||||
comp.apiKeyWarning = "userApiKeyWarning";
|
apiKeyTitle: "apiKey",
|
||||||
comp.apiKeyDescription = "apiKeyRotateDesc";
|
apiKeyWarning: "userApiKeyWarning",
|
||||||
|
apiKeyDescription: "apiKeyRotateDesc",
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue