@paperclipai/server 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/codex-models.d.ts +4 -0
- package/dist/adapters/codex-models.d.ts.map +1 -0
- package/dist/adapters/codex-models.js +98 -0
- package/dist/adapters/codex-models.js.map +1 -0
- package/dist/adapters/http/execute.d.ts +3 -0
- package/dist/adapters/http/execute.d.ts.map +1 -0
- package/dist/adapters/http/execute.js +39 -0
- package/dist/adapters/http/execute.js.map +1 -0
- package/dist/adapters/http/index.d.ts +3 -0
- package/dist/adapters/http/index.d.ts.map +1 -0
- package/dist/adapters/http/index.js +20 -0
- package/dist/adapters/http/index.js.map +1 -0
- package/dist/adapters/http/test.d.ts +3 -0
- package/dist/adapters/http/test.d.ts.map +1 -0
- package/dist/adapters/http/test.js +106 -0
- package/dist/adapters/http/test.js.map +1 -0
- package/dist/adapters/index.d.ts +4 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +3 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/process/execute.d.ts +3 -0
- package/dist/adapters/process/execute.d.ts.map +1 -0
- package/dist/adapters/process/execute.js +63 -0
- package/dist/adapters/process/execute.js.map +1 -0
- package/dist/adapters/process/index.d.ts +3 -0
- package/dist/adapters/process/index.d.ts.map +1 -0
- package/dist/adapters/process/index.js +23 -0
- package/dist/adapters/process/index.js.map +1 -0
- package/dist/adapters/process/test.d.ts +3 -0
- package/dist/adapters/process/test.d.ts.map +1 -0
- package/dist/adapters/process/test.js +77 -0
- package/dist/adapters/process/test.js.map +1 -0
- package/dist/adapters/registry.d.ts +9 -0
- package/dist/adapters/registry.d.ts.map +1 -0
- package/dist/adapters/registry.js +63 -0
- package/dist/adapters/registry.js.map +1 -0
- package/dist/adapters/types.d.ts +2 -0
- package/dist/adapters/types.d.ts.map +1 -0
- package/dist/adapters/types.js +2 -0
- package/dist/adapters/types.js.map +1 -0
- package/dist/adapters/utils.d.ts +10 -0
- package/dist/adapters/utils.d.ts.map +1 -0
- package/dist/adapters/utils.js +14 -0
- package/dist/adapters/utils.js.map +1 -0
- package/dist/agent-auth-jwt.d.ts +14 -0
- package/dist/agent-auth-jwt.d.ts.map +1 -0
- package/dist/agent-auth-jwt.js +117 -0
- package/dist/agent-auth-jwt.js.map +1 -0
- package/dist/app.d.ts +20 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +127 -0
- package/dist/app.js.map +1 -0
- package/dist/auth/better-auth.d.ts +23 -0
- package/dist/auth/better-auth.d.ts.map +1 -0
- package/dist/auth/better-auth.js +80 -0
- package/dist/auth/better-auth.js.map +1 -0
- package/dist/board-claim.d.ts +23 -0
- package/dist/board-claim.d.ts.map +1 -0
- package/dist/board-claim.js +115 -0
- package/dist/board-claim.js.map +1 -0
- package/dist/config-file.d.ts +3 -0
- package/dist/config-file.d.ts.map +1 -0
- package/dist/config-file.js +16 -0
- package/dist/config-file.js.map +1 -0
- package/dist/config.d.ts +33 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +114 -0
- package/dist/config.js.map +1 -0
- package/dist/errors.d.ts +12 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +28 -0
- package/dist/errors.js.map +1 -0
- package/dist/home-paths.d.ts +11 -0
- package/dist/home-paths.d.ts.map +1 -0
- package/dist/home-paths.js +54 -0
- package/dist/home-paths.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +439 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware/auth.d.ts +12 -0
- package/dist/middleware/auth.d.ts.map +1 -0
- package/dist/middleware/auth.js +124 -0
- package/dist/middleware/auth.js.map +1 -0
- package/dist/middleware/board-mutation-guard.d.ts +3 -0
- package/dist/middleware/board-mutation-guard.d.ts.map +1 -0
- package/dist/middleware/board-mutation-guard.js +60 -0
- package/dist/middleware/board-mutation-guard.js.map +1 -0
- package/dist/middleware/error-handler.d.ts +3 -0
- package/dist/middleware/error-handler.d.ts.map +1 -0
- package/dist/middleware/error-handler.js +22 -0
- package/dist/middleware/error-handler.js.map +1 -0
- package/dist/middleware/index.d.ts +4 -0
- package/dist/middleware/index.d.ts.map +1 -0
- package/dist/middleware/index.js +4 -0
- package/dist/middleware/index.js.map +1 -0
- package/dist/middleware/logger.d.ts +4 -0
- package/dist/middleware/logger.d.ts.map +1 -0
- package/dist/middleware/logger.js +37 -0
- package/dist/middleware/logger.js.map +1 -0
- package/dist/middleware/private-hostname-guard.d.ts +11 -0
- package/dist/middleware/private-hostname-guard.d.ts.map +1 -0
- package/dist/middleware/private-hostname-guard.js +78 -0
- package/dist/middleware/private-hostname-guard.js.map +1 -0
- package/dist/middleware/validate.d.ts +4 -0
- package/dist/middleware/validate.d.ts.map +1 -0
- package/dist/middleware/validate.js +7 -0
- package/dist/middleware/validate.js.map +1 -0
- package/dist/paths.d.ts +3 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +31 -0
- package/dist/paths.js.map +1 -0
- package/dist/realtime/live-events-ws.d.ts +10 -0
- package/dist/realtime/live-events-ws.d.ts.map +1 -0
- package/dist/realtime/live-events-ws.js +185 -0
- package/dist/realtime/live-events-ws.js.map +1 -0
- package/dist/redaction.d.ts +4 -0
- package/dist/redaction.d.ts.map +1 -0
- package/dist/redaction.js +63 -0
- package/dist/redaction.js.map +1 -0
- package/dist/routes/access.d.ts +9 -0
- package/dist/routes/access.d.ts.map +1 -0
- package/dist/routes/access.js +887 -0
- package/dist/routes/access.js.map +1 -0
- package/dist/routes/activity.d.ts +3 -0
- package/dist/routes/activity.d.ts.map +1 -0
- package/dist/routes/activity.js +87 -0
- package/dist/routes/activity.js.map +1 -0
- package/dist/routes/agents.d.ts +3 -0
- package/dist/routes/agents.d.ts.map +1 -0
- package/dist/routes/agents.js +1132 -0
- package/dist/routes/agents.js.map +1 -0
- package/dist/routes/approvals.d.ts +3 -0
- package/dist/routes/approvals.d.ts.map +1 -0
- package/dist/routes/approvals.js +271 -0
- package/dist/routes/approvals.js.map +1 -0
- package/dist/routes/assets.d.ts +4 -0
- package/dist/routes/assets.d.ts.map +1 -0
- package/dist/routes/assets.js +138 -0
- package/dist/routes/assets.js.map +1 -0
- package/dist/routes/authz.d.ts +15 -0
- package/dist/routes/authz.d.ts.map +1 -0
- package/dist/routes/authz.js +40 -0
- package/dist/routes/authz.js.map +1 -0
- package/dist/routes/companies.d.ts +3 -0
- package/dist/routes/companies.d.ts.map +1 -0
- package/dist/routes/companies.js +159 -0
- package/dist/routes/companies.js.map +1 -0
- package/dist/routes/costs.d.ts +3 -0
- package/dist/routes/costs.d.ts.map +1 -0
- package/dist/routes/costs.js +113 -0
- package/dist/routes/costs.js.map +1 -0
- package/dist/routes/dashboard.d.ts +3 -0
- package/dist/routes/dashboard.d.ts.map +1 -0
- package/dist/routes/dashboard.js +15 -0
- package/dist/routes/dashboard.js.map +1 -0
- package/dist/routes/goals.d.ts +3 -0
- package/dist/routes/goals.d.ts.map +1 -0
- package/dist/routes/goals.js +95 -0
- package/dist/routes/goals.js.map +1 -0
- package/dist/routes/health.d.ts +9 -0
- package/dist/routes/health.d.ts.map +1 -0
- package/dist/routes/health.js +38 -0
- package/dist/routes/health.js.map +1 -0
- package/dist/routes/index.d.ts +15 -0
- package/dist/routes/index.d.ts.map +1 -0
- package/dist/routes/index.js +15 -0
- package/dist/routes/index.js.map +1 -0
- package/dist/routes/issues.d.ts +4 -0
- package/dist/routes/issues.d.ts.map +1 -0
- package/dist/routes/issues.js +973 -0
- package/dist/routes/issues.js.map +1 -0
- package/dist/routes/llms.d.ts +3 -0
- package/dist/routes/llms.d.ts.map +1 -0
- package/dist/routes/llms.js +78 -0
- package/dist/routes/llms.js.map +1 -0
- package/dist/routes/projects.d.ts +3 -0
- package/dist/routes/projects.d.ts.map +1 -0
- package/dist/routes/projects.js +253 -0
- package/dist/routes/projects.js.map +1 -0
- package/dist/routes/secrets.d.ts +3 -0
- package/dist/routes/secrets.d.ts.map +1 -0
- package/dist/routes/secrets.js +128 -0
- package/dist/routes/secrets.js.map +1 -0
- package/dist/routes/sidebar-badges.d.ts +3 -0
- package/dist/routes/sidebar-badges.d.ts.map +1 -0
- package/dist/routes/sidebar-badges.js +47 -0
- package/dist/routes/sidebar-badges.js.map +1 -0
- package/dist/secrets/external-stub-providers.d.ts +5 -0
- package/dist/secrets/external-stub-providers.d.ts.map +1 -0
- package/dist/secrets/external-stub-providers.js +21 -0
- package/dist/secrets/external-stub-providers.js.map +1 -0
- package/dist/secrets/local-encrypted-provider.d.ts +3 -0
- package/dist/secrets/local-encrypted-provider.d.ts.map +1 -0
- package/dist/secrets/local-encrypted-provider.js +116 -0
- package/dist/secrets/local-encrypted-provider.js.map +1 -0
- package/dist/secrets/provider-registry.d.ts +5 -0
- package/dist/secrets/provider-registry.d.ts.map +1 -0
- package/dist/secrets/provider-registry.js +20 -0
- package/dist/secrets/provider-registry.js.map +1 -0
- package/dist/secrets/types.d.ts +21 -0
- package/dist/secrets/types.d.ts.map +1 -0
- package/dist/secrets/types.js +2 -0
- package/dist/secrets/types.js.map +1 -0
- package/dist/services/access.d.ts +81 -0
- package/dist/services/access.d.ts.map +1 -0
- package/dist/services/access.js +187 -0
- package/dist/services/access.js.map +1 -0
- package/dist/services/activity-log.d.ts +14 -0
- package/dist/services/activity-log.d.ts.map +1 -0
- package/dist/services/activity-log.js +32 -0
- package/dist/services/activity-log.js.map +1 -0
- package/dist/services/activity.d.ts +764 -0
- package/dist/services/activity.d.ts.map +1 -0
- package/dist/services/activity.js +105 -0
- package/dist/services/activity.js.map +1 -0
- package/dist/services/agent-permissions.d.ts +6 -0
- package/dist/services/agent-permissions.d.ts.map +1 -0
- package/dist/services/agent-permissions.js +18 -0
- package/dist/services/agent-permissions.js.map +1 -0
- package/dist/services/agents.d.ts +1494 -0
- package/dist/services/agents.d.ts.map +1 -0
- package/dist/services/agents.js +454 -0
- package/dist/services/agents.js.map +1 -0
- package/dist/services/approvals.d.ts +540 -0
- package/dist/services/approvals.d.ts.map +1 -0
- package/dist/services/approvals.js +173 -0
- package/dist/services/approvals.js.map +1 -0
- package/dist/services/assets.d.ts +33 -0
- package/dist/services/assets.d.ts.map +1 -0
- package/dist/services/assets.js +17 -0
- package/dist/services/assets.js.map +1 -0
- package/dist/services/companies.d.ts +503 -0
- package/dist/services/companies.d.ts.map +1 -0
- package/dist/services/companies.js +120 -0
- package/dist/services/companies.js.map +1 -0
- package/dist/services/company-portability.d.ts +8 -0
- package/dist/services/company-portability.d.ts.map +1 -0
- package/dist/services/company-portability.js +851 -0
- package/dist/services/company-portability.js.map +1 -0
- package/dist/services/costs.d.ts +50 -0
- package/dist/services/costs.d.ts.map +1 -0
- package/dist/services/costs.js +166 -0
- package/dist/services/costs.js.map +1 -0
- package/dist/services/dashboard.d.ts +21 -0
- package/dist/services/dashboard.d.ts.map +1 -0
- package/dist/services/dashboard.js +96 -0
- package/dist/services/dashboard.js.map +1 -0
- package/dist/services/goals.d.ts +407 -0
- package/dist/services/goals.d.ts.map +1 -0
- package/dist/services/goals.js +29 -0
- package/dist/services/goals.js.map +1 -0
- package/dist/services/heartbeat.d.ts +1666 -0
- package/dist/services/heartbeat.d.ts.map +1 -0
- package/dist/services/heartbeat.js +1752 -0
- package/dist/services/heartbeat.js.map +1 -0
- package/dist/services/index.d.ts +20 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +20 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/issue-approvals.d.ts +56 -0
- package/dist/services/issue-approvals.d.ts.map +1 -0
- package/dist/services/issue-approvals.js +153 -0
- package/dist/services/issue-approvals.js.map +1 -0
- package/dist/services/issues.d.ts +756 -0
- package/dist/services/issues.d.ts.map +1 -0
- package/dist/services/issues.js +917 -0
- package/dist/services/issues.js.map +1 -0
- package/dist/services/live-events.d.ts +12 -0
- package/dist/services/live-events.d.ts.map +1 -0
- package/dist/services/live-events.js +24 -0
- package/dist/services/live-events.js.map +1 -0
- package/dist/services/projects.d.ts +66 -0
- package/dist/services/projects.d.ts.map +1 -0
- package/dist/services/projects.js +472 -0
- package/dist/services/projects.js.map +1 -0
- package/dist/services/run-log-store.d.ts +34 -0
- package/dist/services/run-log-store.d.ts.map +1 -0
- package/dist/services/run-log-store.js +112 -0
- package/dist/services/run-log-store.js.map +1 -0
- package/dist/services/secrets.d.ts +506 -0
- package/dist/services/secrets.d.ts.map +1 -0
- package/dist/services/secrets.js +284 -0
- package/dist/services/secrets.js.map +1 -0
- package/dist/services/sidebar-badges.d.ts +9 -0
- package/dist/services/sidebar-badges.d.ts.map +1 -0
- package/dist/services/sidebar-badges.js +33 -0
- package/dist/services/sidebar-badges.js.map +1 -0
- package/dist/startup-banner.d.ts +27 -0
- package/dist/startup-banner.d.ts.map +1 -0
- package/dist/startup-banner.js +112 -0
- package/dist/startup-banner.js.map +1 -0
- package/dist/storage/index.d.ts +6 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +29 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/local-disk-provider.d.ts +3 -0
- package/dist/storage/local-disk-provider.d.ts.map +1 -0
- package/dist/storage/local-disk-provider.js +79 -0
- package/dist/storage/local-disk-provider.js.map +1 -0
- package/dist/storage/provider-registry.d.ts +4 -0
- package/dist/storage/provider-registry.d.ts.map +1 -0
- package/dist/storage/provider-registry.js +15 -0
- package/dist/storage/provider-registry.js.map +1 -0
- package/dist/storage/s3-provider.d.ts +11 -0
- package/dist/storage/s3-provider.d.ts.map +1 -0
- package/dist/storage/s3-provider.js +123 -0
- package/dist/storage/s3-provider.js.map +1 -0
- package/dist/storage/service.d.ts +3 -0
- package/dist/storage/service.d.ts.map +1 -0
- package/dist/storage/service.js +120 -0
- package/dist/storage/service.js.map +1 -0
- package/dist/storage/types.d.ts +55 -0
- package/dist/storage/types.d.ts.map +1 -0
- package/dist/storage/types.js +2 -0
- package/dist/storage/types.js.map +1 -0
- package/package.json +62 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
/// <reference path="./types/express.d.ts" />
|
|
2
|
+
import { existsSync, readFileSync, rmSync } from "node:fs";
|
|
3
|
+
import { createServer } from "node:http";
|
|
4
|
+
import { resolve } from "node:path";
|
|
5
|
+
import { createInterface } from "node:readline/promises";
|
|
6
|
+
import { stdin, stdout } from "node:process";
|
|
7
|
+
import { and, eq } from "drizzle-orm";
|
|
8
|
+
import { createDb, ensurePostgresDatabase, inspectMigrations, applyPendingMigrations, reconcilePendingMigrationHistory, authUsers, companies, companyMemberships, instanceUserRoles, } from "@paperclipai/db";
|
|
9
|
+
import detectPort from "detect-port";
|
|
10
|
+
import { createApp } from "./app.js";
|
|
11
|
+
import { loadConfig } from "./config.js";
|
|
12
|
+
import { logger } from "./middleware/logger.js";
|
|
13
|
+
import { setupLiveEventsWebSocketServer } from "./realtime/live-events-ws.js";
|
|
14
|
+
import { heartbeatService } from "./services/index.js";
|
|
15
|
+
import { createStorageServiceFromConfig } from "./storage/index.js";
|
|
16
|
+
import { printStartupBanner } from "./startup-banner.js";
|
|
17
|
+
import { getBoardClaimWarningUrl, initializeBoardClaimChallenge } from "./board-claim.js";
|
|
18
|
+
import { createBetterAuthHandler, createBetterAuthInstance, resolveBetterAuthSession, resolveBetterAuthSessionFromHeaders, } from "./auth/better-auth.js";
|
|
19
|
+
const config = loadConfig();
|
|
20
|
+
if (process.env.PAPERCLIP_SECRETS_PROVIDER === undefined) {
|
|
21
|
+
process.env.PAPERCLIP_SECRETS_PROVIDER = config.secretsProvider;
|
|
22
|
+
}
|
|
23
|
+
if (process.env.PAPERCLIP_SECRETS_STRICT_MODE === undefined) {
|
|
24
|
+
process.env.PAPERCLIP_SECRETS_STRICT_MODE = config.secretsStrictMode ? "true" : "false";
|
|
25
|
+
}
|
|
26
|
+
if (process.env.PAPERCLIP_SECRETS_MASTER_KEY_FILE === undefined) {
|
|
27
|
+
process.env.PAPERCLIP_SECRETS_MASTER_KEY_FILE = config.secretsMasterKeyFilePath;
|
|
28
|
+
}
|
|
29
|
+
function formatPendingMigrationSummary(migrations) {
|
|
30
|
+
if (migrations.length === 0)
|
|
31
|
+
return "none";
|
|
32
|
+
return migrations.length > 3
|
|
33
|
+
? `${migrations.slice(0, 3).join(", ")} (+${migrations.length - 3} more)`
|
|
34
|
+
: migrations.join(", ");
|
|
35
|
+
}
|
|
36
|
+
async function promptApplyMigrations(migrations) {
|
|
37
|
+
if (process.env.PAPERCLIP_MIGRATION_PROMPT === "never")
|
|
38
|
+
return false;
|
|
39
|
+
if (process.env.PAPERCLIP_MIGRATION_AUTO_APPLY === "true")
|
|
40
|
+
return true;
|
|
41
|
+
if (!stdin.isTTY || !stdout.isTTY)
|
|
42
|
+
return true;
|
|
43
|
+
const prompt = createInterface({ input: stdin, output: stdout });
|
|
44
|
+
try {
|
|
45
|
+
const answer = (await prompt.question(`Apply pending migrations (${formatPendingMigrationSummary(migrations)}) now? (y/N): `)).trim().toLowerCase();
|
|
46
|
+
return answer === "y" || answer === "yes";
|
|
47
|
+
}
|
|
48
|
+
finally {
|
|
49
|
+
prompt.close();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
async function ensureMigrations(connectionString, label, opts) {
|
|
53
|
+
const autoApply = opts?.autoApply === true;
|
|
54
|
+
let state = await inspectMigrations(connectionString);
|
|
55
|
+
if (state.status === "needsMigrations" && state.reason === "pending-migrations") {
|
|
56
|
+
const repair = await reconcilePendingMigrationHistory(connectionString);
|
|
57
|
+
if (repair.repairedMigrations.length > 0) {
|
|
58
|
+
logger.warn({ repairedMigrations: repair.repairedMigrations }, `${label} had drifted migration history; repaired migration journal entries from existing schema state.`);
|
|
59
|
+
state = await inspectMigrations(connectionString);
|
|
60
|
+
if (state.status === "upToDate")
|
|
61
|
+
return "already applied";
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (state.status === "upToDate")
|
|
65
|
+
return "already applied";
|
|
66
|
+
if (state.status === "needsMigrations" && state.reason === "no-migration-journal-non-empty-db") {
|
|
67
|
+
logger.warn({ tableCount: state.tableCount }, `${label} has existing tables but no migration journal. Run migrations manually to sync schema.`);
|
|
68
|
+
const apply = autoApply ? true : await promptApplyMigrations(state.pendingMigrations);
|
|
69
|
+
if (!apply) {
|
|
70
|
+
logger.warn({ pendingMigrations: state.pendingMigrations }, `${label} has pending migrations; continuing without applying. Run pnpm db:migrate to apply before startup.`);
|
|
71
|
+
return "pending migrations skipped";
|
|
72
|
+
}
|
|
73
|
+
logger.info({ pendingMigrations: state.pendingMigrations }, `Applying ${state.pendingMigrations.length} pending migrations for ${label}`);
|
|
74
|
+
await applyPendingMigrations(connectionString);
|
|
75
|
+
return "applied (pending migrations)";
|
|
76
|
+
}
|
|
77
|
+
const apply = autoApply ? true : await promptApplyMigrations(state.pendingMigrations);
|
|
78
|
+
if (!apply) {
|
|
79
|
+
logger.warn({ pendingMigrations: state.pendingMigrations }, `${label} has pending migrations; continuing without applying. Run pnpm db:migrate to apply before startup.`);
|
|
80
|
+
return "pending migrations skipped";
|
|
81
|
+
}
|
|
82
|
+
logger.info({ pendingMigrations: state.pendingMigrations }, `Applying ${state.pendingMigrations.length} pending migrations for ${label}`);
|
|
83
|
+
await applyPendingMigrations(connectionString);
|
|
84
|
+
return "applied (pending migrations)";
|
|
85
|
+
}
|
|
86
|
+
function isLoopbackHost(host) {
|
|
87
|
+
const normalized = host.trim().toLowerCase();
|
|
88
|
+
return normalized === "127.0.0.1" || normalized === "localhost" || normalized === "::1";
|
|
89
|
+
}
|
|
90
|
+
const LOCAL_BOARD_USER_ID = "local-board";
|
|
91
|
+
const LOCAL_BOARD_USER_EMAIL = "local@paperclip.local";
|
|
92
|
+
const LOCAL_BOARD_USER_NAME = "Board";
|
|
93
|
+
async function ensureLocalTrustedBoardPrincipal(db) {
|
|
94
|
+
const now = new Date();
|
|
95
|
+
const existingUser = await db
|
|
96
|
+
.select({ id: authUsers.id })
|
|
97
|
+
.from(authUsers)
|
|
98
|
+
.where(eq(authUsers.id, LOCAL_BOARD_USER_ID))
|
|
99
|
+
.then((rows) => rows[0] ?? null);
|
|
100
|
+
if (!existingUser) {
|
|
101
|
+
await db.insert(authUsers).values({
|
|
102
|
+
id: LOCAL_BOARD_USER_ID,
|
|
103
|
+
name: LOCAL_BOARD_USER_NAME,
|
|
104
|
+
email: LOCAL_BOARD_USER_EMAIL,
|
|
105
|
+
emailVerified: true,
|
|
106
|
+
image: null,
|
|
107
|
+
createdAt: now,
|
|
108
|
+
updatedAt: now,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
const role = await db
|
|
112
|
+
.select({ id: instanceUserRoles.id })
|
|
113
|
+
.from(instanceUserRoles)
|
|
114
|
+
.where(and(eq(instanceUserRoles.userId, LOCAL_BOARD_USER_ID), eq(instanceUserRoles.role, "instance_admin")))
|
|
115
|
+
.then((rows) => rows[0] ?? null);
|
|
116
|
+
if (!role) {
|
|
117
|
+
await db.insert(instanceUserRoles).values({
|
|
118
|
+
userId: LOCAL_BOARD_USER_ID,
|
|
119
|
+
role: "instance_admin",
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
const companyRows = await db.select({ id: companies.id }).from(companies);
|
|
123
|
+
for (const company of companyRows) {
|
|
124
|
+
const membership = await db
|
|
125
|
+
.select({ id: companyMemberships.id })
|
|
126
|
+
.from(companyMemberships)
|
|
127
|
+
.where(and(eq(companyMemberships.companyId, company.id), eq(companyMemberships.principalType, "user"), eq(companyMemberships.principalId, LOCAL_BOARD_USER_ID)))
|
|
128
|
+
.then((rows) => rows[0] ?? null);
|
|
129
|
+
if (membership)
|
|
130
|
+
continue;
|
|
131
|
+
await db.insert(companyMemberships).values({
|
|
132
|
+
companyId: company.id,
|
|
133
|
+
principalType: "user",
|
|
134
|
+
principalId: LOCAL_BOARD_USER_ID,
|
|
135
|
+
status: "active",
|
|
136
|
+
membershipRole: "owner",
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
let db;
|
|
141
|
+
let embeddedPostgres = null;
|
|
142
|
+
let embeddedPostgresStartedByThisProcess = false;
|
|
143
|
+
let migrationSummary = "skipped";
|
|
144
|
+
let startupDbInfo;
|
|
145
|
+
if (config.databaseUrl) {
|
|
146
|
+
migrationSummary = await ensureMigrations(config.databaseUrl, "PostgreSQL");
|
|
147
|
+
db = createDb(config.databaseUrl);
|
|
148
|
+
logger.info("Using external PostgreSQL via DATABASE_URL/config");
|
|
149
|
+
startupDbInfo = { mode: "external-postgres", connectionString: config.databaseUrl };
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
const moduleName = "embedded-postgres";
|
|
153
|
+
let EmbeddedPostgres;
|
|
154
|
+
try {
|
|
155
|
+
const mod = await import(moduleName);
|
|
156
|
+
EmbeddedPostgres = mod.default;
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
throw new Error("Embedded PostgreSQL mode requires optional dependency `embedded-postgres`. Install optional dependencies or set DATABASE_URL for external Postgres.");
|
|
160
|
+
}
|
|
161
|
+
const dataDir = resolve(config.embeddedPostgresDataDir);
|
|
162
|
+
const configuredPort = config.embeddedPostgresPort;
|
|
163
|
+
let port = configuredPort;
|
|
164
|
+
const embeddedPostgresLogBuffer = [];
|
|
165
|
+
const EMBEDDED_POSTGRES_LOG_BUFFER_LIMIT = 120;
|
|
166
|
+
const verboseEmbeddedPostgresLogs = process.env.PAPERCLIP_EMBEDDED_POSTGRES_VERBOSE === "true";
|
|
167
|
+
const appendEmbeddedPostgresLog = (message) => {
|
|
168
|
+
const text = typeof message === "string" ? message : message instanceof Error ? message.message : String(message ?? "");
|
|
169
|
+
for (const lineRaw of text.split(/\r?\n/)) {
|
|
170
|
+
const line = lineRaw.trim();
|
|
171
|
+
if (!line)
|
|
172
|
+
continue;
|
|
173
|
+
embeddedPostgresLogBuffer.push(line);
|
|
174
|
+
if (embeddedPostgresLogBuffer.length > EMBEDDED_POSTGRES_LOG_BUFFER_LIMIT) {
|
|
175
|
+
embeddedPostgresLogBuffer.splice(0, embeddedPostgresLogBuffer.length - EMBEDDED_POSTGRES_LOG_BUFFER_LIMIT);
|
|
176
|
+
}
|
|
177
|
+
if (verboseEmbeddedPostgresLogs) {
|
|
178
|
+
logger.info({ embeddedPostgresLog: line }, "embedded-postgres");
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
const logEmbeddedPostgresFailure = (phase, err) => {
|
|
183
|
+
if (embeddedPostgresLogBuffer.length > 0) {
|
|
184
|
+
logger.error({
|
|
185
|
+
phase,
|
|
186
|
+
recentLogs: embeddedPostgresLogBuffer,
|
|
187
|
+
err,
|
|
188
|
+
}, "Embedded PostgreSQL failed; showing buffered startup logs");
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
if (config.databaseMode === "postgres") {
|
|
192
|
+
logger.warn("Database mode is postgres but no connection string was set; falling back to embedded PostgreSQL");
|
|
193
|
+
}
|
|
194
|
+
const clusterVersionFile = resolve(dataDir, "PG_VERSION");
|
|
195
|
+
const clusterAlreadyInitialized = existsSync(clusterVersionFile);
|
|
196
|
+
const postmasterPidFile = resolve(dataDir, "postmaster.pid");
|
|
197
|
+
const isPidRunning = (pid) => {
|
|
198
|
+
try {
|
|
199
|
+
process.kill(pid, 0);
|
|
200
|
+
return true;
|
|
201
|
+
}
|
|
202
|
+
catch {
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
const getRunningPid = () => {
|
|
207
|
+
if (!existsSync(postmasterPidFile))
|
|
208
|
+
return null;
|
|
209
|
+
try {
|
|
210
|
+
const pidLine = readFileSync(postmasterPidFile, "utf8").split("\n")[0]?.trim();
|
|
211
|
+
const pid = Number(pidLine);
|
|
212
|
+
if (!Number.isInteger(pid) || pid <= 0)
|
|
213
|
+
return null;
|
|
214
|
+
if (!isPidRunning(pid))
|
|
215
|
+
return null;
|
|
216
|
+
return pid;
|
|
217
|
+
}
|
|
218
|
+
catch {
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
const runningPid = getRunningPid();
|
|
223
|
+
if (runningPid) {
|
|
224
|
+
logger.warn(`Embedded PostgreSQL already running; reusing existing process (pid=${runningPid}, port=${port})`);
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
const detectedPort = await detectPort(configuredPort);
|
|
228
|
+
if (detectedPort !== configuredPort) {
|
|
229
|
+
logger.warn(`Embedded PostgreSQL port is in use; using next free port (requestedPort=${configuredPort}, selectedPort=${detectedPort})`);
|
|
230
|
+
}
|
|
231
|
+
port = detectedPort;
|
|
232
|
+
logger.info(`Using embedded PostgreSQL because no DATABASE_URL set (dataDir=${dataDir}, port=${port})`);
|
|
233
|
+
embeddedPostgres = new EmbeddedPostgres({
|
|
234
|
+
databaseDir: dataDir,
|
|
235
|
+
user: "paperclip",
|
|
236
|
+
password: "paperclip",
|
|
237
|
+
port,
|
|
238
|
+
persistent: true,
|
|
239
|
+
onLog: appendEmbeddedPostgresLog,
|
|
240
|
+
onError: appendEmbeddedPostgresLog,
|
|
241
|
+
});
|
|
242
|
+
if (!clusterAlreadyInitialized) {
|
|
243
|
+
try {
|
|
244
|
+
await embeddedPostgres.initialise();
|
|
245
|
+
}
|
|
246
|
+
catch (err) {
|
|
247
|
+
logEmbeddedPostgresFailure("initialise", err);
|
|
248
|
+
throw err;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
logger.info(`Embedded PostgreSQL cluster already exists (${clusterVersionFile}); skipping init`);
|
|
253
|
+
}
|
|
254
|
+
if (existsSync(postmasterPidFile)) {
|
|
255
|
+
logger.warn("Removing stale embedded PostgreSQL lock file");
|
|
256
|
+
rmSync(postmasterPidFile, { force: true });
|
|
257
|
+
}
|
|
258
|
+
try {
|
|
259
|
+
await embeddedPostgres.start();
|
|
260
|
+
}
|
|
261
|
+
catch (err) {
|
|
262
|
+
logEmbeddedPostgresFailure("start", err);
|
|
263
|
+
throw err;
|
|
264
|
+
}
|
|
265
|
+
embeddedPostgresStartedByThisProcess = true;
|
|
266
|
+
}
|
|
267
|
+
const embeddedAdminConnectionString = `postgres://paperclip:paperclip@127.0.0.1:${port}/postgres`;
|
|
268
|
+
const dbStatus = await ensurePostgresDatabase(embeddedAdminConnectionString, "paperclip");
|
|
269
|
+
if (dbStatus === "created") {
|
|
270
|
+
logger.info("Created embedded PostgreSQL database: paperclip");
|
|
271
|
+
}
|
|
272
|
+
const embeddedConnectionString = `postgres://paperclip:paperclip@127.0.0.1:${port}/paperclip`;
|
|
273
|
+
const shouldAutoApplyFirstRunMigrations = !clusterAlreadyInitialized || dbStatus === "created";
|
|
274
|
+
if (shouldAutoApplyFirstRunMigrations) {
|
|
275
|
+
logger.info("Detected first-run embedded PostgreSQL setup; applying pending migrations automatically");
|
|
276
|
+
}
|
|
277
|
+
migrationSummary = await ensureMigrations(embeddedConnectionString, "Embedded PostgreSQL", {
|
|
278
|
+
autoApply: shouldAutoApplyFirstRunMigrations,
|
|
279
|
+
});
|
|
280
|
+
db = createDb(embeddedConnectionString);
|
|
281
|
+
logger.info("Embedded PostgreSQL ready");
|
|
282
|
+
startupDbInfo = { mode: "embedded-postgres", dataDir, port };
|
|
283
|
+
}
|
|
284
|
+
if (config.deploymentMode === "local_trusted" && !isLoopbackHost(config.host)) {
|
|
285
|
+
throw new Error(`local_trusted mode requires loopback host binding (received: ${config.host}). ` +
|
|
286
|
+
"Use authenticated mode for non-loopback deployments.");
|
|
287
|
+
}
|
|
288
|
+
if (config.deploymentMode === "local_trusted" && config.deploymentExposure !== "private") {
|
|
289
|
+
throw new Error("local_trusted mode only supports private exposure");
|
|
290
|
+
}
|
|
291
|
+
if (config.deploymentMode === "authenticated") {
|
|
292
|
+
if (config.authBaseUrlMode === "explicit" && !config.authPublicBaseUrl) {
|
|
293
|
+
throw new Error("auth.baseUrlMode=explicit requires auth.publicBaseUrl");
|
|
294
|
+
}
|
|
295
|
+
if (config.deploymentExposure === "public") {
|
|
296
|
+
if (config.authBaseUrlMode !== "explicit") {
|
|
297
|
+
throw new Error("authenticated public exposure requires auth.baseUrlMode=explicit");
|
|
298
|
+
}
|
|
299
|
+
if (!config.authPublicBaseUrl) {
|
|
300
|
+
throw new Error("authenticated public exposure requires auth.publicBaseUrl");
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
let authReady = config.deploymentMode === "local_trusted";
|
|
305
|
+
let betterAuthHandler;
|
|
306
|
+
let resolveSession;
|
|
307
|
+
let resolveSessionFromHeaders;
|
|
308
|
+
if (config.deploymentMode === "local_trusted") {
|
|
309
|
+
await ensureLocalTrustedBoardPrincipal(db);
|
|
310
|
+
}
|
|
311
|
+
if (config.deploymentMode === "authenticated") {
|
|
312
|
+
const betterAuthSecret = process.env.BETTER_AUTH_SECRET?.trim() ?? process.env.PAPERCLIP_AGENT_JWT_SECRET?.trim();
|
|
313
|
+
if (!betterAuthSecret) {
|
|
314
|
+
throw new Error("authenticated mode requires BETTER_AUTH_SECRET (or PAPERCLIP_AGENT_JWT_SECRET) to be set");
|
|
315
|
+
}
|
|
316
|
+
const auth = createBetterAuthInstance(db, config);
|
|
317
|
+
betterAuthHandler = createBetterAuthHandler(auth);
|
|
318
|
+
resolveSession = (req) => resolveBetterAuthSession(auth, req);
|
|
319
|
+
resolveSessionFromHeaders = (headers) => resolveBetterAuthSessionFromHeaders(auth, headers);
|
|
320
|
+
await initializeBoardClaimChallenge(db, { deploymentMode: config.deploymentMode });
|
|
321
|
+
authReady = true;
|
|
322
|
+
}
|
|
323
|
+
const uiMode = config.uiDevMiddleware ? "vite-dev" : config.serveUi ? "static" : "none";
|
|
324
|
+
const storageService = createStorageServiceFromConfig(config);
|
|
325
|
+
const app = await createApp(db, {
|
|
326
|
+
uiMode,
|
|
327
|
+
storageService,
|
|
328
|
+
deploymentMode: config.deploymentMode,
|
|
329
|
+
deploymentExposure: config.deploymentExposure,
|
|
330
|
+
allowedHostnames: config.allowedHostnames,
|
|
331
|
+
bindHost: config.host,
|
|
332
|
+
authReady,
|
|
333
|
+
companyDeletionEnabled: config.companyDeletionEnabled,
|
|
334
|
+
betterAuthHandler,
|
|
335
|
+
resolveSession,
|
|
336
|
+
});
|
|
337
|
+
const server = createServer(app);
|
|
338
|
+
const listenPort = await detectPort(config.port);
|
|
339
|
+
if (listenPort !== config.port) {
|
|
340
|
+
logger.warn(`Requested port is busy; using next free port (requestedPort=${config.port}, selectedPort=${listenPort})`);
|
|
341
|
+
}
|
|
342
|
+
const runtimeListenHost = config.host;
|
|
343
|
+
const runtimeApiHost = runtimeListenHost === "0.0.0.0" || runtimeListenHost === "::"
|
|
344
|
+
? "localhost"
|
|
345
|
+
: runtimeListenHost;
|
|
346
|
+
process.env.PAPERCLIP_LISTEN_HOST = runtimeListenHost;
|
|
347
|
+
process.env.PAPERCLIP_LISTEN_PORT = String(listenPort);
|
|
348
|
+
process.env.PAPERCLIP_API_URL = `http://${runtimeApiHost}:${listenPort}`;
|
|
349
|
+
setupLiveEventsWebSocketServer(server, db, {
|
|
350
|
+
deploymentMode: config.deploymentMode,
|
|
351
|
+
resolveSessionFromHeaders,
|
|
352
|
+
});
|
|
353
|
+
if (config.heartbeatSchedulerEnabled) {
|
|
354
|
+
const heartbeat = heartbeatService(db);
|
|
355
|
+
// Reap orphaned runs at startup (no threshold -- runningProcesses is empty)
|
|
356
|
+
void heartbeat.reapOrphanedRuns().catch((err) => {
|
|
357
|
+
logger.error({ err }, "startup reap of orphaned heartbeat runs failed");
|
|
358
|
+
});
|
|
359
|
+
setInterval(() => {
|
|
360
|
+
void heartbeat
|
|
361
|
+
.tickTimers(new Date())
|
|
362
|
+
.then((result) => {
|
|
363
|
+
if (result.enqueued > 0) {
|
|
364
|
+
logger.info({ ...result }, "heartbeat timer tick enqueued runs");
|
|
365
|
+
}
|
|
366
|
+
})
|
|
367
|
+
.catch((err) => {
|
|
368
|
+
logger.error({ err }, "heartbeat timer tick failed");
|
|
369
|
+
});
|
|
370
|
+
// Periodically reap orphaned runs (5-min staleness threshold)
|
|
371
|
+
void heartbeat
|
|
372
|
+
.reapOrphanedRuns({ staleThresholdMs: 5 * 60 * 1000 })
|
|
373
|
+
.catch((err) => {
|
|
374
|
+
logger.error({ err }, "periodic reap of orphaned heartbeat runs failed");
|
|
375
|
+
});
|
|
376
|
+
}, config.heartbeatSchedulerIntervalMs);
|
|
377
|
+
}
|
|
378
|
+
server.listen(listenPort, config.host, () => {
|
|
379
|
+
logger.info(`Server listening on ${config.host}:${listenPort}`);
|
|
380
|
+
if (process.env.PAPERCLIP_OPEN_ON_LISTEN === "true") {
|
|
381
|
+
const openHost = config.host === "0.0.0.0" || config.host === "::" ? "127.0.0.1" : config.host;
|
|
382
|
+
const url = `http://${openHost}:${listenPort}`;
|
|
383
|
+
void import("open")
|
|
384
|
+
.then((mod) => mod.default(url))
|
|
385
|
+
.then(() => {
|
|
386
|
+
logger.info(`Opened browser at ${url}`);
|
|
387
|
+
})
|
|
388
|
+
.catch((err) => {
|
|
389
|
+
logger.warn({ err, url }, "Failed to open browser on startup");
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
printStartupBanner({
|
|
393
|
+
host: config.host,
|
|
394
|
+
deploymentMode: config.deploymentMode,
|
|
395
|
+
deploymentExposure: config.deploymentExposure,
|
|
396
|
+
authReady,
|
|
397
|
+
requestedPort: config.port,
|
|
398
|
+
listenPort,
|
|
399
|
+
uiMode,
|
|
400
|
+
db: startupDbInfo,
|
|
401
|
+
migrationSummary,
|
|
402
|
+
heartbeatSchedulerEnabled: config.heartbeatSchedulerEnabled,
|
|
403
|
+
heartbeatSchedulerIntervalMs: config.heartbeatSchedulerIntervalMs,
|
|
404
|
+
});
|
|
405
|
+
const boardClaimUrl = getBoardClaimWarningUrl(config.host, listenPort);
|
|
406
|
+
if (boardClaimUrl) {
|
|
407
|
+
const red = "\x1b[41m\x1b[30m";
|
|
408
|
+
const yellow = "\x1b[33m";
|
|
409
|
+
const reset = "\x1b[0m";
|
|
410
|
+
console.log([
|
|
411
|
+
`${red} BOARD CLAIM REQUIRED ${reset}`,
|
|
412
|
+
`${yellow}This instance was previously local_trusted and still has local-board as the only admin.${reset}`,
|
|
413
|
+
`${yellow}Sign in with a real user and open this one-time URL to claim ownership:${reset}`,
|
|
414
|
+
`${yellow}${boardClaimUrl}${reset}`,
|
|
415
|
+
`${yellow}If you are connecting over Tailscale, replace the host in this URL with your Tailscale IP/MagicDNS name.${reset}`,
|
|
416
|
+
].join("\n"));
|
|
417
|
+
}
|
|
418
|
+
});
|
|
419
|
+
if (embeddedPostgres && embeddedPostgresStartedByThisProcess) {
|
|
420
|
+
const shutdown = async (signal) => {
|
|
421
|
+
logger.info({ signal }, "Stopping embedded PostgreSQL");
|
|
422
|
+
try {
|
|
423
|
+
await embeddedPostgres?.stop();
|
|
424
|
+
}
|
|
425
|
+
catch (err) {
|
|
426
|
+
logger.error({ err }, "Failed to stop embedded PostgreSQL cleanly");
|
|
427
|
+
}
|
|
428
|
+
finally {
|
|
429
|
+
process.exit(0);
|
|
430
|
+
}
|
|
431
|
+
};
|
|
432
|
+
process.once("SIGINT", () => {
|
|
433
|
+
void shutdown("SIGINT");
|
|
434
|
+
});
|
|
435
|
+
process.once("SIGTERM", () => {
|
|
436
|
+
void shutdown("SIGTERM");
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Request, RequestHandler } from "express";
|
|
2
|
+
import type { Db } from "@paperclipai/db";
|
|
3
|
+
import type { DeploymentMode } from "@paperclipai/shared";
|
|
4
|
+
import type { BetterAuthSessionResult } from "../auth/better-auth.js";
|
|
5
|
+
interface ActorMiddlewareOptions {
|
|
6
|
+
deploymentMode: DeploymentMode;
|
|
7
|
+
resolveSession?: (req: Request) => Promise<BetterAuthSessionResult | null>;
|
|
8
|
+
}
|
|
9
|
+
export declare function actorMiddleware(db: Db, opts: ActorMiddlewareOptions): RequestHandler;
|
|
10
|
+
export declare function requireBoard(req: Express.Request): boolean;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAEvD,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AAG1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAOtE,UAAU,sBAAsB;IAC9B,cAAc,EAAE,cAAc,CAAC;IAC/B,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC,CAAC;CAC5E;AAED,wBAAgB,eAAe,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,sBAAsB,GAAG,cAAc,CAoIpF;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,WAEhD"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { and, eq, isNull } from "drizzle-orm";
|
|
3
|
+
import { agentApiKeys, agents, companyMemberships, instanceUserRoles } from "@paperclipai/db";
|
|
4
|
+
import { verifyLocalAgentJwt } from "../agent-auth-jwt.js";
|
|
5
|
+
import { logger } from "./logger.js";
|
|
6
|
+
function hashToken(token) {
|
|
7
|
+
return createHash("sha256").update(token).digest("hex");
|
|
8
|
+
}
|
|
9
|
+
export function actorMiddleware(db, opts) {
|
|
10
|
+
return async (req, _res, next) => {
|
|
11
|
+
req.actor =
|
|
12
|
+
opts.deploymentMode === "local_trusted"
|
|
13
|
+
? { type: "board", userId: "local-board", isInstanceAdmin: true, source: "local_implicit" }
|
|
14
|
+
: { type: "none", source: "none" };
|
|
15
|
+
const runIdHeader = req.header("x-paperclip-run-id");
|
|
16
|
+
const authHeader = req.header("authorization");
|
|
17
|
+
if (!authHeader?.toLowerCase().startsWith("bearer ")) {
|
|
18
|
+
if (opts.deploymentMode === "authenticated" && opts.resolveSession) {
|
|
19
|
+
let session = null;
|
|
20
|
+
try {
|
|
21
|
+
session = await opts.resolveSession(req);
|
|
22
|
+
}
|
|
23
|
+
catch (err) {
|
|
24
|
+
logger.warn({ err, method: req.method, url: req.originalUrl }, "Failed to resolve auth session from request headers");
|
|
25
|
+
}
|
|
26
|
+
if (session?.user?.id) {
|
|
27
|
+
const userId = session.user.id;
|
|
28
|
+
const [roleRow, memberships] = await Promise.all([
|
|
29
|
+
db
|
|
30
|
+
.select({ id: instanceUserRoles.id })
|
|
31
|
+
.from(instanceUserRoles)
|
|
32
|
+
.where(and(eq(instanceUserRoles.userId, userId), eq(instanceUserRoles.role, "instance_admin")))
|
|
33
|
+
.then((rows) => rows[0] ?? null),
|
|
34
|
+
db
|
|
35
|
+
.select({ companyId: companyMemberships.companyId })
|
|
36
|
+
.from(companyMemberships)
|
|
37
|
+
.where(and(eq(companyMemberships.principalType, "user"), eq(companyMemberships.principalId, userId), eq(companyMemberships.status, "active"))),
|
|
38
|
+
]);
|
|
39
|
+
req.actor = {
|
|
40
|
+
type: "board",
|
|
41
|
+
userId,
|
|
42
|
+
companyIds: memberships.map((row) => row.companyId),
|
|
43
|
+
isInstanceAdmin: Boolean(roleRow),
|
|
44
|
+
runId: runIdHeader ?? undefined,
|
|
45
|
+
source: "session",
|
|
46
|
+
};
|
|
47
|
+
next();
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (runIdHeader)
|
|
52
|
+
req.actor.runId = runIdHeader;
|
|
53
|
+
next();
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const token = authHeader.slice("bearer ".length).trim();
|
|
57
|
+
if (!token) {
|
|
58
|
+
next();
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const tokenHash = hashToken(token);
|
|
62
|
+
const key = await db
|
|
63
|
+
.select()
|
|
64
|
+
.from(agentApiKeys)
|
|
65
|
+
.where(and(eq(agentApiKeys.keyHash, tokenHash), isNull(agentApiKeys.revokedAt)))
|
|
66
|
+
.then((rows) => rows[0] ?? null);
|
|
67
|
+
if (!key) {
|
|
68
|
+
const claims = verifyLocalAgentJwt(token);
|
|
69
|
+
if (!claims) {
|
|
70
|
+
next();
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const agentRecord = await db
|
|
74
|
+
.select()
|
|
75
|
+
.from(agents)
|
|
76
|
+
.where(eq(agents.id, claims.sub))
|
|
77
|
+
.then((rows) => rows[0] ?? null);
|
|
78
|
+
if (!agentRecord || agentRecord.companyId !== claims.company_id) {
|
|
79
|
+
next();
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
if (agentRecord.status === "terminated" || agentRecord.status === "pending_approval") {
|
|
83
|
+
next();
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
req.actor = {
|
|
87
|
+
type: "agent",
|
|
88
|
+
agentId: claims.sub,
|
|
89
|
+
companyId: claims.company_id,
|
|
90
|
+
keyId: undefined,
|
|
91
|
+
runId: runIdHeader || claims.run_id || undefined,
|
|
92
|
+
source: "agent_jwt",
|
|
93
|
+
};
|
|
94
|
+
next();
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
await db
|
|
98
|
+
.update(agentApiKeys)
|
|
99
|
+
.set({ lastUsedAt: new Date() })
|
|
100
|
+
.where(eq(agentApiKeys.id, key.id));
|
|
101
|
+
const agentRecord = await db
|
|
102
|
+
.select()
|
|
103
|
+
.from(agents)
|
|
104
|
+
.where(eq(agents.id, key.agentId))
|
|
105
|
+
.then((rows) => rows[0] ?? null);
|
|
106
|
+
if (!agentRecord || agentRecord.status === "terminated" || agentRecord.status === "pending_approval") {
|
|
107
|
+
next();
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
req.actor = {
|
|
111
|
+
type: "agent",
|
|
112
|
+
agentId: key.agentId,
|
|
113
|
+
companyId: key.companyId,
|
|
114
|
+
keyId: key.id,
|
|
115
|
+
runId: runIdHeader || undefined,
|
|
116
|
+
source: "agent_key",
|
|
117
|
+
};
|
|
118
|
+
next();
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
export function requireBoard(req) {
|
|
122
|
+
return req.actor.type === "board";
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"board-mutation-guard.d.ts","sourceRoot":"","sources":["../../src/middleware/board-mutation-guard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,cAAc,EAAE,MAAM,SAAS,CAAC;AAuCvD,wBAAgB,kBAAkB,IAAI,cAAc,CA2BnD"}
|