@qontinui/ui-bridge 0.21.0 → 0.21.1
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/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/dist/injected/bundle.global.js +1 -1
- package/dist/{nextjs-NxTdtHhA.d.ts → nextjs-Bu7ZGwGe.d.ts} +35 -7
- package/dist/{nextjs-DZf4_LXo.d.mts → nextjs-DCLP7WgI.d.mts} +35 -7
- package/dist/react/index.js +1 -1
- package/dist/react/index.mjs +1 -1
- package/dist/server/index.d.mts +2 -2
- package/dist/server/index.d.ts +2 -2
- package/dist/server/index.js +57 -11
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +57 -11
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/nextjs.d.mts +1 -1
- package/dist/server/nextjs.d.ts +1 -1
- package/dist/server/nextjs.js +15 -2
- package/dist/server/nextjs.js.map +1 -1
- package/dist/server/nextjs.mjs +15 -2
- package/dist/server/nextjs.mjs.map +1 -1
- package/package.json +1 -1
package/dist/server/index.mjs
CHANGED
|
@@ -25865,7 +25865,12 @@ function handleRelayRoute(method, path, request, relay, config) {
|
|
|
25865
25865
|
400
|
|
25866
25866
|
);
|
|
25867
25867
|
}
|
|
25868
|
-
|
|
25868
|
+
const callerUserId = request.headers.get("x-caller-user-id") ?? request.headers.get("X-Caller-User-Id") ?? void 0;
|
|
25869
|
+
const registration = relay.recordRegistration(
|
|
25870
|
+
heartbeatTabId,
|
|
25871
|
+
{ userId, sessionId },
|
|
25872
|
+
{ callerUserId }
|
|
25873
|
+
);
|
|
25869
25874
|
relay.receiveHeartbeat(heartbeatTabId, {
|
|
25870
25875
|
url: typeof body?.url === "string" ? body.url : void 0,
|
|
25871
25876
|
title: typeof body?.title === "string" ? body.title : void 0,
|
|
@@ -25875,7 +25880,15 @@ function handleRelayRoute(method, path, request, relay, config) {
|
|
|
25875
25880
|
const tabRegistered = diag.connectedTabs.includes(heartbeatTabId);
|
|
25876
25881
|
return jsonResponse({
|
|
25877
25882
|
success: true,
|
|
25878
|
-
data: {
|
|
25883
|
+
data: {
|
|
25884
|
+
received: true,
|
|
25885
|
+
tabRegistered,
|
|
25886
|
+
// Observability: signals an ownership claim/transfer was refused
|
|
25887
|
+
// because the claimed userId was not auth-proven. Not a fatal
|
|
25888
|
+
// heartbeat error — the loop continues; the tab simply keeps its
|
|
25889
|
+
// prior (or no) owner. Absent when ownership was assigned.
|
|
25890
|
+
...registration.ownershipAssigned ? {} : { ownershipAssigned: false, ownerChangeRejected: registration.rejectedReason }
|
|
25891
|
+
},
|
|
25879
25892
|
timestamp: Date.now()
|
|
25880
25893
|
});
|
|
25881
25894
|
})();
|
|
@@ -29125,20 +29138,52 @@ var CommandRelay = class {
|
|
|
29125
29138
|
* has been called for it. `listOwnedTabs`, `assertOwnership`, and the
|
|
29126
29139
|
* bus-envelope receiver check all key off this map.
|
|
29127
29140
|
*
|
|
29128
|
-
* Re-registration under a DIFFERENT `userId`
|
|
29129
|
-
*
|
|
29130
|
-
*
|
|
29131
|
-
*
|
|
29132
|
-
*
|
|
29133
|
-
*
|
|
29134
|
-
|
|
29135
|
-
|
|
29141
|
+
* Re-registration under a DIFFERENT `userId` (e.g. a tab survives a
|
|
29142
|
+
* re-login) is permitted ONLY when the new user is AUTH-PROVEN, not
|
|
29143
|
+
* merely asserted. `metadata.userId` rides in the (browser-supplied)
|
|
29144
|
+
* heartbeat body and is therefore untrusted on its own: without a
|
|
29145
|
+
* proof gate, anyone who learns a victim's `tabId` could POST a
|
|
29146
|
+
* heartbeat claiming any `userId` and silently seize ownership of the
|
|
29147
|
+
* tab (and with it the ability to drive it / settle its commands).
|
|
29148
|
+
*
|
|
29149
|
+
* `options.callerUserId` is the identity the consumer's auth gate
|
|
29150
|
+
* proved and injected as `X-Caller-User-Id` (never a browser value).
|
|
29151
|
+
* The rule:
|
|
29152
|
+
*
|
|
29153
|
+
* - Same-owner heartbeat (existing owner === claimed userId): always
|
|
29154
|
+
* a refresh — `sessionId`/`lastSeen` updated in place. No proof
|
|
29155
|
+
* needed; you already hold the tab and the claim matches.
|
|
29156
|
+
* - TRANSFER (a DIFFERENT user already owns the tab): the claimed
|
|
29157
|
+
* `userId` MUST be auth-proven and equal to `callerUserId`. An
|
|
29158
|
+
* unauthenticated (`callerUserId` absent) or mismatched claim is
|
|
29159
|
+
* REFUSED and the prior owner is left untouched — this is the
|
|
29160
|
+
* takeover primitive being closed. A genuine re-login carries the
|
|
29161
|
+
* new user's proven identity and therefore still transfers.
|
|
29162
|
+
* - First CLAIM (tab has no owner yet — bootstrap): honored, so a
|
|
29163
|
+
* header-less / single-trust-domain deployment can still register
|
|
29164
|
+
* tabs. A *present* proven identity must still match the claimed
|
|
29165
|
+
* `userId` (you cannot bootstrap a tab under an identity you
|
|
29166
|
+
* cannot back).
|
|
29167
|
+
*
|
|
29168
|
+
* Returns whether ownership was (re)assigned so the HTTP layer can
|
|
29169
|
+
* surface the refusal without bricking the heartbeat loop.
|
|
29170
|
+
*/
|
|
29171
|
+
recordRegistration(tabId, metadata, options) {
|
|
29136
29172
|
const now = Date.now();
|
|
29173
|
+
const proven = options?.callerUserId;
|
|
29174
|
+
if (proven != null && proven !== metadata.userId) {
|
|
29175
|
+
return { ownershipAssigned: false, rejectedReason: "OWNER_CHANGE_UNVERIFIED" };
|
|
29176
|
+
}
|
|
29137
29177
|
const existing = this.tabOwnership.get(tabId);
|
|
29138
29178
|
if (existing && existing.userId === metadata.userId) {
|
|
29139
29179
|
existing.sessionId = metadata.sessionId;
|
|
29140
29180
|
existing.lastSeen = now;
|
|
29141
|
-
return;
|
|
29181
|
+
return { ownershipAssigned: true };
|
|
29182
|
+
}
|
|
29183
|
+
if (existing) {
|
|
29184
|
+
if (proven == null) {
|
|
29185
|
+
return { ownershipAssigned: false, rejectedReason: "OWNER_CHANGE_UNVERIFIED" };
|
|
29186
|
+
}
|
|
29142
29187
|
}
|
|
29143
29188
|
this.tabOwnership.set(tabId, {
|
|
29144
29189
|
userId: metadata.userId,
|
|
@@ -29146,6 +29191,7 @@ var CommandRelay = class {
|
|
|
29146
29191
|
firstSeen: existing?.firstSeen ?? now,
|
|
29147
29192
|
lastSeen: now
|
|
29148
29193
|
});
|
|
29194
|
+
return { ownershipAssigned: true };
|
|
29149
29195
|
}
|
|
29150
29196
|
/**
|
|
29151
29197
|
* Return the stored ownership record for a tab, or `null` if the tab
|