filegrc 0.16.9 → 0.16.10
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/package.json +1 -1
- package/src/applicability-scope.js +52 -10
package/package.json
CHANGED
|
@@ -117,13 +117,16 @@ export function applicabilityScopeRevision(record, program, resources, model, op
|
|
|
117
117
|
policies: resources
|
|
118
118
|
.filter(({ type, id }) => type === "policy" && selectedPolicyIds.has(id))
|
|
119
119
|
.sort(compareRecordIds)
|
|
120
|
-
.map((policy) => options.legacyPolicyStatus
|
|
120
|
+
.map((policy) => options.legacyPolicyStatus || options.legacyPolicyOverrides
|
|
121
121
|
? pick({
|
|
122
122
|
...policy,
|
|
123
|
-
status: options.legacyPolicyStatus
|
|
124
|
-
?
|
|
125
|
-
effectiveOn: options.
|
|
126
|
-
? undefined : policy.effectiveOn
|
|
123
|
+
status: (options.legacyPolicyOverrides?.[policy.id]?.status || options.legacyPolicyStatus || "current") === "current"
|
|
124
|
+
? policy.status : options.legacyPolicyOverrides?.[policy.id]?.status || options.legacyPolicyStatus,
|
|
125
|
+
effectiveOn: (options.legacyPolicyOverrides?.[policy.id]?.withoutEffectiveOn
|
|
126
|
+
?? options.legacyPolicyWithoutEffectiveOn) ? undefined : policy.effectiveOn,
|
|
127
|
+
approvedContentRevisions: (options.legacyPolicyOverrides?.[policy.id]?.withoutApprovalBinding
|
|
128
|
+
?? options.legacyPolicyWithoutApprovalBinding)
|
|
129
|
+
? undefined : policy.approvedContentRevisions
|
|
127
130
|
}, [
|
|
128
131
|
"id", "status", "policyKind", "version", "programRole", "effectiveOn",
|
|
129
132
|
"requirementIds", "audience", "acknowledgementRequired",
|
|
@@ -168,11 +171,50 @@ export function applicabilityReviewIsCurrent(review, record, program, resources,
|
|
|
168
171
|
if (!review?.scopeRevision) return false;
|
|
169
172
|
const matches = (revision) => revisionsMatch("applicability-scope", review.scopeRevision, revision);
|
|
170
173
|
if (matches(applicabilityScopeRevision(record, program, resources, model))) return true;
|
|
171
|
-
//
|
|
172
|
-
//
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
174
|
+
// Older reviews hashed Policy approval metadata alongside scope facts.
|
|
175
|
+
// Reconstruct each Policy independently because other Policies may already
|
|
176
|
+
// have been approved when one Policy changes. Material fields stay current.
|
|
177
|
+
for (const legacyPolicyStatus of ["current", "draft", "in-review", "approved", "active"]) {
|
|
178
|
+
for (const legacyPolicyWithoutApprovalBinding of [false, true]) {
|
|
179
|
+
for (const legacyPolicyWithoutEffectiveOn of [false, true]) {
|
|
180
|
+
if (matches(applicabilityScopeRevision(record, program, resources, model, {
|
|
181
|
+
legacyPolicyStatus,
|
|
182
|
+
legacyPolicyWithoutApprovalBinding,
|
|
183
|
+
legacyPolicyWithoutEffectiveOn
|
|
184
|
+
}))) return true;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
const selectedControlIds = new Set(program?.controlIds || []);
|
|
189
|
+
const selectedPolicyIds = new Set(resources
|
|
190
|
+
.filter(({ type, id }) => type === "control" && selectedControlIds.has(id))
|
|
191
|
+
.flatMap(({ policyIds }) => policyIds || []));
|
|
192
|
+
for (const id of record.policyIds || []) selectedPolicyIds.add(id);
|
|
193
|
+
const policies = resources.filter(({ type, id }) => type === "policy" && selectedPolicyIds.has(id));
|
|
194
|
+
// One Policy may advance while the others retain different approval states.
|
|
195
|
+
// Reconstruct that Policy's former lifecycle fields without changing any
|
|
196
|
+
// material scope fact or searching combinations of unrelated Policies.
|
|
197
|
+
for (const policy of policies) {
|
|
198
|
+
for (const value of legacyPolicyAlternatives(policy)) {
|
|
199
|
+
if (matches(applicabilityScopeRevision(record, program, resources, model, {
|
|
200
|
+
legacyPolicyOverrides: { [policy.id]: value }
|
|
201
|
+
}))) return true;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return false;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function legacyPolicyAlternatives(policy) {
|
|
208
|
+
const prior = {
|
|
209
|
+
active: ["approved", "in-review", "draft"],
|
|
210
|
+
approved: ["in-review", "draft"],
|
|
211
|
+
"in-review": ["draft"]
|
|
212
|
+
}[policy.status] || [];
|
|
213
|
+
return prior.map((status) => ({
|
|
214
|
+
status,
|
|
215
|
+
withoutApprovalBinding: status === "draft" || status === "in-review",
|
|
216
|
+
withoutEffectiveOn: true
|
|
217
|
+
}));
|
|
176
218
|
}
|
|
177
219
|
|
|
178
220
|
function pick(record, fields, model, objectType = null) {
|