revert: remove db agents for now
This commit is contained in:
parent
7cfe3b3ebe
commit
e168a8ddf5
5 changed files with 1 additions and 2664 deletions
|
|
@ -1,29 +0,0 @@
|
||||||
CREATE TABLE `agent_tokens` (
|
|
||||||
`id` text PRIMARY KEY,
|
|
||||||
`name` text NOT NULL,
|
|
||||||
`token_hash` text NOT NULL,
|
|
||||||
`token_prefix` text NOT NULL,
|
|
||||||
`agent_id` text NOT NULL,
|
|
||||||
`created_by` text NOT NULL,
|
|
||||||
`last_used_at` integer,
|
|
||||||
`revoked_at` integer,
|
|
||||||
`created_at` integer DEFAULT (unixepoch() * 1000) NOT NULL,
|
|
||||||
CONSTRAINT `fk_agent_tokens_agent_id_agents_id_fk` FOREIGN KEY (`agent_id`) REFERENCES `agents`(`id`) ON DELETE CASCADE,
|
|
||||||
CONSTRAINT `fk_agent_tokens_created_by_users_table_id_fk` FOREIGN KEY (`created_by`) REFERENCES `users_table`(`id`) ON DELETE CASCADE
|
|
||||||
);
|
|
||||||
--> statement-breakpoint
|
|
||||||
CREATE TABLE `agents` (
|
|
||||||
`id` text PRIMARY KEY,
|
|
||||||
`name` text NOT NULL,
|
|
||||||
`organization_id` text NOT NULL,
|
|
||||||
`created_by` text NOT NULL,
|
|
||||||
`last_seen_at` integer,
|
|
||||||
`created_at` integer DEFAULT (unixepoch() * 1000) NOT NULL,
|
|
||||||
CONSTRAINT `fk_agents_organization_id_organization_id_fk` FOREIGN KEY (`organization_id`) REFERENCES `organization`(`id`) ON DELETE CASCADE,
|
|
||||||
CONSTRAINT `fk_agents_created_by_users_table_id_fk` FOREIGN KEY (`created_by`) REFERENCES `users_table`(`id`) ON DELETE CASCADE,
|
|
||||||
CONSTRAINT `agents_name_org_uidx` UNIQUE(`name`,`organization_id`)
|
|
||||||
);
|
|
||||||
--> statement-breakpoint
|
|
||||||
CREATE UNIQUE INDEX `agent_tokens_token_hash_uidx` ON `agent_tokens` (`token_hash`);--> statement-breakpoint
|
|
||||||
CREATE INDEX `agent_tokens_agent_id_idx` ON `agent_tokens` (`agent_id`);--> statement-breakpoint
|
|
||||||
CREATE INDEX `agents_organization_id_idx` ON `agents` (`organization_id`);
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -95,29 +95,6 @@ export const relations = defineRelations(schema, (r) => ({
|
||||||
to: r.usersTable.id,
|
to: r.usersTable.id,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
agentsTable: {
|
|
||||||
organization: r.one.organization({
|
|
||||||
from: r.agentsTable.organizationId,
|
|
||||||
to: r.organization.id,
|
|
||||||
optional: false,
|
|
||||||
}),
|
|
||||||
createdByUser: r.one.usersTable({
|
|
||||||
from: r.agentsTable.createdBy,
|
|
||||||
to: r.usersTable.id,
|
|
||||||
}),
|
|
||||||
tokens: r.many.agentTokensTable(),
|
|
||||||
},
|
|
||||||
agentTokensTable: {
|
|
||||||
agent: r.one.agentsTable({
|
|
||||||
from: r.agentTokensTable.agentId,
|
|
||||||
to: r.agentsTable.id,
|
|
||||||
optional: false,
|
|
||||||
}),
|
|
||||||
createdByUser: r.one.usersTable({
|
|
||||||
from: r.agentTokensTable.createdBy,
|
|
||||||
to: r.usersTable.id,
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
organization: {
|
organization: {
|
||||||
users: r.many.usersTable({
|
users: r.many.usersTable({
|
||||||
alias: "usersTable_id_organization_id_via_member",
|
alias: "usersTable_id_organization_id_via_member",
|
||||||
|
|
@ -129,7 +106,6 @@ export const relations = defineRelations(schema, (r) => ({
|
||||||
members: r.many.member(),
|
members: r.many.member(),
|
||||||
invitations: r.many.invitation(),
|
invitations: r.many.invitation(),
|
||||||
ssoProviders: r.many.ssoProvider(),
|
ssoProviders: r.many.ssoProvider(),
|
||||||
agents: r.many.agentsTable(),
|
|
||||||
},
|
},
|
||||||
ssoProvider: {
|
ssoProvider: {
|
||||||
user: r.one.usersTable({
|
user: r.one.usersTable({
|
||||||
|
|
|
||||||
|
|
@ -413,61 +413,6 @@ export const appMetadataTable = sqliteTable("app_metadata", {
|
||||||
});
|
});
|
||||||
export type AppMetadata = typeof appMetadataTable.$inferSelect;
|
export type AppMetadata = typeof appMetadataTable.$inferSelect;
|
||||||
|
|
||||||
/**
|
|
||||||
* Agents Table
|
|
||||||
*/
|
|
||||||
export const agentsTable = sqliteTable(
|
|
||||||
"agents",
|
|
||||||
{
|
|
||||||
id: text("id").primaryKey(),
|
|
||||||
name: text("name").notNull(),
|
|
||||||
organizationId: text("organization_id")
|
|
||||||
.notNull()
|
|
||||||
.references(() => organization.id, { onDelete: "cascade" }),
|
|
||||||
createdBy: text("created_by")
|
|
||||||
.notNull()
|
|
||||||
.references(() => usersTable.id, { onDelete: "cascade" }),
|
|
||||||
lastSeenAt: int("last_seen_at", { mode: "number" }),
|
|
||||||
createdAt: int("created_at", { mode: "number" })
|
|
||||||
.notNull()
|
|
||||||
.default(sql`(unixepoch() * 1000)`),
|
|
||||||
},
|
|
||||||
(table) => [
|
|
||||||
index("agents_organization_id_idx").on(table.organizationId),
|
|
||||||
unique("agents_name_org_uidx").on(table.name, table.organizationId),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
export type Agent = typeof agentsTable.$inferSelect;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Agent Tokens Table
|
|
||||||
*/
|
|
||||||
export const agentTokensTable = sqliteTable(
|
|
||||||
"agent_tokens",
|
|
||||||
{
|
|
||||||
id: text("id").primaryKey(),
|
|
||||||
name: text("name").notNull(),
|
|
||||||
tokenHash: text("token_hash").notNull(),
|
|
||||||
tokenPrefix: text("token_prefix").notNull(),
|
|
||||||
agentId: text("agent_id")
|
|
||||||
.notNull()
|
|
||||||
.references(() => agentsTable.id, { onDelete: "cascade" }),
|
|
||||||
createdBy: text("created_by")
|
|
||||||
.notNull()
|
|
||||||
.references(() => usersTable.id, { onDelete: "cascade" }),
|
|
||||||
lastUsedAt: int("last_used_at", { mode: "number" }),
|
|
||||||
revokedAt: int("revoked_at", { mode: "number" }),
|
|
||||||
createdAt: int("created_at", { mode: "number" })
|
|
||||||
.notNull()
|
|
||||||
.default(sql`(unixepoch() * 1000)`),
|
|
||||||
},
|
|
||||||
(table) => [
|
|
||||||
uniqueIndex("agent_tokens_token_hash_uidx").on(table.tokenHash),
|
|
||||||
index("agent_tokens_agent_id_idx").on(table.agentId),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
export type AgentToken = typeof agentTokensTable.$inferSelect;
|
|
||||||
|
|
||||||
export const twoFactor = sqliteTable(
|
export const twoFactor = sqliteTable(
|
||||||
"two_factor",
|
"two_factor",
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,46 +1,7 @@
|
||||||
import crypto from "node:crypto";
|
|
||||||
import { eq } from "drizzle-orm";
|
|
||||||
import { db } from "~/server/db/db";
|
|
||||||
import { agentTokensTable } from "~/server/db/schema";
|
|
||||||
import { cryptoUtils } from "~/server/utils/crypto";
|
import { cryptoUtils } from "~/server/utils/crypto";
|
||||||
|
|
||||||
export const generateToken = () => {
|
|
||||||
return `zbk_${crypto.randomBytes(32).toString("hex")}`;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const hashToken = (token: string) => {
|
|
||||||
return crypto.createHash("sha256").update(token).digest("hex");
|
|
||||||
};
|
|
||||||
|
|
||||||
export const deriveLocalAgentToken = async () => {
|
export const deriveLocalAgentToken = async () => {
|
||||||
const derived = await cryptoUtils.deriveSecret("zerobyte:local-agent-token");
|
return cryptoUtils.deriveSecret("zerobyte:local-agent-token");
|
||||||
return `zbk_${derived}`;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const createAgentToken = async ({
|
|
||||||
name,
|
|
||||||
agentId,
|
|
||||||
createdBy,
|
|
||||||
}: {
|
|
||||||
name: string;
|
|
||||||
agentId: string;
|
|
||||||
createdBy: string;
|
|
||||||
}) => {
|
|
||||||
const plaintext = generateToken();
|
|
||||||
const tokenHash = hashToken(plaintext);
|
|
||||||
const tokenPrefix = plaintext.slice(0, 12);
|
|
||||||
|
|
||||||
const id = Bun.randomUUIDv7();
|
|
||||||
await db.insert(agentTokensTable).values({
|
|
||||||
id,
|
|
||||||
name,
|
|
||||||
tokenHash,
|
|
||||||
tokenPrefix,
|
|
||||||
agentId,
|
|
||||||
createdBy,
|
|
||||||
});
|
|
||||||
|
|
||||||
return { id, name, tokenPrefix, plaintext };
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const validateAgentToken = async (token: string) => {
|
export const validateAgentToken = async (token: string) => {
|
||||||
|
|
@ -48,40 +9,4 @@ export const validateAgentToken = async (token: string) => {
|
||||||
if (token === localToken) {
|
if (token === localToken) {
|
||||||
return { agentId: "local", organizationId: null, agentName: "local" };
|
return { agentId: "local", organizationId: null, agentName: "local" };
|
||||||
}
|
}
|
||||||
|
|
||||||
const tokenHash = hashToken(token);
|
|
||||||
|
|
||||||
const record = await db.query.agentTokensTable.findFirst({
|
|
||||||
where: { tokenHash, revokedAt: { isNull: true } },
|
|
||||||
with: { agent: true },
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!record) return null;
|
|
||||||
|
|
||||||
await db.update(agentTokensTable).set({ lastUsedAt: Date.now() }).where(eq(agentTokensTable.id, record.id));
|
|
||||||
|
|
||||||
return {
|
|
||||||
agentId: record.agentId,
|
|
||||||
organizationId: record.agent.organizationId,
|
|
||||||
agentName: record.name,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const revokeAgentToken = async (tokenId: string, agentId: string) => {
|
|
||||||
const token = await db.query.agentTokensTable.findFirst({
|
|
||||||
where: { id: tokenId, agentId, revokedAt: { isNull: true } },
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!token) return false;
|
|
||||||
|
|
||||||
await db.update(agentTokensTable).set({ revokedAt: Date.now() }).where(eq(agentTokensTable.id, tokenId));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const listAgentTokens = async (agentId: string) => {
|
|
||||||
return db.query.agentTokensTable.findMany({
|
|
||||||
where: { agentId },
|
|
||||||
columns: { id: true, name: true, tokenPrefix: true, lastUsedAt: true, revokedAt: true, createdAt: true },
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue