@nextera.one/axis-server-sdk 0.9.1 → 0.9.2
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/core/index.d.mts +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/index.d.mts +245 -103
- package/dist/index.d.ts +245 -103
- package/dist/index.js +561 -5
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +525 -5
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -6
package/dist/index.mjs
CHANGED
|
@@ -1368,10 +1368,10 @@ function tlv(type, value) {
|
|
|
1368
1368
|
]);
|
|
1369
1369
|
}
|
|
1370
1370
|
function buildTLVs(items, opts) {
|
|
1371
|
-
const
|
|
1371
|
+
const allow2 = opts?.allowDupTypes ?? /* @__PURE__ */ new Set();
|
|
1372
1372
|
const sorted = [...items].sort((a, b) => a.type - b.type);
|
|
1373
1373
|
for (let i = 1; i < sorted.length; i++) {
|
|
1374
|
-
if (sorted[i].type === sorted[i - 1].type && !
|
|
1374
|
+
if (sorted[i].type === sorted[i - 1].type && !allow2.has(sorted[i].type)) {
|
|
1375
1375
|
throw new Error(`TLV_DUP_TYPE_${sorted[i].type}`);
|
|
1376
1376
|
}
|
|
1377
1377
|
}
|
|
@@ -1941,6 +1941,20 @@ var INTENT_REQUIREMENTS = {
|
|
|
1941
1941
|
"passport.revoke": ["write", "witness"],
|
|
1942
1942
|
"stream.publish": ["write"],
|
|
1943
1943
|
"stream.subscribe": ["read"],
|
|
1944
|
+
// NestFlow intents
|
|
1945
|
+
"auth.web.login.*": ["execute"],
|
|
1946
|
+
"tickauth.challenge.*": ["execute"],
|
|
1947
|
+
"capsule.issue.*": ["write", "execute"],
|
|
1948
|
+
"session.*": ["execute"],
|
|
1949
|
+
"device.list": ["read"],
|
|
1950
|
+
"device.rename": ["write"],
|
|
1951
|
+
"device.trust.*": ["write", "execute"],
|
|
1952
|
+
"device.revoke": ["write", "execute"],
|
|
1953
|
+
"identity.*": ["admin", "execute"],
|
|
1954
|
+
"primary.device.*": ["admin", "execute"],
|
|
1955
|
+
"secret.rotate": ["admin"],
|
|
1956
|
+
"org.security.*": ["admin"],
|
|
1957
|
+
"production.execution.*": ["admin", "execute"],
|
|
1944
1958
|
"admin.*": ["admin"]
|
|
1945
1959
|
};
|
|
1946
1960
|
|
|
@@ -1962,13 +1976,29 @@ var AXIS_OPCODES = /* @__PURE__ */ new Set([
|
|
|
1962
1976
|
"INTENT.EXEC",
|
|
1963
1977
|
"ACTOR.KEY.ROTATE",
|
|
1964
1978
|
"ACTOR.KEY.REVOKE",
|
|
1965
|
-
"ISSUER.KEY.ROTATE"
|
|
1979
|
+
"ISSUER.KEY.ROTATE",
|
|
1980
|
+
// NestFlow opcodes
|
|
1981
|
+
"AUTH.WEB.LOGIN",
|
|
1982
|
+
"AUTH.WEB.SCAN",
|
|
1983
|
+
"TICKAUTH.CREATE",
|
|
1984
|
+
"TICKAUTH.FULFILL",
|
|
1985
|
+
"TICKAUTH.REJECT",
|
|
1986
|
+
"SESSION.ACTIVATE",
|
|
1987
|
+
"SESSION.REFRESH",
|
|
1988
|
+
"SESSION.LOGOUT",
|
|
1989
|
+
"DEVICE.TRUST",
|
|
1990
|
+
"DEVICE.PROMOTE",
|
|
1991
|
+
"DEVICE.REVOKE",
|
|
1992
|
+
"DEVICE.LIST",
|
|
1993
|
+
"DEVICE.RENAME",
|
|
1994
|
+
"IDENTITY.RECOVERY",
|
|
1995
|
+
"IDENTITY.LOCK"
|
|
1966
1996
|
]);
|
|
1967
1997
|
function isKnownOpcode(op) {
|
|
1968
1998
|
return AXIS_OPCODES.has(op);
|
|
1969
1999
|
}
|
|
1970
2000
|
function isAdminOpcode(op) {
|
|
1971
|
-
return op.startsWith("ACTOR.KEY.") || op.startsWith("ISSUER.KEY.");
|
|
2001
|
+
return op.startsWith("ACTOR.KEY.") || op.startsWith("ISSUER.KEY.") || op.startsWith("IDENTITY.");
|
|
1972
2002
|
}
|
|
1973
2003
|
|
|
1974
2004
|
// src/core/receipt.ts
|
|
@@ -2018,7 +2048,42 @@ var INTENT_SENSITIVITY_MAP = {
|
|
|
2018
2048
|
// Admin intents
|
|
2019
2049
|
"admin.create_capsule": 4 /* CRITICAL */,
|
|
2020
2050
|
"admin.revoke_capsule": 4 /* CRITICAL */,
|
|
2021
|
-
"admin.issue_node_cert": 4 /* CRITICAL
|
|
2051
|
+
"admin.issue_node_cert": 4 /* CRITICAL */,
|
|
2052
|
+
// NestFlow: Auth
|
|
2053
|
+
"auth.web.login.request": 2 /* MEDIUM */,
|
|
2054
|
+
"auth.web.login.scan": 3 /* HIGH */,
|
|
2055
|
+
// NestFlow: TickAuth
|
|
2056
|
+
"tickauth.challenge.create": 2 /* MEDIUM */,
|
|
2057
|
+
"tickauth.challenge.fulfill": 3 /* HIGH */,
|
|
2058
|
+
"tickauth.challenge.reject": 2 /* MEDIUM */,
|
|
2059
|
+
// NestFlow: Capsule issuance
|
|
2060
|
+
"capsule.issue.login": 3 /* HIGH */,
|
|
2061
|
+
"capsule.issue.device_registration": 3 /* HIGH */,
|
|
2062
|
+
"capsule.issue.step_up": 3 /* HIGH */,
|
|
2063
|
+
"capsule.issue.recovery": 4 /* CRITICAL */,
|
|
2064
|
+
// NestFlow: Session
|
|
2065
|
+
"session.activate": 3 /* HIGH */,
|
|
2066
|
+
"session.refresh": 2 /* MEDIUM */,
|
|
2067
|
+
"session.logout": 1 /* LOW */,
|
|
2068
|
+
// NestFlow: Device trust
|
|
2069
|
+
"device.trust.request": 3 /* HIGH */,
|
|
2070
|
+
"device.trust.promote": 4 /* CRITICAL */,
|
|
2071
|
+
"device.revoke": 4 /* CRITICAL */,
|
|
2072
|
+
"device.list": 1 /* LOW */,
|
|
2073
|
+
"device.rename": 1 /* LOW */,
|
|
2074
|
+
// NestFlow: Protected operations
|
|
2075
|
+
"flow.publish": 2 /* MEDIUM */,
|
|
2076
|
+
"flow.delete": 3 /* HIGH */,
|
|
2077
|
+
"node.delete": 4 /* CRITICAL */,
|
|
2078
|
+
"secret.rotate": 4 /* CRITICAL */,
|
|
2079
|
+
"org.security.update": 4 /* CRITICAL */,
|
|
2080
|
+
"production.execution.approve": 4 /* CRITICAL */,
|
|
2081
|
+
// NestFlow: Recovery
|
|
2082
|
+
"identity.recovery.start": 4 /* CRITICAL */,
|
|
2083
|
+
"identity.recovery.complete": 4 /* CRITICAL */,
|
|
2084
|
+
"primary.device.rotate": 4 /* CRITICAL */,
|
|
2085
|
+
"identity.lock": 4 /* CRITICAL */,
|
|
2086
|
+
"identity.unlock": 4 /* CRITICAL */
|
|
2022
2087
|
};
|
|
2023
2088
|
function classifyIntent(intent) {
|
|
2024
2089
|
if (INTENT_SENSITIVITY_MAP[intent]) {
|
|
@@ -2116,6 +2181,425 @@ function isTimestampValid(ts, skewSeconds = 120) {
|
|
|
2116
2181
|
const diff = Math.abs(now - ts);
|
|
2117
2182
|
return diff <= skewSeconds;
|
|
2118
2183
|
}
|
|
2184
|
+
|
|
2185
|
+
// src/nestflow/types.ts
|
|
2186
|
+
var DeviceType = /* @__PURE__ */ ((DeviceType2) => {
|
|
2187
|
+
DeviceType2["MOBILE"] = "mobile";
|
|
2188
|
+
DeviceType2["BROWSER"] = "browser";
|
|
2189
|
+
DeviceType2["CLI"] = "cli";
|
|
2190
|
+
DeviceType2["SERVICE"] = "service";
|
|
2191
|
+
return DeviceType2;
|
|
2192
|
+
})(DeviceType || {});
|
|
2193
|
+
var DeviceTrustLevel = /* @__PURE__ */ ((DeviceTrustLevel2) => {
|
|
2194
|
+
DeviceTrustLevel2["PRIMARY"] = "primary";
|
|
2195
|
+
DeviceTrustLevel2["TRUSTED"] = "trusted";
|
|
2196
|
+
DeviceTrustLevel2["EPHEMERAL"] = "ephemeral";
|
|
2197
|
+
return DeviceTrustLevel2;
|
|
2198
|
+
})(DeviceTrustLevel || {});
|
|
2199
|
+
var DeviceStatus = /* @__PURE__ */ ((DeviceStatus2) => {
|
|
2200
|
+
DeviceStatus2["ACTIVE"] = "active";
|
|
2201
|
+
DeviceStatus2["REVOKED"] = "revoked";
|
|
2202
|
+
DeviceStatus2["SUSPENDED"] = "suspended";
|
|
2203
|
+
return DeviceStatus2;
|
|
2204
|
+
})(DeviceStatus || {});
|
|
2205
|
+
var LoginChallengeStatus = /* @__PURE__ */ ((LoginChallengeStatus3) => {
|
|
2206
|
+
LoginChallengeStatus3["PENDING"] = "pending";
|
|
2207
|
+
LoginChallengeStatus3["SCANNED"] = "scanned";
|
|
2208
|
+
LoginChallengeStatus3["APPROVED"] = "approved";
|
|
2209
|
+
LoginChallengeStatus3["REJECTED"] = "rejected";
|
|
2210
|
+
LoginChallengeStatus3["EXPIRED"] = "expired";
|
|
2211
|
+
return LoginChallengeStatus3;
|
|
2212
|
+
})(LoginChallengeStatus || {});
|
|
2213
|
+
var TickAuthChallengeStatus = /* @__PURE__ */ ((TickAuthChallengeStatus2) => {
|
|
2214
|
+
TickAuthChallengeStatus2["PENDING"] = "pending";
|
|
2215
|
+
TickAuthChallengeStatus2["FULFILLED"] = "fulfilled";
|
|
2216
|
+
TickAuthChallengeStatus2["REJECTED"] = "rejected";
|
|
2217
|
+
TickAuthChallengeStatus2["EXPIRED"] = "expired";
|
|
2218
|
+
return TickAuthChallengeStatus2;
|
|
2219
|
+
})(TickAuthChallengeStatus || {});
|
|
2220
|
+
var NestFlowCapsuleType = /* @__PURE__ */ ((NestFlowCapsuleType2) => {
|
|
2221
|
+
NestFlowCapsuleType2["LOGIN"] = "login";
|
|
2222
|
+
NestFlowCapsuleType2["DEVICE_REGISTRATION"] = "device_registration";
|
|
2223
|
+
NestFlowCapsuleType2["STEP_UP"] = "step_up";
|
|
2224
|
+
NestFlowCapsuleType2["RECOVERY"] = "recovery";
|
|
2225
|
+
return NestFlowCapsuleType2;
|
|
2226
|
+
})(NestFlowCapsuleType || {});
|
|
2227
|
+
var CapsuleStatus = /* @__PURE__ */ ((CapsuleStatus2) => {
|
|
2228
|
+
CapsuleStatus2["ACTIVE"] = "active";
|
|
2229
|
+
CapsuleStatus2["CONSUMED"] = "consumed";
|
|
2230
|
+
CapsuleStatus2["REVOKED"] = "revoked";
|
|
2231
|
+
CapsuleStatus2["EXPIRED"] = "expired";
|
|
2232
|
+
return CapsuleStatus2;
|
|
2233
|
+
})(CapsuleStatus || {});
|
|
2234
|
+
var SessionStatus = /* @__PURE__ */ ((SessionStatus2) => {
|
|
2235
|
+
SessionStatus2["ACTIVE"] = "active";
|
|
2236
|
+
SessionStatus2["EXPIRED"] = "expired";
|
|
2237
|
+
SessionStatus2["REVOKED"] = "revoked";
|
|
2238
|
+
return SessionStatus2;
|
|
2239
|
+
})(SessionStatus || {});
|
|
2240
|
+
var TrustLinkType = /* @__PURE__ */ ((TrustLinkType2) => {
|
|
2241
|
+
TrustLinkType2["LOGIN"] = "login";
|
|
2242
|
+
TrustLinkType2["PROMOTION"] = "promotion";
|
|
2243
|
+
TrustLinkType2["RECOVERY"] = "recovery";
|
|
2244
|
+
return TrustLinkType2;
|
|
2245
|
+
})(TrustLinkType || {});
|
|
2246
|
+
var TrustLinkStatus = /* @__PURE__ */ ((TrustLinkStatus2) => {
|
|
2247
|
+
TrustLinkStatus2["ACTIVE"] = "active";
|
|
2248
|
+
TrustLinkStatus2["REVOKED"] = "revoked";
|
|
2249
|
+
return TrustLinkStatus2;
|
|
2250
|
+
})(TrustLinkStatus || {});
|
|
2251
|
+
var AuthLevel = /* @__PURE__ */ ((AuthLevel2) => {
|
|
2252
|
+
AuthLevel2["SESSION"] = "session";
|
|
2253
|
+
AuthLevel2["SESSION_BROWSER"] = "session_browser";
|
|
2254
|
+
AuthLevel2["STEP_UP"] = "step_up";
|
|
2255
|
+
AuthLevel2["PRIMARY_DEVICE"] = "primary_device";
|
|
2256
|
+
return AuthLevel2;
|
|
2257
|
+
})(AuthLevel || {});
|
|
2258
|
+
|
|
2259
|
+
// src/nestflow/intents.ts
|
|
2260
|
+
var NESTFLOW_INTENTS = {
|
|
2261
|
+
// Auth
|
|
2262
|
+
AUTH_WEB_LOGIN_REQUEST: "auth.web.login.request",
|
|
2263
|
+
AUTH_WEB_LOGIN_SCAN: "auth.web.login.scan",
|
|
2264
|
+
// TickAuth
|
|
2265
|
+
TICKAUTH_CHALLENGE_CREATE: "tickauth.challenge.create",
|
|
2266
|
+
TICKAUTH_CHALLENGE_FULFILL: "tickauth.challenge.fulfill",
|
|
2267
|
+
TICKAUTH_CHALLENGE_REJECT: "tickauth.challenge.reject",
|
|
2268
|
+
// Capsule
|
|
2269
|
+
CAPSULE_ISSUE_LOGIN: "capsule.issue.login",
|
|
2270
|
+
CAPSULE_ISSUE_DEVICE_REGISTRATION: "capsule.issue.device_registration",
|
|
2271
|
+
CAPSULE_ISSUE_STEP_UP: "capsule.issue.step_up",
|
|
2272
|
+
CAPSULE_ISSUE_RECOVERY: "capsule.issue.recovery",
|
|
2273
|
+
// Session
|
|
2274
|
+
SESSION_ACTIVATE: "session.activate",
|
|
2275
|
+
SESSION_REFRESH: "session.refresh",
|
|
2276
|
+
SESSION_LOGOUT: "session.logout",
|
|
2277
|
+
// Device Trust
|
|
2278
|
+
DEVICE_TRUST_REQUEST: "device.trust.request",
|
|
2279
|
+
DEVICE_TRUST_PROMOTE: "device.trust.promote",
|
|
2280
|
+
DEVICE_REVOKE: "device.revoke",
|
|
2281
|
+
DEVICE_LIST: "device.list",
|
|
2282
|
+
DEVICE_RENAME: "device.rename",
|
|
2283
|
+
// Protected Operations
|
|
2284
|
+
FLOW_PUBLISH: "flow.publish",
|
|
2285
|
+
FLOW_DELETE: "flow.delete",
|
|
2286
|
+
NODE_DELETE: "node.delete",
|
|
2287
|
+
SECRET_ROTATE: "secret.rotate",
|
|
2288
|
+
ORG_SECURITY_UPDATE: "org.security.update",
|
|
2289
|
+
PRODUCTION_EXECUTION_APPROVE: "production.execution.approve",
|
|
2290
|
+
// Recovery
|
|
2291
|
+
IDENTITY_RECOVERY_START: "identity.recovery.start",
|
|
2292
|
+
IDENTITY_RECOVERY_COMPLETE: "identity.recovery.complete",
|
|
2293
|
+
PRIMARY_DEVICE_ROTATE: "primary.device.rotate",
|
|
2294
|
+
IDENTITY_LOCK: "identity.lock",
|
|
2295
|
+
IDENTITY_UNLOCK: "identity.unlock"
|
|
2296
|
+
};
|
|
2297
|
+
var NESTFLOW_INTENT_SET = new Set(
|
|
2298
|
+
Object.values(NESTFLOW_INTENTS)
|
|
2299
|
+
);
|
|
2300
|
+
function isNestFlowIntent(intent) {
|
|
2301
|
+
return NESTFLOW_INTENT_SET.has(intent);
|
|
2302
|
+
}
|
|
2303
|
+
|
|
2304
|
+
// src/nestflow/policy-map.ts
|
|
2305
|
+
var NESTFLOW_POLICY_MAP = {
|
|
2306
|
+
// Auth — unauthenticated initiator (session issued after)
|
|
2307
|
+
[NESTFLOW_INTENTS.AUTH_WEB_LOGIN_REQUEST]: "session" /* SESSION */,
|
|
2308
|
+
[NESTFLOW_INTENTS.AUTH_WEB_LOGIN_SCAN]: "primary_device" /* PRIMARY_DEVICE */,
|
|
2309
|
+
// TickAuth — primary device handles challenges
|
|
2310
|
+
[NESTFLOW_INTENTS.TICKAUTH_CHALLENGE_CREATE]: "session" /* SESSION */,
|
|
2311
|
+
[NESTFLOW_INTENTS.TICKAUTH_CHALLENGE_FULFILL]: "primary_device" /* PRIMARY_DEVICE */,
|
|
2312
|
+
[NESTFLOW_INTENTS.TICKAUTH_CHALLENGE_REJECT]: "primary_device" /* PRIMARY_DEVICE */,
|
|
2313
|
+
// Capsule issuance — varies per type
|
|
2314
|
+
[NESTFLOW_INTENTS.CAPSULE_ISSUE_LOGIN]: "primary_device" /* PRIMARY_DEVICE */,
|
|
2315
|
+
[NESTFLOW_INTENTS.CAPSULE_ISSUE_DEVICE_REGISTRATION]: "primary_device" /* PRIMARY_DEVICE */,
|
|
2316
|
+
[NESTFLOW_INTENTS.CAPSULE_ISSUE_STEP_UP]: "primary_device" /* PRIMARY_DEVICE */,
|
|
2317
|
+
[NESTFLOW_INTENTS.CAPSULE_ISSUE_RECOVERY]: "primary_device" /* PRIMARY_DEVICE */,
|
|
2318
|
+
// Session management
|
|
2319
|
+
[NESTFLOW_INTENTS.SESSION_ACTIVATE]: "session" /* SESSION */,
|
|
2320
|
+
[NESTFLOW_INTENTS.SESSION_REFRESH]: "session_browser" /* SESSION_BROWSER */,
|
|
2321
|
+
[NESTFLOW_INTENTS.SESSION_LOGOUT]: "session" /* SESSION */,
|
|
2322
|
+
// Device trust management
|
|
2323
|
+
[NESTFLOW_INTENTS.DEVICE_TRUST_REQUEST]: "session_browser" /* SESSION_BROWSER */,
|
|
2324
|
+
[NESTFLOW_INTENTS.DEVICE_TRUST_PROMOTE]: "step_up" /* STEP_UP */,
|
|
2325
|
+
[NESTFLOW_INTENTS.DEVICE_REVOKE]: "step_up" /* STEP_UP */,
|
|
2326
|
+
[NESTFLOW_INTENTS.DEVICE_LIST]: "session" /* SESSION */,
|
|
2327
|
+
[NESTFLOW_INTENTS.DEVICE_RENAME]: "session_browser" /* SESSION_BROWSER */,
|
|
2328
|
+
// Protected operations — require step-up auth
|
|
2329
|
+
[NESTFLOW_INTENTS.FLOW_PUBLISH]: "session_browser" /* SESSION_BROWSER */,
|
|
2330
|
+
[NESTFLOW_INTENTS.FLOW_DELETE]: "step_up" /* STEP_UP */,
|
|
2331
|
+
[NESTFLOW_INTENTS.NODE_DELETE]: "step_up" /* STEP_UP */,
|
|
2332
|
+
[NESTFLOW_INTENTS.SECRET_ROTATE]: "step_up" /* STEP_UP */,
|
|
2333
|
+
[NESTFLOW_INTENTS.ORG_SECURITY_UPDATE]: "step_up" /* STEP_UP */,
|
|
2334
|
+
[NESTFLOW_INTENTS.PRODUCTION_EXECUTION_APPROVE]: "step_up" /* STEP_UP */,
|
|
2335
|
+
// Recovery — highest privilege
|
|
2336
|
+
[NESTFLOW_INTENTS.IDENTITY_RECOVERY_START]: "primary_device" /* PRIMARY_DEVICE */,
|
|
2337
|
+
[NESTFLOW_INTENTS.IDENTITY_RECOVERY_COMPLETE]: "primary_device" /* PRIMARY_DEVICE */,
|
|
2338
|
+
[NESTFLOW_INTENTS.PRIMARY_DEVICE_ROTATE]: "primary_device" /* PRIMARY_DEVICE */,
|
|
2339
|
+
[NESTFLOW_INTENTS.IDENTITY_LOCK]: "primary_device" /* PRIMARY_DEVICE */,
|
|
2340
|
+
[NESTFLOW_INTENTS.IDENTITY_UNLOCK]: "primary_device" /* PRIMARY_DEVICE */
|
|
2341
|
+
};
|
|
2342
|
+
function getRequiredAuthLevel(intent) {
|
|
2343
|
+
return NESTFLOW_POLICY_MAP[intent];
|
|
2344
|
+
}
|
|
2345
|
+
var AUTH_LEVEL_ORDER = [
|
|
2346
|
+
"session" /* SESSION */,
|
|
2347
|
+
"session_browser" /* SESSION_BROWSER */,
|
|
2348
|
+
"step_up" /* STEP_UP */,
|
|
2349
|
+
"primary_device" /* PRIMARY_DEVICE */
|
|
2350
|
+
];
|
|
2351
|
+
function satisfiesAuthLevel(provided, required) {
|
|
2352
|
+
const providedIdx = AUTH_LEVEL_ORDER.indexOf(provided);
|
|
2353
|
+
const requiredIdx = AUTH_LEVEL_ORDER.indexOf(required);
|
|
2354
|
+
return providedIdx >= requiredIdx;
|
|
2355
|
+
}
|
|
2356
|
+
|
|
2357
|
+
// src/nestflow/guards.ts
|
|
2358
|
+
var allow = () => ({ allowed: true });
|
|
2359
|
+
var deny = (reason) => ({ allowed: false, reason });
|
|
2360
|
+
function checkIntentPolicy(intent, currentAuthLevel) {
|
|
2361
|
+
const required = getRequiredAuthLevel(intent);
|
|
2362
|
+
if (!required) {
|
|
2363
|
+
return allow();
|
|
2364
|
+
}
|
|
2365
|
+
if (satisfiesAuthLevel(currentAuthLevel, required)) {
|
|
2366
|
+
return allow();
|
|
2367
|
+
}
|
|
2368
|
+
return {
|
|
2369
|
+
allowed: false,
|
|
2370
|
+
reason: `Intent '${intent}' requires auth level '${required}', got '${currentAuthLevel}'`,
|
|
2371
|
+
step_up_intent: required === "step_up" /* STEP_UP */ ? intent : void 0
|
|
2372
|
+
};
|
|
2373
|
+
}
|
|
2374
|
+
function checkSession(session) {
|
|
2375
|
+
if (!session) {
|
|
2376
|
+
return deny("No session found");
|
|
2377
|
+
}
|
|
2378
|
+
if (session.status !== "active" /* ACTIVE */) {
|
|
2379
|
+
return deny(`Session status is '${session.status}', expected 'active'`);
|
|
2380
|
+
}
|
|
2381
|
+
if (new Date(session.expires_at).getTime() < Date.now()) {
|
|
2382
|
+
return deny("Session has expired");
|
|
2383
|
+
}
|
|
2384
|
+
return allow();
|
|
2385
|
+
}
|
|
2386
|
+
function checkBrowserProof(proof, expectedNonce) {
|
|
2387
|
+
if (!proof) {
|
|
2388
|
+
return deny("Browser proof-of-possession required but not provided");
|
|
2389
|
+
}
|
|
2390
|
+
if (!proof.server_nonce || !proof.signature || !proof.signature_algorithm) {
|
|
2391
|
+
return deny("Browser proof is missing required fields");
|
|
2392
|
+
}
|
|
2393
|
+
if (proof.server_nonce !== expectedNonce) {
|
|
2394
|
+
return deny("Browser proof nonce does not match expected server nonce");
|
|
2395
|
+
}
|
|
2396
|
+
return allow();
|
|
2397
|
+
}
|
|
2398
|
+
var TRUST_ORDER = [
|
|
2399
|
+
"ephemeral" /* EPHEMERAL */,
|
|
2400
|
+
"trusted" /* TRUSTED */,
|
|
2401
|
+
"primary" /* PRIMARY */
|
|
2402
|
+
];
|
|
2403
|
+
function checkDeviceTrust(device, minimumTrust) {
|
|
2404
|
+
if (!device) {
|
|
2405
|
+
return deny("Device not found");
|
|
2406
|
+
}
|
|
2407
|
+
if (device.status !== "active" /* ACTIVE */) {
|
|
2408
|
+
return deny(`Device status is '${device.status}', expected 'active'`);
|
|
2409
|
+
}
|
|
2410
|
+
const deviceIdx = TRUST_ORDER.indexOf(device.trust_level);
|
|
2411
|
+
const requiredIdx = TRUST_ORDER.indexOf(minimumTrust);
|
|
2412
|
+
if (deviceIdx < requiredIdx) {
|
|
2413
|
+
return deny(
|
|
2414
|
+
`Device trust level '${device.trust_level}' does not meet minimum '${minimumTrust}'`
|
|
2415
|
+
);
|
|
2416
|
+
}
|
|
2417
|
+
return allow();
|
|
2418
|
+
}
|
|
2419
|
+
function checkCapsule(capsule, intent, requestingDeviceUid) {
|
|
2420
|
+
if (!capsule) {
|
|
2421
|
+
return deny("Capsule not found");
|
|
2422
|
+
}
|
|
2423
|
+
if (capsule.status !== "active" /* ACTIVE */) {
|
|
2424
|
+
return deny(`Capsule status is '${capsule.status}', expected 'active'`);
|
|
2425
|
+
}
|
|
2426
|
+
if (new Date(capsule.expires_at).getTime() < Date.now()) {
|
|
2427
|
+
return deny("Capsule has expired");
|
|
2428
|
+
}
|
|
2429
|
+
const intentAllowed = capsule.intents.some((pattern) => {
|
|
2430
|
+
if (pattern === "*") return true;
|
|
2431
|
+
if (pattern === intent) return true;
|
|
2432
|
+
if (pattern.endsWith(".*")) {
|
|
2433
|
+
return intent.startsWith(pattern.slice(0, -1));
|
|
2434
|
+
}
|
|
2435
|
+
return false;
|
|
2436
|
+
});
|
|
2437
|
+
if (!intentAllowed) {
|
|
2438
|
+
return deny(`Capsule does not authorize intent '${intent}'`);
|
|
2439
|
+
}
|
|
2440
|
+
if (capsule.device_uid && requestingDeviceUid && capsule.device_uid !== requestingDeviceUid) {
|
|
2441
|
+
return deny("Capsule is bound to a different device");
|
|
2442
|
+
}
|
|
2443
|
+
return allow();
|
|
2444
|
+
}
|
|
2445
|
+
function checkLoginChallenge(challenge, expectedStatus) {
|
|
2446
|
+
if (!challenge) {
|
|
2447
|
+
return deny("Login challenge not found");
|
|
2448
|
+
}
|
|
2449
|
+
if (new Date(challenge.expires_at).getTime() < Date.now()) {
|
|
2450
|
+
return deny("Login challenge has expired");
|
|
2451
|
+
}
|
|
2452
|
+
if (challenge.status !== expectedStatus) {
|
|
2453
|
+
return deny(
|
|
2454
|
+
`Login challenge status is '${challenge.status}', expected '${expectedStatus}'`
|
|
2455
|
+
);
|
|
2456
|
+
}
|
|
2457
|
+
return allow();
|
|
2458
|
+
}
|
|
2459
|
+
function checkTickAuth(challenge) {
|
|
2460
|
+
if (!challenge) {
|
|
2461
|
+
return deny("TickAuth challenge not found");
|
|
2462
|
+
}
|
|
2463
|
+
if (challenge.status !== "pending" /* PENDING */) {
|
|
2464
|
+
return deny(
|
|
2465
|
+
`TickAuth challenge status is '${challenge.status}', expected 'pending'`
|
|
2466
|
+
);
|
|
2467
|
+
}
|
|
2468
|
+
const now = Date.now();
|
|
2469
|
+
const start = new Date(challenge.tick_window.start).getTime();
|
|
2470
|
+
const end = new Date(challenge.tick_window.end).getTime();
|
|
2471
|
+
if (now < start || now > end) {
|
|
2472
|
+
return deny("TickAuth challenge is outside its tick window");
|
|
2473
|
+
}
|
|
2474
|
+
return allow();
|
|
2475
|
+
}
|
|
2476
|
+
async function checkReplayProtection(nonce, store, windowMs = 5 * 60 * 1e3) {
|
|
2477
|
+
if (!nonce) {
|
|
2478
|
+
return deny("Nonce is required for replay protection");
|
|
2479
|
+
}
|
|
2480
|
+
const seen = await store.has(nonce);
|
|
2481
|
+
if (seen) {
|
|
2482
|
+
return deny("Nonce has already been used (replay detected)");
|
|
2483
|
+
}
|
|
2484
|
+
await store.add(nonce, new Date(Date.now() + windowMs));
|
|
2485
|
+
return allow();
|
|
2486
|
+
}
|
|
2487
|
+
|
|
2488
|
+
// src/nestflow/invariants.ts
|
|
2489
|
+
var LOGIN_CHALLENGE_TRANSITIONS = {
|
|
2490
|
+
["pending" /* PENDING */]: [
|
|
2491
|
+
"scanned" /* SCANNED */,
|
|
2492
|
+
"expired" /* EXPIRED */
|
|
2493
|
+
],
|
|
2494
|
+
["scanned" /* SCANNED */]: [
|
|
2495
|
+
"approved" /* APPROVED */,
|
|
2496
|
+
"rejected" /* REJECTED */,
|
|
2497
|
+
"expired" /* EXPIRED */
|
|
2498
|
+
],
|
|
2499
|
+
["approved" /* APPROVED */]: [],
|
|
2500
|
+
["rejected" /* REJECTED */]: [],
|
|
2501
|
+
["expired" /* EXPIRED */]: []
|
|
2502
|
+
};
|
|
2503
|
+
var TICKAUTH_TRANSITIONS = {
|
|
2504
|
+
["pending" /* PENDING */]: [
|
|
2505
|
+
"fulfilled" /* FULFILLED */,
|
|
2506
|
+
"rejected" /* REJECTED */,
|
|
2507
|
+
"expired" /* EXPIRED */
|
|
2508
|
+
],
|
|
2509
|
+
["fulfilled" /* FULFILLED */]: [],
|
|
2510
|
+
["rejected" /* REJECTED */]: [],
|
|
2511
|
+
["expired" /* EXPIRED */]: []
|
|
2512
|
+
};
|
|
2513
|
+
var CAPSULE_TRANSITIONS = {
|
|
2514
|
+
["active" /* ACTIVE */]: [
|
|
2515
|
+
"consumed" /* CONSUMED */,
|
|
2516
|
+
"revoked" /* REVOKED */,
|
|
2517
|
+
"expired" /* EXPIRED */
|
|
2518
|
+
],
|
|
2519
|
+
["consumed" /* CONSUMED */]: [],
|
|
2520
|
+
["revoked" /* REVOKED */]: [],
|
|
2521
|
+
["expired" /* EXPIRED */]: []
|
|
2522
|
+
};
|
|
2523
|
+
var SESSION_TRANSITIONS = {
|
|
2524
|
+
["active" /* ACTIVE */]: ["expired" /* EXPIRED */, "revoked" /* REVOKED */],
|
|
2525
|
+
["expired" /* EXPIRED */]: [],
|
|
2526
|
+
["revoked" /* REVOKED */]: []
|
|
2527
|
+
};
|
|
2528
|
+
var DEVICE_TRANSITIONS = {
|
|
2529
|
+
["active" /* ACTIVE */]: ["suspended" /* SUSPENDED */, "revoked" /* REVOKED */],
|
|
2530
|
+
["suspended" /* SUSPENDED */]: ["active" /* ACTIVE */, "revoked" /* REVOKED */],
|
|
2531
|
+
["revoked" /* REVOKED */]: []
|
|
2532
|
+
};
|
|
2533
|
+
var TRUST_LINK_TRANSITIONS = {
|
|
2534
|
+
["active" /* ACTIVE */]: ["revoked" /* REVOKED */],
|
|
2535
|
+
["revoked" /* REVOKED */]: []
|
|
2536
|
+
};
|
|
2537
|
+
function checkTransition(entity, transitions, from, to) {
|
|
2538
|
+
const allowed = transitions[from];
|
|
2539
|
+
if (!allowed) {
|
|
2540
|
+
return {
|
|
2541
|
+
valid: false,
|
|
2542
|
+
reason: `${entity}: unknown current state '${from}'`
|
|
2543
|
+
};
|
|
2544
|
+
}
|
|
2545
|
+
if (!allowed.includes(to)) {
|
|
2546
|
+
return {
|
|
2547
|
+
valid: false,
|
|
2548
|
+
reason: `${entity}: invalid transition '${from}' \u2192 '${to}'. Allowed: [${allowed.join(", ")}]`
|
|
2549
|
+
};
|
|
2550
|
+
}
|
|
2551
|
+
return { valid: true };
|
|
2552
|
+
}
|
|
2553
|
+
function validateLoginChallengeTransition(from, to) {
|
|
2554
|
+
return checkTransition(
|
|
2555
|
+
"LoginChallenge",
|
|
2556
|
+
LOGIN_CHALLENGE_TRANSITIONS,
|
|
2557
|
+
from,
|
|
2558
|
+
to
|
|
2559
|
+
);
|
|
2560
|
+
}
|
|
2561
|
+
function validateTickAuthTransition(from, to) {
|
|
2562
|
+
return checkTransition("TickAuthChallenge", TICKAUTH_TRANSITIONS, from, to);
|
|
2563
|
+
}
|
|
2564
|
+
function validateCapsuleTransition(from, to) {
|
|
2565
|
+
return checkTransition("Capsule", CAPSULE_TRANSITIONS, from, to);
|
|
2566
|
+
}
|
|
2567
|
+
function validateSessionTransition(from, to) {
|
|
2568
|
+
return checkTransition("Session", SESSION_TRANSITIONS, from, to);
|
|
2569
|
+
}
|
|
2570
|
+
function validateDeviceTransition(from, to) {
|
|
2571
|
+
return checkTransition("Device", DEVICE_TRANSITIONS, from, to);
|
|
2572
|
+
}
|
|
2573
|
+
function validateTrustLinkTransition(from, to) {
|
|
2574
|
+
return checkTransition("TrustLink", TRUST_LINK_TRANSITIONS, from, to);
|
|
2575
|
+
}
|
|
2576
|
+
function isLoginChallengeTerminal(status) {
|
|
2577
|
+
return [
|
|
2578
|
+
"approved" /* APPROVED */,
|
|
2579
|
+
"rejected" /* REJECTED */,
|
|
2580
|
+
"expired" /* EXPIRED */
|
|
2581
|
+
].includes(status);
|
|
2582
|
+
}
|
|
2583
|
+
function isTickAuthTerminal(status) {
|
|
2584
|
+
return [
|
|
2585
|
+
"fulfilled" /* FULFILLED */,
|
|
2586
|
+
"rejected" /* REJECTED */,
|
|
2587
|
+
"expired" /* EXPIRED */
|
|
2588
|
+
].includes(status);
|
|
2589
|
+
}
|
|
2590
|
+
function isCapsuleTerminal(status) {
|
|
2591
|
+
return [
|
|
2592
|
+
"consumed" /* CONSUMED */,
|
|
2593
|
+
"revoked" /* REVOKED */,
|
|
2594
|
+
"expired" /* EXPIRED */
|
|
2595
|
+
].includes(status);
|
|
2596
|
+
}
|
|
2597
|
+
function isSessionTerminal(status) {
|
|
2598
|
+
return ["expired" /* EXPIRED */, "revoked" /* REVOKED */].includes(status);
|
|
2599
|
+
}
|
|
2600
|
+
function isDeviceTerminal(status) {
|
|
2601
|
+
return status === "revoked" /* REVOKED */;
|
|
2602
|
+
}
|
|
2119
2603
|
export {
|
|
2120
2604
|
ATS1_HDR,
|
|
2121
2605
|
ATS1_SCHEMA,
|
|
@@ -2123,14 +2607,19 @@ export {
|
|
|
2123
2607
|
AXIS_OPCODES,
|
|
2124
2608
|
AXIS_VERSION,
|
|
2125
2609
|
ats1_exports as Ats1Codec,
|
|
2610
|
+
AuthLevel,
|
|
2126
2611
|
AxisFrameZ,
|
|
2127
2612
|
T as AxisPacketTags,
|
|
2128
2613
|
BodyProfile,
|
|
2129
2614
|
CAPABILITIES,
|
|
2615
|
+
CapsuleStatus,
|
|
2130
2616
|
ContractViolationError,
|
|
2131
2617
|
DEFAULT_CONTRACTS,
|
|
2132
2618
|
DEFAULT_TIMEOUT,
|
|
2133
2619
|
Decision,
|
|
2620
|
+
DeviceStatus,
|
|
2621
|
+
DeviceTrustLevel,
|
|
2622
|
+
DeviceType,
|
|
2134
2623
|
ERR_BAD_SIGNATURE,
|
|
2135
2624
|
ERR_CONTRACT_VIOLATION,
|
|
2136
2625
|
ERR_INVALID_PACKET,
|
|
@@ -2149,6 +2638,7 @@ export {
|
|
|
2149
2638
|
Intent,
|
|
2150
2639
|
IntentRouter,
|
|
2151
2640
|
IntentSensitivity,
|
|
2641
|
+
LoginChallengeStatus,
|
|
2152
2642
|
MAX_BODY_LEN,
|
|
2153
2643
|
MAX_FRAME_LEN,
|
|
2154
2644
|
MAX_HDR_LEN,
|
|
@@ -2163,6 +2653,10 @@ export {
|
|
|
2163
2653
|
NCERT_PUB,
|
|
2164
2654
|
NCERT_SCOPE,
|
|
2165
2655
|
NCERT_SIG,
|
|
2656
|
+
NESTFLOW_INTENTS,
|
|
2657
|
+
NESTFLOW_INTENT_SET,
|
|
2658
|
+
NESTFLOW_POLICY_MAP,
|
|
2659
|
+
NestFlowCapsuleType,
|
|
2166
2660
|
PROOF_CAPABILITIES,
|
|
2167
2661
|
PROOF_CAPSULE,
|
|
2168
2662
|
PROOF_JWT,
|
|
@@ -2177,6 +2671,7 @@ export {
|
|
|
2177
2671
|
Schema2012_PasskeyLoginVerifyRes,
|
|
2178
2672
|
Schema2021_PasskeyRegisterOptionsReq,
|
|
2179
2673
|
SensorDecisions,
|
|
2674
|
+
SessionStatus,
|
|
2180
2675
|
TLV_ACTOR_ID,
|
|
2181
2676
|
TLV_AUD,
|
|
2182
2677
|
TLV_BODY_ARR,
|
|
@@ -2208,6 +2703,9 @@ export {
|
|
|
2208
2703
|
TLV_TRACE_ID,
|
|
2209
2704
|
TLV_TS,
|
|
2210
2705
|
TLV_UPLOAD_ID,
|
|
2706
|
+
TickAuthChallengeStatus,
|
|
2707
|
+
TrustLinkStatus,
|
|
2708
|
+
TrustLinkType,
|
|
2211
2709
|
axis1SigningBytes,
|
|
2212
2710
|
b64urlDecode,
|
|
2213
2711
|
b64urlDecodeString,
|
|
@@ -2221,6 +2719,14 @@ export {
|
|
|
2221
2719
|
canAccessResource,
|
|
2222
2720
|
canonicalJson,
|
|
2223
2721
|
canonicalJsonExcluding,
|
|
2722
|
+
checkBrowserProof,
|
|
2723
|
+
checkCapsule,
|
|
2724
|
+
checkDeviceTrust,
|
|
2725
|
+
checkIntentPolicy,
|
|
2726
|
+
checkLoginChallenge,
|
|
2727
|
+
checkReplayProtection,
|
|
2728
|
+
checkSession,
|
|
2729
|
+
checkTickAuth,
|
|
2224
2730
|
classifyIntent,
|
|
2225
2731
|
computeReceiptHash,
|
|
2226
2732
|
computeSignaturePayload,
|
|
@@ -2237,10 +2743,17 @@ export {
|
|
|
2237
2743
|
encodeTLVs,
|
|
2238
2744
|
encodeVarint,
|
|
2239
2745
|
generateEd25519KeyPair,
|
|
2746
|
+
getRequiredAuthLevel,
|
|
2240
2747
|
getSignTarget,
|
|
2241
2748
|
hasScope,
|
|
2242
2749
|
isAdminOpcode,
|
|
2750
|
+
isCapsuleTerminal,
|
|
2751
|
+
isDeviceTerminal,
|
|
2243
2752
|
isKnownOpcode,
|
|
2753
|
+
isLoginChallengeTerminal,
|
|
2754
|
+
isNestFlowIntent,
|
|
2755
|
+
isSessionTerminal,
|
|
2756
|
+
isTickAuthTerminal,
|
|
2244
2757
|
isTimestampValid,
|
|
2245
2758
|
nonce16,
|
|
2246
2759
|
normalizeSensorDecision,
|
|
@@ -2251,6 +2764,7 @@ export {
|
|
|
2251
2764
|
packPasskeyRegisterOptionsReq,
|
|
2252
2765
|
parseScope,
|
|
2253
2766
|
resolveTimeout,
|
|
2767
|
+
satisfiesAuthLevel,
|
|
2254
2768
|
sensitivityName,
|
|
2255
2769
|
sha256,
|
|
2256
2770
|
signFrame,
|
|
@@ -2260,7 +2774,13 @@ export {
|
|
|
2260
2774
|
unpackPasskeyLoginVerifyReq,
|
|
2261
2775
|
unpackPasskeyRegisterOptionsReq,
|
|
2262
2776
|
utf8,
|
|
2777
|
+
validateCapsuleTransition,
|
|
2778
|
+
validateDeviceTransition,
|
|
2263
2779
|
validateFrameShape,
|
|
2780
|
+
validateLoginChallengeTransition,
|
|
2781
|
+
validateSessionTransition,
|
|
2782
|
+
validateTickAuthTransition,
|
|
2783
|
+
validateTrustLinkTransition,
|
|
2264
2784
|
varintLength,
|
|
2265
2785
|
varintU,
|
|
2266
2786
|
verifyFrameSignature
|