feat(console): unblock workspace by account email
This commit is contained in:
@@ -4,7 +4,10 @@ import { safeEqual } from "@opencode-ai/console-core/util/crypto.js"
|
||||
import { Resource } from "@opencode-ai/console-resource"
|
||||
import z from "zod"
|
||||
|
||||
const Body = z.object({ workspaceID: z.string().startsWith("wrk_") })
|
||||
const Body = z.union([
|
||||
z.object({ workspaceID: z.string().startsWith("wrk_") }),
|
||||
z.object({ email: z.email().transform((email) => email.trim().toLowerCase()) }),
|
||||
])
|
||||
|
||||
export async function POST(event: APIEvent) {
|
||||
if (!safeEqual(event.request.headers.get("authorization") ?? "", `Bearer ${Resource.SUPPORT_API_KEY.value}`)) {
|
||||
@@ -15,7 +18,7 @@ export async function POST(event: APIEvent) {
|
||||
if (!body.success) {
|
||||
return Response.json({ error: "Invalid request", issues: body.error.issues }, { status: 400 })
|
||||
}
|
||||
return Workspace.unblock(body.data.workspaceID)
|
||||
.then(() => Response.json({ success: true, message: "Workspace unblocked" }))
|
||||
return Workspace.unblock(body.data)
|
||||
.then((workspaceIDs) => Response.json({ success: true, message: "Workspace unblocked", workspaceIDs }))
|
||||
.catch((error) => Response.json({ error: error instanceof Error ? error.message : String(error) }, { status: 400 }))
|
||||
}
|
||||
|
||||
@@ -7,8 +7,9 @@ import { UserTable } from "./schema/user.sql"
|
||||
import { BillingTable } from "./schema/billing.sql"
|
||||
import { WorkspaceTable } from "./schema/workspace.sql"
|
||||
import { AccountTable } from "./schema/account.sql"
|
||||
import { AuthTable } from "./schema/auth.sql"
|
||||
import { Key } from "./key"
|
||||
import { and, eq, isNull, sql } from "drizzle-orm"
|
||||
import { and, eq, inArray, isNull, sql } from "drizzle-orm"
|
||||
|
||||
export namespace Workspace {
|
||||
export const Region = z.enum(["us", "eu", "sg", "cn"])
|
||||
@@ -104,15 +105,43 @@ export namespace Workspace {
|
||||
)
|
||||
})
|
||||
|
||||
export const unblock = fn(z.string().startsWith("wrk_"), async (workspaceID) => {
|
||||
await Database.transaction(async (tx) => {
|
||||
const workspace = await tx
|
||||
.select({ id: WorkspaceTable.id })
|
||||
.from(WorkspaceTable)
|
||||
.where(eq(WorkspaceTable.id, workspaceID))
|
||||
.then((rows) => rows[0])
|
||||
if (!workspace) throw new Error("Workspace not found")
|
||||
await tx.update(WorkspaceTable).set({ is_blocked: false }).where(eq(WorkspaceTable.id, workspaceID))
|
||||
})
|
||||
})
|
||||
export const unblock = fn(
|
||||
z.union([
|
||||
z.object({ workspaceID: z.string().startsWith("wrk_") }),
|
||||
z.object({ email: z.email() }),
|
||||
]),
|
||||
async (input) => {
|
||||
return Database.transaction(async (tx) => {
|
||||
const workspaces = "workspaceID" in input
|
||||
? await tx
|
||||
.select({ id: WorkspaceTable.id })
|
||||
.from(WorkspaceTable)
|
||||
.where(and(eq(WorkspaceTable.id, input.workspaceID), isNull(WorkspaceTable.timeDeleted)))
|
||||
: await tx
|
||||
.selectDistinct({ id: WorkspaceTable.id })
|
||||
.from(WorkspaceTable)
|
||||
.innerJoin(
|
||||
UserTable,
|
||||
and(eq(UserTable.workspaceID, WorkspaceTable.id), isNull(UserTable.timeDeleted)),
|
||||
)
|
||||
.innerJoin(
|
||||
AuthTable,
|
||||
and(
|
||||
eq(AuthTable.accountID, UserTable.accountID),
|
||||
eq(AuthTable.provider, "email"),
|
||||
eq(AuthTable.subject, input.email.toLowerCase()),
|
||||
isNull(AuthTable.timeDeleted),
|
||||
),
|
||||
)
|
||||
.where(isNull(WorkspaceTable.timeDeleted))
|
||||
if (workspaces.length === 0) throw new Error("Workspace not found")
|
||||
if (!("workspaceID" in input) && workspaces.length > 1) {
|
||||
throw new Error("Email is associated with multiple workspaces; use workspaceID")
|
||||
}
|
||||
const workspaceIDs = workspaces.map((workspace) => workspace.id)
|
||||
await tx.update(WorkspaceTable).set({ is_blocked: false }).where(inArray(WorkspaceTable.id, workspaceIDs))
|
||||
return workspaceIDs
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user