diff --git a/src/client/api/model/website.ts b/src/client/api/model/website.ts
index 9b22395..94a797c 100644
--- a/src/client/api/model/website.ts
+++ b/src/client/api/model/website.ts
@@ -53,6 +53,15 @@ export async function updateWorkspaceWebsiteInfo(
queryClient.resetQueries(['websites', workspaceId]);
}
+export async function deleteWorkspaceWebsite(
+ workspaceId: string,
+ websiteId: string
+) {
+ await request.delete(`/api/workspace/${workspaceId}/website/${websiteId}`);
+
+ queryClient.resetQueries(['websites', workspaceId]);
+}
+
export function useWorspaceWebsites(workspaceId: string) {
const { data: websites = [], isLoading } = useQuery(
['websites', workspaceId],
diff --git a/src/client/api/request.ts b/src/client/api/request.ts
index 38e58bf..9d809f8 100644
--- a/src/client/api/request.ts
+++ b/src/client/api/request.ts
@@ -9,10 +9,7 @@ function createRequest() {
const ins = axios.create();
ins.interceptors.request.use(async (val) => {
- if (
- ['post', 'get'].includes(String(val.method).toLowerCase()) &&
- !val.headers.Authorization
- ) {
+ if (!val.headers.Authorization) {
val.headers.Authorization = `Bearer ${getJWT()}`;
}
diff --git a/src/client/components/WebsiteInfo.tsx b/src/client/components/WebsiteInfo.tsx
index 465b927..25a2a88 100644
--- a/src/client/components/WebsiteInfo.tsx
+++ b/src/client/components/WebsiteInfo.tsx
@@ -1,7 +1,8 @@
-import { Button, Form, Input, message } from 'antd';
+import { Button, Form, Input, message, Popconfirm, Tabs } from 'antd';
import React from 'react';
-import { useParams } from 'react-router';
+import { useNavigate, useParams } from 'react-router';
import {
+ deleteWorkspaceWebsite,
updateWorkspaceWebsiteInfo,
useWorkspaceWebsiteInfo,
} from '../api/model/website';
@@ -20,6 +21,7 @@ export const WebsiteInfo: React.FC = React.memo(() => {
currentWorkspaceId!,
websiteId!
);
+ const navigate = useNavigate();
const [, handleSave] = useRequest(
async (values: { name: string; domain: string }) => {
@@ -32,6 +34,14 @@ export const WebsiteInfo: React.FC = React.memo(() => {
}
);
+ const [, handleDeleteWebsite] = useRequest(async () => {
+ await deleteWorkspaceWebsite(currentWorkspaceId!, websiteId!);
+
+ message.success('Delete Success');
+
+ navigate('/settings/websites');
+ });
+
if (!currentWorkspaceId) {
return ;
}
@@ -55,31 +65,50 @@ export const WebsiteInfo: React.FC = React.memo(() => {
);
diff --git a/src/client/pages/Settings.tsx b/src/client/pages/Settings.tsx
index 3f955df..abc9b4a 100644
--- a/src/client/pages/Settings.tsx
+++ b/src/client/pages/Settings.tsx
@@ -34,7 +34,6 @@ export const Settings: React.FC = React.memo(() => {
mode="vertical"
items={items}
/>
- {pathname}
diff --git a/src/server/middleware/workspace.ts b/src/server/middleware/workspace.ts
index 79bc259..0375e78 100644
--- a/src/server/middleware/workspace.ts
+++ b/src/server/middleware/workspace.ts
@@ -1,7 +1,7 @@
import { Handler } from 'express';
-import { checkIsWorkspaceUser } from '../model/workspace';
+import { getWorkspaceUser } from '../model/workspace';
-export function workspacePermission(): Handler {
+export function workspacePermission(roles: string[] = []): Handler {
return async (req, res, next) => {
const workspaceId =
req.body.workspaceId ?? req.query.workspaceId ?? req.params.workspaceId;
@@ -16,12 +16,20 @@ export function workspacePermission(): Handler {
throw new Error('This middleware should be use after auth()');
}
- const isWorkspaceUser = await checkIsWorkspaceUser(workspaceId, userId);
+ const info = await getWorkspaceUser(workspaceId, userId);
- if (!isWorkspaceUser) {
+ if (!info) {
throw new Error('Is not workspace user');
}
+ if (Array.isArray(roles) && roles.length > 0) {
+ if (!roles.includes(info.role)) {
+ throw new Error(
+ `Workspace roles not has this permission, need ${roles}`
+ );
+ }
+ }
+
next();
};
}
diff --git a/src/server/model/workspace.ts b/src/server/model/workspace.ts
index 509d3e4..8b3e4a6 100644
--- a/src/server/model/workspace.ts
+++ b/src/server/model/workspace.ts
@@ -1,21 +1,23 @@
import { prisma } from './_client';
+export async function getWorkspaceUser(workspaceId: string, userId: string) {
+ const info = await prisma.workspacesOnUsers.findFirst({
+ where: {
+ workspaceId,
+ userId,
+ },
+ });
+
+ return info;
+}
+
export async function checkIsWorkspaceUser(
workspaceId: string,
userId: string
) {
- const workspace = await prisma.workspace.findUnique({
- where: {
- id: workspaceId,
- users: {
- some: {
- userId,
- },
- },
- },
- });
+ const info = await getWorkspaceUser(workspaceId, userId);
- if (workspace) {
+ if (info) {
return true;
} else {
return false;
@@ -84,3 +86,17 @@ export async function addWorkspaceWebsite(
return website;
}
+
+export async function deleteWorkspaceWebsite(
+ workspaceId: string,
+ websiteId: string
+) {
+ const website = await prisma.website.delete({
+ where: {
+ id: websiteId,
+ workspaceId,
+ },
+ });
+
+ return website;
+}
diff --git a/src/server/router/workspace.ts b/src/server/router/workspace.ts
index c462b58..6374eb2 100644
--- a/src/server/router/workspace.ts
+++ b/src/server/router/workspace.ts
@@ -4,10 +4,12 @@ import { body, param, query, validate } from '../middleware/validate';
import { workspacePermission } from '../middleware/workspace';
import {
addWorkspaceWebsite,
+ deleteWorkspaceWebsite,
getWorkspaceWebsiteInfo,
getWorkspaceWebsites,
updateWorkspaceWebsiteInfo,
} from '../model/workspace';
+import { ROLES } from '../utils/const';
export const workspaceRouter = Router();
@@ -128,3 +130,29 @@ workspaceRouter.post(
res.json({ website });
}
);
+
+workspaceRouter.delete(
+ '/:workspaceId/website/:websiteId',
+ validate(
+ param('workspaceId')
+ .isString()
+ .withMessage('workspaceId should be string')
+ .isUUID()
+ .withMessage('workspaceId should be UUID'),
+ param('websiteId')
+ .isString()
+ .withMessage('workspaceId should be string')
+ .isUUID()
+ .withMessage('workspaceId should be UUID')
+ ),
+ auth(),
+ workspacePermission([ROLES.owner]),
+ async (req, res) => {
+ const workspaceId = req.params.workspaceId;
+ const websiteId = req.params.websiteId;
+
+ const website = await deleteWorkspaceWebsite(workspaceId, websiteId);
+
+ res.json({ website });
+ }
+);