@solidstarters/solid-core 1.2.173 → 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/ai-interaction.controller.js +1 -1
- package/dist/controllers/ai-interaction.controller.js.map +1 -1
- 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/controllers/service.controller.js +2 -1
- package/dist/controllers/service.controller.js.map +1 -1
- package/dist/dtos/invoke-ai-prompt.dto.d.ts +1 -0
- package/dist/dtos/invoke-ai-prompt.dto.d.ts.map +1 -1
- package/dist/dtos/invoke-ai-prompt.dto.js +6 -1
- package/dist/dtos/invoke-ai-prompt.dto.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/entities/user.entity.d.ts +1 -0
- package/dist/entities/user.entity.d.ts.map +1 -1
- package/dist/entities/user.entity.js +5 -1
- package/dist/entities/user.entity.js.map +1 -1
- package/dist/interfaces.d.ts +2 -1
- package/dist/interfaces.d.ts.map +1 -1
- package/dist/interfaces.js.map +1 -1
- package/dist/jobs/database/trigger-mcp-client-subscriber-database.service.d.ts +3 -2
- package/dist/jobs/database/trigger-mcp-client-subscriber-database.service.d.ts.map +1 -1
- package/dist/jobs/database/trigger-mcp-client-subscriber-database.service.js +61 -22
- package/dist/jobs/database/trigger-mcp-client-subscriber-database.service.js.map +1 -1
- package/dist/repository/chatter-message-details.repository.d.ts.map +1 -1
- package/dist/repository/chatter-message-details.repository.js +7 -3
- package/dist/repository/chatter-message-details.repository.js.map +1 -1
- package/dist/repository/chatter-message.repository.d.ts.map +1 -1
- package/dist/repository/chatter-message.repository.js +4 -0
- package/dist/repository/chatter-message.repository.js.map +1 -1
- package/dist/seeders/seed-data/solid-core-metadata.json +78 -5
- package/dist/services/ai-interaction.service.d.ts +2 -1
- package/dist/services/ai-interaction.service.d.ts.map +1 -1
- package/dist/services/ai-interaction.service.js +15 -3
- package/dist/services/ai-interaction.service.js.map +1 -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/ai-interaction.controller.ts +1 -1
- package/src/controllers/chatter-message-details.controller.ts +44 -44
- package/src/controllers/chatter-message.controller.ts +58 -38
- package/src/controllers/service.controller.ts +2 -2
- package/src/dtos/invoke-ai-prompt.dto.ts +5 -1
- package/src/entities/chatter-message-details.entity.ts +3 -0
- package/src/entities/chatter-message.entity.ts +9 -2
- package/src/entities/user.entity.ts +2 -0
- package/src/interfaces.ts +2 -1
- package/src/jobs/database/trigger-mcp-client-subscriber-database.service.ts +108 -25
- package/src/repository/chatter-message-details.repository.ts +6 -5
- package/src/repository/chatter-message.repository.ts +2 -0
- package/src/seeders/seed-data/solid-core-metadata.json +78 -5
- package/src/services/ai-interaction.service.ts +24 -3
- 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
|
@@ -3748,7 +3748,8 @@
|
|
|
3748
3748
|
"selectionStaticValues": [
|
|
3749
3749
|
"audit_insert:audit_insert",
|
|
3750
3750
|
"audit_update:audit_update",
|
|
3751
|
-
"audit_delete:audit_delete"
|
|
3751
|
+
"audit_delete:audit_delete",
|
|
3752
|
+
"custom:custom"
|
|
3752
3753
|
]
|
|
3753
3754
|
},
|
|
3754
3755
|
{
|
|
@@ -3835,6 +3836,30 @@
|
|
|
3835
3836
|
"columnName": null,
|
|
3836
3837
|
"relationJoinTableName": "",
|
|
3837
3838
|
"isRelationManyToManyOwner": null
|
|
3839
|
+
},
|
|
3840
|
+
{
|
|
3841
|
+
"name": "modelDisplayName",
|
|
3842
|
+
"displayName": "Model Display Name",
|
|
3843
|
+
"type": "shortText",
|
|
3844
|
+
"ormType": "text",
|
|
3845
|
+
"required": false,
|
|
3846
|
+
"unique": false,
|
|
3847
|
+
"index": false,
|
|
3848
|
+
"private": false,
|
|
3849
|
+
"encrypt": false,
|
|
3850
|
+
"isSystem": false
|
|
3851
|
+
},
|
|
3852
|
+
{
|
|
3853
|
+
"name": "modelUserKey",
|
|
3854
|
+
"displayName": "Model User Key",
|
|
3855
|
+
"type": "shortText",
|
|
3856
|
+
"ormType": "text",
|
|
3857
|
+
"required": false,
|
|
3858
|
+
"unique": false,
|
|
3859
|
+
"index": false,
|
|
3860
|
+
"private": false,
|
|
3861
|
+
"encrypt": false,
|
|
3862
|
+
"isSystem": false
|
|
3838
3863
|
}
|
|
3839
3864
|
]
|
|
3840
3865
|
},
|
|
@@ -3910,6 +3935,19 @@
|
|
|
3910
3935
|
"encrypt": false,
|
|
3911
3936
|
"isSystem": false
|
|
3912
3937
|
},
|
|
3938
|
+
{
|
|
3939
|
+
"name": "fieldDisplayName",
|
|
3940
|
+
"displayName": "Field Display Name",
|
|
3941
|
+
"type": "shortText",
|
|
3942
|
+
"ormType": "varchar",
|
|
3943
|
+
"length": 512,
|
|
3944
|
+
"required": false,
|
|
3945
|
+
"unique": false,
|
|
3946
|
+
"index": false,
|
|
3947
|
+
"private": false,
|
|
3948
|
+
"encrypt": false,
|
|
3949
|
+
"isSystem": false
|
|
3950
|
+
},
|
|
3913
3951
|
{
|
|
3914
3952
|
"name": "chatterMessage",
|
|
3915
3953
|
"displayName": "Chatter Message",
|
|
@@ -12059,7 +12097,7 @@
|
|
|
12059
12097
|
{
|
|
12060
12098
|
"type": "field",
|
|
12061
12099
|
"attrs": {
|
|
12062
|
-
"name": "
|
|
12100
|
+
"name": "contentType"
|
|
12063
12101
|
}
|
|
12064
12102
|
},
|
|
12065
12103
|
{
|
|
@@ -12067,6 +12105,24 @@
|
|
|
12067
12105
|
"attrs": {
|
|
12068
12106
|
"name": "responseTimeMs"
|
|
12069
12107
|
}
|
|
12108
|
+
},
|
|
12109
|
+
{
|
|
12110
|
+
"type": "field",
|
|
12111
|
+
"attrs": {
|
|
12112
|
+
"name": "inputTokens"
|
|
12113
|
+
}
|
|
12114
|
+
},
|
|
12115
|
+
{
|
|
12116
|
+
"type": "field",
|
|
12117
|
+
"attrs": {
|
|
12118
|
+
"name": "outputTokens"
|
|
12119
|
+
}
|
|
12120
|
+
},
|
|
12121
|
+
{
|
|
12122
|
+
"type": "field",
|
|
12123
|
+
"attrs": {
|
|
12124
|
+
"name": "totalTokens"
|
|
12125
|
+
}
|
|
12070
12126
|
}
|
|
12071
12127
|
]
|
|
12072
12128
|
}
|
|
@@ -12184,6 +12240,24 @@
|
|
|
12184
12240
|
"attrs": {
|
|
12185
12241
|
"name": "parentInteraction"
|
|
12186
12242
|
}
|
|
12243
|
+
},
|
|
12244
|
+
{
|
|
12245
|
+
"type": "field",
|
|
12246
|
+
"attrs": {
|
|
12247
|
+
"name": "inputTokens"
|
|
12248
|
+
}
|
|
12249
|
+
},
|
|
12250
|
+
{
|
|
12251
|
+
"type": "field",
|
|
12252
|
+
"attrs": {
|
|
12253
|
+
"name": "outputTokens"
|
|
12254
|
+
}
|
|
12255
|
+
},
|
|
12256
|
+
{
|
|
12257
|
+
"type": "field",
|
|
12258
|
+
"attrs": {
|
|
12259
|
+
"name": "totalTokens"
|
|
12260
|
+
}
|
|
12187
12261
|
}
|
|
12188
12262
|
]
|
|
12189
12263
|
}
|
|
@@ -12249,7 +12323,7 @@
|
|
|
12249
12323
|
"type": "column",
|
|
12250
12324
|
"attrs": {
|
|
12251
12325
|
"name": "col-meta",
|
|
12252
|
-
"label": "
|
|
12326
|
+
"label": "",
|
|
12253
12327
|
"className": "col-12"
|
|
12254
12328
|
},
|
|
12255
12329
|
"children": [
|
|
@@ -12257,8 +12331,7 @@
|
|
|
12257
12331
|
"type": "field",
|
|
12258
12332
|
"attrs": {
|
|
12259
12333
|
"name": "metadata",
|
|
12260
|
-
"
|
|
12261
|
-
"editorLanguage": "json"
|
|
12334
|
+
"height": "80vh"
|
|
12262
12335
|
}
|
|
12263
12336
|
}
|
|
12264
12337
|
]
|
|
@@ -18,6 +18,7 @@ import { RequestContextService } from './request-context.service';
|
|
|
18
18
|
import { ActiveUserData } from 'src/interfaces/active-user-data.interface';
|
|
19
19
|
import { McpToolResponseHandlerFactory } from './mcp-tool-response-handlers/mcp-tool-response-handler-factory.service';
|
|
20
20
|
import { ERROR_MESSAGES } from 'src/constants/error-messages';
|
|
21
|
+
import { InvokeAiPromptDto } from 'src/dtos/invoke-ai-prompt.dto';
|
|
21
22
|
|
|
22
23
|
@Injectable()
|
|
23
24
|
export class AiInteractionService extends CRUDService<AiInteraction> {
|
|
@@ -43,14 +44,14 @@ export class AiInteractionService extends CRUDService<AiInteraction> {
|
|
|
43
44
|
super(modelMetadataService, moduleMetadataService, configService, fileService, discoveryService, crudHelperService, entityManager, repo, 'aiInteraction', 'solid-core', moduleRef);
|
|
44
45
|
}
|
|
45
46
|
|
|
46
|
-
async triggerMcpClientJob(
|
|
47
|
+
async triggerMcpClientJob(dto: InvokeAiPromptDto, userId: number, isAutoApply: boolean = false, threadId: string = null): Promise<any> {
|
|
47
48
|
// const activeUser: ActiveUserData = this.requestContextService.getActiveUser();
|
|
48
49
|
|
|
49
50
|
const aiInteraction = await this.create({
|
|
50
51
|
userId: userId,
|
|
51
52
|
threadId: threadId ? threadId : `thread-${userId}`,
|
|
52
53
|
role: 'human',
|
|
53
|
-
message: prompt,
|
|
54
|
+
message: dto.prompt,
|
|
54
55
|
contentType: '',
|
|
55
56
|
errorMessage: '',
|
|
56
57
|
modelUsed: '',
|
|
@@ -61,6 +62,7 @@ export class AiInteractionService extends CRUDService<AiInteraction> {
|
|
|
61
62
|
const m = {
|
|
62
63
|
payload: {
|
|
63
64
|
aiInteractionId: aiInteraction.id,
|
|
65
|
+
moduleName:dto.moduleName
|
|
64
66
|
},
|
|
65
67
|
parentEntity: 'aiInteraction',
|
|
66
68
|
parentEntityId: aiInteraction.id,
|
|
@@ -137,6 +139,25 @@ export class AiInteractionService extends CRUDService<AiInteraction> {
|
|
|
137
139
|
this.logger.log(`Python script exited with zero exit code: ${stdout}`);
|
|
138
140
|
const raw: McpResponse = JSON.parse(stdout);
|
|
139
141
|
|
|
142
|
+
// Sometimes the raw.response might not be a valid json
|
|
143
|
+
// TODO: examine the content type of the raw response..
|
|
144
|
+
// if (raw.content_type==='json') {
|
|
145
|
+
// }
|
|
146
|
+
let parsedResponse = raw.response;
|
|
147
|
+
try {
|
|
148
|
+
parsedResponse = JSON.parse(raw.response);
|
|
149
|
+
}
|
|
150
|
+
catch (ex) {
|
|
151
|
+
this.logger.warn(`Attempting to parse mcp client response assuming it is JSON, however it is not: ${parsedResponse}`);
|
|
152
|
+
}
|
|
153
|
+
// Parse the response string into an object
|
|
154
|
+
// const parsedResponse = JSON.parse(raw.response);
|
|
155
|
+
|
|
156
|
+
// Replace the string with the parsed object
|
|
157
|
+
const enrichedRaw = {
|
|
158
|
+
...raw,
|
|
159
|
+
response: parsedResponse,
|
|
160
|
+
};
|
|
140
161
|
// if (!raw.success) {
|
|
141
162
|
// return reject(new Error(`MCP error: ${raw.errors?.join(', ')}`));
|
|
142
163
|
// }
|
|
@@ -146,7 +167,7 @@ export class AiInteractionService extends CRUDService<AiInteraction> {
|
|
|
146
167
|
// const parsed = JSON.parse(cleaned);
|
|
147
168
|
// resolve(cleaned);
|
|
148
169
|
|
|
149
|
-
resolve(
|
|
170
|
+
resolve(enrichedRaw);
|
|
150
171
|
} catch (err: any) {
|
|
151
172
|
reject(new Error(`Mcp Invocation Failed: ${err.message}`));
|
|
152
173
|
}
|
|
@@ -986,7 +986,7 @@ export class AuthenticationService {
|
|
|
986
986
|
return accessToken;
|
|
987
987
|
}
|
|
988
988
|
|
|
989
|
-
async generateRefreshToken(user: User) {
|
|
989
|
+
async generateRefreshToken(user: User, previousRefreshToken?: string) {
|
|
990
990
|
const refreshTokenId = randomUUID();
|
|
991
991
|
|
|
992
992
|
const refreshToken = await this.signToken(user.id, this.jwtConfiguration.refreshTokenTtl, {
|
|
@@ -994,7 +994,7 @@ export class AuthenticationService {
|
|
|
994
994
|
})
|
|
995
995
|
|
|
996
996
|
// store the refresh token id in the redis storage.
|
|
997
|
-
await this.refreshTokenIdsStorage.insert(user.id, refreshToken);
|
|
997
|
+
await this.refreshTokenIdsStorage.insert(user.id, refreshToken, previousRefreshToken);
|
|
998
998
|
|
|
999
999
|
return refreshToken;
|
|
1000
1000
|
}
|
|
@@ -1164,7 +1164,11 @@ export class AuthenticationService {
|
|
|
1164
1164
|
roles: true
|
|
1165
1165
|
}
|
|
1166
1166
|
});
|
|
1167
|
-
|
|
1167
|
+
|
|
1168
|
+
// const tokens = await this.generateTokens(user);
|
|
1169
|
+
|
|
1170
|
+
// Get the refresh token for a user from refresh token storage.
|
|
1171
|
+
const refreshTokenState = await this.refreshTokenIdsStorage.getCurrentRefreshTokenState(user.id);
|
|
1168
1172
|
|
|
1169
1173
|
const response = {
|
|
1170
1174
|
user: {
|
|
@@ -1175,7 +1179,8 @@ export class AuthenticationService {
|
|
|
1175
1179
|
id: user.id,
|
|
1176
1180
|
roles: user.roles.map((role) => role.name)
|
|
1177
1181
|
},
|
|
1178
|
-
|
|
1182
|
+
refreshToken: refreshTokenState.currentRefreshToken,
|
|
1183
|
+
// ...tokens
|
|
1179
1184
|
}
|
|
1180
1185
|
return response;
|
|
1181
1186
|
}
|
|
@@ -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
|
}
|