@vess-id/ai-identity 0.3.1 → 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.
- package/dist/constraint/constraint-evaluator.d.ts +33 -2
- package/dist/constraint/constraint-evaluator.d.ts.map +1 -1
- package/dist/index.js +115 -5
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +115 -5
- package/dist/index.mjs.map +1 -1
- package/dist/registry/index.d.ts +2 -1
- package/dist/registry/index.d.ts.map +1 -1
- package/dist/vp/vp-manager.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -1533,6 +1533,7 @@ var VPManager = class {
|
|
|
1533
1533
|
presentationFrame[key] = true;
|
|
1534
1534
|
});
|
|
1535
1535
|
const kbJwtPayload = {
|
|
1536
|
+
iss: options.holderDid,
|
|
1536
1537
|
aud: options.domain,
|
|
1537
1538
|
nonce: options.challenge,
|
|
1538
1539
|
iat: Math.floor(Date.now() / 1e3)
|
|
@@ -3907,6 +3908,98 @@ var ConstraintEvaluator = class {
|
|
|
3907
3908
|
return {};
|
|
3908
3909
|
}
|
|
3909
3910
|
// ============================================================================
|
|
3911
|
+
// PermissionConstraints evaluation (VC-level constraints from PermissionRule)
|
|
3912
|
+
// ============================================================================
|
|
3913
|
+
/**
|
|
3914
|
+
* Evaluate PermissionConstraints from a PermissionRule.
|
|
3915
|
+
*
|
|
3916
|
+
* This is the VC-level constraint evaluator that works with the
|
|
3917
|
+
* normalized PermissionConstraints format (as opposed to GrantConstraints).
|
|
3918
|
+
*
|
|
3919
|
+
* Used by the PolicyEvaluator after rule matching to verify
|
|
3920
|
+
* rule-level constraints are satisfied.
|
|
3921
|
+
*/
|
|
3922
|
+
evaluatePermissionConstraints(constraints, context) {
|
|
3923
|
+
const violations = [];
|
|
3924
|
+
const warnings = [];
|
|
3925
|
+
if (constraints.time) {
|
|
3926
|
+
const timeResult = this.checkPermissionTimeConstraint(
|
|
3927
|
+
constraints.time,
|
|
3928
|
+
new Date(context.now * 1e3)
|
|
3929
|
+
);
|
|
3930
|
+
if (timeResult.violation) violations.push(timeResult.violation);
|
|
3931
|
+
if (timeResult.warning) warnings.push(timeResult.warning);
|
|
3932
|
+
}
|
|
3933
|
+
if (constraints.max_invocations !== void 0 && context.invocationCount !== void 0) {
|
|
3934
|
+
const invResult = this.checkInvocationLimit(
|
|
3935
|
+
constraints.max_invocations,
|
|
3936
|
+
context.invocationCount
|
|
3937
|
+
);
|
|
3938
|
+
if (invResult.violation) violations.push(invResult.violation);
|
|
3939
|
+
if (invResult.warning) warnings.push(invResult.warning);
|
|
3940
|
+
}
|
|
3941
|
+
if (constraints.ip_allowlist && constraints.ip_allowlist.length > 0 && context.ipAddress) {
|
|
3942
|
+
const ipResult = this.checkIpAllowlist(constraints.ip_allowlist, context.ipAddress);
|
|
3943
|
+
if (ipResult.violation) violations.push(ipResult.violation);
|
|
3944
|
+
}
|
|
3945
|
+
if (constraints.risk_threshold !== void 0 && context.riskScore !== void 0) {
|
|
3946
|
+
const riskResult = this.checkRiskThreshold(constraints.risk_threshold, context.riskScore);
|
|
3947
|
+
if (riskResult.violation) violations.push(riskResult.violation);
|
|
3948
|
+
if (riskResult.warning) warnings.push(riskResult.warning);
|
|
3949
|
+
}
|
|
3950
|
+
return {
|
|
3951
|
+
allowed: violations.length === 0,
|
|
3952
|
+
violations,
|
|
3953
|
+
warnings
|
|
3954
|
+
};
|
|
3955
|
+
}
|
|
3956
|
+
/**
|
|
3957
|
+
* Check PermissionTimeConstraint (supports both absolute and recurring)
|
|
3958
|
+
*/
|
|
3959
|
+
checkPermissionTimeConstraint(time, currentTime) {
|
|
3960
|
+
const nowUnix = Math.floor(currentTime.getTime() / 1e3);
|
|
3961
|
+
if (time.not_before !== void 0 && nowUnix < time.not_before) {
|
|
3962
|
+
return {
|
|
3963
|
+
violation: {
|
|
3964
|
+
type: "time_window",
|
|
3965
|
+
message: `Current time is before not_before (${new Date(time.not_before * 1e3).toISOString()})`,
|
|
3966
|
+
details: { now: nowUnix, not_before: time.not_before }
|
|
3967
|
+
}
|
|
3968
|
+
};
|
|
3969
|
+
}
|
|
3970
|
+
if (time.not_after !== void 0 && nowUnix > time.not_after) {
|
|
3971
|
+
return {
|
|
3972
|
+
violation: {
|
|
3973
|
+
type: "time_window",
|
|
3974
|
+
message: `Current time is after not_after (${new Date(time.not_after * 1e3).toISOString()})`,
|
|
3975
|
+
details: { now: nowUnix, not_after: time.not_after }
|
|
3976
|
+
}
|
|
3977
|
+
};
|
|
3978
|
+
}
|
|
3979
|
+
const timezone = time.timezone || this.options.defaultTimezone;
|
|
3980
|
+
if (time.days_of_week && time.days_of_week.length > 0) {
|
|
3981
|
+
const currentDay = this.getDayOfWeekInTimezone(currentTime, timezone);
|
|
3982
|
+
if (!time.days_of_week.includes(currentDay)) {
|
|
3983
|
+
return {
|
|
3984
|
+
violation: {
|
|
3985
|
+
type: "time_window",
|
|
3986
|
+
message: `Current day (${this.getDayName(currentDay)}) is not in allowed days`,
|
|
3987
|
+
details: { currentDay, allowedDays: time.days_of_week }
|
|
3988
|
+
}
|
|
3989
|
+
};
|
|
3990
|
+
}
|
|
3991
|
+
}
|
|
3992
|
+
if (time.recurring_start && time.recurring_end) {
|
|
3993
|
+
const tw = {
|
|
3994
|
+
start: time.recurring_start,
|
|
3995
|
+
end: time.recurring_end,
|
|
3996
|
+
timezone
|
|
3997
|
+
};
|
|
3998
|
+
return this.checkTimeWindow(tw, currentTime);
|
|
3999
|
+
}
|
|
4000
|
+
return {};
|
|
4001
|
+
}
|
|
4002
|
+
// ============================================================================
|
|
3910
4003
|
// Helper Methods
|
|
3911
4004
|
// ============================================================================
|
|
3912
4005
|
getDayOfWeekInTimezone(date, timezone) {
|
|
@@ -3940,21 +4033,38 @@ var ConstraintEvaluator = class {
|
|
|
3940
4033
|
const [hours, minutes] = time.split(":").map(Number);
|
|
3941
4034
|
return hours * 60 + minutes;
|
|
3942
4035
|
}
|
|
4036
|
+
/**
|
|
4037
|
+
* Check if an IP address is within a CIDR range or matches exactly.
|
|
4038
|
+
* Uses unsigned 32-bit arithmetic to avoid sign-bit issues.
|
|
4039
|
+
* Public for reuse by other services (e.g., LocalPolicyEvaluatorService).
|
|
4040
|
+
*/
|
|
3943
4041
|
isIpInCidr(ip, cidr) {
|
|
3944
4042
|
try {
|
|
4043
|
+
if (!cidr.includes("/")) {
|
|
4044
|
+
return ip === cidr;
|
|
4045
|
+
}
|
|
3945
4046
|
const [range, bits] = cidr.split("/");
|
|
3946
|
-
const
|
|
4047
|
+
const prefix = parseInt(bits, 10);
|
|
4048
|
+
if (isNaN(prefix)) return false;
|
|
3947
4049
|
const ipNum = this.ipToNumber(ip);
|
|
3948
4050
|
const rangeNum = this.ipToNumber(range);
|
|
3949
|
-
|
|
3950
|
-
|
|
4051
|
+
if (ipNum === null || rangeNum === null) return false;
|
|
4052
|
+
const mask = prefix === 0 ? 0 : ~0 << 32 - prefix >>> 0;
|
|
4053
|
+
return (ipNum & mask) === (rangeNum & mask);
|
|
3951
4054
|
} catch {
|
|
3952
4055
|
return false;
|
|
3953
4056
|
}
|
|
3954
4057
|
}
|
|
3955
4058
|
ipToNumber(ip) {
|
|
3956
|
-
const parts = ip.split(".")
|
|
3957
|
-
|
|
4059
|
+
const parts = ip.split(".");
|
|
4060
|
+
if (parts.length !== 4) return null;
|
|
4061
|
+
let result = 0;
|
|
4062
|
+
for (const part of parts) {
|
|
4063
|
+
const n = parseInt(part, 10);
|
|
4064
|
+
if (isNaN(n) || n < 0 || n > 255) return null;
|
|
4065
|
+
result = result << 8 | n;
|
|
4066
|
+
}
|
|
4067
|
+
return result >>> 0;
|
|
3958
4068
|
}
|
|
3959
4069
|
};
|
|
3960
4070
|
var defaultConstraintEvaluator = new ConstraintEvaluator();
|