summaryrefslogtreecommitdiffhomepage
path: root/packages/console/core/src
diff options
context:
space:
mode:
authorFrank <[email protected]>2025-10-10 21:24:05 -0400
committerFrank <[email protected]>2025-10-10 21:24:05 -0400
commit2d35b783335cae9898ec80362934bab892fcf973 (patch)
tree146ba002b1bd58044bcac15c5ced977c086a9bd1 /packages/console/core/src
parent07645e070525e627cda5cd4ad7f001f70cbc57dc (diff)
parentc7dfbbeed0e7b5a7421b4b0d8c115a24f5ba7534 (diff)
downloadopencode-2d35b783335cae9898ec80362934bab892fcf973.tar.gz
opencode-2d35b783335cae9898ec80362934bab892fcf973.zip
Merge branch 'console-workspaces' into dev
Diffstat (limited to 'packages/console/core/src')
-rw-r--r--packages/console/core/src/actor.ts5
-rw-r--r--packages/console/core/src/model.ts5
-rw-r--r--packages/console/core/src/provider.ts26
-rw-r--r--packages/console/core/src/user.ts36
-rw-r--r--packages/console/core/src/workspace.ts1
5 files changed, 52 insertions, 21 deletions
diff --git a/packages/console/core/src/actor.ts b/packages/console/core/src/actor.ts
index 88c5e4b51..48f4a6366 100644
--- a/packages/console/core/src/actor.ts
+++ b/packages/console/core/src/actor.ts
@@ -67,6 +67,11 @@ export namespace Actor {
return actor as Extract<Info, { type: T }>
}
+ export const assertAdmin = () => {
+ if (userRole() === "admin") return
+ throw new Error(`Action not allowed. Ask your workspace admin to perform this action.`)
+ }
+
export function workspace() {
const actor = use()
if ("workspaceID" in actor.properties) {
diff --git a/packages/console/core/src/model.ts b/packages/console/core/src/model.ts
index ae636c4f3..48d7e16c5 100644
--- a/packages/console/core/src/model.ts
+++ b/packages/console/core/src/model.ts
@@ -40,13 +40,14 @@ export namespace ZenModel {
export namespace Model {
export const enable = fn(z.object({ model: z.string() }), ({ model }) => {
- const workspaceID = Actor.workspace()
+ Actor.assertAdmin()
return Database.use((db) =>
- db.delete(ModelTable).where(and(eq(ModelTable.workspaceID, workspaceID), eq(ModelTable.model, model))),
+ db.delete(ModelTable).where(and(eq(ModelTable.workspaceID, Actor.workspace()), eq(ModelTable.model, model))),
)
})
export const disable = fn(z.object({ model: z.string() }), ({ model }) => {
+ Actor.assertAdmin()
return Database.use((db) =>
db
.insert(ModelTable)
diff --git a/packages/console/core/src/provider.ts b/packages/console/core/src/provider.ts
index 1f8c07b9f..cf2040b59 100644
--- a/packages/console/core/src/provider.ts
+++ b/packages/console/core/src/provider.ts
@@ -20,8 +20,9 @@ export namespace Provider {
provider: z.string().min(1).max(64),
credentials: z.string(),
}),
- ({ provider, credentials }) =>
- Database.use((tx) =>
+ async ({ provider, credentials }) => {
+ Actor.assertAdmin()
+ return Database.use((tx) =>
tx
.insert(ProviderTable)
.values({
@@ -36,14 +37,21 @@ export namespace Provider {
timeDeleted: null,
},
}),
- ),
+ )
+ },
)
- export const remove = fn(z.object({ provider: z.string() }), ({ provider }) =>
- Database.transaction((tx) =>
- tx
- .delete(ProviderTable)
- .where(and(eq(ProviderTable.provider, provider), eq(ProviderTable.workspaceID, Actor.workspace()))),
- ),
+ export const remove = fn(
+ z.object({
+ provider: z.string(),
+ }),
+ async ({ provider }) => {
+ Actor.assertAdmin()
+ return Database.transaction((tx) =>
+ tx
+ .delete(ProviderTable)
+ .where(and(eq(ProviderTable.provider, provider), eq(ProviderTable.workspaceID, Actor.workspace()))),
+ )
+ },
)
}
diff --git a/packages/console/core/src/user.ts b/packages/console/core/src/user.ts
index 38c8e5e3a..40d74f93d 100644
--- a/packages/console/core/src/user.ts
+++ b/packages/console/core/src/user.ts
@@ -11,13 +11,9 @@ import { Account } from "./account"
import { AccountTable } from "./schema/account.sql"
import { Key } from "./key"
import { KeyTable } from "./schema/key.sql"
+import { WorkspaceTable } from "./schema/workspace.sql"
export namespace User {
- const assertAdmin = () => {
- if (Actor.userRole() === "admin") return
- throw new Error(`Expected admin user, got ${Actor.userRole()}`)
- }
-
const assertNotSelf = (id: string) => {
if (Actor.userID() !== id) return
throw new Error(`Expected not self actor, got self actor`)
@@ -63,9 +59,10 @@ export namespace User {
z.object({
email: z.string(),
role: z.enum(UserRole),
+ monthlyLimit: z.number().nullable().optional(),
}),
- async ({ email, role }) => {
- assertAdmin()
+ async ({ email, role, monthlyLimit }) => {
+ Actor.assertAdmin()
const workspaceID = Actor.workspace()
// create user
@@ -85,10 +82,12 @@ export namespace User {
}),
workspaceID,
role,
+ monthlyLimit,
})
.onDuplicateKeyUpdate({
set: {
role,
+ monthlyLimit,
timeDeleted: null,
},
}),
@@ -117,6 +116,21 @@ export namespace User {
// send email, ignore errors
try {
+ const emailInfo = await Database.use((tx) =>
+ tx
+ .select({
+ email: AccountTable.email,
+ workspaceName: WorkspaceTable.name,
+ })
+ .from(UserTable)
+ .innerJoin(AccountTable, eq(UserTable.accountID, AccountTable.id))
+ .innerJoin(WorkspaceTable, eq(WorkspaceTable.id, workspaceID))
+ .where(
+ and(eq(UserTable.workspaceID, workspaceID), eq(UserTable.id, Actor.assert("user").properties.userID)),
+ )
+ .then((rows) => rows[0]),
+ )
+
const { InviteEmail } = await import("@opencode-ai/console-mail/InviteEmail.jsx")
await AWS.sendEmail({
to: email,
@@ -124,8 +138,10 @@ export namespace User {
body: render(
// @ts-ignore
InviteEmail({
+ inviter: emailInfo.email,
assetsUrl: `https://opencode.ai/email`,
- workspace: workspaceID,
+ workspaceID: workspaceID,
+ workspaceName: emailInfo.workspaceName,
}),
),
})
@@ -176,7 +192,7 @@ export namespace User {
monthlyLimit: z.number().nullable(),
}),
async ({ id, role, monthlyLimit }) => {
- assertAdmin()
+ Actor.assertAdmin()
if (role === "member") assertNotSelf(id)
return await Database.use((tx) =>
tx
@@ -188,7 +204,7 @@ export namespace User {
)
export const remove = fn(z.string(), async (id) => {
- assertAdmin()
+ Actor.assertAdmin()
assertNotSelf(id)
return await Database.use((tx) =>
diff --git a/packages/console/core/src/workspace.ts b/packages/console/core/src/workspace.ts
index 7a742e896..655112ae2 100644
--- a/packages/console/core/src/workspace.ts
+++ b/packages/console/core/src/workspace.ts
@@ -52,6 +52,7 @@ export namespace Workspace {
name: z.string().min(1).max(255),
}),
async ({ name }) => {
+ Actor.assertAdmin()
const workspaceID = Actor.workspace()
return await Database.use((tx) =>
tx