src/compliance/compliance.service.ts
Properties |
|
Methods |
constructor(prismaService: PrismaService, temporalProvider: TemporalProvider, complianceRiskService: ComplianceRiskService, settingsService: SettingsService, policyService: PolicyService)
|
||||||||||||||||||
|
Defined in src/compliance/compliance.service.ts:26
|
||||||||||||||||||
|
Parameters :
|
| Async findSubmission | ||||||||
findSubmission(id: number)
|
||||||||
|
Defined in src/compliance/compliance.service.ts:151
|
||||||||
|
Find a compliance submission by id
Parameters :
Returns :
Promise<ComplianceSubmission>
compliance submission |
| Async generateRisks | ||||||||||||
generateRisks(submission: ComplianceSubmission, rules: any[])
|
||||||||||||
|
Defined in src/compliance/compliance.service.ts:183
|
||||||||||||
|
Generate compliance risks for a submission
Parameters :
Returns :
Promise<ComplianceRisk[]>
list of generated risks |
| Async getActiveSubmissionsForPolicy | ||||||
getActiveSubmissionsForPolicy(policyId: number)
|
||||||
|
Defined in src/compliance/compliance.service.ts:251
|
||||||
|
Parameters :
Returns :
Promise<ComplianceSubmission[]>
|
| Async getComplianceUsers | ||||||||
getComplianceUsers(projectId: number)
|
||||||||
|
Defined in src/compliance/compliance.service.ts:94
|
||||||||
|
Get compliance users with permissions
Parameters :
Returns :
Promise<any[]>
list of users with permissions |
| getLatestProjectDependentSubmissions | ||||||
getLatestProjectDependentSubmissions(projectId: number)
|
||||||
|
Defined in src/compliance/compliance.service.ts:238
|
||||||
|
Function to get the latest project dependent submission
Parameters :
Returns :
Promise<ComplianceSubmission>
Promise |
| Async submitCompliance | ||||||||||||
submitCompliance(submission: ComplianceSubmissionDto, submittedBy: string)
|
||||||||||||
|
Defined in src/compliance/compliance.service.ts:44
|
||||||||||||
|
Submit a compliance submission
Parameters :
Returns :
Promise<ComplianceSubmission>
created submission |
| triggerSubmitComplianceWorkflow | ||||||
triggerSubmitComplianceWorkflow(_submission: ComplianceSubmission)
|
||||||
|
Defined in src/compliance/compliance.service.ts:78
|
||||||
|
Function to trigger the compliance submission workflow
Parameters :
Returns :
Promise<string>
Promise |
| Async updateSubmissionStatus | ||||||||||||
updateSubmissionStatus(id: number, status: ComplianceSubmissionStatus)
|
||||||||||||
|
Defined in src/compliance/compliance.service.ts:168
|
||||||||||||
|
Update a compliance submission status
Parameters :
Returns :
unknown
updated submission |
| Private COMPLIANCE_SUBMISSION_WORKFLOW |
Type : string
|
Default value : "complianceSubmissionWorkflow"
|
|
Defined in src/compliance/compliance.service.ts:35
|
import { PrismaService } from "../common/prisma/prisma.service";
import { Injectable } from "@nestjs/common";
import { ComplianceSubmissionDto } from "./dto/submission.dto";
import {
ComplianceSubmission,
ComplianceSubmissionStatus,
} from "./entities/submission.entity";
import { TemporalProvider } from "../providers/temporal/temporal.provider";
import { getUuidSlug } from "../common/helper";
import { ComplianceRisk } from "./entities/risk.entity";
import { ComplianceRiskStatus } from "./entities/compliance.types";
import { ComplianceRiskCreateInput } from "./dto/risk.dto";
import { ComplianceRiskService } from "./risk.service";
import { SettingsService } from "../project/settings/settings.service";
import { PolicyService } from "../iam";
import {
COMPLIANCE_EVIDENCE_READ_ACTION,
COMPLIANCE_EVIDENCE_SUBMIT_ACTION,
COMPLIANCE_RESOURCE_NAME,
COMPLIANCE_RISK_READ_ACTION,
COMPLIANCE_RISK_SUBMIT_ACTION,
COMPLIANCE_RISK_UPDATE_ACTION,
} from "./compliance.constants";
@Injectable()
export class ComplianceService {
constructor(
private readonly prismaService: PrismaService,
private readonly temporalProvider: TemporalProvider,
private readonly complianceRiskService: ComplianceRiskService,
private readonly settingsService: SettingsService,
private readonly policyService: PolicyService,
) {}
private COMPLIANCE_SUBMISSION_WORKFLOW = "complianceSubmissionWorkflow";
/**
* Submit a compliance submission
* @param {ComplianceSubmissionDto} submission submission data
* @param {number} projectId project id
* @param {string} submittedBy user who submitted the compliance
* @returns {Promise<ComplianceSubmission>} created submission
*/
async submitCompliance(
submission: ComplianceSubmissionDto,
submittedBy: string,
): Promise<ComplianceSubmission> {
const policies = [
...submission.frameworkIds.map((id) => ({ id })),
...submission.policyIds.map((id) => ({ id })),
];
const _submission = new ComplianceSubmission(
await this.prismaService.complianceSubmission.create({
data: {
submittedBy: submittedBy,
status: ComplianceSubmissionStatus.OPEN,
jurisdictions: submission.jurisdictions,
project: {
connect: { id: submission.projectId },
},
policies: {
connect: policies,
},
},
}),
);
await this.triggerSubmitComplianceWorkflow(_submission);
return _submission;
}
/**
* Function to trigger the compliance submission workflow
* @param _submission
* @returns Promise<string> workflow id
*/
triggerSubmitComplianceWorkflow(
_submission: ComplianceSubmission,
): Promise<string> {
return this.temporalProvider.runAsync(
this.COMPLIANCE_SUBMISSION_WORKFLOW,
[_submission.id],
process.env.DEFAULT_QUEUE_NAME,
`workflow-${this.COMPLIANCE_SUBMISSION_WORKFLOW}-${_submission.id}-${getUuidSlug()}`,
);
}
/**
* Get compliance users with permissions
* @param projectId project id
* @returns {Promise<any[]>} list of users with permissions
*/
async getComplianceUsers(projectId: number): Promise<any[]> {
// get project users
const users = await this.settingsService.getProjectUsers(projectId);
const promises = users.map(async (user) => {
const userPermissions = await this.policyService.getUserPermissions(
user.id,
);
return {
...user,
permissions: {
risk: {
read: await this.policyService.checkPermission(
userPermissions,
projectId,
COMPLIANCE_RESOURCE_NAME,
COMPLIANCE_RISK_READ_ACTION,
),
update: await this.policyService.checkPermission(
userPermissions,
projectId,
COMPLIANCE_RESOURCE_NAME,
COMPLIANCE_RISK_UPDATE_ACTION,
),
submit: await this.policyService.checkPermission(
userPermissions,
projectId,
COMPLIANCE_RESOURCE_NAME,
COMPLIANCE_RISK_SUBMIT_ACTION,
),
},
evidence: {
read: await this.policyService.checkPermission(
userPermissions,
projectId,
COMPLIANCE_RESOURCE_NAME,
COMPLIANCE_EVIDENCE_READ_ACTION,
),
submit: await this.policyService.checkPermission(
userPermissions,
projectId,
COMPLIANCE_RESOURCE_NAME,
COMPLIANCE_EVIDENCE_SUBMIT_ACTION,
),
},
},
};
});
return await Promise.all(promises);
}
/**
* Find a compliance submission by id
* @param {number} id submission id
* @returns {Promise<ComplianceSubmission>} compliance submission
*/
async findSubmission(id: number): Promise<ComplianceSubmission> {
const submission = await this.prismaService.complianceSubmission.findUnique(
{
where: { id: id },
include: { policies: true, project: true },
},
);
return new ComplianceSubmission(submission);
}
/**
* Update a compliance submission status
* @param {number} id submission id
* @param {ComplianceSubmissionStatus} status new status
* @returns {Promise<ComplianceSubmission>} updated submission
*/
async updateSubmissionStatus(id: number, status: ComplianceSubmissionStatus) {
const submission = await this.prismaService.complianceSubmission.update({
where: { id: id },
data: { status: status },
});
return new ComplianceSubmission(submission);
}
/**
* Generate compliance risks for a submission
* @param {ComplianceSubmission} submission submission
* @param {any[]} rules list of rules
* @returns {Promise<ComplianceRisk[]>} list of generated risks
*/
async generateRisks(
submission: ComplianceSubmission,
rules: any[],
): Promise<ComplianceRisk[]> {
const existing = await this.complianceRiskService.findExisting({
projectId: submission.project["id"],
status: {
notIn: [
ComplianceRiskStatus.ARCHIVED,
ComplianceRiskStatus.DELETED,
ComplianceRiskStatus.MITIGATED,
],
},
});
const riskToCreate = rules.filter(
(rule) => !existing.some((risk) => risk.rule["id"] === rule.id),
);
const riskToDelete = existing.filter(
(risk) => !rules.some((rule) => rule.id === risk.rule["id"]),
);
const risksCreateData = riskToCreate
.map((rule) => {
const risk: ComplianceRiskCreateInput = {
ruleId: rule.id,
projectId: submission.project["id"],
complianceSubmissionId: submission.id,
status: ComplianceRiskStatus.TODO,
};
return risk;
})
.filter(
(risk, index, self) =>
index === self.findIndex((r) => r.ruleId === risk.ruleId),
);
const risks = this.complianceRiskService.createComplianceRisks(
submission.id,
risksCreateData,
);
if (riskToDelete.length > 0) {
await this.complianceRiskService.deleteDependentRisk(riskToDelete);
}
return risks;
}
/**
* Function to get the latest project dependent submission
* @param projectId
* @returns Promise<ComplianceSubmission>
*/
getLatestProjectDependentSubmissions(
projectId: number,
): Promise<ComplianceSubmission> {
return this.prismaService.complianceSubmission.findFirst({
where: {
projectId: projectId,
},
orderBy: {
createdAt: "desc",
},
});
}
async getActiveSubmissionsForPolicy(policyId: number): Promise<ComplianceSubmission[]> {
// get all submissions for the policy that are not in progress or open
const submissions = await this.prismaService.complianceSubmission.findMany({
where: {
policies: {
some: {
id: policyId,
},
},
status: {
notIn: [ComplianceSubmissionStatus.IN_PROGRESS, ComplianceSubmissionStatus.OPEN],
},
},
orderBy: [
{ projectId: 'asc' },
{ createdAt: 'desc' },
],
distinct: ['projectId'],
include: {
policies: true,
project: true,
},
});
return submissions.map((submission) => new ComplianceSubmission(submission));
}
}