Bind Reddit and Matrix session identities

This commit is contained in:
jjbrunton committed 2026-08-08 19:43:35 +01:00
1 parent 34ae532cdd
commit 492efe0f8a
12 files changed
+234 -55

No files matched your search

+27 -10
View File
@@ -3,6 +3,18 @@ import type { Config } from '../config/index.js';
import type { Logger } from '../utils/logger.js';
import path from 'path';
import fs from 'fs';
import { z } from 'zod';
import type { RedditAccountIdentity } from '../services/account-auth-context.js';
const RedditAccountSchema = z.object({
name: z.string().trim().min(1),
id: z.string().trim().min(1),
}).passthrough();
const RedditIdentityResponseSchema = z.union([
RedditAccountSchema,
z.object({ data: RedditAccountSchema }).passthrough().transform(({ data }) => data),
]);
export interface BrowserRuntime {
launchPersistentContext(
@@ -112,6 +124,11 @@ export class BrowserClient {
/** Returns the account name from Reddit's authenticated identity endpoint. */
async getAuthenticatedUsername(): Promise<string | null> {
return (await this.getAuthenticatedIdentity())?.username ?? null;
}
/** Returns the username and stable t2 account ID for identity binding. */
async getAuthenticatedIdentity(): Promise<RedditAccountIdentity | null> {
try {
return await this.getRedditIdentity(await this.getPage());
} catch {
@@ -168,24 +185,24 @@ export class BrowserClient {
return (await this.getRedditIdentity(page)) !== null;
}
private async getRedditIdentity(page: Page): Promise<string | null> {
private async getRedditIdentity(page: Page): Promise<RedditAccountIdentity | null> {
try {
return await page.evaluate(async () => {
const payload: unknown = await page.evaluate(async () => {
try {
const res = await fetch('https://www.reddit.com/api/me.json', { credentials: 'include' });
if (!res.ok) return null;
const data: unknown = await res.json();
if (!data || typeof data !== 'object') return null;
const account = 'data' in data && data.data && typeof data.data === 'object'
? data.data
: data;
if (!('name' in account) || typeof account.name !== 'string') return null;
const username = account.name.trim();
return username || null;
return await res.json();
} catch {
return null;
}
});
const parsed = RedditIdentityResponseSchema.safeParse(payload);
if (!parsed.success) return null;
const rawAccountId = parsed.data.id;
return {
username: parsed.data.name,
accountId: rawAccountId.startsWith('t2_') ? rawAccountId : `t2_${rawAccountId}`,
};
} catch {
return null;
}