@simitgroup/simpleapp-generator 1.1.7 → 1.1.9

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.
@@ -4,77 +4,128 @@
4
4
  * last change 2023-10-28
5
5
  * Author: Ks Tan
6
6
  */
7
- import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
8
- import { Observable } from 'rxjs';
9
- import { tap } from 'rxjs/operators';
10
- import { Model,Connection, ClientSession } from 'mongoose';
11
- import { InjectConnection,InjectModel } from '@nestjs/mongoose';
7
+ import {
8
+ Injectable,
9
+ NestInterceptor,
10
+ ExecutionContext,
11
+ CallHandler,
12
+ BadGatewayException,
13
+ HttpException,
14
+ } from '@nestjs/common';
15
+ import { Observable, throwError } from 'rxjs';
16
+ import { catchError, tap } from 'rxjs/operators';
17
+ import { Model, Connection, ClientSession } from 'mongoose';
18
+ import { InjectConnection, InjectModel } from '@nestjs/mongoose';
12
19
  import { UserContext } from '../user.context';
13
20
  import { ApiEvent } from '../../types/apievent.type';
14
21
  @Injectable()
15
22
  export class ResponseInterceptor implements NestInterceptor {
16
-
17
- constructor(
18
- @InjectConnection() private readonly connection: Connection,
19
- @InjectModel('ApiEvent') private apieventmodel: Model<ApiEvent>,
20
- ){
21
-
22
-
23
- }
24
- async intercept(context: ExecutionContext, next: CallHandler): Promise<Observable<any>> {
25
- const req = context.switchToHttp().getRequest()
26
- const resp = context.switchToHttp().getResponse()
27
- const usersession:UserContext = req['sessionuser']
28
- const method = req['method']
29
- const headers = {...req['headers']}
30
- const ip = req['ip']
31
- const url = req['url']
32
- // let { url, method, headers, body }
33
- const session:ClientSession = usersession.getDBSession()
34
- const logid:string = crypto.randomUUID()
35
- const starttime =new Date()
23
+ constructor(
24
+ @InjectConnection() private readonly connection: Connection,
25
+ @InjectModel('ApiEvent') private apieventmodel: Model<ApiEvent>,
26
+ ) {}
36
27
 
28
+
29
+ async intercept(
30
+ context: ExecutionContext,
31
+ next: CallHandler,
32
+ ): Promise<Observable<any>> {
33
+ const req = context.switchToHttp().getRequest();
34
+ const resp = context.switchToHttp().getResponse();
35
+ const usersession: UserContext = req['sessionuser'];
36
+
37
+ const method = req['method'];
38
+ const headers = { ...req['headers'] };
39
+ const ip = req['ip'];
40
+ const url = req['url'];
41
+ // let { url, method, headers, body }
42
+ const session = await this.connection.startSession();
43
+ if(!session['runCount']){
44
+ session['runCount']=0
45
+ }else{
46
+ session['runCount']=session['runCount']+1
47
+ }
48
+ usersession.setDBSession(session)
49
+ // const session: ClientSession = usersession.getDBSession();
50
+ const logid: string = crypto.randomUUID();
51
+ const starttime = new Date();
52
+ let canCommit = true
37
53
  //authorization no need
38
- delete headers['authorization']//='--removed--'
39
- const data:ApiEvent = {
54
+ delete headers['authorization']; //='--removed--'
55
+ const eventdata: ApiEvent = {
40
56
  _id: logid,
41
57
  created: starttime.toISOString(),
42
- duration : 0,
58
+ duration: 0,
43
59
  createdBy: usersession.getUid(),
44
60
  path: url,
45
61
  method: method,
46
62
  headers: headers,
47
- ip:ip,
63
+ ip: ip,
48
64
  // data: req.body,
49
- statusCode:0,
50
- status:'D'
51
- }
52
- const eventmodel = new this.apieventmodel(data)
53
-
54
- const eventObj = await eventmodel.save()
55
-
56
- req['eventObj']=eventObj
57
- return next
58
- .handle()
59
- .pipe(
60
- tap(async () => {
61
-
62
- const endtime =new Date()
63
- eventObj.isNew=false
64
- eventObj.statusCode=resp['statusCode']
65
- eventObj.updated = endtime.toISOString()
66
- eventObj.status="OK"
67
- eventObj.duration = endtime.getTime() - starttime.getTime()
68
- const result = await eventObj.save()//({_id:logid},{statusCode:resp['statusCode']})
69
- // console.log("result===",logid,result)
65
+ statusCode: 0,
66
+ status: 'D',
67
+ };
68
+ const eventmodel = new this.apieventmodel(eventdata);
69
+
70
+ const eventObj = await eventmodel.save();
71
+
72
+ // req['eventObj'] = eventObj;
73
+ return next.handle().pipe(
74
+
75
+ catchError( async(err,caught)=>{
76
+
77
+ // console.log('**************catchError at interceptor ',method,url)
78
+ if (session.inTransaction()) {
79
+ await session.abortTransaction()
80
+ canCommit=false
81
+ }
70
82
 
71
- if(process.env.DRYRUN=='true'){
72
- console.warn("--------dryrun! roll back everything-----------")
73
- if(session.inTransaction())session.abortTransaction()
74
- }else{
75
- if(session.inTransaction())session.commitTransaction()
76
- }
77
- }),
78
- );
83
+
84
+ const responseBody = {
85
+ message: err.message,
86
+ timestamp: new Date().toISOString(),
87
+ path: url,
88
+ error: err.options,
89
+ };
90
+
91
+ // eventObj.statusCode = err.status;
92
+ // eventObj.errMsg = responseBody.message;
93
+ // const endtime = new Date();
94
+ // eventObj.updated = endtime.toISOString();
95
+ // eventObj.data = req.body;
96
+ // eventObj.errData = responseBody.error;
97
+ // eventObj.status = 'NG';
98
+ // eventObj.duration =
99
+ // endtime.getTime() - new Date(eventObj.created).getTime();
100
+ // eventObj.save();
101
+
102
+ resp.status(err.status)
103
+ return responseBody
104
+
105
+ }),
106
+ tap(async () => {
107
+ // console.log("============interceptor tap",method,url)
108
+ const endtime = new Date();
109
+ eventObj.isNew = false;
110
+ eventObj.statusCode = resp['statusCode'];
111
+ eventObj.updated = endtime.toISOString();
112
+ eventObj.status = 'OK';
113
+ eventObj.duration = endtime.getTime() - starttime.getTime();
114
+ await eventObj.save();
115
+
116
+
117
+ if (process.env.DRYRUN == 'true') {
118
+ console.warn('--------dryrun! roll back everything-----------');
119
+ if (session.inTransaction() && canCommit ) {
120
+ await session.abortTransaction()
121
+ }
122
+ } else {
123
+ if (session.inTransaction() && canCommit ) {
124
+ await session.commitTransaction()//.then(()=>session.endSession());
125
+ }
126
+ }
127
+ // session.endSession()
128
+ }),
129
+ );
79
130
  }
80
- }
131
+ }
@@ -4,13 +4,19 @@
4
4
  * last change 2023-10-28
5
5
  * Author: Ks Tan
6
6
  */
7
- import { Injectable, NestMiddleware, Logger,Scope,Inject } from '@nestjs/common';
7
+ import {
8
+ Injectable,
9
+ NestMiddleware,
10
+ Logger,
11
+ Scope,
12
+ Inject,
13
+ } from '@nestjs/common';
8
14
  import { Request, Response, NextFunction } from 'express';
9
15
  import { InjectModel } from '@nestjs/mongoose';
10
- import { Model,Connection } from 'mongoose';
16
+ import { Model, Connection } from 'mongoose';
11
17
  // import * as mongoose from 'mongoose';
12
- import { User, } from '../../types/user.type';
13
- import { Permission, } from '../../types/perm.type';
18
+ import { User } from '../../types/user.type';
19
+ import { Permission } from '../../types/perm.type';
14
20
  import { InjectConnection } from '@nestjs/mongoose';
15
21
 
16
22
  const Base64URL = require('@darkwolf/base64url');
@@ -20,75 +26,80 @@ import { UserContext } from '../user.context';
20
26
  // import {KeycloakConfigService} from "../keycloak/keycloak.service"
21
27
  @Injectable()
22
28
  export class TenantMiddleware implements NestMiddleware {
23
- protected defaultxorg=Base64URL.encodeText('0-0-0')
24
- protected excludeXorgs = ['/profile', '/profile/tenant']
25
- protected logger = new Logger()
26
- protected transController
27
- constructor(
28
- @InjectModel('User') private readonly usermodel:Model<User>,
29
- @InjectModel('Permission') private readonly permmodel:Model<Permission>,
30
- @InjectConnection() private readonly connection: Connection,
31
- ){}
32
-
33
- requireXorg(baseurl:string):boolean{
29
+ protected defaultxorg = Base64URL.encodeText('0-0-0');
30
+ protected excludeXorgs = ['/profile', '/profile/tenant'];
31
+ protected logger = new Logger();
32
+ protected transController;
33
+ constructor(
34
+ @InjectModel('User') private readonly usermodel: Model<User>,
35
+ @InjectModel('Permission') private readonly permmodel: Model<Permission>,
36
+
37
+ ) {}
38
+
39
+ requireXorg(baseurl: string): boolean {
34
40
  // console.log('requireXorg')
35
- for(let i =0; i < this.excludeXorgs.length;i++){
36
- if(baseurl.includes(this.excludeXorgs[i])){
37
- this.logger.verbose("requireXorg = false")
38
- return false
41
+ for (let i = 0; i < this.excludeXorgs.length; i++) {
42
+ if (baseurl.includes(this.excludeXorgs[i])) {
43
+ this.logger.verbose('requireXorg = false');
44
+ return false;
39
45
  }
40
46
  }
41
47
  // console.log("Require xorg")
42
- return true
48
+ return true;
43
49
  }
44
50
  async use(req: Request, res: Response, next: NextFunction) {
45
51
  if (req.baseUrl == '/oauth2-redirect.html') {
46
52
  next();
47
53
  return;
48
54
  }
49
- this.logger.debug(`running TenantMiddleware for ${req.baseUrl}`)
55
+ this.logger.debug(`running TenantMiddleware for ${req.baseUrl}`);
50
56
  if (!req.headers['authorization']) {
51
- this.logger.log("undefine bearer token")
57
+ this.logger.log('undefine bearer token');
52
58
  return res.status(401).send('Undefine bearer token');
53
59
  }
54
60
  if (!req.headers['x-org'] && this.requireXorg(req.baseUrl)) {
55
- this.logger.log("undefine x-org and require that at "+req.baseUrl,"TenantMiddleware")
61
+ this.logger.log(
62
+ 'undefine x-org and require that at ' + req.baseUrl,
63
+ 'TenantMiddleware',
64
+ );
56
65
  return res.status(401).send('undefine header string x-org');
57
66
  }
58
- const session = await this.connection.startSession()
59
- const u = new UserContext(this.usermodel,this.permmodel,session)
67
+ // const session = await this.connection.startSession();
68
+ const u = new UserContext(this.usermodel, this.permmodel);
60
69
  // console.log("line 43")
61
70
  try {
62
71
  let tokenstr: string = req.headers['authorization'];
63
72
  tokenstr = tokenstr.replace('Bearer ', '');
64
-
65
- const xorg = req.headers['x-org']?? this.defaultxorg
66
73
 
67
- await u.setCurrentUserInfo(tokenstr,xorg)
68
- if(u.getId()=='' && this.requireXorg(req.baseUrl)){
69
- this.logger.log("access deny of no user:", req.baseUrl)
70
- return res.status(401).send('access deny');
71
- }else{
72
- if(u.getId()==''){
73
- this.logger.verbose(`grant new user (${u.getUid()}) access ${req.baseUrl}`)
74
- }else{
75
- this.logger.verbose(`grant user (${u.getId()}) access ${req.baseUrl}`)
74
+ const xorg = req.headers['x-org'] ?? this.defaultxorg;
75
+
76
+ await u.setCurrentUserInfo(tokenstr, xorg);
77
+ if (u.getId() == '' && this.requireXorg(req.baseUrl)) {
78
+ this.logger.log('access deny of no user:', req.baseUrl);
79
+ return res.status(401).send('access deny');
80
+ } else {
81
+ if (u.getId() == '') {
82
+ this.logger.verbose(
83
+ `grant new user (${u.getUid()}) access ${req.baseUrl}`,
84
+ );
85
+ } else {
86
+ this.logger.verbose(
87
+ `grant user (${u.getId()}) access ${req.baseUrl}`,
88
+ );
76
89
  }
77
- req['sessionuser'] = u
78
- this.logger.verbose(u.getRoles())
90
+ req['sessionuser'] = u;
91
+ this.logger.verbose(u.getRoles());
79
92
 
80
93
  next();
81
94
  }
82
-
83
- } catch(err) {
84
- this.logger.warn(err,"invalid xorg or user info",)
85
- this.logger.error(err)
86
- if(err=='invalid x-org'){
95
+ } catch (err) {
96
+ this.logger.warn(err, 'invalid xorg or user info');
97
+ this.logger.error(err);
98
+ if (err == 'invalid x-org') {
87
99
  return res.status(403).send(err);
88
- }else{
100
+ } else {
89
101
  return res.status(401).send(err);
90
102
  }
91
-
92
103
  }
93
104
  }
94
105
  }