@rynx-ai/daemon 0.1.11-beta.53 → 0.1.11-beta.54
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/plugin-host-rpc.js
CHANGED
|
@@ -9,7 +9,7 @@ import { PluginRunnerError } from "@rynx-ai/plugin-runner";
|
|
|
9
9
|
import { ensurePluginSessionLaunch, replayPluginSessionLaunch, SessionLaunchOperationConflictError, SessionLaunchOperationTargetDeletedError, } from "./session-launch-operations.js";
|
|
10
10
|
import { createControlLink } from "./control-link-store.js";
|
|
11
11
|
import { nodeLogFiles, sessionLogFiles } from "./log-files.js";
|
|
12
|
-
import { issueSessionPortalTicket, revokeSessionPortalGrant, } from "./session-portal-grant-store.js";
|
|
12
|
+
import { issueSessionPortalTicket, revokeSessionPortalGrant, renewSessionPortalGrant, } from "./session-portal-grant-store.js";
|
|
13
13
|
import { claimSessionTimelineProjection, completeSessionTimelineProjection, } from "./session-timeline-projection-store.js";
|
|
14
14
|
const MAX_MESSAGE_LENGTH = 1_000_000;
|
|
15
15
|
/** Leaves ample room for the RPC envelope below the runner's 1 MiB line cap. */
|
|
@@ -134,6 +134,7 @@ export class PluginHostRpc {
|
|
|
134
134
|
? {
|
|
135
135
|
sessionPortalEmbedOrigin: true,
|
|
136
136
|
sessionPortalGrantRevocation: true,
|
|
137
|
+
sessionPortalGrantRenewal: true,
|
|
137
138
|
}
|
|
138
139
|
: {}),
|
|
139
140
|
},
|
|
@@ -251,6 +252,33 @@ export class PluginHostRpc {
|
|
|
251
252
|
this.ownedSession(sessionId);
|
|
252
253
|
return this.issueSessionPortalLink("single_session", requiredSessionPortalAccess(input), sessionId, optionalSessionPortalEmbedOrigin(input.embedOrigin), optionalString(input.grantHandle, "grantHandle", 128));
|
|
253
254
|
}
|
|
255
|
+
case "session.portal.grant.renew": {
|
|
256
|
+
const input = record(params);
|
|
257
|
+
const scope = input.scope;
|
|
258
|
+
if (scope !== "single_session" && scope !== "plugin_sessions") {
|
|
259
|
+
throw new PluginHostCallError("INVALID_PARAMS", "scope must be single_session or plugin_sessions");
|
|
260
|
+
}
|
|
261
|
+
const sessionId = scope === "single_session" ? requiredSessionId(input) : undefined;
|
|
262
|
+
if (sessionId)
|
|
263
|
+
this.ownedSession(sessionId);
|
|
264
|
+
else if (input.sessionId !== undefined) {
|
|
265
|
+
throw new PluginHostCallError("INVALID_PARAMS", "plugin_sessions scope cannot specify a Session");
|
|
266
|
+
}
|
|
267
|
+
const embedOrigin = optionalSessionPortalEmbedOrigin(input.embedOrigin);
|
|
268
|
+
if (!embedOrigin)
|
|
269
|
+
throw new PluginHostCallError("INVALID_PARAMS", "embedOrigin is required for renewal");
|
|
270
|
+
const renewed = renewSessionPortalGrant({
|
|
271
|
+
pluginId: this.principalId,
|
|
272
|
+
grantHandle: requiredString(input.grantHandle, "grantHandle", 128),
|
|
273
|
+
scope,
|
|
274
|
+
access: requiredSessionPortalAccess(input),
|
|
275
|
+
sessionId,
|
|
276
|
+
embedOrigin,
|
|
277
|
+
});
|
|
278
|
+
if (!renewed)
|
|
279
|
+
throw new PluginHostCallError("HOST_CALL_FAILED", "Session Portal grant expired, revoked, or does not match the authorized scope");
|
|
280
|
+
return renewed;
|
|
281
|
+
}
|
|
254
282
|
case "session.portal.grant.revoke": {
|
|
255
283
|
const grantHandle = requiredString(record(params).grantHandle, "grantHandle", 128);
|
|
256
284
|
return revokeSessionPortalGrant({
|
|
@@ -34,6 +34,20 @@ export declare function redeemSessionPortalTicket(ticket: string, now?: Date, em
|
|
|
34
34
|
* exact grant that was issued; it does not authorize an API call. */
|
|
35
35
|
export declare function inspectSessionPortalGrant(portalId: string, now?: Date): SessionPortalAuthorization | undefined;
|
|
36
36
|
export declare function authorizeSessionPortalGrant(portalId: string, secret: string, now?: Date): SessionPortalAuthorization | undefined;
|
|
37
|
+
/** Only the issuing Plugin may extend an embedded grant, after its external
|
|
38
|
+
* authorizer has rechecked the viewer's current permissions. Match the freshly
|
|
39
|
+
* authorized scope so an old handle cannot renew another Session or access level. */
|
|
40
|
+
export declare function renewSessionPortalGrant(input: {
|
|
41
|
+
pluginId: string;
|
|
42
|
+
grantHandle: string;
|
|
43
|
+
scope: SessionPortalScope;
|
|
44
|
+
access: SessionPortalAccess;
|
|
45
|
+
sessionId?: string;
|
|
46
|
+
embedOrigin: string;
|
|
47
|
+
now?: Date;
|
|
48
|
+
}): {
|
|
49
|
+
expiresAt: string;
|
|
50
|
+
} | undefined;
|
|
37
51
|
/** Revoke one issued Portal link, whether its ticket is still unused or it has
|
|
38
52
|
* already become a browser grant. The opaque handle carries no product meaning. */
|
|
39
53
|
export declare function revokeSessionPortalGrant(input: {
|
|
@@ -91,6 +91,20 @@ export function authorizeSessionPortalGrant(portalId, secret, now = new Date())
|
|
|
91
91
|
return undefined;
|
|
92
92
|
return publicGrant(row);
|
|
93
93
|
}
|
|
94
|
+
/** Only the issuing Plugin may extend an embedded grant, after its external
|
|
95
|
+
* authorizer has rechecked the viewer's current permissions. Match the freshly
|
|
96
|
+
* authorized scope so an old handle cannot renew another Session or access level. */
|
|
97
|
+
export function renewSessionPortalGrant(input) {
|
|
98
|
+
if (!input.embedOrigin)
|
|
99
|
+
return undefined;
|
|
100
|
+
const now = input.now ?? new Date();
|
|
101
|
+
const expiresAt = new Date(now.getTime() + GRANT_TTL_MS).toISOString();
|
|
102
|
+
const updated = db().prepare(`UPDATE session_portal_grants SET expires_at = ?
|
|
103
|
+
WHERE plugin_id = ? AND grant_handle = ? AND scope = ? AND access = ?
|
|
104
|
+
AND session_id IS ? AND embed_origin = ?
|
|
105
|
+
AND revoked_at IS NULL AND expires_at > ?`).run(expiresAt, input.pluginId, input.grantHandle, input.scope, input.access, input.sessionId ?? null, input.embedOrigin, now.toISOString());
|
|
106
|
+
return updated.changes > 0 ? { expiresAt } : undefined;
|
|
107
|
+
}
|
|
94
108
|
/** Revoke one issued Portal link, whether its ticket is still unused or it has
|
|
95
109
|
* already become a browser grant. The opaque handle carries no product meaning. */
|
|
96
110
|
export async function revokeSessionPortalGrant(input) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rynx-ai/daemon",
|
|
3
|
-
"version": "0.1.11-beta.
|
|
3
|
+
"version": "0.1.11-beta.54",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/rynx-ai/rynx.git",
|
|
@@ -60,18 +60,18 @@
|
|
|
60
60
|
"tar": "^7.5.19",
|
|
61
61
|
"undici": "^7.28.0",
|
|
62
62
|
"ws": "^8.21.0",
|
|
63
|
-
"@rynx-ai/core": "0.1.11-beta.
|
|
64
|
-
"@rynx-ai/emulator": "0.1.11-beta.
|
|
65
|
-
"@rynx-ai/plugin-runner": "0.1.11-beta.
|
|
66
|
-
"@rynx-ai/plugin-sdk": "0.1.11-beta.
|
|
67
|
-
"@rynx-ai/protocol": "0.1.11-beta.
|
|
68
|
-
"@rynx-ai/remote-runtime-client": "0.1.11-beta.
|
|
69
|
-
"@rynx-ai/server": "0.1.11-beta.
|
|
63
|
+
"@rynx-ai/core": "0.1.11-beta.54",
|
|
64
|
+
"@rynx-ai/emulator": "0.1.11-beta.54",
|
|
65
|
+
"@rynx-ai/plugin-runner": "0.1.11-beta.54",
|
|
66
|
+
"@rynx-ai/plugin-sdk": "0.1.11-beta.54",
|
|
67
|
+
"@rynx-ai/protocol": "0.1.11-beta.54",
|
|
68
|
+
"@rynx-ai/remote-runtime-client": "0.1.11-beta.54",
|
|
69
|
+
"@rynx-ai/server": "0.1.11-beta.54"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
72
|
"@types/ws": "^8.18.1",
|
|
73
|
-
"@rynx-ai/browser-cdp": "0.1.11-beta.
|
|
74
|
-
"@rynx-ai/plugin-channel-lark": "0.1.11-beta.
|
|
73
|
+
"@rynx-ai/browser-cdp": "0.1.11-beta.54",
|
|
74
|
+
"@rynx-ai/plugin-channel-lark": "0.1.11-beta.54"
|
|
75
75
|
},
|
|
76
76
|
"scripts": {
|
|
77
77
|
"build": "rm -rf dist bundled-plugins && tsc -p tsconfig.json && chmod +x dist/index-daemon.js && node scripts/prepare-agent-browser.mjs && node ../../scripts/stage-bundled-plugins.mjs && node scripts/build-plugin-maintenance.mjs",
|