diff --git a/.env.development b/.env.development
index 37f0871ec..8e0d86f9f 100644
--- a/.env.development
+++ b/.env.development
@@ -1,2 +1,2 @@
-VITE_APP_BASE_API=/api
+VITE_APP_BASE_API=http://localhost:5000
VITE_APP_HOMEPAGE=/dashboard/workbench
diff --git a/.eslintrc.cjs b/.eslintrc.cjs
index d5ef0743a..fbcaedb27 100644
--- a/.eslintrc.cjs
+++ b/.eslintrc.cjs
@@ -60,6 +60,7 @@ module.exports = {
'no-param-reassign': 'off',
'space-before-function-paren': 'off',
'class-methods-use-this': 'off',
+ 'consistent-return': 'off',
'jsx-a11y/click-events-have-key-events': 'off',
'jsx-a11y/interactive-supports-focus': 'off',
diff --git a/.firebaserc b/.firebaserc
new file mode 100644
index 000000000..65d5d8286
--- /dev/null
+++ b/.firebaserc
@@ -0,0 +1,5 @@
+{
+ "projects": {
+ "default": "skillrazr-admin"
+ }
+}
diff --git a/.vscode/settings.json b/.vscode/settings.json
index b18b0f3dd..e81a5fcd6 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -23,5 +23,5 @@
"i18n-ally.keystyle": "flat",
"i18n-ally.sortKeys": true,
"i18n-ally.sourceLanguage": "en_US",
- "i18n-ally.displayLanguage": "zh_CN",
+ "i18n-ally.displayLanguage": "en_US",
}
diff --git a/README.md b/README.md
index 8912ec31f..403967b4b 100644
--- a/README.md
+++ b/README.md
@@ -2,20 +2,12 @@
-
Slash Admin
+ SkillRazr Admin App
- Slash Admin is a modern admin dashboard template built with React 18, Vite, Ant Design, and TypeScript. It is designed to help developers quickly create powerful admin management systems.
+ SkillRazr Admin is a modern admin dashboard template built with React 18, Vite, Ant Design, and TypeScript. It is designed to help developers quickly create powerful admin management systems.
-**English** | [中文](./README.zh-CN.md)
-
-## Sponsor
-
-
-
-
-
## Preview
+ https://admin.slashspaces.com/
diff --git a/README.zh-CN.md b/README.zh-CN.md
deleted file mode 100644
index 707b4c0d6..000000000
--- a/README.zh-CN.md
+++ /dev/null
@@ -1,124 +0,0 @@
-
-
-
-
-
Slash Admin
-
- Slash Admin 是一款现代化的后台管理模板,基于 React 18、Vite、Ant Design 和 TypeScript 构建。它旨在帮助开发人员快速搭建功能强大的后台管理系统。
-
-
-
-
-**中文** | [English](./README.md)
-
-## 赞助
-
-
-
-
-
-
-## 预览
-+ https://admin.slashspaces.com/
-
-||
-| ----------------------------------------------------------------- | ------------------------------------------------------------------- |
-||
-## 特性
-
-- 使用 React 18 hooks 进行构建。
-- 基于 Vite 进行快速开发和热模块替换。
-- 集成 Ant Design,提供丰富的 UI 组件和设计模式。
-- 使用 TypeScript 编写,提供类型安全性和更好的开发体验。
-- 响应式设计,适应各种屏幕尺寸和设备。
-- 灵活的路由配置,支持多级嵌套路由。
-- 集成权限管理,根据用户角色控制页面访问权限。
-- 集成国际化支持,轻松切换多语言。
-- 集成常见的后台管理功能,如用户管理、角色管理、权限管理等。
-- 可定制的主题和样式,以满足您的品牌需求。
-- 基于 MSW 和 Faker.js 的Mock方案
-- 使用 Zustand 进行状态管理
-- 使用 React-Query 进行数据获取
-
-## 文档
-[文档地址](https://docs-admin.slashspaces.com/)
-
-## 快速开始
-
-### 获取项目代码
-
-```bash
-git clone https://github.com/d3george/slash-admin.git
-```
-
-### 安装依赖
-
-在项目根目录下运行以下命令安装项目依赖:
-
-```bash
-pnpm install
-```
-
-### 启动开发服务器
-
-运行以下命令以启动开发服务器:
-
-```bash
-pnpm dev
-```
-
-访问 [http://localhost:3001](http://localhost:3001) 查看您的应用程序。
-
-### 构建生产版本
-
-运行以下命令以构建生产版本:
-
-```bash
-pnpm build
-```
-
-构建后的文件将位于 `dist` 目录中。
-
-## 容器化部署
-
-### 构建镜像并运行容器
-#### 构建镜像
-在终端中进入项目根目录,并执行以下命令来构建 Docker 镜像:
-```
-docker build -t your-image-name .
-```
-确保将 `your-image-name` 替换为你自己的镜像名称
-
-#### 运行容器
-使用以下命令在 Docker 容器中运行你的应用:
-```
-docker run -p 3001:80 your-image-name
-```
-这将在容器的端口 `80` (暴露在`Dockerfile`中) 上运行你的应用,并将其映射到你主机的端口 `3001` 上。
-
-现在,你可以通过访问 http://localhost:3001 来查看部署的应用。
-
-
-### 使用docker-compose.yaml
-在终端中进入项目根目录,并执行以下命令来启动 Docker Compose:
-```
-docker-compose up -d
-```
-Docker Compose 根据`docker-compose.yaml`定义的配置构建镜像并在后台运行容器.
-
-容器运行成功后,同样可以通过访问 http://localhost:3001来查看部署的应用。
-
-参考[.commitlint.config.js](./commitlint.config.js)
-
-- `feat` 新功能
-- `fix` 修复bug
-- `docs` 文档注释
-- `style` 代码格式(不影响代码运行的变动)
-- `refactor` 重构
-- `perf` 性能优化
-- `revert` 回滚commit
-- `test` 测试相关
-- `chore` 构建过程或辅助工具的变动
-- `ci` 修改CI配置、脚本
-- `types` 类型定义文件修改
-- `wip` 开发中
diff --git a/firebase.json b/firebase.json
new file mode 100644
index 000000000..6564edd5c
--- /dev/null
+++ b/firebase.json
@@ -0,0 +1,12 @@
+{
+ "hosting": {
+ "public": "dist",
+ "ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
+ "rewrites": [
+ {
+ "source": "**",
+ "destination": "/index.html"
+ }
+ ]
+ }
+}
diff --git a/index.html b/index.html
index aca743b1f..7188c0e8b 100644
--- a/index.html
+++ b/index.html
@@ -3,7 +3,7 @@
- Slash Admin
+ SkillRazr Admin
You need to enable JavaScript to run this app.
diff --git a/package-lock.json b/package-lock.json
index a52879782..a38c47d5b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -27,13 +27,18 @@
"apexcharts": "^3.43.0",
"autosuggest-highlight": "^3.3.4",
"axios": "^1.5.1",
+ "bcryptjs": "^2.4.3",
+ "body-parser": "^1.20.2",
"classnames": "^2.3.2",
"color": "^4.2.3",
+ "cors": "^2.8.5",
"dayjs": "^1.11.10",
+ "express": "^4.19.2",
"framer-motion": "^10.16.4",
"highlight.js": "^11.9.0",
"i18next": "^23.5.1",
"i18next-browser-languagedetector": "^7.1.0",
+ "jsonwebtoken": "^9.0.2",
"nprogress": "^0.2.0",
"numeral": "^2.0.6",
"ramda": "^0.29.1",
@@ -65,7 +70,12 @@
"@commitlint/config-conventional": "^17.7.0",
"@faker-js/faker": "^8.1.0",
"@types/autosuggest-highlight": "^3.2.0",
+ "@types/bcryptjs": "^2.4.6",
+ "@types/body-parser": "^1.19.5",
"@types/color": "^3.0.4",
+ "@types/cors": "^2.8.17",
+ "@types/express": "^4.17.21",
+ "@types/jsonwebtoken": "^9.0.6",
"@types/nprogress": "^0.2.1",
"@types/numeral": "^2.0.3",
"@types/ramda": "^0.29.6",
@@ -2568,6 +2578,22 @@
"@babel/types": "^7.20.7"
}
},
+ "node_modules/@types/bcryptjs": {
+ "version": "2.4.6",
+ "resolved": "https://registry.npmjs.org/@types/bcryptjs/-/bcryptjs-2.4.6.tgz",
+ "integrity": "sha512-9xlo6R2qDs5uixm0bcIqCeMCE6HiQsIyel9KQySStiyqNl2tnj2mP3DX1Nf56MD6KMenNNlBBsy3LJ7gUEQPXQ==",
+ "dev": true
+ },
+ "node_modules/@types/body-parser": {
+ "version": "1.19.5",
+ "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz",
+ "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==",
+ "dev": true,
+ "dependencies": {
+ "@types/connect": "*",
+ "@types/node": "*"
+ }
+ },
"node_modules/@types/color": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/@types/color/-/color-3.0.6.tgz",
@@ -2592,12 +2618,30 @@
"integrity": "sha512-hulKeREDdLFesGQjl96+4aoJSHY5b2GRjagzzcqCfIrWhe5vkCqIvrLbqzBaI1q94Vg8DNJZZqTR5ocdWmWclg==",
"dev": true
},
+ "node_modules/@types/connect": {
+ "version": "3.4.38",
+ "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz",
+ "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
"node_modules/@types/cookie": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz",
"integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==",
"dev": true
},
+ "node_modules/@types/cors": {
+ "version": "2.8.17",
+ "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz",
+ "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
"node_modules/@types/debug": {
"version": "4.1.12",
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz",
@@ -2612,6 +2656,30 @@
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
"dev": true
},
+ "node_modules/@types/express": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz",
+ "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==",
+ "dev": true,
+ "dependencies": {
+ "@types/body-parser": "*",
+ "@types/express-serve-static-core": "^4.17.33",
+ "@types/qs": "*",
+ "@types/serve-static": "*"
+ }
+ },
+ "node_modules/@types/express-serve-static-core": {
+ "version": "4.19.2",
+ "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.2.tgz",
+ "integrity": "sha512-dPSEQElyVJ97BuGduAqQjpBocZWAs0GR94z+ptL7JXQJeJdHw2WBG3EWdFrK36b8Q6j8P4cXOMhgUoi0IIfIsg==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*",
+ "@types/qs": "*",
+ "@types/range-parser": "*",
+ "@types/send": "*"
+ }
+ },
"node_modules/@types/glob": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz",
@@ -2645,6 +2713,12 @@
"hoist-non-react-statics": "^3.3.0"
}
},
+ "node_modules/@types/http-errors": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz",
+ "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==",
+ "dev": true
+ },
"node_modules/@types/js-cookie": {
"version": "2.2.7",
"resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-2.2.7.tgz",
@@ -2662,6 +2736,15 @@
"integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==",
"dev": true
},
+ "node_modules/@types/jsonwebtoken": {
+ "version": "9.0.6",
+ "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.6.tgz",
+ "integrity": "sha512-/5hndP5dCjloafCXns6SZyESp3Ldq7YjH3zwzwczYnjxIT0Fqzk5ROSYVGfFyczIue7IUEj8hkvLbPoLQ18vQw==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
"node_modules/@types/lodash": {
"version": "4.17.1",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.1.tgz",
@@ -2683,6 +2766,12 @@
"@types/unist": "^2"
}
},
+ "node_modules/@types/mime": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
+ "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==",
+ "dev": true
+ },
"node_modules/@types/minimatch": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz",
@@ -2751,6 +2840,12 @@
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz",
"integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q=="
},
+ "node_modules/@types/qs": {
+ "version": "6.9.15",
+ "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz",
+ "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==",
+ "dev": true
+ },
"node_modules/@types/quill": {
"version": "1.3.10",
"resolved": "https://registry.npmjs.org/@types/quill/-/quill-1.3.10.tgz",
@@ -2768,6 +2863,12 @@
"types-ramda": "^0.29.10"
}
},
+ "node_modules/@types/range-parser": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz",
+ "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==",
+ "dev": true
+ },
"node_modules/@types/react": {
"version": "18.3.2",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.2.tgz",
@@ -2833,6 +2934,27 @@
"integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==",
"dev": true
},
+ "node_modules/@types/send": {
+ "version": "0.17.4",
+ "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz",
+ "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==",
+ "dev": true,
+ "dependencies": {
+ "@types/mime": "^1",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/serve-static": {
+ "version": "1.15.7",
+ "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz",
+ "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==",
+ "dev": true,
+ "dependencies": {
+ "@types/http-errors": "*",
+ "@types/node": "*",
+ "@types/send": "*"
+ }
+ },
"node_modules/@types/statuses": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/@types/statuses/-/statuses-2.0.5.tgz",
@@ -3246,6 +3368,18 @@
"resolved": "https://registry.npmjs.org/@yr/monotone-cubic-spline/-/monotone-cubic-spline-1.0.3.tgz",
"integrity": "sha512-FQXkOta0XBSUPHndIKON2Y9JeQz5ZeMqLYZVVK93FliNBFm7LNMIZmY6FrMEB9XPcDbE2bekMbZD6kzDkxwYjA=="
},
+ "node_modules/accepts": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
+ "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
+ "dependencies": {
+ "mime-types": "~2.1.34",
+ "negotiator": "0.6.3"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/acorn": {
"version": "8.11.3",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
@@ -3500,6 +3634,11 @@
"node": ">=0.10.0"
}
},
+ "node_modules/array-flatten": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+ "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
+ },
"node_modules/array-ify": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz",
@@ -3924,6 +4063,11 @@
"node": ">=0.10.0"
}
},
+ "node_modules/bcryptjs": {
+ "version": "2.4.3",
+ "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz",
+ "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ=="
+ },
"node_modules/big.js": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
@@ -3951,6 +4095,42 @@
"integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
"dev": true
},
+ "node_modules/body-parser": {
+ "version": "1.20.2",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz",
+ "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==",
+ "dependencies": {
+ "bytes": "3.1.2",
+ "content-type": "~1.0.5",
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
+ "on-finished": "2.4.1",
+ "qs": "6.11.0",
+ "raw-body": "2.5.2",
+ "type-is": "~1.6.18",
+ "unpipe": "1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8",
+ "npm": "1.2.8000 || >= 1.4.16"
+ }
+ },
+ "node_modules/body-parser/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/body-parser/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+ },
"node_modules/boolbase": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
@@ -4010,12 +4190,25 @@
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
}
},
+ "node_modules/buffer-equal-constant-time": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
+ "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
+ },
"node_modules/buffer-from": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
"devOptional": true
},
+ "node_modules/bytes": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
"node_modules/cac": {
"version": "6.7.14",
"resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
@@ -4646,6 +4839,25 @@
"integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==",
"dev": true
},
+ "node_modules/content-disposition": {
+ "version": "0.5.4",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
+ "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
+ "dependencies": {
+ "safe-buffer": "5.2.1"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/content-type": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
+ "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/conventional-changelog-angular": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-6.0.0.tgz",
@@ -4702,6 +4914,11 @@
"node": ">= 0.6"
}
},
+ "node_modules/cookie-signature": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
+ },
"node_modules/copy-anything": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz",
@@ -4737,7 +4954,6 @@
"version": "2.8.5",
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
- "dev": true,
"dependencies": {
"object-assign": "^4",
"vary": "^1"
@@ -5253,6 +5469,14 @@
"node": ">=0.4.0"
}
},
+ "node_modules/depd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
"node_modules/dequal": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
@@ -5261,6 +5485,15 @@
"node": ">=6"
}
},
+ "node_modules/destroy": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
+ "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
+ "engines": {
+ "node": ">= 0.8",
+ "npm": "1.2.8000 || >= 1.4.16"
+ }
+ },
"node_modules/didyoumean": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
@@ -5389,6 +5622,19 @@
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
"dev": true
},
+ "node_modules/ecdsa-sig-formatter": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
+ "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
+ "dependencies": {
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "node_modules/ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
+ },
"node_modules/electron-to-chromium": {
"version": "1.4.763",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.763.tgz",
@@ -5409,6 +5655,14 @@
"node": ">= 4"
}
},
+ "node_modules/encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
"node_modules/entities": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
@@ -5631,6 +5885,11 @@
"node": ">=6"
}
},
+ "node_modules/escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
+ },
"node_modules/escape-string-regexp": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
@@ -6239,7 +6498,6 @@
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
"integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
- "dev": true,
"engines": {
"node": ">= 0.6"
}
@@ -6364,6 +6622,73 @@
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
"dev": true
},
+ "node_modules/express": {
+ "version": "4.19.2",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz",
+ "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==",
+ "dependencies": {
+ "accepts": "~1.3.8",
+ "array-flatten": "1.1.1",
+ "body-parser": "1.20.2",
+ "content-disposition": "0.5.4",
+ "content-type": "~1.0.4",
+ "cookie": "0.6.0",
+ "cookie-signature": "1.0.6",
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "finalhandler": "1.2.0",
+ "fresh": "0.5.2",
+ "http-errors": "2.0.0",
+ "merge-descriptors": "1.0.1",
+ "methods": "~1.1.2",
+ "on-finished": "2.4.1",
+ "parseurl": "~1.3.3",
+ "path-to-regexp": "0.1.7",
+ "proxy-addr": "~2.0.7",
+ "qs": "6.11.0",
+ "range-parser": "~1.2.1",
+ "safe-buffer": "5.2.1",
+ "send": "0.18.0",
+ "serve-static": "1.15.0",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "type-is": "~1.6.18",
+ "utils-merge": "1.0.1",
+ "vary": "~1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.10.0"
+ }
+ },
+ "node_modules/express/node_modules/cookie": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
+ "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/express/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/express/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+ },
+ "node_modules/express/node_modules/path-to-regexp": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
+ "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
+ },
"node_modules/extend": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
@@ -6554,6 +6879,36 @@
"node": ">=8"
}
},
+ "node_modules/finalhandler": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
+ "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
+ "dependencies": {
+ "debug": "2.6.9",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "on-finished": "2.4.1",
+ "parseurl": "~1.3.3",
+ "statuses": "2.0.1",
+ "unpipe": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/finalhandler/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/finalhandler/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+ },
"node_modules/find-root": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
@@ -6681,6 +7036,14 @@
"node": ">=0.4.x"
}
},
+ "node_modules/forwarded": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
+ "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/fraction.js": {
"version": "4.3.7",
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz",
@@ -6729,6 +7092,14 @@
}
}
},
+ "node_modules/fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/fs-extra": {
"version": "11.2.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz",
@@ -7507,6 +7878,21 @@
"readable-stream": "^3.1.1"
}
},
+ "node_modules/http-errors": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
+ "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
+ "dependencies": {
+ "depd": "2.0.0",
+ "inherits": "2.0.4",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "toidentifier": "1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
"node_modules/human-signals": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
@@ -7566,6 +7952,17 @@
"@babel/runtime": "^7.23.2"
}
},
+ "node_modules/iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/ignore": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz",
@@ -7662,8 +8059,7 @@
"node_modules/inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
- "dev": true
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"node_modules/ini": {
"version": "1.3.8",
@@ -7707,6 +8103,14 @@
"loose-envify": "^1.0.0"
}
},
+ "node_modules/ipaddr.js": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+ "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
"node_modules/is-accessor-descriptor": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.1.tgz",
@@ -8584,6 +8988,27 @@
"node": "*"
}
},
+ "node_modules/jsonwebtoken": {
+ "version": "9.0.2",
+ "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz",
+ "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==",
+ "dependencies": {
+ "jws": "^3.2.2",
+ "lodash.includes": "^4.3.0",
+ "lodash.isboolean": "^3.0.3",
+ "lodash.isinteger": "^4.0.4",
+ "lodash.isnumber": "^3.0.3",
+ "lodash.isplainobject": "^4.0.6",
+ "lodash.isstring": "^4.0.1",
+ "lodash.once": "^4.0.0",
+ "ms": "^2.1.1",
+ "semver": "^7.5.4"
+ },
+ "engines": {
+ "node": ">=12",
+ "npm": ">=6"
+ }
+ },
"node_modules/jsx-ast-utils": {
"version": "3.3.5",
"resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz",
@@ -8599,6 +9024,25 @@
"node": ">=4.0"
}
},
+ "node_modules/jwa": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
+ "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
+ "dependencies": {
+ "buffer-equal-constant-time": "1.0.1",
+ "ecdsa-sig-formatter": "1.0.11",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "node_modules/jws": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
+ "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
+ "dependencies": {
+ "jwa": "^1.4.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
"node_modules/keyv": {
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
@@ -8969,17 +9413,41 @@
"integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==",
"dev": true
},
+ "node_modules/lodash.includes": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
+ "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w=="
+ },
+ "node_modules/lodash.isboolean": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
+ "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg=="
+ },
"node_modules/lodash.isfunction": {
"version": "3.0.9",
"resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz",
"integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==",
"dev": true
},
+ "node_modules/lodash.isinteger": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
+ "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA=="
+ },
+ "node_modules/lodash.isnumber": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
+ "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw=="
+ },
"node_modules/lodash.isplainobject": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
- "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
- "dev": true
+ "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="
+ },
+ "node_modules/lodash.isstring": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
+ "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw=="
},
"node_modules/lodash.kebabcase": {
"version": "4.1.1",
@@ -8999,6 +9467,11 @@
"integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==",
"dev": true
},
+ "node_modules/lodash.once": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
+ "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="
+ },
"node_modules/lodash.snakecase": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz",
@@ -9563,6 +10036,14 @@
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz",
"integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow=="
},
+ "node_modules/media-typer": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/memoize-one": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz",
@@ -9605,6 +10086,11 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/merge-descriptors": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+ "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
+ },
"node_modules/merge-options": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/merge-options/-/merge-options-1.0.1.tgz",
@@ -9632,6 +10118,14 @@
"node": ">= 8"
}
},
+ "node_modules/methods": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+ "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/micromark": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz",
@@ -10180,6 +10674,17 @@
"node": ">=8.6"
}
},
+ "node_modules/mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+ "bin": {
+ "mime": "cli.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
@@ -10462,6 +10967,14 @@
"integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==",
"dev": true
},
+ "node_modules/negotiator": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
+ "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/node-releases": {
"version": "2.0.14",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
@@ -10627,7 +11140,6 @@
"version": "1.13.1",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz",
"integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==",
- "dev": true,
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@ -10795,6 +11307,17 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/on-finished": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
+ "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
+ "dependencies": {
+ "ee-first": "1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
@@ -10960,6 +11483,14 @@
"resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
"integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw=="
},
+ "node_modules/parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
"node_modules/pascalcase": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
@@ -11903,6 +12434,18 @@
"url": "https://github.com/sponsors/wooorm"
}
},
+ "node_modules/proxy-addr": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
+ "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
+ "dependencies": {
+ "forwarded": "0.2.0",
+ "ipaddr.js": "1.9.1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
@@ -11925,6 +12468,20 @@
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
}
},
+ "node_modules/qs": {
+ "version": "6.11.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
+ "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
+ "dependencies": {
+ "side-channel": "^1.0.4"
+ },
+ "engines": {
+ "node": ">=0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/query-string": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz",
@@ -12017,6 +12574,28 @@
"url": "https://opencollective.com/ramda"
}
},
+ "node_modules/range-parser": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/raw-body": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
+ "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
+ "dependencies": {
+ "bytes": "3.1.2",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
+ "unpipe": "1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
"node_modules/rc-cascader": {
"version": "3.25.0",
"resolved": "https://registry.npmjs.org/rc-cascader/-/rc-cascader-3.25.0.tgz",
@@ -13642,7 +14221,6 @@
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
- "dev": true,
"funding": [
{
"type": "github",
@@ -13684,6 +14262,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+ },
"node_modules/sass": {
"version": "1.77.1",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.77.1.tgz",
@@ -13732,7 +14315,6 @@
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
- "dev": true,
"dependencies": {
"lru-cache": "^6.0.0"
},
@@ -13747,7 +14329,6 @@
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "dev": true,
"dependencies": {
"yallist": "^4.0.0"
},
@@ -13758,8 +14339,62 @@
"node_modules/semver/node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "dev": true
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+ },
+ "node_modules/send": {
+ "version": "0.18.0",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
+ "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
+ "dependencies": {
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "fresh": "0.5.2",
+ "http-errors": "2.0.0",
+ "mime": "1.6.0",
+ "ms": "2.1.3",
+ "on-finished": "2.4.1",
+ "range-parser": "~1.2.1",
+ "statuses": "2.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/send/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/send/node_modules/debug/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+ },
+ "node_modules/send/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
+ },
+ "node_modules/serve-static": {
+ "version": "1.15.0",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
+ "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
+ "dependencies": {
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.3",
+ "send": "0.18.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
},
"node_modules/server-only": {
"version": "0.0.1",
@@ -13861,6 +14496,11 @@
"node": ">=0.10.0"
}
},
+ "node_modules/setprototypeof": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
+ },
"node_modules/shallowequal": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz",
@@ -13891,7 +14531,6 @@
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
"integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
- "dev": true,
"dependencies": {
"call-bind": "^1.0.7",
"es-errors": "^1.3.0",
@@ -14372,7 +15011,6 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
- "dev": true,
"engines": {
"node": ">= 0.8"
}
@@ -16978,6 +17616,14 @@
"resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz",
"integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ=="
},
+ "node_modules/toidentifier": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
+ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
"node_modules/traverse": {
"version": "0.6.9",
"resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.9.tgz",
@@ -17208,6 +17854,18 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/type-is": {
+ "version": "1.6.18",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
+ "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+ "dependencies": {
+ "media-typer": "0.3.0",
+ "mime-types": "~2.1.24"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/typed-array-buffer": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz",
@@ -17573,6 +18231,14 @@
"node": ">= 10.0.0"
}
},
+ "node_modules/unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
"node_modules/unset-value": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
@@ -17712,6 +18378,14 @@
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
"dev": true
},
+ "node_modules/utils-merge": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
"node_modules/uvu": {
"version": "0.5.6",
"resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz",
@@ -17757,7 +18431,6 @@
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
"integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
- "dev": true,
"engines": {
"node": ">= 0.8"
}
diff --git a/package.json b/package.json
index b2c118f2c..0de1b3394 100644
--- a/package.json
+++ b/package.json
@@ -9,7 +9,8 @@
"build": "tsc && vite build",
"lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview",
- "prepare": "husky install"
+ "prepare": "husky install",
+ "startServer": "npx ts-node src/server.ts"
},
"dependencies": {
"@ant-design/cssinjs": "^1.17.2",
@@ -31,13 +32,18 @@
"apexcharts": "^3.43.0",
"autosuggest-highlight": "^3.3.4",
"axios": "^1.5.1",
+ "bcryptjs": "^2.4.3",
+ "body-parser": "^1.20.2",
"classnames": "^2.3.2",
"color": "^4.2.3",
+ "cors": "^2.8.5",
"dayjs": "^1.11.10",
+ "express": "^4.19.2",
"framer-motion": "^10.16.4",
"highlight.js": "^11.9.0",
"i18next": "^23.5.1",
"i18next-browser-languagedetector": "^7.1.0",
+ "jsonwebtoken": "^9.0.2",
"nprogress": "^0.2.0",
"numeral": "^2.0.6",
"ramda": "^0.29.1",
@@ -69,7 +75,12 @@
"@commitlint/config-conventional": "^17.7.0",
"@faker-js/faker": "^8.1.0",
"@types/autosuggest-highlight": "^3.2.0",
+ "@types/bcryptjs": "^2.4.6",
+ "@types/body-parser": "^1.19.5",
"@types/color": "^3.0.4",
+ "@types/cors": "^2.8.17",
+ "@types/express": "^4.17.21",
+ "@types/jsonwebtoken": "^9.0.6",
"@types/nprogress": "^0.2.1",
"@types/numeral": "^2.0.3",
"@types/ramda": "^0.29.6",
diff --git a/src/App.tsx b/src/App.tsx
index 66a4609f0..be5fa947b 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -13,7 +13,7 @@ function App() {
- Slash Admin
+ SkillRazr Admin
diff --git a/src/_mock/assets.js b/src/_mock/assets.js
index 68de9a390..4e6e34baa 100644
--- a/src/_mock/assets.js
+++ b/src/_mock/assets.js
@@ -531,3 +531,5 @@ export const TEST_USER = {
permissions: TEST_ROLE.permission,
};
export const USER_LIST = [DEFAULT_USER, TEST_USER];
+export const adminPermissions = ADMIN_ROLE.permission;
+export const testPermmissions = TEST_ROLE.permission;
diff --git a/src/_mock/handlers/_user.js b/src/_mock/handlers/_user.js
index 6ce6ab4e6..cd2c4ce16 100644
--- a/src/_mock/handlers/_user.js
+++ b/src/_mock/handlers/_user.js
@@ -5,9 +5,9 @@ import { UserApi } from '@/api/services/userService';
import { USER_LIST } from '../assets';
+// mock server - this is not used as Node server is used
const signIn = http.post(`/api${UserApi.SignIn}`, async ({ request }) => {
const { username, password } = await request.json();
-
const user = USER_LIST.find((item) => item.username === username);
if (!user || user.password !== password) {
diff --git a/src/api/apiClient.ts b/src/api/apiClient.ts
index f31946f9b..d53edf216 100644
--- a/src/api/apiClient.ts
+++ b/src/api/apiClient.ts
@@ -7,14 +7,13 @@ import { t } from '@/locales/i18n';
import { Result } from '#/api';
import { ResultEnum } from '#/enum';
-// 创建 axios 实例
+console.log('api base url', import.meta.env.VITE_APP_BASE_API);
const axiosInstance = axios.create({
baseURL: import.meta.env.VITE_APP_BASE_API,
timeout: 50000,
headers: { 'Content-Type': 'application/json;charset=utf-8' },
});
-// 请求拦截
axiosInstance.interceptors.request.use(
(config) => {
// 在请求被发送之前做些什么
@@ -30,11 +29,14 @@ axiosInstance.interceptors.request.use(
// 响应拦截
axiosInstance.interceptors.response.use(
(res: AxiosResponse) => {
+ console.log('axios resp1', res);
+
if (!res.data) throw new Error(t('sys.api.apiRequestFailed'));
const { status, data, message } = res.data;
- // 业务请求成功
+
const hasSuccess = data && Reflect.has(res.data, 'status') && status === ResultEnum.SUCCESS;
+
if (hasSuccess) {
return data;
}
@@ -50,7 +52,6 @@ axiosInstance.interceptors.response.use(
} catch (error) {
throw new Error(error as unknown as string);
}
- // 对响应错误做点什么
if (isEmpty(errMsg)) {
// checkStatus
// errMsg = checkStatus(response.data.status);
diff --git a/src/api/services/userService.ts b/src/api/services/userService.ts
index 59a037b08..dc74d5070 100644
--- a/src/api/services/userService.ts
+++ b/src/api/services/userService.ts
@@ -13,11 +13,11 @@ export interface SignUpReq extends SignInReq {
export type SignInRes = UserToken & { user: UserInfo };
export enum UserApi {
- SignIn = '/auth/signin',
- SignUp = '/auth/signup',
- Logout = '/auth/logout',
- Refresh = '/auth/refresh',
- User = '/user',
+ SignIn = 'signin',
+ SignUp = 'signup',
+ Logout = 'logout',
+ Refresh = 'refresh',
+ User = 'user',
}
const signin = (data: SignInReq) => apiClient.post({ url: UserApi.SignIn, data });
diff --git a/src/assets/images/skillrazr.jpg b/src/assets/images/skillrazr.jpg
new file mode 100644
index 000000000..839c83314
Binary files /dev/null and b/src/assets/images/skillrazr.jpg differ
diff --git a/src/layouts/_common/notice.tsx b/src/layouts/_common/notice.tsx
index fdc646d50..50ff9b2f6 100644
--- a/src/layouts/_common/notice.tsx
+++ b/src/layouts/_common/notice.tsx
@@ -128,7 +128,7 @@ function NoticeTab() {
{faker.person.fullName()}
mentioned you in
- Slash Admin
+ SkillRazr Admin
1 days ago
diff --git a/src/layouts/dashboard/nav.tsx b/src/layouts/dashboard/nav.tsx
index 91416ff2e..260a6e368 100644
--- a/src/layouts/dashboard/nav.tsx
+++ b/src/layouts/dashboard/nav.tsx
@@ -131,7 +131,7 @@ export default function Nav(props: Props) {
{themeLayout !== ThemeLayout.Mini && (
- Slash Admin
+ SkillRazr Admin
)}
diff --git a/src/pages/dashboard/workbench/banner-card.tsx b/src/pages/dashboard/workbench/banner-card.tsx
index fe8c64c71..b0a4379d9 100644
--- a/src/pages/dashboard/workbench/banner-card.tsx
+++ b/src/pages/dashboard/workbench/banner-card.tsx
@@ -33,8 +33,8 @@ export default function BannerCard() {
style={{ color: themeToken.colorPrimaryTextActive }}
className="mx-auto mb-6 mt-4 max-w-sm text-sm opacity-80 md:mx-0"
>
- Welcome to join the Discord channel to discuss everything about Slash Admin, or you can
- visite my blog:
+ Welcome to join the Discord channel to discuss everything about SkillRazr Admin, or you
+ can visite my blog:
new Date(expiresIn!).getTime();
+
+ if (accessToken && !isTokenExpired) {
return ;
}
@@ -40,7 +40,9 @@ function Login() {
background: bg,
}}
>
- Slash Admin
+
+ SkillRazr Admin
+
{t('sys.login.signInSecondTitle')}
diff --git a/src/pages/sys/login/LoginForm.tsx b/src/pages/sys/login/LoginForm.tsx
index 914f9e49e..adff29ffe 100644
--- a/src/pages/sys/login/LoginForm.tsx
+++ b/src/pages/sys/login/LoginForm.tsx
@@ -1,12 +1,11 @@
-import { Alert, Button, Checkbox, Col, Divider, Form, Input, Row } from 'antd';
+import { Button, Checkbox, Col, Divider, Form, Input, Row } from 'antd';
import { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { AiFillGithub, AiFillGoogleCircle, AiFillWechat } from 'react-icons/ai';
-import { DEFAULT_USER, TEST_USER } from '@/_mock/assets';
+import { DEFAULT_USER } from '@/_mock/assets';
import { SignInReq } from '@/api/services/userService';
import { useSignIn } from '@/store/userStore';
-import ProTag from '@/theme/antd/components/tag';
import { useThemeToken } from '@/theme/hooks';
import { LoginStateEnum, useLoginStateContext } from './providers/LoginStateProvider';
@@ -42,37 +41,6 @@ function LoginForm() {
}}
onFinish={handleFinish}
>
-
-
-
-
Admin {t('sys.login.userName')}:
-
- {DEFAULT_USER.username}
-
-
-
-
-
Test {t('sys.login.userName')}:
-
- {TEST_USER.username}
-
-
-
-
-
{t('sys.login.password')}:
-
- {DEFAULT_USER.password}
-
-
-
- }
- showIcon
- />
-
-
{
console.log('Received values of form: ', values);
- await signUpMutation.mutateAsync(values);
- backToLogin();
+ try {
+ const resp = await signUpMutation.mutateAsync(values);
+ console.log('resp signup from server', resp);
+ backToLogin();
+ } catch (e) {
+ console.log('e', e);
+ }
};
return (
diff --git a/src/pages/sys/others/calendar/index.tsx b/src/pages/sys/others/calendar/index.tsx
index b02d00460..d3a892974 100644
--- a/src/pages/sys/others/calendar/index.tsx
+++ b/src/pages/sys/others/calendar/index.tsx
@@ -28,7 +28,7 @@ const DefaultEventInitValue = {
color: '',
};
export default function Calendar() {
- const [events, setEvents] = useState([]);
+ const [events] = useState([]);
const fullCalendarRef = useRef(null);
const [view, setView] = useState('dayGridMonth');
const [date, setDate] = useState(new Date());
diff --git a/src/router/components/auth-guard.tsx b/src/router/components/auth-guard.tsx
index 2c0b88a36..0c8e56c43 100644
--- a/src/router/components/auth-guard.tsx
+++ b/src/router/components/auth-guard.tsx
@@ -11,13 +11,16 @@ type Props = {
};
export default function AuthGuard({ children }: Props) {
const router = useRouter();
- const { accessToken } = useUserToken();
+ const { accessToken, expiresIn } = useUserToken();
+ console.log('accessToken', accessToken, expiresIn);
+ const isTokenExpired = Date.now() > new Date(expiresIn!).getTime();
+ console.log('token expired', isTokenExpired);
const check = useCallback(() => {
- if (!accessToken) {
+ if (!accessToken || isTokenExpired) {
router.replace('/login');
}
- }, [router, accessToken]);
+ }, [router, accessToken, isTokenExpired]);
useEffect(() => {
check();
diff --git a/src/server.ts b/src/server.ts
new file mode 100644
index 000000000..ce1d4eacf
--- /dev/null
+++ b/src/server.ts
@@ -0,0 +1,142 @@
+import bcrypt from 'bcryptjs';
+import bodyParser from 'body-parser';
+import cors from 'cors';
+import express, { Request, Response } from 'express';
+import jwt from 'jsonwebtoken';
+
+import { adminPermissions } from './_mock/assets';
+
+const app = express();
+const PORT = 5000;
+
+// Secret key for JWT
+const JWT_SECRET = 'skillrazr_admin_app_1234$2893';
+
+// Middleware
+app.use(bodyParser.json());
+app.use(cors());
+
+// Mock user data (replace this with your database in a real app)
+interface User {
+ username: string;
+ password: string;
+ permissions: any;
+}
+const users: User[] = [];
+
+console.log('users in the server', users);
+console.log('hello');
+//
+// Signup endpoint
+app.post('/signup', async (req: Request, res: Response): Promise => {
+ const { username, password } = req.body;
+
+ console.log('signup, userName', 'password', username, password);
+
+ // Check if the user already exists
+ const userExists = users.find((user) => user.username === username);
+ if (userExists) {
+ return res.status(400).json({ message: 'User already exists' });
+ }
+
+ // Hash the password
+ const hashedPassword = await bcrypt.hash(password, 10);
+
+ // Save the new user
+ users.push({ username, password: hashedPassword, permissions: adminPermissions });
+
+ console.log('hashed password', hashedPassword, 'users database', users);
+
+ return res.status(201).json({ message: 'User created successfully', status: 0, data: [] });
+});
+
+// Signin endpoint
+app.post('/signin', async (req: Request, res: Response) => {
+ const { username, password } = req.body;
+
+ const now = Date.now();
+ const expiresIn = new Date(now + 1 * 60 * 1000).toISOString();
+
+ console.log('sign in, userName', 'password', username, password, expiresIn);
+
+ // Find the user
+ const user = users.find((user) => user.username === username);
+
+ console.log('user found ', user);
+ if (!user) {
+ return res.status(400).json({ message: 'Invalid credentials' });
+ }
+
+ // Check the password
+ const isMatch = await bcrypt.compare(password, user.password);
+ if (!isMatch) {
+ return res.status(400).json({ message: 'Invalid credentials' });
+ }
+
+ // Generate a JWT token
+ const token = jwt.sign({ username: user.username }, JWT_SECRET, { expiresIn: '1h' });
+
+ res.json({ status: 0, data: { user, accessToken: token, expiresIn } });
+});
+
+// Protected route example
+app.get('/protected', (req: Request, res: Response) => {
+ const token = req.headers.authorization;
+ if (!token) {
+ return res.status(401).json({ message: 'You are not authorized to access this' });
+ }
+
+ jwt.verify(token, JWT_SECRET, (err, decoded) => {
+ if (err) {
+ return res.status(401).json({ message: 'Invalid token' });
+ }
+
+ res.json({ message: 'Protected route accessed', user: decoded, status: 0 });
+ });
+});
+
+// const tokenCheck = (req, res, next) => {
+// const token = req.headers['authorization'];
+// if (!token) {
+// return res.status(401).json({ message: 'You are not authorized to access this'});
+// } else {
+// // do token checks using jwt
+// jwt.verify(token, JWT_SECRET, (err, decoded) => {
+// if (err) {
+// return res.status(401).json({ message: 'Invalid token' });
+// }
+
+// next()
+// });
+// }
+// }
+
+// app.get('/getExerciseMarks', [tokenCheck], (req: Request, res: Response) => {
+// const {userName} = req;
+
+// // make a db call to get exercise scroes for this userName
+
+// const token = req.headers['authorization'];
+// if (!token) {
+// return res.status(401).json({ message: 'You are not authorized to access this' });
+// }
+// // get exerciseScore from exerciseDb
+
+// });
+
+// app.get('/getQuizScores', [tokenCheck], (req: Request, res: Response) => {
+// const token = req.headers['authorization'];
+// if (!token) {
+// return res.status(401).json({ message: 'You are not authorized to access this' });
+// }
+
+// // get quizScore from exerciseDb
+// });
+
+app.get('/', (req: Request, res: Response) => {
+ res.send('Hello World!');
+});
+
+app.listen(PORT, () => {
+ console.log(`Server running on port ${PORT}`);
+});
diff --git a/src/store/userStore.ts b/src/store/userStore.ts
index a7704a916..207d2a839 100644
--- a/src/store/userStore.ts
+++ b/src/store/userStore.ts
@@ -60,8 +60,10 @@ export const useSignIn = () => {
const signIn = async (data: SignInReq) => {
try {
const res = await signInMutation.mutateAsync(data);
- const { user, accessToken, refreshToken } = res;
- setUserToken({ accessToken, refreshToken });
+ console.log('res from login api', res);
+
+ const { user, accessToken, refreshToken, expiresIn } = res;
+ setUserToken({ accessToken, refreshToken, expiresIn });
setUserInfo(user);
navigatge(HOMEPAGE, { replace: true });
diff --git a/tsconfig.json b/tsconfig.json
index 463b4122c..6f50da188 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -40,6 +40,10 @@
"#/*": ["types/*"]
}
},
+ "ts-node": {
+ "esm": true,
+ "experimentalSpecifierResolution": "node"
+ },
"include": ["src", "test", "types/**/*.ts", "**.ts", "*.json", "**.*js"],
"exclude": ["node_modules", "dist"],
"references": [{ "path": "./tsconfig.node.json" }]
diff --git a/types/entity.ts b/types/entity.ts
index 724e8e834..bfc1b8cc5 100644
--- a/types/entity.ts
+++ b/types/entity.ts
@@ -3,6 +3,7 @@ import { BasicStatus, PermissionType } from './enum';
export interface UserToken {
accessToken?: string;
refreshToken?: string;
+ expiresIn?: string
}
export interface UserInfo {