diff --git a/bun.lock b/bun.lock index e6a34a8..40a92c1 100644 --- a/bun.lock +++ b/bun.lock @@ -4,6 +4,7 @@ "": { "name": "3r", "dependencies": { + "@casl/ability": "^6.7.3", "@fastify/static": "^8.2.0", "@nestjs/common": "^11.1.3", "@nestjs/core": "^11.1.3", @@ -167,6 +168,8 @@ "@bcoe/v8-coverage": ["@bcoe/v8-coverage@0.2.3", "", {}, "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw=="], + "@casl/ability": ["@casl/ability@6.7.3", "", { "dependencies": { "@ucast/mongo2js": "^1.3.0" } }, "sha512-A4L28Ko+phJAsTDhRjzCOZWECQWN2jzZnJPnROWWHjJpyMq1h7h9ZqjwS2WbIUa3Z474X1ZPSgW0f1PboZGC0A=="], + "@colors/colors": ["@colors/colors@1.5.0", "", {}, "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ=="], "@cspotcode/source-map-support": ["@cspotcode/source-map-support@0.8.1", "", { "dependencies": { "@jridgewell/trace-mapping": "0.3.9" } }, "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw=="], @@ -577,6 +580,14 @@ "@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.34.1", "", { "dependencies": { "@typescript-eslint/types": "8.34.1", "eslint-visitor-keys": "^4.2.1" } }, "sha512-xoh5rJ+tgsRKoXnkBPFRLZ7rjKM0AfVbC68UZ/ECXoDbfggb9RbEySN359acY1vS3qZ0jVTVWzbtfapwm5ztxw=="], + "@ucast/core": ["@ucast/core@1.10.2", "", {}, "sha512-ons5CwXZ/51wrUPfoduC+cO7AS1/wRb0ybpQJ9RrssossDxVy4t49QxWoWgfBDvVKsz9VXzBk9z0wqTdZ+Cq8g=="], + + "@ucast/js": ["@ucast/js@3.0.4", "", { "dependencies": { "@ucast/core": "^1.0.0" } }, "sha512-TgG1aIaCMdcaEyckOZKQozn1hazE0w90SVdlpIJ/er8xVumE11gYAtSbw/LBeUnA4fFnFWTcw3t6reqseeH/4Q=="], + + "@ucast/mongo": ["@ucast/mongo@2.4.3", "", { "dependencies": { "@ucast/core": "^1.4.1" } }, "sha512-XcI8LclrHWP83H+7H2anGCEeDq0n+12FU2mXCTz6/Tva9/9ddK/iacvvhCyW6cijAAOILmt0tWplRyRhVyZLsA=="], + + "@ucast/mongo2js": ["@ucast/mongo2js@1.4.0", "", { "dependencies": { "@ucast/core": "^1.6.1", "@ucast/js": "^3.0.0", "@ucast/mongo": "^2.4.0" } }, "sha512-vR9RJ3BHlkI3RfKJIZFdVktxWvBCQRiSTeJSWN9NPxP5YJkpfXvcBWAMLwvyJx4HbB+qib5/AlSDEmQiuQyx2w=="], + "@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="], "@unrs/resolver-binding-android-arm-eabi": ["@unrs/resolver-binding-android-arm-eabi@1.9.0", "", { "os": "android", "cpu": "arm" }, "sha512-h1T2c2Di49ekF2TE8ZCoJkb+jwETKUIPDJ/nO3tJBKlLFPu+fyd93f0rGP/BvArKx2k2HlRM4kqkNarj3dvZlg=="], diff --git a/package.json b/package.json index 993e520..8242a6e 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "test:e2e": "jest --config ./test/jest-e2e.json" }, "dependencies": { + "@casl/ability": "^6.7.3", "@fastify/static": "^8.2.0", "@nestjs/common": "^11.1.3", "@nestjs/core": "^11.1.3", diff --git a/src/modules/user/entities/user.entity.ts b/src/modules/user/entities/user.entity.ts index 7b2021e..136ab93 100644 --- a/src/modules/user/entities/user.entity.ts +++ b/src/modules/user/entities/user.entity.ts @@ -5,12 +5,15 @@ import { CreateDateColumn, DeleteDateColumn, Entity, + ManyToMany, OneToMany, PrimaryColumn, UpdateDateColumn, } from 'typeorm'; import { CommentEntity, PostEntity } from '@/modules/content/entities'; +import { PermissionEntity } from '@/modules/rbac/entities/permission.entity'; +import { RoleEntity } from '@/modules/rbac/entities/role.entity'; import { AccessTokenEntity } from '@/modules/user/entities/access.token.entity'; /** @@ -101,4 +104,18 @@ export class UserEntity { */ @OneToMany(() => AccessTokenEntity, (token) => token.user, { cascade: true }) accessTokens: Relation[]; + + /** + * 用户权限 + */ + @Expose() + @ManyToMany(() => PermissionEntity, (permission) => permission.users, { cascade: true }) + permissions: Relation[]; + + /** + * 用户角色 + */ + @Expose() + @ManyToMany(() => RoleEntity, (role) => role.users, { cascade: true }) + roles: Relation[]; }