w-web-api 1.0.23 → 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.
Files changed (37) hide show
  1. package/.eslintrc.js +1 -0
  2. package/.vscode/launch.json +21 -0
  3. package/README.md +21 -4
  4. package/dist/css/{chunk-vendors.1474a727.css → chunk-vendors.ca61ed63.css} +1 -1
  5. package/dist/img/connecting.26511805.svg +10 -0
  6. package/dist/img/deny.e7b81b94.png +0 -0
  7. package/dist/index.tmp +1 -1
  8. package/dist/js/app-legacy.9ae046af.js +2 -0
  9. package/dist/js/app-legacy.9ae046af.js.map +1 -0
  10. package/dist/js/app.e95d00d5.js +2 -0
  11. package/dist/js/app.e95d00d5.js.map +1 -0
  12. package/dist/js/chunk-vendors-legacy.0023ac2c.js +14 -0
  13. package/dist/js/chunk-vendors-legacy.0023ac2c.js.map +1 -0
  14. package/dist/js/chunk-vendors.0023ac2c.js +14 -0
  15. package/dist/js/chunk-vendors.0023ac2c.js.map +1 -0
  16. package/dist/w-web-api.umd.js +2 -2
  17. package/dist/w-web-api.umd.js.map +1 -1
  18. package/docs/WWebApi.html +85 -13
  19. package/docs/WWebApi.mjs.html +149 -30
  20. package/docs/index.html +1 -1
  21. package/package.json +5 -4
  22. package/server/WWebApi.mjs +148 -29
  23. package/src/App.vue +43 -7
  24. package/src/components/LayoutState.vue +87 -0
  25. package/src/main.js +5 -2
  26. package/src/plugins/mUI.mjs +12 -0
  27. package/src/store/mutations.mjs +13 -6
  28. package/srv.mjs +21 -2
  29. package/tableTags-web-api.json +1 -1
  30. package/dist/js/app-legacy.c9a65a85.js +0 -2
  31. package/dist/js/app-legacy.c9a65a85.js.map +0 -1
  32. package/dist/js/app.c9a65a85.js +0 -2
  33. package/dist/js/app.c9a65a85.js.map +0 -1
  34. package/dist/js/chunk-vendors-legacy.bf09c4e2.js +0 -14
  35. package/dist/js/chunk-vendors-legacy.bf09c4e2.js.map +0 -1
  36. package/dist/js/chunk-vendors.bf09c4e2.js +0 -14
  37. package/dist/js/chunk-vendors.bf09c4e2.js.map +0 -1
@@ -10,17 +10,19 @@ import iseobj from 'wsemi/src/iseobj.mjs'
10
10
  import isestr from 'wsemi/src/isestr.mjs'
11
11
  import ispint from 'wsemi/src/ispint.mjs'
12
12
  import isfun from 'wsemi/src/isfun.mjs'
13
+ import ispm from 'wsemi/src/ispm.mjs'
13
14
  import cint from 'wsemi/src/cint.mjs'
14
15
  import strleft from 'wsemi/src/strleft.mjs'
15
16
  import strdelleft from 'wsemi/src/strdelleft.mjs'
16
17
  import strright from 'wsemi/src/strright.mjs'
17
18
  import strdelright from 'wsemi/src/strdelright.mjs'
19
+ import pm2resolve from 'wsemi/src/pm2resolve.mjs'
18
20
  import b642str from 'wsemi/src/b642str.mjs'
19
21
  import fsIsFolder from 'wsemi/src/fsIsFolder.mjs'
20
22
  import replace from 'wsemi/src/replace.mjs'
21
23
  import WServHapiServer from 'w-serv-hapi/src/WServHapiServer.mjs'
22
- import ds from '../src/schema/index.mjs'
23
24
  import WServOrm from 'w-serv-orm/src/WServOrm.mjs'
25
+ import ds from '../src/schema/index.mjs'
24
26
 
25
27
 
26
28
  /**
@@ -30,11 +32,13 @@ import WServOrm from 'w-serv-orm/src/WServOrm.mjs'
30
32
  * @param {Function} WOrm 輸入資料庫ORM函數
31
33
  * @param {String} url 輸入資料庫連線字串,例如'mongodb://sername:password@$127.0.0.1:27017'
32
34
  * @param {String} db 輸入資料庫名稱字串
35
+ * @param {Function} getUserByToken 輸入處理函數,函數會傳入使用者token,通過此函數處理後並回傳使用者資訊物件,並至少須提供'id'、'email'、'name'、'isAdmin'欄位,且'isAdmin'限輸入'y'或'n',且輸入'y'時會複寫權限系統該使用者之'isAdmin'欄位值
36
+ * @param {Function} verifyUser 輸入處理函數,函數會傳入使用者資訊物件,通過此函數識別後回傳布林值,允許使用者回傳true,反之回傳false
33
37
  * @param {Object} [opt={}] 輸入設定物件,預設{}
34
38
  * @param {Integer} [opt.serverPort=11005] 輸入伺服器通訊port,預設11005
39
+ * @param {Boolean} [opt.bCheckUser=false] 輸入是否檢查使用者資訊布林值,預設false
35
40
  * @param {Function} [opt.getUserById=null] 輸入當bCheckUser=true時依照使用者ID取得使用者資訊物件函數,預設null
36
- * @param {Boolean} [opt.bCheckUser=true] 輸入是否檢查使用者資訊布林值,預設true
37
- * @param {Boolean} [opt.bExcludeWhenNotAdmin=true] 輸入使用ORM的select方法時是否自動刪除數據內isActive欄位之布林值,預設true
41
+ * @param {Boolean} [opt.bExcludeWhenNotAdmin=false] 輸入使用ORM的select方法時是否自動刪除數據內isActive欄位之布林值,預設false
38
42
  * @param {Object} [opt.webName={}] 輸入站台名稱物件,至少包含語系eng與cht鍵的名稱,預設{}
39
43
  * @param {Object} [opt.webDescription={}] 輸入站台描述物件,至少包含語系eng與cht鍵的名稱,預設{}
40
44
  * @param {String} [opt.webLogo=''] 輸入站台logo字串,採base64格式,預設''
@@ -75,7 +79,7 @@ import WServOrm from 'w-serv-orm/src/WServOrm.mjs'
75
79
  * })
76
80
  *
77
81
  */
78
- function WWebApi(WOrm, url, db, opt = {}) {
82
+ function WWebApi(WOrm, url, db, getUserByToken, verifyUser, opt = {}) {
79
83
  let instWServHapiServer = null
80
84
 
81
85
 
@@ -100,6 +104,20 @@ function WWebApi(WOrm, url, db, opt = {}) {
100
104
  }
101
105
 
102
106
 
107
+ //check getUserByToken
108
+ if (!isfun(getUserByToken)) {
109
+ console.log('invalid getUserByToken', getUserByToken)
110
+ throw new Error('invalid getUserByToken')
111
+ }
112
+
113
+
114
+ //check verifyUser
115
+ if (!isfun(verifyUser)) {
116
+ console.log('invalid verifyUser', verifyUser)
117
+ throw new Error('invalid verifyUser')
118
+ }
119
+
120
+
103
121
  //serverPort
104
122
  let serverPort = get(opt, 'serverPort')
105
123
  if (!ispint(serverPort)) {
@@ -170,9 +188,35 @@ function WWebApi(WOrm, url, db, opt = {}) {
170
188
  }
171
189
 
172
190
 
191
+ //verifyUserByToken
192
+ let verifyUserByToken = async (token) => {
193
+
194
+ //getUserByToken
195
+ let user = getUserByToken(token)
196
+ if (ispm(user)) {
197
+ user = await user
198
+ }
199
+ if (!iseobj(user)) {
200
+ return Promise.reject(`token does not have permission`)
201
+ }
202
+
203
+ //verifyUser
204
+ let b = verifyUser(user)
205
+ if (ispm(b)) {
206
+ b = await b
207
+ }
208
+
209
+ //check
210
+ if (!b) {
211
+ return Promise.reject(`user does not have permission`)
212
+ }
213
+
214
+ return user
215
+ }
216
+
173
217
  //getAPIsList
174
- let getAPIsList = async (userId, token) => {
175
- let rs = await woItems.apis.select()
218
+ let getAPIsList = async (query = {}) => {
219
+ let rs = await woItems.apis.select(query)
176
220
  return rs
177
221
  }
178
222
 
@@ -222,7 +266,7 @@ function WWebApi(WOrm, url, db, opt = {}) {
222
266
 
223
267
 
224
268
  //updateAPIs
225
- let updateAPIs = async (userId, params = {}) => {
269
+ let updateAPIs = async (params = {}) => {
226
270
 
227
271
  //spread params
228
272
  let { apis: rsApis } = params
@@ -237,7 +281,7 @@ function WWebApi(WOrm, url, db, opt = {}) {
237
281
 
238
282
 
239
283
  //replaceAPIsByLevels
240
- let replaceAPIsByLevels = async (userId, params = {}) => {
284
+ let replaceAPIsByLevels = async (params = {}) => {
241
285
 
242
286
  //spread params
243
287
  let { group, apis: rsApis } = params
@@ -266,11 +310,17 @@ function WWebApi(WOrm, url, db, opt = {}) {
266
310
  //subfolder
267
311
  let fnEntryIn = 'index.tmp'
268
312
  let fnEntryOut = 'index.html'
269
- let fpEntryIn = path.resolve(pathStaticFiles, fnEntryIn)
270
- let fpEntryOut = path.resolve(pathStaticFiles, fnEntryOut)
271
- let c = fs.readFileSync(fpEntryIn, 'utf8')
272
- c = replace(c, '{sfd}', subfolder)
273
- fs.writeFileSync(fpEntryOut, c, 'utf8')
313
+ try {
314
+ let fpEntryIn = path.resolve(pathStaticFiles, fnEntryIn)
315
+ let fpEntryOut = path.resolve(pathStaticFiles, fnEntryOut)
316
+ let c = fs.readFileSync(fpEntryIn, 'utf8')
317
+ c = replace(c, '{sfd}', subfolder)
318
+ fs.writeFileSync(fpEntryOut, c, 'utf8')
319
+ }
320
+ catch (err) {
321
+ console.log(err)
322
+ console.log(`can not generate ${fnEntryOut}`)
323
+ }
274
324
 
275
325
 
276
326
  //apis
@@ -293,16 +343,53 @@ function WWebApi(WOrm, url, db, opt = {}) {
293
343
  return getWebInfor()
294
344
  },
295
345
  },
346
+ {
347
+ method: 'GET',
348
+ path: '/api/getUserByToken', //未登入界面需先檢測token是否為系統管理員, 確認後回傳為系統管理員資訊物件, getUserByToken為w-ui-loginout預設值, 若要更改兩邊須同時修改
349
+ handler: async function (req, res) {
350
+ // console.log('getUserByToken', req)
351
+
352
+ async function core() {
353
+
354
+ //token
355
+ let token = get(req, 'query.token', '')
356
+
357
+ //verifyUserByToken
358
+ let user = await verifyUserByToken(token)
359
+
360
+ return user
361
+ }
362
+
363
+ //pm2resolve core
364
+ let r = await pm2resolve(core)() //w-ui-loginout接收已預設格式用pm2resolve轉過, 會提取state進行判斷
365
+ // console.log('getUserByToken', r)
366
+
367
+ return r
368
+ },
369
+ },
296
370
  {
297
371
  method: 'GET',
298
372
  path: '/getAPIsList',
299
373
  handler: async function (req, res) {
374
+ // console.log('getAPIsList', req)
375
+
376
+ async function core() {
377
+
378
+ //token
379
+ let token = get(req, 'query.token', '')
380
+
381
+ //verifyUserByToken
382
+ await verifyUserByToken(token)
300
383
 
301
- //token
302
- let token = get(req, 'query.token', '')
384
+ //getAPIsList
385
+ let r = await getAPIsList({ isActive: 'y' })
303
386
 
304
- //getAPIsList
305
- let r = await getAPIsList('', token)
387
+ return r
388
+ }
389
+
390
+ //pm2resolve core
391
+ let r = await pm2resolve(core)()
392
+ // console.log('verifyIdentity', r)
306
393
 
307
394
  return r
308
395
  },
@@ -311,14 +398,29 @@ function WWebApi(WOrm, url, db, opt = {}) {
311
398
  method: 'POST',
312
399
  path: '/updateAPIs',
313
400
  handler: async function (req, res) {
314
- // console.log(req, res)
401
+ // console.log('updateAPIs', req)
315
402
  // console.log('payload', req.payload)
316
403
 
317
- //parsePayload
318
- let inp = parsePayload(req)
404
+ async function core() {
405
+
406
+ //token
407
+ let token = get(req, 'query.token', '')
408
+
409
+ //verifyUserByToken
410
+ await verifyUserByToken(token)
411
+
412
+ //parsePayload
413
+ let inp = parsePayload(req)
414
+
415
+ //updateAPIs
416
+ let r = await updateAPIs(inp)
417
+
418
+ return r
419
+ }
319
420
 
320
- //updateAPIs
321
- let r = await updateAPIs('', inp)
421
+ //pm2resolve core
422
+ let r = await pm2resolve(core)()
423
+ // console.log('verifyIdentity', r)
322
424
 
323
425
  return r
324
426
  },
@@ -327,14 +429,29 @@ function WWebApi(WOrm, url, db, opt = {}) {
327
429
  method: 'POST',
328
430
  path: '/replaceAPIsByLevels',
329
431
  handler: async function (req, res) {
330
- // console.log(req, res)
432
+ // console.log('replaceAPIsByLevels', req)
331
433
  // console.log('payload', req.payload)
332
434
 
333
- //parsePayload
334
- let inp = parsePayload(req)
435
+ async function core() {
335
436
 
336
- //replaceAPIsByLevels
337
- let r = await replaceAPIsByLevels('', inp)
437
+ //token
438
+ let token = get(req, 'query.token', '')
439
+
440
+ //verifyUserByToken
441
+ await verifyUserByToken(token)
442
+
443
+ //parsePayload
444
+ let inp = parsePayload(req)
445
+
446
+ //replaceAPIsByLevels
447
+ let r = await replaceAPIsByLevels(inp)
448
+
449
+ return r
450
+ }
451
+
452
+ //pm2resolve core
453
+ let r = await pm2resolve(core)()
454
+ // console.log('verifyIdentity', r)
338
455
 
339
456
  return r
340
457
  },
@@ -356,7 +473,7 @@ function WWebApi(WOrm, url, db, opt = {}) {
356
473
  pathStaticFiles,
357
474
  apis,
358
475
  getUserIDFromToken: async (token) => { //可使用async或sync函數
359
- return 'id-for-admin'
476
+ return ''
360
477
  },
361
478
  useDbORM: true,
362
479
  dbORMs: woItems,
@@ -366,7 +483,9 @@ function WWebApi(WOrm, url, db, opt = {}) {
366
483
  tableNamesSync,
367
484
  extFuncs: { //接收參數第1個為userId, 之後才是前端給予參數
368
485
  getWebInfor,
369
- getAPIsList,
486
+ getAPIsList: (userId, query = {}) => {
487
+ return getAPIsList(query)
488
+ },
370
489
  //...
371
490
  },
372
491
  hookBefores: null,
package/src/App.vue CHANGED
@@ -4,6 +4,8 @@
4
4
  @domresize="resize"
5
5
  >
6
6
 
7
+ <LayoutState :style="`opacity:${ready?0:1};`" v-if="!ready"></LayoutState>
8
+
7
9
  <transition enter-active-class="fade-enter-active" leave-active-class="fade-leave-active">
8
10
  <Layout v-if="ready"></Layout>
9
11
  </transition>
@@ -12,30 +14,64 @@
12
14
  </template>
13
15
 
14
16
  <script>
15
- // import get from 'lodash/get'
16
- // import find from 'lodash/find'
17
+ import get from 'lodash/get'
18
+ import cloneDeep from 'lodash/cloneDeep'
19
+ import wui from 'w-ui-loginout/src/WUiLoginout.mjs'
17
20
  import Layout from './components/Layout.vue'
21
+ import LayoutState from './components/LayoutState.vue'
18
22
 
19
23
 
20
24
  export default {
21
25
  components: {
22
26
  Layout,
27
+ LayoutState,
23
28
  },
24
29
  data: function() {
25
30
  return {
26
-
27
- ready: true,
28
-
31
+ ll: null,
29
32
  }
30
33
  },
31
- mounted: function() {
32
- // console.log('mounted')
34
+ beforeMount: function() {
35
+ // console.log('methods beforeMount')
33
36
 
34
37
  let vo = this
35
38
 
36
39
  //setVo, 更換ui內vo, 才能使用廣播技術, 更換語系才能用廣播通知全部組件forceUpdate
37
40
  vo.$ui.setVo(vo)
38
41
 
42
+ function loginSuccess(data) {
43
+ console.log('login success', cloneDeep(data.user))
44
+ vo.$ui.updateConnState('已連線')
45
+ vo.$ui.updateUserToken(data.token)
46
+ vo.$ui.updateUserSelf(data.user)
47
+ }
48
+
49
+ function loginError(data) {
50
+ console.log('login error', cloneDeep(data))
51
+ vo.$ui.updateConnState(data.text)
52
+ vo.$ui.updateUserToken('')
53
+ vo.$ui.updateUserSelf(get(vo, `$store.state.userDef`))
54
+ }
55
+
56
+ //login
57
+ console.log('login...')
58
+ let ll = wui('wperm')
59
+ ll.login({
60
+ afterGetUser: null,
61
+ afterLogin: null,
62
+ loginSuccess,
63
+ loginError,
64
+ })
65
+ vo.ll = ll
66
+
67
+ },
68
+ computed: {
69
+
70
+ ready: function() {
71
+ let connState = get(this, `$store.state.connState`)
72
+ return connState === '已連線'
73
+ },
74
+
39
75
  },
40
76
  methods: {
41
77
 
@@ -0,0 +1,87 @@
1
+ <template>
2
+ <div
3
+ :style="`position:absolute; top:0px; left:0px; width:100%; height:100%; transition:all 0.5s linear; display:flex; align-items:center; justify-content:center;`"
4
+ >
5
+
6
+ <template v-if="connState==='已連線' || connState==='連線中...'">
7
+
8
+ <img src="../../public/connecting.svg">
9
+
10
+ <div style="margin-left:10px;">
11
+ <div style="color:#aaa;">
12
+ {{connState}}
13
+ </div>
14
+ </div>
15
+
16
+ </template>
17
+
18
+ <template v-else-if="connState==='已登出'">
19
+
20
+ <img style="width:75px; height:75px;" src="../../public/logout.png">
21
+
22
+ <div style="margin-left:10px;">
23
+ <div style="color:#aaa;">
24
+ {{connState}}
25
+ </div>
26
+ </div>
27
+
28
+ </template>
29
+
30
+ <template v-else-if="connState==='無法連線'">
31
+
32
+ <img style="width:75px; height:75px;" src="../../public/disconnect.png">
33
+
34
+ <div style="margin-left:10px;">
35
+ <div style="color:#aaa;">
36
+ {{connState}}
37
+ </div>
38
+ </div>
39
+
40
+ </template>
41
+
42
+ <template v-else>
43
+
44
+ <img style="width:75px; height:75px;" src="../../public/deny.png">
45
+
46
+ <div style="margin-left:10px;">
47
+ <div style="color:#aaa;">
48
+ {{connState}}
49
+ </div>
50
+ </div>
51
+
52
+ </template>
53
+
54
+ </div>
55
+ </template>
56
+
57
+ <script>
58
+ import get from 'lodash/get'
59
+
60
+
61
+ export default {
62
+ components: {
63
+ },
64
+ props: {
65
+ },
66
+ data: function() {
67
+ return {
68
+ }
69
+ },
70
+ computed: {
71
+
72
+ connState: function() {
73
+ //console.log('computed loading')
74
+
75
+ let vo = this
76
+
77
+ return get(vo, `$store.state.connState`)
78
+ },
79
+
80
+ },
81
+ methods: {
82
+ }
83
+ }
84
+ </script>
85
+
86
+ <style scoped>
87
+ </style>
package/src/main.js CHANGED
@@ -56,12 +56,15 @@ Vue.directive('domdragdrop', domDragDrop())
56
56
  //WServHapiClient
57
57
  let bFirstSync = false
58
58
  WServHapiClient({
59
+ showLog: false,
59
60
  getUrl: () => {
60
61
  return window.location.origin + window.location.pathname
61
62
  },
62
- useWaitToken: false,
63
+ useWaitToken: true,
63
64
  getToken: () => {
64
- return get(Vue.prototype, `$store.state.userToken`, '')
65
+ let token = get(Vue.prototype, `$store.state.userToken`, '')
66
+ // console.log('getToken', token)
67
+ return token
65
68
  },
66
69
  getServerMethods: (_fapi) => {
67
70
  console.log('$fapi', _fapi)
@@ -67,6 +67,16 @@ function updateViewState(viewState) {
67
67
  }
68
68
 
69
69
 
70
+ function updateUserToken(userToken) {
71
+ vo.$store.commit(vo.$store.types.UpdateUserToken, userToken)
72
+ }
73
+
74
+
75
+ function updateUserSelf(userSelf) {
76
+ vo.$store.commit(vo.$store.types.UpdateUserSelf, userSelf)
77
+ }
78
+
79
+
70
80
  function forceUpdate() {
71
81
  // console.log('call forceUpdate')
72
82
 
@@ -200,6 +210,8 @@ let mUI = {
200
210
  updateConnState,
201
211
  updateLoading,
202
212
  updateViewState,
213
+ updateUserToken,
214
+ updateUserSelf,
203
215
  forceUpdate,
204
216
 
205
217
  setLang,
@@ -1,9 +1,20 @@
1
1
  import each from 'lodash/each'
2
2
  import set from 'lodash/set'
3
+ import cloneDeep from 'lodash/cloneDeep'
3
4
  import * as types from './types.mjs'
4
5
  import ds from '../schema/index.mjs'
5
6
 
6
7
 
8
+ //userDef
9
+ let userDef = {
10
+ id: '', //id-for-admin
11
+ name: '', //測試者
12
+ email: '', //id-for-admin@gmail.com
13
+ // isVirtual: 'n',
14
+ isAdmin: 'n',
15
+ // isActive: 'n',
16
+ }
17
+
7
18
  //state, 全域狀態
8
19
  let state = {
9
20
 
@@ -24,12 +35,8 @@ let state = {
24
35
  menu: {}, //初始值需為物件, 否則LayoutContent會取menu.key出錯
25
36
 
26
37
  userToken: '',
27
- userSelf: {
28
- id: 'id-for-admin',
29
- name: '系統管理員',
30
- email: 'admin@email.com',
31
- isAdmin: true,
32
- },
38
+ userDef: cloneDeep(userDef),
39
+ userSelf: cloneDeep(userDef),
33
40
 
34
41
  lang: 'cht',
35
42
  keyLangs: {
package/srv.mjs CHANGED
@@ -10,8 +10,8 @@ let url = `mongodb://${st.dbUsername}:${st.dbPassword}@${st.dbIP}:${st.dbPort}`
10
10
  let db = st.dbName
11
11
  let opt = {
12
12
 
13
- getUserById: null,
14
13
  bCheckUser: false,
14
+ getUserById: null,
15
15
  bExcludeWhenNotAdmin: false,
16
16
 
17
17
  serverPort: 11005,
@@ -29,8 +29,27 @@ let opt = {
29
29
 
30
30
  }
31
31
 
32
+ let getUserByToken = (token) => {
33
+ console.log('getUserByToken token', token)
34
+ // return {} //測試無法登入條件
35
+ if (token !== 'sys') {
36
+ return {}
37
+ }
38
+ return {
39
+ id: 'id-for-admin',
40
+ name: '測試者',
41
+ email: 'admin@example.com',
42
+ isAdmin: 'y',
43
+ }
44
+ }
45
+
46
+ let verifyUser = (user) => {
47
+ return user.isAdmin === 'y'
48
+ }
49
+
50
+
32
51
  //WWebApi
33
- let instWWebApi = WWebApi(WOrm, url, db, opt)
52
+ let instWWebApi = WWebApi(WOrm, url, db, getUserByToken, verifyUser, opt)
34
53
 
35
54
  instWWebApi.on('error', (err) => {
36
55
  console.log(err)
@@ -1 +1 @@
1
- {"apis":"zv3kI4"}
1
+ {"apis":"mUjGag"}