@volter/teams 0.1.51 → 0.1.52

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/machine-core.mjs CHANGED
@@ -244,7 +244,7 @@ export class MachineCore extends EventEmitter {
244
244
  }
245
245
  const index = this.nextConnection++;
246
246
  // A delegated caller's claim also carries the name its workplace signed for it (who typed a turn).
247
- const entry = { channel, admitted, principal: claim.principal, name: typeof claim.name === 'string' ? claim.name : null, verify: () => this.#admitClaim(claim), localAdmission: () => admitFromGrants(claim, { custodianId: this.custodianId, grants: this.linkGrants }) };
247
+ const entry = { channel, admitted, principal: claim.principal, name: typeof claim.name === 'string' ? claim.name : null, roomContext: claim.roomContext ?? null, verify: () => this.#admitClaim(claim), localAdmission: () => admitFromGrants(claim, { custodianId: this.custodianId, grants: this.linkGrants }) };
248
248
  this.connections.set(index, entry);
249
249
  stream.on('close', () => { this.connections.delete(index); this.connectionClosed(index); });
250
250
  this.log.append({ principal: entry.principal, cap: 'connect', target: '*', outcome: admitted.class, detail: 'server' });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volter/teams",
3
- "version": "0.1.51",
3
+ "version": "0.1.52",
4
4
  "type": "module",
5
5
  "description": "Volter Teams, the neutral team plane: machine identity and daemon core, the local door and server link, admission from machine grants, product doors, and the Teams server's neutral routes (company RFC 0008).",
6
6
  "license": "MIT",
@@ -102,7 +102,8 @@ export async function delegatedSessionOf(api, token) {
102
102
  // The member's name as the workplace knows it: who the session is told typed a turn. From the signed token, never
103
103
  // from what the browser sends.
104
104
  const name = typeof claims.name === 'string' && claims.name.trim() ? claims.name.trim().slice(0, 80) : null;
105
- return { conversation: claims.conversation, expiresAt: claims.exp * 1000, issuer: claims.iss, name, room: claims.room, scope: claims.scope, sessionRef: session.id, subject: claims.sub, teamId: session.team };
105
+ const roomContext = claims.roomContext === false ? null : { id: claims.room, name: typeof claims.roomName === 'string' ? claims.roomName.slice(0, 120) : claims.room, sender: claims.sub };
106
+ return { roomContext, conversation: claims.conversation, expiresAt: claims.exp * 1000, issuer: claims.iss, name, room: claims.room, scope: claims.scope, sessionRef: session.id, subject: claims.sub, teamId: session.team };
106
107
  }
107
108
 
108
109
  /** A token's claims when it is one this server trusts: signed by the issuer's key, for this server, in its lifetime. */
@@ -56,7 +56,7 @@ export async function machineGrantRows(api, teamId, machineId) {
56
56
  async function claimFor(api, auth, machineId) {
57
57
  if (auth.kind === 'delegated') {
58
58
  const row = await api.store.one('SELECT id, revision FROM machine_grants WHERE team_id=? AND machine_id=? AND id=? AND expires_at>?', [auth.team_id, machineId, auth.grant_id, api.clock.nowMs()]);
59
- return row ? { principal: auth.principal_id, groups: [], grants: [row.id], revisions: { [row.id]: row.revision }, ...(auth.name ? { name: auth.name } : {}) } : null;
59
+ return row ? { principal: auth.principal_id, groups: [], grants: [row.id], revisions: { [row.id]: row.revision }, ...(auth.name ? { name: auth.name } : {}), ...(auth.roomContext ? { roomContext: auth.roomContext } : {}) } : null;
60
60
  }
61
61
  const machine = await api.store.one('SELECT custodian_id FROM machines WHERE team_id=? AND id=? AND revoked_at IS NULL', [auth.team_id, machineId]);
62
62
  if (!machine) return null;
@@ -231,7 +231,7 @@ async function delegatedSessionChannel(api, teamId, sessionRef, token) {
231
231
  { sql: "DELETE FROM machine_grants WHERE team_id=? AND issuer_id LIKE 'delegated:%' AND expires_at<=?", params: [teamId, now] },
232
232
  { sql: 'INSERT INTO machine_grants(team_id,id,machine_id,subject_id,caps_json,targets_json,issuer_id,created_at,expires_at) VALUES (?,?,?,?,?,?,?,?,?)', params: [teamId, id, target.machineId, principal, JSON.stringify(access.scope === 'control' ? ['observe', 'interact'] : ['observe']), JSON.stringify([`session:${target.harness}/${target.nativeId}`]), issuer, now, access.expiresAt] },
233
233
  ]).catch((error) => { if (error.code !== 'not_found') throw error; return null; });
234
- return { door: 'channel', teamId, machineId: target.machineId, auth: { kind: 'delegated', team_id: teamId, principal_id: principal, group_ids: [], grant_id: id, grant_issuer: issuer, expires_at: access.expiresAt, name: access.name } };
234
+ return { door: 'channel', teamId, machineId: target.machineId, auth: { kind: 'delegated', team_id: teamId, principal_id: principal, group_ids: [], grant_id: id, grant_issuer: issuer, expires_at: access.expiresAt, name: access.name, roomContext: access.roomContext } };
235
235
  }
236
236
 
237
237
  /**