Skip to content

Commit 772be89

Browse files
committed
Split guest auth test harness
1 parent 5641248 commit 772be89

13 files changed

Lines changed: 1608 additions & 1476 deletions

File tree

apps/backend/src/guestAuth.testHarness.ts

Lines changed: 1 addition & 1476 deletions
Large diffs are not rendered by default.
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
import assert from "node:assert/strict";
2+
import type pg from "pg";
3+
import type { DatabaseExecutor } from "../db";
4+
import { handleAuthExecutorQuery } from "./handlers/auth";
5+
import { handleContentExecutorQuery } from "./handlers/content";
6+
import { handleSyncExecutorQuery } from "./handlers/sync";
7+
import { handleUserSettingsExecutorQuery } from "./handlers/userSettings";
8+
import { handleWorkspaceExecutorQuery } from "./handlers/workspaces";
9+
import {
10+
type GuestUpgradeExecutorParam,
11+
type GuestUpgradeHandlerContext,
12+
type MutableState,
13+
} from "./models";
14+
import { createQueryResult } from "./queryResult";
15+
16+
function handleExecutorScopeQuery<Row extends pg.QueryResultRow>(
17+
context: GuestUpgradeHandlerContext,
18+
text: string,
19+
params: ReadonlyArray<GuestUpgradeExecutorParam>,
20+
): pg.QueryResult<Row> | null {
21+
const { state } = context;
22+
23+
if (!text.includes("set_config('app.user_id'")) {
24+
return null;
25+
}
26+
27+
state.currentUserId = typeof params[0] === "string" ? params[0] : null;
28+
state.currentWorkspaceId = typeof params[1] === "string" && params[1] !== "" ? params[1] : null;
29+
return createQueryResult<Row>([]);
30+
}
31+
32+
export function createGuestUpgradeExecutor(state: MutableState): DatabaseExecutor {
33+
function requireCurrentUserScope(userId: string): void {
34+
assert.equal(
35+
state.currentUserId,
36+
userId,
37+
`Expected app.user_id scope ${userId}, got ${state.currentUserId ?? "null"}`,
38+
);
39+
}
40+
41+
function requireCurrentWorkspaceScope(userId: string, workspaceId: string): void {
42+
requireCurrentUserScope(userId);
43+
assert.equal(
44+
state.currentWorkspaceId,
45+
workspaceId,
46+
`Expected app.workspace_id scope ${workspaceId}, got ${state.currentWorkspaceId ?? "null"}`,
47+
);
48+
}
49+
50+
const context: GuestUpgradeHandlerContext = {
51+
state,
52+
scope: {
53+
requireCurrentUserScope,
54+
requireCurrentWorkspaceScope,
55+
},
56+
};
57+
58+
return {
59+
async query<Row extends pg.QueryResultRow>(
60+
text: string,
61+
params: ReadonlyArray<GuestUpgradeExecutorParam>,
62+
): Promise<pg.QueryResult<Row>> {
63+
const scopeResult = handleExecutorScopeQuery<Row>(context, text, params);
64+
if (scopeResult !== null) {
65+
return scopeResult;
66+
}
67+
68+
const authResult = handleAuthExecutorQuery<Row>(context, text, params);
69+
if (authResult !== null) {
70+
return authResult;
71+
}
72+
73+
const userSettingsResult = handleUserSettingsExecutorQuery<Row>(context, text, params);
74+
if (userSettingsResult !== null) {
75+
return userSettingsResult;
76+
}
77+
78+
const workspaceResult = handleWorkspaceExecutorQuery<Row>(context, text, params);
79+
if (workspaceResult !== null) {
80+
return workspaceResult;
81+
}
82+
83+
const syncResult = handleSyncExecutorQuery<Row>(context, text, params);
84+
if (syncResult !== null) {
85+
return syncResult;
86+
}
87+
88+
const contentResult = handleContentExecutorQuery<Row>(context, text, params);
89+
if (contentResult !== null) {
90+
return contentResult;
91+
}
92+
93+
throw new Error(`Unexpected query: ${text}`);
94+
},
95+
};
96+
}
97+
98+
export function isGuestUpgradeMergeOnlyExecutorQuery(text: string): boolean {
99+
return text.includes("FROM sync.claim_installation")
100+
|| (text.startsWith("SELECT") && text.includes("FROM sync.workspace_replicas"))
101+
|| text.includes("INSERT INTO sync.workspace_replicas")
102+
|| text.includes("UPDATE sync.workspace_replicas")
103+
|| text.includes("INSERT INTO auth.guest_upgrade_history")
104+
|| text.includes("INSERT INTO auth.guest_replica_aliases")
105+
|| text === "UPDATE auth.guest_sessions SET revoked_at = now() WHERE session_id = $1"
106+
|| text === "SELECT workspace_id FROM sync.find_conflicting_workspace_id($1, $2) LIMIT 1"
107+
|| text.includes("FROM sync.hot_changes")
108+
|| text.includes("INSERT INTO sync.hot_changes")
109+
|| text.startsWith("DELETE FROM content.")
110+
|| text.startsWith("INSERT INTO content.")
111+
|| text.startsWith("UPDATE content.")
112+
|| text.startsWith("DELETE FROM org.workspaces")
113+
|| text === "DELETE FROM org.user_settings WHERE user_id = $1"
114+
|| text
115+
=== "INSERT INTO org.workspaces ( workspace_id, name, fsrs_client_updated_at, fsrs_last_modified_by_replica_id, fsrs_last_operation_id ) VALUES ($1, $2, $3, $4, $5)"
116+
|| text === "INSERT INTO org.workspace_memberships (workspace_id, user_id, role) VALUES ($1, $2, 'owner')"
117+
|| text
118+
=== "INSERT INTO sync.workspace_sync_metadata (workspace_id, min_available_hot_change_id, updated_at) VALUES ($1, 0, now()) ON CONFLICT (workspace_id) DO NOTHING"
119+
|| text === "UPDATE org.user_settings SET workspace_id = $1 WHERE user_id = $2"
120+
|| text.startsWith("UPDATE org.workspaces SET");
121+
}

0 commit comments

Comments
 (0)