1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-06 19:53:59 +00:00

PM-23264 Show cipher name instead of short id

This commit is contained in:
voommen-livefront
2025-07-09 12:41:14 -05:00
parent 3da58e1752
commit 08e2a1452a
8 changed files with 83 additions and 6 deletions

View File

@@ -10,6 +10,7 @@ import { FileDownloadService } from "@bitwarden/common/platform/abstractions/fil
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { OrganizationId, UserId } from "@bitwarden/common/types/guid";
import { ToastService } from "@bitwarden/components";
import { EventService } from "../../core";
@@ -24,6 +25,8 @@ export abstract class BaseEventsComponent {
continuationToken: string;
abstract readonly exportFileName: string;
abstract organizationId: OrganizationId;
abstract userId: UserId;
protected eventsForm = new FormGroup({
start: new FormControl(null),
@@ -134,6 +137,7 @@ export abstract class BaseEventsComponent {
endDate: string,
continuationToken: string,
) {
await this.eventService.loadAllOrganizationCiphers(this.organizationId, this.userId);
const response = await this.requestEvents(startDate, endDate, continuationToken);
const events = await Promise.all(
@@ -157,6 +161,8 @@ export abstract class BaseEventsComponent {
installationId: r.installationId,
systemUser: r.systemUser,
serviceAccountId: r.serviceAccountId,
eventName: eventInfo.eventName,
eventLink: eventInfo.eventLink,
});
}),
);

View File

@@ -195,6 +195,8 @@ export class EntityEventsComponent implements OnInit, OnDestroy {
installationId: r.installationId,
systemUser: r.systemUser,
serviceAccountId: r.serviceAccountId,
eventName: eventInfo.eventName,
eventLink: eventInfo.eventLink,
});
}),
);

View File

@@ -100,7 +100,11 @@
<td bitCell>
<span title="{{ e.userEmail }}">{{ e.userName }}</span>
</td>
<td bitCell [innerHTML]="e.message"></td>
<td bitCell *ngIf="e.eventName && e.eventLink">
<span>{{ e.eventName }}</span
><br /><span [innerHtml]="e.eventLink"></span>
</td>
<td bitCell *ngIf="!(e.eventName && e.eventLink)" [innerHTML]="e.message"></td>
</tr>
</ng-template>
</bit-table>

View File

@@ -27,6 +27,7 @@ import { FileDownloadService } from "@bitwarden/common/platform/abstractions/fil
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { OrganizationId, UserId } from "@bitwarden/common/types/guid";
import { DialogService, ToastService } from "@bitwarden/components";
import {
@@ -52,9 +53,10 @@ const EVENT_SYSTEM_USER_TO_TRANSLATION: Record<EventSystemUser, string> = {
})
export class EventsComponent extends BaseEventsComponent implements OnInit, OnDestroy {
exportFileName = "org-events";
organizationId: string;
organizationId: OrganizationId;
organization: Organization;
organizationSubscription: OrganizationSubscriptionResponse;
userId: UserId;
placeholderEvents = placeholderEvents as EventView[];
@@ -99,14 +101,14 @@ export class EventsComponent extends BaseEventsComponent implements OnInit, OnDe
}
async ngOnInit() {
const userId = await firstValueFrom(getUserId(this.accountService.activeAccount$));
this.userId = await firstValueFrom(getUserId(this.accountService.activeAccount$));
this.route.params
.pipe(
concatMap(async (params) => {
this.organizationId = params.organizationId;
this.organization = await firstValueFrom(
this.organizationService
.organizations$(userId)
.organizations$(this.userId)
.pipe(getOrganizationById(this.organizationId)),
);

View File

@@ -11,15 +11,21 @@ import { getUserId } from "@bitwarden/common/auth/services/account.service";
import { DeviceType, EventType } from "@bitwarden/common/enums";
import { EventResponse } from "@bitwarden/common/models/response/event.response";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { OrganizationId, UserId } from "@bitwarden/common/types/guid";
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
@Injectable()
export class EventService {
private policies: Policy[];
private organizationCiphers: CipherView[] = [];
private ciphers: CipherView[] = [];
constructor(
private i18nService: I18nService,
policyService: PolicyService,
accountService: AccountService,
private cipherService: CipherService,
) {
accountService.activeAccount$
.pipe(
@@ -48,20 +54,39 @@ export class EventService {
return [start.toISOString(), end.toISOString()];
}
async loadAllOrganizationCiphers(organizationId: OrganizationId, userId: UserId) {
// this.organizationCiphers =
// await this.cipherService.getAllFromApiForOrganization(organizationId);
this.ciphers = await this.cipherService.getAllDecrypted(userId);
}
async getEventInfo(ev: EventResponse, options = new EventOptions()): Promise<EventInfo> {
const appInfo = this.getAppInfo(ev);
const { message, humanReadableMessage } = await this.getEventMessage(ev, options);
// const cv = this.organizationCiphers.find((c) => c.id === ev.cipherId);
const cv = this.ciphers.find((c) => c.id === ev.cipherId);
options.cipher = cv;
options.useCipherName = !!cv;
const { message, humanReadableMessage, eventName, eventLink } = await this.getEventMessage(
ev,
options,
);
return {
message: message,
humanReadableMessage: humanReadableMessage,
appIcon: appInfo[0],
appName: appInfo[1],
eventName: eventName.replace(".", ""),
eventLink,
};
}
private async getEventMessage(ev: EventResponse, options: EventOptions) {
let msg = "";
let humanReadableMsg = "";
let eventName = "";
const eventLink = ev.cipherId ? this.formatCipherId(ev, options) : "";
switch (ev.type) {
// User
case EventType.User_LoggedIn:
@@ -104,10 +129,12 @@ export class EventService {
case EventType.Cipher_Created:
msg = this.i18nService.t("createdItemId", this.formatCipherId(ev, options));
humanReadableMsg = this.i18nService.t("createdItemId", this.getShortId(ev.cipherId));
eventName = this.i18nService.t("createdItemId", "");
break;
case EventType.Cipher_Updated:
msg = this.i18nService.t("editedItemId", this.formatCipherId(ev, options));
humanReadableMsg = this.i18nService.t("editedItemId", this.getShortId(ev.cipherId));
eventName = this.i18nService.t("editedItemId", "");
break;
case EventType.Cipher_Deleted:
msg = this.i18nService.t("permanentlyDeletedItemId", this.formatCipherId(ev, options));
@@ -115,6 +142,7 @@ export class EventService {
"permanentlyDeletedItemId",
this.getShortId(ev.cipherId),
);
eventName = this.i18nService.t("permanentlyDeletedItemId", "");
break;
case EventType.Cipher_SoftDeleted:
msg = this.i18nService.t("deletedItemId", this.formatCipherId(ev, options));
@@ -123,6 +151,7 @@ export class EventService {
case EventType.Cipher_Restored:
msg = this.i18nService.t("restoredItemId", this.formatCipherId(ev, options));
humanReadableMsg = this.i18nService.t("restoredItemId", this.formatCipherId(ev, options));
eventName = this.i18nService.t("restoredItemId", "");
break;
case EventType.Cipher_AttachmentCreated:
msg = this.i18nService.t("createdAttachmentForItem", this.formatCipherId(ev, options));
@@ -130,6 +159,7 @@ export class EventService {
"createdAttachmentForItem",
this.getShortId(ev.cipherId),
);
eventName = this.i18nService.t("createdAttachmentForItem", "");
break;
case EventType.Cipher_AttachmentDeleted:
msg = this.i18nService.t("deletedAttachmentForItem", this.formatCipherId(ev, options));
@@ -137,18 +167,22 @@ export class EventService {
"deletedAttachmentForItem",
this.getShortId(ev.cipherId),
);
eventName = this.i18nService.t("deletedAttachmentForItem", "");
break;
case EventType.Cipher_Shared:
msg = this.i18nService.t("movedItemIdToOrg", this.formatCipherId(ev, options));
humanReadableMsg = this.i18nService.t("movedItemIdToOrg", this.getShortId(ev.cipherId));
eventName = this.i18nService.t("movedItemIdToOrg", "");
break;
case EventType.Cipher_ClientViewed:
msg = this.i18nService.t("viewedItemId", this.formatCipherId(ev, options));
humanReadableMsg = this.i18nService.t("viewedItemId", this.getShortId(ev.cipherId));
eventName = this.i18nService.t("viewedItemId", "");
break;
case EventType.Cipher_ClientToggledPasswordVisible:
msg = this.i18nService.t("viewedPasswordItemId", this.formatCipherId(ev, options));
humanReadableMsg = this.i18nService.t("viewedPasswordItemId", this.getShortId(ev.cipherId));
eventName = this.i18nService.t("viewedPasswordItemId", "");
break;
case EventType.Cipher_ClientToggledHiddenFieldVisible:
msg = this.i18nService.t("viewedHiddenFieldItemId", this.formatCipherId(ev, options));
@@ -156,6 +190,7 @@ export class EventService {
"viewedHiddenFieldItemId",
this.getShortId(ev.cipherId),
);
eventName = this.i18nService.t("viewedHiddenFieldItemId", "");
break;
case EventType.Cipher_ClientToggledCardNumberVisible:
msg = this.i18nService.t("viewedCardNumberItemId", this.formatCipherId(ev, options));
@@ -163,6 +198,7 @@ export class EventService {
"viewedCardNumberItemId",
this.getShortId(ev.cipherId),
);
eventName = this.i18nService.t("viewedCardNumberItemId", "");
break;
case EventType.Cipher_ClientToggledCardCodeVisible:
msg = this.i18nService.t("viewedSecurityCodeItemId", this.formatCipherId(ev, options));
@@ -170,6 +206,7 @@ export class EventService {
"viewedSecurityCodeItemId",
this.getShortId(ev.cipherId),
);
eventName = this.i18nService.t("viewedSecurityCodeItemId", "");
break;
case EventType.Cipher_ClientCopiedHiddenField:
msg = this.i18nService.t("copiedHiddenFieldItemId", this.formatCipherId(ev, options));
@@ -177,10 +214,12 @@ export class EventService {
"copiedHiddenFieldItemId",
this.getShortId(ev.cipherId),
);
eventName = this.i18nService.t("copiedHiddenFieldItemId", "");
break;
case EventType.Cipher_ClientCopiedPassword:
msg = this.i18nService.t("copiedPasswordItemId", this.formatCipherId(ev, options));
humanReadableMsg = this.i18nService.t("copiedPasswordItemId", this.getShortId(ev.cipherId));
eventName = this.i18nService.t("copiedPasswordItemId", "");
break;
case EventType.Cipher_ClientCopiedCardCode:
msg = this.i18nService.t("copiedSecurityCodeItemId", this.formatCipherId(ev, options));
@@ -188,10 +227,12 @@ export class EventService {
"copiedSecurityCodeItemId",
this.getShortId(ev.cipherId),
);
eventName = this.i18nService.t("copiedSecurityCodeItemId", "");
break;
case EventType.Cipher_ClientAutofilled:
msg = this.i18nService.t("autofilledItemId", this.formatCipherId(ev, options));
humanReadableMsg = this.i18nService.t("autofilledItemId", this.getShortId(ev.cipherId));
eventName = this.i18nService.t("autofilledItemId", "");
break;
case EventType.Cipher_UpdatedCollections:
msg = this.i18nService.t("editedCollectionsForItem", this.formatCipherId(ev, options));
@@ -199,6 +240,7 @@ export class EventService {
"editedCollectionsForItem",
this.getShortId(ev.cipherId),
);
eventName = this.i18nService.t("editedCollectionsForItem", "");
break;
// Collection
case EventType.Collection_Created:
@@ -488,6 +530,8 @@ export class EventService {
return {
message: msg === "" ? null : msg,
humanReadableMessage: humanReadableMsg === "" ? null : humanReadableMsg,
eventName: eventName,
eventLink: eventLink,
};
}
@@ -558,7 +602,12 @@ export class EventService {
if (ev.organizationId == null || !options.cipherInfo) {
return "<code>" + shortId + "</code>";
}
const a = this.makeAnchor(shortId);
const anchorName =
options.useCipherName && options.cipher && options.cipher.name
? options.cipher.name
: shortId;
const a = this.makeAnchor(anchorName);
a.setAttribute(
"href",
`#/organizations/${ev.organizationId}/vault?search=${shortId}&viewEvents=${ev.cipherId}&type=all`,
@@ -680,8 +729,12 @@ export class EventInfo {
humanReadableMessage: string;
appIcon: string;
appName: string;
eventName: string;
eventLink: string;
}
export class EventOptions {
cipherInfo = true;
useCipherName = false;
cipher: CipherView | null = null;
}

View File

@@ -11,6 +11,7 @@ import { FileDownloadService } from "@bitwarden/common/platform/abstractions/fil
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { OrganizationId, UserId } from "@bitwarden/common/types/guid";
import { ToastService } from "@bitwarden/components";
import { BaseEventsComponent } from "@bitwarden/web-vault/app/admin-console/common/base.events.component";
import { EventService } from "@bitwarden/web-vault/app/core";
@@ -22,6 +23,8 @@ import { EventExportService } from "@bitwarden/web-vault/app/tools/event-export"
standalone: false,
})
export class EventsComponent extends BaseEventsComponent implements OnInit {
organizationId: OrganizationId;
userId: UserId;
exportFileName = "provider-events";
providerId: string;

View File

@@ -8,6 +8,7 @@ import { FileDownloadService } from "@bitwarden/common/platform/abstractions/fil
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { OrganizationId, UserId } from "@bitwarden/common/types/guid";
import { ToastService } from "@bitwarden/components";
import { BaseEventsComponent } from "@bitwarden/web-vault/app/admin-console/common/base.events.component";
import { EventService } from "@bitwarden/web-vault/app/core";
@@ -24,6 +25,8 @@ export class ServiceAccountEventsComponent
extends BaseEventsComponent
implements OnInit, OnDestroy
{
organizationId: OrganizationId;
userId: UserId;
exportFileName = "machine-account-events";
private destroy$ = new Subject<void>();
private serviceAccountId: string;

View File

@@ -14,6 +14,8 @@ export class EventView {
installationId: string;
systemUser: EventSystemUser;
serviceAccountId: string;
eventName: string;
eventLink: string;
constructor(data: Required<EventView>) {
this.message = data.message;
@@ -29,5 +31,7 @@ export class EventView {
this.installationId = data.installationId;
this.systemUser = data.systemUser;
this.serviceAccountId = data.serviceAccountId;
this.eventName = data.eventName;
this.eventLink = data.eventLink;
}
}