w-web-api 1.0.27 → 1.0.29

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 (42) hide show
  1. package/README.md +23 -16
  2. package/dist/css/app.d38a4241.css +1 -0
  3. package/dist/index.tmp +1 -1
  4. package/dist/js/app-legacy.86198344.js +2 -0
  5. package/dist/js/app-legacy.86198344.js.map +1 -0
  6. package/dist/js/app.86198344.js +2 -0
  7. package/dist/js/app.86198344.js.map +1 -0
  8. package/dist/js/chunk-vendors-legacy.c0c4267e.js +14 -0
  9. package/dist/js/chunk-vendors-legacy.c0c4267e.js.map +1 -0
  10. package/dist/js/chunk-vendors.c0c4267e.js +14 -0
  11. package/dist/js/chunk-vendors.c0c4267e.js.map +1 -0
  12. package/dist/w-web-api.umd.js +2 -2
  13. package/dist/w-web-api.umd.js.map +1 -1
  14. package/docs/WWebApi.html +4 -4
  15. package/docs/WWebApi.mjs.html +167 -64
  16. package/docs/index.html +1 -1
  17. package/{g.mDb.mjs → g.backupDb.mjs} +1 -1
  18. package/{g.mInitialTestData.mjs → g.initialTestData.mjs} +1 -1
  19. package/package.json +5 -10
  20. package/public/index.html +1 -1
  21. package/server/WWebApi.mjs +166 -63
  22. package/server/provideApis.mjs +2 -2
  23. package/src/App.vue +1 -8
  24. package/src/components/Layout.vue +2 -2
  25. package/src/components/LayoutContent.vue +634 -25
  26. package/src/main.js +0 -2
  27. package/src/store/mutations.mjs +13 -0
  28. package/srv.mjs +21 -12
  29. package/tableTags-web-api.json +1 -1
  30. package/vue.config.js +1 -1
  31. package/dist/css/app.e645631b.css +0 -1
  32. package/dist/css/chunk-vendors.ca61ed63.css +0 -5
  33. package/dist/js/app-legacy.4bcebb66.js +0 -2
  34. package/dist/js/app-legacy.4bcebb66.js.map +0 -1
  35. package/dist/js/app.8115e31a.js +0 -2
  36. package/dist/js/app.8115e31a.js.map +0 -1
  37. package/dist/js/chunk-vendors-legacy.0b4288c4.js +0 -14
  38. package/dist/js/chunk-vendors-legacy.0b4288c4.js.map +0 -1
  39. package/dist/js/chunk-vendors.0b4288c4.js +0 -14
  40. package/dist/js/chunk-vendors.0b4288c4.js.map +0 -1
  41. package/src/components/LayoutContentList.vue +0 -589
  42. package/src/plugins/mVuetify.mjs +0 -12
@@ -8,6 +8,7 @@ import keys from 'lodash/keys'
8
8
  import j2o from 'wsemi/src/j2o.mjs'
9
9
  import iseobj from 'wsemi/src/iseobj.mjs'
10
10
  import isestr from 'wsemi/src/isestr.mjs'
11
+ import isearr from 'wsemi/src/isearr.mjs'
11
12
  import ispint from 'wsemi/src/ispint.mjs'
12
13
  import isfun from 'wsemi/src/isfun.mjs'
13
14
  import ispm from 'wsemi/src/ispm.mjs'
@@ -26,7 +27,7 @@ import ds from '../src/schema/index.mjs'
26
27
 
27
28
 
28
29
  /**
29
- * 基於hapi之API伺服器
30
+ * API伺服器
30
31
  *
31
32
  * @class
32
33
  * @param {Function} WOrm 輸入資料庫ORM函數
@@ -45,10 +46,9 @@ import ds from '../src/schema/index.mjs'
45
46
  * @param {String} [opt.subfolder=''] 輸入站台所在子目錄字串,提供站台位於內網採反向代理進行服務時,故需支援位於子目錄情形,預設''
46
47
  * @returns {Object} 回傳物件,其內server為hapi伺服器實體,wsrv為w-converhp的伺服器事件物件,wsds為w-serv-webdata的伺服器事件物件,可監聽error事件
47
48
  * @example
48
- *
49
49
  * import WOrm from 'w-orm-mongodb/src/WOrmMongodb.mjs' //自行選擇引用ORM, 使用Mongodb測試
50
- * import getSettings from './server/getSettings.mjs'
51
50
  * import WWebApi from './server/WWebApi.mjs'
51
+ * import getSettings from './g.getSettings.mjs'
52
52
  *
53
53
  * //st
54
54
  * let st = getSettings()
@@ -57,22 +57,55 @@ import ds from '../src/schema/index.mjs'
57
57
  * let db = st.dbName
58
58
  * let opt = {
59
59
  *
60
- * getUserById: null,
61
60
  * bCheckUser: false,
61
+ * getUserById: null,
62
62
  * bExcludeWhenNotAdmin: false,
63
63
  *
64
64
  * serverPort: 11005,
65
- * subfolder: '', //mpai
65
+ * subfolder: '', //mapi
66
66
  *
67
67
  * webName: {
68
68
  * 'eng': 'API Service',
69
- * 'cht': 'API管理系統'
69
+ * 'cht': 'API管理系統',
70
70
  * },
71
+ * webDescription: {
72
+ * 'eng': 'A web service package as methods to send requests to and receive responses from an API.',
73
+ * 'cht': 'A web service package as methods to send requests to and receive responses from an API.',
74
+ * },
75
+ * webLogo: 'data:image/svg+xml;base64,...',
76
+ *
77
+ * }
71
78
  *
79
+ * let getUserByToken = (token) => {
80
+ * // return {} //測試無法登入
81
+ * if (token === '{token-for-application}') { //提供外部應用系統作為存取使用者
82
+ * return {
83
+ * id: 'id-for-application',
84
+ * name: 'application',
85
+ * email: 'admin@example.com',
86
+ * isAdmin: 'y',
87
+ * }
88
+ * }
89
+ * if (token === 'sys') { //開發階段w-ui-loginout自動給予browser使用者(且位於localhost)的token為sys
90
+ * return {
91
+ * id: 'id-for-admin',
92
+ * name: '測試者',
93
+ * email: 'admin@example.com',
94
+ * isAdmin: 'y',
95
+ * }
96
+ * }
97
+ * console.log('invalid token', token)
98
+ * console.log('於生產環境時得加入SSO等驗證token機制')
99
+ * return {}
100
+ * }
101
+ *
102
+ * let verifyUser = (user) => {
103
+ * console.log('於生產環境時得加入驗證user機制')
104
+ * return user.isAdmin === 'y' //測試僅系統管理者使用
72
105
  * }
73
106
  *
74
107
  * //WWebApi
75
- * let instWWebApi = WWebApi(WOrm, url, db, opt)
108
+ * let instWWebApi = WWebApi(WOrm, url, db, getUserByToken, verifyUser, opt)
76
109
  *
77
110
  * instWWebApi.on('error', (err) => {
78
111
  * console.log(err)
@@ -188,32 +221,37 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyUser, opt = {}) {
188
221
  }
189
222
 
190
223
 
191
- //verifyUserByToken
192
- let verifyUserByToken = async (token) => {
224
+ //getTokenUserForSelf
225
+ let getTokenUserForSelf = async (token) => {
193
226
 
194
227
  //getUserByToken
195
- let user = getUserByToken(token)
196
- if (ispm(user)) {
197
- user = await user
228
+ let userSelf = getUserByToken(token)
229
+ if (ispm(userSelf)) {
230
+ userSelf = await userSelf
198
231
  }
199
- if (!iseobj(user)) {
200
- return Promise.reject(`token does not have permission`)
232
+
233
+ //check
234
+ if (!iseobj(userSelf)) {
235
+ console.log(`can not find the user from token`, token)
236
+ return Promise.reject(`can not find the user from token`)
201
237
  }
202
238
 
203
239
  //verifyUser
204
- let b = verifyUser(user)
240
+ let b = verifyUser(userSelf)
205
241
  if (ispm(b)) {
206
242
  b = await b
207
243
  }
208
244
 
209
245
  //check
210
246
  if (!b) {
247
+ console.log('userSelf', userSelf)
211
248
  return Promise.reject(`user does not have permission`)
212
249
  }
213
250
 
214
- return user
251
+ return userSelf
215
252
  }
216
253
 
254
+
217
255
  //getAPIsList
218
256
  let getAPIsList = async (query = {}) => {
219
257
  let rs = await woItems.apis.select(query)
@@ -222,7 +260,7 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyUser, opt = {}) {
222
260
 
223
261
 
224
262
  //parsePayload
225
- let parsePayload = (req) => {
263
+ let parsePayload = async (req) => {
226
264
  let inp = get(req, 'payload')
227
265
 
228
266
  //to obj
@@ -230,37 +268,57 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyUser, opt = {}) {
230
268
  inp = j2o(inp)
231
269
  }
232
270
 
233
- //cv apis for base64
234
- if (iseobj(inp)) {
235
-
236
- //spread
237
- let { group, apis } = inp
238
-
239
- //apis
240
- each(apis, (api, kapi) => {
241
- // console.log(kapi, api.name)
242
- each(api, (v, k) => {
243
- // console.log(k, v)
244
- if (isestr(v)) {
245
- if (strleft(v, 7) === 'base64:') {
246
- // console.log(k, 'get base64')
247
- v = strdelleft(v, 7)
248
- v = b642str(v)
249
- // console.log(v)
250
- apis[kapi][k] = v
251
- }
252
- }
253
- })
254
- })
271
+ //check
272
+ if (!iseobj(inp)) {
273
+ console.log('inp', inp)
274
+ return Promise.reject(`invalid inp from req`)
275
+ }
255
276
 
256
- //resave
257
- inp = { group, apis }
277
+ //group
278
+ let group = get(inp, 'group', '')
258
279
 
280
+ //check
281
+ if (!isestr(group)) {
282
+ console.log('inp', inp)
283
+ console.log('group', group)
284
+ return Promise.reject(`invalid group from inp`)
259
285
  }
260
- else {
261
- inp = null
286
+
287
+ //apis
288
+ let apis = get(inp, 'apis', [])
289
+
290
+ //check
291
+ if (!isearr(apis)) {
292
+ console.log('inp', inp)
293
+ console.log('apis', apis)
294
+ return Promise.reject(`invalid apis from inp`)
262
295
  }
263
296
 
297
+ //偵測b64自動恢復
298
+ each(apis, (api, kapi) => {
299
+ // console.log(kapi, api.name)
300
+ each(api, (v, k) => {
301
+ // console.log(k, v)
302
+ if (isestr(v)) {
303
+ if (strleft(v, 7) === 'base64:') {
304
+ // console.log(k, 'get base64')
305
+ v = strdelleft(v, 7)
306
+ v = b642str(v)
307
+ // console.log(v)
308
+ apis[kapi][k] = v
309
+ }
310
+ }
311
+ })
312
+ })
313
+
314
+ //save group
315
+ each(apis, (api, kapi) => {
316
+ apis[kapi].group = group
317
+ })
318
+
319
+ //resave
320
+ inp = { group, apis }
321
+
264
322
  return inp
265
323
  }
266
324
 
@@ -280,19 +338,36 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyUser, opt = {}) {
280
338
  }
281
339
 
282
340
 
283
- //replaceAPIsByLevels
284
- let replaceAPIsByLevels = async (params = {}) => {
341
+ //syncAndReplaceApis
342
+ let syncAndReplaceApis = async (params) => {
285
343
 
286
- //spread params
287
- let { group, apis: rsApis } = params
344
+ //group
345
+ let group = get(params, 'group', '')
288
346
  // console.log('group', group)
289
- // console.log('rsApis', rsApis)
347
+
348
+ //check
349
+ if (!isestr(group)) {
350
+ console.log('params', params)
351
+ console.log('group', group)
352
+ return Promise.reject(`invalid group`)
353
+ }
354
+
355
+ //apis
356
+ let apis = get(params, 'apis', [])
357
+ // console.log('apis', apis)
358
+
359
+ //check
360
+ if (!isearr(apis)) {
361
+ console.log('params', params)
362
+ console.log('apis', apis)
363
+ return Promise.reject(`invalid apis`)
364
+ }
290
365
 
291
366
  //delAll group
292
367
  await woItems.apis.delAll({ group })
293
368
 
294
369
  //insert
295
- let r = await woItems.apis.insert(rsApis)
370
+ let r = await woItems.apis.insert(apis)
296
371
 
297
372
  return r
298
373
  }
@@ -354,8 +429,15 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyUser, opt = {}) {
354
429
  //token
355
430
  let token = get(req, 'query.token', '')
356
431
 
357
- //verifyUserByToken
358
- let user = await verifyUserByToken(token)
432
+ //getTokenUserForSelf
433
+ let user = await getTokenUserForSelf(token)
434
+
435
+ //check
436
+ if (!iseobj(user)) {
437
+ console.log('token', token)
438
+ console.log('[API]getUserByToken/check user: invalid user')
439
+ return Promise.reject(`token does not have permission`)
440
+ }
359
441
 
360
442
  return user
361
443
  }
@@ -378,8 +460,15 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyUser, opt = {}) {
378
460
  //token
379
461
  let token = get(req, 'query.token', '')
380
462
 
381
- //verifyUserByToken
382
- await verifyUserByToken(token)
463
+ //getTokenUserForSelf
464
+ let user = await getTokenUserForSelf(token)
465
+
466
+ //check
467
+ if (!iseobj(user)) {
468
+ console.log('token', token)
469
+ console.log('[API]getAPIsList/check user: invalid user')
470
+ return Promise.reject(`token does not have permission`)
471
+ }
383
472
 
384
473
  //getAPIsList
385
474
  let r = await getAPIsList({ isActive: 'y' })
@@ -406,11 +495,18 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyUser, opt = {}) {
406
495
  //token
407
496
  let token = get(req, 'query.token', '')
408
497
 
409
- //verifyUserByToken
410
- await verifyUserByToken(token)
498
+ //getTokenUserForSelf
499
+ let user = await getTokenUserForSelf(token)
500
+
501
+ //check
502
+ if (!iseobj(user)) {
503
+ console.log('token', token)
504
+ console.log('[API]updateAPIs/check user: invalid user')
505
+ return Promise.reject(`token does not have permission`)
506
+ }
411
507
 
412
508
  //parsePayload
413
- let inp = parsePayload(req)
509
+ let inp = await parsePayload(req)
414
510
 
415
511
  //updateAPIs
416
512
  let r = await updateAPIs(inp)
@@ -427,9 +523,9 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyUser, opt = {}) {
427
523
  },
428
524
  {
429
525
  method: 'POST',
430
- path: '/replaceAPIsByLevels',
526
+ path: '/syncAndReplaceApis',
431
527
  handler: async function (req, res) {
432
- // console.log('replaceAPIsByLevels', req)
528
+ // console.log('syncAndReplaceApis', req)
433
529
  // console.log('payload', req.payload)
434
530
 
435
531
  async function core() {
@@ -437,14 +533,21 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyUser, opt = {}) {
437
533
  //token
438
534
  let token = get(req, 'query.token', '')
439
535
 
440
- //verifyUserByToken
441
- await verifyUserByToken(token)
536
+ //getTokenUserForSelf
537
+ let user = await getTokenUserForSelf(token)
538
+
539
+ //check
540
+ if (!iseobj(user)) {
541
+ console.log('token', token)
542
+ console.log('[API]syncAndReplaceApis/check user: invalid user')
543
+ return Promise.reject(`token does not have permission`)
544
+ }
442
545
 
443
546
  //parsePayload
444
- let inp = parsePayload(req)
547
+ let inp = await parsePayload(req)
445
548
 
446
- //replaceAPIsByLevels
447
- let r = await replaceAPIsByLevels(inp)
549
+ //syncAndReplaceApis
550
+ let r = await syncAndReplaceApis(inp)
448
551
 
449
552
  return r
450
553
  }
@@ -4,8 +4,8 @@ import genPm from 'wsemi/src/genPm.mjs'
4
4
 
5
5
 
6
6
  async function provideApis(url, group, apis) {
7
- //url: 指API伺服器提供的接入網址, 例如 http://localhost:11005/replaceAPIsByLevels
8
- //group: 指API所屬群組, 主要呼叫replaceAPIsByLevels為主
7
+ //url: 指API伺服器提供的接入網址, 例如 http://localhost:11005/syncAndReplaceApis
8
+ //group: 指API所屬群組
9
9
 
10
10
  //pm
11
11
  let pm = genPm()
package/src/App.vue CHANGED
@@ -57,6 +57,7 @@ export default {
57
57
  console.log('login...')
58
58
  let ll = wui('wperm', {
59
59
  timeWaitAnimation: 2000,
60
+ params: {},
60
61
  })
61
62
  ll.login({
62
63
  afterGetUser: null,
@@ -109,14 +110,6 @@ button {
109
110
  font-family: inherit;
110
111
  }
111
112
 
112
- .v-application, .v-application--wrap {
113
- font-family: inherit;
114
- }
115
-
116
- .v-chip {
117
- cursor: inherit;
118
- }
119
-
120
113
  .fade-enter-active {
121
114
  animation: go 1s;
122
115
  }
@@ -1,7 +1,8 @@
1
1
  <template>
2
2
  <div style="height:100vh; background:#f5f5f5;">
3
3
 
4
- <div :style="`height:${heightToolbar}px; padding:0px 10px; display:flex; align-items:center; background:#fff; border-bottom:1px solid #ccc;`">
4
+ <!-- menu top, 因窄版導致名稱換行故須使用overflow-y:hidden -->
5
+ <div :style="`height:${heightToolbar}px; overflow-y:hidden; padding:0px 10px; background:#fff; border-bottom:1px solid #ccc; display:flex; align-items:center;`">
5
6
 
6
7
  <WButtonCircle
7
8
  :icon="'mdi-menu'"
@@ -24,7 +25,6 @@
24
25
  </div>
25
26
 
26
27
  </div>
27
-
28
28
  </div>
29
29
 
30
30
  <div style="width:100%;"></div>