mirror of
https://github.com/aljazceru/opencode.git
synced 2025-12-21 01:34:22 +01:00
wip: zen
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { Context } from "./context"
|
||||
import { UserRole } from "./schema/user.sql"
|
||||
import { Log } from "./util/log"
|
||||
|
||||
export namespace Actor {
|
||||
@@ -21,6 +22,7 @@ export namespace Actor {
|
||||
userID: string
|
||||
workspaceID: string
|
||||
accountID: string
|
||||
role: (typeof UserRole)[number]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,4 +82,12 @@ export namespace Actor {
|
||||
}
|
||||
throw new Error(`actor of type "${actor.type}" is not associated with an account`)
|
||||
}
|
||||
|
||||
export function userID() {
|
||||
return Actor.assert("user").properties.userID
|
||||
}
|
||||
|
||||
export function userRole() {
|
||||
return Actor.assert("user").properties.role
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,8 +10,6 @@ import { User } from "./user"
|
||||
|
||||
export namespace Key {
|
||||
export const list = fn(z.void(), async () => {
|
||||
const userID = Actor.assert("user").properties.userID
|
||||
const user = await User.fromID(userID)
|
||||
const keys = await Database.use((tx) =>
|
||||
tx
|
||||
.select({
|
||||
@@ -30,7 +28,7 @@ export namespace Key {
|
||||
...[
|
||||
eq(KeyTable.workspaceID, Actor.workspace()),
|
||||
isNull(KeyTable.timeDeleted),
|
||||
...(user.role === "admin" ? [] : [eq(KeyTable.userID, userID)]),
|
||||
...(Actor.userRole() === "admin" ? [] : [eq(KeyTable.userID, Actor.userID())]),
|
||||
],
|
||||
),
|
||||
)
|
||||
@@ -39,7 +37,7 @@ export namespace Key {
|
||||
// only return value for user's keys
|
||||
return keys.map((key) => ({
|
||||
...key,
|
||||
key: key.userID === userID ? key.key : undefined,
|
||||
key: key.userID === Actor.userID() ? key.key : undefined,
|
||||
keyDisplay: `${key.key.slice(0, 7)}...${key.key.slice(-4)}`,
|
||||
}))
|
||||
})
|
||||
@@ -78,14 +76,22 @@ export namespace Key {
|
||||
)
|
||||
|
||||
export const remove = fn(z.object({ id: z.string() }), async (input) => {
|
||||
const workspace = Actor.workspace()
|
||||
await Database.transaction((tx) =>
|
||||
// only admin can remove other user's keys
|
||||
await Database.use((tx) =>
|
||||
tx
|
||||
.update(KeyTable)
|
||||
.set({
|
||||
timeDeleted: sql`now()`,
|
||||
})
|
||||
.where(and(eq(KeyTable.id, input.id), eq(KeyTable.workspaceID, workspace))),
|
||||
.where(
|
||||
and(
|
||||
...[
|
||||
eq(KeyTable.id, input.id),
|
||||
eq(KeyTable.workspaceID, Actor.workspace()),
|
||||
...(Actor.userRole() === "admin" ? [] : [eq(KeyTable.userID, Actor.userID())]),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { z } from "zod"
|
||||
import { and, eq, getTableColumns, inArray, isNull, or, sql } from "drizzle-orm"
|
||||
import { and, eq, getTableColumns, isNull, sql } from "drizzle-orm"
|
||||
import { fn } from "./util/fn"
|
||||
import { Database } from "./drizzle"
|
||||
import { UserRole, UserTable } from "./schema/user.sql"
|
||||
@@ -13,19 +13,14 @@ import { Key } from "./key"
|
||||
import { KeyTable } from "./schema/key.sql"
|
||||
|
||||
export namespace User {
|
||||
const assertAdmin = async () => {
|
||||
const actor = Actor.assert("user")
|
||||
const user = await User.fromID(actor.properties.userID)
|
||||
if (user?.role !== "admin") {
|
||||
throw new Error(`Expected admin user, got ${user?.role}`)
|
||||
}
|
||||
const assertAdmin = () => {
|
||||
if (Actor.userRole() === "admin") return
|
||||
throw new Error(`Expected admin user, got ${Actor.userRole()}`)
|
||||
}
|
||||
|
||||
const assertNotSelf = (id: string) => {
|
||||
const actor = Actor.assert("user")
|
||||
if (actor.properties.userID === id) {
|
||||
throw new Error(`Expected not self actor, got self actor`)
|
||||
}
|
||||
if (Actor.userID() !== id) return
|
||||
throw new Error(`Expected not self actor, got self actor`)
|
||||
}
|
||||
|
||||
export const list = fn(z.void(), () =>
|
||||
@@ -70,7 +65,7 @@ export namespace User {
|
||||
role: z.enum(UserRole),
|
||||
}),
|
||||
async ({ email, role }) => {
|
||||
await assertAdmin()
|
||||
assertAdmin()
|
||||
const workspaceID = Actor.workspace()
|
||||
|
||||
// create user
|
||||
@@ -181,7 +176,7 @@ export namespace User {
|
||||
monthlyLimit: z.number().nullable(),
|
||||
}),
|
||||
async ({ id, role, monthlyLimit }) => {
|
||||
await assertAdmin()
|
||||
assertAdmin()
|
||||
if (role === "member") assertNotSelf(id)
|
||||
return await Database.use((tx) =>
|
||||
tx
|
||||
@@ -193,7 +188,7 @@ export namespace User {
|
||||
)
|
||||
|
||||
export const remove = fn(z.string(), async (id) => {
|
||||
await assertAdmin()
|
||||
assertAdmin()
|
||||
assertNotSelf(id)
|
||||
|
||||
return await Database.use((tx) =>
|
||||
|
||||
Reference in New Issue
Block a user