@simitgroup/simpleapp-generator 1.0.24 → 1.0.25

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/dist/framework.js CHANGED
@@ -41,6 +41,12 @@ let config = {
41
41
  "frontendFolder": "./myfrontend",
42
42
  "frontendPort": "8080",
43
43
  "openapi3Yaml": "../openapi.yaml",
44
+ "keycloaksetting": {
45
+ "OAUTH2_CONFIGURL": "https://keycloak-server-url/realms/realm-name",
46
+ "OAUTH2_CLIENTID": "client-id",
47
+ "OAUTH2_CLIENTSECRET": "client-secret-value",
48
+ "AUTH_SECRET_KEY": "my-secret",
49
+ }
44
50
  };
45
51
  const setConfiguration = (paraconfig) => {
46
52
  config = paraconfig;
@@ -81,18 +87,18 @@ const prepareNest = (callback) => {
81
87
  const targetfolder = config.backendFolder;
82
88
  log.info(`creating backend project ${targetfolder}`);
83
89
  if (!fs_1.default.existsSync(`${targetfolder}/.env`)) {
84
- (0, child_process_1.exec)(`cd ${targetfolder};pnpm install --save axios @darkwolf/base64url json-schema @wearenova/mongoose-tenant @nestjs/swagger @nestjs/mongoose mongoose ajv ajv-formats @nestjs/config`, async (error, stdout, stderr) => {
90
+ (0, child_process_1.exec)(`cd ${targetfolder};pnpm install --save @nestjs/serve-static axios @darkwolf/base64url json-schema @wearenova/mongoose-tenant @nestjs/swagger @nestjs/mongoose mongoose ajv ajv-formats @nestjs/config`, async (error, stdout, stderr) => {
85
91
  // log.info(`dependency installed`)
86
92
  if (!error) {
93
+ fs_1.default.mkdirSync(`${targetfolder}/public_html`, { recursive: true });
87
94
  const eta = new eta_1.Eta({ views: constants.templatedir });
88
- const variables = {
89
- backendPort: config.backendPort,
90
- mongoConnectStr: config.mongoConnectStr
91
- };
95
+ const variables = config;
92
96
  const txtEnv = eta.render('./nest/nest.env.eta', variables);
93
97
  const txtMain = eta.render('./nest/nest.main.eta', variables);
98
+ const txtRedirectHtml = eta.render('./nest/oauth2-redirect.eta', variables);
94
99
  fs_1.default.writeFileSync(`${targetfolder}/.env`, txtEnv);
95
100
  fs_1.default.writeFileSync(`${targetfolder}/src/main.ts`, txtMain);
101
+ fs_1.default.writeFileSync(`${targetfolder}/public_html/oauth2-redirect.html`, txtRedirectHtml);
96
102
  const tsconfigpath = process.cwd() + '/' + `${targetfolder}/tsconfig.json`;
97
103
  const tsconfig = require(tsconfigpath);
98
104
  tsconfig.compilerOptions.esModuleInterop = true;
@@ -118,22 +124,20 @@ const prepareNuxt = (callback) => {
118
124
  const targetfolder = config.frontendFolder;
119
125
  if (!fs_1.default.existsSync(`${targetfolder}/.env`)) {
120
126
  //asume no environment. prepare now
121
- (0, child_process_1.exec)(`cd ${targetfolder};pnpm install;pnpm install -D @nuxt/ui @types/node @vueuse/nuxt @sidebase/nuxt-auth @vueuse/core nuxt-security prettier `, (error, stdout, stderr) => {
127
+ (0, child_process_1.exec)(`cd ${targetfolder};pnpm install;pnpm install -D @sidebase/nuxt-auth @nuxt/ui @types/node @vueuse/nuxt @sidebase/nuxt-auth @vueuse/core nuxt-security prettier `, (error, stdout, stderr) => {
122
128
  //;pnpm install
123
129
  console.log(error, stdout, stderr);
124
- (0, child_process_1.exec)(`cd ${targetfolder};pnpm install --save @darkwolf/base64url @nuxt/ui ajv dotenv @fullcalendar/core @fullcalendar/vue3 quill uuid ajv-formats primeflex primeicons prettier primevue axios json-schema mitt @simitgroup/simpleapp-vue-component@latest`, (error, stdout, stderr) => {
130
+ (0, child_process_1.exec)(`cd ${targetfolder};pnpm install --save next-auth@4.21.1 @darkwolf/base64url @nuxt/ui ajv dotenv @fullcalendar/core @fullcalendar/vue3 quill uuid ajv-formats primeflex primeicons prettier primevue axios json-schema mitt @simitgroup/simpleapp-vue-component@latest`, (error, stdout, stderr) => {
125
131
  console.log(error, stdout, stderr);
126
132
  fs_1.default.mkdirSync(`${targetfolder}/assets/css/`, { recursive: true });
127
133
  fs_1.default.mkdirSync(`${targetfolder}/layouts`, { recursive: true });
128
134
  fs_1.default.mkdirSync(`${targetfolder}/components`, { recursive: true });
129
135
  fs_1.default.mkdirSync(`${targetfolder}/server/api/[xorg]`, { recursive: true });
130
- fs_1.default.mkdirSync(`${targetfolder}/pages`, { recursive: true });
136
+ fs_1.default.mkdirSync(`${targetfolder}/server/api/auth`, { recursive: true });
137
+ fs_1.default.mkdirSync(`${targetfolder}/pages/[xorg]`, { recursive: true });
131
138
  fs_1.default.mkdirSync(`${targetfolder}/plugins`, { recursive: true });
132
139
  const eta = new eta_1.Eta({ views: `${constants.templatedir}/nuxt` });
133
- const variables = {
134
- backendPort: config.backendPort,
135
- frontendPort: config.frontendPort
136
- };
140
+ const variables = config;
137
141
  const writes = {
138
142
  './app.vue.eta': 'app.vue',
139
143
  './components.eventmonitor.vue.eta': 'components/EventMonitor.vue',
@@ -142,8 +146,12 @@ const prepareNuxt = (callback) => {
142
146
  './components.debugdocdata.vue.eta': 'components/DebugDocumentData.vue',
143
147
  './layouts.default.vue.eta': 'layouts/default.vue',
144
148
  './server.api.ts.eta': 'server/api/[xorg]/[...].ts',
149
+ './server.api.auth.logout.ts.eta': 'server/api/auth/logout.ts',
150
+ './server.api.auth[...].ts.eta': 'server/api/auth/[...].ts',
145
151
  './nuxt.config.ts.eta': 'nuxt.config.ts',
146
152
  './pages.index.vue.eta': 'pages/index.vue',
153
+ './pages.[xorg].index.vue.eta': 'pages/[xorg]/index.vue',
154
+ './pages.login.vue.eta': 'pages/login.vue',
147
155
  './plugins.simpleapp.ts.eta': 'plugins/simpleapp.ts',
148
156
  './tailwind.config.ts.eta': 'tailwind.config.ts',
149
157
  './tailwind.css.eta': 'assets/css/tailwind.css',
@@ -1 +1 @@
1
- {"version":3,"file":"framework.js","sourceRoot":"","sources":["../src/framework.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"framework.js","sourceRoot":"","sources":["../src/framework.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simitgroup/simpleapp-generator",
3
- "version": "1.0.24",
3
+ "version": "1.0.25",
4
4
  "description": "frontend nuxtjs and backend nests code generator using jsonschema",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
package/src/framework.ts CHANGED
@@ -13,6 +13,12 @@ let config = {
13
13
  "frontendFolder":"./myfrontend",
14
14
  "frontendPort":"8080",
15
15
  "openapi3Yaml":"../openapi.yaml",
16
+ "keycloaksetting":{
17
+ "OAUTH2_CONFIGURL":"https://keycloak-server-url/realms/realm-name",
18
+ "OAUTH2_CLIENTID":"client-id",
19
+ "OAUTH2_CLIENTSECRET":"client-secret-value",
20
+ "AUTH_SECRET_KEY":"my-secret",
21
+ }
16
22
  }
17
23
 
18
24
  export const setConfiguration=(paraconfig)=>{
@@ -53,20 +59,19 @@ export const prepareNest = (callback:Function)=>{
53
59
  if(!fs.existsSync(`${targetfolder}/.env`)){
54
60
 
55
61
 
56
- exec(`cd ${targetfolder};pnpm install --save axios @darkwolf/base64url json-schema @wearenova/mongoose-tenant @nestjs/swagger @nestjs/mongoose mongoose ajv ajv-formats @nestjs/config`,async (error, stdout, stderr)=>{
62
+ exec(`cd ${targetfolder};pnpm install --save @nestjs/serve-static axios @darkwolf/base64url json-schema @wearenova/mongoose-tenant @nestjs/swagger @nestjs/mongoose mongoose ajv ajv-formats @nestjs/config`,async (error, stdout, stderr)=>{
57
63
  // log.info(`dependency installed`)
58
64
  if(!error){
59
-
65
+ fs.mkdirSync(`${targetfolder}/public_html`,{recursive:true})
60
66
  const eta = new Eta({views: constants.templatedir});
61
- const variables={
62
- backendPort:config.backendPort,
63
- mongoConnectStr:config.mongoConnectStr
64
- }
67
+ const variables=config
65
68
  const txtEnv = eta.render('./nest/nest.env.eta', variables);
66
69
  const txtMain = eta.render('./nest/nest.main.eta', variables);
70
+ const txtRedirectHtml = eta.render('./nest/oauth2-redirect.eta', variables);
67
71
 
68
72
  fs.writeFileSync(`${targetfolder}/.env`, txtEnv);
69
73
  fs.writeFileSync(`${targetfolder}/src/main.ts`, txtMain);
74
+ fs.writeFileSync(`${targetfolder}/public_html/oauth2-redirect.html`, txtRedirectHtml);
70
75
  const tsconfigpath = process.cwd()+'/'+`${targetfolder}/tsconfig.json`
71
76
  const tsconfig = require(tsconfigpath)
72
77
  tsconfig.compilerOptions.esModuleInterop=true
@@ -91,23 +96,21 @@ export const prepareNuxt = (callback:Function)=>{
91
96
  const targetfolder = config.frontendFolder
92
97
  if(!fs.existsSync(`${targetfolder}/.env`)){
93
98
  //asume no environment. prepare now
94
- exec(`cd ${targetfolder};pnpm install;pnpm install -D @nuxt/ui @types/node @vueuse/nuxt @sidebase/nuxt-auth @vueuse/core nuxt-security prettier `, (error, stdout, stderr)=>{
99
+ exec(`cd ${targetfolder};pnpm install;pnpm install -D @sidebase/nuxt-auth @nuxt/ui @types/node @vueuse/nuxt @sidebase/nuxt-auth @vueuse/core nuxt-security prettier `, (error, stdout, stderr)=>{
95
100
  //;pnpm install
96
101
  console.log(error, stdout, stderr)
97
- exec(`cd ${targetfolder};pnpm install --save @darkwolf/base64url @nuxt/ui ajv dotenv @fullcalendar/core @fullcalendar/vue3 quill uuid ajv-formats primeflex primeicons prettier primevue axios json-schema mitt @simitgroup/simpleapp-vue-component@latest`, (error, stdout, stderr)=>{
102
+ exec(`cd ${targetfolder};pnpm install --save next-auth@4.21.1 @darkwolf/base64url @nuxt/ui ajv dotenv @fullcalendar/core @fullcalendar/vue3 quill uuid ajv-formats primeflex primeicons prettier primevue axios json-schema mitt @simitgroup/simpleapp-vue-component@latest`, (error, stdout, stderr)=>{
98
103
  console.log(error, stdout, stderr)
99
104
 
100
105
  fs.mkdirSync(`${targetfolder}/assets/css/`,{recursive:true})
101
106
  fs.mkdirSync(`${targetfolder}/layouts`,{recursive:true})
102
107
  fs.mkdirSync(`${targetfolder}/components`,{recursive:true})
103
108
  fs.mkdirSync(`${targetfolder}/server/api/[xorg]`,{recursive:true})
104
- fs.mkdirSync(`${targetfolder}/pages`,{recursive:true})
109
+ fs.mkdirSync(`${targetfolder}/server/api/auth`,{recursive:true})
110
+ fs.mkdirSync(`${targetfolder}/pages/[xorg]`,{recursive:true})
105
111
  fs.mkdirSync(`${targetfolder}/plugins`,{recursive:true})
106
112
  const eta = new Eta({views: `${constants.templatedir}/nuxt`});
107
- const variables={
108
- backendPort:config.backendPort,
109
- frontendPort:config.frontendPort
110
- }
113
+ const variables=config
111
114
  const writes = {
112
115
  './app.vue.eta':'app.vue',
113
116
  './components.eventmonitor.vue.eta':'components/EventMonitor.vue',
@@ -116,11 +119,15 @@ export const prepareNuxt = (callback:Function)=>{
116
119
  './components.debugdocdata.vue.eta':'components/DebugDocumentData.vue',
117
120
  './layouts.default.vue.eta':'layouts/default.vue',
118
121
  './server.api.ts.eta':'server/api/[xorg]/[...].ts',
122
+ './server.api.auth.logout.ts.eta':'server/api/auth/logout.ts',
123
+ './server.api.auth[...].ts.eta':'server/api/auth/[...].ts',
119
124
  './nuxt.config.ts.eta':'nuxt.config.ts',
120
125
  './pages.index.vue.eta':'pages/index.vue',
126
+ './pages.[xorg].index.vue.eta':'pages/[xorg]/index.vue',
127
+ './pages.login.vue.eta':'pages/login.vue',
121
128
  './plugins.simpleapp.ts.eta':'plugins/simpleapp.ts',
122
129
  './tailwind.config.ts.eta':'tailwind.config.ts',
123
- './tailwind.css.eta':'assets/css/tailwind.css',
130
+ './tailwind.css.eta':'assets/css/tailwind.css',
124
131
  './env.eta':'.env',
125
132
  }
126
133
 
@@ -23,9 +23,10 @@ const schemasetting = {
23
23
  <% }else if( schema[key].type == 'array'){%>
24
24
  <%= key %>: [{type: <%= schema[key].item.type %>, required:false}] //basic array
25
25
  <% }else{%>
26
- <%= key %>: {type: <%= capitalizeFirstLetter(schema[key].type) %>, required:false}, //field
26
+ <%= key %>: {type: <%= capitalizeFirstLetter(schema[key].type) %>, required: <% if(key==it.autocompletecode || key==it.autocompletename){%>true<%}else{%>false<%}%>}, //field
27
27
  <% } %>
28
28
  <%}) %>
29
29
  };
30
30
 
31
31
  export const <%= it.doctype %>MongoSchema = new Schema(schemasetting,{collection: '<%= it.name %>'})
32
+ .index({<%=it.autocompletecode%>:1,orgId:1},{unique:true});
@@ -1,30 +1,39 @@
1
-
2
- import { Injectable, NestMiddleware,Scope } from '@nestjs/common';
1
+ import { Injectable, NestMiddleware, Scope } from '@nestjs/common';
3
2
  import { Request, Response, NextFunction } from 'express';
4
- import {User} from './User'
3
+ // import * as jwt from 'nestjs-jwt'
4
+
5
5
 
6
+ import { User } from './User';
7
+ // import {KeycloakConfigService} from "../keycloak/keycloak.service"
6
8
  @Injectable({
7
- scope: Scope.REQUEST
9
+ scope: Scope.REQUEST,
8
10
  })
11
+
9
12
  export class TenantMiddleware implements NestMiddleware {
10
13
  use(req: Request, res: Response, next: NextFunction) {
11
- req.headers['x-org']
12
- if(req.headers['x-org']){
13
- const u = User.getInstance()
14
- try{
15
- u.setXorg(req.headers['x-org'].toString())
16
- u.setUser('user1')
17
- //console.log(u.getInfo())
18
- // u.uid='user1'
19
- next();
20
- }catch{
21
- return res.status(401).send("Invalid x-org or user info")
22
- }
23
-
24
- }else{
25
- return res.status(401).send("undefine header string x-org")
14
+ if (req.baseUrl == '/oauth2-redirect.html') {
15
+ next();
16
+ return ;
17
+ }
18
+ if(!req.headers['authorization']){
19
+ return res.status(401).send('Undefine bearer token');
20
+ }
21
+ if (!req.headers['x-org']){
22
+ return res.status(401).send('undefine header string x-org');
23
+ }
24
+ const u = User.getInstance();
26
25
 
26
+ try {
27
+ u.setXorg(req.headers['x-org'].toString());
28
+ let tokenstr:string = req.headers['authorization']
29
+ tokenstr = tokenstr.replace("Bearer ",'')
30
+ u.setUserToken(tokenstr);
31
+ next();
32
+ } catch {
33
+ return res.status(401).send('Invalid x-org or user info');
27
34
  }
35
+
36
+
28
37
 
29
38
  }
30
39
  }
@@ -1,80 +1,115 @@
1
1
  import { Injectable, Scope } from '@nestjs/common';
2
- import Base64URL from '@darkwolf/base64url'
2
+ import Base64URL from '@darkwolf/base64url';
3
+ import * as jwt from 'jsonwebtoken'
4
+
5
+
6
+
7
+
3
8
 
4
9
  @Injectable({
5
- scope: Scope.REQUEST
10
+ scope: Scope.REQUEST,
6
11
  })
7
12
  export class User {
8
- private static instance: User;
9
- protected uid:string=''
10
- protected uname:string=''
11
- protected email:string=''
12
- protected xOrg:string=''
13
- protected tenantId:number=0
14
- protected orgId:number=0
15
- protected branchId:number=0
16
- constructor() {}
17
- public static getInstance(): User {
18
- if (!User.instance) {
19
- User.instance = new User();
20
- }
21
- return User.instance;
22
- }
23
- setUser = (uid:string)=>{
24
- User.getInstance().uid=uid
25
- }
26
- getInfo=()=>{
27
- return User.getInstance()
28
- }
29
- getBranchFilter=()=>{
30
- return {
31
- tenantId:User.getInstance().tenantId,
32
- orgId: User.getInstance().orgId,
33
- branchId:User.getInstance().branchId
34
- }
35
- }
36
- getTenantFilter=()=>{
37
- return {tenantId:User.getInstance().tenantId}
38
- }
39
- getOrgFilter=()=>{
40
- return {tenantId:User.getInstance().tenantId,orgId: User.getInstance().orgId}
13
+ private static instance: User;
14
+ protected uid: string = '';
15
+ protected uname: string = '';
16
+ protected email: string = '';
17
+ protected fullname:string=''
18
+ protected xOrg: string = '';
19
+ protected tenantId: number = 0;
20
+ protected orgId: number = 0;
21
+ protected branchId: number = 0;
22
+ protected accessrights:any = {}
23
+ protected token:string = ''
24
+ protected refreshtoken:string = ''
25
+ constructor() {}
26
+ public static getInstance(): User {
27
+ if (!User.instance) {
28
+ User.instance = new User();
41
29
  }
30
+ return User.instance;
31
+ }
32
+ setUserToken = (tokenstr: string) => {
33
+ const tokeninfo = jwt.decode(tokenstr)
34
+ // realm_access: {
35
+ // roles: [
36
+ // 'default-roles-simitdeveloper',
37
+ // 'offline_access',
38
+ // 'uma_authorization'
39
+ // ]
40
+ // },
41
+ // resource_access: { account: { roles: [Array] } },
42
+ // scope: 'openid email profile',
43
+ // sid: '53192f53-d4af-413b-b8d7-1e186419fe53',
44
+ // email_verified: false,
45
+ // name: 'kstan kstan',
46
+ // preferred_username: 'kstan',
47
+ // given_name: 'kstan',
48
+ // family_name: 'kstan',
49
+ // email: 'kstan@simitgroup.com'
50
+
51
+ const u = User.getInstance()
52
+ u.token = tokenstr
53
+ u.uid = tokeninfo.sid;
54
+ u.email = tokeninfo.email
55
+ u.uname = tokeninfo.preferred_username
56
+ u.fullname = tokeninfo.name
57
+ u.accessrights = tokeninfo.resource_access
58
+ };
59
+ getInfo = () => {
60
+ return User.getInstance();
61
+ };
62
+ getBranchFilter = () => {
63
+ return {
64
+ tenantId: User.getInstance().tenantId,
65
+ orgId: User.getInstance().orgId,
66
+ branchId: User.getInstance().branchId,
67
+ };
68
+ };
69
+ getTenantFilter = () => {
70
+ return { tenantId: User.getInstance().tenantId };
71
+ };
72
+ getOrgFilter = () => {
73
+ return {
74
+ tenantId: User.getInstance().tenantId,
75
+ orgId: User.getInstance().orgId,
76
+ };
77
+ };
42
78
 
43
- getCreateFilter=()=>{
44
- const u = User.getInstance()
45
- return {
46
- tenantId:u.tenantId,
47
- orgId: u.orgId,
48
- branchId:u.branchId,
49
- createdby: u.uid,
50
- updatedby: u.uid,
51
- created: new Date().getTime().toString(),
52
- updated: new Date().getTime().toString()
53
- }
54
- }
55
- getUpdateFilter=()=>{
56
- const u = User.getInstance()
57
- return {
58
- updatedby: u.uid,
59
- updated: new Date().getTime().toString()
60
- }
61
- }
62
- setXorg = (xorg)=>{
63
- try{
64
- const decodedText:string = Base64URL.decodeText(xorg)
65
- const arrXorg = decodedText.split('-')
66
-
67
- if(arrXorg.length==3){
68
- const u = User.getInstance()
69
- u.tenantId = Number(arrXorg[0])
70
- u.orgId = Number(arrXorg[1])
71
- u.branchId = Number(arrXorg[2])
72
- }else{
73
- throw "invalid x-org"
74
- }
75
- }catch(err){
76
- throw err
77
- }
78
-
79
+ getCreateFilter = () => {
80
+ const u = User.getInstance();
81
+ return {
82
+ tenantId: u.tenantId,
83
+ orgId: u.orgId,
84
+ branchId: u.branchId,
85
+ createdby: u.uid,
86
+ updatedby: u.uid,
87
+ created: new Date().getTime().toString(),
88
+ updated: new Date().getTime().toString(),
89
+ };
90
+ };
91
+ getUpdateFilter = () => {
92
+ const u = User.getInstance();
93
+ return {
94
+ updatedby: u.uid,
95
+ updated: new Date().getTime().toString(),
96
+ };
97
+ };
98
+ setXorg = (xorg) => {
99
+ try {
100
+ const decodedText: string = Base64URL.decodeText(xorg);
101
+ const arrXorg = decodedText.split('-');
102
+
103
+ if (arrXorg.length == 3) {
104
+ const u = User.getInstance();
105
+ u.tenantId = Number(arrXorg[0]);
106
+ u.orgId = Number(arrXorg[1]);
107
+ u.branchId = Number(arrXorg[2]);
108
+ } else {
109
+ throw 'invalid x-org';
110
+ }
111
+ } catch (err) {
112
+ throw err;
79
113
  }
114
+ };
80
115
  }
@@ -1,6 +1,8 @@
1
1
  import { Module,MiddlewareConsumer,NestModule } from '@nestjs/common';
2
2
  import { MongooseModule } from '@nestjs/mongoose';
3
3
  import { ConfigModule } from '@nestjs/config';
4
+ import { ServeStaticModule } from '@nestjs/serve-static';
5
+ import { join } from 'path';
4
6
  import {TenantMiddleware} from './class/TenantMiddleware'
5
7
  <% for(let i=0;i<it.length; i++){ %>
6
8
  import {<%= it[i].docname %>Module} from './docs/<%= it[i].doctype %>/<%= it[i].doctype %>.module'
@@ -8,7 +10,14 @@ import {<%= it[i].docname %>Module} from './docs/<%= it[i].doctype %>/<%= it[i].
8
10
 
9
11
  @Module({
10
12
  //define environment variables: MONGODB_URL='mongodb://<user>:<pass>@<host>:<port>/<db>?authMechanism=DEFAULT'
11
- imports: [ConfigModule.forRoot(),MongooseModule.forRoot(process.env.MONGODB_URL),<% for(let i=0;i<it.length; i++){ %><%= it[i].docname %>Module,<%}%>],
13
+ imports: [
14
+ ConfigModule.forRoot(),
15
+ MongooseModule.forRoot(process.env.MONGODB_URL),
16
+ ServeStaticModule.forRoot({
17
+ rootPath: join(__dirname, '..', 'public_html'),
18
+ exclude: ['/api/(.*)'],
19
+ }),
20
+ <% for(let i=0;i<it.length; i++){ %><%= it[i].docname %>Module,<%}%>],
12
21
  controllers: [],
13
22
  providers: [],
14
23
  })
@@ -4,4 +4,15 @@ HTTP_PORT=<%=it.backendPort%>
4
4
 
5
5
  PROJECT_NAME=SimpleApp Demo1
6
6
  PROJECT_DESCRIPTION=Try CRUD
7
- PROJECT_Version=1.0.0
7
+ PROJECT_Version=1.0.0
8
+
9
+
10
+ OAUTH2_CONFIGURL=<%=it.keycloaksetting.OAUTH2_CONFIGURL%>
11
+
12
+ OAUTH2_CLIENTID=<%=it.keycloaksetting.OAUTH2_CLIENTID%>
13
+
14
+ OAUTH2_CLIENTSECRET=<%=it.keycloaksetting.OAUTH2_CLIENTSECRET%>
15
+
16
+ AUTH_SECRET_KEY=<%=it.keycloaksetting.AUTH_SECRET_KEY%>
17
+
18
+ AUTH_ORIGIN=http://localhost:8080
@@ -9,14 +9,23 @@ async function bootstrap() {
9
9
  .setTitle(process.env.PROJECT_NAME)
10
10
  .setDescription(process.env.PROJECT_DESCRIPTION)
11
11
  .setVersion(process.env.PROJECT_VERSION)
12
- .addApiKey({in:'header',name:'x-org',type:'apiKey',description:'base 64 url encode. example: MS0xLTE'},'x-org')
12
+ .addApiKey({
13
+ in: 'header',name: 'x-org',type: 'apiKey',description: 'base 64 url encode. example: MS0xLTE',
14
+ },'x-org',)
15
+ .addOAuth2({
16
+ name:'oauth2',in:'header',type:'oauth2',flows:{
17
+ implicit:{
18
+ authorizationUrl: `${process.env.OAUTH2_CONFIGURL}/protocol/openid-connect/auth`,
19
+ scopes:[],
20
+ }}},'oauth2')
13
21
  .addSecurityRequirements('x-org')
22
+ .addSecurityRequirements('oauth2')
14
23
  .build();
15
24
  const document = SwaggerModule.createDocument(app, config);
16
25
  SwaggerModule.setup('api', app, document, {
17
- swaggerOptions: { showExtensions: true },
26
+ swaggerOptions: { showExtensions: true, persistAuthorization: true },
18
27
  });
19
28
 
20
- await app.listen(process.env.HTTP_PORT ?? <%=it.backendPort%>); //listen which port
29
+ await app.listen(process.env.HTTP_PORT ?? 8000); //listen which port
21
30
  }
22
- bootstrap();
31
+ bootstrap();
@@ -0,0 +1,79 @@
1
+ <!doctype html>
2
+ <html lang="en-US">
3
+ <head>
4
+ <title>Swagger UI: OAuth2 Redirect</title>
5
+ </head>
6
+ <body>
7
+ <script>
8
+ 'use strict';
9
+ function run () {
10
+ var oauth2 = window.opener.swaggerUIRedirectOauth2;
11
+ var sentState = oauth2.state;
12
+ var redirectUrl = oauth2.redirectUrl;
13
+ var isValid, qp, arr;
14
+
15
+ if (/code|token|error/.test(window.location.hash)) {
16
+ qp = window.location.hash.substring(1).replace('?', '&');
17
+ } else {
18
+ qp = location.search.substring(1);
19
+ }
20
+
21
+ arr = qp.split("&");
22
+ arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';});
23
+ qp = qp ? JSON.parse('{' + arr.join() + '}',
24
+ function (key, value) {
25
+ return key === "" ? value : decodeURIComponent(value);
26
+ }
27
+ ) : {};
28
+
29
+ isValid = qp.state === sentState;
30
+
31
+ if ((
32
+ oauth2.auth.schema.get("flow") === "accessCode" ||
33
+ oauth2.auth.schema.get("flow") === "authorizationCode" ||
34
+ oauth2.auth.schema.get("flow") === "authorization_code"
35
+ ) && !oauth2.auth.code) {
36
+ if (!isValid) {
37
+ oauth2.errCb({
38
+ authId: oauth2.auth.name,
39
+ source: "auth",
40
+ level: "warning",
41
+ message: "Authorization may be unsafe, passed state was changed in server. The passed state wasn't returned from auth server."
42
+ });
43
+ }
44
+
45
+ if (qp.code) {
46
+ delete oauth2.state;
47
+ oauth2.auth.code = qp.code;
48
+ oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl});
49
+ } else {
50
+ let oauthErrorMsg;
51
+ if (qp.error) {
52
+ oauthErrorMsg = "["+qp.error+"]: " +
53
+ (qp.error_description ? qp.error_description+ ". " : "no accessCode received from the server. ") +
54
+ (qp.error_uri ? "More info: "+qp.error_uri : "");
55
+ }
56
+
57
+ oauth2.errCb({
58
+ authId: oauth2.auth.name,
59
+ source: "auth",
60
+ level: "error",
61
+ message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server."
62
+ });
63
+ }
64
+ } else {
65
+ oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid, redirectUrl: redirectUrl});
66
+ }
67
+ window.close();
68
+ }
69
+
70
+ if (document.readyState !== 'loading') {
71
+ run();
72
+ } else {
73
+ document.addEventListener('DOMContentLoaded', function () {
74
+ run();
75
+ });
76
+ }
77
+ </script>
78
+ </body>
79
+ </html>
@@ -47,7 +47,6 @@ const newData = () => {
47
47
 
48
48
  const triggerEdit = (event: any) => {
49
49
  let id = event.data._id.toString()
50
- editRecord(event.data._id);
51
50
  router.push({ path: `${props.path}/${id}` })
52
51
  };
53
52
  const editRecord = (id:string) => {
@@ -95,7 +94,7 @@ refresh();
95
94
  <button class="bg-primary" @click="newData" v-tooltip="'Add new(ctrl+i)'" >New</button>
96
95
  <SimpleAppDatatable
97
96
  @row-dblclick="triggerEdit"
98
- v-model="recordlist"
97
+ v-model="recordlist"
99
98
  :setting="{}"
100
99
  :columns="listColumns"
101
100
  >
@@ -6,18 +6,23 @@
6
6
  */
7
7
 
8
8
  import * as o from "../simpleapp/openapi";
9
-
9
+ import axios from 'axios'
10
10
  const getAutoComplete = (apiname: string): any => {
11
+ const { csrf } = useCsrf()
12
+ axios.defaults.headers.common = {"CSRF-TOKEN": csrf};
13
+ const route = useRoute();
14
+
11
15
  const config: o.Configuration = {
12
- basePath: useRuntimeConfig().public.APP_URL + "/api",
16
+ basePath: `${useRuntimeConfig().public.APP_URL}/api/${route.params.xorg}`,
13
17
  isJsonMime: () => true,
14
18
  };
15
19
  const docsOpenapi: any = {
16
- <% for(let i=0;i<it.length; i++){ %>
17
- <% let obj = it[i]%>
18
- '<%=obj.docname.toLowerCase()%>' : new o.<%=obj.doctype.toUpperCase()%>Api(config),
19
- <%}%>
20
- };
20
+ 'category' : new o.CATApi(config),
21
+ 'leadtype' : new o.LEADTApi(config),
22
+ 'level' : new o.LVLApi(config),
23
+ 'product' : new o.PRDApi(config),
24
+ 'studentgroup' : new o.STGApi(config),
25
+ };
21
26
  if (!docsOpenapi[apiname]) {
22
27
  console.error(
23
28
  `api for '${apiname}' does not exists, most probably define wrong x-foreignkey`,
@@ -4,13 +4,24 @@
4
4
  * last change 2023-09-10
5
5
  * author: Ks Tan
6
6
  */
7
-
8
- export const getMenus =(xorg:string)=>[
9
- {label: 'Cruds',icon: 'pi pi-fw pi-pencil',items:[
10
- <% for(let i=0;i<it.length; i++){ %>
11
- <% let obj = it[i]%>
12
- {label: '<%=obj.docname.toLowerCase()%>', to:`/${xorg}/<%=obj.docname.toLowerCase()%>`},
13
- <%}%>
14
- ]},
15
- {label: 'Profile',icon: 'pi pi-fw pi-user'},
16
- ]
7
+
8
+ export const getMenus =()=>{
9
+
10
+ const route = useRoute();
11
+ const xorg = route.params.xorg
12
+ let data =[];
13
+ if(xorg){
14
+ data =[
15
+ {label: 'Home',icon: 'pi pi-fw pi-home', url:'/'},
16
+ {label: 'Cruds',icon: 'pi pi-fw pi-pencil',items:[
17
+ <% for(let i=0;i<it.length; i++){ %>
18
+ <% let obj = it[i]%>
19
+ {label: '<%=obj.docname.toLowerCase()%>', to:`/${xorg}/<%=obj.docname.toLowerCase()%>`},
20
+ <%}%>
21
+ ]},
22
+ ]
23
+ }else{
24
+ data= [{label: 'Home',icon: 'pi pi-fw pi-home', url:'/'},]
25
+ }
26
+ return data
27
+ }
@@ -4,4 +4,14 @@ SIMPLEAPP_BACKEND_URL=http://localhost:<%=it.backendPort%>
4
4
 
5
5
  APP_URL=http://localhost:<%=it.frontendPort%>
6
6
 
7
- DEBUGDATA=1
7
+ DEBUGDATA=1
8
+
9
+ OAUTH2_CONFIGURL=<%=it.keycloaksetting.OAUTH2_CONFIGURL%>
10
+
11
+ OAUTH2_CLIENTID=<%=it.keycloaksetting.OAUTH2_CLIENTID%>
12
+
13
+ OAUTH2_CLIENTSECRET=<%=it.keycloaksetting.OAUTH2_CLIENTSECRET%>
14
+
15
+ AUTH_SECRET_KEY=<%=it.keycloaksetting.AUTH_SECRET_KEY%>
16
+
17
+ AUTH_ORIGIN=http://localhost:<%=it.frontendPort%>
@@ -19,19 +19,19 @@ tailwindcss: {
19
19
  // Options
20
20
  },
21
21
  modules: [
22
- // '@sidebase/nuxt-auth',
23
- "nuxt-security",
24
-
22
+ '@sidebase/nuxt-auth',
23
+ "nuxt-security",
25
24
  '@vueuse/nuxt',
26
25
  '@nuxt/ui'
27
- //'@nuxtjs/tailwindcss', //use @nuxt/ui own tailwind
28
- // '@nuxtjs/color-mode'
29
-
30
26
  ],
31
- ssr: true,
27
+ auth: {
28
+ globalAppMiddleware: true
29
+ },
32
30
  security: {
33
31
  csrf: true,
34
32
  },
33
+ ssr: true,
34
+
35
35
  css: [
36
36
  "primevue/resources/themes/lara-light-blue/theme.css",
37
37
  'primeicons/primeicons.css'
@@ -41,5 +41,6 @@ tailwindcss: {
41
41
  transpile: ["primevue"]
42
42
  },
43
43
 
44
+
44
45
 
45
46
  })
@@ -0,0 +1,19 @@
1
+ <script lang="ts" setup>
2
+ /**
3
+ * This file was automatically generated by simpleapp generator during initialization.
4
+ * You may modify it for your need
5
+ * last change 2023-09-09
6
+ * author: Ks Tan
7
+ */
8
+ </script>
9
+ <template>
10
+ <div>
11
+ <h1>index page</h1>
12
+ <ul>
13
+ <li><NuxtLink :external="true" to="/MS0xLTE" >MS0xLTE (1-1-1)</NuxtLink></li>
14
+ <li><NuxtLink :external="true" to="/Mi0yLTI" >Mi0yLTI (2-2-2)</NuxtLink></li>
15
+ </ul>
16
+
17
+ </div>
18
+
19
+ </template>
@@ -7,5 +7,13 @@
7
7
  */
8
8
  </script>
9
9
  <template>
10
- <div>index page</div>
10
+ <div>
11
+ <h1>index page</h1>
12
+ <ul>
13
+ <li><NuxtLink :external="true" to="/MS0xLTE" >MS0xLTE (1-1-1)</NuxtLink></li>
14
+ <li><NuxtLink :external="true" to="/Mi0yLTI" >Mi0yLTI (2-2-2)</NuxtLink></li>
15
+ </ul>
16
+
17
+ </div>
18
+
11
19
  </template>
@@ -0,0 +1,20 @@
1
+ <template>
2
+ <NuxtPage />
3
+ </template>
4
+ <script setup lang="ts">
5
+ definePageMeta({
6
+ name: 'Login',
7
+ auth: false,
8
+ })
9
+
10
+ // const route = useRoute();
11
+ const { signIn } = useAuth()
12
+ onMounted(async () => {
13
+ let callbackUrl = '/';
14
+ // if(route.params.redirect) {
15
+ // callbackUrl = <string>route.params.redirect;
16
+ // }
17
+ await signIn('keycloak', { callbackUrl: callbackUrl })
18
+ })
19
+
20
+ </script>
@@ -40,9 +40,8 @@ const emitter = mitt()
40
40
 
41
41
 
42
42
  export default defineNuxtPlugin((nuxtApp) => {
43
- const { csrf } = useCsrf()
44
- axios.defaults.headers.common = {"CSRF-TOKEN": csrf};
45
-
43
+ const { csrf } = useCsrf()
44
+ axios.defaults.headers.common = {"CSRF-TOKEN": csrf};
46
45
  nuxtApp.vueApp.use(PrimeVue, { ripple: true });
47
46
  nuxtApp.vueApp
48
47
  .component("SimpleAppAutocomplete",SimpleAppAutocomplete)
@@ -0,0 +1,12 @@
1
+ // give keycloak for
2
+ export default defineEventHandler(async (event) => {
3
+ const path = `${
4
+ process.env.OAUTH2_CONFIGURL
5
+ }/protocol/openid-connect/logout?redirect_uri=${encodeURIComponent(
6
+ process.env.AUTH_ORIGIN ?? ""
7
+ )}`;
8
+
9
+ return {
10
+ path: path
11
+ }
12
+ });
@@ -0,0 +1,144 @@
1
+ /**
2
+ * This file was automatically generated by simpleapp generator during initialization.
3
+ * DO NOT MODIFY IT BY HAND.
4
+ * last change 2023-09-09
5
+ * author: Ks Tan
6
+ */
7
+
8
+
9
+ import axios from 'axios';
10
+ import { getServerSession } from '#auth'
11
+ import type { Session } from 'next-auth';
12
+
13
+ export default defineEventHandler(async (event) => {
14
+ let session:any=null
15
+ // console.log('---------hihi---------')
16
+
17
+ try {
18
+ session = await getServerSession(event)
19
+
20
+ } catch (error) {
21
+ return sendRedirect(event, '/login', 401)
22
+ }
23
+ // console.log(session)
24
+ return new Promise<any>(async (resolve, reject) => {
25
+ if(!session) {
26
+ //if(!session || !session.accessToken) {
27
+ reject({ statusMessage: 'Unauthorized', statusCode: 401 });
28
+ throw createError({ statusMessage: 'Unauthorized', statusCode: 401 })
29
+ }
30
+ // console.log("------hihi------")
31
+ const seperateSymbol = '.';
32
+ // const seperateSymbol = '&';
33
+ const xOrg = event.context.params?.xorg ?? ''
34
+ const documentLink = event.context.params?._ ?? ''
35
+ // const platform = event.context.params?.platform ?? ''
36
+
37
+
38
+ // console.error("event.context???",event.context)
39
+ const accessToken = session?.accessToken;
40
+
41
+ // const allowPlatform = ['report-api', 'cloudapi'];
42
+ // if(!key || !platform || !allowPlatform.includes(platform) || !accessToken) {
43
+ // reject({ statusMessage: 'Unauthorized', statusCode: 401 });
44
+ // // throw createError({ statusMessage: 'Unauthorized', statusCode: 401 })
45
+ // }
46
+
47
+ // let tenantKey = '', organizationKey = '';
48
+ // let xOrg = '';
49
+
50
+ // if(key !== 'system') {
51
+ // [tenantKey, organizationKey] = key.split(seperateSymbol);
52
+ // xOrg = `${tenantKey}/${organizationKey}/`;
53
+ // }
54
+
55
+ // if(key === 'system' && platform == 'cloudapi') {
56
+ // // xOrg = 'MC0wLTA'
57
+ // }
58
+
59
+ let forwardData: any = {};
60
+
61
+ const req = event.node.req;
62
+
63
+ if(req.method == 'POST' || req.method == 'PUT') {
64
+
65
+ forwardData = await readBody(event);
66
+ } else {
67
+ forwardData = getQuery(event);
68
+ }
69
+
70
+ // if(typeof forwardData === "object" && "_branch" in forwardData) {
71
+ // xOrg = xOrg + forwardData._branch;
72
+ // delete forwardData._branch;
73
+ // }
74
+
75
+ const frontEndRes = event.node.res;
76
+ const url = process.env.SIMPLEAPP_BACKEND_URL + '/' + documentLink;
77
+ // console.warn('backend server-----',url,'xorg',xOrg,'documentLink',documentLink)
78
+ const axiosConfig: any = {
79
+ method: req.method,
80
+ url: url,
81
+ headers: {
82
+ Authorization: `Bearer ${accessToken}`,
83
+ 'X-Org': xOrg,
84
+ },
85
+ data: forwardData,
86
+ params: forwardData,
87
+ }
88
+
89
+ // if(key === 'system') {
90
+ // axiosConfig.headers["X-Global"] = true;
91
+ // delete axiosConfig.headers["X-Org"];
92
+ // }
93
+
94
+ // if(otherLink.includes('avatar')) {
95
+ // axiosConfig.responseType = 'arraybuffer';
96
+ // // axiosConfig.headers['Acceptable'] = 'text/html,image/avif,image/webp,image/apng';
97
+ // }
98
+
99
+ axios(axiosConfig).then((res) => {
100
+ if (res.headers['content-type'] === 'image/png') {
101
+ // Set the response headers for the image
102
+ frontEndRes.setHeader('Content-Type', 'image/png');
103
+ frontEndRes.setHeader('Content-Disposition', 'inline');
104
+
105
+ // Send the image data as the response body
106
+ frontEndRes.end(Buffer.from(res.data, 'binary'));
107
+ } else {
108
+ // For non-image responses, set the Content-Type header and send the response body
109
+ // setHeader(event, 'Content-type', <string>res.headers['Content-Type']);
110
+
111
+ frontEndRes.statusCode = res.status;
112
+ if(res.statusText) {
113
+ frontEndRes.statusMessage = res.statusText;
114
+ }
115
+
116
+ resolve(res.data);
117
+ }
118
+
119
+ }).catch((error) => {
120
+ // console.log("==============================================================")
121
+ // console.log('@@@@@@@@@@@@@ API error', error)
122
+ // console.log("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@")
123
+ // console.log('######### response', error.response)
124
+ // console.log('#####################################')
125
+ // console.log(axiosConfig);
126
+ // console.log('#####################################')
127
+
128
+ if (error.response?.status && error.response.status == '401') {
129
+ return reject({ statusMessage: 'Unauthorized', statusCode: 401 });
130
+ // throw createError({ statusMessage: 'Unauthorized', statusCode: 401 })
131
+ }
132
+
133
+ // reject(error.data)
134
+ reject({ statusMessage: error.response.statusText, statusCode: error.response.status });
135
+ // resolve({ status: 'ok' })
136
+ // throw createError({ statusMessage: 'Bad Requests', statusCode: 404 })
137
+ })
138
+
139
+ // resolve({
140
+ // status: 'ok'
141
+ // })
142
+ })
143
+
144
+ })
@@ -7,22 +7,27 @@
7
7
 
8
8
 
9
9
  import axios from 'axios';
10
- // import { getServerSession } from '#auth'
11
- // import type { Session } from 'next-auth';
10
+ import { getServerSession } from '#auth'
11
+ import type { Session } from 'next-auth';
12
12
 
13
13
  export default defineEventHandler(async (event) => {
14
- // let session: Session | null = null
15
- // try {
16
- // session = await getServerSession(event)
17
- // } catch (error) {
18
- // return sendRedirect(event, '/login', 401)
19
- // }
14
+ type additionalprops = {accessToken?:string}
15
+ let session:any=null
16
+
17
+
18
+ try {
19
+ session = await getServerSession(event)
20
+
21
+ } catch (error) {
22
+ return sendRedirect(event, '/login', 401)
23
+ }
20
24
 
21
25
  return new Promise<any>(async (resolve, reject) => {
22
- // if(!session || !session.accessToken) {
23
- // reject({ statusMessage: 'Unauthorized', statusCode: 401 });
24
- // throw createError({ statusMessage: 'Unauthorized', statusCode: 401 })
25
- // }
26
+ if(!session) {
27
+ //if(!session || !session.accessToken) {
28
+ reject({ statusMessage: 'Unauthorized', statusCode: 401 });
29
+ throw createError({ statusMessage: 'Unauthorized', statusCode: 401 })
30
+ }
26
31
  // console.log("------hihi------")
27
32
  const seperateSymbol = '.';
28
33
  // const seperateSymbol = '&';
@@ -32,7 +37,7 @@ export default defineEventHandler(async (event) => {
32
37
 
33
38
 
34
39
  // console.error("event.context???",event.context)
35
- // const accessToken = session?.accessToken;
40
+ const accessToken = session?.accessToken;
36
41
 
37
42
  // const allowPlatform = ['report-api', 'cloudapi'];
38
43
  // if(!key || !platform || !allowPlatform.includes(platform) || !accessToken) {
@@ -75,7 +80,7 @@ export default defineEventHandler(async (event) => {
75
80
  method: req.method,
76
81
  url: url,
77
82
  headers: {
78
- // Authorization: `Bearer ${accessToken}`,
83
+ Authorization: `Bearer ${accessToken}`,
79
84
  'X-Org': xOrg,
80
85
  },
81
86
  data: forwardData,