mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
101 lines
3.1 KiB
TypeScript
101 lines
3.1 KiB
TypeScript
import { NotificationRecipients } from "@edr/types";
|
|
import { Injectable, Logger } from "@nestjs/common";
|
|
|
|
import { BackofficeService } from "../backoffice/backoffice.service";
|
|
import { CompanyProfileRepository } from "../companies/company-profile.repository";
|
|
import { ExternalProfileRepository } from "../companies/external-profile.repository";
|
|
|
|
/**
|
|
* Turns a {@link NotificationRecipients} selector into a de-duplicated set of
|
|
* IAM user ids.
|
|
*
|
|
* - `userIds` → honored as-is.
|
|
* - `companyId` → all portal users linked to the company (external_profiles).
|
|
* - `companyProfileId` → resolved to its company, then to that company's users.
|
|
* - `organizationId` → all current employees of the org (backoffice staff).
|
|
* - `permissionKeys` → current employees (any org) holding any of these
|
|
* permission keys (e.g. department/role-scoped targeting).
|
|
*/
|
|
@Injectable()
|
|
export class NotificationRecipientsService {
|
|
private readonly logger = new Logger(NotificationRecipientsService.name);
|
|
|
|
constructor(
|
|
private readonly externalProfiles: ExternalProfileRepository,
|
|
private readonly companyProfiles: CompanyProfileRepository,
|
|
private readonly backoffice: BackofficeService,
|
|
) {}
|
|
|
|
async resolve(recipients: NotificationRecipients): Promise<string[]> {
|
|
const ids = new Set<string>();
|
|
|
|
for (const id of recipients.userIds ?? []) {
|
|
if (id) ids.add(id);
|
|
}
|
|
|
|
let companyId = recipients.companyId;
|
|
if (!companyId && recipients.companyProfileId) {
|
|
const profile = await this.companyProfiles.findById(
|
|
recipients.companyProfileId,
|
|
);
|
|
companyId = profile?.companyId ?? undefined;
|
|
}
|
|
if (companyId) {
|
|
const profiles = await this.externalProfiles.findByCompanyId(companyId);
|
|
for (const p of profiles) {
|
|
if (p.userId) ids.add(p.userId);
|
|
}
|
|
}
|
|
|
|
if (recipients.organizationId) {
|
|
try {
|
|
const { items } = await this.backoffice.getOrganizationEmployees(
|
|
recipients.organizationId,
|
|
{},
|
|
);
|
|
for (const employee of items as Array<{
|
|
user?: { id?: string };
|
|
userId?: string;
|
|
}>) {
|
|
const uid = employee?.user?.id ?? employee?.userId;
|
|
if (uid) ids.add(uid);
|
|
}
|
|
} catch (err) {
|
|
this.logger.warn(
|
|
`Failed to resolve org recipients for ${recipients.organizationId}: ${
|
|
(err as Error).message
|
|
}`,
|
|
);
|
|
}
|
|
}
|
|
|
|
if (recipients.allBackoffice) {
|
|
try {
|
|
for (const uid of await this.backoffice.getAllCurrentEmployeeUserIds()) {
|
|
ids.add(uid);
|
|
}
|
|
} catch (err) {
|
|
this.logger.warn(
|
|
`Failed to resolve allBackoffice recipients: ${(err as Error).message}`,
|
|
);
|
|
}
|
|
}
|
|
|
|
if (recipients.permissionKeys?.length) {
|
|
try {
|
|
for (const uid of await this.backoffice.getEmployeeUserIdsByPermission(
|
|
recipients.permissionKeys,
|
|
)) {
|
|
ids.add(uid);
|
|
}
|
|
} catch (err) {
|
|
this.logger.warn(
|
|
`Failed to resolve permissionKeys recipients: ${(err as Error).message}`,
|
|
);
|
|
}
|
|
}
|
|
|
|
return [...ids];
|
|
}
|
|
}
|