@simitgroup/simpleapp-generator 1.6.6-q-alpha → 1.6.6-s-alpha
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/ReleaseNote.md +6 -0
- package/dist/buildinschemas/index.d.ts +1 -0
- package/dist/buildinschemas/index.d.ts.map +1 -1
- package/dist/buildinschemas/index.js +3 -1
- package/dist/buildinschemas/index.js.map +1 -1
- package/dist/buildinschemas/message.d.ts +3 -0
- package/dist/buildinschemas/message.d.ts.map +1 -0
- package/dist/buildinschemas/message.js +34 -0
- package/dist/buildinschemas/message.js.map +1 -0
- package/dist/buildinschemas/webhook.d.ts.map +1 -1
- package/dist/buildinschemas/webhook.js +124 -53
- package/dist/buildinschemas/webhook.js.map +1 -1
- package/dist/buildinschemas/webhookhistory.d.ts +3 -0
- package/dist/buildinschemas/webhookhistory.d.ts.map +1 -0
- package/dist/buildinschemas/webhookhistory.js +44 -0
- package/dist/buildinschemas/webhookhistory.js.map +1 -0
- package/dist/buildinschemas/webhooklog.d.ts +3 -0
- package/dist/buildinschemas/webhooklog.d.ts.map +1 -0
- package/dist/buildinschemas/webhooklog.js +77 -0
- package/dist/buildinschemas/webhooklog.js.map +1 -0
- package/dist/createproject.js +138 -0
- package/dist/createproject.js.map +1 -0
- package/dist/framework.js +3 -3
- package/dist/framework.js.map +1 -1
- package/dist/generate-allow-changebackend.js +305 -0
- package/dist/generate-allow-changebackend.js.map +1 -0
- package/dist/generate.js +2 -2
- package/dist/generate.js.map +1 -1
- package/dist/index2.js +118 -0
- package/dist/index2.js.map +1 -0
- package/dist/installdependency.js +20 -0
- package/dist/installdependency.js.map +1 -0
- package/dist/installnest.js +2 -0
- package/dist/installnest.js.map +1 -0
- package/dist/installnuxt.js +2 -0
- package/dist/installnuxt.js.map +1 -0
- package/dist/processors/groupsbuilder.js +2 -0
- package/dist/processors/groupsbuilder.js.map +1 -0
- package/dist/schematype/baseschema.js +25 -0
- package/dist/schematype/baseschema.js.map +1 -0
- package/dist/schematype/default.js +2 -0
- package/dist/schematype/default.js.map +1 -0
- package/dist/schematype/index.js +12 -0
- package/dist/schematype/index.js.map +1 -0
- package/dist/schematype/primarymasterdata.js +38 -0
- package/dist/schematype/primarymasterdata.js.map +1 -0
- package/dist/schematype/simple.js +24 -0
- package/dist/schematype/simple.js.map +1 -0
- package/dist/schematype/simplemasterdata.js +31 -0
- package/dist/schematype/simplemasterdata.js.map +1 -0
- package/dist/schematype/transaction.js +74 -0
- package/dist/schematype/transaction.js.map +1 -0
- package/package.json +1 -1
- package/src/buildinschemas/index.ts +1 -0
- package/src/buildinschemas/webhook.ts +126 -55
- package/src/buildinschemas/webhooklog.ts +75 -0
- package/src/framework.ts +4 -4
- package/src/generate.ts +2 -2
- package/templates/nest/src/simpleapp/generate/commons/middlewares/tenant.middleware.ts.eta +4 -2
- package/templates/nest/src/simpleapp/generate/commons/runwebhook.service.ts.eta +143 -168
- package/templates/nest/src/simpleapp/generate/commons/user.context.ts.eta +22 -13
- package/templates/nest/src/simpleapp/generate/processors/simpleapp.processor.ts.eta +22 -16
- package/templates/nest/src/simpleapp/webhooks/branch.ts._eta +37 -0
- package/templates/nest/src/simpleapp/webhooks/index.ts._eta +21 -0
- package/templates/nuxt/plugins/20.simpleapp-userstore.ts.eta +341 -316
- /package/templates/nest/src/simpleapp/generate/processors/{webhook.processor.ts.eta → webhook.processor.ts.etaxxxx} +0 -0
|
@@ -13,6 +13,7 @@ import { Model } from 'mongoose';
|
|
|
13
13
|
import { Permission } from '../../types/perm.type';
|
|
14
14
|
import { User } from '../../types/user.type';
|
|
15
15
|
import { Appintegration } from '../../types/appintegration.type';
|
|
16
|
+
import { Webhook } from '../../types/Webhook.type';
|
|
16
17
|
import { UserContext } from '../user.context';
|
|
17
18
|
|
|
18
19
|
@Injectable()
|
|
@@ -27,6 +28,7 @@ export class TenantMiddleware implements NestMiddleware {
|
|
|
27
28
|
@InjectModel('User') private readonly userModel: Model<User>,
|
|
28
29
|
@InjectModel('Permission') private readonly permModel: Model<Permission>,
|
|
29
30
|
@InjectModel('Appintegration') private readonly appModel: Model<Appintegration>,
|
|
31
|
+
@InjectModel('Webhook') private readonly webhookModel: Model<Webhook>,
|
|
30
32
|
) {}
|
|
31
33
|
|
|
32
34
|
requireXOrg(baseurl: string): boolean {
|
|
@@ -53,7 +55,7 @@ export class TenantMiddleware implements NestMiddleware {
|
|
|
53
55
|
|
|
54
56
|
if (req.baseUrl == '/graphql') {
|
|
55
57
|
if (tokenStr) {
|
|
56
|
-
await user.setCurrentUserInfo(tokenStr, xOrg);
|
|
58
|
+
await user.setCurrentUserInfo(tokenStr, xOrg,this.webhookModel);
|
|
57
59
|
}
|
|
58
60
|
req['sessionuser'] = user;
|
|
59
61
|
next();
|
|
@@ -88,7 +90,7 @@ export class TenantMiddleware implements NestMiddleware {
|
|
|
88
90
|
}
|
|
89
91
|
|
|
90
92
|
try {
|
|
91
|
-
await user.setCurrentUserInfo(tokenStr, xOrg);
|
|
93
|
+
await user.setCurrentUserInfo(tokenStr, xOrg,this.webhookModel);
|
|
92
94
|
if (user.getId() == '' && this.requireXOrg(req.baseUrl)) {
|
|
93
95
|
this.logger.log('Access deny for user:', req.baseUrl);
|
|
94
96
|
return res.status(401).send('Access deny for user');
|
|
@@ -4,192 +4,167 @@
|
|
|
4
4
|
* last change 2024-03-17
|
|
5
5
|
* Author: Ks Tan
|
|
6
6
|
*/
|
|
7
|
-
import {
|
|
8
|
-
BadRequestException,
|
|
9
|
-
Injectable,
|
|
10
|
-
InternalServerErrorException,
|
|
11
|
-
Logger,
|
|
12
|
-
NotFoundException,
|
|
13
|
-
} from '@nestjs/common';
|
|
7
|
+
import { BadRequestException, Injectable,Inject, InternalServerErrorException, Logger, NotFoundException } from '@nestjs/common';
|
|
14
8
|
import { EventEmitter2, OnEvent } from '@nestjs/event-emitter';
|
|
15
9
|
import { UserContext } from './user.context';
|
|
16
|
-
import {
|
|
17
|
-
Webhook,
|
|
18
|
-
WebhookService,
|
|
19
|
-
} from 'src/simpleapp/services/webhook.service';
|
|
10
|
+
import { Webhook,Webhooklog } from '../types';
|
|
20
11
|
import { alldocuments } from 'src/simpleapp/generate/commons/dicts/documents';
|
|
21
12
|
|
|
22
13
|
@Injectable()
|
|
23
14
|
export class RunWebhookService {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
15
|
+
@Inject(EventEmitter2)
|
|
16
|
+
protected eventEmitter: EventEmitter2;
|
|
17
|
+
|
|
18
|
+
protected logger = new Logger();
|
|
19
|
+
protected maxRetries = 5
|
|
20
|
+
public constructor() {}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* trigger
|
|
26
|
+
*/
|
|
27
|
+
async run(appuser: UserContext, documentName: string, actionName: string, data: any) {
|
|
28
|
+
return await this.runRealtimeWebHook(appuser,documentName,actionName,data)
|
|
34
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* get/delete
|
|
32
|
+
* http://myendpoint.com/{orgid}/invoice/{documentid}/delete
|
|
33
|
+
* http://myendpoint.com/{orgid}/invoice/{documentid}?action=delete
|
|
34
|
+
*
|
|
35
|
+
* post/put/patch
|
|
36
|
+
* http://myendpoint.com/{orgid}/invoice/{documentid}
|
|
37
|
+
* {json body}
|
|
38
|
+
*/
|
|
39
|
+
async runRealtimeWebHook(appuser: UserContext, documentName: string, actionName: string, data: any) {
|
|
40
|
+
this.logger.debug(`Run webhook ${documentName}, ${actionName}`);
|
|
41
|
+
// console.log(`Run webhook ${documentName}, ${actionName}`);
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
const webhooks = appuser.getWebHooks().filter(wh=>
|
|
45
|
+
wh.resourceName==documentName && wh.eventType==actionName
|
|
46
|
+
)
|
|
47
|
+
// console.log(webhooks);
|
|
48
|
+
|
|
49
|
+
//same resource,actionName may have multiple webhook, run 1 by 1
|
|
50
|
+
for(let whNo=0;whNo<webhooks.length;whNo++){
|
|
51
|
+
|
|
52
|
+
const webhook = webhooks[whNo]
|
|
53
|
+
const reqMethod = webhook.requestMethod
|
|
54
|
+
this.logger.verbose(webhook)
|
|
55
|
+
const headers = {};
|
|
56
|
+
|
|
57
|
+
if (Array.isArray(webhook.headers)) {
|
|
58
|
+
webhook.headers.forEach((h) => {
|
|
59
|
+
h.value = h.value.replace('{{access_token}}',appuser.getUserToken())
|
|
60
|
+
headers[h.name] = h.value;
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
headers['accept'] = 'application/json';
|
|
64
|
+
headers['content-type'] = 'application/json';
|
|
65
|
+
headers['x-org']=appuser.getXOrg()
|
|
66
|
+
headers['x-resource-name']=documentName
|
|
67
|
+
headers['x-action-name']=actionName
|
|
68
|
+
|
|
69
|
+
if(webhook.authentication=='basic')
|
|
70
|
+
headers['Authorization']= 'Basic ' + Buffer.from(webhook.basicAuth.user + ":" + webhook.basicAuth.password).toString('base64');
|
|
35
71
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const filter = {
|
|
47
|
-
eventTypes: documentName + '.' + actionName,
|
|
48
|
-
active: true,
|
|
49
|
-
};
|
|
50
|
-
// console.log('Load webhook', documentName, actionName, filter);
|
|
51
|
-
const webhooks = await this.webhookService.search(appuser, filter);
|
|
52
|
-
// console.log('Loaded webhook', webhooks);
|
|
53
|
-
if (webhooks.length == 0) return;
|
|
54
|
-
|
|
55
|
-
for (let i = 0; i < webhooks.length; i++) {
|
|
56
|
-
const webhook = webhooks[i];
|
|
72
|
+
let tries = webhook.retryAttemps ?? 0
|
|
73
|
+
//first try need + 1
|
|
74
|
+
tries = tries+1
|
|
75
|
+
//hardcode max retries
|
|
76
|
+
if(tries > this.maxRetries) tries = this.maxRetries
|
|
77
|
+
const options:RequestInit = {
|
|
78
|
+
method: reqMethod.toUpperCase(),
|
|
79
|
+
headers: headers,
|
|
80
|
+
|
|
81
|
+
};
|
|
57
82
|
try {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
83
|
+
if(['POST','PUT','PATCH'].includes(options.method)){
|
|
84
|
+
options.body= this.prepareBody(webhook,data)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
while(tries>0){
|
|
91
|
+
tries--
|
|
92
|
+
console.log("Excute webhook id",webhook._id)
|
|
93
|
+
const req = await fetch(webhook.url, options);
|
|
94
|
+
const statusCode = req.status;
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
if (statusCode >= 200 && statusCode <= 300) {
|
|
99
|
+
//success, continue next webhook
|
|
100
|
+
const msg = `webhook triggered successfully for ${documentName}:${actionName}. ${reqMethod} ${webhook.url}, try:${tries}, ${statusCode},${req.statusText}`
|
|
101
|
+
this.addLog(appuser,documentName,webhook,actionName,data,options,"success",statusCode,msg)
|
|
102
|
+
break;
|
|
103
|
+
}else if(tries<=0 && webhook.jobType=='roll-back-when-failed'){
|
|
104
|
+
//failed, trigger server error for roll back
|
|
105
|
+
const msg = `webhook faied, data roll back ${documentName}:${actionName}. ${reqMethod} ${webhook.url}, try:${tries}, ${statusCode},${req.statusText}`
|
|
106
|
+
this.addLog(appuser,documentName,webhook,actionName,data,options,'failed',statusCode,msg)
|
|
107
|
+
throw new InternalServerErrorException(msg);
|
|
108
|
+
}else if(tries<=0 && webhook.jobType=='realtime'){
|
|
109
|
+
//failed, but no need to trigger server error/rollback
|
|
110
|
+
const msg = `webhook failed, ${documentName}:${actionName}. ${reqMethod} ${webhook.url}, try:${tries}, ${statusCode},${req.statusText}`
|
|
111
|
+
this.addLog(appuser,documentName,webhook,actionName,data,options,'failed',statusCode,msg)
|
|
112
|
+
}else{
|
|
113
|
+
//failed, but still continue retry
|
|
114
|
+
const msg = `webhook ${documentName}:${actionName}. ${reqMethod} ${webhook.url}, try:${tries}, ${statusCode},${req.statusText}`
|
|
115
|
+
this.addLog(appuser,documentName,webhook,actionName,data,options,'warn',statusCode,msg)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// const body = req.body;
|
|
65
121
|
} catch (e) {
|
|
66
|
-
|
|
122
|
+
throw new InternalServerErrorException(e);
|
|
67
123
|
}
|
|
124
|
+
|
|
68
125
|
}
|
|
126
|
+
|
|
127
|
+
return true
|
|
69
128
|
}
|
|
70
129
|
|
|
71
|
-
async runWebHook(
|
|
72
|
-
appuser: UserContext,
|
|
73
|
-
webhook: Webhook,
|
|
74
|
-
documentName: string,
|
|
75
|
-
actionName: string,
|
|
76
|
-
data: any,
|
|
77
|
-
) {
|
|
78
|
-
const headers = {};
|
|
79
|
-
|
|
80
|
-
// console.log('Run webhook ', documentName, actionName);
|
|
81
|
-
if (Array.isArray(webhook.headers)) {
|
|
82
|
-
webhook.headers.forEach((h) => {
|
|
83
|
-
headers[h.name] = h.value;
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
headers['accept'] = 'application/json';
|
|
87
|
-
headers['content-type'] = 'application/json';
|
|
88
|
-
headers['Authorization'] = this.webhookApiKey;
|
|
89
|
-
const eventname = `${this.webhookprefix}${documentName}.${actionName}`;
|
|
90
|
-
const options = {
|
|
91
|
-
method: webhook.requestMethod.toUpperCase(),
|
|
92
|
-
headers: headers,
|
|
93
|
-
body: JSON.stringify({
|
|
94
|
-
labels: {
|
|
95
|
-
tenantId: appuser.getTenantId().toString(),
|
|
96
|
-
},
|
|
97
|
-
metadata: {
|
|
98
|
-
src: process.env.PROJECT_NAME,
|
|
99
|
-
user: appuser.getFullname(),
|
|
100
|
-
},
|
|
101
|
-
application_id: this.webhookAppId,
|
|
102
|
-
event_type: eventname,
|
|
103
|
-
event_id: crypto.randomUUID(),
|
|
104
|
-
occurred_at: new Date().toISOString(),
|
|
105
|
-
payload: JSON.stringify(data),
|
|
106
|
-
payload_content_type: 'application/json',
|
|
107
|
-
}),
|
|
108
|
-
};
|
|
109
|
-
try {
|
|
110
|
-
// console.log('webhook request ', this.webhookeventurl, options);
|
|
111
|
-
const req = await fetch(this.webhookeventurl, options);
|
|
112
|
-
const statusCode = req.status;
|
|
113
|
-
if (statusCode >= 300) {
|
|
114
|
-
throw new InternalServerErrorException(
|
|
115
|
-
`create event ${eventname} failed to webhook server`,
|
|
116
|
-
);
|
|
117
|
-
}
|
|
118
130
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
131
|
+
addLog(appuser: UserContext, documentName: string, webhook:Webhook, actionName: string, data: any,options,status:string,statusCode:number,msg:string){
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
if(status=='warn'){
|
|
135
|
+
status="failed"
|
|
136
|
+
this.logger.warn(msg)
|
|
122
137
|
}
|
|
123
|
-
|
|
138
|
+
else if(status=='success')
|
|
139
|
+
this.logger.debug(msg)
|
|
140
|
+
else
|
|
141
|
+
this.logger.error (msg)
|
|
124
142
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
// "resource_type_name": "invoice",
|
|
136
|
-
// "verb_name": "documentno",
|
|
137
|
-
// "event_type_name": "billing.invoice.documentno"
|
|
138
|
-
// },
|
|
139
|
-
try {
|
|
140
|
-
const res = await fetch(
|
|
141
|
-
`${this.webhookeventtypeurl}?application_id=${this.webhookAppId}`,
|
|
142
|
-
options,
|
|
143
|
-
);
|
|
144
|
-
|
|
145
|
-
const locallist = this.getSchemaEventTypes();
|
|
146
|
-
const eventlist = (await res.json()).map((item) => item.event_type_name);
|
|
147
|
-
|
|
148
|
-
for (let i = 0; i < locallist.length; i++) {
|
|
149
|
-
const item = locallist[i];
|
|
150
|
-
if (!eventlist.includes(item)) {
|
|
151
|
-
//create remote event type
|
|
152
|
-
await this.createEventType(item);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
} catch (e) {
|
|
156
|
-
throw new InternalServerErrorException(e);
|
|
143
|
+
let body = JSON.stringify(options,null,4)
|
|
144
|
+
|
|
145
|
+
const whlog: Webhooklog = {
|
|
146
|
+
title: `${webhook.requestMethod} ${webhook.url}`,
|
|
147
|
+
resource: documentName,
|
|
148
|
+
actionName: actionName,
|
|
149
|
+
status: status,
|
|
150
|
+
statusCode: statusCode,
|
|
151
|
+
body: body,
|
|
152
|
+
msg:msg
|
|
157
153
|
}
|
|
158
|
-
}
|
|
159
154
|
|
|
160
|
-
|
|
161
|
-
const para = eventname.split('.');
|
|
162
|
-
const options = {
|
|
163
|
-
method: 'POST',
|
|
164
|
-
headers: {
|
|
165
|
-
accept: 'application/json',
|
|
166
|
-
'content-type': 'application/json',
|
|
167
|
-
Authorization: this.webhookApiKey,
|
|
168
|
-
},
|
|
169
|
-
body: JSON.stringify({
|
|
170
|
-
application_id: this.webhookAppId,
|
|
171
|
-
resource_type: para[0],
|
|
172
|
-
service: para[1],
|
|
173
|
-
verb: para[2],
|
|
174
|
-
}),
|
|
175
|
-
};
|
|
176
|
-
|
|
177
|
-
await fetch(this.webhookeventtypeurl, options);
|
|
178
|
-
// .then(response => response.json())
|
|
179
|
-
// .then(response => console.log(response))
|
|
180
|
-
// .catch(err => console.error(err));
|
|
181
|
-
}
|
|
182
|
-
getSchemaEventTypes() {
|
|
183
|
-
const alleventtypes: string[] = [];
|
|
184
|
-
alldocuments
|
|
185
|
-
.filter((item) => Array.isArray(item.webhook))
|
|
186
|
-
.forEach((item) => {
|
|
187
|
-
item.webhook.forEach((h) => {
|
|
188
|
-
alleventtypes.push(
|
|
189
|
-
`${this.webhookprefix}${item.docName.toLowerCase()}.${h}`,
|
|
190
|
-
);
|
|
191
|
-
});
|
|
192
|
-
});
|
|
193
|
-
return alleventtypes;
|
|
155
|
+
this.eventEmitter.emit('webhooklog.add', appuser,whlog);
|
|
194
156
|
}
|
|
157
|
+
prepareBody(webhook:Webhook,data:any){
|
|
158
|
+
const cleandata = JSON.parse(JSON.stringify(data))
|
|
159
|
+
|
|
160
|
+
if(webhook.body?.trim()=='*'){
|
|
161
|
+
return JSON.stringify(cleandata)
|
|
162
|
+
}
|
|
163
|
+
const parse = require('json-templates');
|
|
164
|
+
const template = parse(webhook.body);
|
|
165
|
+
const x:BodyInit =template(cleandata)
|
|
166
|
+
// this.logger.log(x)
|
|
167
|
+
return JSON.parse(JSON.stringify(x))
|
|
168
|
+
}
|
|
169
|
+
|
|
195
170
|
}
|
|
@@ -6,15 +6,18 @@
|
|
|
6
6
|
* 2.
|
|
7
7
|
*/
|
|
8
8
|
import Base64URL from '@darkwolf/base64url';
|
|
9
|
+
import { InjectModel } from '@nestjs/mongoose';
|
|
9
10
|
import { BadRequestException, ForbiddenException, Injectable, Logger, Scope } from '@nestjs/common';
|
|
10
11
|
import * as jwt from 'jsonwebtoken';
|
|
11
12
|
import { ClientSession, Model, PipelineStage } from 'mongoose';
|
|
12
|
-
import { Branch, Organization, Permission, Tenant, TenantClientSetting, User, Appintegration } from 'src/simpleapp/generate/types';
|
|
13
|
+
import { Branch, Organization, Permission, Tenant, TenantClientSetting, User, Appintegration, Webhook } from 'src/simpleapp/generate/types';
|
|
13
14
|
import { ProfileUserBranch, ProfileUserInvites } from '../../profile/profile.types';
|
|
14
15
|
import { ModifiedRecords } from '../types';
|
|
15
16
|
import { Role } from './roles/roles.enum';
|
|
17
|
+
import systemWebHooks from '../../webhooks';
|
|
16
18
|
import * as rolegroups from './roles/roles.group';
|
|
17
19
|
|
|
20
|
+
|
|
18
21
|
@Injectable({ scope: Scope.REQUEST })
|
|
19
22
|
export class UserContext {
|
|
20
23
|
protected sessionId: string = crypto.randomUUID();
|
|
@@ -89,6 +92,7 @@ export class UserContext {
|
|
|
89
92
|
|
|
90
93
|
protected package: string = '';
|
|
91
94
|
|
|
95
|
+
protected webhooks: Webhook[] = systemWebHooks
|
|
92
96
|
protected clientSetting: TenantClientSetting = {
|
|
93
97
|
auditTrail: false,
|
|
94
98
|
support: false,
|
|
@@ -97,7 +101,7 @@ export class UserContext {
|
|
|
97
101
|
};
|
|
98
102
|
|
|
99
103
|
private dbsession: ClientSession;
|
|
100
|
-
|
|
104
|
+
|
|
101
105
|
protected modifiedRecords: ModifiedRecords = {
|
|
102
106
|
createds: {},
|
|
103
107
|
updateds: {},
|
|
@@ -110,7 +114,7 @@ export class UserContext {
|
|
|
110
114
|
} = { simbiz6: false, einvoice: false };
|
|
111
115
|
|
|
112
116
|
constructor(
|
|
113
|
-
private readonly userModel: Model<User>,
|
|
117
|
+
private readonly userModel: Model<User>,
|
|
114
118
|
private readonly permModel: Model<Permission>,
|
|
115
119
|
private readonly appModel: Model<Appintegration>,
|
|
116
120
|
) {}
|
|
@@ -202,9 +206,14 @@ export class UserContext {
|
|
|
202
206
|
return data;
|
|
203
207
|
};
|
|
204
208
|
|
|
205
|
-
|
|
209
|
+
|
|
210
|
+
setCurrentUserInfo = async (tokenstr: string, xOrg: string,webhookModel:Model<Webhook>) => {
|
|
206
211
|
this.setXOrg(xOrg);
|
|
207
|
-
await this.setUserToken(tokenstr);
|
|
212
|
+
await this.setUserToken(tokenstr);
|
|
213
|
+
const wh = await webhookModel.find({branchId:this.getBranchId(),active:true})
|
|
214
|
+
|
|
215
|
+
if(Array.isArray(wh) && wh.length>0)
|
|
216
|
+
this.webhooks = this.webhooks.concat(wh)
|
|
208
217
|
};
|
|
209
218
|
|
|
210
219
|
/**
|
|
@@ -258,6 +267,7 @@ export class UserContext {
|
|
|
258
267
|
as: 'currentTenant',
|
|
259
268
|
},
|
|
260
269
|
},
|
|
270
|
+
|
|
261
271
|
{
|
|
262
272
|
$unwind: '$currentTenant',
|
|
263
273
|
},
|
|
@@ -391,7 +401,8 @@ export class UserContext {
|
|
|
391
401
|
orgId: this.orgId,
|
|
392
402
|
};
|
|
393
403
|
};
|
|
394
|
-
|
|
404
|
+
getWebHooks = ()=> this.webhooks
|
|
405
|
+
|
|
395
406
|
getWorkflowTaskFilter() {
|
|
396
407
|
return {
|
|
397
408
|
'data.tenantId': this.tenantId,
|
|
@@ -720,7 +731,6 @@ export class UserContext {
|
|
|
720
731
|
return results;
|
|
721
732
|
}
|
|
722
733
|
|
|
723
|
-
|
|
724
734
|
setAsStaticUser = (uid: string, uname: string, name: string, email: string, xorg: string) => {
|
|
725
735
|
// Define token info
|
|
726
736
|
this.token = '';
|
|
@@ -757,13 +767,12 @@ export class UserContext {
|
|
|
757
767
|
const appintegration = await this.appModel.aggregate(extension);
|
|
758
768
|
if (appintegration && appintegration.length > 0) {
|
|
759
769
|
appintegration.forEach((item) => {
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
770
|
+
if (item.appId === 'simbiz6') this.appintegration.simbiz6 = true;
|
|
771
|
+
if (item.appId === 'einvoice') this.appintegration.einvoice = true;
|
|
772
|
+
});
|
|
773
|
+
}
|
|
774
|
+
return this.appintegration;
|
|
763
775
|
}
|
|
764
|
-
return this.appintegration;
|
|
765
|
-
|
|
766
|
-
}
|
|
767
776
|
/**
|
|
768
777
|
* Define additional properties from user into moreProps
|
|
769
778
|
*/
|
|
@@ -35,6 +35,7 @@ import { UserContext } from '../commons/user.context';
|
|
|
35
35
|
import { CloudApiService } from 'src/cloudapi/cloudapi.service';
|
|
36
36
|
import { PrintApiService } from 'src/printapi/printapi.service';
|
|
37
37
|
import { DocNumberFormatGenerator } from '../commons/docnogenerator.service';
|
|
38
|
+
import { RunWebhookService } from '../commons/runwebhook.service';
|
|
38
39
|
import {
|
|
39
40
|
IsolationType,
|
|
40
41
|
DefaultHooks,
|
|
@@ -54,6 +55,8 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
|
|
|
54
55
|
protected cloudapi: CloudApiService;
|
|
55
56
|
@Inject(PrintApiService)
|
|
56
57
|
protected printapi: PrintApiService;
|
|
58
|
+
@Inject(RunWebhookService)
|
|
59
|
+
protected runWebHook:RunWebhookService;
|
|
57
60
|
protected hooks: DefaultHooks<T> = {};
|
|
58
61
|
protected logger = new Logger();
|
|
59
62
|
protected strictIsolation = true;
|
|
@@ -490,7 +493,7 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
|
|
|
490
493
|
try {
|
|
491
494
|
if (this.hooks.afterCreate)
|
|
492
495
|
await this.hooks.afterCreate(appuser, result);
|
|
493
|
-
this.callWebhook(appuser, 'create', result);
|
|
496
|
+
await this.callWebhook(appuser, 'create', result);
|
|
494
497
|
|
|
495
498
|
// return result as T;
|
|
496
499
|
} catch (err) {
|
|
@@ -608,7 +611,7 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
|
|
|
608
611
|
|
|
609
612
|
try {
|
|
610
613
|
if (this.hooks.afterCreate) await this.hooks.afterCreate(appuser, result);
|
|
611
|
-
this.callWebhook(appuser, 'create', result);
|
|
614
|
+
await this.callWebhook(appuser, 'create', result);
|
|
612
615
|
return result as T;
|
|
613
616
|
} catch (err) {
|
|
614
617
|
throw new InternalServerErrorException(
|
|
@@ -690,7 +693,7 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
|
|
|
690
693
|
|
|
691
694
|
try {
|
|
692
695
|
if (this.hooks.afterCreate) await this.hooks.afterCreate(appuser, result);
|
|
693
|
-
this.callWebhook(appuser, 'create', result);
|
|
696
|
+
await this.callWebhook(appuser, 'create', result);
|
|
694
697
|
return result as T;
|
|
695
698
|
} catch (err) {
|
|
696
699
|
throw new InternalServerErrorException(
|
|
@@ -863,7 +866,7 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
|
|
|
863
866
|
if (this.hooks.afterDelete)
|
|
864
867
|
await this.hooks.afterDelete(appuser, deleteresult, id);
|
|
865
868
|
//this.doc.findByIdAndDelete(id);
|
|
866
|
-
this.callWebhook(appuser, 'delete', deletedata);
|
|
869
|
+
await this.callWebhook(appuser, 'delete', deletedata);
|
|
867
870
|
return deleteresult;
|
|
868
871
|
} else {
|
|
869
872
|
this.logger.debug('reject query', dependency);
|
|
@@ -956,7 +959,7 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
|
|
|
956
959
|
appuser.addUpdatedRecordId(this.documentName, data._id);
|
|
957
960
|
if (this.hooks.afterUpdate)
|
|
958
961
|
await this.hooks.afterUpdate(appuser, id, existingdata, result);
|
|
959
|
-
this.callWebhook(appuser, 'update', result);
|
|
962
|
+
await this.callWebhook(appuser, 'update', result);
|
|
960
963
|
return result; // await this.findById(appuser, id);
|
|
961
964
|
} catch (err) {
|
|
962
965
|
this.logger.error(err);
|
|
@@ -1033,7 +1036,7 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
|
|
|
1033
1036
|
appuser.addUpdatedRecordId(this.documentName, data._id);
|
|
1034
1037
|
if (this.hooks.afterUpdate)
|
|
1035
1038
|
await this.hooks.afterUpdate(appuser, id, existingdata, result);
|
|
1036
|
-
this.callWebhook(appuser, 'update', result);
|
|
1039
|
+
await this.callWebhook(appuser, 'update', result);
|
|
1037
1040
|
return result; // await this.findById(appuser, id);
|
|
1038
1041
|
} catch (err) {
|
|
1039
1042
|
this.logger.error(err);
|
|
@@ -1102,7 +1105,7 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
|
|
|
1102
1105
|
|
|
1103
1106
|
if (this.hooks.afterUpdate)
|
|
1104
1107
|
await this.hooks.afterUpdate(appuser, id, existingdata, result);
|
|
1105
|
-
this.callWebhook(appuser, 'update', result);
|
|
1108
|
+
await this.callWebhook(appuser, 'update', result);
|
|
1106
1109
|
return result; //await this.findById(appuser, id);
|
|
1107
1110
|
} catch (err) {
|
|
1108
1111
|
throw new InternalServerErrorException(err.message);
|
|
@@ -1224,7 +1227,7 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
|
|
|
1224
1227
|
data,
|
|
1225
1228
|
);
|
|
1226
1229
|
|
|
1227
|
-
this.callWebhook(appuser, docstatus, finaldata);
|
|
1230
|
+
await this.callWebhook(appuser, docstatus, finaldata);
|
|
1228
1231
|
return updateresult;
|
|
1229
1232
|
}
|
|
1230
1233
|
}
|
|
@@ -1482,13 +1485,16 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
|
|
|
1482
1485
|
return pipelines;
|
|
1483
1486
|
}
|
|
1484
1487
|
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
this.documentName,
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1488
|
+
|
|
1489
|
+
//only realtime webhook supported at this moment
|
|
1490
|
+
async callWebhook(appuser: UserContext, actionName: string, data: any) {
|
|
1491
|
+
try{
|
|
1492
|
+
await this.runWebHook.run(appuser,this.documentName, actionName,data)
|
|
1493
|
+
}
|
|
1494
|
+
catch(e)
|
|
1495
|
+
{
|
|
1496
|
+
throw new InternalServerErrorException(e);
|
|
1497
|
+
}
|
|
1498
|
+
|
|
1493
1499
|
}
|
|
1494
1500
|
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file was automatically generated by simpleapp generator. Every
|
|
3
|
+
* --remove-this-line-to-prevent-override--
|
|
4
|
+
* last change 2025-06-26
|
|
5
|
+
* Author: Ks Tan
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { Webhook } from "../generate/types";
|
|
9
|
+
const branch_hooks:Webhook[] = []
|
|
10
|
+
|
|
11
|
+
branch_hooks.push({
|
|
12
|
+
"_id": "branch.update",
|
|
13
|
+
"title": "branch_update",
|
|
14
|
+
"url": "https://localhost:8080",
|
|
15
|
+
"requestMethod": "post",
|
|
16
|
+
"authentication": "none",
|
|
17
|
+
"description": "aa",
|
|
18
|
+
"body": '{ "id":"{{_id}}", "code":"{{branchCode}}","name":"{{branchName}}" }',
|
|
19
|
+
"active": false,
|
|
20
|
+
"resourceName": "branch",
|
|
21
|
+
"eventType": "update",
|
|
22
|
+
"jobType": "realtime",
|
|
23
|
+
"retryAttemps": 2,
|
|
24
|
+
"basicAuth": {
|
|
25
|
+
"user": "",
|
|
26
|
+
"password": ""
|
|
27
|
+
},
|
|
28
|
+
"headers": [
|
|
29
|
+
{
|
|
30
|
+
"name": "token",
|
|
31
|
+
"value": "{{access_token}}"
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
export default branch_hooks
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file was automatically generated by simpleapp generator. Every
|
|
3
|
+
* --remove-this-line-to-prevent-override--
|
|
4
|
+
* last change 2025-06-26
|
|
5
|
+
* Author: Ks Tan
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { Webhook } from "../generate/types";
|
|
9
|
+
import branch_hooks from './branch'
|
|
10
|
+
|
|
11
|
+
const systemWebHooks:Webhook[] = []
|
|
12
|
+
function addMore(hooks:Webhook[]){
|
|
13
|
+
hooks.forEach(h=>{
|
|
14
|
+
if(h.active) systemWebHooks.push(h)
|
|
15
|
+
})
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
addMore(branch_hooks)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
export default systemWebHooks
|