From b44816ff0cac19001b03d8409770e0221def3c03 Mon Sep 17 00:00:00 2001 From: jingyang <3161362058@qq.com> Date: Mon, 16 Oct 2023 15:21:24 +0800 Subject: [PATCH] feat license page Signed-off-by: jingyang <3161362058@qq.com> --- service/license/.env.template | 27 +++ service/license/public/images/background.svg | 178 ++++++++++++++++++ .../license/src/components/icons/LockIcon.tsx | 5 +- .../src/components/icons/PersonIcon.tsx | 8 + .../src/components/icons/SafetyIcon.tsx | 9 + service/license/src/components/icons/index.ts | 2 + .../components/signin/auth/usePassword.tsx | 6 +- .../src/components/signin/auth/useSms.tsx | 3 +- .../license/src/components/signin/index.tsx | 1 - service/license/src/pages/404.tsx | 6 +- .../src/pages/api/auth/namespace/abdicate.ts | 76 -------- .../src/pages/api/auth/namespace/create.ts | 80 -------- .../src/pages/api/auth/namespace/delete.ts | 65 ------- .../src/pages/api/auth/namespace/details.ts | 53 ------ .../src/pages/api/auth/namespace/invite.ts | 60 ------ .../src/pages/api/auth/namespace/list.ts | 39 ---- .../pages/api/auth/namespace/modifyRole.ts | 68 ------- .../src/pages/api/auth/namespace/recive.ts | 32 ---- .../pages/api/auth/namespace/removeUser.ts | 86 --------- .../src/pages/api/auth/namespace/switch.ts | 53 ------ .../pages/api/auth/namespace/verifyInvite.ts | 56 ------ .../license/src/pages/api/license/result.ts | 56 +++--- .../license/src/pages/api/platform/getEnv.ts | 49 +++++ .../license/components/CurrencySymbol.tsx | 2 +- .../src/pages/license/components/Recharge.tsx | 26 +-- service/license/src/pages/license/index.tsx | 24 +-- service/license/src/services/backend/auth.ts | 41 ++-- .../license/src/services/backend/db/user.ts | 1 + service/license/src/stores/session.ts | 1 - service/license/src/types/session.ts | 2 + service/license/src/types/user.ts | 8 +- service/license/src/utils/ProcessManager.ts | 61 ------ service/license/src/utils/crypto.ts | 2 + service/license/src/utils/tools.ts | 19 -- 34 files changed, 363 insertions(+), 842 deletions(-) create mode 100644 service/license/.env.template create mode 100644 service/license/public/images/background.svg create mode 100644 service/license/src/components/icons/PersonIcon.tsx create mode 100644 service/license/src/components/icons/SafetyIcon.tsx delete mode 100644 service/license/src/pages/api/auth/namespace/abdicate.ts delete mode 100644 service/license/src/pages/api/auth/namespace/create.ts delete mode 100644 service/license/src/pages/api/auth/namespace/delete.ts delete mode 100644 service/license/src/pages/api/auth/namespace/details.ts delete mode 100644 service/license/src/pages/api/auth/namespace/invite.ts delete mode 100644 service/license/src/pages/api/auth/namespace/list.ts delete mode 100644 service/license/src/pages/api/auth/namespace/modifyRole.ts delete mode 100644 service/license/src/pages/api/auth/namespace/recive.ts delete mode 100644 service/license/src/pages/api/auth/namespace/removeUser.ts delete mode 100644 service/license/src/pages/api/auth/namespace/switch.ts delete mode 100644 service/license/src/pages/api/auth/namespace/verifyInvite.ts create mode 100644 service/license/src/pages/api/platform/getEnv.ts delete mode 100644 service/license/src/utils/ProcessManager.ts diff --git a/service/license/.env.template b/service/license/.env.template new file mode 100644 index 00000000000..53db89856ce --- /dev/null +++ b/service/license/.env.template @@ -0,0 +1,27 @@ +PUBLIC_URL=. +NEXT_PUBLIC_SERVICE=/service/ +SEALOS_CLOUD_DOMAIN="cloud.sealos.io" + +# GITHUB_CLIENT_ID= +# GITHUB_CLIENT_SECRET= +# WECHAT_CLIENT_ID= +# WECHAT_CLIENT_SECRET= +# KUBECONFIG= +# MONGODB_URI= +# JWT_SECRET= +# ALI_ACCESS_KEY_ID= +# ALI_ACCESS_KEY_SECRET= +# ALI_TEMPLATE_CODE= +# ALI_SIGN_NAME= +# PRIVATE_PROTOCOL= +# SERVICE_PROTOCOL= +# CALLBACK_URL= +# PASSWORD_SALT= +# WECHAT_ENABLED= +# GITHUB_ENABLED= +# PASSWORD_ENABLED= +# SMS_ENABLED= + +# costcenter +STRIPE_ENABLED= +STRIPE_PUB= \ No newline at end of file diff --git a/service/license/public/images/background.svg b/service/license/public/images/background.svg new file mode 100644 index 00000000000..8b3de7be43f --- /dev/null +++ b/service/license/public/images/background.svg @@ -0,0 +1,178 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/service/license/src/components/icons/LockIcon.tsx b/service/license/src/components/icons/LockIcon.tsx index 5ec13d4969a..916ca11ba85 100644 --- a/service/license/src/components/icons/LockIcon.tsx +++ b/service/license/src/components/icons/LockIcon.tsx @@ -2,10 +2,7 @@ import { Icon, IconProps } from '@chakra-ui/react'; export const LocklIcon = (props: IconProps) => { return ( - + ); }; diff --git a/service/license/src/components/icons/PersonIcon.tsx b/service/license/src/components/icons/PersonIcon.tsx new file mode 100644 index 00000000000..c6e9b19e089 --- /dev/null +++ b/service/license/src/components/icons/PersonIcon.tsx @@ -0,0 +1,8 @@ +import { Icon, IconProps } from '@chakra-ui/react'; +export const PersonIcon = (props: IconProps) => { + return ( + + + + ); +}; diff --git a/service/license/src/components/icons/SafetyIcon.tsx b/service/license/src/components/icons/SafetyIcon.tsx new file mode 100644 index 00000000000..7d1fd36795e --- /dev/null +++ b/service/license/src/components/icons/SafetyIcon.tsx @@ -0,0 +1,9 @@ +import { Icon, IconProps } from '@chakra-ui/react'; +export const SafetyIcon = (props: IconProps) => { + return ( + + + + + ); +}; diff --git a/service/license/src/components/icons/index.ts b/service/license/src/components/icons/index.ts index 1166d65305d..097016ef2ba 100644 --- a/service/license/src/components/icons/index.ts +++ b/service/license/src/components/icons/index.ts @@ -15,3 +15,5 @@ export * from './WechatIcon'; export * from './WarningIcon'; export * from './CloseIcon'; export * from './LockIcon'; +export * from './SafetyIcon'; +export * from './PersonIcon'; diff --git a/service/license/src/components/signin/auth/usePassword.tsx b/service/license/src/components/signin/auth/usePassword.tsx index 7fbbba4fc2f..60657034e95 100644 --- a/service/license/src/components/signin/auth/usePassword.tsx +++ b/service/license/src/components/signin/auth/usePassword.tsx @@ -5,7 +5,7 @@ import { TUserExist } from '@/types/user'; import { Flex, Image, Img, Input, InputGroup, InputLeftAddon, Text } from '@chakra-ui/react'; import { useTranslation } from 'next-i18next'; import { useRouter } from 'next/router'; -import { LocklIcon } from '@/components/icons'; +import { LocklIcon, PersonIcon } from '@/components/icons'; import { useState } from 'react'; import { useForm } from 'react-hook-form'; @@ -113,7 +113,7 @@ export default function usePassword({ border="1px solid #E5E5E5" > - person setUserExist(true)} /> + - person + - safety + request>('/api/platform/getEnv') ); - console.log('123'); const { service_protocol = '', diff --git a/service/license/src/pages/404.tsx b/service/license/src/pages/404.tsx index 701f2b365af..07e8393085a 100644 --- a/service/license/src/pages/404.tsx +++ b/service/license/src/pages/404.tsx @@ -3,9 +3,9 @@ import { useRouter } from 'next/router'; const NonePage = () => { const router = useRouter(); - useEffect(() => { - router.push('/'); - }, [router]); + // useEffect(() => { + // router.push('/'); + // }, [router]); return
; }; diff --git a/service/license/src/pages/api/auth/namespace/abdicate.ts b/service/license/src/pages/api/auth/namespace/abdicate.ts deleted file mode 100644 index 9a64543ee36..00000000000 --- a/service/license/src/pages/api/auth/namespace/abdicate.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { authSession } from '@/services/backend/auth'; -import { changeOwnerBinding, queryUsersByNamespace } from '@/services/backend/db/userToNamespace'; -import { jsonRes } from '@/services/backend/response'; -import { modifyBinding, modifyTeamRole, unbindingRole } from '@/services/backend/team'; -import { InvitedStatus, NSType, UserRole } from '@/types/team'; -import { NextApiRequest, NextApiResponse } from 'next'; -export default async function handler(req: NextApiRequest, res: NextApiResponse) { - try { - const payload = await authSession(req.headers); - if (!payload) return jsonRes(res, { code: 401, message: 'token verify error' }); - const { ns_uid, targetUsername, targetUserId } = req.body as { - ns_uid?: string; - targetUserId?: string; - targetUsername?: string; - }; - if (!ns_uid) return jsonRes(res, { code: 400, message: 'ns_uid is required' }); - if (!targetUsername) return jsonRes(res, { code: 400, message: 'targetUsername is required' }); - if (!targetUserId) return jsonRes(res, { code: 400, message: 'targetUserId is required' }); - if (targetUserId === payload.user.uid) - return jsonRes(res, { code: 409, message: "the targetUserId can't be self" }); - // 校检自身user - const utns = await queryUsersByNamespace({ namespaceId: ns_uid }); - const ownUtn = utns.find((utn) => utn.userId === payload.user.uid); - if (!ownUtn) return jsonRes(res, { code: 404, message: 'you are not in namespace' }); - if (ownUtn) - if (ownUtn.role !== UserRole.Owner) - return jsonRes(res, { code: 403, message: 'you are not owner' }); - if (ownUtn.namespace.nstype === NSType.Private) - return jsonRes(res, { code: 403, message: "you can't abdicate private " }); - // 校检目标user - const targetUtn = utns.find( - (utn) => utn.userId === targetUserId && utn.k8s_username === targetUsername - ); - if (!targetUtn || targetUtn.status !== InvitedStatus.Accepted) - return jsonRes(res, { code: 404, message: 'the targetUser is not in namespace' }); - - await modifyTeamRole({ - action: 'Change', - pre_k8s_username: payload.user.k8s_username, - k8s_username: targetUsername, - userId: targetUserId, - role: UserRole.Owner, - namespace: ownUtn.namespace - }); - // 升级为 owner - // const bindResult = await modifyBinding({ - // k8s_username: targetUsername, - // namespaceId: ns_uid, - // role: UserRole.Owner, - // userId: targetUserId - // }); - // if (!bindResult) throw new Error('fail to binding role'); - // // 降级为 developer - // const unbindResult = await modifyBinding({ - // k8s_username: payload.user.k8s_username, - // role: UserRole.Developer, - // userId: payload.user.uid, - // namespaceId: ns_uid - // }); - // if (!unbindResult) throw new Error('fail to unbinding role'); - await changeOwnerBinding({ - userId: payload.user.uid, - k8s_username: payload.user.k8s_username, - namespaceId: ns_uid, - tUserId: targetUserId, - tK8sUsername: targetUsername - }); - jsonRes(res, { - code: 200, - message: 'Successfully' - }); - } catch (e) { - console.log(e); - jsonRes(res, { code: 500, message: 'adbication error' }); - } -} diff --git a/service/license/src/pages/api/auth/namespace/create.ts b/service/license/src/pages/api/auth/namespace/create.ts deleted file mode 100644 index 91e0fa1d829..00000000000 --- a/service/license/src/pages/api/auth/namespace/create.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { authSession } from '@/services/backend/auth'; -import { createNS } from '@/services/backend/db/namespace'; -import { get_k8s_username, queryUser } from '@/services/backend/db/user'; -import { queryNamespacesByUser } from '@/services/backend/db/userToNamespace'; -import { getTeamKubeconfig } from '@/services/backend/kubernetes/admin'; -import { GetUserDefaultNameSpace } from '@/services/backend/kubernetes/user'; -import { jsonRes } from '@/services/backend/response'; -import { bindingRole, modifyTeamRole } from '@/services/backend/team'; -import { NSType, NamespaceDto, UserRole } from '@/types/team'; -import { NextApiRequest, NextApiResponse } from 'next'; -const TEAM_LIMIT = 5; -export default async function handler(req: NextApiRequest, res: NextApiResponse) { - try { - const payload = await authSession(req.headers); - if (!payload) return jsonRes(res, { code: 401, message: 'token verify error' }); - const { user: tokenUser } = payload; - const { teamName } = req.body as { teamName?: string }; - if (!teamName) return jsonRes(res, { code: 400, message: 'teamName is required' }); - const currentNamespaces = await queryNamespacesByUser({ - userId: tokenUser.uid, - k8s_username: tokenUser.k8s_username - }); - if (currentNamespaces.length >= TEAM_LIMIT) - return jsonRes(res, { code: 403, message: 'The number of teams created is too many' }); - const alreadyNamespace = currentNamespaces.findIndex((utn) => { - const res = utn.namespace.teamName === teamName; - return res; - }); - if (alreadyNamespace > -1) - return jsonRes(res, { code: 409, message: 'The team is already exist' }); - const user = await queryUser({ id: tokenUser.uid, provider: 'uid' }); - if (!user) throw new Error('fail to get user'); - const ns_creater = await get_k8s_username(); - if (!ns_creater) throw new Error('fail to get ns_creater'); - const nsid = GetUserDefaultNameSpace(ns_creater); - // 创建伪user - const creater_kc_str = await getTeamKubeconfig(ns_creater, tokenUser.k8s_username); - if (!creater_kc_str) throw new Error('fail to get kubeconfig'); - const namespace = await createNS({ - namespace: nsid, - nstype: NSType.Team, - teamName - }); - if (!namespace) throw new Error(`failed to create namespace: ${nsid}`); - const k8s_username = tokenUser.k8s_username; - // 分配owner权限 - const utnResult = await bindingRole({ - userId: user.uid, - k8s_username, - ns_uid: namespace?.uid, - role: UserRole.Owner, - direct: true - }); - if (!utnResult) throw new Error(`fail to binding namesapce: ${nsid}`); - await modifyTeamRole({ - k8s_username, - userId: user.uid, - role: UserRole.Owner, - action: 'Create', - namespace - }); - jsonRes<{ namespace: NamespaceDto }>(res, { - code: 200, - message: 'Successfully', - data: { - namespace: { - role: UserRole.Owner, - createTime: namespace.createTime, - uid: namespace.uid, - id: namespace.id, - nstype: namespace.nstype, - teamName: namespace.teamName - } - } - }); - } catch (e) { - console.log(e); - jsonRes(res, { code: 500, message: 'failed to create team' }); - } -} diff --git a/service/license/src/pages/api/auth/namespace/delete.ts b/service/license/src/pages/api/auth/namespace/delete.ts deleted file mode 100644 index 7613db10883..00000000000 --- a/service/license/src/pages/api/auth/namespace/delete.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { authSession } from '@/services/backend/auth'; -import { queryNSByUid } from '@/services/backend/db/namespace'; -import { queryUser } from '@/services/backend/db/user'; -import { queryUTN, queryUsersByNamespace } from '@/services/backend/db/userToNamespace'; -import { setUserTeamDelete } from '@/services/backend/kubernetes/admin'; -import { jsonRes } from '@/services/backend/response'; -import { applyDeleteRequest, modifyTeamRole, unbindingRole } from '@/services/backend/team'; -import { NSType, UserRole } from '@/types/team'; -import { NextApiRequest, NextApiResponse } from 'next'; -export default async function handler(req: NextApiRequest, res: NextApiResponse) { - try { - const payload = await authSession(req.headers); - if (!payload) return jsonRes(res, { code: 401, message: 'token verify error' }); - const { user: tokenUser } = payload; - const { ns_uid } = req.body as { ns_uid?: string }; - if (!ns_uid) return jsonRes(res, { code: 400, message: 'ns_uid is required' }); - const user = await queryUser({ id: tokenUser.uid, provider: 'uid' }); - if (tokenUser.ns_uid === ns_uid) - return jsonRes(res, { - code: 403, - message: 'you can not delete the namespace which you are in' - }); - if (!user) - return jsonRes(res, { code: 404, message: `the user ${tokenUser.uid} is not found` }); - const utn = await queryUTN({ - userId: tokenUser.uid, - k8s_username: tokenUser.k8s_username, - namespaceId: ns_uid - }); - if (!utn) return jsonRes(res, { code: 404, message: 'you are not in the namespace' }); - if (utn.role !== UserRole.Owner) - return jsonRes(res, { code: 403, message: 'you are not owner' }); - const namespace = await queryNSByUid({ uid: ns_uid }); - if (!namespace) return jsonRes(res, { code: 404, message: 'fail to get ns' }); - if (namespace.nstype === NSType.Private) - return jsonRes(res, { code: 403, message: "this namespace can't be delete" }); - - const users = await queryUsersByNamespace({ namespaceId: ns_uid }); - if (!users) return jsonRes(res, { code: 404, message: 'fail to get users of ns' }); - const creator = namespace.id.replace('ns-', ''); - const res1 = await setUserTeamDelete(creator); - if (!res1) throw new Error('fail to update user '); - const res2 = await applyDeleteRequest(creator); - if (!res2) throw new Error('fail to delete namespace '); - const results = await Promise.all( - users.map(async ({ userId, k8s_username }) => { - // 保证每个用户都清掉 - const _result = await unbindingRole({ - userId, - k8s_username, - ns_uid: namespace.uid - }); - if (!_result) return false; - return true; - }) - ); - - if (!results.every((x) => x)) - return jsonRes(res, { code: 404, message: 'fail to remove users of ns' }); - jsonRes(res, { code: 200, message: 'Successfully' }); - } catch (e) { - console.log(e); - jsonRes(res, { code: 500, message: 'fail to remove ns' }); - } -} diff --git a/service/license/src/pages/api/auth/namespace/details.ts b/service/license/src/pages/api/auth/namespace/details.ts deleted file mode 100644 index 2e6cf0caa85..00000000000 --- a/service/license/src/pages/api/auth/namespace/details.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { authSession } from '@/services/backend/auth'; -import { queryUsersByNamespace } from '@/services/backend/db/userToNamespace'; -import { jsonRes } from '@/services/backend/response'; -import { NamespaceDto } from '@/types/team'; -import { TeamUserDto } from '@/types/user'; -import { NextApiRequest, NextApiResponse } from 'next'; -export default async function handler(req: NextApiRequest, res: NextApiResponse) { - try { - const payload = await authSession(req.headers); - if (!payload) return jsonRes(res, { code: 401, message: 'token verify error' }); - const { ns_uid } = req.body; - if (!ns_uid) return jsonRes(res, { code: 400, message: 'nsid is required' }); - const utnWithUser = await queryUsersByNamespace({ namespaceId: ns_uid }); - - if (utnWithUser.length <= 0) - return jsonRes(res, { code: 404, message: 'namespace not founded!' }); - - const rawNamespace = utnWithUser[0].namespace; - const selfUtn = utnWithUser.find( - (utn) => utn.userId === payload.user.uid && utn.k8s_username === payload.user.k8s_username - ); - if (!selfUtn) return jsonRes(res, { code: 404, message: 'You are not in the namespace' }); - const namespace: NamespaceDto = { - uid: rawNamespace.uid, - id: rawNamespace.id, - role: selfUtn.role, - createTime: rawNamespace.createTime, - teamName: rawNamespace.teamName, - nstype: rawNamespace.nstype - }; - const users = utnWithUser.map((x) => ({ - uid: x.userId, - k8s_username: x.k8s_username, - avatarUrl: x.user.avatar_url, - name: x.user.name, - createdTime: x.user.created_time, - joinTime: x.joinTime, - role: x.role, - status: x.status - })); - jsonRes(res, { - code: 200, - message: 'Successfully', - data: { - users, - namespace - } - }); - } catch (e) { - console.log(e); - jsonRes(res, { code: 500, message: 'query ns error' }); - } -} diff --git a/service/license/src/pages/api/auth/namespace/invite.ts b/service/license/src/pages/api/auth/namespace/invite.ts deleted file mode 100644 index da1c9c85e87..00000000000 --- a/service/license/src/pages/api/auth/namespace/invite.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { authSession } from '@/services/backend/auth'; -import { queryNSByUid } from '@/services/backend/db/namespace'; -import { queryUserByk8sUser } from '@/services/backend/db/user'; -import { queryUTN, queryUsersByNamespace } from '@/services/backend/db/userToNamespace'; -import { jsonRes } from '@/services/backend/response'; -import { bindingRole, checkCanManage } from '@/services/backend/team'; -import { INVITE_LIMIT } from '@/types/api'; -import { InvitedStatus, UserRole } from '@/types/team'; -import { isUserRole, vaildManage } from '@/utils/tools'; -import { NextApiRequest, NextApiResponse } from 'next'; -export default async function handler(req: NextApiRequest, res: NextApiResponse) { - try { - const payload = await authSession(req.headers); - if (!payload) return jsonRes(res, { code: 401, message: 'token verify error' }); - const { ns_uid, targetUsername, role } = req.body as { - ns_uid?: string; - targetUsername?: string; - role?: UserRole; - }; - if (!ns_uid) return jsonRes(res, { code: 400, message: 'ns_uid is required' }); - if (!targetUsername) return jsonRes(res, { code: 400, message: 'targetUsername is required' }); - if (!isUserRole(role)) return jsonRes(res, { code: 400, message: 'role is required' }); - if (role === UserRole.Owner) return jsonRes(res, { code: 403, message: 'role must be others' }); - if (targetUsername === payload.user.k8s_username) - return jsonRes(res, { code: 403, message: 'target user must be others' }); - const tUser = await queryUserByk8sUser(targetUsername); - if (!tUser) return jsonRes(res, { code: 404, message: 'user is not found' }); - const userUtns = await queryUsersByNamespace({ namespaceId: ns_uid }); - if (!userUtns) - return jsonRes(res, { code: 404, message: 'there are not user in the namespace ' }); - const userInInvit = userUtns.filter((v) => v.status === InvitedStatus.Inviting); - if (userInInvit.length >= INVITE_LIMIT) - return jsonRes(res, { code: 403, message: 'the invited users are too many' }); - const ownUtn = userUtns.find( - (x) => x.userId === payload.user.uid && x.k8s_username === payload.user.k8s_username - ); - if (!ownUtn) return jsonRes(res, { code: 403, message: 'you are not in the namespace' }); - const vaild = vaildManage(ownUtn.role, ownUtn.userId)(role, tUser.uid); - if (!vaild) return jsonRes(res, { code: 403, message: 'you are not manager' }); - const tUtn = userUtns.find( - (utn) => utn.k8s_username === targetUsername && tUser.uid === utn.userId - ); - if (tUtn) return jsonRes(res, { code: 403, message: 'target user is already invite' }); - const result = await bindingRole({ - k8s_username: targetUsername, - ns_uid, - role, - userId: tUser.uid, - managerId: ownUtn.userId - }); - if (!result) throw new Error('fail to binding role'); - jsonRes(res, { - code: 200, - message: 'Successfully' - }); - } catch (e) { - console.log(e); - jsonRes(res, { code: 500, message: 'invite member error' }); - } -} diff --git a/service/license/src/pages/api/auth/namespace/list.ts b/service/license/src/pages/api/auth/namespace/list.ts deleted file mode 100644 index 1d06cd11d3a..00000000000 --- a/service/license/src/pages/api/auth/namespace/list.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { authSession } from '@/services/backend/auth'; -import { queryNamespacesByUser } from '@/services/backend/db/userToNamespace'; -import { jsonRes } from '@/services/backend/response'; -import { InvitedStatus, NamespaceDto, UserRole } from '@/types/team'; -import { NextApiRequest, NextApiResponse } from 'next'; -export default async function handler(req: NextApiRequest, res: NextApiResponse) { - try { - const payload = await authSession(req.headers); - if (!payload) return jsonRes(res, { code: 401, message: 'token verify error' }); - const k8s_username = payload.user.k8s_username; - const ns = await queryNamespacesByUser({ userId: payload.user.uid, k8s_username }); - // 没接受应该不能查看消息 - const namespaces = ns - .filter( - (x) => - x.status === InvitedStatus.Accepted && - x.k8s_username === payload.user.k8s_username && - x.userId === payload.user.uid - ) - .map((x) => ({ - id: x.namespace.id, - uid: x.namespace.uid, - createTime: x.namespace.createTime, - nstype: x.namespace.nstype, - teamName: x.namespace.teamName, - role: x.role - })); - jsonRes(res, { - code: 200, - message: 'Successfully', - data: { - namespaces - } - }); - } catch (e) { - console.log(e); - jsonRes(res, { code: 500, message: 'list ns error' }); - } -} diff --git a/service/license/src/pages/api/auth/namespace/modifyRole.ts b/service/license/src/pages/api/auth/namespace/modifyRole.ts deleted file mode 100644 index 3b489f370a6..00000000000 --- a/service/license/src/pages/api/auth/namespace/modifyRole.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { authSession } from '@/services/backend/auth'; -import { queryUsersByNamespace, updateUTN } from '@/services/backend/db/userToNamespace'; -import { jsonRes } from '@/services/backend/response'; -import { modifyBinding, modifyTeamRole } from '@/services/backend/team'; -import { InvitedStatus, NSType, UserRole } from '@/types/team'; -import { isUserRole, vaildManage } from '@/utils/tools'; -import { NextApiRequest, NextApiResponse } from 'next'; -export default async function handler(req: NextApiRequest, res: NextApiResponse) { - try { - const payload = await authSession(req.headers); - if (!payload) return jsonRes(res, { code: 401, message: 'token verify error' }); - // - const { ns_uid, tUserId, tK8s_username, tRole } = req.body as { - ns_uid?: string; - tUserId?: string; - tK8s_username?: string; - tRole?: UserRole; - }; - if (!tUserId) return jsonRes(res, { code: 400, message: 'tUserId is required' }); - if (!tK8s_username) return jsonRes(res, { code: 400, message: 'tK8s_username is required' }); - if (!isUserRole(tRole)) return jsonRes(res, { code: 400, message: 'tRole is required' }); - if (!ns_uid) return jsonRes(res, { code: 400, message: 'ns_uid is required' }); - // 翻出utn - const utns = await queryUsersByNamespace({ namespaceId: ns_uid }); - const ownUtn = utns.find((utn) => utn.userId === payload.user.uid); - if (!ownUtn) return jsonRes(res, { code: 403, message: 'you are not in namespace' }); - if (ownUtn.namespace.nstype === NSType.Private) - return jsonRes(res, { code: 403, message: "you can't modify private" }); - // 校检目标user - const tUtn = utns.find((utn) => utn.userId === tUserId && utn.k8s_username === tK8s_username); - // 还没进入团队中 - if (!tUtn || tUtn.status !== InvitedStatus.Accepted) - return jsonRes(res, { code: 403, message: 'target user is not in namespace' }); - if (payload.user.k8s_username === tK8s_username && payload.user.uid === tUserId) - return jsonRes(res, { code: 403, message: 'target user is not self' }); - // 不在ns - if (!ownUtn) return jsonRes(res, { code: 403, message: 'you are not in namespace' }); - const vaildFn = vaildManage(ownUtn.role, ownUtn.userId); - if (!vaildFn(tUtn.role, tUtn.userId) || !vaildFn(ownUtn.role, tUtn.userId)) - return jsonRes(res, { code: 403, message: 'you are not manager' }); - - // 权限一致,不用管 - if (tUtn.role === tRole) return jsonRes(res, { code: 200, message: 'Successfully' }); - - await modifyTeamRole({ - k8s_username: tK8s_username, - role: tRole, - action: 'Modify', - namespace: { - id: tUtn.namespace.id - }, - userId: tUserId, - pre_role: tUtn.role - }); - const updateResult = await modifyBinding({ - ...tUtn, - role: tRole - }); - if (!updateResult) throw new Error('modify utn error'); - jsonRes(res, { - code: 200, - message: 'Successfully' - }); - } catch (e) { - console.log(e); - jsonRes(res, { code: 500, message: 'fail to remove team member' }); - } -} diff --git a/service/license/src/pages/api/auth/namespace/recive.ts b/service/license/src/pages/api/auth/namespace/recive.ts deleted file mode 100644 index d4134a5ae4b..00000000000 --- a/service/license/src/pages/api/auth/namespace/recive.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { authSession } from '@/services/backend/auth'; -import { queryMessage, queryNamespacesByUser } from '@/services/backend/db/userToNamespace'; -import { jsonRes } from '@/services/backend/response'; -import { InvitedStatus, teamMessageDto } from '@/types/team'; -import { NextApiRequest, NextApiResponse } from 'next'; -export default async function handler(req: NextApiRequest, res: NextApiResponse) { - try { - const payload = await authSession(req.headers); - if (!payload) return jsonRes(res, { code: 401, message: 'token verify error' }); - const k8s_username = payload.user.k8s_username; - const ns = await queryMessage({ userId: payload.user.uid, k8s_username }); - const messages = ns - .filter((x) => x.status === InvitedStatus.Inviting) - .map((x) => ({ - nsid: x.namespace.id, - ns_uid: x.namespace.uid, - teamName: x.namespace.teamName, - role: x.role, - managerName: x.manager.name - })); - jsonRes(res, { - code: 200, - message: 'Successfully', - data: { - messages - } - }); - } catch (e) { - console.log(e); - jsonRes(res, { code: 500, message: 'list reciveMessage error' }); - } -} diff --git a/service/license/src/pages/api/auth/namespace/removeUser.ts b/service/license/src/pages/api/auth/namespace/removeUser.ts deleted file mode 100644 index 92dfc84ea6f..00000000000 --- a/service/license/src/pages/api/auth/namespace/removeUser.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { authSession } from '@/services/backend/auth'; -import { queryNSByUid } from '@/services/backend/db/namespace'; -import { queryUser } from '@/services/backend/db/user'; -import { queryUTN } from '@/services/backend/db/userToNamespace'; -import { jsonRes } from '@/services/backend/response'; -import { checkCanManage, modifyTeamRole, unbindingRole } from '@/services/backend/team'; -import { InvitedStatus, UserRole } from '@/types/team'; -import { NextApiRequest, NextApiResponse } from 'next'; -export default async function handler(req: NextApiRequest, res: NextApiResponse) { - try { - const payload = await authSession(req.headers); - if (!payload) return jsonRes(res, { code: 401, message: 'token verify error' }); - // - const { ns_uid, tUserId, tK8s_username } = req.body as { - ns_uid?: string; - tUserId?: string; - tK8s_username?: string; - }; - const k8s_username = payload.user.k8s_username; - - if (!ns_uid) return jsonRes(res, { code: 400, message: 'ns_id is required' }); - if (!tUserId) return jsonRes(res, { code: 400, message: 'tUserId is required' }); - if (!tK8s_username) return jsonRes(res, { code: 400, message: 'tK8s_username is required' }); - - if (tUserId === payload.user.uid) { - return jsonRes(res, { code: 403, message: 'target user must be others' }); - } - const utn = await queryUTN({ - userId: tUserId, - k8s_username: tK8s_username, - namespaceId: ns_uid - }); - // 之前没绑上, - if (!utn) return jsonRes(res, { code: 404, message: 'target user is not in namespace' }); - const role = utn.role; - if ( - !checkCanManage({ - userId: payload.user.uid, - k8s_username, - namespaceId: ns_uid, - role, - tUserId - }) - ) - return jsonRes(res, { code: 403, message: 'you are not manager' }); - - const namespace = await queryNSByUid({ uid: ns_uid }); - if (!namespace) return jsonRes(res, { code: 404, message: 'namespace is not found' }); - let unbinding_result = null; - if (InvitedStatus.Inviting === utn.status) { - // 等于取消邀请 - unbinding_result = await unbindingRole({ - k8s_username: tK8s_username, - ns_uid: namespace.uid, - userId: tUserId - }); - } else if (InvitedStatus.Accepted === utn.status) { - // 删除权限 - - await modifyTeamRole({ - k8s_username: tK8s_username, - role, - action: 'Deprive', - namespace, - userId: tUserId, - pre_role: utn.role - }); - unbinding_result = await unbindingRole({ - k8s_username: tK8s_username, - userId: tUserId, - ns_uid: namespace.uid - }); - } - if (!unbinding_result) throw new Error('fail to remove team memeber role'); - jsonRes(res, { - code: 200, - message: 'Successfully', - data: { - unbinding_result - } - }); - } catch (e) { - console.log(e); - jsonRes(res, { code: 500, message: 'fail to remove team member' }); - } -} diff --git a/service/license/src/pages/api/auth/namespace/switch.ts b/service/license/src/pages/api/auth/namespace/switch.ts deleted file mode 100644 index 19131a0b145..00000000000 --- a/service/license/src/pages/api/auth/namespace/switch.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { authSession, generateJWT } from '@/services/backend/auth'; -import { queryUsersByNamespace } from '@/services/backend/db/userToNamespace'; -import { switchNamespace } from '@/services/backend/kubernetes/user'; -import { jsonRes } from '@/services/backend/response'; -import * as jsYaml from 'js-yaml'; -import { Session } from 'sealos-desktop-sdk'; -import { NextApiRequest, NextApiResponse } from 'next'; -export default async function handler(req: NextApiRequest, res: NextApiResponse) { - try { - const payload = await authSession(req.headers); - if (!payload) return jsonRes(res, { code: 401, message: 'token verify error' }); - const { ns_uid } = req.body; - if (!ns_uid) return jsonRes(res, { code: 400, message: 'ns_uid is required' }); - const nsUsers = await queryUsersByNamespace({ namespaceId: ns_uid }); - const userInNs = nsUsers.find( - (item) => item.userId === payload.user.uid && payload.user.k8s_username === item.k8s_username - ); // if ( - if (!userInNs) return jsonRes(res, { code: 403, message: 'you are not in this namespace' }); - const kubeconfig = jsYaml.dump( - JSON.parse(switchNamespace(payload.kc, userInNs?.namespace?.id || '').exportConfig()) - ); - const user = { - ns_uid: userInNs.namespaceId, - nsid: userInNs.namespace.id, - userId: payload.user.uid, - k8s_username: payload.user.k8s_username, - name: userInNs.user.name, - avatar: userInNs.user.avatar_url - }; - - const token = generateJWT({ - kubeconfig, - user: { - uid: user.userId, - k8s_username: user.k8s_username, - ns_uid: user.ns_uid, - nsid: user.nsid - } - }); - const data: Session = { - token, - user, - kubeconfig - }; - return jsonRes(res, { - data, - code: 200, - message: 'Successfully' - }); - } catch (e) { - jsonRes(res, { code: 500, message: 'fail to switch namespace' }); - } -} diff --git a/service/license/src/pages/api/auth/namespace/verifyInvite.ts b/service/license/src/pages/api/auth/namespace/verifyInvite.ts deleted file mode 100644 index 9801b96acbc..00000000000 --- a/service/license/src/pages/api/auth/namespace/verifyInvite.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { reciveAction } from '@/api/namespace'; -import { authSession } from '@/services/backend/auth'; -import { queryNSByUid } from '@/services/backend/db/namespace'; -import { queryUTN } from '@/services/backend/db/userToNamespace'; -import { jsonRes } from '@/services/backend/response'; -import { acceptInvite, modifyTeamRole, unbindingRole } from '@/services/backend/team'; - -import { NextApiRequest, NextApiResponse } from 'next'; -export default async function handler(req: NextApiRequest, res: NextApiResponse) { - try { - const payload = await authSession(req.headers); - if (!payload) return jsonRes(res, { code: 401, message: 'token verify error' }); - - const { k8s_username, uid } = payload.user; - const { ns_uid, action } = req.body as { ns_uid?: string; action: reciveAction }; - if (!ns_uid) return jsonRes(res, { code: 400, message: 'nsid is required' }); - if (![reciveAction.Accepte, reciveAction.Reject].includes(action)) - return jsonRes(res, { - code: 400, - message: `action must be ${reciveAction.Accepte}, ${reciveAction.Reject}` - }); - const namespace = await queryNSByUid({ uid: ns_uid }); - if (!namespace) return jsonRes(res, { code: 404, message: 'fail to get ns' }); - // 邀请状态这层, - // const user = await queryUser({ id: payload.user.uid, provider: 'uid' }); - // if (!user) return jsonRes(res, { code: 404, message: 'fail to get user' }); - const utn = await queryUTN({ userId: uid, k8s_username, namespaceId: ns_uid }); - if (!utn) return jsonRes(res, { code: 404, message: "you're not invited" }); - if (action === reciveAction.Accepte) { - await modifyTeamRole({ - k8s_username, - role: utn.role, - userId: uid, - namespace, - action: 'Grant' - }); - const result = await acceptInvite({ - k8s_username, - ns_uid, - userId: uid - }); - if (!result) throw new Error('failed to change Status'); - } else if (action === reciveAction.Reject) { - const unbindingResult = await unbindingRole({ k8s_username, ns_uid, userId: uid }); - if (!unbindingResult) throw new Error('fail to unbinding'); - } - - jsonRes(res, { - code: 200, - message: 'Successfully' - }); - } catch (e) { - console.log(e); - jsonRes(res, { code: 500, message: 'get price error' }); - } -} diff --git a/service/license/src/pages/api/license/result.ts b/service/license/src/pages/api/license/result.ts index a51198f2d9b..1bab777d5e8 100644 --- a/service/license/src/pages/api/license/result.ts +++ b/service/license/src/pages/api/license/result.ts @@ -1,32 +1,32 @@ -import { authSession } from '@/services/backend/auth'; -import { GetCRD } from '@/services/backend/kubernetes/user'; -import { jsonRes } from '@/services/backend/response'; -import type { NextApiRequest, NextApiResponse } from 'next'; +// import { authSession } from '@/services/backend/auth'; +// import { GetCRD } from '@/services/backend/kubernetes/user'; +// import { jsonRes } from '@/services/backend/response'; +// import type { NextApiRequest, NextApiResponse } from 'next'; -export default async function handler(req: NextApiRequest, resp: NextApiResponse) { - try { - const payload = await authSession(req.headers); - if (!payload) return jsonRes(resp, { code: 401, message: 'token verify error' }); +// export default async function handler(req: NextApiRequest, resp: NextApiResponse) { +// try { +// const payload = await authSession(req.headers); +// if (!payload) return jsonRes(resp, { code: 401, message: 'token verify error' }); - const { paymentName } = req.query as { - paymentName: string; - }; +// const { paymentName } = req.query as { +// paymentName: string; +// }; - if (typeof paymentName !== 'string' || paymentName === '') { - return jsonRes(resp, { code: 400, message: 'payment name cannot be empty' }); - } +// if (typeof paymentName !== 'string' || paymentName === '') { +// return jsonRes(resp, { code: 400, message: 'payment name cannot be empty' }); +// } - const paymentM = { - group: 'infostream.sealos.io', - version: 'v1', - namespace: payload.user.nsid, - plural: 'payments' - }; - const paymentDesc = await GetCRD(payload.kc, paymentM, paymentName); - console.log(paymentDesc?.body?.status, 'payment'); - return jsonRes(resp, { data: paymentDesc?.body?.status }); - } catch (error) { - console.log(error); - jsonRes(resp, { code: 500, data: error }); - } -} +// const paymentM = { +// group: 'infostream.sealos.io', +// version: 'v1', +// namespace: payload.user.nsid, +// plural: 'payments' +// }; +// const paymentDesc = await GetCRD(payload.kc, paymentM, paymentName); +// console.log(paymentDesc?.body?.status, 'payment'); +// return jsonRes(resp, { data: paymentDesc?.body?.status }); +// } catch (error) { +// console.log(error); +// jsonRes(resp, { code: 500, data: error }); +// } +// } diff --git a/service/license/src/pages/api/platform/getEnv.ts b/service/license/src/pages/api/platform/getEnv.ts new file mode 100644 index 00000000000..455c83e8e0f --- /dev/null +++ b/service/license/src/pages/api/platform/getEnv.ts @@ -0,0 +1,49 @@ +import type { NextApiRequest, NextApiResponse } from 'next'; +import { jsonRes } from '@/services/backend/response'; +import { + enableGithub, + enableWechat, + enablePassword, + enableSms, + enableGoogle, + enableStripe, + enableWechatRecharge, + enableLicense +} from '@/services/enable'; + +export default async function handler(req: NextApiRequest, res: NextApiResponse) { + const wechat_client_id = process.env.WECHAT_CLIENT_ID || ''; + const github_client_id = process.env.GITHUB_CLIENT_ID || ''; + const google_client_id = process.env.GOOGLE_CLIENT_ID || ''; + const service_protocol = process.env.SERVICE_PROTOCOL || ''; + const private_protocol = process.env.PRIVATE_PROTOCOL || ''; + const needGithub = enableGithub(); + const needWechat = enableWechat(); + const needPassword = enablePassword(); + const needSms = enableSms(); + const needGoogle = enableGoogle(); + const callback_url = process.env.CALLBACK_URL; + const stripeEnabled = enableStripe(); + const wechatEnabledRecharge = enableWechatRecharge(); + const licenseEnabled = enableLicense(); + + jsonRes(res, { + data: { + SEALOS_CLOUD_DOMAIN: process.env.SEALOS_CLOUD_DOMAIN || 'cloud.sealos.io', + wechat_client_id, + github_client_id, + google_client_id, + callback_url, + service_protocol, + private_protocol, + needPassword, + needSms, + needGithub, + needWechat, + needGoogle, + stripeEnabled, + wechatEnabledRecharge, + licenseEnabled + } + }); +} diff --git a/service/license/src/pages/license/components/CurrencySymbol.tsx b/service/license/src/pages/license/components/CurrencySymbol.tsx index 3c934b6382c..2c6c5e5b8d7 100644 --- a/service/license/src/pages/license/components/CurrencySymbol.tsx +++ b/service/license/src/pages/license/components/CurrencySymbol.tsx @@ -1,4 +1,4 @@ -import { Text, Icon } from '@chakra-ui/react'; +import { Text, Icon, IconProps } from '@chakra-ui/react'; export default function currencysymbol({ type = 'shellCoin', ...props diff --git a/service/license/src/pages/license/components/Recharge.tsx b/service/license/src/pages/license/components/Recharge.tsx index 8a7832e13c3..631d2763aa5 100644 --- a/service/license/src/pages/license/components/Recharge.tsx +++ b/service/license/src/pages/license/components/Recharge.tsx @@ -40,19 +40,19 @@ export default function RechargeComponent() { const [hid, setHid] = useState(''); // license key // handle hid - useEffect(() => { - if (query?.hid && typeof query.hid === 'string') { - const decodedHid = decodeURIComponent(query.hid); - setHid(decodedHid); - } else { - toast({ - status: 'error', - title: 'Purchase Link Error', - isClosable: true, - position: 'top' - }); - } - }, []); + // useEffect(() => { + // if (query?.hid && typeof query.hid === 'string') { + // const decodedHid = decodeURIComponent(query.hid); + // setHid(decodedHid); + // } else { + // toast({ + // status: 'error', + // title: 'Purchase Link Error', + // isClosable: true, + // position: 'top' + // }); + // } + // }, []); const onModalClose = () => { setComplete(0); diff --git a/service/license/src/pages/license/index.tsx b/service/license/src/pages/license/index.tsx index 039a6c03269..3cc1737e797 100644 --- a/service/license/src/pages/license/index.tsx +++ b/service/license/src/pages/license/index.tsx @@ -14,18 +14,18 @@ export default function LicensePage() { const router = useRouter(); const goHome = () => router.replace('/'); - const { data: platformEnv } = useQuery( - ['getPlatformEnv'], - () => request>('/api/platform/getEnv'), - { - onSuccess(data) { - console.log(data.data?.licenseEnabled, 'licenseEnabled'); - if (!data.data?.licenseEnabled) { - goHome(); - } - } - } - ); + // const { data: platformEnv } = useQuery( + // ['getPlatformEnv'], + // () => request>('/api/platform/getEnv'), + // { + // onSuccess(data) { + // console.log(data.data?.licenseEnabled, 'licenseEnabled'); + // if (!data.data?.licenseEnabled) { + // goHome(); + // } + // } + // } + // ); return ( diff --git a/service/license/src/services/backend/auth.ts b/service/license/src/services/backend/auth.ts index a833aa6f5da..e5248badd08 100644 --- a/service/license/src/services/backend/auth.ts +++ b/service/license/src/services/backend/auth.ts @@ -6,31 +6,32 @@ const jwtSecret = (process.env.JWT_SECRET as string) || '123456789'; export const authSession = async (header: IncomingHttpHeaders) => { try { - if (!header?.authorization) { - throw new Error('缺少凭证'); - } - const token = decodeURIComponent(header.authorization); - const payload = await verifyJWT(token); - if ( - !payload || - !payload.kubeconfig || - !payload?.user?.uid || - !payload?.user?.nsid || - !payload?.user?.ns_uid || - !payload?.user?.k8s_username - ) - throw new Error('token is null'); + // if (!header?.authorization) { + // throw new Error('缺少凭证'); + // } + // const token = decodeURIComponent(header.authorization); + // const payload = await verifyJWT(token); + // if ( + // !payload || + // !payload.kubeconfig || + // !payload?.user?.uid || + // !payload?.user?.nsid || + // !payload?.user?.ns_uid || + // !payload?.user?.k8s_username + // ) + // throw new Error('token is null'); // console.log('jwt:', payload.kubeconfig) - const kc = K8sApi(payload.kubeconfig); - const username = kc.getCurrentUser()?.name; - const user = payload.user; - if (!username || user.k8s_username !== username) throw new Error('user is invaild'); - return Promise.resolve({ kc, user }); + // const kc = K8sApi(payload.kubeconfig); + // const username = kc.getCurrentUser()?.name; + // const user = payload.user; + // if (!username || user.k8s_username !== username) throw new Error('user is invaild'); + // return Promise.resolve({ kc, user }); } catch (err) { - console.error(err); + console.error(err, '==='); return Promise.resolve(null); } }; + export const verifyJWT: (token: string) => Promise = (token: string) => new Promise((resolve) => { verify(token, jwtSecret, (err, payload) => { diff --git a/service/license/src/services/backend/db/user.ts b/service/license/src/services/backend/db/user.ts index 9052c5e7b32..722069bccfb 100644 --- a/service/license/src/services/backend/db/user.ts +++ b/service/license/src/services/backend/db/user.ts @@ -6,6 +6,7 @@ const LetterBytes = 'abcdefghijklmnopqrstuvwxyz0123456789'; const HostnameLength = 8; const nanoid = customAlphabet(LetterBytes, HostnameLength); + async function connectToUserCollection() { const client = await connectToDatabase(); const collection = client.db().collection('user'); diff --git a/service/license/src/stores/session.ts b/service/license/src/stores/session.ts index a75615f9eb2..28b87be50f5 100644 --- a/service/license/src/stores/session.ts +++ b/service/license/src/stores/session.ts @@ -13,7 +13,6 @@ type SessionState = { getSession: () => Session; delSession: () => void; isUserLogin: () => boolean; - // getKubeconfigToken: () => string; generateState: () => string; compareState: (state: string) => boolean; setProvider: (provider?: OauthProvider) => void; diff --git a/service/license/src/types/session.ts b/service/license/src/types/session.ts index e77e4b1e0ee..e8c3cd86477 100644 --- a/service/license/src/types/session.ts +++ b/service/license/src/types/session.ts @@ -23,8 +23,10 @@ export type Session = { // 帮忙导出用的 kubeconfig: KubeConfig; }; + export type JWTPayload = { kubeconfig: KubeConfig; user: Record<'uid' | 'nsid' | 'k8s_username' | 'ns_uid', string>; }; + export const sessionKey = 'session'; diff --git a/service/license/src/types/user.ts b/service/license/src/types/user.ts index 7cd28a20632..2a7880422e5 100644 --- a/service/license/src/types/user.ts +++ b/service/license/src/types/user.ts @@ -1,5 +1,3 @@ -import { InvitedStatus, UserRole } from './team'; - export type TgithubToken = { access_token: string; expires_in: number; @@ -85,6 +83,7 @@ export type User = { password?: string; password_user?: string; }; + export type UserDto = { uid: string; avatarUrl: string; @@ -92,8 +91,3 @@ export type UserDto = { k8s_username: string; createdTime: string; }; -export type TeamUserDto = UserDto & { - joinTime?: Date; - role: UserRole; - status: InvitedStatus; -}; diff --git a/service/license/src/utils/ProcessManager.ts b/service/license/src/utils/ProcessManager.ts deleted file mode 100644 index 4f0b6e9512f..00000000000 --- a/service/license/src/utils/ProcessManager.ts +++ /dev/null @@ -1,61 +0,0 @@ -import type { TApp } from '@/types'; -let _id = 0; -const counter = () => _id++; - -class AppRunningState { - state: 'running' | 'suspend'; - pid: number = -1; - key: string; - constructor(key: TApp['key']) { - this.pid = counter(); - this.state = 'suspend'; - this.key = key; - } -} - -export default class AppStateManager { - allApps!: Set; - openedApps: AppRunningState[]; - // currentPid: Pid; - constructor(apps: string[]) { - this.loadApps(apps || []); - this.openedApps = []; - // this.currentPid = -1; - } - suspendApp(pid: number) { - const _state = this.findState(pid); - if (!_state) return; - _state.state = 'suspend'; - } - closeApp(pid: number) { - const idx = this.openedApps.findIndex((app) => app.pid === pid); - this.openedApps.splice(idx, 1); - } - loadApps(appKeys: string[]) { - this.allApps = new Set(appKeys); - } - loadApp(appKey: string) { - this.allApps.add(appKey); - } - unloadApp(appKey: string) { - this.allApps.delete(appKey); - /// remove all apps - const goal: number[] = []; - this.openedApps.forEach((app) => { - if (app.key === app.key) { - goal.push(app.pid); - } - }); - this.openedApps = this.openedApps.filter((x) => goal.includes(x.pid)); - } - // open app - openApp(key: string) { - const appRunningState = new AppRunningState(key as `user-${string}` | `system-${string}`); - appRunningState.state = 'running'; - this.openedApps.push(appRunningState); - return appRunningState; - } - findState(pid: number) { - return this.openedApps.find((x) => x.pid === pid); - } -} diff --git a/service/license/src/utils/crypto.ts b/service/license/src/utils/crypto.ts index 7c9cb089267..40f2bcb9c33 100644 --- a/service/license/src/utils/crypto.ts +++ b/service/license/src/utils/crypto.ts @@ -9,5 +9,7 @@ export function hashPassword(password: string): string { export const verifyPassword = (password: string, hash: string): boolean => hashPassword(password) === hash; + export const strongPassword = (password: string): boolean => /^(?=.*\S).{8,}$/.test(password); + export const strongUsername = (username: string): boolean => /^[a-zA-Z0-9_-]{3,16}$/.test(username); diff --git a/service/license/src/utils/tools.ts b/service/license/src/utils/tools.ts index 0f84135ea16..d76567495c6 100644 --- a/service/license/src/utils/tools.ts +++ b/service/license/src/utils/tools.ts @@ -1,4 +1,3 @@ -import { UserRole } from '@/types/team'; import dayjs from 'dayjs'; export const formatTime = (time: string | number | Date, format = 'YYYY-MM-DD HH:mm:ss') => { @@ -65,21 +64,3 @@ export const retrySerially = (fn: () => Promise, times: number) => }; attempt(); }); -// 自己的权限能管理什么权限 -export const vaildManage = - (ownRole: UserRole, userId: string) => (targetRole: UserRole, tUserId: string) => { - if (targetRole === UserRole.Owner) - return [UserRole.Owner].includes(ownRole); // 不论目标是不是自己,都必须要最高权限 - else if (targetRole === UserRole.Manager) - return [UserRole.Owner, ...(tUserId === userId ? [UserRole.Manager] : [])].includes(ownRole); - //对自己操作定义的role可以是平级 - else if (targetRole === UserRole.Developer) - return [ - UserRole.Owner, - UserRole.Manager, - ...(tUserId === userId ? [UserRole.Developer] : []) - ].includes(ownRole); - else return false; - }; -export const isUserRole = (role: any): role is UserRole => - [UserRole.Developer, UserRole.Manager, UserRole.Owner].includes(role);