@simitgroup/simpleapp-generator 1.6.4-f-alpha → 1.6.6-a-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 +16 -0
- package/package.json +1 -1
- package/templates/basic/nest/controller.ts.eta +3 -3
- package/templates/basic/nuxt/simpleapp.generate.client.ts.eta +2 -2
- package/templates/nest/.env._eta +2 -0
- package/templates/nest/src/app.module.ts.eta +12 -5
- package/templates/nest/src/main.ts.eta +30 -0
- package/templates/nest/src/simpleapp/generate/apischemas/simpleapp.apischema.ts.eta +46 -12
- package/templates/nest/src/simpleapp/generate/commons/customkeycloa.guard.ts.eta +43 -0
- package/templates/nest/src/simpleapp/generate/commons/middlewares/tenant.middleware.ts.eta +31 -5
- package/templates/nest/src/simpleapp/generate/commons/robotuser.service.ts.eta +15 -17
- package/templates/nest/src/simpleapp/generate/commons/user.context.ts.eta +17 -2
- package/templates/nest/src/simpleapp/generate/processors/simpleapp.processor.ts.eta +5 -4
- package/templates/nuxt/composables/getOpenApi.generate.ts.eta +1 -1
- package/templates/nuxt/simpleapp/generate/clients/SimpleAppClient.ts.eta +1 -1
package/ReleaseNote.md
CHANGED
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
[1.6.6a-alpha]
|
|
2
|
+
1. fix simpleapp generated frontend lib bugs
|
|
3
|
+
|
|
4
|
+
[1.6.5g]
|
|
5
|
+
1. change simpleapp document controller use document name instead of document type
|
|
6
|
+
2. allow use header x-apikey(match env X_APIKEY), x-apisecret (match env X_APISECRET), to by pass access token. which will use robotuser in user context
|
|
7
|
+
3. add support of x-guest-accesstoken (submit by external user source, like parent/student app), it store into usercontext as guestinfo, since appuser = robotuser
|
|
8
|
+
4. Fix document search properties to restrict (required field and sorts)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
[1.6.5f]
|
|
12
|
+
1. added webhook db
|
|
13
|
+
2. support audit trail
|
|
14
|
+
3. support upload avatar to cloudapi
|
|
15
|
+
4. added html input for simpleapp
|
|
16
|
+
|
|
1
17
|
[1.2.0]
|
|
2
18
|
1. lot of house keeping
|
|
3
19
|
2. frontend more stable login using keycloak
|
package/package.json
CHANGED
|
@@ -56,9 +56,9 @@ import {UserContext} from '../commons/user.context'
|
|
|
56
56
|
}
|
|
57
57
|
%>
|
|
58
58
|
<% let superadmindoctype = ['tenant','globaluser'] %>
|
|
59
|
-
const
|
|
60
|
-
@ApiTags(
|
|
61
|
-
@Controller(
|
|
59
|
+
const apiname = '<%= it.typename %>'.toUpperCase();
|
|
60
|
+
@ApiTags(apiname)
|
|
61
|
+
@Controller(apiname.toLowerCase())
|
|
62
62
|
export class <%= it.typename %>Controller extends SimpleAppAbstractController<
|
|
63
63
|
<%= it.typename %>Service,
|
|
64
64
|
schemas.<%= it.typename%>,
|
|
@@ -34,7 +34,7 @@ export type {
|
|
|
34
34
|
|
|
35
35
|
} from '../openapi'
|
|
36
36
|
|
|
37
|
-
export class <%= it.
|
|
37
|
+
export class <%= capitalizeFirstLetter(it.name)%>Client extends SimpleAppClient<openapi.<%= capitalizeFirstLetter(it.name)%>,openapi.<%= it.name.toUpperCase()%>Api>{
|
|
38
38
|
public readonly schema= <%~ JSON.stringify(it.jsonschema) %> as SchemaType;
|
|
39
39
|
protected documentIdentityCode='<%~ it.autocompletecode %>'
|
|
40
40
|
protected documentIdentityName='<%~ it.autocompletename %>'
|
|
@@ -49,7 +49,7 @@ export class <%= it.typename%>Client extends SimpleAppClient<openapi.<%= it.type
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
//const apipath = `${useRuntimeConfig().public.API_URL}/${xorg}`
|
|
52
|
-
//const apiobj = new <%= it.
|
|
52
|
+
//const apiobj = new <%= it.name.toUpperCase()%>Api(undefined,apipath,$axios)
|
|
53
53
|
const apiobj = getDocumentApi('<%=it.name %>')
|
|
54
54
|
super(apiobj,'<%= it.doctype %>','<%=it.name %>')
|
|
55
55
|
this.event=$event
|
package/templates/nest/.env._eta
CHANGED
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
RoleGuard,
|
|
26
26
|
PolicyEnforcementMode,
|
|
27
27
|
} from 'nest-keycloak-connect';
|
|
28
|
+
import { CustomKeycloakGuard } from './simpleapp/generate/commons/customkeycloak.guard';
|
|
28
29
|
import {RolesGuard} from './simpleapp/generate/commons/roles/roles.guard'
|
|
29
30
|
import { ConfigModule } from '@nestjs/config';
|
|
30
31
|
import { ServeStaticModule } from '@nestjs/serve-static';
|
|
@@ -92,11 +93,17 @@ import { EventEmitterModule } from '@nestjs/event-emitter';
|
|
|
92
93
|
]),
|
|
93
94
|
],
|
|
94
95
|
controllers: [AppController],
|
|
95
|
-
providers: [
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
96
|
+
providers: [
|
|
97
|
+
AppService,
|
|
98
|
+
CustomKeycloakGuard,
|
|
99
|
+
ResourceGuard,
|
|
100
|
+
AppResolver,
|
|
101
|
+
{
|
|
102
|
+
provide: APP_INTERCEPTOR,
|
|
103
|
+
useClass: ResponseInterceptor,
|
|
104
|
+
},
|
|
105
|
+
{provide: APP_GUARD,useClass: CustomKeycloakGuard,},
|
|
106
|
+
// {provide: APP_GUARD,useClass: AuthGuard,},
|
|
100
107
|
{provide: APP_GUARD,useClass: ResourceGuard,},
|
|
101
108
|
{provide: APP_GUARD,useClass: RolesGuard,}
|
|
102
109
|
],
|
|
@@ -49,9 +49,39 @@ async function bootstrap() {
|
|
|
49
49
|
},
|
|
50
50
|
},
|
|
51
51
|
'oauth2',
|
|
52
|
+
).
|
|
53
|
+
addApiKey(
|
|
54
|
+
{
|
|
55
|
+
in: 'header',
|
|
56
|
+
name: 'x-apikey',
|
|
57
|
+
type: 'apiKey',
|
|
58
|
+
description: 'optional only use for specal case',
|
|
59
|
+
},
|
|
60
|
+
'x-apikey',
|
|
61
|
+
).addApiKey(
|
|
62
|
+
{
|
|
63
|
+
in: 'header',
|
|
64
|
+
name: 'x-apisecret',
|
|
65
|
+
type: 'apiKey',
|
|
66
|
+
description: 'optional only use for specal case',
|
|
67
|
+
},
|
|
68
|
+
'x-apisecret',
|
|
69
|
+
)
|
|
70
|
+
.addApiKey(
|
|
71
|
+
{
|
|
72
|
+
in: 'header',
|
|
73
|
+
name: 'x-guest-accesstoken',
|
|
74
|
+
type: 'apiKey',
|
|
75
|
+
description: 'optional only use for specal case',
|
|
76
|
+
},
|
|
77
|
+
'x-guest-accesstoken',
|
|
52
78
|
)
|
|
79
|
+
|
|
53
80
|
.addSecurityRequirements('x-org')
|
|
54
81
|
.addSecurityRequirements('oauth2')
|
|
82
|
+
.addSecurityRequirements('x-apikey')
|
|
83
|
+
.addSecurityRequirements('x-apisecret')
|
|
84
|
+
.addSecurityRequirements('x-guest-accesstoken')
|
|
55
85
|
.build();
|
|
56
86
|
const document = SwaggerModule.createDocument(app, config);
|
|
57
87
|
SwaggerModule.setup('api', app, document, {
|
|
@@ -7,16 +7,50 @@
|
|
|
7
7
|
|
|
8
8
|
import { ApiProperty } from '@nestjs/swagger';
|
|
9
9
|
export class ApiKeyValuePair {
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
@ApiProperty({
|
|
11
|
+
type: Object,
|
|
12
|
+
required: false,
|
|
13
|
+
examples: ['{"field1":"1"}'],
|
|
14
|
+
default: '',
|
|
15
|
+
})
|
|
16
|
+
field1: any;
|
|
17
|
+
}
|
|
18
|
+
export class SortItem {
|
|
19
|
+
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
export class ApiSearchBody {
|
|
24
|
+
@ApiProperty({
|
|
25
|
+
type: Object,
|
|
26
|
+
required: false,
|
|
27
|
+
examples: ['{"field1":"1"}'],
|
|
28
|
+
default: { field1: 'ok', field2: true },
|
|
29
|
+
})
|
|
30
|
+
filter?: Object;
|
|
31
|
+
@ApiProperty({
|
|
32
|
+
type: [String],
|
|
33
|
+
required: false,
|
|
34
|
+
examples: ['["field1","field2"]'],
|
|
35
|
+
default: ['field1', 'field2'],
|
|
36
|
+
})
|
|
37
|
+
fields?: string[];
|
|
38
|
+
@ApiProperty({
|
|
39
|
+
type: 'array',
|
|
40
|
+
required: false,
|
|
41
|
+
items:{
|
|
42
|
+
type: 'array',
|
|
43
|
+
items:{
|
|
44
|
+
type:'string'
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
examples: ['[[ "field1", "asc" ]]'],
|
|
48
|
+
default: [['field1', 'asc']],
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
sorts?: string[][];
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@ApiProperty({ type: () => Object, required: false })
|
|
55
|
+
lookup: Object;
|
|
12
56
|
}
|
|
13
|
-
export class ApiSearchBody{
|
|
14
|
-
@ApiProperty({ "type":Object, "required":false, "examples":['{"field1":"1"}'] ,"default":{"field1":"ok","field2":true,}} )
|
|
15
|
-
filter: Object;
|
|
16
|
-
@ApiProperty({"type":[Object],"required":true,"examples":['["field1","field2"]'],"default":["field1","field2"]} )
|
|
17
|
-
fields: [Object];
|
|
18
|
-
@ApiProperty({"type":()=>[Object],"required":true,"examples":['[[ "field1", "asc" ]]'],"default":[[ 'field1', 'asc' ]]} )
|
|
19
|
-
sorts: [Object];
|
|
20
|
-
@ApiProperty({type: () => Object,required: false,})
|
|
21
|
-
lookup: Object
|
|
22
|
-
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file was automatically generated by simpleapp generator. Every
|
|
3
|
+
* MODIFICATION OVERRIDE BY GENERATEOR
|
|
4
|
+
* last change 2024-04-17
|
|
5
|
+
* Author: Ks Tan
|
|
6
|
+
*/
|
|
7
|
+
import { Injectable, CanActivate, ExecutionContext, UnauthorizedException } from '@nestjs/common';
|
|
8
|
+
import { Reflector } from '@nestjs/core';
|
|
9
|
+
import { ResourceGuard } from 'nest-keycloak-connect';
|
|
10
|
+
|
|
11
|
+
@Injectable()
|
|
12
|
+
export class CustomKeycloakGuard implements CanActivate {
|
|
13
|
+
constructor(private reflector: Reflector, private resourceGuard: ResourceGuard) {}
|
|
14
|
+
|
|
15
|
+
async canActivate(context: ExecutionContext): Promise<boolean> {
|
|
16
|
+
const request = context.switchToHttp().getRequest();
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
//graphql no http request, exclude from capability of x-apikey
|
|
20
|
+
if(request?.headers){
|
|
21
|
+
const apiKey = request.headers['x-apikey'];
|
|
22
|
+
const apiSecret = request.headers['x-apisecret'];
|
|
23
|
+
// validate apikey and apisecret at middleware level, reach here mean approved as robot
|
|
24
|
+
if (apiKey && apiSecret ) {
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// If API key is not present, fall back to Keycloak authentication
|
|
30
|
+
try {
|
|
31
|
+
const canActivate = await this.resourceGuard.canActivate(context);
|
|
32
|
+
return canActivate as boolean;
|
|
33
|
+
} catch (error) {
|
|
34
|
+
throw new UnauthorizedException('Invalid API key or Keycloak token');
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
private validateApiKey(apiKey: string, apiSecret: string): boolean {
|
|
39
|
+
// Implement your API key and secret validation logic here
|
|
40
|
+
// This is just a simple example
|
|
41
|
+
return apiKey === 'your-valid-api-key' && apiSecret === 'your-valid-api-secret';
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -56,9 +56,9 @@ export class TenantMiddleware implements NestMiddleware {
|
|
|
56
56
|
|
|
57
57
|
if (req.baseUrl == '/graphql') {
|
|
58
58
|
let tokenstr: string = req.headers['authorization'] ?? '';
|
|
59
|
-
tokenstr = tokenstr.replace('Bearer ', '');
|
|
60
|
-
const xorg = req.headers['x-org'] ?? this.defaultxorg;
|
|
61
|
-
if (tokenstr) {
|
|
59
|
+
tokenstr = tokenstr.replace('Bearer ', '');
|
|
60
|
+
const xorg = req.headers['x-org'] ?? this.defaultxorg;
|
|
61
|
+
if (tokenstr) {
|
|
62
62
|
await u.setCurrentUserInfo(tokenstr, xorg);
|
|
63
63
|
}
|
|
64
64
|
req['sessionuser'] = u;
|
|
@@ -66,6 +66,33 @@ export class TenantMiddleware implements NestMiddleware {
|
|
|
66
66
|
return;
|
|
67
67
|
}
|
|
68
68
|
this.logger.debug(`running TenantMiddleware for ${req.baseUrl}`);
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
//if APIKEY defined, and there is api key and secret supplied. use robot user
|
|
72
|
+
if(process.env.X_APIKEY &&req.headers['x-apikey'] && req.headers['x-apisecret']){
|
|
73
|
+
|
|
74
|
+
if(req.headers['x-apikey']==process.env.X_APIKEY &&
|
|
75
|
+
req.headers['x-apisecret']==process.env.X_APISECRET){
|
|
76
|
+
|
|
77
|
+
u.setAsStaticUser(
|
|
78
|
+
'00000000-0000-0000-0000-000000000000',
|
|
79
|
+
'robot',
|
|
80
|
+
'Robot',
|
|
81
|
+
'robot@a.org',
|
|
82
|
+
req.headers['x-org']?? this.defaultxorg
|
|
83
|
+
);
|
|
84
|
+
if(req.headers['x-guest-accesstoken']) {
|
|
85
|
+
u.setGuestToken(<string>req.headers['x-guest-accesstoken']);
|
|
86
|
+
}
|
|
87
|
+
req['sessionuser'] = u;
|
|
88
|
+
next();
|
|
89
|
+
return;
|
|
90
|
+
}else{
|
|
91
|
+
this.logger.log('invalid api key/scret');
|
|
92
|
+
throw new BadRequestException('invalid api key/scret');
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
69
96
|
if (!req.headers['authorization']) {
|
|
70
97
|
this.logger.log('undefine bearer token');
|
|
71
98
|
return res.status(401).send('Undefine bearer token');
|
|
@@ -84,8 +111,7 @@ export class TenantMiddleware implements NestMiddleware {
|
|
|
84
111
|
let tokenstr: string = req.headers['authorization'];
|
|
85
112
|
tokenstr = tokenstr.replace('Bearer ', '');
|
|
86
113
|
|
|
87
|
-
const xorg = req.headers['x-org'] ?? this.defaultxorg;
|
|
88
|
-
|
|
114
|
+
const xorg = req.headers['x-org'] ?? this.defaultxorg;
|
|
89
115
|
await u.setCurrentUserInfo(tokenstr, xorg);
|
|
90
116
|
if (u.getId() == '' && this.requireXorg(req.baseUrl)) {
|
|
91
117
|
this.logger.log('access deny of no user:', req.baseUrl);
|
|
@@ -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) =>
|
|
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
|
-
|
|
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
|
-
|
|
86
|
-
|
|
87
|
-
|
|
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
|
-
|
|
107
|
-
// 'return user ' + appuser.getUname(),
|
|
108
|
-
// appuser.getXorg(),
|
|
109
|
-
// appuser.getUserToken().length,
|
|
110
|
-
// );
|
|
108
|
+
|
|
111
109
|
return appuser;
|
|
112
110
|
}
|
|
113
111
|
}
|
|
@@ -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
|
*/
|
|
@@ -628,7 +628,7 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
|
|
|
628
628
|
// }
|
|
629
629
|
// this.logger.debug('warn2');
|
|
630
630
|
if (this.hooks.beforeUpdate)
|
|
631
|
-
await this.hooks.beforeUpdate(appuser, id,
|
|
631
|
+
await this.hooks.beforeUpdate(appuser, id, existingdata, data);
|
|
632
632
|
|
|
633
633
|
const dbsession = appuser.getDBSession();
|
|
634
634
|
if (dbsession && !dbsession.inTransaction()) {
|
|
@@ -691,7 +691,7 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
|
|
|
691
691
|
data.__v = existingdata.__v + 1;
|
|
692
692
|
|
|
693
693
|
if (this.hooks.beforeUpdate)
|
|
694
|
-
await this.hooks.beforeUpdate(appuser, id,existingdata, data);
|
|
694
|
+
await this.hooks.beforeUpdate(appuser, id, existingdata, data);
|
|
695
695
|
|
|
696
696
|
const dbsession = appuser.getDBSession();
|
|
697
697
|
if (dbsession && !dbsession.inTransaction()) {
|
|
@@ -1058,7 +1058,8 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
|
|
|
1058
1058
|
collections.forEach((tokey: string) => {
|
|
1059
1059
|
const toarr = tokey.split('.');
|
|
1060
1060
|
const to = toarr[0];
|
|
1061
|
-
|
|
1061
|
+
toarr.splice(0,1)
|
|
1062
|
+
const foreignField = toarr.join('.') ?? '_id';
|
|
1062
1063
|
pipelines.push({
|
|
1063
1064
|
$lookup: {
|
|
1064
1065
|
from: to,
|
|
@@ -1083,7 +1084,7 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
|
|
|
1083
1084
|
});
|
|
1084
1085
|
pipelines.push({ $sort: sortobj });
|
|
1085
1086
|
}
|
|
1086
|
-
|
|
1087
|
+
this.logger.warn( pipelines,'pipelinespipelinespipelines',);
|
|
1087
1088
|
|
|
1088
1089
|
return pipelines;
|
|
1089
1090
|
}
|
|
@@ -39,7 +39,7 @@ export const getDocumentApi = (documentName: string): any => {
|
|
|
39
39
|
const config = getAxiosConfig()
|
|
40
40
|
const docsOpenapi: any = {
|
|
41
41
|
<% for(let i=0;i<it.modules.length; i++){ %>
|
|
42
|
-
'<%=it.modules[i].docname.toLowerCase()%>': new o.<%=it.modules[i].
|
|
42
|
+
'<%=it.modules[i].docname.toLowerCase()%>': new o.<%=it.modules[i].docname.toUpperCase()%>Api(config),
|
|
43
43
|
<%}%>
|
|
44
44
|
};
|
|
45
45
|
|