mirror of
https://github.com/bitwarden/browser.git
synced 2024-12-21 16:18:28 +01:00
[SM-401] Adding the ability to edit service account name (#4845)
* Adding the ability to edit service account name * Update bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/service-accounts-list.component.html Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com> * Suggested Updates * removing unecessary messages * Adding back messages.json entry, updating API Call * fix * Update bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/service-account.service.ts Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com> * Update bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/models/requests/service-account-update.request.ts Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com> * Update bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/dialog/service-account-dialog.component.ts Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com> * Fixing endpoints after Server side change * changes * updates * adding loading notification * adding description to message * Update bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/service-accounts-list.component.html Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Thomas's suggested changes * reorder list --------- Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com> Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com>
This commit is contained in:
parent
da9210b551
commit
6971c3dca2
@ -5876,6 +5876,10 @@
|
|||||||
"message": "Search service accounts",
|
"message": "Search service accounts",
|
||||||
"description": "Placeholder text for searching service accounts."
|
"description": "Placeholder text for searching service accounts."
|
||||||
},
|
},
|
||||||
|
"editServiceAccount":{
|
||||||
|
"message":"Edit service account",
|
||||||
|
"description" : "Title for editing a service account."
|
||||||
|
},
|
||||||
"addProject": {
|
"addProject": {
|
||||||
"message": "Add project",
|
"message": "Add project",
|
||||||
"description": "Title for creating a new project."
|
"description": "Title for creating a new project."
|
||||||
@ -5933,6 +5937,10 @@
|
|||||||
"message": "Service account created",
|
"message": "Service account created",
|
||||||
"description": "Notifies that a new service account has been created"
|
"description": "Notifies that a new service account has been created"
|
||||||
},
|
},
|
||||||
|
"serviceAccountUpdated": {
|
||||||
|
"message": "Service account updated",
|
||||||
|
"description": "Notifies that a service account has been updated"
|
||||||
|
},
|
||||||
"newSaSelectAccess": {
|
"newSaSelectAccess": {
|
||||||
"message": "Type or select projects or secrets",
|
"message": "Type or select projects or secrets",
|
||||||
"description": "Instructions for selecting projects or secrets for a new service account"
|
"description": "Instructions for selecting projects or secrets for a new service account"
|
||||||
|
@ -225,6 +225,7 @@ export class OverviewComponent implements OnInit, OnDestroy {
|
|||||||
this.dialogService.open<unknown, ServiceAccountOperation>(ServiceAccountDialogComponent, {
|
this.dialogService.open<unknown, ServiceAccountOperation>(ServiceAccountDialogComponent, {
|
||||||
data: {
|
data: {
|
||||||
organizationId: this.organizationId,
|
organizationId: this.organizationId,
|
||||||
|
operation: OperationType.Add,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,17 @@
|
|||||||
<form [formGroup]="formGroup" [bitSubmit]="submit">
|
<form [formGroup]="formGroup" [bitSubmit]="submit">
|
||||||
<bit-dialog dialogSize="small">
|
<bit-dialog dialogSize="small">
|
||||||
<ng-container bitDialogTitle>{{ "newServiceAccount" | i18n }}</ng-container>
|
<ng-container bitDialogTitle>{{ title | i18n }}</ng-container>
|
||||||
<div bitDialogContent>
|
<div bitDialogContent>
|
||||||
|
<div *ngIf="loading" class="tw-text-center">
|
||||||
|
<i class="bwi bwi-spinner bwi-spin bwi-3x"></i>
|
||||||
|
</div>
|
||||||
|
<div *ngIf="!loading">
|
||||||
<bit-form-field>
|
<bit-form-field>
|
||||||
<bit-label>{{ "serviceAccountName" | i18n }}</bit-label>
|
<bit-label>{{ "serviceAccountName" | i18n }}</bit-label>
|
||||||
<input formControlName="name" bitInput />
|
<input formControlName="name" maxlength="1000" bitInput />
|
||||||
</bit-form-field>
|
</bit-form-field>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<div bitDialogFooter class="tw-flex tw-gap-2">
|
<div bitDialogFooter class="tw-flex tw-gap-2">
|
||||||
<button type="submit" bitButton buttonType="primary" bitFormButton>
|
<button type="submit" bitButton buttonType="primary" bitFormButton>
|
||||||
{{ "save" | i18n }}
|
{{ "save" | i18n }}
|
||||||
|
@ -8,8 +8,15 @@ import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUti
|
|||||||
import { ServiceAccountView } from "../../models/view/service-account.view";
|
import { ServiceAccountView } from "../../models/view/service-account.view";
|
||||||
import { ServiceAccountService } from "../service-account.service";
|
import { ServiceAccountService } from "../service-account.service";
|
||||||
|
|
||||||
|
export enum OperationType {
|
||||||
|
Add,
|
||||||
|
Edit,
|
||||||
|
}
|
||||||
|
|
||||||
export interface ServiceAccountOperation {
|
export interface ServiceAccountOperation {
|
||||||
organizationId: string;
|
organizationId: string;
|
||||||
|
serviceAccountId?: string;
|
||||||
|
operation: OperationType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -21,6 +28,8 @@ export class ServiceAccountDialogComponent {
|
|||||||
name: new FormControl("", [Validators.required]),
|
name: new FormControl("", [Validators.required]),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
protected loading = false;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public dialogRef: DialogRef,
|
public dialogRef: DialogRef,
|
||||||
@Inject(DIALOG_DATA) private data: ServiceAccountOperation,
|
@Inject(DIALOG_DATA) private data: ServiceAccountOperation,
|
||||||
@ -29,6 +38,23 @@ export class ServiceAccountDialogComponent {
|
|||||||
private platformUtilsService: PlatformUtilsService
|
private platformUtilsService: PlatformUtilsService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
async ngOnInit() {
|
||||||
|
if (this.data.operation == OperationType.Edit) {
|
||||||
|
this.loadData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async loadData() {
|
||||||
|
this.loading = true;
|
||||||
|
const serviceAccount: ServiceAccountView =
|
||||||
|
await this.serviceAccountService.getByServiceAccountId(
|
||||||
|
this.data.serviceAccountId,
|
||||||
|
this.data.organizationId
|
||||||
|
);
|
||||||
|
this.formGroup.patchValue({ name: serviceAccount.name });
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
|
||||||
submit = async () => {
|
submit = async () => {
|
||||||
this.formGroup.markAllAsTouched();
|
this.formGroup.markAllAsTouched();
|
||||||
|
|
||||||
@ -37,12 +63,21 @@ export class ServiceAccountDialogComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const serviceAccountView = this.getServiceAccountView();
|
const serviceAccountView = this.getServiceAccountView();
|
||||||
|
let serviceAccountMessage: string;
|
||||||
|
|
||||||
|
if (this.data.operation == OperationType.Add) {
|
||||||
await this.serviceAccountService.create(this.data.organizationId, serviceAccountView);
|
await this.serviceAccountService.create(this.data.organizationId, serviceAccountView);
|
||||||
this.platformUtilsService.showToast(
|
serviceAccountMessage = this.i18nService.t("serviceAccountCreated");
|
||||||
"success",
|
} else {
|
||||||
null,
|
await this.serviceAccountService.update(
|
||||||
this.i18nService.t("serviceAccountCreated")
|
this.data.serviceAccountId,
|
||||||
|
this.data.organizationId,
|
||||||
|
serviceAccountView
|
||||||
);
|
);
|
||||||
|
serviceAccountMessage = this.i18nService.t("serviceAccountUpdated");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.platformUtilsService.showToast("success", null, serviceAccountMessage);
|
||||||
this.dialogRef.close();
|
this.dialogRef.close();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -52,4 +87,8 @@ export class ServiceAccountDialogComponent {
|
|||||||
serviceAccountView.name = this.formGroup.value.name;
|
serviceAccountView.name = this.formGroup.value.name;
|
||||||
return serviceAccountView;
|
return serviceAccountView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get title() {
|
||||||
|
return this.data.operation === OperationType.Add ? "newServiceAccount" : "editServiceAccount";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,41 @@ export class ServiceAccountService {
|
|||||||
return await this.createServiceAccountViews(organizationId, results.data);
|
return await this.createServiceAccountViews(organizationId, results.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getByServiceAccountId(
|
||||||
|
serviceAccountId: string,
|
||||||
|
organizationId: string
|
||||||
|
): Promise<ServiceAccountView> {
|
||||||
|
const orgKey = await this.getOrganizationKey(organizationId);
|
||||||
|
const r = await this.apiService.send(
|
||||||
|
"GET",
|
||||||
|
"/service-accounts/" + serviceAccountId,
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
return await this.createServiceAccountView(orgKey, new ServiceAccountResponse(r));
|
||||||
|
}
|
||||||
|
|
||||||
|
async update(
|
||||||
|
serviceAccountId: string,
|
||||||
|
organizationId: string,
|
||||||
|
serviceAccountView: ServiceAccountView
|
||||||
|
) {
|
||||||
|
const orgKey = await this.getOrganizationKey(organizationId);
|
||||||
|
const request = await this.getServiceAccountRequest(orgKey, serviceAccountView);
|
||||||
|
const r = await this.apiService.send(
|
||||||
|
"PUT",
|
||||||
|
"/service-accounts/" + serviceAccountId,
|
||||||
|
request,
|
||||||
|
true,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
this._serviceAccount.next(
|
||||||
|
await this.createServiceAccountView(orgKey, new ServiceAccountResponse(r))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
async create(organizationId: string, serviceAccountView: ServiceAccountView) {
|
async create(organizationId: string, serviceAccountView: ServiceAccountView) {
|
||||||
const orgKey = await this.getOrganizationKey(organizationId);
|
const orgKey = await this.getOrganizationKey(organizationId);
|
||||||
const request = await this.getServiceAccountRequest(orgKey, serviceAccountView);
|
const request = await this.getServiceAccountRequest(orgKey, serviceAccountView);
|
||||||
|
@ -83,6 +83,10 @@
|
|||||||
<i class="bwi bwi-fw bwi-eye" aria-hidden="true"></i>
|
<i class="bwi bwi-fw bwi-eye" aria-hidden="true"></i>
|
||||||
{{ "viewServiceAccount" | i18n }}
|
{{ "viewServiceAccount" | i18n }}
|
||||||
</a>
|
</a>
|
||||||
|
<button type="button" bitMenuItem (click)="editServiceAccountEvent.emit(serviceAccount.id)">
|
||||||
|
<i class="bwi bwi-fw bwi-pencil" aria-hidden="true"></i>
|
||||||
|
{{ "editServiceAccount" | i18n }}
|
||||||
|
</button>
|
||||||
<button type="button" bitMenuItem (click)="delete(serviceAccount)">
|
<button type="button" bitMenuItem (click)="delete(serviceAccount)">
|
||||||
<i class="bwi bwi-fw bwi-trash tw-text-danger" aria-hidden="true"></i>
|
<i class="bwi bwi-fw bwi-trash tw-text-danger" aria-hidden="true"></i>
|
||||||
<span class="tw-text-danger">
|
<span class="tw-text-danger">
|
||||||
|
@ -32,6 +32,7 @@ export class ServiceAccountsListComponent implements OnDestroy {
|
|||||||
@Output() newServiceAccountEvent = new EventEmitter();
|
@Output() newServiceAccountEvent = new EventEmitter();
|
||||||
@Output() deleteServiceAccountsEvent = new EventEmitter<ServiceAccountView[]>();
|
@Output() deleteServiceAccountsEvent = new EventEmitter<ServiceAccountView[]>();
|
||||||
@Output() onServiceAccountCheckedEvent = new EventEmitter<string[]>();
|
@Output() onServiceAccountCheckedEvent = new EventEmitter<string[]>();
|
||||||
|
@Output() editServiceAccountEvent = new EventEmitter<string>();
|
||||||
|
|
||||||
private destroy$: Subject<void> = new Subject<void>();
|
private destroy$: Subject<void> = new Subject<void>();
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
<sm-service-accounts-list
|
<sm-service-accounts-list
|
||||||
[serviceAccounts]="serviceAccounts$ | async"
|
[serviceAccounts]="serviceAccounts$ | async"
|
||||||
(newServiceAccountEvent)="openNewServiceAccountDialog()"
|
(newServiceAccountEvent)="openNewServiceAccountDialog()"
|
||||||
|
(editServiceAccountEvent)="openEditServiceAccountDialog($event)"
|
||||||
(deleteServiceAccountsEvent)="openDeleteDialog($event)"
|
(deleteServiceAccountsEvent)="openDeleteDialog($event)"
|
||||||
[search]="search"
|
[search]="search"
|
||||||
></sm-service-accounts-list>
|
></sm-service-accounts-list>
|
||||||
|
@ -12,6 +12,7 @@ import {
|
|||||||
ServiceAccountDeleteOperation,
|
ServiceAccountDeleteOperation,
|
||||||
} from "./dialog/service-account-delete-dialog.component";
|
} from "./dialog/service-account-delete-dialog.component";
|
||||||
import {
|
import {
|
||||||
|
OperationType,
|
||||||
ServiceAccountDialogComponent,
|
ServiceAccountDialogComponent,
|
||||||
ServiceAccountOperation,
|
ServiceAccountOperation,
|
||||||
} from "./dialog/service-account-dialog.component";
|
} from "./dialog/service-account-dialog.component";
|
||||||
@ -51,6 +52,17 @@ export class ServiceAccountsComponent implements OnInit {
|
|||||||
this.dialogService.open<unknown, ServiceAccountOperation>(ServiceAccountDialogComponent, {
|
this.dialogService.open<unknown, ServiceAccountOperation>(ServiceAccountDialogComponent, {
|
||||||
data: {
|
data: {
|
||||||
organizationId: this.organizationId,
|
organizationId: this.organizationId,
|
||||||
|
operation: OperationType.Add,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
openEditServiceAccountDialog(serviceAccountId: string) {
|
||||||
|
this.dialogService.open<unknown, ServiceAccountOperation>(ServiceAccountDialogComponent, {
|
||||||
|
data: {
|
||||||
|
organizationId: this.organizationId,
|
||||||
|
serviceAccountId: serviceAccountId,
|
||||||
|
operation: OperationType.Edit,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -61,6 +61,7 @@ export class NewMenuComponent implements OnInit, OnDestroy {
|
|||||||
this.dialogService.open<unknown, ServiceAccountOperation>(ServiceAccountDialogComponent, {
|
this.dialogService.open<unknown, ServiceAccountOperation>(ServiceAccountDialogComponent, {
|
||||||
data: {
|
data: {
|
||||||
organizationId: this.organizationId,
|
organizationId: this.organizationId,
|
||||||
|
operation: OperationType.Add,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user