@simitgroup/simpleapp-generator 1.6.4-e-alpha → 1.6.4-g-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.
Files changed (45) hide show
  1. package/ReleaseNote.md +13 -0
  2. package/dist/buildinschemas/index.d.ts +0 -1
  3. package/dist/buildinschemas/index.d.ts.map +1 -1
  4. package/dist/buildinschemas/index.js +1 -3
  5. package/dist/buildinschemas/index.js.map +1 -1
  6. package/dist/buildinschemas/systemmessage.js +3 -3
  7. package/dist/buildinschemas/systemmessage.js.map +1 -1
  8. package/dist/buildinschemas/user.d.ts.map +1 -1
  9. package/dist/buildinschemas/user.js +7 -0
  10. package/dist/buildinschemas/user.js.map +1 -1
  11. package/dist/buildinschemas/webhook.d.ts.map +1 -1
  12. package/dist/buildinschemas/webhook.js +20 -5
  13. package/dist/buildinschemas/webhook.js.map +1 -1
  14. package/package.json +1 -1
  15. package/src/buildinschemas/index.ts +0 -1
  16. package/src/buildinschemas/systemmessage.ts +3 -3
  17. package/src/buildinschemas/user.ts +7 -0
  18. package/src/buildinschemas/webhook.ts +21 -7
  19. package/templates/basic/nest/controller.ts.eta +3 -3
  20. package/templates/nest/.env._eta +7 -0
  21. package/templates/nest/src/app.module.ts.eta +12 -5
  22. package/templates/nest/src/main.ts.eta +30 -0
  23. package/templates/nest/src/simpleapp/generate/apischemas/simpleapp.apischema.ts.eta +32 -12
  24. package/templates/nest/src/simpleapp/generate/commons/audittrail.service.ts.eta +31 -26
  25. package/templates/nest/src/simpleapp/generate/commons/customkeycloa.guard.ts.eta +43 -0
  26. package/templates/nest/src/simpleapp/generate/commons/dicts/documents.ts.eta +2 -1
  27. package/templates/nest/src/simpleapp/generate/commons/middlewares/tenant.middleware.ts.eta +31 -5
  28. package/templates/nest/src/simpleapp/generate/commons/robotuser.service.ts.eta +15 -17
  29. package/templates/nest/src/simpleapp/generate/commons/runwebhook.service.ts.eta +161 -29
  30. package/templates/nest/src/simpleapp/generate/commons/user.context.ts.eta +17 -2
  31. package/templates/nest/src/simpleapp/generate/processors/simpleapp.processor.ts.eta +4 -6
  32. package/templates/nest/src/simpleapp/generate/processors/webhook.processor.ts.eta +224 -0
  33. package/templates/nuxt/components/calendar/CalendarSmall.vue.eta +113 -110
  34. package/templates/nuxt/components/image/ImageAvatar.vue.eta._vue +47 -13
  35. package/templates/nuxt/components/image/ImageToBase64Uploader.vue.eta.vue +5 -5
  36. package/templates/nuxt/components/renderer/RendererDocHistories.vue.eta +8 -5
  37. package/templates/nuxt/components/simpleApp/SimpleAppInput.vue.eta +25 -18
  38. package/templates/nuxt/composables/stringHelper.generate.ts.eta +13 -9
  39. package/templates/nuxt/pages/profile.vue.eta +3 -1
  40. package/templates/nuxt/server/api/profile/[...].ts.eta +11 -2
  41. package/templates/nuxt/simpleapp/generate/commons/documents.ts.eta +3 -1
  42. package/templates/nuxt/types/others.ts.eta +1 -0
  43. package/templates/nuxt/types/simpleappinput.ts.eta +2 -1
  44. package/tsconfig.tsbuildinfo +1 -1
  45. package/src/buildinschemas/webhookhistory.ts +0 -42
@@ -11,12 +11,12 @@ import { Model } from 'mongoose';
11
11
  import { UserContext } from 'src/simpleapp/generate/commons/user.context';
12
12
  import { User } from 'src/simpleapp/services/user.service';
13
13
  import { Permission } from 'src/simpleapp/services/perm.service';
14
-
14
+ const Base64URL = require('@darkwolf/base64url');
15
15
  @Injectable()
16
16
  export class SimpleAppRobotUserService {
17
17
  private systemAccessToken: string;
18
- private setToken = (token:string) => this.systemAccessToken = token
19
- private getToken = ()=>this.systemAccessToken
18
+ private setToken = (token: string) => (this.systemAccessToken = token);
19
+ private getToken = () => this.systemAccessToken;
20
20
  private expired: string;
21
21
  logger = new Logger();
22
22
  @InjectModel('User') private readonly usermodel: Model<User>;
@@ -28,7 +28,7 @@ export class SimpleAppRobotUserService {
28
28
  }
29
29
 
30
30
  async init() {
31
- await this.refreshSystemToken();
31
+ // await this.refreshSystemToken();
32
32
  }
33
33
  async refreshSystemToken() {
34
34
  enum GrantType {
@@ -76,25 +76,27 @@ export class SimpleAppRobotUserService {
76
76
  return data;
77
77
  });
78
78
 
79
- this.setToken(tokens.access_token)
80
- // console.log("access token ",this.getToken())
79
+ this.setToken(tokens.access_token);
80
+ console.log("access token ",this.getToken())
81
81
  const nextrefresh = tokens.expires_in * 0.8;
82
82
  const appuser = this.prepareAppUser(undefined);
83
-
84
- if(tokens.access_token){
85
- setTimeout(async () => {
86
- await this.refreshSystemToken();
87
- }, nextrefresh * 1000);
88
- }
83
+
84
+ // if (tokens.access_token) {
85
+ // setTimeout(async () => {
86
+ // await this.refreshSystemToken();
87
+ // }, nextrefresh * 1000);
88
+ // }
89
89
  }
90
90
 
91
91
  prepareAppUser(data: any) {
92
+ console.log("prepareAppUserprepareAppUser");
92
93
  const appuser = new UserContext(this.usermodel, this.permmodel);
93
94
  appuser.setAsStaticUser(
94
95
  '00000000-0000-0000-0000-000000000000',
95
96
  'robot',
96
97
  'Robot',
97
98
  'robot@a.org',
99
+ Base64URL.encodeText('0-0-0')
98
100
  );
99
101
 
100
102
  const tenantId = data?.tenantId ?? 0;
@@ -103,11 +105,7 @@ export class SimpleAppRobotUserService {
103
105
 
104
106
  appuser.setXorg(appuser.generateXorg(tenantId, orgId, branchId));
105
107
  appuser.setUserToken(this.getToken());
106
- // console.log(
107
- // 'return user ' + appuser.getUname(),
108
- // appuser.getXorg(),
109
- // appuser.getUserToken().length,
110
- // );
108
+
111
109
  return appuser;
112
110
  }
113
111
  }
@@ -11,16 +11,27 @@ import {
11
11
  Webhook,
12
12
  WebhookService,
13
13
  } from 'src/simpleapp/services/webhook.service';
14
- import {
15
- Webhookhistory,
16
- WebhookhistoryService,
17
- } from 'src/simpleapp/services/webhookhistory.service';
14
+ import {alldocuments} from 'src/simpleapp/generate/commons/dicts/documents'
15
+
18
16
  @Injectable()
19
17
  export class RunWebhookService {
18
+ private webhookApiKey = process.env.WEBHOOK_SERVER_APIKEY
19
+ private webhookAppId=process.env.WEBHOOK_SERVER_APP_ID
20
+ private webhookurl = process.env.WEBHOOK_SERVER_URL;
21
+ private webhookprefix = process.env.PROJECT_CODE+'.'
22
+ private webhookeventurl = `${process.env.WEBHOOK_SERVER_URL}/event/`;
23
+ private webhookeventtypeurl = `${process.env.WEBHOOK_SERVER_URL}/event_types/`;
24
+ private webhooksync:boolean = process.env.WEBHOOKER_SYNC_EVENTTYPE=='true'
25
+
26
+
27
+
20
28
  public constructor(
21
- private webhookService: WebhookService,
22
- private webhookhistoryService: WebhookhistoryService,
23
- ) {}
29
+ private webhookService: WebhookService,
30
+ ) {
31
+ if(this.webhooksync) this.syncEventTypes()
32
+ }
33
+
34
+
24
35
  @OnEvent('webhook')
25
36
  async loadWebhook(
26
37
  appuser: UserContext,
@@ -28,42 +39,163 @@ export class RunWebhookService {
28
39
  actionName: string,
29
40
  data?: any,
30
41
  ) {
31
- let subscribeall = false;
32
- const webhooks = await this.webhookService.search(appuser, {
33
- documentName: documentName,
34
- active: true,
35
- });
36
- if (webhooks.length == 0) return;
37
42
 
38
- const webhook = webhooks[0];
39
- let subscribes: string[] = [];
40
- if (webhook.setting == '' || webhook.setting === undefined) {
41
- subscribeall = true;
42
- } else {
43
- subscribes = JSON.parse(webhook.setting);
43
+ //no webhook server implemented
44
+ if(!this.webhookApiKey) return true
45
+
46
+
47
+ const filter = {
48
+ eventTypes: documentName + '.' + actionName ,
49
+ active: true,
44
50
  }
51
+ console.log("Load webhook",documentName,actionName,filter)
52
+ const webhooks = await this.webhookService.search(appuser, filter);
53
+ console.log("Loaded webhook",webhooks)
54
+ if (webhooks.length == 0) return;
45
55
 
46
- if (subscribeall || subscribes.includes(actionName)) {
47
- await this.runWebHook(appuser, webhook, data);
56
+ for (let i = 0; i < webhooks.length; i++) {
57
+ const webhook = webhooks[i];
58
+ try {
59
+ const res = await this.runWebHook(
60
+ appuser,
61
+ webhook,
62
+ documentName,
63
+ actionName,
64
+ data,
65
+ );
66
+ } catch (e) {
67
+ return e;
68
+ }
48
69
  }
49
70
  }
50
71
 
51
- async runWebHook(appuser: UserContext, webhook: Webhook, data: any) {
52
- const webhookurl = webhook.url;
53
- const headers = { 'x-from': process.env.PROJECT_NAME };
72
+ async runWebHook(
73
+ appuser: UserContext,
74
+ webhook: Webhook,
75
+ documentName: string,
76
+ actionName: string,
77
+ data: any,
78
+ ) {
79
+
80
+ const headers = {};
81
+
82
+ console.log("Run webhook ",documentName,actionName)
54
83
  if (Array.isArray(webhook.headers)) {
55
84
  webhook.headers.forEach((h) => {
56
85
  headers[h.name] = h.value;
57
86
  });
58
87
  }
88
+ headers['accept'] = 'application/json';
89
+ headers['content-type'] = 'application/json';
90
+ headers['Authorization'] = this.webhookApiKey;
91
+ const eventname = `${this.webhookprefix}${documentName}.${actionName}`
59
92
  const options = {
60
- method: webhook.requestMethod,
61
- body: JSON.stringify(data),
93
+ method: webhook.requestMethod.toUpperCase(),
62
94
  headers: headers,
95
+ body: JSON.stringify({
96
+ labels: {
97
+ tenantId: appuser.getTenantId().toString(),
98
+ },
99
+ metadata: {
100
+ src: process.env.PROJECT_NAME,
101
+ user: appuser.getFullname(),
102
+ },
103
+ application_id: this.webhookAppId,
104
+ event_type: eventname,
105
+ event_id: crypto.randomUUID(),
106
+ occurred_at: new Date().toISOString(),
107
+ payload: JSON.stringify(data),
108
+ payload_content_type: 'application/json',
109
+ }),
110
+ };
111
+ try {
112
+ console.log("webhook request ",this.webhookeventurl,options)
113
+ const req = await fetch(this.webhookeventurl, options);
114
+ const statusCode = req.status;
115
+ if(statusCode>=300){
116
+ throw new InternalServerErrorException(`create event ${eventname} failed to webhook server`)
117
+ }
118
+
119
+ // const body = req.body;
120
+ } catch (e) {
121
+ return e
122
+ }
123
+ }
124
+
125
+
126
+
127
+ async syncEventTypes(){
128
+ const options = {
129
+ method: 'GET',
130
+ headers: {
131
+ accept: 'application/json',
132
+ Authorization: this.webhookApiKey
133
+ }};
134
+ // {
135
+ // "service_name": "billing",
136
+ // "resource_type_name": "invoice",
137
+ // "verb_name": "documentno",
138
+ // "event_type_name": "billing.invoice.documentno"
139
+ // },
140
+ try{
141
+
142
+
143
+ const res = await fetch(
144
+ `${this.webhookeventtypeurl}?application_id=${this.webhookAppId}`,
145
+ options)
146
+
147
+ const locallist = this.getSchemaEventTypes()
148
+ const eventlist = (await res.json()).map(item=>item.event_type_name)
149
+
150
+ for(let i=0; i<locallist.length;i++){
151
+ const item = locallist[i]
152
+ if(!eventlist.includes(item)){
153
+ //create remote event type
154
+ await this.createEventType(item)
155
+ }
156
+ }
157
+
158
+
159
+ }catch(e){
160
+ throw new InternalServerErrorException(e)
161
+ }
162
+
163
+
164
+ }
165
+
166
+
167
+ async createEventType(eventname:string){
168
+ const para = eventname.split('.')
169
+ const options = {
170
+ method: 'POST',
171
+ headers: {
172
+ accept: 'application/json',
173
+ 'content-type': 'application/json',
174
+ Authorization: this.webhookApiKey
175
+ },
176
+ body: JSON.stringify({
177
+ application_id: this.webhookAppId,
178
+ resource_type: para[0],
179
+ service: para[1],
180
+ verb: para[2]
181
+ })
63
182
  };
64
183
 
65
- const req = await fetch(webhookurl, options);
66
- const statusCode = req.status;
67
- const body = req.body;
184
+ await fetch(this.webhookeventtypeurl, options)
185
+ // .then(response => response.json())
186
+ // .then(response => console.log(response))
187
+ // .catch(err => console.error(err));
188
+ }
189
+ getSchemaEventTypes(){
190
+ const alleventtypes:string[] = []
191
+ alldocuments.filter(item=>Array.isArray(item.webhook))
192
+ .forEach(item=>{
193
+ item.webhook.forEach(h=>{
194
+ alleventtypes.push(
195
+ `${this.webhookprefix}${item.docName.toLowerCase()}.${h}`)
196
+ })
197
+ })
198
+ return alleventtypes
199
+
68
200
  }
69
201
  }
@@ -58,6 +58,9 @@ export class UserContext {
58
58
  protected ssoACL: any = {};
59
59
  protected token: string = '';
60
60
  protected refreshtoken: string = '';
61
+ //guest access token obtain from header 'x-guest-accesstoken', during use x-apikey/x-apisecret
62
+ protected guestToken?: string='';
63
+ protected guestInfo:{uid:string,uname:string,fullname:string,email:string} = {uid:'',uname:'',fullname:'',email:''}
61
64
  protected groups: string[] = [];
62
65
  protected branchCode: string = '';
63
66
  protected branchName: string = '';
@@ -110,6 +113,7 @@ export class UserContext {
110
113
  getOffsetMinute = () => this.offsetMinute;
111
114
  getGroups = () => this.groups;
112
115
  getCurrency = () => this.currency;
116
+ getGuestInfo = () => this.guestInfo;
113
117
  getMoreProps = () => this.moreProps;
114
118
  getRoles = () => this.roles;
115
119
  getModifieds = () => this.modifiedRecords;
@@ -282,10 +286,11 @@ export class UserContext {
282
286
  this.uid = tokeninfo?.sub ?? '';
283
287
  this.email = tokeninfo?.email ?? '';
284
288
  this.uname = tokeninfo?.preferred_username ?? '';
285
- this.fullname = tokeninfo?.name ?? [];
289
+ this.fullname = tokeninfo?.name ?? '';
286
290
  this.ssoACL = tokeninfo?.resource_access ?? [];
287
291
  this.logger.verbose(`set token ${this.uid}`);
288
292
  //read current user from db
293
+ // console.log("Set User token")
289
294
  // console.log("await this.obtainProfileFromDb()")
290
295
  const userinfo = await this.obtainProfileFromDb();
291
296
  this.logger.verbose(userinfo, 'obtainProfileFromDb result');
@@ -696,6 +701,7 @@ export class UserContext {
696
701
  uname: string,
697
702
  name: string,
698
703
  email: string,
704
+ xorg:string
699
705
  ) => {
700
706
  //define token info
701
707
  this.token = '';
@@ -704,9 +710,18 @@ export class UserContext {
704
710
  this.uname = uname;
705
711
  this.fullname = name;
706
712
  this.ssoACL = '';
707
- this.roles = [Role.Everyone, Role.User];
713
+ this.roles = [Role.Everyone, Role.User,Role.SuperUser];
714
+ this.setXorg(xorg);
708
715
  };
709
716
 
717
+ setGuestToken(tokenstr:string){
718
+ const tokeninfo = jwt.decode(tokenstr);
719
+ this.guestInfo.uid = tokeninfo?.sub ?? '';
720
+ this.guestInfo.email = tokeninfo?.email ?? '';
721
+ this.guestInfo.uname = tokeninfo?.preferred_username ?? '';
722
+ this.guestInfo.fullname = tokeninfo?.name ?? '';
723
+
724
+ }
710
725
  /**
711
726
  * define additional properties from user into moreProps
712
727
  */
@@ -367,7 +367,6 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
367
367
  dbsession.startTransaction();
368
368
  }
369
369
 
370
-
371
370
  this.logger.debug(
372
371
  'this.withDocNumberFormat :' +
373
372
  this.withDocNumberFormat +
@@ -379,7 +378,6 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
379
378
  await this.genNewDocNo(appuser, data);
380
379
  }
381
380
 
382
-
383
381
  let isolationFilter: any = { ...appuser.getCreateFilter() };
384
382
  isolationFilter = this.polishIsolationFilter(isolationFilter, data);
385
383
 
@@ -623,14 +621,14 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
623
621
  `You submit older version data "v${data.__v}"" but latest version = "v${existingdata.__v}"`,
624
622
  );
625
623
  }
626
- this.logger.debug('warn1', existingdata);
624
+ // this.logger.debug('warn1', existingdata);
627
625
  data.__v = existingdata.__v + 1;
628
626
  // if (!existingdata) {
629
627
  // throw new NotFoundException(`${id} not found`, 'not found');
630
628
  // }
631
- this.logger.debug('warn2');
629
+ // this.logger.debug('warn2');
632
630
  if (this.hooks.beforeUpdate)
633
- await this.hooks.beforeUpdate(appuser, id, data, existingdata);
631
+ await this.hooks.beforeUpdate(appuser, id, existingdata,data);
634
632
 
635
633
  const dbsession = appuser.getDBSession();
636
634
  if (dbsession && !dbsession.inTransaction()) {
@@ -693,7 +691,7 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
693
691
  data.__v = existingdata.__v + 1;
694
692
 
695
693
  if (this.hooks.beforeUpdate)
696
- await this.hooks.beforeUpdate(appuser, id, data, existingdata);
694
+ await this.hooks.beforeUpdate(appuser, id,existingdata, data);
697
695
 
698
696
  const dbsession = appuser.getDBSession();
699
697
  if (dbsession && !dbsession.inTransaction()) {
@@ -0,0 +1,224 @@
1
+ /**
2
+ * This file was automatically generated by simpleapp generator. Every
3
+ * MODIFICATION OVERRIDE BY GENERATEOR
4
+ * last change 2024-02-23
5
+ * Author: Ks Tan
6
+ */
7
+ import { UserContext } from '../commons/user.context';
8
+ import * as sharelibs from '../sharelibs';
9
+ import { Injectable, InternalServerErrorException, } from '@nestjs/common';
10
+ import { InjectModel } from '@nestjs/mongoose';
11
+ import * as jsonpath from 'jsonpath';
12
+ import { Model } from 'mongoose';
13
+ import { WebhookJsonSchema } from '../jsonschemas/webhook.jsonschema';
14
+ import { SimpleAppService } from './simpleapp.processor';
15
+ import * as types from '../types';
16
+ import { DocNumberFormatGenerator } from '../commons/docnogenerator.service';
17
+ import {
18
+ WebhookBasicAuth,
19
+ WebhookHeaders,
20
+ Webhook,
21
+ } from '../types/webhook.type';
22
+ import {
23
+ DefaultWebhookBasicAuth,
24
+ DefaultWebhookHeaders,
25
+ DefaultWebhook,
26
+ } from '../defaults/webhook.default';
27
+
28
+ @Injectable()
29
+ export class WebhookProcessor extends SimpleAppService<Webhook> {
30
+ protected documentIdentityCode = 'title';
31
+ protected documentIdentityLabel = 'title';
32
+ private webhookApiKey = process.env.WEBHOOK_SERVER_APIKEY
33
+ private webhookAppId=process.env.WEBHOOK_SERVER_APP_ID
34
+ private webhookurl = process.env.WEBHOOK_SERVER_URL;
35
+ private webhookprefix = process.env.PROJECT_CODE+'.'
36
+ private webhooksubscribtionurl = `${process.env.WEBHOOK_SERVER_URL}/subscriptions/`;
37
+
38
+ protected hooks: types.WebhookHooks = {
39
+ beforeCreate: async (appuser: UserContext, data: types.Webhook) =>
40
+ this.beforeCreate(appuser, data),
41
+ beforeUpdate: async (
42
+ appuser: UserContext,
43
+ id: string,
44
+ prevdata: types.Webhook,
45
+ newdata: types.Webhook,
46
+ ) => this.beforeUpdate(appuser, id, prevdata, newdata),
47
+ afterDelete: async (
48
+ appuser: UserContext,
49
+ result: types.DeleteResultType<types.Webhook>,
50
+ id: string,
51
+ ) => this.afterDelete(appuser, result, id),
52
+ };
53
+
54
+
55
+ protected foreignkeys = {};
56
+ constructor(mydoc: Model<Webhook>) {
57
+ super('WEBHOOK', 'webhook', mydoc, types.IsolationType.tenant);
58
+ this.setSchema(WebhookJsonSchema);
59
+ this.setData(DefaultWebhook(crypto.randomUUID()));
60
+ }
61
+
62
+ reCalculateValue(data: Webhook) {
63
+ //console.log('trigger new recalculate')
64
+ const $data = data;
65
+ const jsopbj = new jsonpath['JSONPath']();
66
+ }
67
+
68
+ async beforeCreate(appuser: UserContext, data: types.Webhook) {
69
+ const createResult = await this.addRemoteWebhook(appuser, data);
70
+ if (!createResult['subscription_id'])
71
+ throw new InternalServerErrorException(
72
+ 'syncronize webhook server failed',
73
+ );
74
+ data.serverSubscriptionId = createResult.subscription_id;
75
+ data.serverSubscriptionSecret = createResult.secret;
76
+ // throw new BadRequestException("fail purposely")
77
+ }
78
+
79
+ async beforeUpdate(
80
+ appuser: UserContext,
81
+ id: string,
82
+ prevdata: types.Webhook,
83
+ newdata: types.Webhook,
84
+ ) {
85
+
86
+ if(!prevdata.serverSubscriptionId){
87
+ const createResult = await this.addRemoteWebhook(appuser, newdata);
88
+ if (!createResult['subscription_id'])
89
+ throw new InternalServerErrorException(
90
+ 'syncronize webhook server failed',
91
+ );
92
+ newdata.serverSubscriptionId = createResult.subscription_id;
93
+ newdata.serverSubscriptionSecret = createResult.secret;
94
+ }else{
95
+ await this.updateRemoteWebhook(appuser,newdata)
96
+ }
97
+ }
98
+
99
+ async afterDelete(
100
+ appuser: UserContext,
101
+ result: types.DeleteResultType<types.Webhook>,
102
+ id: string,
103
+ ) {
104
+ await this.removeRemoteWebhook(appuser,result,id)
105
+ }
106
+
107
+ async removeRemoteWebhook(
108
+ appuser: UserContext,
109
+ result: types.DeleteResultType<types.Webhook>,
110
+ id: string,
111
+ ){
112
+ const options = {
113
+ method: 'DELETE',
114
+ headers: {Authorization: this.webhookApiKey}
115
+ };
116
+
117
+
118
+ const subscriptionId=result.data.serverSubscriptionId
119
+ if(!subscriptionId)return
120
+
121
+ try{
122
+ const res = await fetch(
123
+ `${this.webhooksubscribtionurl}/${subscriptionId}?application_id=${this.webhookAppId}`,
124
+ options)
125
+ }catch(e){
126
+ throw new InternalServerErrorException(e)
127
+ }
128
+
129
+ }
130
+ async addRemoteWebhook(appuser: UserContext, data: types.Webhook) {
131
+ const headers = {};
132
+ data.headers.forEach((h) => {
133
+ headers[h.name] = h.value;
134
+ });
135
+
136
+ const options = {
137
+ method: 'POST',
138
+ headers: {
139
+ Authorization: this.webhookApiKey,
140
+ accept: 'application/json',
141
+ 'content-type': 'application/json',
142
+ },
143
+ body: JSON.stringify({
144
+ application_id: this.webhookAppId,
145
+ description: data.title,
146
+ metadata: {
147
+ tenantId: data.tenantId.toString(),
148
+ creator: appuser.getUname(),
149
+ },
150
+ is_enabled: data.active,
151
+ event_types: data.eventTypes.map(
152
+ (item) => this.webhookprefix + item,
153
+ ),
154
+ label_key: 'tenantId',
155
+ label_value: data.tenantId.toString(),
156
+ target: {
157
+ headers: headers,
158
+ type: 'http',
159
+ method: data.requestMethod.toUpperCase(),
160
+ url: data.url,
161
+ },
162
+ }),
163
+ };
164
+ try {
165
+ const res = await fetch(this.webhooksubscribtionurl, options);
166
+ return await res.json();
167
+ if (res.status >= 300) {
168
+ this.logger.error(res.statusText, 'create webhook failed');
169
+ throw new InternalServerErrorException('create webhook failed');
170
+ }
171
+ } catch (e) {
172
+ throw new InternalServerErrorException(e);
173
+ }
174
+ }
175
+
176
+ async updateRemoteWebhook(appuser: UserContext, data: types.Webhook) {
177
+ const headers = {};
178
+ data.headers.forEach((h) => {
179
+ headers[h.name] = h.value;
180
+ });
181
+
182
+ const options = {
183
+ method: 'PUT',
184
+ headers: {
185
+ Authorization: this.webhookApiKey,
186
+ accept: 'application/json',
187
+ 'content-type': 'application/json',
188
+ },
189
+ body: JSON.stringify({
190
+ application_id: this.webhookAppId,
191
+ description: data.title,
192
+ metadata: {
193
+ tenantId: data.tenantId.toString(),
194
+ creator: appuser.getUname(),
195
+ },
196
+ is_enabled: data.active,
197
+ event_types: data.eventTypes.map(
198
+ (item) => this.webhookprefix + item,
199
+ ),
200
+ label_key: 'tenantId',
201
+ label_value: data.tenantId.toString(),
202
+ target: {
203
+ headers: headers,
204
+ type: 'http',
205
+ method: data.requestMethod.toUpperCase(),
206
+ url: data.url,
207
+ },
208
+ }),
209
+ };
210
+ try {
211
+ const subscriptionId = data.serverSubscriptionId
212
+ const res = await fetch(`${this.webhooksubscribtionurl}/${subscriptionId}`, options);
213
+ return await res.json();
214
+ if (res.status >= 300) {
215
+ this.logger.error(res.statusText, 'updateRemoteWebhook webhook failed');
216
+ throw new InternalServerErrorException('update webhook failed');
217
+ }
218
+ } catch (e) {
219
+ throw new InternalServerErrorException(e);
220
+ }
221
+ }
222
+
223
+ /***************************** additional execute *****************************************/
224
+ }