Add browser-based board CLI auth flow

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
dotta 2026-03-23 07:48:03 -05:00
parent 1376fc8f44
commit 37c2c4acc4
31 changed files with 13299 additions and 19 deletions

View file

@ -0,0 +1,20 @@
import { pgTable, uuid, text, timestamp, index } from "drizzle-orm/pg-core";
import { authUsers } from "./auth.js";
export const boardApiKeys = pgTable(
"board_api_keys",
{
id: uuid("id").primaryKey().defaultRandom(),
userId: text("user_id").notNull().references(() => authUsers.id, { onDelete: "cascade" }),
name: text("name").notNull(),
keyHash: text("key_hash").notNull(),
lastUsedAt: timestamp("last_used_at", { withTimezone: true }),
revokedAt: timestamp("revoked_at", { withTimezone: true }),
expiresAt: timestamp("expires_at", { withTimezone: true }),
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
},
(table) => ({
keyHashIdx: index("board_api_keys_key_hash_idx").on(table.keyHash),
userIdx: index("board_api_keys_user_idx").on(table.userId),
}),
);

View file

@ -0,0 +1,30 @@
import { pgTable, uuid, text, timestamp, index } from "drizzle-orm/pg-core";
import { authUsers } from "./auth.js";
import { companies } from "./companies.js";
import { boardApiKeys } from "./board_api_keys.js";
export const cliAuthChallenges = pgTable(
"cli_auth_challenges",
{
id: uuid("id").primaryKey().defaultRandom(),
secretHash: text("secret_hash").notNull(),
command: text("command").notNull(),
clientName: text("client_name"),
requestedAccess: text("requested_access").notNull().default("board"),
requestedCompanyId: uuid("requested_company_id").references(() => companies.id, { onDelete: "set null" }),
pendingKeyHash: text("pending_key_hash").notNull(),
pendingKeyName: text("pending_key_name").notNull(),
approvedByUserId: text("approved_by_user_id").references(() => authUsers.id, { onDelete: "set null" }),
boardApiKeyId: uuid("board_api_key_id").references(() => boardApiKeys.id, { onDelete: "set null" }),
approvedAt: timestamp("approved_at", { withTimezone: true }),
cancelledAt: timestamp("cancelled_at", { withTimezone: true }),
expiresAt: timestamp("expires_at", { withTimezone: true }).notNull(),
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
},
(table) => ({
secretHashIdx: index("cli_auth_challenges_secret_hash_idx").on(table.secretHash),
approvedByIdx: index("cli_auth_challenges_approved_by_idx").on(table.approvedByUserId),
requestedCompanyIdx: index("cli_auth_challenges_requested_company_idx").on(table.requestedCompanyId),
}),
);

View file

@ -4,6 +4,8 @@ export { authUsers, authSessions, authAccounts, authVerifications } from "./auth
export { instanceSettings } from "./instance_settings.js";
export { instanceUserRoles } from "./instance_user_roles.js";
export { agents } from "./agents.js";
export { boardApiKeys } from "./board_api_keys.js";
export { cliAuthChallenges } from "./cli_auth_challenges.js";
export { companyMemberships } from "./company_memberships.js";
export { principalPermissionGrants } from "./principal_permission_grants.js";
export { invites } from "./invites.js";