@j-schreiber/sf-cli-security-audit 0.6.0 → 0.7.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.
- package/README.md +39 -2
- package/lib/commands/org/audit/init.js +2 -1
- package/lib/commands/org/audit/init.js.map +1 -1
- package/lib/commands/org/audit/run.js +10 -4
- package/lib/commands/org/audit/run.js.map +1 -1
- package/lib/commands/org/scan/user-perms.js +1 -2
- package/lib/commands/org/scan/user-perms.js.map +1 -1
- package/lib/libs/conf-init/auditConfig.js +5 -4
- package/lib/libs/conf-init/auditConfig.js.map +1 -1
- package/lib/libs/conf-init/policyConfigs.d.ts +7 -1
- package/lib/libs/conf-init/policyConfigs.js +29 -3
- package/lib/libs/conf-init/policyConfigs.js.map +1 -1
- package/lib/libs/conf-init/presets/loose.js +16 -0
- package/lib/libs/conf-init/presets/loose.js.map +1 -1
- package/lib/libs/conf-init/presets/strict.js +17 -0
- package/lib/libs/conf-init/presets/strict.js.map +1 -1
- package/lib/libs/{policies → core}/auditRun.d.ts +4 -4
- package/lib/libs/{policies → core}/auditRun.js +8 -14
- package/lib/libs/core/auditRun.js.map +1 -0
- package/lib/libs/core/constants.d.ts +5 -0
- package/lib/libs/core/constants.js +10 -0
- package/lib/libs/core/constants.js.map +1 -1
- package/lib/libs/core/file-mgmt/auditConfigFileManager.d.ts +4 -2
- package/lib/libs/core/file-mgmt/auditConfigFileManager.js +30 -49
- package/lib/libs/core/file-mgmt/auditConfigFileManager.js.map +1 -1
- package/lib/libs/core/file-mgmt/schema.d.ts +32 -11
- package/lib/libs/core/file-mgmt/schema.js +14 -1
- package/lib/libs/core/file-mgmt/schema.js.map +1 -1
- package/lib/libs/core/policies/connectedAppPolicy.d.ts +10 -0
- package/lib/libs/{policies → core/policies}/connectedAppPolicy.js +4 -4
- package/lib/libs/core/policies/connectedAppPolicy.js.map +1 -0
- package/lib/libs/core/policies/permissionSetPolicy.d.ts +11 -0
- package/lib/libs/{policies → core/policies}/permissionSetPolicy.js +4 -4
- package/lib/libs/core/policies/permissionSetPolicy.js.map +1 -0
- package/lib/libs/{policies → core/policies}/policy.d.ts +11 -11
- package/lib/libs/{policies → core/policies}/policy.js +5 -0
- package/lib/libs/core/policies/policy.js.map +1 -0
- package/lib/libs/core/policies/profilePolicy.d.ts +11 -0
- package/lib/libs/{policies → core/policies}/profilePolicy.js +4 -4
- package/lib/libs/core/policies/profilePolicy.js.map +1 -0
- package/lib/libs/{policies → core/policies}/salesforceStandardTypes.d.ts +14 -0
- package/lib/libs/core/policies/salesforceStandardTypes.js.map +1 -0
- package/lib/libs/core/policies/userPolicy.d.ts +11 -0
- package/lib/libs/core/policies/userPolicy.js +104 -0
- package/lib/libs/core/policies/userPolicy.js.map +1 -0
- package/lib/libs/core/policyRegistry.d.ts +23 -0
- package/lib/libs/core/policyRegistry.js +38 -0
- package/lib/libs/core/policyRegistry.js.map +1 -0
- package/lib/libs/core/registries/ruleRegistry.d.ts +1 -3
- package/lib/libs/core/registries/ruleRegistry.js +1 -1
- package/lib/libs/core/registries/ruleRegistry.js.map +1 -1
- package/lib/libs/core/registries/rules/noInactiveUsers.d.ts +9 -0
- package/lib/libs/core/registries/rules/noInactiveUsers.js +44 -0
- package/lib/libs/core/registries/rules/noInactiveUsers.js.map +1 -0
- package/lib/libs/core/registries/rules/noOtherApexApiLogins.d.ts +7 -0
- package/lib/libs/core/registries/rules/noOtherApexApiLogins.js +24 -0
- package/lib/libs/core/registries/rules/noOtherApexApiLogins.js.map +1 -0
- package/lib/libs/core/registries/rules/policyRule.d.ts +4 -1
- package/lib/libs/core/registries/rules/policyRule.js +2 -0
- package/lib/libs/core/registries/rules/policyRule.js.map +1 -1
- package/lib/libs/core/registries/types.d.ts +2 -0
- package/lib/libs/core/registries/types.js +2 -0
- package/lib/libs/core/registries/types.js.map +1 -1
- package/lib/libs/core/registries/users.d.ts +26 -0
- package/lib/libs/core/registries/users.js +10 -0
- package/lib/libs/core/registries/users.js.map +1 -0
- package/lib/libs/core/result-types.d.ts +2 -1
- package/lib/libs/core/utils.d.ts +7 -0
- package/lib/libs/core/utils.js +12 -0
- package/lib/libs/core/utils.js.map +1 -1
- package/lib/ux/auditRunMultiStage.d.ts +1 -1
- package/lib/ux/auditRunMultiStage.js +22 -19
- package/lib/ux/auditRunMultiStage.js.map +1 -1
- package/messages/org.scan.user-perms.md +2 -6
- package/messages/policies.general.md +4 -0
- package/messages/rules.users.md +11 -0
- package/oclif.manifest.json +79 -79
- package/package.json +1 -1
- package/lib/libs/policies/auditRun.js.map +0 -1
- package/lib/libs/policies/connectedAppPolicy.d.ts +0 -9
- package/lib/libs/policies/connectedAppPolicy.js.map +0 -1
- package/lib/libs/policies/permissionSetPolicy.d.ts +0 -10
- package/lib/libs/policies/permissionSetPolicy.js.map +0 -1
- package/lib/libs/policies/policy.js.map +0 -1
- package/lib/libs/policies/profilePolicy.d.ts +0 -10
- package/lib/libs/policies/profilePolicy.js.map +0 -1
- package/lib/libs/policies/salesforceStandardTypes.js.map +0 -1
- /package/lib/libs/{policies → core/policies}/salesforceStandardTypes.js +0 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { Messages } from '@salesforce/core';
|
|
2
|
+
import { ACTIVE_USERS_DETAILS_QUERY, buildLoginHistoryQuery } from '../constants.js';
|
|
3
|
+
import { UsersRegistry } from '../registries/users.js';
|
|
4
|
+
import { ProfilesRiskPreset } from '../policy-types.js';
|
|
5
|
+
import Policy, { getTotal } from './policy.js';
|
|
6
|
+
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
|
|
7
|
+
const messages = Messages.loadMessages('@j-schreiber/sf-cli-security-audit', 'policies.general');
|
|
8
|
+
export default class UserPolicy extends Policy {
|
|
9
|
+
config;
|
|
10
|
+
auditConfig;
|
|
11
|
+
totalEntities;
|
|
12
|
+
constructor(config, auditConfig, registry = UsersRegistry) {
|
|
13
|
+
super(config, auditConfig, registry);
|
|
14
|
+
this.config = config;
|
|
15
|
+
this.auditConfig = auditConfig;
|
|
16
|
+
this.totalEntities = this.config.users ? Object.keys(this.config.users).length : 0;
|
|
17
|
+
}
|
|
18
|
+
async resolveEntities(context) {
|
|
19
|
+
this.emit('entityresolve', {
|
|
20
|
+
total: this.totalEntities,
|
|
21
|
+
resolved: 0,
|
|
22
|
+
});
|
|
23
|
+
const usersById = {};
|
|
24
|
+
const ignoredEntities = {};
|
|
25
|
+
const configuredUsers = this.config.users ?? {};
|
|
26
|
+
const classifiedUsers = [];
|
|
27
|
+
const userIds = [];
|
|
28
|
+
Object.entries(configuredUsers).forEach(([userName, userDef]) => {
|
|
29
|
+
if (userDef.role === ProfilesRiskPreset.UNKNOWN) {
|
|
30
|
+
ignoredEntities[userName] = {
|
|
31
|
+
name: userName,
|
|
32
|
+
message: messages.getMessage('user-with-role-unknown'),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
classifiedUsers.push(userName);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
// fetch all users from org and merge with configured users
|
|
40
|
+
const allUsersOnOrg = await context.targetOrgConnection.query(ACTIVE_USERS_DETAILS_QUERY);
|
|
41
|
+
allUsersOnOrg.records.forEach((user) => {
|
|
42
|
+
if (ignoredEntities[user.Username] === undefined) {
|
|
43
|
+
usersById[user.Id] = {
|
|
44
|
+
userId: user.Id,
|
|
45
|
+
username: user.Username,
|
|
46
|
+
lastLogin: user.LastLoginDate ? Date.parse(user.LastLoginDate) : undefined,
|
|
47
|
+
createdDate: Date.parse(user.CreatedDate),
|
|
48
|
+
assignedProfile: user.Profile.Name,
|
|
49
|
+
assignedPermissionSets: [],
|
|
50
|
+
logins: [],
|
|
51
|
+
role: configuredUsers[user.Username]?.role ?? this.config.options.defaultRoleForMissingUsers,
|
|
52
|
+
};
|
|
53
|
+
userIds.push(user.Id);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
this.totalEntities = allUsersOnOrg.totalSize;
|
|
57
|
+
this.emit('entityresolve', {
|
|
58
|
+
total: this.totalEntities,
|
|
59
|
+
resolved: 0,
|
|
60
|
+
});
|
|
61
|
+
const userLogins = await resolveLogins(context, this.config.options.analyseLastNDaysOfLoginHistory);
|
|
62
|
+
Object.entries(userLogins).forEach(([userId, user]) => {
|
|
63
|
+
if (usersById[userId] !== undefined) {
|
|
64
|
+
usersById[userId].logins = user.logins;
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
// resolve perm set assignments per user
|
|
68
|
+
// const assignments = await context.targetOrgConnection.query<PermissionSetAssignment>(
|
|
69
|
+
// buildPermsetAssignmentsQuery(userIds)
|
|
70
|
+
// );
|
|
71
|
+
// assignments.records.forEach(assignment => {
|
|
72
|
+
// })
|
|
73
|
+
const result = { resolvedEntities: organizeByUsername(usersById), ignoredEntities: Object.values(ignoredEntities) };
|
|
74
|
+
this.emit('entityresolve', {
|
|
75
|
+
total: this.totalEntities,
|
|
76
|
+
resolved: getTotal(result),
|
|
77
|
+
});
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
async function resolveLogins(context, daysToAnalyse) {
|
|
82
|
+
const loginHistory = await context.targetOrgConnection.query(buildLoginHistoryQuery(daysToAnalyse));
|
|
83
|
+
const partialUsers = {};
|
|
84
|
+
loginHistory.records.forEach((loginHistoryRow) => {
|
|
85
|
+
if (!partialUsers[loginHistoryRow.UserId]) {
|
|
86
|
+
partialUsers[loginHistoryRow.UserId] = { logins: [] };
|
|
87
|
+
}
|
|
88
|
+
partialUsers[loginHistoryRow.UserId].logins.push({
|
|
89
|
+
loginType: loginHistoryRow.LoginType,
|
|
90
|
+
loginCount: loginHistoryRow.LoginCount,
|
|
91
|
+
application: loginHistoryRow.Application,
|
|
92
|
+
lastLogin: Date.parse(loginHistoryRow.LastLogin),
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
return partialUsers;
|
|
96
|
+
}
|
|
97
|
+
function organizeByUsername(partial) {
|
|
98
|
+
const full = {};
|
|
99
|
+
Object.values(partial).forEach((resolved) => {
|
|
100
|
+
full[resolved.username] = resolved;
|
|
101
|
+
});
|
|
102
|
+
return full;
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=userPolicy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"userPolicy.js","sourceRoot":"","sources":["../../../../src/libs/core/policies/userPolicy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import z from 'zod';
|
|
2
|
+
import { AuditRunConfigClassifications, AuditRunConfigPolicies } from './file-mgmt/schema.js';
|
|
3
|
+
import { Constructor } from './registries/types.js';
|
|
4
|
+
import Policy from './policies/policy.js';
|
|
5
|
+
export declare const classificationDefs: ClassificationRegistry;
|
|
6
|
+
export type PolicyNames = keyof AuditRunConfigPolicies;
|
|
7
|
+
export type ClassificationNames = keyof AuditRunConfigClassifications;
|
|
8
|
+
export type PolicyRegistry = Record<PolicyNames, PolicyRegistryEntry>;
|
|
9
|
+
export declare const policyDefs: PolicyRegistry;
|
|
10
|
+
type PolicyRegistryEntry = ConfigFileDefinition & {
|
|
11
|
+
dependencies?: ConfigFileDependency[];
|
|
12
|
+
handler: Constructor<Policy<unknown>>;
|
|
13
|
+
};
|
|
14
|
+
type ConfigFileDefinition = {
|
|
15
|
+
fileName?: string;
|
|
16
|
+
schema: z.ZodObject;
|
|
17
|
+
};
|
|
18
|
+
type ConfigFileDependency = {
|
|
19
|
+
errorName: string;
|
|
20
|
+
path: string[];
|
|
21
|
+
};
|
|
22
|
+
type ClassificationRegistry = Record<keyof AuditRunConfigClassifications, ConfigFileDefinition>;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { PermissionsConfigFileSchema, PermSetsPolicyFileSchema, PolicyFileSchema, ProfilesPolicyFileSchema, UsersPolicyFileSchema, } from './file-mgmt/schema.js';
|
|
2
|
+
import ConnectedAppPolicy from './policies/connectedAppPolicy.js';
|
|
3
|
+
import PermissionSetPolicy from './policies/permissionSetPolicy.js';
|
|
4
|
+
import ProfilePolicy from './policies/profilePolicy.js';
|
|
5
|
+
import UserPolicy from './policies/userPolicy.js';
|
|
6
|
+
export const classificationDefs = {
|
|
7
|
+
userPermissions: {
|
|
8
|
+
schema: PermissionsConfigFileSchema,
|
|
9
|
+
},
|
|
10
|
+
customPermissions: {
|
|
11
|
+
schema: PermissionsConfigFileSchema,
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
export const policyDefs = {
|
|
15
|
+
profiles: {
|
|
16
|
+
handler: ProfilePolicy,
|
|
17
|
+
schema: ProfilesPolicyFileSchema,
|
|
18
|
+
dependencies: [
|
|
19
|
+
{ path: ['classifications', 'userPermissions'], errorName: 'UserPermClassificationRequiredForProfiles' },
|
|
20
|
+
],
|
|
21
|
+
},
|
|
22
|
+
permissionSets: {
|
|
23
|
+
handler: PermissionSetPolicy,
|
|
24
|
+
schema: PermSetsPolicyFileSchema,
|
|
25
|
+
dependencies: [
|
|
26
|
+
{ path: ['classifications', 'userPermissions'], errorName: 'UserPermClassificationRequiredForPermSets' },
|
|
27
|
+
],
|
|
28
|
+
},
|
|
29
|
+
connectedApps: {
|
|
30
|
+
handler: ConnectedAppPolicy,
|
|
31
|
+
schema: PolicyFileSchema,
|
|
32
|
+
},
|
|
33
|
+
users: {
|
|
34
|
+
handler: UserPolicy,
|
|
35
|
+
schema: UsersPolicyFileSchema,
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=policyRegistry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policyRegistry.js","sourceRoot":"","sources":["../../../src/libs/core/policyRegistry.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,2BAA2B,EAC3B,wBAAwB,EACxB,gBAAgB,EAChB,wBAAwB,EACxB,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,kBAAkB,MAAM,kCAAkC,CAAC;AAClE,OAAO,mBAAmB,MAAM,mCAAmC,CAAC;AAEpE,OAAO,aAAa,MAAM,6BAA6B,CAAC;AACxD,OAAO,UAAU,MAAM,0BAA0B,CAAC;AAElD,MAAM,CAAC,MAAM,kBAAkB,GAA2B;IACxD,eAAe,EAAE;QACf,MAAM,EAAE,2BAA2B;KACpC;IACD,iBAAiB,EAAE;QACjB,MAAM,EAAE,2BAA2B;KACpC;CACF,CAAC;AAOF,MAAM,CAAC,MAAM,UAAU,GAAmB;IACxC,QAAQ,EAAE;QACR,OAAO,EAAE,aAAa;QACtB,MAAM,EAAE,wBAAwB;QAChC,YAAY,EAAE;YACZ,EAAE,IAAI,EAAE,CAAC,iBAAiB,EAAE,iBAAiB,CAAC,EAAE,SAAS,EAAE,2CAA2C,EAAE;SACzG;KACF;IACD,cAAc,EAAE;QACd,OAAO,EAAE,mBAAmB;QAC5B,MAAM,EAAE,wBAAwB;QAChC,YAAY,EAAE;YACZ,EAAE,IAAI,EAAE,CAAC,iBAAiB,EAAE,iBAAiB,CAAC,EAAE,SAAS,EAAE,2CAA2C,EAAE;SACzG;KACF;IACD,aAAa,EAAE;QACb,OAAO,EAAE,kBAAkB;QAC3B,MAAM,EAAE,gBAAgB;KACzB;IACD,KAAK,EAAE;QACL,OAAO,EAAE,UAAU;QACnB,MAAM,EAAE,qBAAqB;KAC9B;CACF,CAAC"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { EntityResolveError, PolicyRuleSkipResult } from '../result-types.js';
|
|
2
2
|
import { AuditRunConfig, RuleMap } from '../../core/file-mgmt/schema.js';
|
|
3
|
-
import { RowLevelPolicyRule } from './types.js';
|
|
4
|
-
type Constructor<T, Args extends any[] = any[]> = new (...args: Args) => T;
|
|
3
|
+
import { Constructor, RowLevelPolicyRule } from './types.js';
|
|
5
4
|
/**
|
|
6
5
|
* Result contains the actually available and enabled rules
|
|
7
6
|
* from the raw config file. Rules that are not present in the
|
|
@@ -36,4 +35,3 @@ export default class RuleRegistry {
|
|
|
36
35
|
*/
|
|
37
36
|
resolveRules(ruleObjs: RuleMap, auditContext: AuditRunConfig): RegistryRuleResolveResult;
|
|
38
37
|
}
|
|
39
|
-
export {};
|
|
@@ -33,7 +33,7 @@ export default class RuleRegistry {
|
|
|
33
33
|
const resolveErrors = new Array();
|
|
34
34
|
Object.entries(ruleObjs).forEach(([ruleName, ruleConfig]) => {
|
|
35
35
|
if (this.rules[ruleName] && ruleConfig.enabled) {
|
|
36
|
-
enabledRules.push(new this.rules[ruleName]({ auditContext, ruleDisplayName: ruleName, ruleConfig: ruleConfig.
|
|
36
|
+
enabledRules.push(new this.rules[ruleName]({ auditContext, ruleDisplayName: ruleName, ruleConfig: ruleConfig.options }));
|
|
37
37
|
}
|
|
38
38
|
else if (!ruleConfig.enabled) {
|
|
39
39
|
skippedRules.push({ name: ruleName, skipReason: messages.getMessage('skip-reason.rule-not-enabled') });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ruleRegistry.js","sourceRoot":"","sources":["../../../../src/libs/core/registries/ruleRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAK5C,QAAQ,CAAC,kCAAkC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC7D,MAAM,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAC,oCAAoC,EAAE,kBAAkB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"ruleRegistry.js","sourceRoot":"","sources":["../../../../src/libs/core/registries/ruleRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAK5C,QAAQ,CAAC,kCAAkC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC7D,MAAM,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAC,oCAAoC,EAAE,kBAAkB,CAAC,CAAC;AAajG;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,YAAY;IACL;IAA1B,YAA0B,KAA+D;QAA/D,UAAK,GAAL,KAAK,CAA0D;IAAG,CAAC;IAE7F;;;;OAIG;IACI,eAAe;QACpB,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC;IAED;;;;;;;OAOG;IACI,YAAY,CAAC,QAAiB,EAAE,YAA4B;QACjE,MAAM,YAAY,GAAG,IAAI,KAAK,EAA+B,CAAC;QAC9D,MAAM,YAAY,GAAG,IAAI,KAAK,EAAwB,CAAC;QACvD,MAAM,aAAa,GAAG,IAAI,KAAK,EAAsB,CAAC;QACtD,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,UAAU,CAAC,EAAE,EAAE;YAC1D,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,UAAU,CAAC,OAAO,EAAE,CAAC;gBAC/C,YAAY,CAAC,IAAI,CACf,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,YAAY,EAAE,eAAe,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC,CACtG,CAAC;YACJ,CAAC;iBAAM,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;gBAC/B,YAAY,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,CAAC,UAAU,CAAC,8BAA8B,CAAC,EAAE,CAAC,CAAC;YACzG,CAAC;iBAAM,CAAC;gBACN,aAAa,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,mCAAmC,CAAC,EAAE,CAAC,CAAC;YAC5G,CAAC;QACH,CAAC,CAAC,CAAC;QACH,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC;IACvD,CAAC;CACF"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { NoInactiveUsersOptions } from '../../file-mgmt/schema.js';
|
|
2
|
+
import { PartialPolicyRuleResult, RuleAuditContext } from '../types.js';
|
|
3
|
+
import { ResolvedUser } from '../users.js';
|
|
4
|
+
import PolicyRule, { ConfigurableRuleOptions } from './policyRule.js';
|
|
5
|
+
export default class NoInactiveUsers extends PolicyRule<ResolvedUser> {
|
|
6
|
+
private ruleConfig;
|
|
7
|
+
constructor(localOpts: ConfigurableRuleOptions<NoInactiveUsersOptions>);
|
|
8
|
+
run(context: RuleAuditContext<ResolvedUser>): Promise<PartialPolicyRuleResult>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Messages } from '@salesforce/core';
|
|
2
|
+
import { NoInactiveUsersOptionsSchema } from '../../file-mgmt/schema.js';
|
|
3
|
+
import { differenceInDays } from '../../utils.js';
|
|
4
|
+
import PolicyRule from './policyRule.js';
|
|
5
|
+
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
|
|
6
|
+
const messages = Messages.loadMessages('@j-schreiber/sf-cli-security-audit', 'rules.users');
|
|
7
|
+
export default class NoInactiveUsers extends PolicyRule {
|
|
8
|
+
ruleConfig;
|
|
9
|
+
constructor(localOpts) {
|
|
10
|
+
super(localOpts);
|
|
11
|
+
this.ruleConfig = NoInactiveUsersOptionsSchema.parse(localOpts.ruleConfig ?? {});
|
|
12
|
+
}
|
|
13
|
+
run(context) {
|
|
14
|
+
const result = this.initResult();
|
|
15
|
+
Object.values(context.resolvedEntities).forEach((user) => {
|
|
16
|
+
if (user.lastLogin) {
|
|
17
|
+
const diffInDays = differenceInDays(Date.now(), user.lastLogin);
|
|
18
|
+
if (diffInDays > this.ruleConfig.daysAfterUserIsInactive) {
|
|
19
|
+
result.violations.push({
|
|
20
|
+
identifier: [user.username],
|
|
21
|
+
message: messages.getMessage('violations.inactive-since-n-days', [
|
|
22
|
+
diffInDays,
|
|
23
|
+
new Date(user.lastLogin).toISOString(),
|
|
24
|
+
]),
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
Object.values(context.resolvedEntities).forEach((user) => {
|
|
30
|
+
if (!user.lastLogin) {
|
|
31
|
+
const createdNDaysAgo = differenceInDays(Date.now(), user.createdDate);
|
|
32
|
+
result.violations.push({
|
|
33
|
+
identifier: [user.username],
|
|
34
|
+
message: messages.getMessage('violations.has-never-logged-in', [
|
|
35
|
+
new Date(user.createdDate).toISOString(),
|
|
36
|
+
createdNDaysAgo,
|
|
37
|
+
]),
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
return Promise.resolve(result);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=noInactiveUsers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"noInactiveUsers.js","sourceRoot":"","sources":["../../../../../src/libs/core/registries/rules/noInactiveUsers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAA0B,4BAA4B,EAAE,MAAM,2BAA2B,CAAC;AAEjG,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,OAAO,UAAuC,MAAM,iBAAiB,CAAC;AAEtE,QAAQ,CAAC,kCAAkC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC7D,MAAM,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAC,oCAAoC,EAAE,aAAa,CAAC,CAAC;AAE5F,MAAM,CAAC,OAAO,OAAO,eAAgB,SAAQ,UAAwB;IAC3D,UAAU,CAAyB;IAE3C,YAAmB,SAA0D;QAC3E,KAAK,CAAC,SAAS,CAAC,CAAC;QACjB,IAAI,CAAC,UAAU,GAAG,4BAA4B,CAAC,KAAK,CAAC,SAAS,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC;IACnF,CAAC;IAEM,GAAG,CAAC,OAAuC;QAChD,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QACjC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;YACvD,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACnB,MAAM,UAAU,GAAG,gBAAgB,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;gBAChE,IAAI,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,uBAAuB,EAAE,CAAC;oBACzD,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;wBACrB,UAAU,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC;wBAC3B,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,kCAAkC,EAAE;4BAC/D,UAAU;4BACV,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE;yBACvC,CAAC;qBACH,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;YACvD,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;gBACpB,MAAM,eAAe,GAAG,gBAAgB,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;gBACvE,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;oBACrB,UAAU,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC;oBAC3B,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,gCAAgC,EAAE;wBAC7D,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,WAAW,EAAE;wBACxC,eAAe;qBAChB,CAAC;iBACH,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 '../types.js';
|
|
2
|
+
import { ResolvedUser } from '../users.js';
|
|
3
|
+
import PolicyRule, { RuleOptions } from './policyRule.js';
|
|
4
|
+
export default class NoOtherApexApiLogins extends PolicyRule<ResolvedUser> {
|
|
5
|
+
constructor(opts: RuleOptions);
|
|
6
|
+
run(context: RuleAuditContext<ResolvedUser>): Promise<PartialPolicyRuleResult>;
|
|
7
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
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.users');
|
|
5
|
+
export default class NoOtherApexApiLogins extends PolicyRule {
|
|
6
|
+
constructor(opts) {
|
|
7
|
+
super(opts);
|
|
8
|
+
}
|
|
9
|
+
run(context) {
|
|
10
|
+
const result = this.initResult();
|
|
11
|
+
Object.values(context.resolvedEntities).forEach((user) => {
|
|
12
|
+
user.logins.forEach((loginSummary) => {
|
|
13
|
+
if (loginSummary.loginType === 'Other Apex API') {
|
|
14
|
+
result.violations.push({
|
|
15
|
+
identifier: [user.username],
|
|
16
|
+
message: messages.getMessage('violations.no-other-apex-api-logins', [loginSummary.loginCount]),
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
return Promise.resolve(result);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=noOtherApexApiLogins.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"noOtherApexApiLogins.js","sourceRoot":"","sources":["../../../../../src/libs/core/registries/rules/noOtherApexApiLogins.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,aAAa,CAAC,CAAC;AAE5F,MAAM,CAAC,OAAO,OAAO,oBAAqB,SAAQ,UAAwB;IACxE,YAAmB,IAAiB;QAClC,KAAK,CAAC,IAAI,CAAC,CAAC;IACd,CAAC;IAEM,GAAG,CAAC,OAAuC;QAChD,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QACjC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;YACvD,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,EAAE,EAAE;gBACnC,IAAI,YAAY,CAAC,SAAS,KAAK,gBAAgB,EAAE,CAAC;oBAChD,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;wBACrB,UAAU,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC;wBAC3B,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,qCAAqC,EAAE,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;qBAC/F,CAAC,CAAC;gBACL,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;CACF"}
|
|
@@ -3,9 +3,12 @@ import { AuditRunConfig, NamedPermissionsClassification } from '../../file-mgmt/
|
|
|
3
3
|
export type RuleOptions = {
|
|
4
4
|
auditContext: AuditRunConfig;
|
|
5
5
|
ruleDisplayName: string;
|
|
6
|
-
|
|
6
|
+
};
|
|
7
|
+
export type ConfigurableRuleOptions<T> = RuleOptions & {
|
|
8
|
+
ruleConfig: T;
|
|
7
9
|
};
|
|
8
10
|
export default abstract class PolicyRule<EntityType> implements RowLevelPolicyRule<EntityType> {
|
|
11
|
+
protected opts: RuleOptions;
|
|
9
12
|
auditContext: AuditRunConfig;
|
|
10
13
|
ruleDisplayName: string;
|
|
11
14
|
constructor(opts: RuleOptions);
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { Messages } from '@salesforce/core';
|
|
2
2
|
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
|
|
3
3
|
export default class PolicyRule {
|
|
4
|
+
opts;
|
|
4
5
|
auditContext;
|
|
5
6
|
ruleDisplayName;
|
|
6
7
|
constructor(opts) {
|
|
8
|
+
this.opts = opts;
|
|
7
9
|
this.auditContext = opts.auditContext;
|
|
8
10
|
this.ruleDisplayName = opts.ruleDisplayName;
|
|
9
11
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"policyRule.js","sourceRoot":"","sources":["../../../../../src/libs/core/registries/rules/policyRule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAK5C,QAAQ,CAAC,kCAAkC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"policyRule.js","sourceRoot":"","sources":["../../../../../src/libs/core/registries/rules/policyRule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAK5C,QAAQ,CAAC,kCAAkC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAW7D,MAAM,CAAC,OAAO,OAAgB,UAAU;IAIT;IAHtB,YAAY,CAAiB;IAC7B,eAAe,CAAS;IAE/B,YAA6B,IAAiB;QAAjB,SAAI,GAAJ,IAAI,CAAa;QAC5C,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"}
|
|
@@ -5,7 +5,9 @@ export declare const RuleRegistries: {
|
|
|
5
5
|
ConnectedApps: import("./connectedApps.js").default;
|
|
6
6
|
Profiles: import("./profiles.js").default;
|
|
7
7
|
PermissionSets: import("./permissionSets.js").default;
|
|
8
|
+
Users: import("./users.js").default;
|
|
8
9
|
};
|
|
10
|
+
export type Constructor<T, Args extends any[] = any[]> = new (...args: Args) => T;
|
|
9
11
|
/**
|
|
10
12
|
* A rule must only implement a subset of the rule result. All optional
|
|
11
13
|
* properties are completed by the policy.
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { ConnectedAppsRegistry } from './connectedApps.js';
|
|
2
2
|
import { PermissionSetsRegistry } from './permissionSets.js';
|
|
3
3
|
import { ProfilesRegistry } from './profiles.js';
|
|
4
|
+
import { UsersRegistry } from './users.js';
|
|
4
5
|
export const RuleRegistries = {
|
|
5
6
|
ConnectedApps: ConnectedAppsRegistry,
|
|
6
7
|
Profiles: ProfilesRegistry,
|
|
7
8
|
PermissionSets: PermissionSetsRegistry,
|
|
9
|
+
Users: UsersRegistry,
|
|
8
10
|
};
|
|
9
11
|
//# sourceMappingURL=types.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/libs/core/registries/types.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/libs/core/registries/types.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,aAAa,EAAE,qBAAqB;IACpC,QAAQ,EAAE,gBAAgB;IAC1B,cAAc,EAAE,sBAAsB;IACtC,KAAK,EAAE,aAAa;CACrB,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ProfilesRiskPreset } from '../policy-types.js';
|
|
2
|
+
import RuleRegistry from './ruleRegistry.js';
|
|
3
|
+
export type ResolvedUser = {
|
|
4
|
+
userId: string;
|
|
5
|
+
username: string;
|
|
6
|
+
role: ProfilesRiskPreset;
|
|
7
|
+
assignedPermissionSets: UserPermissionSetAssignment[];
|
|
8
|
+
logins: UserLogins[];
|
|
9
|
+
assignedProfile: string;
|
|
10
|
+
createdDate: number;
|
|
11
|
+
lastLogin?: number;
|
|
12
|
+
};
|
|
13
|
+
type UserLogins = {
|
|
14
|
+
loginType: string;
|
|
15
|
+
application: string;
|
|
16
|
+
loginCount: number;
|
|
17
|
+
lastLogin: number;
|
|
18
|
+
};
|
|
19
|
+
type UserPermissionSetAssignment = {
|
|
20
|
+
permissionSetIdentifier: string;
|
|
21
|
+
};
|
|
22
|
+
export default class UsersRuleRegistry extends RuleRegistry {
|
|
23
|
+
constructor();
|
|
24
|
+
}
|
|
25
|
+
export declare const UsersRegistry: UsersRuleRegistry;
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import RuleRegistry from './ruleRegistry.js';
|
|
2
|
+
import NoInactiveUsers from './rules/noInactiveUsers.js';
|
|
3
|
+
import NoOtherApexApiLogins from './rules/noOtherApexApiLogins.js';
|
|
4
|
+
export default class UsersRuleRegistry extends RuleRegistry {
|
|
5
|
+
constructor() {
|
|
6
|
+
super({ NoOtherApexApiLogins, NoInactiveUsers });
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
export const UsersRegistry = new UsersRuleRegistry();
|
|
10
|
+
//# sourceMappingURL=users.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"users.js","sourceRoot":"","sources":["../../../../src/libs/core/registries/users.ts"],"names":[],"mappings":"AACA,OAAO,YAAY,MAAM,mBAAmB,CAAC;AAC7C,OAAO,eAAe,MAAM,4BAA4B,CAAC;AACzD,OAAO,oBAAoB,MAAM,iCAAiC,CAAC;AAwBnE,MAAM,CAAC,OAAO,OAAO,iBAAkB,SAAQ,YAAY;IACzD;QACE,KAAK,CAAC,EAAE,oBAAoB,EAAE,eAAe,EAAE,CAAC,CAAC;IACnD,CAAC;CACF;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,iBAAiB,EAAE,CAAC"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { AuditRunConfigPolicies } from './file-mgmt/schema.js';
|
|
1
2
|
/**
|
|
2
3
|
* A single violation from a policy rule execution.
|
|
3
4
|
*/
|
|
@@ -166,6 +167,6 @@ export type AuditResult = {
|
|
|
166
167
|
* Record map of all modules (policies) that were run.
|
|
167
168
|
*/
|
|
168
169
|
policies: {
|
|
169
|
-
[
|
|
170
|
+
[P in keyof AuditRunConfigPolicies]: AuditPolicyResult;
|
|
170
171
|
};
|
|
171
172
|
};
|
package/lib/libs/core/utils.d.ts
CHANGED
|
@@ -2,4 +2,11 @@ export declare function isEmpty(anything?: unknown): boolean;
|
|
|
2
2
|
export declare function isNullish(anything: unknown): boolean;
|
|
3
3
|
export declare function capitalize(anyString: string): string;
|
|
4
4
|
export declare function uncapitalize(anyString: string): string;
|
|
5
|
+
/**
|
|
6
|
+
* Both dates have to be UNIX timestamps
|
|
7
|
+
*
|
|
8
|
+
* @param date1
|
|
9
|
+
* @param date2
|
|
10
|
+
*/
|
|
11
|
+
export declare function differenceInDays(date1: number | string, date2: number | string): number;
|
|
5
12
|
export type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;
|
package/lib/libs/core/utils.js
CHANGED
|
@@ -16,4 +16,16 @@ export function capitalize(anyString) {
|
|
|
16
16
|
export function uncapitalize(anyString) {
|
|
17
17
|
return `${anyString[0].toLowerCase()}${anyString.slice(1)}`;
|
|
18
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* Both dates have to be UNIX timestamps
|
|
21
|
+
*
|
|
22
|
+
* @param date1
|
|
23
|
+
* @param date2
|
|
24
|
+
*/
|
|
25
|
+
export function differenceInDays(date1, date2) {
|
|
26
|
+
const convertedDate1 = typeof date1 === 'number' ? date1 : Date.parse(date1);
|
|
27
|
+
const convertedDate2 = typeof date2 === 'number' ? date2 : Date.parse(date2);
|
|
28
|
+
const diff = Math.abs(convertedDate2 - convertedDate1);
|
|
29
|
+
return Math.floor(diff / (1000 * 60 * 60 * 24));
|
|
30
|
+
}
|
|
19
31
|
//# sourceMappingURL=utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/libs/core/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;AAED,MAAM,UAAU,UAAU,CAAC,SAAiB;IAC1C,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,SAAiB;IAC5C,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AAC9D,CAAC"}
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/libs/core/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;AAED,MAAM,UAAU,UAAU,CAAC,SAAiB;IAC1C,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,SAAiB;IAC5C,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AAC9D,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAsB,EAAE,KAAsB;IAC7E,MAAM,cAAc,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC7E,MAAM,cAAc,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC7E,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,cAAc,GAAG,cAAc,CAAC,CAAC;IACvD,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;AAClD,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { MultiStageOutput, MultiStageOutputOptions } from '@oclif/multi-stage-output';
|
|
2
|
-
import AuditRun from '../libs/
|
|
2
|
+
import AuditRun from '../libs/core/auditRun.js';
|
|
3
3
|
export declare const LOAD_AUDIT_CONFIG = "Loading audit config";
|
|
4
4
|
export declare const RESOLVE_POLICIES = "Resolving policies";
|
|
5
5
|
export declare const EXECUTE_RULES = "Executing rules";
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { MultiStageOutput } from '@oclif/multi-stage-output';
|
|
2
|
+
import { capitalize } from '../libs/core/utils.js';
|
|
2
3
|
export const LOAD_AUDIT_CONFIG = 'Loading audit config';
|
|
3
4
|
export const RESOLVE_POLICIES = 'Resolving policies';
|
|
4
5
|
export const EXECUTE_RULES = 'Executing rules';
|
|
@@ -61,27 +62,29 @@ export default class AuditRunMultiStageOutput {
|
|
|
61
62
|
startPolicyResolve(runInstance) {
|
|
62
63
|
this.mso.goto(RESOLVE_POLICIES, { currentStatus: 'Resolving' });
|
|
63
64
|
Object.entries(runInstance.configs.policies).forEach(([policyName, policy]) => {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
this.stageSpecificBlocks.push({
|
|
67
|
-
stage: RESOLVE_POLICIES,
|
|
68
|
-
type: 'dynamic-key-value',
|
|
69
|
-
label: policyName,
|
|
70
|
-
get: (data) => {
|
|
71
|
-
if (data?.policies?.[policyName]) {
|
|
72
|
-
return `${data.policies[policyName].resolved ?? 0}/${data.policies[policyName].total ?? 0}`;
|
|
73
|
-
}
|
|
74
|
-
else {
|
|
75
|
-
return '';
|
|
76
|
-
}
|
|
77
|
-
},
|
|
78
|
-
});
|
|
79
|
-
if (policyDef.content.rules && Object.keys(policyDef.content.rules).length > 0) {
|
|
65
|
+
if (policy.content.enabled) {
|
|
66
|
+
this.addPolicyStatsListener(policyName, runInstance);
|
|
80
67
|
this.stageSpecificBlocks.push({
|
|
81
|
-
stage:
|
|
82
|
-
type: '
|
|
83
|
-
|
|
68
|
+
stage: RESOLVE_POLICIES,
|
|
69
|
+
type: 'dynamic-key-value',
|
|
70
|
+
label: capitalize(policyName),
|
|
71
|
+
get: (data) => {
|
|
72
|
+
if (data?.policies?.[policyName]) {
|
|
73
|
+
return `${data.policies[policyName].resolved ?? 0}/${data.policies[policyName].total ?? 0}`;
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
return '';
|
|
77
|
+
}
|
|
78
|
+
},
|
|
84
79
|
});
|
|
80
|
+
if (policy.content.rules && Object.keys(policy.content.rules).length > 0) {
|
|
81
|
+
const enabledRules = Object.values(policy.content.rules).filter((ruleConfig) => ruleConfig.enabled).length;
|
|
82
|
+
this.stageSpecificBlocks.push({
|
|
83
|
+
stage: EXECUTE_RULES,
|
|
84
|
+
type: 'message',
|
|
85
|
+
get: () => `Execute ${enabledRules} rule(s) for ${policyName}`,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
85
88
|
}
|
|
86
89
|
});
|
|
87
90
|
this.mso.updateData({});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auditRunMultiStage.js","sourceRoot":"","sources":["../../src/ux/auditRunMultiStage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAA2B,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"auditRunMultiStage.js","sourceRoot":"","sources":["../../src/ux/auditRunMultiStage.ts"],"names":[],"mappings":"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"}
|
|
@@ -22,10 +22,6 @@ The target org to scan.
|
|
|
22
22
|
|
|
23
23
|
- <%= config.bin %> <%= command.id %>
|
|
24
24
|
|
|
25
|
-
# success.
|
|
25
|
+
# success.scanned-entities-count
|
|
26
26
|
|
|
27
|
-
Scanned %s profiles.
|
|
28
|
-
|
|
29
|
-
# success.permissionsets-count
|
|
30
|
-
|
|
31
|
-
Scanned %s permission sets.
|
|
27
|
+
Scanned %s profiles and %s permission sets.
|
|
@@ -10,6 +10,10 @@ Org did not return valid metadata for the profile. Entity cannot be processed.
|
|
|
10
10
|
|
|
11
11
|
%ss with preset UNKNOWN are ignored.
|
|
12
12
|
|
|
13
|
+
# user-with-role-unknown
|
|
14
|
+
|
|
15
|
+
Users with role UNKNOWN are ignored. To apply the default role, remove them from config.
|
|
16
|
+
|
|
13
17
|
# skip-reason.rule-not-enabled
|
|
14
18
|
|
|
15
19
|
Rule was disabled in policy config.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# violations.no-other-apex-api-logins
|
|
2
|
+
|
|
3
|
+
Has %s logins with "Other Apex API", which is a deprecated and insecure login type.
|
|
4
|
+
|
|
5
|
+
# violations.inactive-since-n-days
|
|
6
|
+
|
|
7
|
+
User is inactive for %s days (last login was %s).
|
|
8
|
+
|
|
9
|
+
# violations.has-never-logged-in
|
|
10
|
+
|
|
11
|
+
User was created %s (%s days ago), but never logged in.
|