mirror of
https://github.com/bitwarden/browser
synced 2025-12-11 13:53:34 +00:00
[SM-574] Hide edit/delete when user only has read access (#4941)
* Hide edit/delete when user only has read access * Wire up read/write for secret response * Remove variable * Resolve changes after merge * SM-671: Fix small bug in sm/SM-574 branch to pass secret instead of secret id on deletion (#5096) --------- Co-authored-by: Colton Hurst <colton@coltonhurst.com>
This commit is contained in:
@@ -7,4 +7,6 @@ export class SecretListView {
|
|||||||
creationDate: string;
|
creationDate: string;
|
||||||
revisionDate: string;
|
revisionDate: string;
|
||||||
projects: SecretProjectView[];
|
projects: SecretProjectView[];
|
||||||
|
read: boolean;
|
||||||
|
write: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,4 +9,7 @@ export class SecretView {
|
|||||||
creationDate: string;
|
creationDate: string;
|
||||||
revisionDate: string;
|
revisionDate: string;
|
||||||
projects: SecretProjectView[];
|
projects: SecretProjectView[];
|
||||||
|
|
||||||
|
read: boolean;
|
||||||
|
write: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,14 @@
|
|||||||
<button type="submit" bitButton buttonType="primary" bitFormButton>
|
<button type="submit" bitButton buttonType="primary" bitFormButton>
|
||||||
{{ "save" | i18n }}
|
{{ "save" | i18n }}
|
||||||
</button>
|
</button>
|
||||||
<button type="button" bitButton buttonType="secondary" bitFormButton bitDialogClose>
|
<button
|
||||||
|
type="button"
|
||||||
|
bitButton
|
||||||
|
buttonType="secondary"
|
||||||
|
bitFormButton
|
||||||
|
bitDialogClose
|
||||||
|
[disabled]="false"
|
||||||
|
>
|
||||||
{{ "cancel" | i18n }}
|
{{ "cancel" | i18n }}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ export class SecretDialogComponent implements OnInit {
|
|||||||
projects: ProjectListView[];
|
projects: ProjectListView[];
|
||||||
|
|
||||||
private destroy$ = new Subject<void>();
|
private destroy$ = new Subject<void>();
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public dialogRef: DialogRef,
|
public dialogRef: DialogRef,
|
||||||
@Inject(DIALOG_DATA) private data: SecretOperation,
|
@Inject(DIALOG_DATA) private data: SecretOperation,
|
||||||
@@ -80,8 +81,12 @@ export class SecretDialogComponent implements OnInit {
|
|||||||
notes: secret.note,
|
notes: secret.note,
|
||||||
project: secret.projects[0]?.id ?? "",
|
project: secret.projects[0]?.id ?? "",
|
||||||
});
|
});
|
||||||
|
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
this.formGroup.enable();
|
|
||||||
|
if (secret.write) {
|
||||||
|
this.formGroup.enable();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy(): void {
|
ngOnDestroy(): void {
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ export class SecretListItemResponse extends BaseResponse {
|
|||||||
creationDate: string;
|
creationDate: string;
|
||||||
revisionDate: string;
|
revisionDate: string;
|
||||||
projects: SecretProjectResponse[];
|
projects: SecretProjectResponse[];
|
||||||
|
read: boolean;
|
||||||
|
write: boolean;
|
||||||
|
|
||||||
constructor(response: any) {
|
constructor(response: any) {
|
||||||
super(response);
|
super(response);
|
||||||
@@ -17,6 +19,8 @@ export class SecretListItemResponse extends BaseResponse {
|
|||||||
this.name = this.getResponseProperty("Key");
|
this.name = this.getResponseProperty("Key");
|
||||||
this.creationDate = this.getResponseProperty("CreationDate");
|
this.creationDate = this.getResponseProperty("CreationDate");
|
||||||
this.revisionDate = this.getResponseProperty("RevisionDate");
|
this.revisionDate = this.getResponseProperty("RevisionDate");
|
||||||
|
this.read = this.getResponseProperty("Read");
|
||||||
|
this.write = this.getResponseProperty("Write");
|
||||||
|
|
||||||
const project = this.getResponseProperty("projects");
|
const project = this.getResponseProperty("projects");
|
||||||
this.projects = project == null ? null : project.map((k: any) => new SecretProjectResponse(k));
|
this.projects = project == null ? null : project.map((k: any) => new SecretProjectResponse(k));
|
||||||
|
|||||||
@@ -10,6 +10,10 @@ export class SecretResponse extends BaseResponse {
|
|||||||
note: string;
|
note: string;
|
||||||
creationDate: string;
|
creationDate: string;
|
||||||
revisionDate: string;
|
revisionDate: string;
|
||||||
|
|
||||||
|
read: boolean;
|
||||||
|
write: boolean;
|
||||||
|
|
||||||
projects: SecretProjectResponse[];
|
projects: SecretProjectResponse[];
|
||||||
|
|
||||||
constructor(response: any) {
|
constructor(response: any) {
|
||||||
@@ -22,6 +26,9 @@ export class SecretResponse extends BaseResponse {
|
|||||||
this.creationDate = this.getResponseProperty("CreationDate");
|
this.creationDate = this.getResponseProperty("CreationDate");
|
||||||
this.revisionDate = this.getResponseProperty("RevisionDate");
|
this.revisionDate = this.getResponseProperty("RevisionDate");
|
||||||
|
|
||||||
|
this.read = this.getResponseProperty("Read");
|
||||||
|
this.write = this.getResponseProperty("Write");
|
||||||
|
|
||||||
const projects = this.getResponseProperty("Projects");
|
const projects = this.getResponseProperty("Projects");
|
||||||
this.projects =
|
this.projects =
|
||||||
projects == null ? null : projects.map((k: any) => new SecretProjectResponse(k));
|
projects == null ? null : projects.map((k: any) => new SecretProjectResponse(k));
|
||||||
|
|||||||
@@ -176,6 +176,9 @@ export class SecretService {
|
|||||||
secretView.value = value;
|
secretView.value = value;
|
||||||
secretView.note = note;
|
secretView.note = note;
|
||||||
|
|
||||||
|
secretView.read = secretResponse.read;
|
||||||
|
secretView.write = secretResponse.write;
|
||||||
|
|
||||||
if (secretResponse.projects != null) {
|
if (secretResponse.projects != null) {
|
||||||
secretView.projects = await this.decryptProjectsMappedToSecrets(
|
secretView.projects = await this.decryptProjectsMappedToSecrets(
|
||||||
orgKey,
|
orgKey,
|
||||||
@@ -214,6 +217,9 @@ export class SecretService {
|
|||||||
projectIds.includes(p.id)
|
projectIds.includes(p.id)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
secretListView.read = s.read;
|
||||||
|
secretListView.write = s.write;
|
||||||
|
|
||||||
return secretListView;
|
return secretListView;
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -98,7 +98,12 @@
|
|||||||
</td>
|
</td>
|
||||||
|
|
||||||
<bit-menu #secretMenu>
|
<bit-menu #secretMenu>
|
||||||
<button type="button" bitMenuItem (click)="editSecretEvent.emit(secret.id)" *ngIf="!trash">
|
<button
|
||||||
|
type="button"
|
||||||
|
bitMenuItem
|
||||||
|
(click)="editSecretEvent.emit(secret.id)"
|
||||||
|
*ngIf="secret.write && !trash"
|
||||||
|
>
|
||||||
<i class="bwi bwi-fw bwi-pencil" aria-hidden="true"></i>
|
<i class="bwi bwi-fw bwi-pencil" aria-hidden="true"></i>
|
||||||
{{ "editSecret" | i18n }}
|
{{ "editSecret" | i18n }}
|
||||||
</button>
|
</button>
|
||||||
@@ -129,7 +134,12 @@
|
|||||||
<i class="bwi bwi-fw bwi-refresh" aria-hidden="true"></i>
|
<i class="bwi bwi-fw bwi-refresh" aria-hidden="true"></i>
|
||||||
{{ "restoreSecret" | i18n }}
|
{{ "restoreSecret" | i18n }}
|
||||||
</button>
|
</button>
|
||||||
<button type="button" bitMenuItem (click)="deleteSecretsEvent.emit([secret])">
|
<button
|
||||||
|
type="button"
|
||||||
|
bitMenuItem
|
||||||
|
(click)="deleteSecretsEvent.emit([secret])"
|
||||||
|
*ngIf="secret.write"
|
||||||
|
>
|
||||||
<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">{{
|
||||||
(trash ? "permanentlyDelete" : "deleteSecret") | i18n
|
(trash ? "permanentlyDelete" : "deleteSecret") | i18n
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ export class BitFormButtonDirective implements OnDestroy {
|
|||||||
private destroy$ = new Subject<void>();
|
private destroy$ = new Subject<void>();
|
||||||
|
|
||||||
@Input() type: string;
|
@Input() type: string;
|
||||||
|
@Input() disabled?: boolean;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
buttonComponent: ButtonLikeAbstraction,
|
buttonComponent: ButtonLikeAbstraction,
|
||||||
@@ -44,7 +45,9 @@ export class BitFormButtonDirective implements OnDestroy {
|
|||||||
});
|
});
|
||||||
|
|
||||||
submitDirective.disabled$.pipe(takeUntil(this.destroy$)).subscribe((disabled) => {
|
submitDirective.disabled$.pipe(takeUntil(this.destroy$)).subscribe((disabled) => {
|
||||||
buttonComponent.disabled = disabled;
|
if (this.disabled !== false) {
|
||||||
|
buttonComponent.disabled = disabled;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user