@j-schreiber/sf-cli-security-audit 0.8.2 → 0.8.3

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 (150) hide show
  1. package/lib/commands/org/audit/init.d.ts +19 -0
  2. package/lib/commands/org/audit/init.js +72 -0
  3. package/lib/commands/org/audit/init.js.map +1 -0
  4. package/lib/commands/org/audit/run.d.ts +23 -0
  5. package/lib/commands/org/audit/run.js +124 -0
  6. package/lib/commands/org/audit/run.js.map +1 -0
  7. package/lib/commands/org/scan/user-perms.d.ts +20 -0
  8. package/lib/commands/org/scan/user-perms.js +87 -0
  9. package/lib/commands/org/scan/user-perms.js.map +1 -0
  10. package/lib/libs/conf-init/auditConfig.d.ts +35 -0
  11. package/lib/libs/conf-init/auditConfig.js +41 -0
  12. package/lib/libs/conf-init/auditConfig.js.map +1 -0
  13. package/lib/libs/conf-init/permissionsClassification.d.ts +17 -0
  14. package/lib/libs/conf-init/permissionsClassification.js +80 -0
  15. package/lib/libs/conf-init/permissionsClassification.js.map +1 -0
  16. package/lib/libs/conf-init/policyConfigs.d.ts +31 -0
  17. package/lib/libs/conf-init/policyConfigs.js +91 -0
  18. package/lib/libs/conf-init/policyConfigs.js.map +1 -0
  19. package/lib/libs/conf-init/presets/loose.d.ts +6 -0
  20. package/lib/libs/conf-init/presets/loose.js +85 -0
  21. package/lib/libs/conf-init/presets/loose.js.map +1 -0
  22. package/lib/libs/conf-init/presets/none.d.ts +30 -0
  23. package/lib/libs/conf-init/presets/none.js +54 -0
  24. package/lib/libs/conf-init/presets/none.js.map +1 -0
  25. package/lib/libs/conf-init/presets/strict.d.ts +4 -0
  26. package/lib/libs/conf-init/presets/strict.js +79 -0
  27. package/lib/libs/conf-init/presets/strict.js.map +1 -0
  28. package/lib/libs/conf-init/presets.d.ts +7 -0
  29. package/lib/libs/conf-init/presets.js +20 -0
  30. package/lib/libs/conf-init/presets.js.map +1 -0
  31. package/lib/libs/core/auditRun.d.ts +36 -0
  32. package/lib/libs/core/auditRun.js +86 -0
  33. package/lib/libs/core/auditRun.js.map +1 -0
  34. package/lib/libs/core/classification-types.d.ts +20 -0
  35. package/lib/libs/core/classification-types.js +23 -0
  36. package/lib/libs/core/classification-types.js.map +1 -0
  37. package/lib/libs/core/constants.d.ts +10 -0
  38. package/lib/libs/core/constants.js +20 -0
  39. package/lib/libs/core/constants.js.map +1 -0
  40. package/lib/libs/core/file-mgmt/auditConfigFileManager.d.ts +48 -0
  41. package/lib/libs/core/file-mgmt/auditConfigFileManager.js +145 -0
  42. package/lib/libs/core/file-mgmt/auditConfigFileManager.js.map +1 -0
  43. package/lib/libs/core/file-mgmt/schema.d.ts +123 -0
  44. package/lib/libs/core/file-mgmt/schema.js +69 -0
  45. package/lib/libs/core/file-mgmt/schema.js.map +1 -0
  46. package/lib/libs/core/mdapi/mdapiRetriever.d.ts +54 -0
  47. package/lib/libs/core/mdapi/mdapiRetriever.js +123 -0
  48. package/lib/libs/core/mdapi/mdapiRetriever.js.map +1 -0
  49. package/lib/libs/core/mdapi/metadataRegistryEntry.d.ts +40 -0
  50. package/lib/libs/core/mdapi/metadataRegistryEntry.js +46 -0
  51. package/lib/libs/core/mdapi/metadataRegistryEntry.js.map +1 -0
  52. package/lib/libs/core/mdapi/namedMetadataToolingQueryable.d.ts +33 -0
  53. package/lib/libs/core/mdapi/namedMetadataToolingQueryable.js +41 -0
  54. package/lib/libs/core/mdapi/namedMetadataToolingQueryable.js.map +1 -0
  55. package/lib/libs/core/mdapi/namedMetadataType.d.ts +20 -0
  56. package/lib/libs/core/mdapi/namedMetadataType.js +41 -0
  57. package/lib/libs/core/mdapi/namedMetadataType.js.map +1 -0
  58. package/lib/libs/core/mdapi/singletonMetadataType.d.ts +21 -0
  59. package/lib/libs/core/mdapi/singletonMetadataType.js +37 -0
  60. package/lib/libs/core/mdapi/singletonMetadataType.js.map +1 -0
  61. package/lib/libs/core/mdapi/usersRepository.d.ts +85 -0
  62. package/lib/libs/core/mdapi/usersRepository.js +126 -0
  63. package/lib/libs/core/mdapi/usersRepository.js.map +1 -0
  64. package/lib/libs/core/policies/connectedAppPolicy.d.ts +10 -0
  65. package/lib/libs/core/policies/connectedAppPolicy.js +78 -0
  66. package/lib/libs/core/policies/connectedAppPolicy.js.map +1 -0
  67. package/lib/libs/core/policies/permissionSetPolicy.d.ts +11 -0
  68. package/lib/libs/core/policies/permissionSetPolicy.js +62 -0
  69. package/lib/libs/core/policies/permissionSetPolicy.js.map +1 -0
  70. package/lib/libs/core/policies/policy.d.ts +31 -0
  71. package/lib/libs/core/policies/policy.js +100 -0
  72. package/lib/libs/core/policies/policy.js.map +1 -0
  73. package/lib/libs/core/policies/profilePolicy.d.ts +11 -0
  74. package/lib/libs/core/policies/profilePolicy.js +64 -0
  75. package/lib/libs/core/policies/profilePolicy.js.map +1 -0
  76. package/lib/libs/core/policies/salesforceStandardTypes.d.ts +58 -0
  77. package/lib/libs/core/policies/salesforceStandardTypes.js +2 -0
  78. package/lib/libs/core/policies/salesforceStandardTypes.js.map +1 -0
  79. package/lib/libs/core/policies/userPolicy.d.ts +11 -0
  80. package/lib/libs/core/policies/userPolicy.js +60 -0
  81. package/lib/libs/core/policies/userPolicy.js.map +1 -0
  82. package/lib/libs/core/policy-types.d.ts +18 -0
  83. package/lib/libs/core/policy-types.js +28 -0
  84. package/lib/libs/core/policy-types.js.map +1 -0
  85. package/lib/libs/core/policyRegistry.d.ts +23 -0
  86. package/lib/libs/core/policyRegistry.js +38 -0
  87. package/lib/libs/core/policyRegistry.js.map +1 -0
  88. package/lib/libs/core/registries/connectedApps.d.ts +13 -0
  89. package/lib/libs/core/registries/connectedApps.js +13 -0
  90. package/lib/libs/core/registries/connectedApps.js.map +1 -0
  91. package/lib/libs/core/registries/helpers/permissionsScanning.d.ts +29 -0
  92. package/lib/libs/core/registries/helpers/permissionsScanning.js +69 -0
  93. package/lib/libs/core/registries/helpers/permissionsScanning.js.map +1 -0
  94. package/lib/libs/core/registries/permissionSets.d.ts +11 -0
  95. package/lib/libs/core/registries/permissionSets.js +11 -0
  96. package/lib/libs/core/registries/permissionSets.js.map +1 -0
  97. package/lib/libs/core/registries/profiles.d.ts +11 -0
  98. package/lib/libs/core/registries/profiles.js +11 -0
  99. package/lib/libs/core/registries/profiles.js.map +1 -0
  100. package/lib/libs/core/registries/ruleRegistry.d.ts +37 -0
  101. package/lib/libs/core/registries/ruleRegistry.js +48 -0
  102. package/lib/libs/core/registries/ruleRegistry.js.map +1 -0
  103. package/lib/libs/core/registries/rules/allUsedAppsUnderManagement.d.ts +7 -0
  104. package/lib/libs/core/registries/rules/allUsedAppsUnderManagement.js +23 -0
  105. package/lib/libs/core/registries/rules/allUsedAppsUnderManagement.js.map +1 -0
  106. package/lib/libs/core/registries/rules/enforcePermissionPresets.d.ts +7 -0
  107. package/lib/libs/core/registries/rules/enforcePermissionPresets.js +58 -0
  108. package/lib/libs/core/registries/rules/enforcePermissionPresets.js.map +1 -0
  109. package/lib/libs/core/registries/rules/enforcePermissionsOnProfileLike.d.ts +7 -0
  110. package/lib/libs/core/registries/rules/enforcePermissionsOnProfileLike.js +26 -0
  111. package/lib/libs/core/registries/rules/enforcePermissionsOnProfileLike.js.map +1 -0
  112. package/lib/libs/core/registries/rules/enforcePermissionsOnUser.d.ts +8 -0
  113. package/lib/libs/core/registries/rules/enforcePermissionsOnUser.js +42 -0
  114. package/lib/libs/core/registries/rules/enforcePermissionsOnUser.js.map +1 -0
  115. package/lib/libs/core/registries/rules/noInactiveUsers.d.ts +9 -0
  116. package/lib/libs/core/registries/rules/noInactiveUsers.js +44 -0
  117. package/lib/libs/core/registries/rules/noInactiveUsers.js.map +1 -0
  118. package/lib/libs/core/registries/rules/noOtherApexApiLogins.d.ts +7 -0
  119. package/lib/libs/core/registries/rules/noOtherApexApiLogins.js +27 -0
  120. package/lib/libs/core/registries/rules/noOtherApexApiLogins.js.map +1 -0
  121. package/lib/libs/core/registries/rules/noUserCanSelfAuthorize.d.ts +7 -0
  122. package/lib/libs/core/registries/rules/noUserCanSelfAuthorize.js +31 -0
  123. package/lib/libs/core/registries/rules/noUserCanSelfAuthorize.js.map +1 -0
  124. package/lib/libs/core/registries/rules/policyRule.d.ts +19 -0
  125. package/lib/libs/core/registries/rules/policyRule.js +32 -0
  126. package/lib/libs/core/registries/rules/policyRule.js.map +1 -0
  127. package/lib/libs/core/registries/types.d.ts +37 -0
  128. package/lib/libs/core/registries/types.js +11 -0
  129. package/lib/libs/core/registries/types.js.map +1 -0
  130. package/lib/libs/core/registries/users.d.ts +10 -0
  131. package/lib/libs/core/registries/users.js +17 -0
  132. package/lib/libs/core/registries/users.js.map +1 -0
  133. package/lib/libs/core/result-types.d.ts +172 -0
  134. package/lib/libs/core/result-types.js +2 -0
  135. package/lib/libs/core/result-types.js.map +1 -0
  136. package/lib/libs/core/utils.d.ts +12 -0
  137. package/lib/libs/core/utils.js +31 -0
  138. package/lib/libs/core/utils.js.map +1 -0
  139. package/lib/libs/quick-scan/types.d.ts +17 -0
  140. package/lib/libs/quick-scan/types.js +2 -0
  141. package/lib/libs/quick-scan/types.js.map +1 -0
  142. package/lib/libs/quick-scan/userPermissionScanner.d.ts +22 -0
  143. package/lib/libs/quick-scan/userPermissionScanner.js +75 -0
  144. package/lib/libs/quick-scan/userPermissionScanner.js.map +1 -0
  145. package/lib/ux/auditRunMultiStage.d.ts +65 -0
  146. package/lib/ux/auditRunMultiStage.js +120 -0
  147. package/lib/ux/auditRunMultiStage.js.map +1 -0
  148. package/oclif.manifest.json +253 -2
  149. package/package.json +1 -1
  150. package/bin/dev.js +0 -8
@@ -0,0 +1,46 @@
1
+ import { readFileSync, rmSync } from 'node:fs';
2
+ import path from 'node:path';
3
+ import { XMLParser } from 'fast-xml-parser';
4
+ import { RETRIEVE_CACHE } from '../constants.js';
5
+ export default class MetadataRegistryEntry {
6
+ opts;
7
+ parser;
8
+ retrieveType;
9
+ rootNodeName;
10
+ constructor(opts) {
11
+ this.opts = opts;
12
+ this.retrieveType = this.opts.retrieveType;
13
+ this.parser = this.opts.parser ?? new XMLParser();
14
+ this.rootNodeName = this.opts.rootNodeName;
15
+ }
16
+ parse(fullFilePath) {
17
+ const fileContent = readFileSync(fullFilePath, 'utf-8');
18
+ const parsedContent = this.parser.parse(fileContent);
19
+ if (this.opts.parsePostProcessor) {
20
+ return this.opts.parsePostProcessor(parsedContent[this.rootNodeName]);
21
+ }
22
+ return parsedContent[this.rootNodeName];
23
+ }
24
+ }
25
+ export async function retrieve(compSet, con) {
26
+ const retrieveRequest = await compSet.retrieve({
27
+ usernameOrConnection: con,
28
+ output: RETRIEVE_CACHE,
29
+ });
30
+ const retrieveResult = await retrieveRequest.pollStatus();
31
+ return retrieveResult;
32
+ }
33
+ export function cleanRetrieveDir(files) {
34
+ const dirNames = new Set();
35
+ files.forEach((file) => {
36
+ if (file.filePath) {
37
+ const dirName = path.dirname(path.normalize(file.filePath));
38
+ const parts = dirName.split(path.sep).filter((dirPart) => dirPart.startsWith('metadataPackage_'));
39
+ parts.forEach((mdPart) => dirNames.add(mdPart));
40
+ }
41
+ });
42
+ dirNames.forEach((dir) => {
43
+ rmSync(path.join(RETRIEVE_CACHE, dir), { recursive: true });
44
+ });
45
+ }
46
+ //# sourceMappingURL=metadataRegistryEntry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadataRegistryEntry.js","sourceRoot":"","sources":["../../../../src/libs/core/mdapi/metadataRegistryEntry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,YAAY,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACzD,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG5C,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AA8BjD,MAAM,CAAC,OAAO,OAAgB,qBAAqB;IAKtB;IAJpB,MAAM,CAAY;IAClB,YAAY,CAAS;IACrB,YAAY,CAAM;IAEzB,YAA2B,IAA0C;QAA1C,SAAI,GAAJ,IAAI,CAAsC;QACnE,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC;QAC3C,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAClD,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC;IAC7C,CAAC;IAEM,KAAK,CAAC,YAAsB;QACjC,MAAM,WAAW,GAAG,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QACxD,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAS,CAAC;QAC7D,IAAI,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC;YACjC,OAAO,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;QACxE,CAAC;QACD,OAAO,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC1C,CAAC;CACF;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,OAAqB,EAAE,GAAe;IACnE,MAAM,eAAe,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC;QAC7C,oBAAoB,EAAE,GAAG;QACzB,MAAM,EAAE,cAAc;KACvB,CAAC,CAAC;IACH,MAAM,cAAc,GAAG,MAAM,eAAe,CAAC,UAAU,EAAE,CAAC;IAC1D,OAAO,cAAc,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAAqB;IACpD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;IACnC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QACrB,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;YAC5D,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAC,CAAC;YAClG,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;QAClD,CAAC;IACH,CAAC,CAAC,CAAC;IACH,QAAQ,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;QACvB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,GAAG,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,33 @@
1
+ import { Connection } from '@salesforce/core';
2
+ import { NamedMetadataResolver } from './metadataRegistryEntry.js';
3
+ export type NamedMetadataQueryableOpts<Type> = {
4
+ /**
5
+ * Object API name to retrieve. Must be available in tooling API
6
+ */
7
+ objectName: string;
8
+ /**
9
+ * Unique name field that is used to retrieve the object
10
+ */
11
+ nameField: string;
12
+ /**
13
+ * Post processor function that sanitises the XML parse result
14
+ */
15
+ parsePostProcessor?: (parseResult: Type) => Type;
16
+ };
17
+ /**
18
+ * The entry is a typical named metadata that is organized in a dedicated source folder
19
+ * where all entities have the same format. The components are queried from tooling API
20
+ * and organized by their developer name.
21
+ */
22
+ export default class NamedMetadataQueryable<Type, Key extends keyof Type> implements NamedMetadataResolver<Type[Key]> {
23
+ private opts;
24
+ constructor(opts: NamedMetadataQueryableOpts<Type[Key]>);
25
+ /**
26
+ * Resolves a set of component names by querying "Metadata" property from tooling API
27
+ *
28
+ * @param con
29
+ * @param componentNames
30
+ * @returns
31
+ */
32
+ resolve(con: Connection, componentNames: string[]): Promise<Record<string, Type[Key]>>;
33
+ }
@@ -0,0 +1,41 @@
1
+ import { isNullish } from '../utils.js';
2
+ /**
3
+ * The entry is a typical named metadata that is organized in a dedicated source folder
4
+ * where all entities have the same format. The components are queried from tooling API
5
+ * and organized by their developer name.
6
+ */
7
+ export default class NamedMetadataQueryable {
8
+ opts;
9
+ constructor(opts) {
10
+ this.opts = opts;
11
+ }
12
+ /**
13
+ * Resolves a set of component names by querying "Metadata" property from tooling API
14
+ *
15
+ * @param con
16
+ * @param componentNames
17
+ * @returns
18
+ */
19
+ async resolve(con, componentNames) {
20
+ const pendingQueries = new Array();
21
+ componentNames.forEach((cname) => {
22
+ const qr = Promise.resolve(con.tooling.query(`SELECT ${this.opts.nameField},Metadata FROM ${this.opts.objectName} WHERE ${this.opts.nameField} = '${cname}'`));
23
+ pendingQueries.push(qr);
24
+ });
25
+ const queryResults = await Promise.all(pendingQueries);
26
+ const resultMap = {};
27
+ queryResults.forEach((qr) => {
28
+ if (qr.totalSize > 0) {
29
+ const record = qr.records[0];
30
+ const identifier = record[this.opts.nameField];
31
+ if (identifier && !isNullish(record.Metadata)) {
32
+ resultMap[identifier] = this.opts.parsePostProcessor
33
+ ? this.opts.parsePostProcessor(record.Metadata)
34
+ : record.Metadata;
35
+ }
36
+ }
37
+ });
38
+ return resultMap;
39
+ }
40
+ }
41
+ //# sourceMappingURL=namedMetadataToolingQueryable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"namedMetadataToolingQueryable.js","sourceRoot":"","sources":["../../../../src/libs/core/mdapi/namedMetadataToolingQueryable.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAoBxC;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,sBAAsB;IACd;IAA3B,YAA2B,IAA2C;QAA3C,SAAI,GAAJ,IAAI,CAAuC;IAAG,CAAC;IAC1E;;;;;;OAMG;IACI,KAAK,CAAC,OAAO,CAAC,GAAe,EAAE,cAAwB;QAC5D,MAAM,cAAc,GAAG,IAAI,KAAK,EAAmD,CAAC;QACpF,cAAc,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YAC/B,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CACxB,GAAG,CAAC,OAAO,CAAC,KAAK,CACf,UAAU,IAAI,CAAC,IAAI,CAAC,SAAS,kBAAkB,IAAI,CAAC,IAAI,CAAC,UAAU,UAAU,IAAI,CAAC,IAAI,CAAC,SAAS,OAAO,KAAK,GAAG,CAChH,CACF,CAAC;YACF,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;QACH,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QACvD,MAAM,SAAS,GAA8B,EAAE,CAAC;QAChD,YAAY,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE;YAC1B,IAAI,EAAE,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC;gBACrB,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;gBAC7B,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAW,CAAC;gBACzD,IAAI,UAAU,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAC9C,SAAS,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,kBAAkB;wBAClD,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,QAAQ,CAAC;wBAC/C,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;gBACtB,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;QACH,OAAO,SAAS,CAAC;IACnB,CAAC;CACF"}
@@ -0,0 +1,20 @@
1
+ import { Connection } from '@salesforce/core';
2
+ import MetadataRegistryEntry, { MetadataRegistryEntryOpts } from './metadataRegistryEntry.js';
3
+ /**
4
+ * The entry is a typical named metadata that is organized in a dedicated source folder
5
+ * where all entities have the same format. The components are retrieved and organized
6
+ * by their developer name.
7
+ */
8
+ export default class NamedMetadata<Type, Key extends keyof Type> extends MetadataRegistryEntry<Type, Key> {
9
+ constructor(opts: MetadataRegistryEntryOpts<Type, Key>);
10
+ /**
11
+ * Resolves component names, retrieves the metadata and returns
12
+ * as a strongly typed result.
13
+ *
14
+ * @param con
15
+ * @param componentNames
16
+ * @returns
17
+ */
18
+ resolve(con: Connection, componentNames: string[]): Promise<Record<string, Type[Key]>>;
19
+ private parseSourceFiles;
20
+ }
@@ -0,0 +1,41 @@
1
+ import { ComponentSet } from '@salesforce/source-deploy-retrieve';
2
+ import MetadataRegistryEntry, { cleanRetrieveDir, retrieve, } from './metadataRegistryEntry.js';
3
+ /**
4
+ * The entry is a typical named metadata that is organized in a dedicated source folder
5
+ * where all entities have the same format. The components are retrieved and organized
6
+ * by their developer name.
7
+ */
8
+ export default class NamedMetadata extends MetadataRegistryEntry {
9
+ constructor(opts) {
10
+ super(opts);
11
+ }
12
+ /**
13
+ * Resolves component names, retrieves the metadata and returns
14
+ * as a strongly typed result.
15
+ *
16
+ * @param con
17
+ * @param componentNames
18
+ * @returns
19
+ */
20
+ async resolve(con, componentNames) {
21
+ const cmpSet = new ComponentSet(componentNames.map((cname) => ({ type: this.retrieveType, fullName: cname })));
22
+ const retrieveResult = await retrieve(cmpSet, con);
23
+ const resolvedFiles = this.parseSourceFiles(retrieveResult.components, componentNames);
24
+ cleanRetrieveDir(retrieveResult.getFileResponses());
25
+ return resolvedFiles;
26
+ }
27
+ parseSourceFiles(componentSet, retrievedNames) {
28
+ const cmps = componentSet.getSourceComponents().toArray();
29
+ const result = {};
30
+ cmps.forEach((sourceComponent) => {
31
+ if (sourceComponent.xml && retrievedNames.includes(sourceComponent.name)) {
32
+ // the available method parseXmlSync on source component does not
33
+ // resolve the "rootNodeProblem" from XML. Therefore, we implement
34
+ // our own method to parse and return the "inner xml".
35
+ result[sourceComponent.name] = this.parse(sourceComponent.xml);
36
+ }
37
+ });
38
+ return result;
39
+ }
40
+ }
41
+ //# sourceMappingURL=namedMetadataType.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"namedMetadataType.js","sourceRoot":"","sources":["../../../../src/libs/core/mdapi/namedMetadataType.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAClE,OAAO,qBAAqB,EAAE,EAC5B,gBAAgB,EAEhB,QAAQ,GACT,MAAM,4BAA4B,CAAC;AAEpC;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,aAA4C,SAAQ,qBAAgC;IACvG,YAAmB,IAA0C;QAC3D,KAAK,CAAC,IAAI,CAAC,CAAC;IACd,CAAC;IACD;;;;;;;OAOG;IACI,KAAK,CAAC,OAAO,CAAC,GAAe,EAAE,cAAwB;QAC5D,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;QAC/G,MAAM,cAAc,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACnD,MAAM,aAAa,GAAG,IAAI,CAAC,gBAAgB,CAAC,cAAc,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;QACvF,gBAAgB,CAAC,cAAc,CAAC,gBAAgB,EAAE,CAAC,CAAC;QACpD,OAAO,aAAa,CAAC;IACvB,CAAC;IAEO,gBAAgB,CAAC,YAA0B,EAAE,cAAwB;QAC3E,MAAM,IAAI,GAAG,YAAY,CAAC,mBAAmB,EAAE,CAAC,OAAO,EAAE,CAAC;QAC1D,MAAM,MAAM,GAA8B,EAAE,CAAC;QAC7C,IAAI,CAAC,OAAO,CAAC,CAAC,eAAe,EAAE,EAAE;YAC/B,IAAI,eAAe,CAAC,GAAG,IAAI,cAAc,CAAC,QAAQ,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;gBACzE,iEAAiE;gBACjE,kEAAkE;gBAClE,sDAAsD;gBACtD,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;YACjE,CAAC;QACH,CAAC,CAAC,CAAC;QACH,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"}
@@ -0,0 +1,21 @@
1
+ import { Connection } from '@salesforce/core';
2
+ import MetadataRegistryEntry, { MetadataRegistryEntryOpts } from './metadataRegistryEntry.js';
3
+ /**
4
+ * The entry is a type that only has one single instance on the org, such as
5
+ * a Setting. The component is typically retrieved by a more generic name and
6
+ * organized & cached by the explicit name.
7
+ */
8
+ export default class SingletonMetadata<Type, Key extends keyof Type> extends MetadataRegistryEntry<Type, Key> {
9
+ retrieveName: string;
10
+ constructor(opts: MetadataRegistryEntryOpts<Type, Key>);
11
+ /**
12
+ * Resolves component names, retrieves the metadata and returns
13
+ * as a strongly typed result.
14
+ *
15
+ * @param con
16
+ * @param componentNames
17
+ * @returns
18
+ */
19
+ resolve(con: Connection): Promise<Type[Key]>;
20
+ private parseSourceFile;
21
+ }
@@ -0,0 +1,37 @@
1
+ import { ComponentSet } from '@salesforce/source-deploy-retrieve';
2
+ import MetadataRegistryEntry, { cleanRetrieveDir, retrieve, } from './metadataRegistryEntry.js';
3
+ /**
4
+ * The entry is a type that only has one single instance on the org, such as
5
+ * a Setting. The component is typically retrieved by a more generic name and
6
+ * organized & cached by the explicit name.
7
+ */
8
+ export default class SingletonMetadata extends MetadataRegistryEntry {
9
+ retrieveName;
10
+ constructor(opts) {
11
+ super(opts);
12
+ this.retrieveName = opts.retrieveName ?? String(this.rootNodeName);
13
+ }
14
+ /**
15
+ * Resolves component names, retrieves the metadata and returns
16
+ * as a strongly typed result.
17
+ *
18
+ * @param con
19
+ * @param componentNames
20
+ * @returns
21
+ */
22
+ async resolve(con) {
23
+ const cmpSet = new ComponentSet([{ type: this.retrieveType, fullName: this.retrieveName }]);
24
+ const retrieveResult = await retrieve(cmpSet, con);
25
+ const resolvedCmp = this.parseSourceFile(retrieveResult.components);
26
+ cleanRetrieveDir(retrieveResult.getFileResponses());
27
+ return resolvedCmp;
28
+ }
29
+ parseSourceFile(componentSet) {
30
+ const cmps = componentSet.getSourceComponents({ type: this.retrieveType, fullName: this.retrieveName }).toArray();
31
+ if (cmps.length > 0 && cmps[0].xml) {
32
+ return this.parse(cmps[0].xml);
33
+ }
34
+ throw new Error('Failed to resolve settings for: ' + this.retrieveName);
35
+ }
36
+ }
37
+ //# sourceMappingURL=singletonMetadataType.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"singletonMetadataType.js","sourceRoot":"","sources":["../../../../src/libs/core/mdapi/singletonMetadataType.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAClE,OAAO,qBAAqB,EAAE,EAC5B,gBAAgB,EAEhB,QAAQ,GACT,MAAM,4BAA4B,CAAC;AAEpC;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,iBAAgD,SAAQ,qBAAgC;IACpG,YAAY,CAAS;IAC5B,YAAmB,IAA0C;QAC3D,KAAK,CAAC,IAAI,CAAC,CAAC;QACZ,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACrE,CAAC;IAED;;;;;;;OAOG;IACI,KAAK,CAAC,OAAO,CAAC,GAAe;QAClC,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,QAAQ,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;QAC5F,MAAM,cAAc,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACnD,MAAM,WAAW,GAAG,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;QACpE,gBAAgB,CAAC,cAAc,CAAC,gBAAgB,EAAE,CAAC,CAAC;QACpD,OAAO,WAAW,CAAC;IACrB,CAAC;IAEO,eAAe,CAAC,YAA0B;QAChD,MAAM,IAAI,GAAG,YAAY,CAAC,mBAAmB,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,QAAQ,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;QAClH,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;YACnC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACjC,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,kCAAkC,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC;IAC1E,CAAC;CACF"}
@@ -0,0 +1,85 @@
1
+ import { Connection } from '@salesforce/core';
2
+ import { PermissionSet, Profile } from '@jsforce/jsforce-node/lib/api/metadata.js';
3
+ export type User = {
4
+ userId: string;
5
+ username: string;
6
+ profileName: string;
7
+ createdDate: number;
8
+ lastLogin?: number;
9
+ logins?: UserLogins[];
10
+ };
11
+ export type UserPermissions = {
12
+ profileMetadata?: Profile;
13
+ assignedPermissionsets: PermissionSetAssignment[];
14
+ };
15
+ export type UserLogins = {
16
+ loginType: string;
17
+ application: string;
18
+ loginCount: number;
19
+ lastLogin: number;
20
+ };
21
+ export type PermissionSetAssignment = {
22
+ /**
23
+ * Developer name of the permission set
24
+ */
25
+ permissionSetIdentifier: string;
26
+ /**
27
+ * How user got this permission set assigned
28
+ */
29
+ permissionSetSource: 'direct' | 'group';
30
+ /**
31
+ * Metadata of the permission set
32
+ */
33
+ metadata?: PermissionSet;
34
+ /**
35
+ * If permission set is assigned through a group,
36
+ * this is the name of the group.
37
+ */
38
+ groupName?: string;
39
+ };
40
+ export type ResolveUsersOptions = {
41
+ /**
42
+ * Include aggregated login history
43
+ */
44
+ withLoginHistory: boolean;
45
+ /**
46
+ * When login history is set, the number of days that is searched
47
+ */
48
+ loginHistoryDaysToAnalyse?: number;
49
+ };
50
+ export type ResolvePermissionsOptions = {
51
+ /**
52
+ * Resolve permission set and profile metadata
53
+ */
54
+ withMetadata: boolean;
55
+ };
56
+ export default class UsersRepository {
57
+ private readonly connection;
58
+ private readonly mdapiRepo;
59
+ constructor(connection: Connection);
60
+ /**
61
+ * Resolves all users from the target org of this repository
62
+ *
63
+ * @param opts
64
+ * @returns
65
+ */
66
+ resolveAllUsers(opts?: ResolveUsersOptions): Promise<Map<string, User>>;
67
+ /**
68
+ * Resolves permission-granting entities (profiles and permission sets)
69
+ * for a list of users.
70
+ *
71
+ * @param userIds Users to be resolved
72
+ * @returns Map of permissions organized by user id
73
+ */
74
+ resolveUserPermissions(users: User[], opts?: ResolvePermissionsOptions): Promise<Map<string, UserPermissions>>;
75
+ /**
76
+ * Resolves all permission set assignments for the user with metadata of the
77
+ * permission set. If the user has no assignments, an empty list is returned.
78
+ *
79
+ * @param userIds
80
+ * @returns
81
+ */
82
+ resolvePermissionSetAssignments(userIds: string[], opts?: ResolvePermissionsOptions): Promise<Map<string, PermissionSetAssignment[]>>;
83
+ private resolveLogins;
84
+ private fetchAssignments;
85
+ }
@@ -0,0 +1,126 @@
1
+ import { ACTIVE_USERS_DETAILS_QUERY, buildLoginHistoryQuery, buildPermsetAssignmentsQuery } from '../constants.js';
2
+ import { isNullish } from '../utils.js';
3
+ import MDAPI from './mdapiRetriever.js';
4
+ export default class UsersRepository {
5
+ connection;
6
+ mdapiRepo;
7
+ constructor(connection) {
8
+ this.connection = connection;
9
+ this.mdapiRepo = MDAPI.create(this.connection);
10
+ }
11
+ /**
12
+ * Resolves all users from the target org of this repository
13
+ *
14
+ * @param opts
15
+ * @returns
16
+ */
17
+ async resolveAllUsers(opts) {
18
+ const result = new Map();
19
+ const allUsersOnOrg = await this.connection.query(ACTIVE_USERS_DETAILS_QUERY);
20
+ for (const user of allUsersOnOrg.records) {
21
+ const usr = {
22
+ userId: user.Id,
23
+ username: user.Username,
24
+ lastLogin: user.LastLoginDate ? Date.parse(user.LastLoginDate) : undefined,
25
+ createdDate: Date.parse(user.CreatedDate),
26
+ profileName: user.Profile.Name,
27
+ };
28
+ result.set(user.Username, usr);
29
+ }
30
+ if (opts?.withLoginHistory) {
31
+ const userLogins = await this.resolveLogins(opts.loginHistoryDaysToAnalyse);
32
+ for (const user of result.values()) {
33
+ if (userLogins.has(user.userId)) {
34
+ user.logins = userLogins.get(user.userId);
35
+ }
36
+ else {
37
+ user.logins = [];
38
+ }
39
+ }
40
+ }
41
+ return result;
42
+ }
43
+ /**
44
+ * Resolves permission-granting entities (profiles and permission sets)
45
+ * for a list of users.
46
+ *
47
+ * @param userIds Users to be resolved
48
+ * @returns Map of permissions organized by user id
49
+ */
50
+ async resolveUserPermissions(users, opts) {
51
+ const result = new Map();
52
+ const permsets = await this.resolvePermissionSetAssignments(users.map((usr) => usr.userId), opts);
53
+ const profiles = opts?.withMetadata
54
+ ? await this.mdapiRepo.resolve('Profile', uniqueProfileNames(Object.values(users)))
55
+ : {};
56
+ for (const user of users) {
57
+ result.set(user.userId, {
58
+ assignedPermissionsets: permsets.get(user.userId) ?? [],
59
+ profileMetadata: profiles[user.profileName],
60
+ });
61
+ }
62
+ return result;
63
+ }
64
+ /**
65
+ * Resolves all permission set assignments for the user with metadata of the
66
+ * permission set. If the user has no assignments, an empty list is returned.
67
+ *
68
+ * @param userIds
69
+ * @returns
70
+ */
71
+ async resolvePermissionSetAssignments(userIds, opts) {
72
+ const result = new Map();
73
+ const { assignments, permSetNames } = await this.fetchAssignments(userIds);
74
+ const permsets = opts?.withMetadata ? await this.mdapiRepo.resolve('PermissionSet', permSetNames) : {};
75
+ for (const userId of userIds) {
76
+ result.set(userId, assignments.get(userId)
77
+ ? assignments.get(userId).map((ass) => ({
78
+ ...ass,
79
+ metadata: permsets[ass.permissionSetIdentifier],
80
+ }))
81
+ : []);
82
+ }
83
+ return result;
84
+ }
85
+ async resolveLogins(daysToAnalyse) {
86
+ const loginHistory = await this.connection.query(buildLoginHistoryQuery(daysToAnalyse));
87
+ const partialUsers = new Map();
88
+ for (const loginHistoryRow of loginHistory.records) {
89
+ if (!partialUsers.has(loginHistoryRow.UserId)) {
90
+ partialUsers.set(loginHistoryRow.UserId, []);
91
+ }
92
+ partialUsers.get(loginHistoryRow.UserId).push({
93
+ loginType: loginHistoryRow.LoginType,
94
+ loginCount: loginHistoryRow.LoginCount,
95
+ application: loginHistoryRow.Application,
96
+ lastLogin: Date.parse(loginHistoryRow.LastLogin),
97
+ });
98
+ }
99
+ return partialUsers;
100
+ }
101
+ async fetchAssignments(userIds) {
102
+ const assignments = new Map();
103
+ const uniquePermSets = new Set();
104
+ const rawAssignment = await this.connection.query(buildPermsetAssignmentsQuery(userIds));
105
+ for (const assignment of rawAssignment.records) {
106
+ if (isNullish(assignments.get(assignment.AssigneeId))) {
107
+ assignments.set(assignment.AssigneeId, []);
108
+ }
109
+ assignments.get(assignment.AssigneeId).push({
110
+ permissionSetIdentifier: assignment.PermissionSet.Name,
111
+ permissionSetSource: assignment.PermissionSetGroupId ? 'group' : 'direct',
112
+ groupName: assignment.PermissionSetGroup?.DeveloperName,
113
+ });
114
+ uniquePermSets.add(assignment.PermissionSet.Name);
115
+ }
116
+ return { assignments, permSetNames: Array.from(uniquePermSets) };
117
+ }
118
+ }
119
+ function uniqueProfileNames(users) {
120
+ const uniqueProfiles = new Set();
121
+ for (const usr of users) {
122
+ uniqueProfiles.add(usr.profileName);
123
+ }
124
+ return Array.from(uniqueProfiles);
125
+ }
126
+ //# sourceMappingURL=usersRepository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usersRepository.js","sourceRoot":"","sources":["../../../../src/libs/core/mdapi/usersRepository.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import { AuditRunConfig, BasePolicyFileContent } from '../file-mgmt/schema.js';
2
+ import { AuditContext } from '../registries/types.js';
3
+ import { ResolvedConnectedApp } from '../registries/connectedApps.js';
4
+ import Policy, { ResolveEntityResult } from './policy.js';
5
+ export default class ConnectedAppPolicy extends Policy<ResolvedConnectedApp> {
6
+ config: BasePolicyFileContent;
7
+ auditConfig: AuditRunConfig;
8
+ constructor(config: BasePolicyFileContent, auditConfig: AuditRunConfig, registry?: import("../registries/connectedApps.js").default);
9
+ protected resolveEntities(context: AuditContext): Promise<ResolveEntityResult<ResolvedConnectedApp>>;
10
+ }
@@ -0,0 +1,78 @@
1
+ import { CONNECTED_APPS_QUERY, OAUTH_TOKEN_QUERY } from '../constants.js';
2
+ import { ConnectedAppsRegistry } from '../registries/connectedApps.js';
3
+ import MDAPI from '../mdapi/mdapiRetriever.js';
4
+ import Policy, { getTotal } from './policy.js';
5
+ export default class ConnectedAppPolicy extends Policy {
6
+ config;
7
+ auditConfig;
8
+ constructor(config, auditConfig, registry = ConnectedAppsRegistry) {
9
+ super(config, auditConfig, registry);
10
+ this.config = config;
11
+ this.auditConfig = auditConfig;
12
+ }
13
+ // eslint-disable-next-line class-methods-use-this
14
+ async resolveEntities(context) {
15
+ const successfullyResolved = {};
16
+ const ignoredEntities = {};
17
+ const metadataApi = new MDAPI(context.targetOrgConnection);
18
+ this.emit('entityresolve', {
19
+ total: 0,
20
+ resolved: 0,
21
+ });
22
+ const installedApps = await context.targetOrgConnection.query(CONNECTED_APPS_QUERY);
23
+ this.emit('entityresolve', {
24
+ total: installedApps.totalSize,
25
+ resolved: 0,
26
+ });
27
+ installedApps.records.forEach((installedApp) => {
28
+ successfullyResolved[installedApp.Name] = {
29
+ name: installedApp.Name,
30
+ origin: 'Installed',
31
+ onlyAdminApprovedUsersAllowed: installedApp.OptionsAllowAdminApprovedUsersOnly,
32
+ overrideByApiSecurityAccess: false,
33
+ useCount: 0,
34
+ users: [],
35
+ };
36
+ });
37
+ const usersOAuthToken = await context.targetOrgConnection.query(OAUTH_TOKEN_QUERY);
38
+ usersOAuthToken.records.forEach((token) => {
39
+ if (successfullyResolved[token.AppName] === undefined) {
40
+ successfullyResolved[token.AppName] = {
41
+ name: token.AppName,
42
+ origin: 'OauthToken',
43
+ onlyAdminApprovedUsersAllowed: false,
44
+ overrideByApiSecurityAccess: false,
45
+ useCount: token.UseCount,
46
+ users: [token.User.Username],
47
+ };
48
+ }
49
+ else {
50
+ successfullyResolved[token.AppName].useCount += token.UseCount;
51
+ if (!successfullyResolved[token.AppName].users.includes(token.User.Username)) {
52
+ successfullyResolved[token.AppName].users.push(token.User.Username);
53
+ }
54
+ }
55
+ });
56
+ this.emit('entityresolve', {
57
+ total: Object.keys(successfullyResolved).length,
58
+ resolved: 0,
59
+ });
60
+ let overrideByApiSecurityAccess = false;
61
+ const apiSecurityAccessSetting = await metadataApi.resolveSingleton('ConnectedAppSettings');
62
+ if (apiSecurityAccessSetting && apiSecurityAccessSetting.enableAdminApprovedAppsOnly) {
63
+ overrideByApiSecurityAccess = true;
64
+ }
65
+ Object.values(successfullyResolved).forEach((conApp) => {
66
+ // eslint-disable-next-line no-param-reassign
67
+ conApp.overrideByApiSecurityAccess = overrideByApiSecurityAccess;
68
+ });
69
+ const result = { resolvedEntities: successfullyResolved, ignoredEntities: Object.values(ignoredEntities) };
70
+ this.emit('entityresolve', {
71
+ total: getTotal(result),
72
+ resolved: getTotal(result),
73
+ });
74
+ // also query from tooling, to get additional information info
75
+ return result;
76
+ }
77
+ }
78
+ //# sourceMappingURL=connectedAppPolicy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connectedAppPolicy.js","sourceRoot":"","sources":["../../../../src/libs/core/policies/connectedAppPolicy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { AuditRunConfig, PermSetsPolicyFileContent } from '../file-mgmt/schema.js';
2
+ import { AuditContext } from '../registries/types.js';
3
+ import { ResolvedPermissionSet } from '../registries/permissionSets.js';
4
+ import Policy, { ResolveEntityResult } from './policy.js';
5
+ export default class PermissionSetPolicy extends Policy<ResolvedPermissionSet> {
6
+ config: PermSetsPolicyFileContent;
7
+ auditContext: AuditRunConfig;
8
+ private totalEntities;
9
+ constructor(config: PermSetsPolicyFileContent, auditContext: AuditRunConfig, registry?: import("../registries/permissionSets.js").default);
10
+ protected resolveEntities(context: AuditContext): Promise<ResolveEntityResult<ResolvedPermissionSet>>;
11
+ }