From a72e99265d2b97b4a00bf6aab92ea2966f079427 Mon Sep 17 00:00:00 2001 From: Ian Calvert Date: Tue, 23 Dec 2025 20:53:26 +0000 Subject: [PATCH 1/5] Don't link to staging --- .../506ef767-d8be-4c19-afc8-f03318602cb5.json | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/packages/catalog-realm/SystemCard/506ef767-d8be-4c19-afc8-f03318602cb5.json b/packages/catalog-realm/SystemCard/506ef767-d8be-4c19-afc8-f03318602cb5.json index c7ffa956d1c..a6730819317 100644 --- a/packages/catalog-realm/SystemCard/506ef767-d8be-4c19-afc8-f03318602cb5.json +++ b/packages/catalog-realm/SystemCard/506ef767-d8be-4c19-afc8-f03318602cb5.json @@ -26,16 +26,6 @@ "self": "../RecommendedModel/37533a45-5b7a-4cfd-a169-a46976e155be" } }, - "modelConfigurations.1": { - "links": { - "self": "https://realms-staging.stack.cards/catalog/ModelConfiguration/anthropic-claude-haiku-45" - } - }, - "modelConfigurations.2": { - "links": { - "self": "https://realms-staging.stack.cards/ctse/personal/ModelConfiguration/08dfc745-4e5c-4be7-b1ba-a7ba56ebd4e3" - } - }, "defaultModelConfiguration": { "links": { "self": null @@ -43,4 +33,4 @@ } } } -} \ No newline at end of file +} From fd6228f5ecb7d9c0339bc2f1ba14096625a611b9 Mon Sep 17 00:00:00 2001 From: Ian Calvert Date: Tue, 23 Dec 2025 20:54:00 +0000 Subject: [PATCH 2/5] Simplify setup to require a single session room for all comms --- packages/host/app/services/matrix-service.ts | 13 +++--- packages/matrix/helpers/index.ts | 30 ------------- ...1000_add-realm-user-id-to-session-rooms.js | 9 ++++ .../handlers/handle-create-session.ts | 14 +++++-- .../handlers/handle-realm-auth.ts | 6 +++ packages/realm-server/main.ts | 8 ++-- packages/realm-server/node-realm.ts | 21 ++++++++-- packages/realm-server/server.ts | 33 ++------------- .../db-queries/session-room-queries.ts | 37 ++++++++++++---- packages/runtime-common/realm.ts | 42 +++++++++---------- 10 files changed, 109 insertions(+), 104 deletions(-) create mode 100644 packages/postgres/migrations/1766509131000_add-realm-user-id-to-session-rooms.js diff --git a/packages/host/app/services/matrix-service.ts b/packages/host/app/services/matrix-service.ts index d1cbaeb1122..d05ade6ddb7 100644 --- a/packages/host/app/services/matrix-service.ts +++ b/packages/host/app/services/matrix-service.ts @@ -1810,6 +1810,7 @@ export default class MatrixService extends Service { event.type === 'm.room.message' && event.content?.msgtype === APP_BOXEL_REALM_SERVER_EVENT_MSGTYPE ) { + console.log('Received realm server event', event); await this.realmServer.handleEvent(event); } else if ( event.type === APP_BOXEL_REALM_EVENT_TYPE && @@ -1831,14 +1832,16 @@ export default class MatrixService extends Service { let realmResourceForEvent = this.realm.realmForSessionRoomId( event.room_id!, ); + console.log('Trying to figure out realm for event', { + event, + realmResourceForEvent, + }); if (!realmResourceForEvent) { - realmEventsLogger.debug( - 'Ignoring realm event because no realm found', - event, - ); + console.log('Ignoring realm event because no realm found', event); } else { + // TODO: CHECK THAT THE SENDER IS THE REALM SERVER? if (realmResourceForEvent.info?.realmUserId !== event.sender) { - realmEventsLogger.warn( + console.log( `Realm event sender ${event.sender} is not the realm user ${realmResourceForEvent.info?.realmUserId}`, event, ); diff --git a/packages/matrix/helpers/index.ts b/packages/matrix/helpers/index.ts index 39a1eb22d7b..4e6edfa4e7c 100644 --- a/packages/matrix/helpers/index.ts +++ b/packages/matrix/helpers/index.ts @@ -120,36 +120,6 @@ export async function setRealmRedirects(page: Page) { } export async function registerRealmUsers(synapse: SynapseInstance) { - await registerUser( - synapse, - 'base_realm', - await realmPassword('base_realm', realmSecretSeed), - ); - await registerUser( - synapse, - 'experiments_realm', - await realmPassword('experiments_realm', realmSecretSeed), - ); - await registerUser( - synapse, - 'catalog_realm', - await realmPassword('catalog_realm', realmSecretSeed), - ); - await registerUser( - synapse, - 'skills_realm', - await realmPassword('skills_realm', realmSecretSeed), - ); - await registerUser( - synapse, - 'test_realm', - await realmPassword('test_realm', realmSecretSeed), - ); - await registerUser( - synapse, - 'node-test_realm', - await realmPassword('node-test_realm', realmSecretSeed), - ); await registerUser( synapse, 'realm_server', diff --git a/packages/postgres/migrations/1766509131000_add-realm-user-id-to-session-rooms.js b/packages/postgres/migrations/1766509131000_add-realm-user-id-to-session-rooms.js new file mode 100644 index 00000000000..f28057745f5 --- /dev/null +++ b/packages/postgres/migrations/1766509131000_add-realm-user-id-to-session-rooms.js @@ -0,0 +1,9 @@ +exports.up = (pgm) => { + pgm.addColumns('session_rooms', { + realm_user_id: { type: 'varchar' }, + }); +}; + +exports.down = (pgm) => { + pgm.dropColumns('session_rooms', ['realm_user_id']); +}; diff --git a/packages/realm-server/handlers/handle-create-session.ts b/packages/realm-server/handlers/handle-create-session.ts index 8bd1c49d879..b95efe051bd 100644 --- a/packages/realm-server/handlers/handle-create-session.ts +++ b/packages/realm-server/handlers/handle-create-session.ts @@ -1,7 +1,6 @@ import { fetchSessionRoom, logger, - REALM_SERVER_REALM, SupportedMimeType, upsertSessionRoom, } from '@cardstack/runtime-common'; @@ -42,17 +41,26 @@ export default function handleCreateSessionRequest({ createJWT: async (user: string, sessionRoom: string) => createJWT({ user, sessionRoom }, realmSecretSeed), ensureSessionRoom: async (userId: string) => { + const realmServerUserId = matrixClient.getUserId(); + if (!realmServerUserId) { + throw new Error( + 'Realm server Matrix user ID is not available, unable to create session room', + ); + } + console.log('Realm server user ID:', realmServerUserId); let sessionRoom = await fetchSessionRoom( dbAdapter, - REALM_SERVER_REALM, + realmServerUserId, userId, ); + console.log('Fetched session room from DB:', sessionRoom); if (!sessionRoom) { + console.log('No session room???', userId); sessionRoom = await matrixClient.createDM(userId); await upsertSessionRoom( dbAdapter, - REALM_SERVER_REALM, + realmServerUserId, userId, sessionRoom, ); diff --git a/packages/realm-server/handlers/handle-realm-auth.ts b/packages/realm-server/handlers/handle-realm-auth.ts index 1e70c1c3b18..0708d531202 100644 --- a/packages/realm-server/handlers/handle-realm-auth.ts +++ b/packages/realm-server/handlers/handle-realm-auth.ts @@ -50,6 +50,12 @@ export default function handleRealmAuth({ } try { + console.log( + 'Realm auth creating session for realm:', + realmUrl, + 'and user:', + matrixUserId, + ); let sessionRoom = await realm.ensureSessionRoom(matrixUserId); sessions[realmUrl] = createJWT( { diff --git a/packages/realm-server/main.ts b/packages/realm-server/main.ts index 843ce85d027..a299cdeaae8 100644 --- a/packages/realm-server/main.ts +++ b/packages/realm-server/main.ts @@ -228,11 +228,12 @@ const getIndexHTML = async () => { await waitForWorkerManager(workerManagerPort); } - let realmServerMatrixClient = new MatrixClient({ + let matrixClient = new MatrixClient({ matrixURL: new URL(MATRIX_URL), username: REALM_SERVER_MATRIX_USERNAME, seed: REALM_SECRET_SEED, }); + await matrixClient.login(); let prerenderer = createRemotePrerenderer(prerendererUrl); let createPrerenderAuth = buildCreatePrerenderAuth(REALM_SECRET_SEED); @@ -261,12 +262,11 @@ const getIndexHTML = async () => { { url, adapter: realmAdapter, - matrix: { url: new URL(matrixURL), username }, secretSeed: REALM_SECRET_SEED, virtualNetwork, dbAdapter, queue, - realmServerMatrixClient, + matrixClient, definitionLookup, }, { @@ -304,7 +304,7 @@ const getIndexHTML = async () => { let server = new RealmServer({ realms, virtualNetwork, - matrixClient: realmServerMatrixClient, + matrixClient, realmsRootPath, realmServerSecretSeed: REALM_SERVER_SECRET_SEED, realmSecretSeed: REALM_SECRET_SEED, diff --git a/packages/realm-server/node-realm.ts b/packages/realm-server/node-realm.ts index 329b35e268b..3e9ea5d712b 100644 --- a/packages/realm-server/node-realm.ts +++ b/packages/realm-server/node-realm.ts @@ -234,7 +234,7 @@ export class NodeAdapter implements RealmAdapter { dbAdapter: DBAdapter, ): Promise { realmEventsLog.debug('Broadcasting realm event', event); - + let realmUserId; if (dbAdapter.isClosed) { realmEventsLog.warn( `Database adapter is closed, skipping sending realm event`, @@ -243,12 +243,25 @@ export class NodeAdapter implements RealmAdapter { } try { await matrixClient.login(); + realmUserId = matrixClient.getUserId(); + if (!realmUserId) { + realmEventsLog.error( + 'Matrix client has no user ID after login, unable to broadcast realm event', + event, + ); + return; + } } catch (e) { realmEventsLog.error('Error logging into matrix. Skipping broadcast', e); return; } - let dmRooms = await this.waitForSessionRooms(dbAdapter, realmUrl); + let dmRooms = await this.waitForSessionRooms( + dbAdapter, + realmUrl, + realmUserId, + ); + console.log('Dm rooms for realm: ', realmUrl, dmRooms); realmEventsLog.debug('Sending to dm rooms', Object.values(dmRooms)); @@ -269,6 +282,7 @@ export class NodeAdapter implements RealmAdapter { private async waitForSessionRooms( dbAdapter: DBAdapter, realmUrl: string, + realmUserId: string, attempts = 3, delayMs = 50, ): Promise> { @@ -278,7 +292,7 @@ export class NodeAdapter implements RealmAdapter { let dmRooms: Record = {}; try { - dmRooms = await fetchAllSessionRooms(dbAdapter, realmUrl); + dmRooms = await fetchAllSessionRooms(dbAdapter, realmUrl, realmUserId); } catch (e) { realmEventsLog.error('Error getting account data', e); return {}; // bail immediately on errors instead of retrying @@ -296,6 +310,7 @@ export class NodeAdapter implements RealmAdapter { return await this.waitForSessionRooms( dbAdapter, realmUrl, + realmUserId, attempts - 1, delayMs, ); diff --git a/packages/realm-server/server.ts b/packages/realm-server/server.ts index b1ca890654c..bc409dab8df 100644 --- a/packages/realm-server/server.ts +++ b/packages/realm-server/server.ts @@ -33,7 +33,6 @@ import { fetchRequestFromContext, methodOverrideSupport, } from './middleware'; -import { registerUser } from './synapse'; import convertAcceptHeaderQueryParam from './middleware/convert-accept-header-qp'; import convertAuthHeaderQueryParam from './middleware/convert-auth-header-qp'; import { NodeAdapter } from './node-realm'; @@ -44,10 +43,7 @@ import { extractSupportedMimeType } from '@cardstack/runtime-common/router'; import { any, type Expression } from '@cardstack/runtime-common/expression'; import * as Sentry from '@sentry/node'; import type { MatrixClient } from '@cardstack/runtime-common/matrix-client'; -import { - passwordFromSeed, - getMatrixUsername, -} from '@cardstack/runtime-common/matrix-client'; +import { getMatrixUsername } from '@cardstack/runtime-common/matrix-client'; import { createRoutes } from './routes'; import { APP_BOXEL_REALM_SERVER_EVENT_MSGTYPE } from '@cardstack/runtime-common/matrix-constants'; import type { Prerenderer } from '@cardstack/runtime-common'; @@ -536,18 +532,7 @@ export class RealmServer { let realmPath = resolve(join(this.realmsRootPath, ownerUsername, endpoint)); ensureDirSync(realmPath); - let username = `realm/${ownerUsername}_${endpoint}`; - let { userId } = await registerUser({ - matrixURL: this.matrixClient.matrixURL, - displayname: username, - username, - password: await passwordFromSeed(username, this.realmSecretSeed), - registrationSecret: await this.getMatrixRegistrationSecret(), - }); - this.log.debug(`created realm bot user '${userId}' for new realm ${url}`); - await insertPermissions(this.dbAdapter, new URL(url), { - [userId]: DEFAULT_PERMISSIONS, [ownerUserId]: DEFAULT_PERMISSIONS, }); @@ -573,12 +558,10 @@ export class RealmServer { let realm = this.createAndMountRealm( realmPath, url, - username, undefined, undefined, userInitiatedPriority, ); - await realm.ensureSessionRoom(ownerUserId); return { realm, @@ -589,7 +572,6 @@ export class RealmServer { private createAndMountRealm = ( path: string, url: string, - username: string, copiedFromRealm?: URL, enableFileWatcher?: boolean, fromScratchIndexPriority?: number, @@ -616,11 +598,7 @@ export class RealmServer { virtualNetwork: this.virtualNetwork, dbAdapter: this.dbAdapter, queue: this.queue, - matrix: { - url: new URL(this.matrixClient.matrixURL), - username, - }, - realmServerMatrixClient: this.matrixClient, + matrixClient: this.matrixClient, definitionLookup: this.definitionLookup, }, Object.keys(realmOptions).length ? realmOptions : undefined, @@ -676,7 +654,6 @@ export class RealmServer { continue; } let adapter = new NodeAdapter(realmPath, this.enableFileWatcher); - let username = `realm/${owner}_${realmName}`; let realm = new Realm({ url, adapter, @@ -684,11 +661,7 @@ export class RealmServer { virtualNetwork: this.virtualNetwork, dbAdapter: this.dbAdapter, queue: this.queue, - matrix: { - url: this.matrixClient.matrixURL, - username, - }, - realmServerMatrixClient: this.matrixClient, + matrixClient: this.matrixClient, definitionLookup: this.definitionLookup, }); this.virtualNetwork.mount(realm.handle); diff --git a/packages/runtime-common/db-queries/session-room-queries.ts b/packages/runtime-common/db-queries/session-room-queries.ts index 17d9d23efe4..c92fd6211ab 100644 --- a/packages/runtime-common/db-queries/session-room-queries.ts +++ b/packages/runtime-common/db-queries/session-room-queries.ts @@ -8,12 +8,12 @@ export const REALM_SERVER_REALM = '__realm-server__'; */ export async function fetchSessionRoom( dbAdapter: DBAdapter, - realmURL: string, + realmUserId: string, matrixUserId: string, ) { let rows = await query(dbAdapter, [ - 'SELECT room_id FROM session_rooms WHERE realm_url =', - param(realmURL), + 'SELECT room_id FROM session_rooms WHERE realm_user_id =', + param(realmUserId), 'AND matrix_user_id =', param(matrixUserId), ]); @@ -31,14 +31,16 @@ export async function fetchSessionRoom( */ export async function upsertSessionRoom( dbAdapter: DBAdapter, - realmURL: string, + realmUserId: string, matrixUserId: string, roomId: string, ) { await query(dbAdapter, [ - 'INSERT INTO session_rooms (realm_url, matrix_user_id, room_id, created_at, updated_at)', + 'INSERT INTO session_rooms (realm_url, realm_user_id, matrix_user_id, room_id, created_at, updated_at)', 'VALUES (', - param(realmURL), + param(REALM_SERVER_REALM), + ',', + param(realmUserId), ',', param(matrixUserId), ',', @@ -52,6 +54,9 @@ export async function upsertSessionRoom( 'room_id =', param(roomId), ',', + 'realm_user_id =', + param(realmUserId), + ',', 'updated_at =', dbExpression({ pg: 'NOW()', sqlite: 'CURRENT_TIMESTAMP' }), ]); @@ -63,12 +68,30 @@ export async function upsertSessionRoom( export async function fetchAllSessionRooms( dbAdapter: DBAdapter, realmURL: string, + realmUserId: string, ) { + console.log( + 'Fetching all session rooms for realmURL:', + realmURL, + 'and realmUserId:', + realmUserId, + ); let rows = await query(dbAdapter, [ - 'SELECT matrix_user_id, room_id FROM session_rooms WHERE realm_url =', + 'SELECT sr.matrix_user_id, sr.room_id', + 'FROM session_rooms sr', + 'JOIN realm_user_permissions rup', + 'ON rup.username = sr.matrix_user_id', + 'WHERE rup.realm_url =', param(realmURL), + 'AND (rup.read = true OR rup.write = true)', + 'AND sr.realm_user_id =', + param(realmUserId), + 'AND sr.realm_url =', + param(REALM_SERVER_REALM), ]); + console.log('Fetched session rooms:', rows); + let result: Record = {}; for (let row of rows) { if (row.matrix_user_id && row.room_id) { diff --git a/packages/runtime-common/realm.ts b/packages/runtime-common/realm.ts index 9aadc58f49d..d9375b415d9 100644 --- a/packages/runtime-common/realm.ts +++ b/packages/runtime-common/realm.ts @@ -318,7 +318,6 @@ export type RequestContext = { realm: Realm; permissions: RealmPermissions }; export class Realm { #startedUp = new Deferred(); #matrixClient: MatrixClient; - #realmServerMatrixClient: MatrixClient; #realmIndexUpdater: RealmIndexUpdater; #realmIndexQueryEngine: RealmIndexQueryEngine; #adapter: RealmAdapter; @@ -332,7 +331,6 @@ export class Realm { #disableModuleCaching = false; #fullIndexOnStartup = false; #fromScratchIndexPriority = systemInitiatedPriority; - #realmServerMatrixUserId: string; #definitionLookup: DefinitionLookup; #copiedFromRealm: URL | undefined; #sourceCache = new AliasCache(); @@ -366,28 +364,25 @@ export class Realm { { url, adapter, - matrix, secretSeed, dbAdapter, queue, virtualNetwork, - realmServerMatrixClient, + matrixClient, definitionLookup, }: { url: string; adapter: RealmAdapter; - matrix: MatrixConfig; secretSeed: string; dbAdapter: DBAdapter; queue: QueuePublisher; virtualNetwork: VirtualNetwork; - realmServerMatrixClient: MatrixClient; + matrixClient: MatrixClient; definitionLookup: DefinitionLookup; }, opts?: Options, ) { this.paths = new RealmPaths(new URL(url)); - let { username, url: matrixURL } = matrix; this.#realmSecretSeed = secretSeed; this.#dbAdapter = dbAdapter; this.#adapter = adapter; @@ -395,16 +390,7 @@ export class Realm { this.#fullIndexOnStartup = opts?.fullIndexOnStartup ?? false; this.#fromScratchIndexPriority = opts?.fromScratchIndexPriority ?? systemInitiatedPriority; - this.#realmServerMatrixClient = realmServerMatrixClient; - this.#realmServerMatrixUserId = userIdFromUsername( - realmServerMatrixClient.username, - realmServerMatrixClient.matrixURL.href, - ); - this.#matrixClient = new MatrixClient({ - matrixURL, - username, - seed: secretSeed, - }); + this.#matrixClient = matrixClient; this.#disableModuleCaching = Boolean(opts?.disableModuleCaching); this.#copiedFromRealm = opts?.copiedFromRealm; let owner: string | undefined; @@ -434,7 +420,7 @@ export class Realm { // server so that we can assume user that owns this realm. refactor this // back to using the realm's own matrix client after running cards in // headless chrome lands. - new RealmAuthDataSource(this.#realmServerMatrixClient, () => _fetch), + new RealmAuthDataSource(this.#matrixClient, () => _fetch), ), ]); @@ -578,18 +564,25 @@ export class Realm { } async ensureSessionRoom(matrixUserId: string): Promise { + console.log('realm.ts - Ensuring session room for user:', matrixUserId); let sessionRoom = await fetchSessionRoom( this.#dbAdapter, - this.url, + this.#matrixClient.getUserId(), matrixUserId, ); + console.log('Fetched session room from DB:', sessionRoom); if (!sessionRoom) { + console.log('No session room, creating one for user:', matrixUserId); await this.#matrixClient.login(); + console.log( + 'Logged into matrix as realm server user', + this.#matrixClient.getUserId(), + ); sessionRoom = await this.#matrixClient.createDM(matrixUserId); await upsertSessionRoom( this.#dbAdapter, - this.url, + this.#matrixClient.getUserId(), matrixUserId, sessionRoom, ); @@ -1306,7 +1299,12 @@ export class Realm { ensureSessionRoom: async (userId: string) => this.ensureSessionRoom(userId), setSessionRoom: (userId: string, roomId: string) => - upsertSessionRoom(this.#dbAdapter, this.url, userId, roomId), + upsertSessionRoom( + this.#dbAdapter, + this.#matrixClient.getUserId(), + userId, + roomId, + ), } as Utils, ); @@ -3751,7 +3749,7 @@ export class Realm { private async createRequestContext(): Promise { let permissions = { - [this.#realmServerMatrixUserId]: ['assume-user'] as RealmAction[], + [this.#matrixClient.getUserId()]: ['assume-user'] as RealmAction[], ...(await fetchRealmPermissions(this.#dbAdapter, new URL(this.url))), }; return { From d920670c2cb2e4b10147333ef9613161eb6da879 Mon Sep 17 00:00:00 2001 From: Ian Calvert Date: Wed, 24 Dec 2025 00:46:40 +0000 Subject: [PATCH 3/5] Add realm url to indexing events --- packages/base/matrix-event.gts | 7 +++-- packages/host/app/services/matrix-service.ts | 31 ++++++------------- packages/host/app/services/message-service.ts | 6 +++- packages/host/tests/helpers/adapter.ts | 7 ++++- .../message-service-subscription-test.gts | 1 + packages/realm-server/node-realm.ts | 10 +++++- .../tests/card-source-endpoints-test.ts | 6 ++++ .../realm-server/tests/helpers/indexing.ts | 2 ++ .../tests/realm-endpoints-test.ts | 4 +++ 9 files changed, 47 insertions(+), 27 deletions(-) diff --git a/packages/base/matrix-event.gts b/packages/base/matrix-event.gts index 9f2b6cca49c..8961f0619ef 100644 --- a/packages/base/matrix-event.gts +++ b/packages/base/matrix-event.gts @@ -372,9 +372,12 @@ export interface RealmEvent extends BaseMatrixEvent { content: RealmEventContent; } -export type RealmEventContent = +export type RealmEventContent = ( | IndexRealmEventContent - | UpdateRealmEventContent; + | UpdateRealmEventContent +) & { + realmURL?: string; +}; export type IndexRealmEventContent = | IncrementalIndexEventContent diff --git a/packages/host/app/services/matrix-service.ts b/packages/host/app/services/matrix-service.ts index d05ade6ddb7..edbe9a1b260 100644 --- a/packages/host/app/services/matrix-service.ts +++ b/packages/host/app/services/matrix-service.ts @@ -1829,30 +1829,17 @@ export default class MatrixService extends Service { return; } - let realmResourceForEvent = this.realm.realmForSessionRoomId( - event.room_id!, - ); - console.log('Trying to figure out realm for event', { - event, - realmResourceForEvent, - }); - if (!realmResourceForEvent) { - console.log('Ignoring realm event because no realm found', event); - } else { - // TODO: CHECK THAT THE SENDER IS THE REALM SERVER? - if (realmResourceForEvent.info?.realmUserId !== event.sender) { - console.log( - `Realm event sender ${event.sender} is not the realm user ${realmResourceForEvent.info?.realmUserId}`, - event, - ); - } - - (event.content as any).origin_server_ts = event.origin_server_ts; - this.messageService.relayRealmEvent( - realmResourceForEvent.url, - event.content as RealmEventContent, + const content = event.content as RealmEventContent; + if (!content.realmURL) { + realmEventsLogger.debug( + 'Ignoring realm event because no realm URL was provided', + event, ); + return; } + + (content as any).origin_server_ts = event.origin_server_ts; + this.messageService.relayRealmEvent(content); } } diff --git a/packages/host/app/services/message-service.ts b/packages/host/app/services/message-service.ts index 52e41ae8e21..85c2df81683 100644 --- a/packages/host/app/services/message-service.ts +++ b/packages/host/app/services/message-service.ts @@ -44,7 +44,11 @@ export default class MessageService extends Service { } } - relayRealmEvent(realmURL: string, event: RealmEventContent) { + relayRealmEvent(event: RealmEventContent) { + const realmURL = event.realmURL; + if (!realmURL) { + return; + } this.listenerCallbacks.get(realmURL)?.forEach((cb) => { cb(event); }); diff --git a/packages/host/tests/helpers/adapter.ts b/packages/host/tests/helpers/adapter.ts index 43be7607f88..71cdaa91a18 100644 --- a/packages/host/tests/helpers/adapter.ts +++ b/packages/host/tests/helpers/adapter.ts @@ -127,8 +127,13 @@ export class TestRealmAdapter implements RealmAdapter { rid.replace('test-session-room-realm-', '').startsWith(realmUrl), ); + const eventWithRealmURL: RealmEventContent = { + ...event, + realmURL: realmUrl, + }; + for (let roomId of targetRoomIds) { - simulateRemoteMessage(roomId, realmMatrixUsername, event, { + simulateRemoteMessage(roomId, realmMatrixUsername, eventWithRealmURL, { type: APP_BOXEL_REALM_EVENT_TYPE, }); } diff --git a/packages/host/tests/integration/message-service-subscription-test.gts b/packages/host/tests/integration/message-service-subscription-test.gts index c5879533ff8..7d60c7783cf 100644 --- a/packages/host/tests/integration/message-service-subscription-test.gts +++ b/packages/host/tests/integration/message-service-subscription-test.gts @@ -107,6 +107,7 @@ module('Integration | message service subscription', function (hooks) { eventName: 'index', indexType: 'incremental-index-initiation', updatedFile: 'index.json', + realmURL: testRealmURL, }, }); diff --git a/packages/realm-server/node-realm.ts b/packages/realm-server/node-realm.ts index 3e9ea5d712b..868ad28429a 100644 --- a/packages/realm-server/node-realm.ts +++ b/packages/realm-server/node-realm.ts @@ -234,6 +234,10 @@ export class NodeAdapter implements RealmAdapter { dbAdapter: DBAdapter, ): Promise { realmEventsLog.debug('Broadcasting realm event', event); + const eventWithRealmURL: RealmEventContent = { + ...event, + realmURL: realmUrl, + }; let realmUserId; if (dbAdapter.isClosed) { realmEventsLog.warn( @@ -268,7 +272,11 @@ export class NodeAdapter implements RealmAdapter { for (let userId of Object.keys(dmRooms)) { let roomId = dmRooms[userId]; try { - await matrixClient.sendEvent(roomId, APP_BOXEL_REALM_EVENT_TYPE, event); + await matrixClient.sendEvent( + roomId, + APP_BOXEL_REALM_EVENT_TYPE, + eventWithRealmURL, + ); } catch (e) { realmEventsLog.error( `Unable to send event in room ${roomId} for user ${userId}`, diff --git a/packages/realm-server/tests/card-source-endpoints-test.ts b/packages/realm-server/tests/card-source-endpoints-test.ts index 7a8b62b4fcc..d8b67962a77 100644 --- a/packages/realm-server/tests/card-source-endpoints-test.ts +++ b/packages/realm-server/tests/card-source-endpoints-test.ts @@ -882,6 +882,7 @@ module(basename(__filename), function () { eventName: 'index', indexType: 'incremental-index-initiation', updatedFile: `${testRealmURL}test-card.gts`, + realmURL: testRealmURL, }, }, { @@ -891,6 +892,7 @@ module(basename(__filename), function () { indexType: 'incremental', invalidations: [`${testRealmURL}test-card.gts`], clientRequestId: null, + realmURL: testRealmURL, }, }, { @@ -899,6 +901,7 @@ module(basename(__filename), function () { eventName: 'index', indexType: 'incremental-index-initiation', updatedFile: `${testRealmURL}test-card.gts`, + realmURL: testRealmURL, }, }, { @@ -908,6 +911,7 @@ module(basename(__filename), function () { indexType: 'incremental', invalidations: [`${testRealmURL}test-card.gts`, id], clientRequestId: null, + realmURL: testRealmURL, }, }, { @@ -916,6 +920,7 @@ module(basename(__filename), function () { eventName: 'index', indexType: 'incremental-index-initiation', updatedFile: `${id}.json`, + realmURL: testRealmURL, }, }, { @@ -925,6 +930,7 @@ module(basename(__filename), function () { indexType: 'incremental', invalidations: [id], clientRequestId: null, + realmURL: testRealmURL, }, }, ]; diff --git a/packages/realm-server/tests/helpers/indexing.ts b/packages/realm-server/tests/helpers/indexing.ts index 5c8d5f36a3c..0445a452507 100644 --- a/packages/realm-server/tests/helpers/indexing.ts +++ b/packages/realm-server/tests/helpers/indexing.ts @@ -84,12 +84,14 @@ export async function expectIncrementalIndexEvent( eventName: 'index', indexType: 'incremental-index-initiation', updatedFile: targetUrl, + realmURL: realm, }); let expectedIncrementalContent: any = { eventName: 'index', indexType: 'incremental', invalidations: [invalidation], + realmURL: realm, }; let actualContent = { ...incrementalEventContent }; diff --git a/packages/realm-server/tests/realm-endpoints-test.ts b/packages/realm-server/tests/realm-endpoints-test.ts index 30c2a52bc6c..bb2da70171d 100644 --- a/packages/realm-server/tests/realm-endpoints-test.ts +++ b/packages/realm-server/tests/realm-endpoints-test.ts @@ -937,6 +937,7 @@ module(basename(__filename), function () { eventName: 'index', indexType: 'incremental-index-initiation', updatedFile: `${newCardId}.json`, + realmURL: testRealmHref, }); assert.deepEqual(incrementalEvent?.content, { @@ -944,6 +945,7 @@ module(basename(__filename), function () { indexType: 'incremental', invalidations: [newCardId], clientRequestId: null, + realmURL: testRealmHref, }); { @@ -1101,12 +1103,14 @@ module(basename(__filename), function () { eventName: 'index', indexType: 'incremental-index-initiation', updatedFile: `${testRealmHref}person-1.json`, + realmURL: testRealmHref, }); assert.deepEqual(incrementalEvent?.content, { eventName: 'index', indexType: 'incremental', invalidations: [`${testRealmHref}person-1`], + realmURL: testRealmHref, }); { From 7bc0935d60d16673fd06f14881f308975b4befad Mon Sep 17 00:00:00 2001 From: Ian Calvert Date: Tue, 27 Jan 2026 13:24:41 +0000 Subject: [PATCH 4/5] Remove username from publishing realm --- .../handlers/handle-publish-realm.ts | 21 +------------------ packages/realm-server/routes.ts | 1 - packages/realm-server/server.ts | 7 +------ 3 files changed, 2 insertions(+), 27 deletions(-) diff --git a/packages/realm-server/handlers/handle-publish-realm.ts b/packages/realm-server/handlers/handle-publish-realm.ts index 7e452568edd..c1dfe377f25 100644 --- a/packages/realm-server/handlers/handle-publish-realm.ts +++ b/packages/realm-server/handlers/handle-publish-realm.ts @@ -28,8 +28,6 @@ import { import { createJWT } from '../jwt'; import type { CreateRoutesArgs } from '../routes'; import type { RealmServerTokenClaim } from '../utils/jwt'; -import { registerUser } from '../synapse'; -import { passwordFromSeed } from '@cardstack/runtime-common/matrix-client'; const log = logger('handle-publish'); @@ -99,13 +97,11 @@ function rewriteHostHomeForPublishedRealm( export default function handlePublishRealm({ dbAdapter, - matrixClient, realmSecretSeed, serverURL, virtualNetwork, realms, realmsRootPath, - getMatrixRegistrationSecret, createAndMountRealm, domainsForPublishedRealms, }: CreateRoutesArgs): (ctxt: Koa.Context, next: Koa.Next) => Promise { @@ -246,7 +242,6 @@ export default function handlePublishRealm({ ); let userId; - let realmUsername; let publishedRealmData: PublishedRealmTable | undefined; if (existingPublishedRealm) { let results = (await query(dbAdapter, [ @@ -261,7 +256,6 @@ export default function handlePublishRealm({ | 'last_published_at' >[]; publishedRealmData = results[0]; - realmUsername = `realm/${PUBLISHED_DIRECTORY_NAME}_${publishedRealmData.id}`; let lastPublishedAt = Date.now().toString(); await query(dbAdapter, [ @@ -273,10 +267,9 @@ export default function handlePublishRealm({ publishedRealmData.last_published_at = lastPublishedAt; } else { let publishedRealmId = uuidv4(); - realmUsername = `realm/${PUBLISHED_DIRECTORY_NAME}_${publishedRealmId}`; let { valueExpressions, nameExpressions } = asExpressions({ id: publishedRealmId, - owner_username: realmUsername, + owner_username: 'NONE', source_realm_url: sourceRealmURL, published_realm_url: publishedRealmURL, last_published_at: Date.now().toString(), @@ -294,18 +287,7 @@ export default function handlePublishRealm({ | 'last_published_at' >[]; publishedRealmData = results[0]; - - let { userId: newUserId } = await registerUser({ - matrixURL: matrixClient.matrixURL, - displayname: realmUsername, - username: realmUsername, - password: await passwordFromSeed(realmUsername, realmSecretSeed), - registrationSecret: await getMatrixRegistrationSecret(), - }); - userId = newUserId; - await insertPermissions(dbAdapter, new URL(publishedRealmURL), { - [userId]: ['read', 'realm-owner'], [ownerUserId]: ['read', 'realm-owner'], '*': ['read'], }); @@ -350,7 +332,6 @@ export default function handlePublishRealm({ let realm = createAndMountRealm( publishedRealmPath, publishedRealmURL, - realmUsername, new URL(sourceRealmURL), false, ); diff --git a/packages/realm-server/routes.ts b/packages/realm-server/routes.ts index 4fc5962172f..6e4bdd449b6 100644 --- a/packages/realm-server/routes.ts +++ b/packages/realm-server/routes.ts @@ -59,7 +59,6 @@ export type CreateRoutesArgs = { createAndMountRealm: ( path: string, url: string, - username: string, copiedFromRealm?: URL, enableFileWatcher?: boolean, fromScratchIndexPriority?: number, diff --git a/packages/realm-server/server.ts b/packages/realm-server/server.ts index 9a7ae4bba74..cb004d2feb2 100644 --- a/packages/realm-server/server.ts +++ b/packages/realm-server/server.ts @@ -936,7 +936,6 @@ export class RealmServer { } let adapter = new NodeAdapter(realmPath, this.enableFileWatcher); - let username = publishedRealmRow.owner_username; let realm = new Realm({ url: publishedRealmUrl, @@ -945,11 +944,7 @@ export class RealmServer { virtualNetwork: this.virtualNetwork, dbAdapter: this.dbAdapter, queue: this.queue, - matrix: { - url: this.matrixClient.matrixURL, - username, - }, - realmServerMatrixClient: this.matrixClient, + matrixClient: this.matrixClient, realmServerURL: this.serverURL.href, definitionLookup: this.definitionLookup, cardSizeLimitBytes: this.cardSizeLimitBytes, From 7cd147b2c3d8bcfd66dfcf088b7ade694522c2bf Mon Sep 17 00:00:00 2001 From: Ian Calvert Date: Tue, 27 Jan 2026 14:52:32 +0000 Subject: [PATCH 5/5] Remove console logging --- packages/host/app/services/matrix-service.ts | 1 - packages/realm-server/handlers/handle-create-session.ts | 3 --- packages/realm-server/handlers/handle-realm-auth.ts | 6 ------ packages/realm-server/node-realm.ts | 1 - .../runtime-common/db-queries/session-room-queries.ts | 8 -------- packages/runtime-common/realm.ts | 7 ------- 6 files changed, 26 deletions(-) diff --git a/packages/host/app/services/matrix-service.ts b/packages/host/app/services/matrix-service.ts index 8fab7d5a2d4..93eaf840ae0 100644 --- a/packages/host/app/services/matrix-service.ts +++ b/packages/host/app/services/matrix-service.ts @@ -1828,7 +1828,6 @@ export default class MatrixService extends Service { event.type === 'm.room.message' && event.content?.msgtype === APP_BOXEL_REALM_SERVER_EVENT_MSGTYPE ) { - console.log('Received realm server event', event); await this.realmServer.handleEvent(event); } else if ( event.type === APP_BOXEL_REALM_EVENT_TYPE && diff --git a/packages/realm-server/handlers/handle-create-session.ts b/packages/realm-server/handlers/handle-create-session.ts index b95efe051bd..1fb6b147060 100644 --- a/packages/realm-server/handlers/handle-create-session.ts +++ b/packages/realm-server/handlers/handle-create-session.ts @@ -47,16 +47,13 @@ export default function handleCreateSessionRequest({ 'Realm server Matrix user ID is not available, unable to create session room', ); } - console.log('Realm server user ID:', realmServerUserId); let sessionRoom = await fetchSessionRoom( dbAdapter, realmServerUserId, userId, ); - console.log('Fetched session room from DB:', sessionRoom); if (!sessionRoom) { - console.log('No session room???', userId); sessionRoom = await matrixClient.createDM(userId); await upsertSessionRoom( dbAdapter, diff --git a/packages/realm-server/handlers/handle-realm-auth.ts b/packages/realm-server/handlers/handle-realm-auth.ts index 369199e9423..5b67734bbb0 100644 --- a/packages/realm-server/handlers/handle-realm-auth.ts +++ b/packages/realm-server/handlers/handle-realm-auth.ts @@ -51,12 +51,6 @@ export default function handleRealmAuth({ } try { - console.log( - 'Realm auth creating session for realm:', - realmUrl, - 'and user:', - matrixUserId, - ); let sessionRoom = await realm.ensureSessionRoom(matrixUserId); sessions[realmUrl] = createJWT( { diff --git a/packages/realm-server/node-realm.ts b/packages/realm-server/node-realm.ts index 6de2f6b2ec3..3196b893b3d 100644 --- a/packages/realm-server/node-realm.ts +++ b/packages/realm-server/node-realm.ts @@ -269,7 +269,6 @@ export class NodeAdapter implements RealmAdapter { realmUrl, realmUserId, ); - console.log('Dm rooms for realm: ', realmUrl, dmRooms); realmEventsLog.debug('Sending to dm rooms', Object.values(dmRooms)); diff --git a/packages/runtime-common/db-queries/session-room-queries.ts b/packages/runtime-common/db-queries/session-room-queries.ts index c92fd6211ab..b49fc644a9b 100644 --- a/packages/runtime-common/db-queries/session-room-queries.ts +++ b/packages/runtime-common/db-queries/session-room-queries.ts @@ -70,12 +70,6 @@ export async function fetchAllSessionRooms( realmURL: string, realmUserId: string, ) { - console.log( - 'Fetching all session rooms for realmURL:', - realmURL, - 'and realmUserId:', - realmUserId, - ); let rows = await query(dbAdapter, [ 'SELECT sr.matrix_user_id, sr.room_id', 'FROM session_rooms sr', @@ -90,8 +84,6 @@ export async function fetchAllSessionRooms( param(REALM_SERVER_REALM), ]); - console.log('Fetched session rooms:', rows); - let result: Record = {}; for (let row of rows) { if (row.matrix_user_id && row.room_id) { diff --git a/packages/runtime-common/realm.ts b/packages/runtime-common/realm.ts index 5c9792a29eb..664ee9223b1 100644 --- a/packages/runtime-common/realm.ts +++ b/packages/runtime-common/realm.ts @@ -671,21 +671,14 @@ export class Realm { } async ensureSessionRoom(matrixUserId: string): Promise { - console.log('realm.ts - Ensuring session room for user:', matrixUserId); let sessionRoom = await fetchSessionRoom( this.#dbAdapter, this.#matrixClient.getUserId(), matrixUserId, ); - console.log('Fetched session room from DB:', sessionRoom); if (!sessionRoom) { - console.log('No session room, creating one for user:', matrixUserId); await this.#matrixClient.login(); - console.log( - 'Logged into matrix as realm server user', - this.#matrixClient.getUserId(), - ); sessionRoom = await this.#matrixClient.createDM(matrixUserId); await upsertSessionRoom( this.#dbAdapter,