@j-schreiber/sf-cli-security-audit 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/README.md +10 -2
  2. package/lib/commands/org/audit/init.d.ts +17 -0
  3. package/lib/commands/org/audit/init.js +61 -0
  4. package/lib/commands/org/audit/init.js.map +1 -0
  5. package/lib/commands/org/audit/run.d.ts +22 -0
  6. package/lib/commands/org/audit/run.js +113 -0
  7. package/lib/commands/org/audit/run.js.map +1 -0
  8. package/lib/libs/audit/types.d.ts +154 -0
  9. package/lib/libs/audit/types.js +2 -0
  10. package/lib/libs/audit/types.js.map +1 -0
  11. package/lib/libs/config/audit-run/auditConfigFileManager.d.ts +26 -0
  12. package/lib/libs/config/audit-run/auditConfigFileManager.js +98 -0
  13. package/lib/libs/config/audit-run/auditConfigFileManager.js.map +1 -0
  14. package/lib/libs/config/audit-run/schema.d.ts +100 -0
  15. package/lib/libs/config/audit-run/schema.js +45 -0
  16. package/lib/libs/config/audit-run/schema.js.map +1 -0
  17. package/lib/libs/config/defaultPolicyClassification.d.ts +2 -0
  18. package/lib/libs/config/defaultPolicyClassification.js +63 -0
  19. package/lib/libs/config/defaultPolicyClassification.js.map +1 -0
  20. package/lib/libs/config/queries.d.ts +5 -0
  21. package/lib/libs/config/queries.js +6 -0
  22. package/lib/libs/config/queries.js.map +1 -0
  23. package/lib/libs/config/registries/connectedApps.d.ts +5 -0
  24. package/lib/libs/config/registries/connectedApps.js +13 -0
  25. package/lib/libs/config/registries/connectedApps.js.map +1 -0
  26. package/lib/libs/config/registries/permissionSets.d.ts +5 -0
  27. package/lib/libs/config/registries/permissionSets.js +11 -0
  28. package/lib/libs/config/registries/permissionSets.js.map +1 -0
  29. package/lib/libs/config/registries/profiles.d.ts +5 -0
  30. package/lib/libs/config/registries/profiles.js +13 -0
  31. package/lib/libs/config/registries/profiles.js.map +1 -0
  32. package/lib/libs/config/registries/ruleRegistry.d.ts +29 -0
  33. package/lib/libs/config/registries/ruleRegistry.js +48 -0
  34. package/lib/libs/config/registries/ruleRegistry.js.map +1 -0
  35. package/lib/libs/config/registries/types.d.ts +7 -0
  36. package/lib/libs/config/registries/types.js +2 -0
  37. package/lib/libs/config/registries/types.js.map +1 -0
  38. package/lib/libs/mdapiRetriever.d.ts +18 -0
  39. package/lib/libs/mdapiRetriever.js +60 -0
  40. package/lib/libs/mdapiRetriever.js.map +1 -0
  41. package/lib/libs/policies/auditRun.d.ts +36 -0
  42. package/lib/libs/policies/auditRun.js +92 -0
  43. package/lib/libs/policies/auditRun.js.map +1 -0
  44. package/lib/libs/policies/connectedAppPolicy.d.ts +18 -0
  45. package/lib/libs/policies/connectedAppPolicy.js +78 -0
  46. package/lib/libs/policies/connectedAppPolicy.js.map +1 -0
  47. package/lib/libs/policies/initialisation/auditConfig.d.ts +27 -0
  48. package/lib/libs/policies/initialisation/auditConfig.js +41 -0
  49. package/lib/libs/policies/initialisation/auditConfig.js.map +1 -0
  50. package/lib/libs/policies/initialisation/permissionsClassification.d.ts +17 -0
  51. package/lib/libs/policies/initialisation/permissionsClassification.js +71 -0
  52. package/lib/libs/policies/initialisation/permissionsClassification.js.map +1 -0
  53. package/lib/libs/policies/initialisation/policyConfigs.d.ts +25 -0
  54. package/lib/libs/policies/initialisation/policyConfigs.js +67 -0
  55. package/lib/libs/policies/initialisation/policyConfigs.js.map +1 -0
  56. package/lib/libs/policies/interfaces/policyRuleInterfaces.d.ts +30 -0
  57. package/lib/libs/policies/interfaces/policyRuleInterfaces.js +2 -0
  58. package/lib/libs/policies/interfaces/policyRuleInterfaces.js.map +1 -0
  59. package/lib/libs/policies/permissionSetPolicy.d.ts +17 -0
  60. package/lib/libs/policies/permissionSetPolicy.js +61 -0
  61. package/lib/libs/policies/permissionSetPolicy.js.map +1 -0
  62. package/lib/libs/policies/policy.d.ts +32 -0
  63. package/lib/libs/policies/policy.js +95 -0
  64. package/lib/libs/policies/policy.js.map +1 -0
  65. package/lib/libs/policies/profilePolicy.d.ts +17 -0
  66. package/lib/libs/policies/profilePolicy.js +71 -0
  67. package/lib/libs/policies/profilePolicy.js.map +1 -0
  68. package/lib/libs/policies/rules/allUsedAppsUnderManagement.d.ts +7 -0
  69. package/lib/libs/policies/rules/allUsedAppsUnderManagement.js +23 -0
  70. package/lib/libs/policies/rules/allUsedAppsUnderManagement.js.map +1 -0
  71. package/lib/libs/policies/rules/enforceCustomPermsClassificationOnProfiles.d.ts +7 -0
  72. package/lib/libs/policies/rules/enforceCustomPermsClassificationOnProfiles.js +51 -0
  73. package/lib/libs/policies/rules/enforceCustomPermsClassificationOnProfiles.js.map +1 -0
  74. package/lib/libs/policies/rules/enforceUserPermsClassificationOnPermSets.d.ts +7 -0
  75. package/lib/libs/policies/rules/enforceUserPermsClassificationOnPermSets.js +51 -0
  76. package/lib/libs/policies/rules/enforceUserPermsClassificationOnPermSets.js.map +1 -0
  77. package/lib/libs/policies/rules/enforceUserPermsClassificationOnProfiles.d.ts +7 -0
  78. package/lib/libs/policies/rules/enforceUserPermsClassificationOnProfiles.js +53 -0
  79. package/lib/libs/policies/rules/enforceUserPermsClassificationOnProfiles.js.map +1 -0
  80. package/lib/libs/policies/rules/noUserCanSelfAuthorize.d.ts +7 -0
  81. package/lib/libs/policies/rules/noUserCanSelfAuthorize.js +31 -0
  82. package/lib/libs/policies/rules/noUserCanSelfAuthorize.js.map +1 -0
  83. package/lib/libs/policies/rules/policyRule.d.ts +16 -0
  84. package/lib/libs/policies/rules/policyRule.js +29 -0
  85. package/lib/libs/policies/rules/policyRule.js.map +1 -0
  86. package/lib/libs/policies/salesforceStandardTypes.d.ts +39 -0
  87. package/lib/libs/policies/salesforceStandardTypes.js +2 -0
  88. package/lib/libs/policies/salesforceStandardTypes.js.map +1 -0
  89. package/lib/libs/policies/types.d.ts +36 -0
  90. package/lib/libs/policies/types.js +45 -0
  91. package/lib/libs/policies/types.js.map +1 -0
  92. package/lib/libs/utils.d.ts +3 -0
  93. package/lib/libs/utils.js +13 -0
  94. package/lib/libs/utils.js.map +1 -0
  95. package/lib/ux/auditRunMultiStage.d.ts +65 -0
  96. package/lib/ux/auditRunMultiStage.js +117 -0
  97. package/lib/ux/auditRunMultiStage.js.map +1 -0
  98. package/messages/org.audit.init.md +1 -1
  99. package/messages/org.audit.run.md +0 -4
  100. package/messages/policies.general.md +12 -0
  101. package/messages/rules.connectedApps.md +11 -0
  102. package/oclif.manifest.json +159 -2
  103. package/package.json +2 -1
@@ -0,0 +1,23 @@
1
+ import { Messages } from '@salesforce/core';
2
+ import PolicyRule from './policyRule.js';
3
+ Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
4
+ const messages = Messages.loadMessages('@j-schreiber/sf-cli-security-audit', 'rules.connectedApps');
5
+ export default class AllUsedAppsUnderManagement extends PolicyRule {
6
+ constructor(opts) {
7
+ super(opts);
8
+ }
9
+ run(context) {
10
+ const result = this.initResult();
11
+ const resolvedConnectedApps = context.resolvedEntities;
12
+ Object.values(resolvedConnectedApps).forEach((app) => {
13
+ if (app.origin === 'OauthToken') {
14
+ result.violations.push({
15
+ identifier: [app.name],
16
+ message: messages.getMessage('violations.app-used-but-not-registered', [app.users.length, app.useCount]),
17
+ });
18
+ }
19
+ });
20
+ return Promise.resolve(result);
21
+ }
22
+ }
23
+ //# sourceMappingURL=allUsedAppsUnderManagement.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"allUsedAppsUnderManagement.js","sourceRoot":"","sources":["../../../../src/libs/policies/rules/allUsedAppsUnderManagement.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAG5C,OAAO,UAA2B,MAAM,iBAAiB,CAAC;AAE1D,QAAQ,CAAC,kCAAkC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC7D,MAAM,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAC,oCAAoC,EAAE,qBAAqB,CAAC,CAAC;AAEpG,MAAM,CAAC,OAAO,OAAO,0BAA2B,SAAQ,UAAgC;IACtF,YAAmB,IAAiB;QAClC,KAAK,CAAC,IAAI,CAAC,CAAC;IACd,CAAC;IAEM,GAAG,CAAC,OAA+C;QACxD,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QACjC,MAAM,qBAAqB,GAAG,OAAO,CAAC,gBAAgB,CAAC;QACvD,MAAM,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;YACnD,IAAI,GAAG,CAAC,MAAM,KAAK,YAAY,EAAE,CAAC;gBAChC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;oBACrB,UAAU,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC;oBACtB,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,wCAAwC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;iBACzG,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CAAC,CAAC;QACH,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;CACF"}
@@ -0,0 +1,7 @@
1
+ import { PartialPolicyRuleResult, RuleAuditContext } from '../interfaces/policyRuleInterfaces.js';
2
+ import { ResolvedProfile } from '../profilePolicy.js';
3
+ import PolicyRule, { RuleOptions } from './policyRule.js';
4
+ export default class EnforceCustomPermsClassificationOnProfiles extends PolicyRule<ResolvedProfile> {
5
+ constructor(opts: RuleOptions);
6
+ run(context: RuleAuditContext<ResolvedProfile>): Promise<PartialPolicyRuleResult>;
7
+ }
@@ -0,0 +1,51 @@
1
+ import { Messages } from '@salesforce/core';
2
+ import { permissionAllowedInPreset, PolicyRiskLevel } from '../types.js';
3
+ import PolicyRule from './policyRule.js';
4
+ const messages = Messages.loadMessages('@j-schreiber/sf-cli-security-audit', 'rules.enforceClassificationPresets');
5
+ export default class EnforceCustomPermsClassificationOnProfiles extends PolicyRule {
6
+ constructor(opts) {
7
+ super(opts);
8
+ }
9
+ run(context) {
10
+ const result = this.initResult();
11
+ const resolvedProfiles = context.resolvedEntities;
12
+ Object.values(resolvedProfiles).forEach((profile) => {
13
+ const customPerms = profile.metadata.customPermissions ?? [];
14
+ customPerms.forEach((perm) => {
15
+ const identifier = [profile.name, perm.name];
16
+ const classifiedPerm = this.resolveCustomPermission(perm.name);
17
+ if (classifiedPerm) {
18
+ if (classifiedPerm.classification === PolicyRiskLevel.BLOCKED) {
19
+ result.violations.push({
20
+ identifier,
21
+ message: messages.getMessage('violations.permission-is-blocked'),
22
+ });
23
+ }
24
+ else if (!permissionAllowedInPreset(classifiedPerm.classification, profile.preset)) {
25
+ result.violations.push({
26
+ identifier,
27
+ message: messages.getMessage('violations.classification-preset-mismatch', [
28
+ classifiedPerm.classification,
29
+ profile.preset,
30
+ ]),
31
+ });
32
+ }
33
+ else if (classifiedPerm.classification === PolicyRiskLevel.UNKNOWN) {
34
+ result.warnings.push({
35
+ identifier,
36
+ message: messages.getMessage('warnings.permission-unknown'),
37
+ });
38
+ }
39
+ }
40
+ else {
41
+ result.warnings.push({
42
+ identifier,
43
+ message: messages.getMessage('warnings.permission-not-classified-in-profile'),
44
+ });
45
+ }
46
+ });
47
+ });
48
+ return Promise.resolve(result);
49
+ }
50
+ }
51
+ //# sourceMappingURL=enforceCustomPermsClassificationOnProfiles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enforceCustomPermsClassificationOnProfiles.js","sourceRoot":"","sources":["../../../../src/libs/policies/rules/enforceCustomPermsClassificationOnProfiles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,yBAAyB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEzE,OAAO,UAA2B,MAAM,iBAAiB,CAAC;AAE1D,MAAM,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAC,oCAAoC,EAAE,oCAAoC,CAAC,CAAC;AAEnH,MAAM,CAAC,OAAO,OAAO,0CAA2C,SAAQ,UAA2B;IACjG,YAAmB,IAAiB;QAClC,KAAK,CAAC,IAAI,CAAC,CAAC;IACd,CAAC;IAEM,GAAG,CAAC,OAA0C;QACnD,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QACjC,MAAM,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;QAClD,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAClD,MAAM,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,iBAAiB,IAAI,EAAE,CAAC;YAC7D,WAAW,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;gBAC3B,MAAM,UAAU,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC7C,MAAM,cAAc,GAAG,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC/D,IAAI,cAAc,EAAE,CAAC;oBACnB,IAAI,cAAc,CAAC,cAAc,KAAK,eAAe,CAAC,OAAO,EAAE,CAAC;wBAC9D,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;4BACrB,UAAU;4BACV,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,kCAAkC,CAAC;yBACjE,CAAC,CAAC;oBACL,CAAC;yBAAM,IAAI,CAAC,yBAAyB,CAAC,cAAc,CAAC,cAAc,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;wBACrF,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;4BACrB,UAAU;4BACV,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,2CAA2C,EAAE;gCACxE,cAAc,CAAC,cAAc;gCAC7B,OAAO,CAAC,MAAM;6BACf,CAAC;yBACH,CAAC,CAAC;oBACL,CAAC;yBAAM,IAAI,cAAc,CAAC,cAAc,KAAK,eAAe,CAAC,OAAO,EAAE,CAAC;wBACrE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;4BACnB,UAAU;4BACV,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,6BAA6B,CAAC;yBAC5D,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;wBACnB,UAAU;wBACV,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,+CAA+C,CAAC;qBAC9E,CAAC,CAAC;gBACL,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;CACF"}
@@ -0,0 +1,7 @@
1
+ import { PartialPolicyRuleResult, RuleAuditContext } from '../interfaces/policyRuleInterfaces.js';
2
+ import { ResolvedPermissionSet } from '../permissionSetPolicy.js';
3
+ import PolicyRule, { RuleOptions } from './policyRule.js';
4
+ export default class EnforceUserPermsClassificationOnPermSets extends PolicyRule<ResolvedPermissionSet> {
5
+ constructor(opts: RuleOptions);
6
+ run(context: RuleAuditContext<ResolvedPermissionSet>): Promise<PartialPolicyRuleResult>;
7
+ }
@@ -0,0 +1,51 @@
1
+ import { Messages } from '@salesforce/core';
2
+ import { permissionAllowedInPreset, PolicyRiskLevel } from '../types.js';
3
+ import PolicyRule from './policyRule.js';
4
+ const messages = Messages.loadMessages('@j-schreiber/sf-cli-security-audit', 'rules.enforceClassificationPresets');
5
+ export default class EnforceUserPermsClassificationOnPermSets extends PolicyRule {
6
+ constructor(opts) {
7
+ super(opts);
8
+ }
9
+ run(context) {
10
+ const result = this.initResult();
11
+ const resolvedPermsets = context.resolvedEntities;
12
+ Object.values(resolvedPermsets).forEach((permset) => {
13
+ const userPerms = permset.metadata.userPermissions ?? [];
14
+ userPerms.forEach((userPerm) => {
15
+ const identifier = [permset.name, userPerm.name];
16
+ const classifiedUserPerm = this.resolveUserPermission(userPerm.name);
17
+ if (classifiedUserPerm) {
18
+ if (classifiedUserPerm.classification === PolicyRiskLevel.BLOCKED) {
19
+ result.violations.push({
20
+ identifier,
21
+ message: messages.getMessage('violations.permission-is-blocked'),
22
+ });
23
+ }
24
+ else if (!permissionAllowedInPreset(classifiedUserPerm.classification, permset.preset)) {
25
+ result.violations.push({
26
+ identifier,
27
+ message: messages.getMessage('violations.classification-preset-mismatch', [
28
+ classifiedUserPerm.classification,
29
+ permset.preset,
30
+ ]),
31
+ });
32
+ }
33
+ else if (classifiedUserPerm.classification === PolicyRiskLevel.UNKNOWN) {
34
+ result.warnings.push({
35
+ identifier,
36
+ message: messages.getMessage('warnings.permission-unknown'),
37
+ });
38
+ }
39
+ }
40
+ else {
41
+ result.warnings.push({
42
+ identifier,
43
+ message: messages.getMessage('warnings.permission-not-classified-in-permission-set'),
44
+ });
45
+ }
46
+ });
47
+ });
48
+ return Promise.resolve(result);
49
+ }
50
+ }
51
+ //# sourceMappingURL=enforceUserPermsClassificationOnPermSets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enforceUserPermsClassificationOnPermSets.js","sourceRoot":"","sources":["../../../../src/libs/policies/rules/enforceUserPermsClassificationOnPermSets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,yBAAyB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEzE,OAAO,UAA2B,MAAM,iBAAiB,CAAC;AAE1D,MAAM,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAC,oCAAoC,EAAE,oCAAoC,CAAC,CAAC;AAEnH,MAAM,CAAC,OAAO,OAAO,wCAAyC,SAAQ,UAAiC;IACrG,YAAmB,IAAiB;QAClC,KAAK,CAAC,IAAI,CAAC,CAAC;IACd,CAAC;IAEM,GAAG,CAAC,OAAgD;QACzD,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QACjC,MAAM,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;QAClD,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAClD,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC,eAAe,IAAI,EAAE,CAAC;YACzD,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;gBAC7B,MAAM,UAAU,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;gBACjD,MAAM,kBAAkB,GAAG,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;gBACrE,IAAI,kBAAkB,EAAE,CAAC;oBACvB,IAAI,kBAAkB,CAAC,cAAc,KAAK,eAAe,CAAC,OAAO,EAAE,CAAC;wBAClE,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;4BACrB,UAAU;4BACV,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,kCAAkC,CAAC;yBACjE,CAAC,CAAC;oBACL,CAAC;yBAAM,IAAI,CAAC,yBAAyB,CAAC,kBAAkB,CAAC,cAAc,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;wBACzF,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;4BACrB,UAAU;4BACV,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,2CAA2C,EAAE;gCACxE,kBAAkB,CAAC,cAAc;gCACjC,OAAO,CAAC,MAAM;6BACf,CAAC;yBACH,CAAC,CAAC;oBACL,CAAC;yBAAM,IAAI,kBAAkB,CAAC,cAAc,KAAK,eAAe,CAAC,OAAO,EAAE,CAAC;wBACzE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;4BACnB,UAAU;4BACV,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,6BAA6B,CAAC;yBAC5D,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;wBACnB,UAAU;wBACV,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,sDAAsD,CAAC;qBACrF,CAAC,CAAC;gBACL,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;CACF"}
@@ -0,0 +1,7 @@
1
+ import { PartialPolicyRuleResult, RuleAuditContext } from '../interfaces/policyRuleInterfaces.js';
2
+ import { ResolvedProfile } from '../profilePolicy.js';
3
+ import PolicyRule, { RuleOptions } from './policyRule.js';
4
+ export default class EnforceUserPermsClassificationOnProfiles extends PolicyRule<ResolvedProfile> {
5
+ constructor(opts: RuleOptions);
6
+ run(context: RuleAuditContext<ResolvedProfile>): Promise<PartialPolicyRuleResult>;
7
+ }
@@ -0,0 +1,53 @@
1
+ import { Messages } from '@salesforce/core';
2
+ import { isNullish } from '../../utils.js';
3
+ import { permissionAllowedInPreset, PolicyRiskLevel } from '../types.js';
4
+ import PolicyRule from './policyRule.js';
5
+ const messages = Messages.loadMessages('@j-schreiber/sf-cli-security-audit', 'rules.enforceClassificationPresets');
6
+ export default class EnforceUserPermsClassificationOnProfiles extends PolicyRule {
7
+ constructor(opts) {
8
+ super(opts);
9
+ }
10
+ run(context) {
11
+ const result = this.initResult();
12
+ const resolvedProfiles = context.resolvedEntities;
13
+ Object.values(resolvedProfiles).forEach((profile) => {
14
+ if (!isNullish(profile.metadata.userPermissions)) {
15
+ profile.metadata.userPermissions.forEach((userPerm) => {
16
+ const identifier = [profile.name, userPerm.name];
17
+ const classifiedUserPerm = this.resolveUserPermission(userPerm.name);
18
+ if (classifiedUserPerm) {
19
+ if (classifiedUserPerm.classification === PolicyRiskLevel.BLOCKED) {
20
+ result.violations.push({
21
+ identifier,
22
+ message: messages.getMessage('violations.permission-is-blocked'),
23
+ });
24
+ }
25
+ else if (!permissionAllowedInPreset(classifiedUserPerm.classification, profile.preset)) {
26
+ result.violations.push({
27
+ identifier,
28
+ message: messages.getMessage('violations.classification-preset-mismatch', [
29
+ classifiedUserPerm.classification,
30
+ profile.preset,
31
+ ]),
32
+ });
33
+ }
34
+ else if (classifiedUserPerm.classification === PolicyRiskLevel.UNKNOWN) {
35
+ result.warnings.push({
36
+ identifier,
37
+ message: messages.getMessage('warnings.permission-unknown'),
38
+ });
39
+ }
40
+ }
41
+ else {
42
+ result.warnings.push({
43
+ identifier,
44
+ message: messages.getMessage('warnings.permission-not-classified-in-profile'),
45
+ });
46
+ }
47
+ });
48
+ }
49
+ });
50
+ return Promise.resolve(result);
51
+ }
52
+ }
53
+ //# sourceMappingURL=enforceUserPermsClassificationOnProfiles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enforceUserPermsClassificationOnProfiles.js","sourceRoot":"","sources":["../../../../src/libs/policies/rules/enforceUserPermsClassificationOnProfiles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,OAAO,EAAE,yBAAyB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEzE,OAAO,UAA2B,MAAM,iBAAiB,CAAC;AAE1D,MAAM,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAC,oCAAoC,EAAE,oCAAoC,CAAC,CAAC;AAEnH,MAAM,CAAC,OAAO,OAAO,wCAAyC,SAAQ,UAA2B;IAC/F,YAAmB,IAAiB;QAClC,KAAK,CAAC,IAAI,CAAC,CAAC;IACd,CAAC;IAEM,GAAG,CAAC,OAA0C;QACnD,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QACjC,MAAM,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;QAClD,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAClD,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;gBACjD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;oBACpD,MAAM,UAAU,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;oBACjD,MAAM,kBAAkB,GAAG,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;oBACrE,IAAI,kBAAkB,EAAE,CAAC;wBACvB,IAAI,kBAAkB,CAAC,cAAc,KAAK,eAAe,CAAC,OAAO,EAAE,CAAC;4BAClE,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;gCACrB,UAAU;gCACV,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,kCAAkC,CAAC;6BACjE,CAAC,CAAC;wBACL,CAAC;6BAAM,IAAI,CAAC,yBAAyB,CAAC,kBAAkB,CAAC,cAAc,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;4BACzF,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;gCACrB,UAAU;gCACV,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,2CAA2C,EAAE;oCACxE,kBAAkB,CAAC,cAAc;oCACjC,OAAO,CAAC,MAAM;iCACf,CAAC;6BACH,CAAC,CAAC;wBACL,CAAC;6BAAM,IAAI,kBAAkB,CAAC,cAAc,KAAK,eAAe,CAAC,OAAO,EAAE,CAAC;4BACzE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;gCACnB,UAAU;gCACV,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,6BAA6B,CAAC;6BAC5D,CAAC,CAAC;wBACL,CAAC;oBACH,CAAC;yBAAM,CAAC;wBACN,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;4BACnB,UAAU;4BACV,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,+CAA+C,CAAC;yBAC9E,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CAAC,CAAC;QACH,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;CACF"}
@@ -0,0 +1,7 @@
1
+ import { PartialPolicyRuleResult, RuleAuditContext } from '../interfaces/policyRuleInterfaces.js';
2
+ import { ResolvedConnectedApp } from '../connectedAppPolicy.js';
3
+ import PolicyRule, { RuleOptions } from './policyRule.js';
4
+ export default class NoUserCanSelfAuthorize extends PolicyRule<ResolvedConnectedApp> {
5
+ constructor(opts: RuleOptions);
6
+ run(context: RuleAuditContext<ResolvedConnectedApp>): Promise<PartialPolicyRuleResult>;
7
+ }
@@ -0,0 +1,31 @@
1
+ import { Messages } from '@salesforce/core';
2
+ import PolicyRule from './policyRule.js';
3
+ Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
4
+ const messages = Messages.loadMessages('@j-schreiber/sf-cli-security-audit', 'rules.connectedApps');
5
+ export default class NoUserCanSelfAuthorize extends PolicyRule {
6
+ constructor(opts) {
7
+ super(opts);
8
+ }
9
+ run(context) {
10
+ const result = this.initResult();
11
+ const resolvedConnectedApps = context.resolvedEntities;
12
+ Object.values(resolvedConnectedApps).forEach((app) => {
13
+ if (!app.onlyAdminApprovedUsersAllowed) {
14
+ if (app.overrideByApiSecurityAccess) {
15
+ result.warnings.push({
16
+ identifier: [app.name],
17
+ message: messages.getMessage('warnings.users-can-self-authorize-but-setting-overrides'),
18
+ });
19
+ }
20
+ else {
21
+ result.violations.push({
22
+ identifier: [app.name],
23
+ message: messages.getMessage('violations.users-can-self-authorize'),
24
+ });
25
+ }
26
+ }
27
+ });
28
+ return Promise.resolve(result);
29
+ }
30
+ }
31
+ //# sourceMappingURL=noUserCanSelfAuthorize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"noUserCanSelfAuthorize.js","sourceRoot":"","sources":["../../../../src/libs/policies/rules/noUserCanSelfAuthorize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAG5C,OAAO,UAA2B,MAAM,iBAAiB,CAAC;AAE1D,QAAQ,CAAC,kCAAkC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC7D,MAAM,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAC,oCAAoC,EAAE,qBAAqB,CAAC,CAAC;AAEpG,MAAM,CAAC,OAAO,OAAO,sBAAuB,SAAQ,UAAgC;IAClF,YAAmB,IAAiB;QAClC,KAAK,CAAC,IAAI,CAAC,CAAC;IACd,CAAC;IAEM,GAAG,CAAC,OAA+C;QACxD,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QACjC,MAAM,qBAAqB,GAAG,OAAO,CAAC,gBAAgB,CAAC;QACvD,MAAM,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;YACnD,IAAI,CAAC,GAAG,CAAC,6BAA6B,EAAE,CAAC;gBACvC,IAAI,GAAG,CAAC,2BAA2B,EAAE,CAAC;oBACpC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;wBACnB,UAAU,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC;wBACtB,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,yDAAyD,CAAC;qBACxF,CAAC,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;wBACrB,UAAU,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC;wBACtB,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,qCAAqC,CAAC;qBACpE,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;QACH,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;CACF"}
@@ -0,0 +1,16 @@
1
+ import { PartialPolicyRuleResult, RowLevelPolicyRule, RuleAuditContext } from '../interfaces/policyRuleInterfaces.js';
2
+ import { AuditRunConfig, NamedPermissionsClassification } from '../../config/audit-run/schema.js';
3
+ export type RuleOptions = {
4
+ auditContext: AuditRunConfig;
5
+ ruleDisplayName: string;
6
+ ruleConfig?: unknown;
7
+ };
8
+ export default abstract class PolicyRule<EntityType> implements RowLevelPolicyRule<EntityType> {
9
+ auditContext: AuditRunConfig;
10
+ ruleDisplayName: string;
11
+ constructor(opts: RuleOptions);
12
+ protected initResult(): PartialPolicyRuleResult;
13
+ protected resolveUserPermission(permName: string): NamedPermissionsClassification | undefined;
14
+ protected resolveCustomPermission(permName: string): NamedPermissionsClassification | undefined;
15
+ abstract run(context: RuleAuditContext<EntityType>): Promise<PartialPolicyRuleResult>;
16
+ }
@@ -0,0 +1,29 @@
1
+ import { Messages } from '@salesforce/core';
2
+ Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
3
+ export default class PolicyRule {
4
+ auditContext;
5
+ ruleDisplayName;
6
+ constructor(opts) {
7
+ this.auditContext = opts.auditContext;
8
+ this.ruleDisplayName = opts.ruleDisplayName;
9
+ }
10
+ initResult() {
11
+ return {
12
+ ruleName: this.ruleDisplayName,
13
+ violations: new Array(),
14
+ mutedViolations: new Array(),
15
+ warnings: new Array(),
16
+ errors: new Array(),
17
+ };
18
+ }
19
+ resolveUserPermission(permName) {
20
+ return nameClassification(permName, this.auditContext.classifications.userPermissions?.content.permissions[permName]);
21
+ }
22
+ resolveCustomPermission(permName) {
23
+ return nameClassification(permName, this.auditContext.classifications.customPermissions?.content.permissions[permName]);
24
+ }
25
+ }
26
+ function nameClassification(permName, perm) {
27
+ return perm ? { name: permName, ...perm } : undefined;
28
+ }
29
+ //# sourceMappingURL=policyRule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policyRule.js","sourceRoot":"","sources":["../../../../src/libs/policies/rules/policyRule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAS5C,QAAQ,CAAC,kCAAkC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAQ7D,MAAM,CAAC,OAAO,OAAgB,UAAU;IAC/B,YAAY,CAAiB;IAC7B,eAAe,CAAS;IAE/B,YAAmB,IAAiB;QAClC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;QACtC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC;IAC9C,CAAC;IAES,UAAU;QAClB,OAAO;YACL,QAAQ,EAAE,IAAI,CAAC,eAAe;YAC9B,UAAU,EAAE,IAAI,KAAK,EAAuB;YAC5C,eAAe,EAAE,IAAI,KAAK,EAA2B;YACrD,QAAQ,EAAE,IAAI,KAAK,EAAwB;YAC3C,MAAM,EAAE,IAAI,KAAK,EAAwB;SAC1C,CAAC;IACJ,CAAC;IAES,qBAAqB,CAAC,QAAgB;QAC9C,OAAO,kBAAkB,CACvB,QAAQ,EACR,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC,eAAe,EAAE,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,CACjF,CAAC;IACJ,CAAC;IAES,uBAAuB,CAAC,QAAgB;QAChD,OAAO,kBAAkB,CACvB,QAAQ,EACR,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC,iBAAiB,EAAE,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,CACnF,CAAC;IACJ,CAAC;CAGF;AAED,SAAS,kBAAkB,CACzB,QAAgB,EAChB,IAAgC;IAEhC,OAAO,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AACxD,CAAC"}
@@ -0,0 +1,39 @@
1
+ import { Record } from '@jsforce/jsforce-node';
2
+ import { Profile as JsForceProfile } from '@jsforce/jsforce-node/lib/api/metadata.js';
3
+ export type CustomPermission = Record & {
4
+ Id: string;
5
+ MasterLabel: string;
6
+ DeveloperName: string;
7
+ };
8
+ export type ConnectedApp = Record & {
9
+ Id: string;
10
+ Name: string;
11
+ OptionsAllowAdminApprovedUsersOnly: boolean;
12
+ };
13
+ export type OauthToken = Record & {
14
+ Id: string;
15
+ User: Pick<User, 'Username'>;
16
+ AppName: string;
17
+ UseCount: number;
18
+ };
19
+ export type User = Record & {
20
+ Username: string;
21
+ };
22
+ export type Profile = ProfileBasic & {
23
+ Metadata: JsForceProfile;
24
+ };
25
+ type ProfileBasic = Record & {
26
+ Id: string;
27
+ Name: string;
28
+ UserType: string;
29
+ };
30
+ export type PermissionSet = Record & {
31
+ Id: string;
32
+ IsOwnedByProfile: boolean;
33
+ IsCustom: boolean;
34
+ Name: string;
35
+ Label: string;
36
+ Profile: ProfileBasic;
37
+ NamespacePrefix?: string;
38
+ };
39
+ export {};
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=salesforceStandardTypes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"salesforceStandardTypes.js","sourceRoot":"","sources":["../../../src/libs/policies/salesforceStandardTypes.ts"],"names":[],"mappings":""}
@@ -0,0 +1,36 @@
1
+ export declare enum PolicyRiskLevel {
2
+ /** Blacklisted permissions that are considered too critical and not allowed */
3
+ BLOCKED = "Blocked",
4
+ /** Developer permissions, allow to modify the application */
5
+ CRITICAL = "Critical",
6
+ /** Admin permissions, allow to manage users and change permissions */
7
+ HIGH = "High",
8
+ /** Elevated business permissions for privileged users */
9
+ MEDIUM = "Medium",
10
+ /** Regular user permissions, typically needed for day-to-day work */
11
+ LOW = "Low",
12
+ /** Not categorized or unknown permission */
13
+ UNKNOWN = "Unknown"
14
+ }
15
+ /**
16
+ * Presets can be assigned to profiles and permission sets.
17
+ * A preset allows permissions up to a fixed risk level.
18
+ */
19
+ export declare enum PermissionRiskLevelPresets {
20
+ /** Allows up to "Critical" permissions */
21
+ DEVELOPER = "Developer",
22
+ /** Allows up to "High" permissions */
23
+ ADMIN = "Admin",
24
+ /** Allows up to "Medium" permissions */
25
+ POWER_USER = "Power User",
26
+ /** Allows only "Low" permissions */
27
+ STANDARD_USER = "Standard User",
28
+ /** Disables the profile for audit */
29
+ UNKNOWN = "Unknown"
30
+ }
31
+ export type PolicyWriteResult = {
32
+ paths: Record<string, string>;
33
+ };
34
+ export declare function resolveRiskLevelOrdinalValue(value: string): number;
35
+ export declare function resolvePresetOrdinalValue(value: string): number;
36
+ export declare function permissionAllowedInPreset(permClassification: string, preset: string): boolean;
@@ -0,0 +1,45 @@
1
+ export var PolicyRiskLevel;
2
+ (function (PolicyRiskLevel) {
3
+ /** Blacklisted permissions that are considered too critical and not allowed */
4
+ PolicyRiskLevel["BLOCKED"] = "Blocked";
5
+ /** Developer permissions, allow to modify the application */
6
+ PolicyRiskLevel["CRITICAL"] = "Critical";
7
+ /** Admin permissions, allow to manage users and change permissions */
8
+ PolicyRiskLevel["HIGH"] = "High";
9
+ /** Elevated business permissions for privileged users */
10
+ PolicyRiskLevel["MEDIUM"] = "Medium";
11
+ /** Regular user permissions, typically needed for day-to-day work */
12
+ PolicyRiskLevel["LOW"] = "Low";
13
+ /** Not categorized or unknown permission */
14
+ PolicyRiskLevel["UNKNOWN"] = "Unknown";
15
+ })(PolicyRiskLevel || (PolicyRiskLevel = {}));
16
+ /**
17
+ * Presets can be assigned to profiles and permission sets.
18
+ * A preset allows permissions up to a fixed risk level.
19
+ */
20
+ export var PermissionRiskLevelPresets;
21
+ (function (PermissionRiskLevelPresets) {
22
+ /** Allows up to "Critical" permissions */
23
+ PermissionRiskLevelPresets["DEVELOPER"] = "Developer";
24
+ /** Allows up to "High" permissions */
25
+ PermissionRiskLevelPresets["ADMIN"] = "Admin";
26
+ /** Allows up to "Medium" permissions */
27
+ PermissionRiskLevelPresets["POWER_USER"] = "Power User";
28
+ /** Allows only "Low" permissions */
29
+ PermissionRiskLevelPresets["STANDARD_USER"] = "Standard User";
30
+ /** Disables the profile for audit */
31
+ PermissionRiskLevelPresets["UNKNOWN"] = "Unknown";
32
+ })(PermissionRiskLevelPresets || (PermissionRiskLevelPresets = {}));
33
+ export function resolveRiskLevelOrdinalValue(value) {
34
+ return Object.keys(PolicyRiskLevel).indexOf(value.toUpperCase());
35
+ }
36
+ export function resolvePresetOrdinalValue(value) {
37
+ return Object.keys(PermissionRiskLevelPresets).indexOf(value.toUpperCase().replace(' ', '_'));
38
+ }
39
+ export function permissionAllowedInPreset(permClassification, preset) {
40
+ // this works, as long as we are mindful when adding new risk levels and presets
41
+ const invertedPermValue = Object.keys(PolicyRiskLevel).length - resolveRiskLevelOrdinalValue(permClassification);
42
+ const invertedPresetValue = Object.keys(PermissionRiskLevelPresets).length - resolvePresetOrdinalValue(preset);
43
+ return invertedPresetValue >= invertedPermValue;
44
+ }
45
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/libs/policies/types.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,eAaX;AAbD,WAAY,eAAe;IACzB,+EAA+E;IAC/E,sCAAmB,CAAA;IACnB,6DAA6D;IAC7D,wCAAqB,CAAA;IACrB,sEAAsE;IACtE,gCAAa,CAAA;IACb,yDAAyD;IACzD,oCAAiB,CAAA;IACjB,qEAAqE;IACrE,8BAAW,CAAA;IACX,4CAA4C;IAC5C,sCAAmB,CAAA;AACrB,CAAC,EAbW,eAAe,KAAf,eAAe,QAa1B;AAED;;;GAGG;AACH,MAAM,CAAN,IAAY,0BAWX;AAXD,WAAY,0BAA0B;IACpC,0CAA0C;IAC1C,qDAAuB,CAAA;IACvB,sCAAsC;IACtC,6CAAe,CAAA;IACf,wCAAwC;IACxC,uDAAyB,CAAA;IACzB,oCAAoC;IACpC,6DAA+B,CAAA;IAC/B,qCAAqC;IACrC,iDAAmB,CAAA;AACrB,CAAC,EAXW,0BAA0B,KAA1B,0BAA0B,QAWrC;AAMD,MAAM,UAAU,4BAA4B,CAAC,KAAa;IACxD,OAAO,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,KAAa;IACrD,OAAO,MAAM,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;AAChG,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,kBAA0B,EAAE,MAAc;IAClF,gFAAgF;IAChF,MAAM,iBAAiB,GAAG,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,MAAM,GAAG,4BAA4B,CAAC,kBAAkB,CAAC,CAAC;IACjH,MAAM,mBAAmB,GAAG,MAAM,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC,MAAM,GAAG,yBAAyB,CAAC,MAAM,CAAC,CAAC;IAC/G,OAAO,mBAAmB,IAAI,iBAAiB,CAAC;AAClD,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare function isEmpty(anything?: unknown): boolean;
2
+ export declare function isNullish(anything: unknown): boolean;
3
+ export type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;
@@ -0,0 +1,13 @@
1
+ export function isEmpty(anything) {
2
+ if (isNullish(anything)) {
3
+ return true;
4
+ }
5
+ if (typeof anything === 'object') {
6
+ return Object.entries(anything).length === 0;
7
+ }
8
+ return false;
9
+ }
10
+ export function isNullish(anything) {
11
+ return !(Boolean(anything) && anything !== null);
12
+ }
13
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/libs/utils.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,OAAO,CAAC,QAAkB;IACxC,IAAI,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,OAAO,MAAM,CAAC,OAAO,CAAC,QAAS,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;IAChD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,QAAiB;IACzC,OAAO,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,QAAQ,KAAK,IAAI,CAAC,CAAC;AACnD,CAAC"}
@@ -0,0 +1,65 @@
1
+ import { MultiStageOutput, MultiStageOutputOptions } from '@oclif/multi-stage-output';
2
+ import AuditRun from '../libs/policies/auditRun.js';
3
+ export declare const LOAD_AUDIT_CONFIG = "Loading audit config";
4
+ export declare const RESOLVE_POLICIES = "Resolving policies";
5
+ export declare const EXECUTE_RULES = "Executing rules";
6
+ export declare const FINALISE = "Formatting results";
7
+ export type AuditRunStageOptions = {
8
+ targetOrg: string;
9
+ directoryRootPath: string;
10
+ jsonEnabled?: boolean;
11
+ };
12
+ /**
13
+ * This type mimics the original "StageBlockInfo" type from
14
+ * MultiStageOutput and allows us to make test asserts.
15
+ */
16
+ type StageBlockInfo<T> = {
17
+ stage: string;
18
+ type: 'dynamic-key-value' | 'static-key-value' | 'message';
19
+ label?: string;
20
+ get(data: T): string;
21
+ };
22
+ export default class AuditRunMultiStageOutput {
23
+ mso: MultiStageOutput<AuditRunData>;
24
+ stageSpecificBlocks: Array<StageBlockInfo<AuditRunData>>;
25
+ private polStats;
26
+ constructor(opts: MultiStageOutputOptions<AuditRunData>);
27
+ /**
28
+ * In unit tests, we stub the actual UX class to hide output in terminal.
29
+ *
30
+ * @param opts
31
+ * @returns
32
+ */
33
+ static initUx(opts: MultiStageOutputOptions<AuditRunData>): MultiStageOutput<AuditRunData>;
34
+ /**
35
+ * This pattern allows to stub multi-stage outputs in tests to mute output
36
+ * to stdout during test execution.
37
+ *
38
+ * In your code, create a new instance like this
39
+ * ```
40
+ * const ms = AuditRunMultiStageOutput.create(sobj, flags.json);
41
+ * ```
42
+ *
43
+ * @param opts
44
+ * @param jsonEnabled
45
+ * @returns
46
+ */
47
+ static create(opts: AuditRunStageOptions): AuditRunMultiStageOutput;
48
+ start(): void;
49
+ startPolicyResolve(runInstance: AuditRun): void;
50
+ startRuleExecution(): void;
51
+ finish(): void;
52
+ private addPolicyStatsListener;
53
+ }
54
+ export type AuditRunData = {
55
+ enabledRulesInPolicy: string[];
56
+ currentStatus: string;
57
+ policies: PolicyStatistics;
58
+ };
59
+ type PolicyStatistics = {
60
+ [policyName: string]: {
61
+ total?: number;
62
+ resolved?: number;
63
+ };
64
+ };
65
+ export {};