From 6951ea137366a59bb46f981cfac634d5f5194911 Mon Sep 17 00:00:00 2001 From: liuyi Date: Mon, 30 Jun 2025 21:51:17 +0800 Subject: [PATCH] add rbac module --- pnpm-lock.yaml | 80 +++++++++---------- .../rbac/entities/permission.entity.ts | 5 +- src/modules/rbac/entities/role.entity.ts | 2 +- src/modules/user/user.module.ts | 8 +- src/options.ts | 2 + 5 files changed, 49 insertions(+), 48 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e3a44d3..2cc3851 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -832,26 +832,21 @@ packages: resolution: {integrity: sha512-1Nox8mAL52PKPfEnUQWBvKU/bp8FTT6AiDu76bFDEJj/qsRFSAVSldfCH3XYMqialti2zHXKvD5gN0AaHc0yKA==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jridgewell/gen-mapping@0.3.8': - resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} - engines: {node: '>=6.0.0'} + '@jridgewell/gen-mapping@0.3.10': + resolution: {integrity: sha512-HM2F4B9N4cA0RH2KQiIZOHAZqtP4xGS4IZ+SFe1SIbO4dyjf9MTY2Bo3vHYnm0hglWfXqBrzUBSa+cJfl3Xvrg==} '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} - '@jridgewell/set-array@1.2.1': - resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} - engines: {node: '>=6.0.0'} + '@jridgewell/source-map@0.3.8': + resolution: {integrity: sha512-3EDAPd0B8X1gsQQgGHU8vyxSp2MB414z3roN67fY7nI0GV3GDthHfaWcbCfrC95tpAzA5xUvAuoO9Dxx/ywwRQ==} - '@jridgewell/source-map@0.3.6': - resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==} + '@jridgewell/sourcemap-codec@1.5.2': + resolution: {integrity: sha512-gKYheCylLIedI+CSZoDtGkFV9YEBxRRVcfCH7OfAqh4TyUyRjEE6WVE/aXDXX0p8BIe/QgLcaAoI0220KRRFgg==} - '@jridgewell/sourcemap-codec@1.5.0': - resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} - - '@jridgewell/trace-mapping@0.3.25': - resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + '@jridgewell/trace-mapping@0.3.27': + resolution: {integrity: sha512-VO95AxtSFMelbg3ouljAYnfvTEwSWVt/2YLf+U5Ejd8iT5mXE2Sa/1LGyvySMne2CGsepGLI7KpF3EzE3Aq9Mg==} '@jridgewell/trace-mapping@0.3.9': resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} @@ -4554,8 +4549,8 @@ packages: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} - token-types@6.0.2: - resolution: {integrity: sha512-p04i+HzAr5Ro1ZBPwE03gf948+F2bwxXNa4xqNy5Z9iHlcWravI1u8lmEW2q0Dg0NKErOHM1OcybFV5UtJ2I4Q==} + token-types@6.0.3: + resolution: {integrity: sha512-IKJ6EzuPPWtKtEIEPpIdXv9j5j2LGJEYk0CKY2efgKoYKLBiZdh6iQkLVBow/CB3phyWAWCyk+bZeaimJn6uRQ==} engines: {node: '>=14.16'} tree-kill@1.2.2: @@ -4943,8 +4938,8 @@ snapshots: '@ampproject/remapping@2.3.0': dependencies: - '@jridgewell/gen-mapping': 0.3.8 - '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/gen-mapping': 0.3.10 + '@jridgewell/trace-mapping': 0.3.27 '@angular-devkit/core@19.2.6(chokidar@4.0.3)': dependencies: @@ -5032,8 +5027,8 @@ snapshots: dependencies: '@babel/parser': 7.27.7 '@babel/types': 7.27.7 - '@jridgewell/gen-mapping': 0.3.8 - '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/gen-mapping': 0.3.10 + '@jridgewell/trace-mapping': 0.3.27 jsesc: 3.1.0 '@babel/helper-compilation-targets@7.27.2': @@ -5597,7 +5592,7 @@ snapshots: '@jest/test-result': 30.0.0 '@jest/transform': 30.0.0 '@jest/types': 30.0.0 - '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/trace-mapping': 0.3.27 '@types/node': 24.0.7 chalk: 4.1.2 collect-v8-coverage: 1.0.2 @@ -5635,7 +5630,7 @@ snapshots: '@jest/source-map@30.0.0': dependencies: - '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/trace-mapping': 0.3.27 callsites: 3.1.0 graceful-fs: 4.2.11 @@ -5657,7 +5652,7 @@ snapshots: dependencies: '@babel/core': 7.27.7 '@jest/types': 30.0.0 - '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/trace-mapping': 0.3.27 babel-plugin-istanbul: 7.0.0 chalk: 4.1.2 convert-source-map: 2.0.0 @@ -5692,32 +5687,29 @@ snapshots: '@types/yargs': 17.0.33 chalk: 4.1.2 - '@jridgewell/gen-mapping@0.3.8': + '@jridgewell/gen-mapping@0.3.10': dependencies: - '@jridgewell/set-array': 1.2.1 - '@jridgewell/sourcemap-codec': 1.5.0 - '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/sourcemap-codec': 1.5.2 + '@jridgewell/trace-mapping': 0.3.27 '@jridgewell/resolve-uri@3.1.2': {} - '@jridgewell/set-array@1.2.1': {} - - '@jridgewell/source-map@0.3.6': + '@jridgewell/source-map@0.3.8': dependencies: - '@jridgewell/gen-mapping': 0.3.8 - '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/gen-mapping': 0.3.10 + '@jridgewell/trace-mapping': 0.3.27 - '@jridgewell/sourcemap-codec@1.5.0': {} + '@jridgewell/sourcemap-codec@1.5.2': {} - '@jridgewell/trace-mapping@0.3.25': + '@jridgewell/trace-mapping@0.3.27': dependencies: '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/sourcemap-codec': 1.5.2 '@jridgewell/trace-mapping@0.3.9': dependencies: '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/sourcemap-codec': 1.5.2 '@lukeed/csprng@1.1.0': {} @@ -6106,7 +6098,7 @@ snapshots: dependencies: debug: 4.4.1 fflate: 0.8.2 - token-types: 6.0.2 + token-types: 6.0.3 transitivePeerDependencies: - supports-color @@ -7718,14 +7710,14 @@ snapshots: dependencies: get-stream: 9.0.1 strtok3: 9.1.1 - token-types: 6.0.2 + token-types: 6.0.3 uint8array-extras: 1.4.0 file-type@21.0.0: dependencies: '@tokenizer/inflate': 0.2.7 strtok3: 10.3.1 - token-types: 6.0.2 + token-types: 6.0.3 uint8array-extras: 1.4.0 transitivePeerDependencies: - supports-color @@ -8266,7 +8258,7 @@ snapshots: istanbul-lib-source-maps@5.0.6: dependencies: - '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/trace-mapping': 0.3.27 debug: 4.4.1 istanbul-lib-coverage: 3.2.2 transitivePeerDependencies: @@ -8819,7 +8811,7 @@ snapshots: magic-string@0.30.17: dependencies: - '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/sourcemap-codec': 1.5.2 make-dir@4.0.0: dependencies: @@ -9822,7 +9814,7 @@ snapshots: terser-webpack-plugin@5.3.14(@swc/core@1.12.7)(webpack@5.99.6(@swc/core@1.12.7)): dependencies: - '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/trace-mapping': 0.3.27 jest-worker: 27.5.1 schema-utils: 4.3.2 serialize-javascript: 6.0.2 @@ -9833,7 +9825,7 @@ snapshots: terser@5.43.1: dependencies: - '@jridgewell/source-map': 0.3.6 + '@jridgewell/source-map': 0.3.8 acorn: 8.15.0 commander: 2.20.3 source-map-support: 0.5.21 @@ -9868,7 +9860,7 @@ snapshots: toidentifier@1.0.1: {} - token-types@6.0.2: + token-types@6.0.3: dependencies: '@tokenizer/token': 0.3.0 ieee754: 1.2.1 @@ -10097,7 +10089,7 @@ snapshots: v8-to-istanbul@9.3.0: dependencies: - '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/trace-mapping': 0.3.27 '@types/istanbul-lib-coverage': 2.0.6 convert-source-map: 2.0.0 diff --git a/src/modules/rbac/entities/permission.entity.ts b/src/modules/rbac/entities/permission.entity.ts index 52d76bb..9a8f4b6 100644 --- a/src/modules/rbac/entities/permission.entity.ts +++ b/src/modules/rbac/entities/permission.entity.ts @@ -1,6 +1,7 @@ import { AbilityTuple, MongoQuery, RawRuleFrom } from '@casl/ability'; import { Exclude, Expose } from 'class-transformer'; -import { Column, Entity, JoinTable, ManyToMany, PrimaryGeneratedColumn, Relation } from 'typeorm'; +import type { Relation } from 'typeorm'; +import { Column, Entity, JoinTable, ManyToMany, PrimaryGeneratedColumn } from 'typeorm'; import { UserEntity } from '@/modules/user/entities'; @@ -53,7 +54,7 @@ export class PermissionEntity< * 权限角色 */ @Expose({ groups: ['permission-list', 'permission-detail'] }) - @ManyToMany(() => RoleEntity, (role) => role.permissions, { cascade: true }) + @ManyToMany(() => RoleEntity, (role) => role.permissions) @JoinTable() roles: Relation[]; diff --git a/src/modules/rbac/entities/role.entity.ts b/src/modules/rbac/entities/role.entity.ts index d824f02..9fb9ccb 100644 --- a/src/modules/rbac/entities/role.entity.ts +++ b/src/modules/rbac/entities/role.entity.ts @@ -1,4 +1,5 @@ import { Exclude, Expose, Type } from 'class-transformer'; +import type { Relation } from 'typeorm'; import { BaseEntity, Column, @@ -7,7 +8,6 @@ import { JoinTable, ManyToMany, PrimaryGeneratedColumn, - Relation, } from 'typeorm'; import { UserEntity } from '@/modules/user/entities'; diff --git a/src/modules/user/user.module.ts b/src/modules/user/user.module.ts index 0ce612b..c6ee6e4 100644 --- a/src/modules/user/user.module.ts +++ b/src/modules/user/user.module.ts @@ -1,4 +1,4 @@ -import { DynamicModule, Module } from '@nestjs/common'; +import { DynamicModule, forwardRef, Module } from '@nestjs/common'; import { PassportModule } from '@nestjs/passport'; @@ -7,6 +7,10 @@ import { Configure } from '@/modules/config/configure'; import { DatabaseModule } from '@/modules/database/database.module'; import { addEntities, addSubscribers } from '@/modules/database/utils'; +import { RbacModule } from '@/modules/rbac/rbac.module'; + +import { RoleRepository } from '@/modules/rbac/repositories'; + import * as entities from './entities'; import * as guards from './guards'; import * as interceptors from './interceptors'; @@ -22,11 +26,13 @@ export class UserModule { module: UserModule, imports: [ PassportModule, + forwardRef(() => RbacModule), services.TokenService.JwtModuleFactory(configure), await addEntities(configure, Object.values(entities)), DatabaseModule.forRepository(Object.values(repositories)), ], providers: [ + RoleRepository, ...Object.values(interceptors), ...Object.values(services), ...Object.values(strategies), diff --git a/src/options.ts b/src/options.ts index e3aa39b..07c7746 100644 --- a/src/options.ts +++ b/src/options.ts @@ -7,6 +7,7 @@ import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify import { existsSync } from 'fs-extra'; import { isNil } from 'lodash'; +import { RbacModule } from '@/modules/rbac/rbac.module'; import { UserModule } from '@/modules/user/user.module'; import * as configs from './config'; @@ -29,6 +30,7 @@ export const createOptions: CreateOptions = { await RestfulModule.forRoot(configure), await ContentModule.forRoot(configure), await UserModule.forRoot(configure), + await RbacModule.forRoot(configure), ], globals: { guard: RbacGuard }, builder: async ({ configure, BootModule }) => {