Merge remote-tracking branch 'origin/main'
# Conflicts: # src/browser/client.ts # src/services/reddit-session-importer.ts # src/web/routes/conversations.ts
This commit is contained in:
commit
48492d5238
30 files changed
+1041
-181
No files matched your search
@@ -2,12 +2,16 @@ import type { Cookie } from 'playwright';
|
||||
import type { MatrixClient } from './chat/matrix/client.js';
|
||||
import type { MatrixCredentials } from './chat/matrix/types.js';
|
||||
import type { AccountAuthContext } from './account-auth-context.js';
|
||||
import {
|
||||
assertMatchingAccountIdentity,
|
||||
normalizeRedditAccountId,
|
||||
type RedditAccountIdentity,
|
||||
} from './account-auth-context.js';
|
||||
|
||||
interface BrowserSessionTarget {
|
||||
importRedditCookies(cookies: Cookie[]): Promise<void>;
|
||||
isSessionValid(): Promise<boolean>;
|
||||
getAuthenticatedUsername(): Promise<string | null>;
|
||||
getAuthenticatedIdentity?(): Promise<{ username: string; accountId: string } | null>;
|
||||
getAuthenticatedIdentity(): Promise<RedditAccountIdentity | null>;
|
||||
}
|
||||
|
||||
interface ChatSessionTarget {
|
||||
@@ -28,11 +32,6 @@ export interface VerifiedRedditSessionStore {
|
||||
}): void;
|
||||
}
|
||||
|
||||
function matrixRedditAccountId(matrixUserId: string): string | null {
|
||||
const match = matrixUserId.match(/^@t2_([^:]+):reddit\.com$/i);
|
||||
return match?.[1]?.toLowerCase() ?? null;
|
||||
}
|
||||
|
||||
export class RedditSessionImporter {
|
||||
constructor(
|
||||
private readonly browser: BrowserSessionTarget,
|
||||
@@ -63,31 +62,37 @@ export class RedditSessionImporter {
|
||||
}
|
||||
|
||||
await this.browser.importRedditCookies(cookies);
|
||||
if (!(await this.browser.isSessionValid())) {
|
||||
throw new Error('Imported cookies did not authenticate with Reddit');
|
||||
}
|
||||
const identity = this.browser.getAuthenticatedIdentity
|
||||
? await this.browser.getAuthenticatedIdentity()
|
||||
: null;
|
||||
const redditUsername = identity?.username ?? await this.browser.getAuthenticatedUsername();
|
||||
if (!redditUsername) throw new Error('Reddit did not return an authenticated account identity');
|
||||
if (identity) {
|
||||
const matrixAccountId = matrixRedditAccountId(userId);
|
||||
if (!matrixAccountId || matrixAccountId !== identity.accountId.toLowerCase().replace(/^t2_/, '')) {
|
||||
throw new Error('Reddit cookies and Matrix credentials belong to different accounts');
|
||||
let redditIdentity: RedditAccountIdentity;
|
||||
try {
|
||||
if (!(await this.browser.isSessionValid())) {
|
||||
throw new Error('Imported cookies did not authenticate with Reddit');
|
||||
}
|
||||
const identity = await this.browser.getAuthenticatedIdentity();
|
||||
if (!identity) throw new Error('Reddit did not return an authenticated account identity');
|
||||
redditIdentity = identity;
|
||||
assertMatchingAccountIdentity({
|
||||
accountId: identity.accountId,
|
||||
redditUsername: identity.username,
|
||||
matrixUserId: userId,
|
||||
});
|
||||
} catch (error) {
|
||||
this.accountAuth.invalidate(error instanceof Error ? error.message : String(error));
|
||||
throw error;
|
||||
}
|
||||
|
||||
this.saveCredentials(credentials);
|
||||
this.chat.setMatrixClient(matrixClient);
|
||||
const account = {
|
||||
accountId: userId,
|
||||
redditUsername,
|
||||
redditUsername: redditIdentity.username,
|
||||
matrixUserId: userId,
|
||||
};
|
||||
this.accountAuth.markAuthenticated({
|
||||
accountId: normalizeRedditAccountId(redditIdentity.accountId),
|
||||
redditUsername: redditIdentity.username,
|
||||
matrixUserId: userId,
|
||||
});
|
||||
this.sessionStore?.save({ ...account, cookies, credentials });
|
||||
await this.chat.switchAccount?.(account.accountId);
|
||||
this.accountAuth.markAuthenticated(account);
|
||||
return account;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user