Bind Reddit and Matrix session identities
This commit is contained in:
1 parent
34ae532cdd
commit
492efe0f8a
12 files changed
+234
-55
No files matched your search
+27
-10
@@ -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;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user