diff --git a/src/services/reddit-account-runtime-builder.ts b/src/services/reddit-account-runtime-builder.ts index 799d95b..b91da1e 100644 --- a/src/services/reddit-account-runtime-builder.ts +++ b/src/services/reddit-account-runtime-builder.ts @@ -17,7 +17,12 @@ import { MonitorService } from './monitor.js'; import { ProcessorService, isSkip } from './processor.js'; import { ResponseCheckerService } from './response-checker.js'; import { StrategySelector } from './strategy-selector.js'; -import { AccountAuthContext } from './account-auth-context.js'; +import { + AccountAuthContext, + normalizeRedditAccountId, + type AuthenticatedAccount, + type RedditAccountIdentity, +} from './account-auth-context.js'; import { ChatCache } from './chat/cache.js'; import { ChatService, MatrixClient, MatrixMediaDownloader, MatrixTokenRefresher, @@ -75,16 +80,12 @@ async function buildRuntime( } const accountAuth = new AccountAuthContext(logger); - accountAuth.markAuthenticated({ - accountId: session.accountId, - redditUsername: identity.username, - matrixUserId: session.matrixUserId, - }); + accountAuth.markAuthenticated(runtimeAuthenticatedAccount(session, identity)); accountAuth.setAuthenticator(async () => { const current = await browserClient.getAuthenticatedIdentity(); if (!current || matrixRedditId(session.matrixUserId) !== current.accountId.toLowerCase().replace(/^t2_/, '')) return null; return await matrixClient.whoami() === session.matrixUserId - ? { accountId: session.accountId, redditUsername: current.username, matrixUserId: session.matrixUserId } + ? runtimeAuthenticatedAccount(session, current) : null; }); @@ -153,6 +154,18 @@ async function buildRuntime( } } +/** Keeps the Reddit auth fullname separate from the Matrix-shaped runtime/database key. */ +export function runtimeAuthenticatedAccount( + session: Pick, + identity: RedditAccountIdentity, +): AuthenticatedAccount { + return { + accountId: normalizeRedditAccountId(identity.accountId), + redditUsername: identity.username, + matrixUserId: session.matrixUserId, + }; +} + class AccountRuntimeLoop { private controller: AbortController | null = null; private loop: Promise | null = null; diff --git a/tests/reddit-account-runtime.test.ts b/tests/reddit-account-runtime.test.ts index 48f1242..5e28e04 100644 --- a/tests/reddit-account-runtime.test.ts +++ b/tests/reddit-account-runtime.test.ts @@ -10,6 +10,7 @@ import { RedditAccountRuntimeManager, type RedditAccountRuntimeResources, } from '../src/services/reddit-account-runtime.js'; +import { runtimeAuthenticatedAccount } from '../src/services/reddit-account-runtime-builder.js'; function account( key: string, @@ -219,6 +220,17 @@ describe('RedditAccountRuntimeManager', () => { }); describe('account runtime isolation', () => { + it('uses the Reddit fullname for auth while retaining the Matrix runtime owner', () => { + expect(runtimeAuthenticatedAccount( + { matrixUserId: '@t2_1u57iqxxbv:reddit.com' }, + { username: 'Upset_Marsupial1006', accountId: 't2_1u57iqxxbv' }, + )).toEqual({ + accountId: 't2_1u57iqxxbv', + redditUsername: 'Upset_Marsupial1006', + matrixUserId: '@t2_1u57iqxxbv:reddit.com', + }); + }); + it('derives distinct deterministic browser profiles from account IDs', () => { const first = accountBrowserProfileDir('./data/browser', '@t2_first:reddit.com'); const second = accountBrowserProfileDir('./data/browser', '@t2_second:reddit.com');