diff --git a/packages/backend/src/services/analysis.ts b/packages/backend/src/services/analysis.ts index 6242a68..7e8c2ff 100644 --- a/packages/backend/src/services/analysis.ts +++ b/packages/backend/src/services/analysis.ts @@ -65,62 +65,68 @@ export const runAnalysis = async (sdk: SDK) => { ); for (const template of templates) { - for (const user of users) { - if (analysisStore.resultExists(template.id, user.id)) { - continue; - } - const analysisRequest = await sendRequest(sdk, template, user); - if (analysisRequest) { - analysisStore.addRequest(analysisRequest); - sdk.api.send("results:created", analysisRequest); + // Run each template async + (async () => { + for (const user of users) { + if (analysisStore.resultExists(template.id, user.id)) { + continue; + } + const analysisRequest = await sendRequest(sdk, template, user); + if (analysisRequest) { + analysisStore.addRequest(analysisRequest); + sdk.api.send("results:created", analysisRequest); + } } - } - } - const roles = roleStore.getRoles(); - for (const template of templates) { - const newRules: TemplateDTO["rules"] = []; - - // Generate role rule statuses in parallel - const rolePromises = roles.map(async (role) => { - const currentRule = template.rules.find( - (rule) => rule.type === "RoleRule" && rule.roleId === role.id, - ) ?? { - type: "RoleRule", - roleId: role.id, - hasAccess: false, - status: "Untested", - }; - - const status = await generateRoleRuleStatus(sdk, template, role.id); - return { ...currentRule, status }; - }); - - // Generate user rule statuses in parallel - const userPromises = users.map(async (user) => { - const currentRule = template.rules.find( - (rule) => rule.type === "UserRule" && rule.userId === user.id, - ) ?? { - type: "UserRule", - userId: user.id, - hasAccess: false, - status: "Untested", - }; - - const status = await generateUserRuleStatus(sdk, template, user); - return { ...currentRule, status }; - }); - - // Await all role and user statuses - const roleResults = await Promise.all(rolePromises); - const userResults = await Promise.all(userPromises); - - // Combine results - newRules.push(...roleResults, ...userResults); - - template.rules = newRules; - templateStore.updateTemplate(template.id, template); - sdk.api.send("templates:updated", template); + const newRules: TemplateDTO["rules"] = []; + const roles = roleStore.getRoles(); + const rolePromises = roles.map(async (role) => { + const currentRule = template.rules.find( + (rule) => rule.type === "RoleRule" && rule.roleId === role.id, + ) ?? { + type: "RoleRule", + roleId: role.id, + hasAccess: false, + status: "Untested", + }; + + + if (currentRule.status !== "Untested") { + return currentRule; + } + + const status = await generateRoleRuleStatus(sdk, template, role.id); + return { ...currentRule, status }; + }); + + const userPromises = users.map(async (user) => { + const currentRule = template.rules.find( + (rule) => rule.type === "UserRule" && rule.userId === user.id, + ) ?? { + type: "UserRule", + userId: user.id, + hasAccess: false, + status: "Untested", + }; + + if (currentRule.status !== "Untested") { + return currentRule; + } + + const status = await generateUserRuleStatus(sdk, template, user); + return { ...currentRule, status }; + }); + + const roleResults = await Promise.all(rolePromises); + const userResults = await Promise.all(userPromises); + + // Combine results + newRules.push(...roleResults, ...userResults); + + template.rules = newRules; + templateStore.updateTemplate(template.id, template); + sdk.api.send("templates:updated", template); + })() } }; diff --git a/packages/backend/src/stores/templates.ts b/packages/backend/src/stores/templates.ts index 7049517..54bea4c 100644 --- a/packages/backend/src/stores/templates.ts +++ b/packages/backend/src/stores/templates.ts @@ -1,4 +1,4 @@ -import type { TemplateDTO } from "shared"; +import type { RoleRuleDTO, TemplateDTO, UserRuleDTO } from "shared"; export class TemplateStore { private static _store?: TemplateStore; @@ -49,7 +49,7 @@ export class TemplateStore { }); if (currRule) { - currRule.hasAccess = !currRule.hasAccess; + this.toggleRule(currRule); } else { template.rules.push({ type: "RoleRule", @@ -63,6 +63,15 @@ export class TemplateStore { return template; } + toggleRule(currRule: RoleRuleDTO | UserRuleDTO) { + currRule.hasAccess = !currRule.hasAccess; + if (currRule.status === "Bypassed" && currRule.hasAccess) { + currRule.status = "Enforced" + } else if (currRule.status === "Enforced" && !currRule.hasAccess) { + currRule.status = "Bypassed" + } + } + toggleTemplateUser(templateId: string, userId: string) { const template = this.templates.get(templateId); if (template) { @@ -71,7 +80,7 @@ export class TemplateStore { }); if (currRule) { - currRule.hasAccess = !currRule.hasAccess; + this.toggleRule(currRule); } else { template.rules.push({ type: "UserRule",