@gadmin2n/schematics 0.0.64 → 0.0.66
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/application/files/gadmin2-game-angle-demo/.dockerignore +2 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/Dockerfile +40 -26
- package/dist/lib/application/files/gadmin2-game-angle-demo/Jenkinsfile +30 -4
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/example.prisma +33 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/system.prisma +170 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/Event.ts +70 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/Game.ts +6 -6
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/ITActivityDay.ts +70 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/Log.ts +2 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/Role.ts +2 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/.env +20 -9
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/.env.local +1 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/.eslintrc.js +1 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/.prettierignore +1 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/README.md +2 -18
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/gadmin-cli.json +1 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/migrate-between-pg-schemas.js +1232 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/package.json +65 -38
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/prisma/.generator.prisma +4 -3
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/prisma.config.ts +16 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/games.ts +1 -71
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/index.ts +17 -21
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/permissions.ts +278 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/seedDataMngtPages.ts +258 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/users.ts +7 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/alias.config.ts +7 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/app.controller.ts +151 -11
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/app.module.ts +29 -13
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/app.service.ts +151 -12
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/lib/auth.guard.ts +87 -41
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/lib/http-cache.interceptor.ts +21 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/lib/logger.ts +19 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/lib/safe-log.util.ts +176 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/lib/{yufuid.ts → taihu.ts} +49 -34
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/lib/tracing.ts +174 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/lib/trim.pipe.ts +51 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/lib/utils.ts +91 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/lib/woaAuth.ts +25 -12
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/main.ts +22 -12
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/audit/audit.controller.spec.ts +20 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/audit/audit.controller.ts +190 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/audit/audit.module.ts +10 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/audit/audit.service.spec.ts +338 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/audit/audit.service.ts +83 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/game/game.controller.spec.ts +20 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/game/game.controller.ts +188 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/game/game.module.ts +10 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/game/game.service.spec.ts +18 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/game/game.service.ts +83 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/page/page.controller.spec.ts +20 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/page/page.controller.ts +250 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/page/page.module.ts +10 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/page/page.service.spec.ts +18 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/page/page.service.ts +1051 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/pageResource/pageResource.controller.spec.ts +20 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/pageResource/pageResource.controller.ts +196 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/pageResource/pageResource.module.ts +13 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/pageResource/pageResource.service.spec.ts +18 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/pageResource/pageResource.service.ts +219 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/resource/resource.controller.spec.ts +20 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/resource/resource.controller.ts +196 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/resource/resource.module.ts +10 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/resource/resource.service.spec.ts +18 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/resource/resource.service.ts +199 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/role/role.controller.spec.ts +20 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/role/role.controller.ts +210 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/role/role.module.ts +12 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/role/role.service.spec.ts +18 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/role/role.service.ts +849 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/role/roles-refresher.service.ts +133 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/rolePages/rolePages.controller.spec.ts +20 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/rolePages/rolePages.controller.ts +196 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/rolePages/rolePages.module.ts +10 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/rolePages/rolePages.service.spec.ts +18 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/rolePages/rolePages.service.ts +201 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/roleResource/roleResource.controller.spec.ts +20 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/roleResource/roleResource.controller.ts +196 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/roleResource/roleResource.module.ts +10 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/roleResource/roleResource.service.spec.ts +18 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/roleResource/roleResource.service.ts +216 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/user/user.controller.spec.ts +20 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/user/user.controller.ts +198 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/user/user.module.ts +10 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/user/user.service.spec.ts +18 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/user/user.service.ts +104 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/start-prod.sh +130 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/tsconfig.json +18 -3
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/index.html +19 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/package.json +34 -42
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/postcss.config.cjs +6 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/App.tsx +111 -185
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/auditLogProvider.ts +5 -5
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/authProvider.ts +2 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/SqlModal.tsx +419 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/contexts/business/index.tsx +1 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/contexts/color-mode/index.tsx +49 -51
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/custom-avatar.tsx +38 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/index.ts +4 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/{header/index.tsx → header.tsx} +22 -31
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/index.ts +3 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/layout.tsx +32 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/logo.tsx +19 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/sider.tsx +331 -166
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/title.tsx +61 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/pagination-total.tsx +21 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/tags/index.ts +1 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/tags/role-tag.tsx +44 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/text.tsx +74 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/config/http.ts +28 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/config/routeRegistry.tsx +258 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/constants/layout.ts +16 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/enums/audit-log.enum.ts +13 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/enums/index.ts +1 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/get-name-initials.ts +8 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/get-random-color.ts +27 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/http.ts +87 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/index.tsx +6 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/login.ts +22 -59
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/utils.tsx +5 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/hooks/useDynamicResources.tsx +211 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/hooks/useFetchData.ts +33 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/hooks/useRoles.ts +30 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/hooks/useUserPageAccess.ts +339 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/i18n.ts +8 -4
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/index.tsx +3 -11
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/{public → src}/locales/en/common.json +1 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/{public → src}/locales/zh_CN/common.json +1 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/audit/components/action-cell.css +3 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/audit/components/action-cell.tsx +134 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/audit/create.tsx +113 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/audit/edit.tsx +122 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/audit/index.ts +8 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/audit/index.tsx +6 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/audit/list.tsx +213 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/audit/show.tsx +61 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/Components/AssignRolesModal.tsx +168 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/Components/CreatePageModal.tsx +42 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/Components/EditPageModal.tsx +42 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/Components/PageDetailDrawer.tsx +101 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/Components/PageFormModal.tsx +731 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/hooks/usePageManagement.ts +36 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/index.ts +1 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/list.tsx +1215 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/queries.ts +17 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/types.ts +45 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/permissionReadme/index.tsx +1089 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/Components/CreateModal.tsx +25 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/Components/EditModal.tsx +28 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/Components/ResourceDetailDrawer.tsx +160 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/Components/modal.tsx +202 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/index.ts +2 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/list.tsx +212 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/queries.ts +10 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/types.ts +9 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/Components/CreateModal.tsx +30 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/Components/EditModal.tsx +47 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/Components/RoleDetailDrawer.tsx +56 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/Components/modal.tsx +302 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/hooks/useRolePage.ts +35 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/index.ts +1 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/list.tsx +431 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/queries.ts +8 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/types.ts +8 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/components/create-modal.tsx +17 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/components/edit-modal.tsx +19 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/components/form-modal.tsx +188 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/components/index.ts +5 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/components/role-tag.tsx +48 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/components/show-drawer.tsx +140 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/index.ts +1 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/list.tsx +372 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/queries.ts +14 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/styles/antd.css +132 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/styles/fc.css +58 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/styles/index.css +128 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/styles/show-drawer.module.css +18 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/styles/show-page.module.css +21 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/types/audit-log.ts +1 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/types/index.ts +3 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/types/role.ts +7 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/types/user.ts +1 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/vite-env.d.ts +1 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/tsconfig.json +5 -4
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/vite.config.ts +31 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/yarn.lock +8321 -0
- package/package.json +1 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/sample.prisma +0 -65
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/Source.ts +0 -76
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/Tasklog.ts +0 -76
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/roles.ts +0 -4
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/craco.config.js +0 -27
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/public/index.html +0 -53
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/styles.ts +0 -10
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/utils.ts +0 -76
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/react-app-env.d.ts +0 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/reportWebVitals.ts +0 -15
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/styles/antd.less +0 -79
- /package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/VanillaJSONEditor/{index.js → index.jsx} +0 -0
package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/lib/{yufuid.ts → taihu.ts}
RENAMED
|
@@ -2,7 +2,7 @@ import * as jwt from 'jsonwebtoken';
|
|
|
2
2
|
import * as request from 'request';
|
|
3
3
|
import { URLSearchParams } from 'url';
|
|
4
4
|
|
|
5
|
-
export type
|
|
5
|
+
export type TaiHuTokenInfo = {
|
|
6
6
|
access_token: string;
|
|
7
7
|
id_token: string;
|
|
8
8
|
expires_in: number;
|
|
@@ -10,7 +10,7 @@ export type YuFuTokenInfo = {
|
|
|
10
10
|
scope: string;
|
|
11
11
|
};
|
|
12
12
|
|
|
13
|
-
export type
|
|
13
|
+
export type TaiHuUserInfo = {
|
|
14
14
|
user_id: string;
|
|
15
15
|
sub: string;
|
|
16
16
|
name: string;
|
|
@@ -21,19 +21,19 @@ export type YuFuUserInfo = {
|
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
export type GAdminUserInfo = Pick<
|
|
24
|
-
|
|
24
|
+
TaiHuUserInfo,
|
|
25
25
|
'user_id' | 'sub' | 'name' | 'email'
|
|
26
26
|
>;
|
|
27
27
|
export const GAdminTokenName = 'gadmin-token';
|
|
28
28
|
|
|
29
29
|
// see https://docs.qq.com/doc/DSEN0SlhZWWFJSHR4
|
|
30
|
-
export default class
|
|
30
|
+
export default class TaiHuId {
|
|
31
31
|
static config = {
|
|
32
|
-
clientId: process.env.
|
|
33
|
-
clientSecret: process.env.
|
|
34
|
-
apiBase: process.env.
|
|
35
|
-
callback: process.env.
|
|
36
|
-
logout: process.env.
|
|
32
|
+
clientId: process.env.TAIHU_ODC_CLIENT_ID,
|
|
33
|
+
clientSecret: process.env.TAIHU_ODC_APP_TOKEN || 'gadmin-default-secret',
|
|
34
|
+
apiBase: process.env.TAIHU_BASE,
|
|
35
|
+
callback: process.env.TAIHU_CALLBACK,
|
|
36
|
+
logout: process.env.TAIHU_LOGOUT,
|
|
37
37
|
};
|
|
38
38
|
|
|
39
39
|
static callApi<T>(
|
|
@@ -44,73 +44,88 @@ export default class YuFuId {
|
|
|
44
44
|
return new Promise((resolve, reject) => {
|
|
45
45
|
request(
|
|
46
46
|
{
|
|
47
|
-
url: `${
|
|
47
|
+
url: `${TaiHuId.config.apiBase}${url}`,
|
|
48
48
|
method: 'POST',
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
headers: {
|
|
50
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
51
|
+
...options?.headers,
|
|
52
|
+
},
|
|
53
|
+
form: params,
|
|
51
54
|
...options,
|
|
52
55
|
},
|
|
53
|
-
(error: Error, _response: unknown, body:
|
|
56
|
+
(error: Error, _response: unknown, body: string) => {
|
|
54
57
|
if (error) {
|
|
55
58
|
reject(error);
|
|
56
59
|
return;
|
|
57
60
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
+
try {
|
|
62
|
+
const parsedBody = JSON.parse(body);
|
|
63
|
+
if (parsedBody.error) {
|
|
64
|
+
reject(new Error(parsedBody.error_description));
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
resolve(parsedBody as T);
|
|
68
|
+
} catch (parseError) {
|
|
69
|
+
reject(new Error('Failed to parse response body as JSON'));
|
|
61
70
|
}
|
|
62
|
-
resolve(body as T);
|
|
63
71
|
},
|
|
64
72
|
);
|
|
65
73
|
});
|
|
66
74
|
}
|
|
67
75
|
|
|
68
76
|
static getToken(code: string) {
|
|
69
|
-
return
|
|
70
|
-
client_id:
|
|
71
|
-
client_secret:
|
|
77
|
+
return TaiHuId.callApi<TaiHuTokenInfo>('/token', {
|
|
78
|
+
client_id: TaiHuId.config.clientId,
|
|
79
|
+
client_secret: TaiHuId.config.clientSecret,
|
|
72
80
|
grant_type: 'authorization_code',
|
|
73
|
-
redirect_uri:
|
|
81
|
+
redirect_uri: TaiHuId.config.callback,
|
|
74
82
|
code,
|
|
75
83
|
});
|
|
76
84
|
}
|
|
77
85
|
|
|
78
86
|
static refreshToken(refreshToken: string) {
|
|
79
|
-
return
|
|
80
|
-
client_id:
|
|
81
|
-
client_secret:
|
|
87
|
+
return TaiHuId.callApi<TaiHuTokenInfo>('/token', {
|
|
88
|
+
client_id: TaiHuId.config.clientId,
|
|
89
|
+
client_secret: TaiHuId.config.clientSecret,
|
|
82
90
|
grant_type: 'refresh_token',
|
|
83
91
|
refresh_token: refreshToken,
|
|
84
92
|
});
|
|
85
93
|
}
|
|
86
94
|
|
|
87
95
|
// get userinfo by api
|
|
88
|
-
static getUserInfo(accessToken: string) {
|
|
89
|
-
|
|
96
|
+
static async getUserInfo(accessToken: string) {
|
|
97
|
+
const user_info = await TaiHuId.callApi<any>('/userinfo', undefined, {
|
|
90
98
|
method: 'GET',
|
|
91
99
|
headers: {
|
|
92
100
|
Authorization: `Bearer ${accessToken}`,
|
|
93
101
|
},
|
|
94
102
|
});
|
|
103
|
+
const { user_name } = user_info;
|
|
104
|
+
return {
|
|
105
|
+
user_id: user_name,
|
|
106
|
+
sub: user_name,
|
|
107
|
+
name: user_name,
|
|
108
|
+
email: `${user_name}@tencent.com`,
|
|
109
|
+
};
|
|
95
110
|
}
|
|
96
111
|
|
|
97
112
|
static authorize(redirectUrl: string, uiLocales = 'zh-CN') {
|
|
98
113
|
const map = new Map();
|
|
99
114
|
map.set('response_type', 'code');
|
|
100
|
-
map.set('client_id',
|
|
115
|
+
map.set('client_id', TaiHuId.config.clientId);
|
|
101
116
|
map.set('ui_locales', uiLocales);
|
|
102
|
-
map.set('scope', 'openid profile
|
|
103
|
-
map.set('redirect_uri',
|
|
117
|
+
map.set('scope', 'openid profile');
|
|
118
|
+
map.set('redirect_uri', TaiHuId.config.callback);
|
|
104
119
|
map.set('state', redirectUrl);
|
|
105
120
|
const params = new URLSearchParams(map);
|
|
106
|
-
return `${
|
|
121
|
+
return `${TaiHuId.config.apiBase}/authorize?${params.toString()}`;
|
|
107
122
|
}
|
|
108
123
|
|
|
109
124
|
static logout(redirectUrl: string) {
|
|
110
125
|
const map = new Map();
|
|
111
|
-
map.set('
|
|
126
|
+
map.set('url', redirectUrl);
|
|
112
127
|
const params = new URLSearchParams(map);
|
|
113
|
-
return `${
|
|
128
|
+
return `${TaiHuId.config.logout}?${params.toString()}`;
|
|
114
129
|
}
|
|
115
130
|
|
|
116
131
|
/**
|
|
@@ -123,7 +138,7 @@ export default class YuFuId {
|
|
|
123
138
|
return new Promise<string>((resolve, reject) => {
|
|
124
139
|
jwt.sign(
|
|
125
140
|
payload,
|
|
126
|
-
|
|
141
|
+
TaiHuId.config.clientSecret,
|
|
127
142
|
{ expiresIn },
|
|
128
143
|
(err, token) => {
|
|
129
144
|
if (err) {
|
|
@@ -148,7 +163,7 @@ export default class YuFuId {
|
|
|
148
163
|
return;
|
|
149
164
|
}
|
|
150
165
|
|
|
151
|
-
jwt.verify(token,
|
|
166
|
+
jwt.verify(token, TaiHuId.config.clientSecret, {}, (err, decoded) => {
|
|
152
167
|
if (err) {
|
|
153
168
|
reject(err);
|
|
154
169
|
return;
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
// OpenTelemetry 手工注入 - 不依赖 K8s autoinstrumentation
|
|
2
|
+
//
|
|
3
|
+
// 通过 NodeSDK 手动配置 Resource、Exporter 和 Instrumentations,
|
|
4
|
+
// 支持通过环境变量或 .env 文件配置,不再依赖 K8s Operator 注入探针。
|
|
5
|
+
|
|
6
|
+
import { trace } from '@opentelemetry/api';
|
|
7
|
+
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc';
|
|
8
|
+
import { ExpressInstrumentation } from '@opentelemetry/instrumentation-express';
|
|
9
|
+
import { HttpInstrumentation } from '@opentelemetry/instrumentation-http';
|
|
10
|
+
import { NestInstrumentation } from '@opentelemetry/instrumentation-nestjs-core';
|
|
11
|
+
import { PgInstrumentation } from '@opentelemetry/instrumentation-pg';
|
|
12
|
+
import { resourceFromAttributes } from '@opentelemetry/resources';
|
|
13
|
+
import { NodeSDK } from '@opentelemetry/sdk-node';
|
|
14
|
+
import {
|
|
15
|
+
BatchSpanProcessor,
|
|
16
|
+
ReadableSpan,
|
|
17
|
+
SpanProcessor,
|
|
18
|
+
} from '@opentelemetry/sdk-trace-base';
|
|
19
|
+
import {
|
|
20
|
+
ATTR_SERVICE_NAME,
|
|
21
|
+
ATTR_SERVICE_VERSION,
|
|
22
|
+
} from '@opentelemetry/semantic-conventions';
|
|
23
|
+
import { PrismaInstrumentation } from '@prisma/instrumentation';
|
|
24
|
+
|
|
25
|
+
// 从 DATABASE_URL 解析数据库连接信息,用于补充 Prisma span 的 peer 属性
|
|
26
|
+
function parseDbUrl(url?: string) {
|
|
27
|
+
if (!url) return null;
|
|
28
|
+
try {
|
|
29
|
+
const parsed = new URL(url);
|
|
30
|
+
return {
|
|
31
|
+
host: parsed.hostname,
|
|
32
|
+
port: parsed.port || '5432',
|
|
33
|
+
name: parsed.pathname.replace('/', ''),
|
|
34
|
+
};
|
|
35
|
+
} catch {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// 自定义 SpanProcessor:为 Prisma 产生的 db span 补充连接信息
|
|
41
|
+
class PrismaDbSpanProcessor implements SpanProcessor {
|
|
42
|
+
private inner: SpanProcessor;
|
|
43
|
+
|
|
44
|
+
constructor(inner: SpanProcessor) {
|
|
45
|
+
this.inner = inner;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
onStart(span: ReadableSpan, parentContext: any) {
|
|
49
|
+
this.inner.onStart(span as any, parentContext);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
onEnd(span: ReadableSpan) {
|
|
53
|
+
const dbInfo = parseDbUrl(process.env.DATABASE_URL);
|
|
54
|
+
if (dbInfo && span.attributes['db.system'] === 'postgresql') {
|
|
55
|
+
const mutableSpan = span as any;
|
|
56
|
+
mutableSpan.attributes['net.peer.name'] = dbInfo.host;
|
|
57
|
+
mutableSpan.attributes['net.peer.port'] = Number(dbInfo.port);
|
|
58
|
+
mutableSpan.attributes['db.name'] = dbInfo.name;
|
|
59
|
+
mutableSpan.attributes['db.instance'] = dbInfo.name;
|
|
60
|
+
mutableSpan.attributes['db.ip'] = dbInfo.host;
|
|
61
|
+
mutableSpan.attributes[
|
|
62
|
+
'peer.service'
|
|
63
|
+
] = `${dbInfo.name}@${dbInfo.host}:${dbInfo.port}`;
|
|
64
|
+
mutableSpan.attributes[
|
|
65
|
+
'peer.filled'
|
|
66
|
+
] = `${dbInfo.name}@${dbInfo.host}:${dbInfo.port}`;
|
|
67
|
+
}
|
|
68
|
+
this.inner.onEnd(span);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
shutdown() {
|
|
72
|
+
return this.inner.shutdown();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
forceFlush() {
|
|
76
|
+
return this.inner.forceFlush();
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function initializeTracing(): void {
|
|
81
|
+
const otelEndpoint = process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT;
|
|
82
|
+
const serviceName =
|
|
83
|
+
process.env.OTEL_SERVICE_NAME || `oit-erp-backend-${process.env.NODE_ENV}`;
|
|
84
|
+
const otelToken = process.env.OTEL_RESOURCE_ATTRIBUTES_TOKEN;
|
|
85
|
+
|
|
86
|
+
console.log('[Tracing] ========== OpenTelemetry 手工注入模式 ==========');
|
|
87
|
+
console.log('[Tracing] NODE_ENV:', process.env.NODE_ENV);
|
|
88
|
+
console.log('[Tracing] OTEL_SERVICE_NAME:', serviceName);
|
|
89
|
+
console.log('[Tracing] OTEL_EXPORTER_OTLP_ENDPOINT:', otelEndpoint);
|
|
90
|
+
console.log(
|
|
91
|
+
'[Tracing] OTEL_RESOURCE_ATTRIBUTES_TOKEN:',
|
|
92
|
+
otelToken ? '******(已配置)' : '未配置',
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
let sdk: NodeSDK | null = null;
|
|
96
|
+
|
|
97
|
+
if (!otelEndpoint) {
|
|
98
|
+
console.log(
|
|
99
|
+
'[Tracing] OTEL_EXPORTER_OTLP_ENDPOINT 未配置,跳过 tracing 初始化',
|
|
100
|
+
);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
console.log('[Tracing] 正在初始化 OpenTelemetry SDK...');
|
|
105
|
+
|
|
106
|
+
try {
|
|
107
|
+
const resource = resourceFromAttributes({
|
|
108
|
+
token: otelToken,
|
|
109
|
+
[ATTR_SERVICE_NAME]: serviceName,
|
|
110
|
+
[ATTR_SERVICE_VERSION]: process.env.npm_package_version || '0.0.1',
|
|
111
|
+
['deployment.environment']: process.env.NODE_ENV || 'development',
|
|
112
|
+
'host.name': process.env.HOSTNAME,
|
|
113
|
+
} as Record<string, string>);
|
|
114
|
+
|
|
115
|
+
const traceExporter = new OTLPTraceExporter({
|
|
116
|
+
url: otelEndpoint,
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
const spanProcessor = new PrismaDbSpanProcessor(
|
|
120
|
+
new BatchSpanProcessor(traceExporter),
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
sdk = new NodeSDK({
|
|
124
|
+
resource,
|
|
125
|
+
spanProcessor,
|
|
126
|
+
instrumentations: [
|
|
127
|
+
new HttpInstrumentation({
|
|
128
|
+
ignoreIncomingRequestHook: (req) => req.method === 'HEAD',
|
|
129
|
+
}),
|
|
130
|
+
new ExpressInstrumentation(),
|
|
131
|
+
new NestInstrumentation(),
|
|
132
|
+
new PgInstrumentation(),
|
|
133
|
+
new PrismaInstrumentation(),
|
|
134
|
+
],
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
sdk.start();
|
|
138
|
+
|
|
139
|
+
// 验证 TracerProvider 是否正常
|
|
140
|
+
const tracer = trace.getTracer(serviceName);
|
|
141
|
+
const testSpan = tracer.startSpan('tracing-init-test');
|
|
142
|
+
const spanContext = testSpan.spanContext();
|
|
143
|
+
|
|
144
|
+
console.log('[Tracing] SDK 启动成功');
|
|
145
|
+
console.log(
|
|
146
|
+
'[Tracing] TracerProvider:',
|
|
147
|
+
trace.getTracerProvider()?.constructor?.name,
|
|
148
|
+
);
|
|
149
|
+
console.log('[Tracing] Test traceId:', spanContext.traceId);
|
|
150
|
+
console.log('[Tracing] Sampled:', spanContext.traceFlags === 1);
|
|
151
|
+
|
|
152
|
+
testSpan.end();
|
|
153
|
+
} catch (error) {
|
|
154
|
+
console.error('[Tracing] 初始化失败:', error);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
process.on('SIGTERM', async () => {
|
|
158
|
+
if (sdk) {
|
|
159
|
+
console.log('[Tracing] 正在关闭 OpenTelemetry SDK...');
|
|
160
|
+
await sdk.shutdown();
|
|
161
|
+
console.log('[Tracing] SDK 已关闭');
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
console.log(
|
|
165
|
+
'[Tracing] ====================================================',
|
|
166
|
+
);
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (process.env.NODE_ENV !== 'development') {
|
|
171
|
+
console.log('[Bootstrap] Initializing tracing...');
|
|
172
|
+
initializeTracing();
|
|
173
|
+
console.log('[Bootstrap] Tracing ready, starting NestJS application...');
|
|
174
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { ArgumentMetadata, Injectable, PipeTransform } from '@nestjs/common';
|
|
2
|
+
|
|
3
|
+
@Injectable()
|
|
4
|
+
export class TrimPipe implements PipeTransform {
|
|
5
|
+
transform(value: any, metadata: ArgumentMetadata) {
|
|
6
|
+
if (value === null || value === undefined) {
|
|
7
|
+
return value;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// parse string and trim
|
|
11
|
+
if (typeof value === 'string') {
|
|
12
|
+
return value.trim();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// parse object and trim
|
|
16
|
+
if (typeof value === 'object' && !Array.isArray(value)) {
|
|
17
|
+
return this.trimObject(value);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// parse array and trim
|
|
21
|
+
if (Array.isArray(value)) {
|
|
22
|
+
return value.map((item) =>
|
|
23
|
+
typeof item === 'string'
|
|
24
|
+
? item.trim()
|
|
25
|
+
: this.transform(item, { ...metadata }),
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
return value;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
private trimObject(obj: any): any {
|
|
32
|
+
Object.keys(obj).forEach((key) => {
|
|
33
|
+
if (typeof obj[key] === 'string') {
|
|
34
|
+
obj[key] = obj[key].trim();
|
|
35
|
+
} else if (
|
|
36
|
+
typeof obj[key] === 'object' &&
|
|
37
|
+
!Array.isArray(obj[key]) &&
|
|
38
|
+
obj[key] !== null
|
|
39
|
+
) {
|
|
40
|
+
obj[key] = this.trimObject(obj[key]);
|
|
41
|
+
} else if (Array.isArray(obj[key])) {
|
|
42
|
+
obj[key] = obj[key].map((item) =>
|
|
43
|
+
typeof item === 'string'
|
|
44
|
+
? item.trim()
|
|
45
|
+
: this.transform(item, { type: 'custom' }),
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
return obj;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -52,3 +52,94 @@ export function addFieldIfExist(
|
|
|
52
52
|
}
|
|
53
53
|
return obj;
|
|
54
54
|
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* AES 加密
|
|
58
|
+
* @param {string} data - 要加密的数据
|
|
59
|
+
* @param {string} key - 加密密钥(16/24/32 字节,对应 AES-128/192/256)
|
|
60
|
+
* @param {string} iv - 初始化向量(16 字节)
|
|
61
|
+
* @param {string} algorithm - 加密算法,默认为 'aes-256-cbc'
|
|
62
|
+
* @param {string} outputEncoding - 输出编码,默认为 'base64'
|
|
63
|
+
* @returns {string} - 加密后的数据
|
|
64
|
+
*/
|
|
65
|
+
export function AES_CBC_ENCRYPT(
|
|
66
|
+
data,
|
|
67
|
+
key,
|
|
68
|
+
iv,
|
|
69
|
+
algorithm = 'aes-256-cbc',
|
|
70
|
+
outputEncoding = 'base64',
|
|
71
|
+
) {
|
|
72
|
+
// 验证输入
|
|
73
|
+
if (!data || !key || !iv) {
|
|
74
|
+
throw new Error('数据、密钥和初始化向量不能为空');
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const keyFromHex = Buffer.from(key, 'hex');
|
|
78
|
+
const ivFromHex = Buffer.from(iv, 'hex');
|
|
79
|
+
|
|
80
|
+
if (ivFromHex.length !== 16) {
|
|
81
|
+
throw new Error('AES IV 必须是 16 字节');
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// 创建加密器
|
|
85
|
+
const cipher = crypto.createCipheriv(algorithm, keyFromHex, ivFromHex);
|
|
86
|
+
|
|
87
|
+
// 更新加密内容
|
|
88
|
+
let encrypted = cipher.update(data, 'utf8', outputEncoding);
|
|
89
|
+
encrypted += cipher.final(outputEncoding);
|
|
90
|
+
|
|
91
|
+
return encrypted;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* AES 解密
|
|
96
|
+
* @param {string} encryptedData - 加密的数据
|
|
97
|
+
* @param {string} key - 解密密钥(必须与加密时使用的相同)
|
|
98
|
+
* @param {string} iv - 初始化向量(必须与加密时使用的相同)
|
|
99
|
+
* @param {string} algorithm - 解密算法,默认为 'aes-256-cbc'
|
|
100
|
+
* @param {string} inputEncoding - 输入编码,默认为 'base64'
|
|
101
|
+
* @returns {string} - 解密后的数据
|
|
102
|
+
*/
|
|
103
|
+
export function AES_CBC_DECRYPT(
|
|
104
|
+
encryptedData,
|
|
105
|
+
key,
|
|
106
|
+
iv,
|
|
107
|
+
algorithm = 'aes-256-cbc',
|
|
108
|
+
inputEncoding = 'base64',
|
|
109
|
+
) {
|
|
110
|
+
// 验证输入
|
|
111
|
+
if (!encryptedData || !key || !iv) {
|
|
112
|
+
throw new Error('加密数据、密钥和初始化向量不能为空');
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const keyFromHex = Buffer.from(key, 'hex');
|
|
116
|
+
const ivFromHex = Buffer.from(iv, 'hex');
|
|
117
|
+
if (ivFromHex.length !== 16) {
|
|
118
|
+
throw new Error('AES IV 必须是 16 字节');
|
|
119
|
+
}
|
|
120
|
+
// 创建解密器
|
|
121
|
+
const decipher = crypto.createDecipheriv(algorithm, keyFromHex, ivFromHex);
|
|
122
|
+
|
|
123
|
+
// 更新解密内容
|
|
124
|
+
let decrypted = decipher.update(encryptedData, inputEncoding, 'utf8');
|
|
125
|
+
decrypted += decipher.final('utf8');
|
|
126
|
+
|
|
127
|
+
return decrypted;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* 生成随机密钥
|
|
132
|
+
* @param {number} length - 密钥长度(字节),默认为 32(对应 AES-256)
|
|
133
|
+
* @returns {string} - 十六进制格式的密钥
|
|
134
|
+
*/
|
|
135
|
+
export function generateKey(length = 32) {
|
|
136
|
+
return crypto.randomBytes(length).toString('hex');
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* 生成随机初始化向量
|
|
141
|
+
* @returns {string} - 十六进制格式的初始化向量
|
|
142
|
+
*/
|
|
143
|
+
export function generateIV() {
|
|
144
|
+
return crypto.randomBytes(16).toString('hex');
|
|
145
|
+
}
|
|
@@ -12,16 +12,23 @@ const crypto = require('crypto'); //改成import,运行时会报错
|
|
|
12
12
|
const jose = require('jose'); //改成import,运行时会报错
|
|
13
13
|
|
|
14
14
|
async function decodeAuthorizationHeader(authorizationHeader, key) {
|
|
15
|
-
const
|
|
16
|
-
|
|
15
|
+
const keyBytes = Buffer.from(key);
|
|
16
|
+
try {
|
|
17
|
+
const dec = await jose.compactDecrypt(authorizationHeader, keyBytes);
|
|
18
|
+
const payload = JSON.parse(dec.plaintext as any);
|
|
17
19
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
const exp = new Date(payload.Expiration);
|
|
21
|
+
// 检验 token 是否已经过期,增加5分钟缓冲,避免服务器时间差异
|
|
22
|
+
if (new Date(new Date().getTime() - 3 * 60 * 1000) > exp) {
|
|
23
|
+
// demo 为了正常运行,此处异常注释了,实际环境需要开启验证
|
|
24
|
+
throw new Error('expired');
|
|
25
|
+
}
|
|
26
|
+
return payload;
|
|
27
|
+
} catch (error) {
|
|
28
|
+
throw new Error(
|
|
29
|
+
`decodeAuthorizationHeader(${authorizationHeader}, ${key}) error: ${error}`,
|
|
30
|
+
);
|
|
23
31
|
}
|
|
24
|
-
return payload;
|
|
25
32
|
}
|
|
26
33
|
|
|
27
34
|
function checkSignature(key, timestampSeconds, signature, extHeaders) {
|
|
@@ -48,8 +55,15 @@ export async function getIdentity(headers, key) {
|
|
|
48
55
|
staffname,
|
|
49
56
|
headers['x-ext-data'] || '',
|
|
50
57
|
];
|
|
51
|
-
if (
|
|
52
|
-
|
|
58
|
+
if (
|
|
59
|
+
staffid &&
|
|
60
|
+
staffname &&
|
|
61
|
+
headers['x-ext-data'] &&
|
|
62
|
+
!checkSignature(key, headers.timestamp, headers.signature, extHeaders)
|
|
63
|
+
) {
|
|
64
|
+
throw new Error(
|
|
65
|
+
`check smartgate signature failed, headers: ${headers.timestamp}, ${headers.signature}, ${extHeaders}`,
|
|
66
|
+
);
|
|
53
67
|
}
|
|
54
68
|
const taiIdentity = headers['x-tai-identity'];
|
|
55
69
|
if (taiIdentity) {
|
|
@@ -75,8 +89,7 @@ export class WoaAuthGuard implements CanActivate {
|
|
|
75
89
|
return true;
|
|
76
90
|
})
|
|
77
91
|
.catch((error) => {
|
|
78
|
-
|
|
79
|
-
throw new UnauthorizedException(error);
|
|
92
|
+
throw new UnauthorizedException();
|
|
80
93
|
});
|
|
81
94
|
}
|
|
82
95
|
}
|
|
@@ -1,5 +1,10 @@
|
|
|
1
|
+
// eslint-disable-next-line import/order
|
|
2
|
+
import './lib/tracing'; // OpenTelemetry Prisma instrumentation - 必须第一个导入
|
|
3
|
+
|
|
1
4
|
import { AllExceptionsFilter, UserType } from '@gadmin2n/nest-common';
|
|
2
|
-
import { ClassSerializerInterceptor, ValidationPipe } from '@nestjs/common';
|
|
5
|
+
import { ClassSerializerInterceptor, UnauthorizedException, ValidationPipe } from '@nestjs/common';
|
|
6
|
+
import './alias.config';
|
|
7
|
+
|
|
3
8
|
import { ConfigService } from '@nestjs/config';
|
|
4
9
|
import { HttpAdapterHost, NestFactory, Reflector } from '@nestjs/core';
|
|
5
10
|
import {
|
|
@@ -13,6 +18,7 @@ import { PrismaClientExceptionFilter, PrismaService } from 'nestjs-prisma';
|
|
|
13
18
|
import { AppModule } from './app.module';
|
|
14
19
|
import AuthGuard from './lib/auth.guard';
|
|
15
20
|
import RolesGuard from './lib/roles.guard';
|
|
21
|
+
import { UserService } from './modules/user/user.service';
|
|
16
22
|
|
|
17
23
|
// https://www.prisma.io/docs/concepts/components/prisma-client/working-with-fields#working-with-bigint
|
|
18
24
|
const stringify = JSON.stringify;
|
|
@@ -25,23 +31,22 @@ JSON.stringify = (value: any, _: any, space: string | number | undefined) => {
|
|
|
25
31
|
};
|
|
26
32
|
|
|
27
33
|
async function bootstrap() {
|
|
28
|
-
const app = await NestFactory.create(AppModule, {
|
|
34
|
+
const app = await NestFactory.create(AppModule, {
|
|
35
|
+
cors: true,
|
|
36
|
+
});
|
|
37
|
+
// 添加全局前缀 '/api'
|
|
38
|
+
app.setGlobalPrefix(`${process.env.DEPLOY_NAME || ''}/api`);
|
|
29
39
|
|
|
30
40
|
const configService = app.get(ConfigService);
|
|
31
41
|
|
|
32
|
-
// enable shutdown hook
|
|
33
42
|
const prismaService: PrismaService = app.get(PrismaService);
|
|
34
|
-
prismaService.enableShutdownHooks(app);
|
|
35
43
|
|
|
36
44
|
app.use(cookieParser());
|
|
37
45
|
app.useGlobalGuards(
|
|
38
|
-
new AuthGuard(
|
|
39
|
-
process.env.WOA_TOKEN || '7R6XOQVQXUW4OCKFZHBIXZ8FLJJLQX5A',
|
|
40
|
-
new Reflector(),
|
|
41
|
-
),
|
|
46
|
+
new AuthGuard(new Reflector(), app.get(UserService)),
|
|
42
47
|
|
|
43
48
|
new RolesGuard((user: UserType) => {
|
|
44
|
-
return prismaService.
|
|
49
|
+
return prismaService.user
|
|
45
50
|
.findMany({
|
|
46
51
|
where: {
|
|
47
52
|
userid: user.username,
|
|
@@ -49,18 +54,21 @@ async function bootstrap() {
|
|
|
49
54
|
})
|
|
50
55
|
.then((records) => {
|
|
51
56
|
if (records.length === 0) {
|
|
52
|
-
if (['
|
|
57
|
+
if (['jasonlan', 'gc_lvhenan'].includes(user.username)) {
|
|
53
58
|
return { business: [-1], roles: ['SYSTEM_ADMIN'] };
|
|
54
59
|
}
|
|
55
60
|
return { business: [], roles: [] };
|
|
56
61
|
}
|
|
62
|
+
if (!records[0].isActive) {
|
|
63
|
+
throw new UnauthorizedException('用户未激活');
|
|
64
|
+
}
|
|
57
65
|
return {
|
|
58
66
|
business: [],
|
|
59
67
|
roles: JSON.parse(records[0].roles),
|
|
60
68
|
};
|
|
61
69
|
})
|
|
62
70
|
.catch(() => {
|
|
63
|
-
if (['
|
|
71
|
+
if (['jasonlan', 'gc_lvhenan'].includes(user.username)) {
|
|
64
72
|
return { business: [-1], roles: ['SYSTEM_ADMIN'] };
|
|
65
73
|
}
|
|
66
74
|
return { business: [], roles: [] };
|
|
@@ -90,6 +98,8 @@ async function bootstrap() {
|
|
|
90
98
|
|
|
91
99
|
// Swagger Api
|
|
92
100
|
const swaggerConfig = configService.get('swagger');
|
|
101
|
+
swaggerConfig.path =
|
|
102
|
+
`${process.env.DEPLOY_NAME || ''}/api` || swaggerConfig.path || 'api';
|
|
93
103
|
if (swaggerConfig.enabled) {
|
|
94
104
|
const config = new DocumentBuilder()
|
|
95
105
|
.setTitle(swaggerConfig.title || 'Nestjs')
|
|
@@ -104,7 +114,7 @@ async function bootstrap() {
|
|
|
104
114
|
};
|
|
105
115
|
const document = SwaggerModule.createDocument(app, config, options);
|
|
106
116
|
|
|
107
|
-
SwaggerModule.setup(swaggerConfig.path
|
|
117
|
+
SwaggerModule.setup(swaggerConfig.path, app, document, {
|
|
108
118
|
customSiteTitle: 'Prisma Day',
|
|
109
119
|
});
|
|
110
120
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Test, TestingModule } from '@nestjs/testing';
|
|
2
|
+
import { AuditController } from './audit.controller';
|
|
3
|
+
import { AuditService } from './audit.service';
|
|
4
|
+
|
|
5
|
+
describe('AuditController', () => {
|
|
6
|
+
let controller: AuditController;
|
|
7
|
+
|
|
8
|
+
beforeEach(async () => {
|
|
9
|
+
const module: TestingModule = await Test.createTestingModule({
|
|
10
|
+
controllers: [AuditController],
|
|
11
|
+
providers: [AuditService],
|
|
12
|
+
}).compile();
|
|
13
|
+
|
|
14
|
+
controller = module.get<AuditController>(AuditController);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('should be defined', () => {
|
|
18
|
+
expect(controller).toBeDefined();
|
|
19
|
+
});
|
|
20
|
+
});
|