@solidstarters/solid-core 1.2.174 → 1.2.175
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/dev-grooming-docs/ozzy-prompts.txt +13 -0
- package/dist/config/iam.config.js +2 -2
- package/dist/config/iam.config.js.map +1 -1
- package/dist/constants/chatter-message.constants.d.ts +11 -0
- package/dist/constants/chatter-message.constants.d.ts.map +1 -0
- package/dist/constants/chatter-message.constants.js +14 -0
- package/dist/constants/chatter-message.constants.js.map +1 -0
- package/dist/controllers/authentication.controller.d.ts +1 -2
- package/dist/controllers/authentication.controller.d.ts.map +1 -1
- package/dist/controllers/chatter-message-details.controller.d.ts +0 -16
- package/dist/controllers/chatter-message-details.controller.d.ts.map +1 -1
- package/dist/controllers/chatter-message-details.controller.js +0 -109
- package/dist/controllers/chatter-message-details.controller.js.map +1 -1
- package/dist/controllers/chatter-message.controller.d.ts +10 -13
- package/dist/controllers/chatter-message.controller.d.ts.map +1 -1
- package/dist/controllers/chatter-message.controller.js +19 -88
- package/dist/controllers/chatter-message.controller.js.map +1 -1
- package/dist/entities/chatter-message-details.entity.d.ts +1 -0
- package/dist/entities/chatter-message-details.entity.d.ts.map +1 -1
- package/dist/entities/chatter-message-details.entity.js +5 -1
- package/dist/entities/chatter-message-details.entity.js.map +1 -1
- package/dist/entities/chatter-message.entity.d.ts +4 -0
- package/dist/entities/chatter-message.entity.d.ts.map +1 -1
- package/dist/entities/chatter-message.entity.js +14 -1
- package/dist/entities/chatter-message.entity.js.map +1 -1
- package/dist/seeders/seed-data/solid-core-metadata.json +39 -1
- package/dist/services/authentication.service.d.ts +2 -3
- package/dist/services/authentication.service.d.ts.map +1 -1
- package/dist/services/authentication.service.js +4 -4
- package/dist/services/authentication.service.js.map +1 -1
- package/dist/services/chatter-message.service.d.ts +16 -3
- package/dist/services/chatter-message.service.d.ts.map +1 -1
- package/dist/services/chatter-message.service.js +120 -25
- package/dist/services/chatter-message.service.js.map +1 -1
- package/dist/services/refresh-token-ids-storage.service.d.ts +2 -1
- package/dist/services/refresh-token-ids-storage.service.d.ts.map +1 -1
- package/dist/services/refresh-token-ids-storage.service.js +6 -7
- package/dist/services/refresh-token-ids-storage.service.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/config/iam.config.ts +2 -2
- package/src/constants/chatter-message.constants.ts +11 -0
- package/src/controllers/chatter-message-details.controller.ts +44 -44
- package/src/controllers/chatter-message.controller.ts +58 -38
- package/src/entities/chatter-message-details.entity.ts +3 -0
- package/src/entities/chatter-message.entity.ts +9 -2
- package/src/seeders/seed-data/solid-core-metadata.json +39 -1
- package/src/services/authentication.service.ts +9 -4
- package/src/services/chatter-message.service.ts +143 -24
- package/src/services/refresh-token-ids-storage.service.ts +11 -7
|
@@ -19,6 +19,10 @@ import { RequestContextService } from './request-context.service';
|
|
|
19
19
|
import { ChatterMessageRepository } from 'src/repository/chatter-message.repository';
|
|
20
20
|
import { lowerFirst } from 'src/helpers/string.helper';
|
|
21
21
|
import { ModelMetadataHelperService } from 'src/helpers/model-metadata-helper.service';
|
|
22
|
+
import { ChatterMessageDetailsRepository } from 'src/repository/chatter-message-details.repository';
|
|
23
|
+
import { FieldMetadata } from 'src/entities/field-metadata.entity';
|
|
24
|
+
import { CHATTER_MESSAGE_TYPE, CHATTER_MESSAGE_SUBTYPE } from 'src/constants/chatter-message.constants';
|
|
25
|
+
import { classify } from '@angular-devkit/core/src/utils/strings';
|
|
22
26
|
@Injectable()
|
|
23
27
|
export class ChatterMessageService extends CRUDService<ChatterMessage> {
|
|
24
28
|
constructor(
|
|
@@ -32,8 +36,10 @@ export class ChatterMessageService extends CRUDService<ChatterMessage> {
|
|
|
32
36
|
readonly entityManager: EntityManager,
|
|
33
37
|
// @InjectRepository(ChatterMessage, 'default')
|
|
34
38
|
readonly repo: ChatterMessageRepository,
|
|
35
|
-
@InjectRepository(
|
|
36
|
-
readonly chatterMessageDetailsRepo:
|
|
39
|
+
// @InjectRepository(ChatterMessageDetailsRepository, 'default')
|
|
40
|
+
readonly chatterMessageDetailsRepo: ChatterMessageDetailsRepository,
|
|
41
|
+
@InjectRepository(FieldMetadata, 'default')
|
|
42
|
+
readonly fieldMetadataRepo: Repository<FieldMetadata>,
|
|
37
43
|
readonly moduleRef: ModuleRef,
|
|
38
44
|
@InjectRepository(ModelMetadata)
|
|
39
45
|
private readonly modelMetadataRepo: Repository<ModelMetadata>,
|
|
@@ -45,8 +51,8 @@ export class ChatterMessageService extends CRUDService<ChatterMessage> {
|
|
|
45
51
|
|
|
46
52
|
async postMessage(postDto: PostChatterMessageDto, files: Express.Multer.File[] = []) {
|
|
47
53
|
const chatterMessage = new ChatterMessage();
|
|
48
|
-
chatterMessage.messageType =
|
|
49
|
-
chatterMessage.messageSubType = postDto.messageSubType ||
|
|
54
|
+
chatterMessage.messageType = CHATTER_MESSAGE_TYPE.CUSTOM;
|
|
55
|
+
chatterMessage.messageSubType = postDto.messageSubType || CHATTER_MESSAGE_SUBTYPE.CUSTOM;
|
|
50
56
|
chatterMessage.messageBody = postDto.messageBody;
|
|
51
57
|
chatterMessage.coModelEntityId = postDto.coModelEntityId;
|
|
52
58
|
chatterMessage.coModelName = postDto.coModelName;
|
|
@@ -97,7 +103,8 @@ export class ChatterMessageService extends CRUDService<ChatterMessage> {
|
|
|
97
103
|
},
|
|
98
104
|
relations: {
|
|
99
105
|
fields: true,
|
|
100
|
-
module: true
|
|
106
|
+
module: true,
|
|
107
|
+
userKeyField: true
|
|
101
108
|
}
|
|
102
109
|
});
|
|
103
110
|
|
|
@@ -114,11 +121,13 @@ export class ChatterMessageService extends CRUDService<ChatterMessage> {
|
|
|
114
121
|
const activeUser = this.requestContextService.getActiveUser();
|
|
115
122
|
|
|
116
123
|
const chatterMessage = new ChatterMessage();
|
|
117
|
-
chatterMessage.messageType =
|
|
118
|
-
chatterMessage.messageSubType =
|
|
124
|
+
chatterMessage.messageType = CHATTER_MESSAGE_TYPE.AUDIT;
|
|
125
|
+
chatterMessage.messageSubType = CHATTER_MESSAGE_SUBTYPE.AUDIT_INSERT;
|
|
119
126
|
chatterMessage.coModelEntityId = entity.id;
|
|
120
|
-
chatterMessage.coModelName = model
|
|
121
|
-
chatterMessage.
|
|
127
|
+
chatterMessage.coModelName = model?.singularName;
|
|
128
|
+
chatterMessage.modelDisplayName = model?.displayName;
|
|
129
|
+
chatterMessage.modelUserKey = entity[model?.userKeyField?.name];
|
|
130
|
+
chatterMessage.messageBody = `New ${model?.displayName} created`;
|
|
122
131
|
|
|
123
132
|
if (activeUser) {
|
|
124
133
|
const userId = activeUser?.sub;
|
|
@@ -135,6 +144,7 @@ export class ChatterMessageService extends CRUDService<ChatterMessage> {
|
|
|
135
144
|
const messageDetail = new ChatterMessageDetails();
|
|
136
145
|
messageDetail.chatterMessage = savedMessage;
|
|
137
146
|
messageDetail.fieldName = field.name;
|
|
147
|
+
messageDetail.fieldDisplayName = field.displayName;
|
|
138
148
|
messageDetail.oldValue = null;
|
|
139
149
|
messageDetail.oldValueDisplay = null;
|
|
140
150
|
messageDetail.newValue = this.formatFieldValue(field, fieldValue);
|
|
@@ -154,7 +164,8 @@ export class ChatterMessageService extends CRUDService<ChatterMessage> {
|
|
|
154
164
|
},
|
|
155
165
|
relations: {
|
|
156
166
|
fields: true,
|
|
157
|
-
module: true
|
|
167
|
+
module: true,
|
|
168
|
+
userKeyField: true
|
|
158
169
|
}
|
|
159
170
|
});
|
|
160
171
|
|
|
@@ -228,11 +239,13 @@ export class ChatterMessageService extends CRUDService<ChatterMessage> {
|
|
|
228
239
|
const activeUser = this.requestContextService.getActiveUser();
|
|
229
240
|
|
|
230
241
|
const chatterMessage = new ChatterMessage();
|
|
231
|
-
chatterMessage.messageType =
|
|
232
|
-
chatterMessage.messageSubType =
|
|
233
|
-
chatterMessage.coModelEntityId = entity
|
|
234
|
-
chatterMessage.coModelName = model
|
|
235
|
-
chatterMessage.
|
|
242
|
+
chatterMessage.messageType = CHATTER_MESSAGE_TYPE.AUDIT;
|
|
243
|
+
chatterMessage.messageSubType = CHATTER_MESSAGE_SUBTYPE.AUDIT_UPDATE;
|
|
244
|
+
chatterMessage.coModelEntityId = entity?.id;
|
|
245
|
+
chatterMessage.coModelName = model?.singularName;
|
|
246
|
+
chatterMessage.modelDisplayName = model.displayName;
|
|
247
|
+
chatterMessage.modelUserKey = entity[model?.userKeyField?.name];
|
|
248
|
+
chatterMessage.messageBody = `${model?.displayName} updated`;
|
|
236
249
|
|
|
237
250
|
if (activeUser) {
|
|
238
251
|
const userId = activeUser?.sub;
|
|
@@ -247,6 +260,7 @@ export class ChatterMessageService extends CRUDService<ChatterMessage> {
|
|
|
247
260
|
const messageDetail = new ChatterMessageDetails();
|
|
248
261
|
messageDetail.chatterMessage = savedMessage;
|
|
249
262
|
messageDetail.fieldName = field.name;
|
|
263
|
+
messageDetail.fieldDisplayName = field.displayName;
|
|
250
264
|
messageDetail.oldValue = this.formatFieldValue(field, oldValue);
|
|
251
265
|
messageDetail.newValue = this.formatFieldValue(field, newValue);
|
|
252
266
|
messageDetail.oldValueDisplay = this.formatFieldValueDisplay(field, oldValue);
|
|
@@ -262,7 +276,8 @@ export class ChatterMessageService extends CRUDService<ChatterMessage> {
|
|
|
262
276
|
},
|
|
263
277
|
relations: {
|
|
264
278
|
fields: true,
|
|
265
|
-
module: true
|
|
279
|
+
module: true,
|
|
280
|
+
userKeyField: true
|
|
266
281
|
}
|
|
267
282
|
});
|
|
268
283
|
|
|
@@ -271,11 +286,13 @@ export class ChatterMessageService extends CRUDService<ChatterMessage> {
|
|
|
271
286
|
}
|
|
272
287
|
|
|
273
288
|
const chatterMessage = new ChatterMessage();
|
|
274
|
-
chatterMessage.messageType =
|
|
275
|
-
chatterMessage.messageSubType =
|
|
276
|
-
chatterMessage.coModelEntityId = databaseEntity
|
|
277
|
-
chatterMessage.coModelName = model
|
|
278
|
-
chatterMessage.
|
|
289
|
+
chatterMessage.messageType = CHATTER_MESSAGE_TYPE.AUDIT;
|
|
290
|
+
chatterMessage.messageSubType = CHATTER_MESSAGE_SUBTYPE.AUDIT_DELETE;
|
|
291
|
+
chatterMessage.coModelEntityId = databaseEntity?.id;
|
|
292
|
+
chatterMessage.coModelName = model?.singularName;
|
|
293
|
+
chatterMessage.modelDisplayName = model?.displayName;
|
|
294
|
+
chatterMessage.modelUserKey = entity[model?.userKeyField?.name];
|
|
295
|
+
chatterMessage.messageBody = `${model?.displayName} deleted`;
|
|
279
296
|
|
|
280
297
|
const activeUser = this.requestContextService.getActiveUser();
|
|
281
298
|
|
|
@@ -302,7 +319,7 @@ export class ChatterMessageService extends CRUDService<ChatterMessage> {
|
|
|
302
319
|
if (field.relationType === "many-to-one") {
|
|
303
320
|
return value.id;
|
|
304
321
|
}
|
|
305
|
-
if (field.relationType === '
|
|
322
|
+
if (field.relationType === 'many-to-many') {
|
|
306
323
|
return value.map(item => item.id).join(', ');
|
|
307
324
|
}
|
|
308
325
|
}
|
|
@@ -324,7 +341,7 @@ export class ChatterMessageService extends CRUDService<ChatterMessage> {
|
|
|
324
341
|
if (field.relationType === "many-to-one") {
|
|
325
342
|
return value.name;
|
|
326
343
|
}
|
|
327
|
-
if (field.relationType === 'many-
|
|
344
|
+
if (field.relationType === 'many-to-many') {
|
|
328
345
|
return value.map(item => item.name).join(', ');
|
|
329
346
|
}
|
|
330
347
|
}
|
|
@@ -383,7 +400,7 @@ export class ChatterMessageService extends CRUDService<ChatterMessage> {
|
|
|
383
400
|
return newId !== oldId;
|
|
384
401
|
}
|
|
385
402
|
|
|
386
|
-
if (field.relationType === 'many-to-many'
|
|
403
|
+
if (field.relationType === 'many-to-many') {
|
|
387
404
|
const newIds = this.extractRelationIds(newValue);
|
|
388
405
|
const oldIds = this.extractRelationIds(oldValue);
|
|
389
406
|
|
|
@@ -469,4 +486,106 @@ export class ChatterMessageService extends CRUDService<ChatterMessage> {
|
|
|
469
486
|
|
|
470
487
|
return populatedEntity;
|
|
471
488
|
}
|
|
489
|
+
|
|
490
|
+
async getChatterMessages(
|
|
491
|
+
entityId: number,
|
|
492
|
+
entityName: string,
|
|
493
|
+
query: any
|
|
494
|
+
) {
|
|
495
|
+
const { limit = 25, offset = 0, sort, populate = [] } = query;
|
|
496
|
+
|
|
497
|
+
const model = await this.modelMetadataRepo.findOne({
|
|
498
|
+
where: {
|
|
499
|
+
singularName: entityName
|
|
500
|
+
},
|
|
501
|
+
});
|
|
502
|
+
const oneToManyFields = await this.fieldMetadataRepo.find({
|
|
503
|
+
where: {
|
|
504
|
+
model: { id: model.id },
|
|
505
|
+
type: 'relation',
|
|
506
|
+
relationType: 'one-to-many'
|
|
507
|
+
}
|
|
508
|
+
});
|
|
509
|
+
|
|
510
|
+
const relatedEntitiesMap = new Map<string, number[]>();
|
|
511
|
+
|
|
512
|
+
for (const field of oneToManyFields) {
|
|
513
|
+
const coModelName = field.relationCoModelSingularName;
|
|
514
|
+
const coModelFieldName = field.relationCoModelFieldName;
|
|
515
|
+
|
|
516
|
+
const coModel = await this.modelMetadataRepo.findOne({
|
|
517
|
+
where: { singularName: coModelName }
|
|
518
|
+
});
|
|
519
|
+
|
|
520
|
+
if (coModel) {
|
|
521
|
+
const relatedEntityRepository = this.entityManager.getRepository(classify(coModelName));
|
|
522
|
+
|
|
523
|
+
const relatedEntities = await relatedEntityRepository.find({
|
|
524
|
+
where: { [coModelFieldName]: { id: entityId } }
|
|
525
|
+
});
|
|
526
|
+
|
|
527
|
+
const relatedIds = relatedEntities.map((entity: any) => entity.id);
|
|
528
|
+
relatedEntitiesMap.set(field.name, relatedIds);
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
const qb = this.repo.createQueryBuilder('entity');
|
|
533
|
+
|
|
534
|
+
const orConditions: string[] = [];
|
|
535
|
+
const parameters: any = {};
|
|
536
|
+
|
|
537
|
+
orConditions.push('(entity.coModelName = :entityName AND entity.coModelEntityId = :entityId)');
|
|
538
|
+
parameters.entityName = entityName;
|
|
539
|
+
parameters.entityId = entityId;
|
|
540
|
+
|
|
541
|
+
let paramIndex = 0;
|
|
542
|
+
for (const [fieldName, relatedIds] of relatedEntitiesMap.entries()) {
|
|
543
|
+
if (relatedIds.length > 0) {
|
|
544
|
+
const field = oneToManyFields.find(f => f.name === fieldName);
|
|
545
|
+
if (field) {
|
|
546
|
+
const coModelName = field.relationCoModelSingularName;
|
|
547
|
+
const idsParamName = `relatedIds${paramIndex}`;
|
|
548
|
+
orConditions.push(`(entity.coModelName = :coModelName${paramIndex} AND entity.coModelEntityId IN (:...${idsParamName}))`);
|
|
549
|
+
parameters[`coModelName${paramIndex}`] = coModelName;
|
|
550
|
+
parameters[idsParamName] = relatedIds;
|
|
551
|
+
paramIndex++;
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
qb.where(orConditions.join(' OR '), parameters);
|
|
557
|
+
|
|
558
|
+
const relations = ['chatterMessageDetails', 'user'];
|
|
559
|
+
if (populate && populate.length > 0) {
|
|
560
|
+
const normalizedPopulate = this.crudHelperService.normalize(populate);
|
|
561
|
+
relations.push(...normalizedPopulate.filter(rel => !relations.includes(rel)));
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
relations.forEach(relation => {
|
|
565
|
+
qb.leftJoinAndSelect(`entity.${relation}`, relation);
|
|
566
|
+
});
|
|
567
|
+
|
|
568
|
+
qb.orderBy('entity.createdAt', 'DESC');
|
|
569
|
+
|
|
570
|
+
qb.skip(offset).take(limit);
|
|
571
|
+
|
|
572
|
+
const [entities, count] = await qb.getManyAndCount();
|
|
573
|
+
|
|
574
|
+
const currentPage = Math.floor(offset / limit) + 1;
|
|
575
|
+
const totalPages = Math.ceil(count / limit);
|
|
576
|
+
const nextPage = currentPage < totalPages ? currentPage + 1 : null;
|
|
577
|
+
const prevPage = currentPage > 1 ? currentPage - 1 : null;
|
|
578
|
+
|
|
579
|
+
return {
|
|
580
|
+
meta: {
|
|
581
|
+
totalRecords: count,
|
|
582
|
+
currentPage: currentPage,
|
|
583
|
+
nextPage: nextPage,
|
|
584
|
+
prevPage: prevPage,
|
|
585
|
+
totalPages: totalPages,
|
|
586
|
+
perPage: +limit,
|
|
587
|
+
},
|
|
588
|
+
records: entities
|
|
589
|
+
};
|
|
590
|
+
}
|
|
472
591
|
}
|
|
@@ -28,13 +28,13 @@ export class RefreshTokenIdsStorageService {
|
|
|
28
28
|
private readonly authenticationService: AuthenticationService
|
|
29
29
|
) { }
|
|
30
30
|
|
|
31
|
-
async insert(userId: number, refreshToken: string): Promise<void> {
|
|
31
|
+
async insert(userId: number, refreshToken: string, previousRefreshToken?: string): Promise<void> {
|
|
32
32
|
// TODO: save a refresh token object with this shape {"currentRefreshToken": "", "previousRefreshToken": ""}
|
|
33
33
|
// Save a refresh token object with the shape: { currentRefreshToken: string, previousRefreshToken: string }
|
|
34
34
|
const existing = (await this.cacheManager.get(this.getKey(userId))) as { currentRefreshToken?: string, previousRefreshToken?: string } | undefined;
|
|
35
35
|
const refreshTokenState = {
|
|
36
36
|
currentRefreshToken: refreshToken,
|
|
37
|
-
previousRefreshToken: "",
|
|
37
|
+
previousRefreshToken: previousRefreshToken ?? "",
|
|
38
38
|
};
|
|
39
39
|
await this.cacheManager.set(this.getKey(userId), refreshTokenState);
|
|
40
40
|
}
|
|
@@ -84,14 +84,14 @@ export class RefreshTokenIdsStorageService {
|
|
|
84
84
|
// Scenario 1: Token matches currentRefreshToken
|
|
85
85
|
valid = true;
|
|
86
86
|
// Rotate tokens: move current to previous, set new current (simulate generation)
|
|
87
|
-
newRefreshToken = await this.authenticationService.generateRefreshToken(user); // Replace with real token generation logic
|
|
87
|
+
newRefreshToken = await this.authenticationService.generateRefreshToken(user, refreshTokenState.currentRefreshToken); // Replace with real token generation logic
|
|
88
88
|
|
|
89
89
|
|
|
90
90
|
// updated cache state
|
|
91
|
-
await this.cacheManager.set(this.getKey(user.id), {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
});
|
|
91
|
+
// await this.cacheManager.set(this.getKey(user.id), {
|
|
92
|
+
// currentRefreshToken: newRefreshToken,
|
|
93
|
+
// previousRefreshToken: refreshTokenState.currentRefreshToken,
|
|
94
|
+
// });
|
|
95
95
|
|
|
96
96
|
// Optionally, set a timeout to clear previousRefreshToken after X minutes
|
|
97
97
|
setTimeout(async () => {
|
|
@@ -125,4 +125,8 @@ export class RefreshTokenIdsStorageService {
|
|
|
125
125
|
private getKey(userId: number): string {
|
|
126
126
|
return `user-${userId}`;
|
|
127
127
|
}
|
|
128
|
+
|
|
129
|
+
getCurrentRefreshTokenState(userId: number): Promise<any> {
|
|
130
|
+
return this.cacheManager.get(this.getKey(userId));
|
|
131
|
+
}
|
|
128
132
|
}
|