@solidstarters/solid-core 1.2.48 → 1.2.49

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.
Files changed (105) hide show
  1. package/dist/controllers/security-rule.controller.d.ts +41 -0
  2. package/dist/controllers/security-rule.controller.d.ts.map +1 -0
  3. package/dist/controllers/security-rule.controller.js +179 -0
  4. package/dist/controllers/security-rule.controller.js.map +1 -0
  5. package/dist/dtos/create-model-metadata.dto.d.ts +3 -0
  6. package/dist/dtos/create-model-metadata.dto.d.ts.map +1 -1
  7. package/dist/dtos/create-model-metadata.dto.js +18 -1
  8. package/dist/dtos/create-model-metadata.dto.js.map +1 -1
  9. package/dist/dtos/create-security-rule.dto.d.ts +10 -0
  10. package/dist/dtos/create-security-rule.dto.d.ts.map +1 -0
  11. package/dist/dtos/create-security-rule.dto.js +65 -0
  12. package/dist/dtos/create-security-rule.dto.js.map +1 -0
  13. package/dist/dtos/security-rule-config.dto.d.ts +4 -0
  14. package/dist/dtos/security-rule-config.dto.d.ts.map +1 -0
  15. package/dist/dtos/security-rule-config.dto.js +4 -0
  16. package/dist/dtos/security-rule-config.dto.js.map +1 -0
  17. package/dist/dtos/update-security-rule.dto.d.ts +11 -0
  18. package/dist/dtos/update-security-rule.dto.d.ts.map +1 -0
  19. package/dist/dtos/update-security-rule.dto.js +72 -0
  20. package/dist/dtos/update-security-rule.dto.js.map +1 -0
  21. package/dist/entities/model-metadata.entity.d.ts +2 -0
  22. package/dist/entities/model-metadata.entity.d.ts.map +1 -1
  23. package/dist/entities/model-metadata.entity.js +9 -1
  24. package/dist/entities/model-metadata.entity.js.map +1 -1
  25. package/dist/entities/security-rule.entity.d.ts +11 -0
  26. package/dist/entities/security-rule.entity.d.ts.map +1 -0
  27. package/dist/entities/security-rule.entity.js +53 -0
  28. package/dist/entities/security-rule.entity.js.map +1 -0
  29. package/dist/entities/user.entity.d.ts.map +1 -1
  30. package/dist/entities/user.entity.js +2 -1
  31. package/dist/entities/user.entity.js.map +1 -1
  32. package/dist/helpers/solid-registry.d.ts +22 -1
  33. package/dist/helpers/solid-registry.d.ts.map +1 -1
  34. package/dist/helpers/solid-registry.js +29 -0
  35. package/dist/helpers/solid-registry.js.map +1 -1
  36. package/dist/index.d.ts +7 -0
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +7 -0
  39. package/dist/index.js.map +1 -1
  40. package/dist/interfaces.d.ts +2 -0
  41. package/dist/interfaces.d.ts.map +1 -1
  42. package/dist/interfaces.js.map +1 -1
  43. package/dist/repository/security-rule.repository.d.ts +20 -0
  44. package/dist/repository/security-rule.repository.d.ts.map +1 -0
  45. package/dist/repository/security-rule.repository.js +128 -0
  46. package/dist/repository/security-rule.repository.js.map +1 -0
  47. package/dist/repository/solid-base.repository.d.ts +14 -0
  48. package/dist/repository/solid-base.repository.d.ts.map +1 -0
  49. package/dist/repository/solid-base.repository.js +26 -0
  50. package/dist/repository/solid-base.repository.js.map +1 -0
  51. package/dist/seeders/module-metadata-seeder.service.d.ts +5 -1
  52. package/dist/seeders/module-metadata-seeder.service.d.ts.map +1 -1
  53. package/dist/seeders/module-metadata-seeder.service.js +22 -2
  54. package/dist/seeders/module-metadata-seeder.service.js.map +1 -1
  55. package/dist/seeders/seed-data/solid-core-metadata.json +263 -0
  56. package/dist/services/field-metadata.service.d.ts.map +1 -1
  57. package/dist/services/field-metadata.service.js +1 -0
  58. package/dist/services/field-metadata.service.js.map +1 -1
  59. package/dist/services/module-metadata.service.d.ts.map +1 -1
  60. package/dist/services/module-metadata.service.js +1 -0
  61. package/dist/services/module-metadata.service.js.map +1 -1
  62. package/dist/services/request-context.service.d.ts +7 -0
  63. package/dist/services/request-context.service.d.ts.map +1 -0
  64. package/dist/services/request-context.service.js +33 -0
  65. package/dist/services/request-context.service.js.map +1 -0
  66. package/dist/services/security-rule.service.d.ts +27 -0
  67. package/dist/services/security-rule.service.d.ts.map +1 -0
  68. package/dist/services/security-rule.service.js +71 -0
  69. package/dist/services/security-rule.service.js.map +1 -0
  70. package/dist/services/view-metadata.service.d.ts +1 -0
  71. package/dist/services/view-metadata.service.d.ts.map +1 -1
  72. package/dist/services/view-metadata.service.js +22 -7
  73. package/dist/services/view-metadata.service.js.map +1 -1
  74. package/dist/solid-core.module.d.ts.map +1 -1
  75. package/dist/solid-core.module.js +15 -1
  76. package/dist/solid-core.module.js.map +1 -1
  77. package/dist/subscribers/security-rule.subscriber.d.ts +16 -0
  78. package/dist/subscribers/security-rule.subscriber.d.ts.map +1 -0
  79. package/dist/subscribers/security-rule.subscriber.js +123 -0
  80. package/dist/subscribers/security-rule.subscriber.js.map +1 -0
  81. package/dist/tsconfig.tsbuildinfo +1 -1
  82. package/package.json +1 -1
  83. package/src/controllers/security-rule.controller.ts +93 -0
  84. package/src/dtos/create-model-metadata.dto.ts +14 -0
  85. package/src/dtos/create-security-rule.dto.ts +34 -0
  86. package/src/dtos/security-rule-config.dto.ts +5 -0
  87. package/src/dtos/update-security-rule.dto.ts +39 -0
  88. package/src/entities/model-metadata.entity.ts +6 -0
  89. package/src/entities/security-rule.entity.ts +25 -0
  90. package/src/entities/user.entity.ts +2 -1
  91. package/src/helpers/solid-registry.ts +34 -0
  92. package/src/index.ts +9 -0
  93. package/src/interfaces.ts +2 -0
  94. package/src/repository/security-rule.repository.ts +135 -0
  95. package/src/repository/solid-base.repository.ts +45 -0
  96. package/src/seeders/module-metadata-seeder.service.ts +28 -1
  97. package/src/seeders/seed-data/solid-core-metadata.json +264 -0
  98. package/src/seeders/seed-data/solid-core-metadata.json.bkp +6638 -0
  99. package/src/services/field-metadata.service.ts +1 -0
  100. package/src/services/module-metadata.service.ts +1 -0
  101. package/src/services/request-context.service.ts +16 -0
  102. package/src/services/security-rule.service.ts +54 -0
  103. package/src/services/view-metadata.service.ts +26 -7
  104. package/src/solid-core.module.ts +15 -1
  105. package/src/subscribers/security-rule.subscriber.ts +78 -0
@@ -739,6 +739,7 @@ export class FieldMetadataService {
739
739
  "relationCoModelSingularName",
740
740
  "relationCoModelColumnName",
741
741
  "relationModelModuleName",
742
+ "relationCascade",
742
743
  "required",
743
744
  "unique",
744
745
  "index",
@@ -150,6 +150,7 @@ export class ModuleMetadataService {
150
150
  emailTemplates: [],
151
151
  smsTemplates: [],
152
152
  mediaStorageProviders: [],
153
+ securityRules: [],
153
154
  };
154
155
 
155
156
  // Convert the object to JSON string
@@ -0,0 +1,16 @@
1
+ import { Inject, Injectable, Scope } from "@nestjs/common";
2
+ import { REQUEST } from "@nestjs/core";
3
+ import { REQUEST_USER_KEY } from "src/constants";
4
+ import { ActiveUserData } from "src/interfaces/active-user-data.interface";
5
+
6
+ @Injectable({scope: Scope.REQUEST})
7
+ export class RequestContextService {
8
+ constructor(@Inject(REQUEST) private readonly request: Request) {
9
+ }
10
+
11
+ // This method i.e getActiveUser() will fetch the user from the request object in the context
12
+ getActiveUser() {
13
+ return this.request[REQUEST_USER_KEY] as ActiveUserData| undefined;
14
+ }
15
+
16
+ }
@@ -0,0 +1,54 @@
1
+ import { Injectable, OnApplicationBootstrap } from '@nestjs/common';
2
+ import { InjectEntityManager, InjectRepository } from '@nestjs/typeorm';
3
+ import { DiscoveryService, ModuleRef } from "@nestjs/core";
4
+ import { EntityManager, Repository } from 'typeorm';
5
+
6
+ import { CRUDService } from 'src/services/crud.service';
7
+ import { ModelMetadataService } from 'src/services/model-metadata.service';
8
+ import { ModuleMetadataService } from 'src/services/module-metadata.service';
9
+ import { ConfigService } from '@nestjs/config';
10
+ import { FileService } from 'src/services/file.service';
11
+ import { CrudHelperService } from 'src/services/crud-helper.service';
12
+
13
+
14
+ import { SecurityRule } from '../entities/security-rule.entity';
15
+ import { SolidRegistry } from 'src/helpers/solid-registry';
16
+
17
+ @Injectable()
18
+ export class SecurityRuleService extends CRUDService<SecurityRule> implements OnApplicationBootstrap {
19
+ constructor(
20
+ readonly modelMetadataService: ModelMetadataService,
21
+ readonly moduleMetadataService: ModuleMetadataService,
22
+ readonly configService: ConfigService,
23
+ readonly fileService: FileService,
24
+ readonly discoveryService: DiscoveryService,
25
+ readonly crudHelperService: CrudHelperService,
26
+ @InjectEntityManager()
27
+ readonly entityManager: EntityManager,
28
+ @InjectRepository(SecurityRule, 'default')
29
+ readonly repo: Repository<SecurityRule>,
30
+ readonly moduleRef: ModuleRef,
31
+ readonly solidRegistry: SolidRegistry,
32
+
33
+ ) {
34
+ super(modelMetadataService, moduleMetadataService, configService, fileService, discoveryService, crudHelperService, entityManager, repo, 'securityRule', 'solid-core', moduleRef);
35
+ }
36
+
37
+ onApplicationBootstrap() {
38
+ // Load the security rules from the database
39
+ this.loadSecurityRules();
40
+ }
41
+
42
+ async loadSecurityRules() {
43
+ const securityRules = await this.repo.find(
44
+ {
45
+ relations: {
46
+ modelMetadata: true,
47
+ role: true,
48
+ }
49
+ }
50
+ );
51
+ this.solidRegistry.registerSecurityRules(securityRules);
52
+ }
53
+
54
+ }
@@ -108,13 +108,7 @@ export class ViewMetadataService extends CRUDService<ViewMetadata> {
108
108
  }
109
109
 
110
110
  // We also need to fetch a map of fields.
111
- const fields = await this.fieldMetadataRepo.find({
112
- where: {
113
- model: {
114
- singularName: modelName,
115
- }
116
- }
117
- });
111
+ const fields = await this.loadFieldHierarchy(modelName);
118
112
  const fieldsMap = new Map<string, FieldMetadata>();
119
113
  for (let i = 0; i < fields.length; i++) {
120
114
  const field = fields[i];
@@ -179,6 +173,31 @@ export class ViewMetadataService extends CRUDService<ViewMetadata> {
179
173
  return r;
180
174
  }
181
175
 
176
+ private async loadFieldHierarchy(modelName: any) {
177
+ const model = await this.modelMetadataRepo.findOne({
178
+ where: {
179
+ singularName: modelName,
180
+ },
181
+ relations: {
182
+ fields: true,
183
+ parentModel: {
184
+ fields: true,
185
+ }
186
+ }
187
+ });
188
+ const fields = [];
189
+ if (model) {
190
+ // Add the fields of the current model
191
+ fields.push(...model.fields);
192
+
193
+ // Add the fields of the parent model
194
+ if (model.parentModel) {
195
+ fields.push(...model.parentModel.fields);
196
+ }
197
+ }
198
+ return fields;
199
+ }
200
+
182
201
  async findOneByUserKey(name: string, relations = {}) {
183
202
  const entity = await this.repo.findOne({
184
203
  where: {
@@ -144,6 +144,12 @@ import { ViewMetadataSubsciber } from './subscribers/view-metadata.subscriber';
144
144
  import { UserViewMetadata } from './entities/user-view-metadata.entity';
145
145
  import { UserViewMetadataService } from './services/user-view-metadata.service';
146
146
  import { UserViewMetadataController } from './controllers/user-view-metadata.controller';
147
+ import { SecurityRule } from './entities/security-rule.entity';
148
+ import { SecurityRuleService } from './services/security-rule.service';
149
+ import { SecurityRuleController } from './controllers/security-rule.controller';
150
+ import { RequestContextService } from './services/request-context.service';
151
+ import { SecurityRuleRepository } from './repository/security-rule.repository';
152
+ import { SecurityRuleSubscriber } from './subscribers/security-rule.subscriber';
147
153
 
148
154
 
149
155
  @Global()
@@ -189,6 +195,7 @@ import { UserViewMetadataController } from './controllers/user-view-metadata.con
189
195
  ConfigModule,
190
196
  TypeOrmModule.forFeature([Setting]),
191
197
  TypeOrmModule.forFeature([UserViewMetadata]),
198
+ TypeOrmModule.forFeature([SecurityRule]),
192
199
  // TypeOrmModule.forFeature([User]),
193
200
  ],
194
201
  controllers: [
@@ -215,6 +222,7 @@ import { UserViewMetadataController } from './controllers/user-view-metadata.con
215
222
  UserController,
216
223
  SettingController,
217
224
  UserViewMetadataController,
225
+ SecurityRuleController,
218
226
  ],
219
227
  providers: [
220
228
  {
@@ -309,7 +317,11 @@ import { UserViewMetadataController } from './controllers/user-view-metadata.con
309
317
  FileS3StorageProvider,
310
318
  MediaRepository,
311
319
  ViewMetadataSubsciber,
312
- UserViewMetadataService
320
+ UserViewMetadataService,
321
+ SecurityRuleService,
322
+ SecurityRuleRepository,
323
+ SecurityRuleSubscriber,
324
+ RequestContextService,
313
325
  ],
314
326
  exports: [
315
327
  ModuleMetadataService,
@@ -337,6 +349,8 @@ import { UserViewMetadataController } from './controllers/user-view-metadata.con
337
349
  MqMessageService,
338
350
  RefreshModelCommand,
339
351
  RefreshModuleCommand,
352
+ RequestContextService,
353
+ SecurityRuleRepository,
340
354
  ],
341
355
  })
342
356
  export class SolidCoreModule { }
@@ -0,0 +1,78 @@
1
+ import { Injectable, Logger } from '@nestjs/common';
2
+ import { InjectDataSource } from "@nestjs/typeorm";
3
+ import * as fs from 'fs/promises'; // Use the Promise-based version of fs for async/await
4
+ import { ModelMetadata } from 'src/entities/model-metadata.entity';
5
+ import { SecurityRule } from 'src/entities/security-rule.entity';
6
+ import { ModuleMetadataHelperService } from "src/helpers/module-metadata-helper.service";
7
+ import { SecurityRuleRepository } from 'src/repository/security-rule.repository';
8
+ import { DataSource, EntitySubscriberInterface, InsertEvent, UpdateEvent } from "typeorm";
9
+
10
+ @Injectable()
11
+ export class SecurityRuleSubscriber implements EntitySubscriberInterface<SecurityRule> {
12
+ private readonly logger = new Logger(SecurityRuleSubscriber.name);
13
+ constructor(
14
+ @InjectDataSource()
15
+ private readonly dataSource: DataSource,
16
+ readonly moduleMetadataHelperService: ModuleMetadataHelperService,
17
+ readonly securityRuleRepo: SecurityRuleRepository,
18
+ ) {
19
+ this.dataSource.subscribers.push(this);
20
+ }
21
+
22
+ listenTo() {
23
+ return SecurityRule;
24
+ }
25
+
26
+ async afterInsert(event: InsertEvent<SecurityRule>) {
27
+ await this.saveSecurityRules(event);
28
+ }
29
+
30
+ async afterUpdate(event: UpdateEvent<SecurityRule>) {
31
+ await this.saveSecurityRules(event);
32
+ }
33
+
34
+ async saveSecurityRules(event: UpdateEvent<SecurityRule>| InsertEvent<SecurityRule>) {
35
+ const securityRule = event.entity as SecurityRule;
36
+ const modelMetadata = event.entity.modelMetadata;
37
+ if (!modelMetadata) {
38
+ this.logger.error(`Model metadata not found for security rule with id ${event.entity.id}`);
39
+ return;
40
+ }
41
+
42
+ const modelMetadataRepo = this.dataSource.getRepository(ModelMetadata);
43
+ const populatedModelMetadata = await modelMetadataRepo.findOne({
44
+ where: {
45
+ id: modelMetadata.id
46
+ },
47
+ relations: {
48
+ module: true,
49
+ }
50
+ });
51
+
52
+ const filePath = this.moduleMetadataHelperService.getModuleMetadataFilePath(populatedModelMetadata.module.name);
53
+ try {
54
+ await fs.access(filePath);
55
+ } catch (error) {
56
+ // FIXME - Should we actually delete the security rule here, if the file is not found?
57
+ this.logger.error(`File not found at path: ${filePath}`);
58
+ return;
59
+ }
60
+ const metaData = await this.moduleMetadataHelperService.getModuleMetadataConfiguration(filePath);
61
+
62
+ if (metaData.securityRule) {
63
+ const securityRuleIndex = metaData.securityRules?.findIndex((ruleFromFile: { name: string }) => ruleFromFile.name === securityRule.name);
64
+ const {id, roleId, modelMetadataId, ...requiredDto} = await this.securityRuleRepo.toDto(securityRule)
65
+ metaData.securityRules[securityRuleIndex] = {requiredDto, securityRuleConfig: JSON.parse(securityRule.securityRuleConfig)}
66
+ }
67
+ else {
68
+ const securityRules = []
69
+ const {id, roleId, modelMetadataId, ...requiredDto} = await this.securityRuleRepo.toDto(securityRule)
70
+ securityRules.push({...requiredDto, securityRuleConfig: JSON.parse(securityRule.securityRuleConfig)})
71
+ metaData.securityRules = securityRules
72
+ }
73
+ // Write the updated object back to the file
74
+ const updatedContent = JSON.stringify(metaData, null, 2);
75
+ await fs.writeFile(filePath, updatedContent);
76
+ }
77
+
78
+ }