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.
- package/README.md +23 -16
- package/dist/css/app.d38a4241.css +1 -0
- package/dist/index.tmp +1 -1
- package/dist/js/app-legacy.86198344.js +2 -0
- package/dist/js/app-legacy.86198344.js.map +1 -0
- package/dist/js/app.86198344.js +2 -0
- package/dist/js/app.86198344.js.map +1 -0
- package/dist/js/chunk-vendors-legacy.c0c4267e.js +14 -0
- package/dist/js/chunk-vendors-legacy.c0c4267e.js.map +1 -0
- package/dist/js/chunk-vendors.c0c4267e.js +14 -0
- package/dist/js/chunk-vendors.c0c4267e.js.map +1 -0
- package/dist/w-web-api.umd.js +2 -2
- package/dist/w-web-api.umd.js.map +1 -1
- package/docs/WWebApi.html +4 -4
- package/docs/WWebApi.mjs.html +167 -64
- package/docs/index.html +1 -1
- package/{g.mDb.mjs → g.backupDb.mjs} +1 -1
- package/{g.mInitialTestData.mjs → g.initialTestData.mjs} +1 -1
- package/package.json +5 -10
- package/public/index.html +1 -1
- package/server/WWebApi.mjs +166 -63
- package/server/provideApis.mjs +2 -2
- package/src/App.vue +1 -8
- package/src/components/Layout.vue +2 -2
- package/src/components/LayoutContent.vue +634 -25
- package/src/main.js +0 -2
- package/src/store/mutations.mjs +13 -0
- package/srv.mjs +21 -12
- package/tableTags-web-api.json +1 -1
- package/vue.config.js +1 -1
- package/dist/css/app.e645631b.css +0 -1
- package/dist/css/chunk-vendors.ca61ed63.css +0 -5
- package/dist/js/app-legacy.4bcebb66.js +0 -2
- package/dist/js/app-legacy.4bcebb66.js.map +0 -1
- package/dist/js/app.8115e31a.js +0 -2
- package/dist/js/app.8115e31a.js.map +0 -1
- package/dist/js/chunk-vendors-legacy.0b4288c4.js +0 -14
- package/dist/js/chunk-vendors-legacy.0b4288c4.js.map +0 -1
- package/dist/js/chunk-vendors.0b4288c4.js +0 -14
- package/dist/js/chunk-vendors.0b4288c4.js.map +0 -1
- package/src/components/LayoutContentList.vue +0 -589
- package/src/plugins/mVuetify.mjs +0 -12
package/server/WWebApi.mjs
CHANGED
|
@@ -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
|
-
*
|
|
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: '', //
|
|
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
|
-
//
|
|
192
|
-
let
|
|
224
|
+
//getTokenUserForSelf
|
|
225
|
+
let getTokenUserForSelf = async (token) => {
|
|
193
226
|
|
|
194
227
|
//getUserByToken
|
|
195
|
-
let
|
|
196
|
-
if (ispm(
|
|
197
|
-
|
|
228
|
+
let userSelf = getUserByToken(token)
|
|
229
|
+
if (ispm(userSelf)) {
|
|
230
|
+
userSelf = await userSelf
|
|
198
231
|
}
|
|
199
|
-
|
|
200
|
-
|
|
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(
|
|
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
|
|
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
|
-
//
|
|
234
|
-
if (iseobj(inp)) {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
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
|
-
|
|
257
|
-
|
|
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
|
-
|
|
261
|
-
|
|
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
|
-
//
|
|
284
|
-
let
|
|
341
|
+
//syncAndReplaceApis
|
|
342
|
+
let syncAndReplaceApis = async (params) => {
|
|
285
343
|
|
|
286
|
-
//
|
|
287
|
-
let
|
|
344
|
+
//group
|
|
345
|
+
let group = get(params, 'group', '')
|
|
288
346
|
// console.log('group', group)
|
|
289
|
-
|
|
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(
|
|
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
|
-
//
|
|
358
|
-
let user = await
|
|
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
|
-
//
|
|
382
|
-
await
|
|
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
|
-
//
|
|
410
|
-
await
|
|
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: '/
|
|
526
|
+
path: '/syncAndReplaceApis',
|
|
431
527
|
handler: async function (req, res) {
|
|
432
|
-
// console.log('
|
|
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
|
-
//
|
|
441
|
-
await
|
|
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
|
-
//
|
|
447
|
-
let r = await
|
|
549
|
+
//syncAndReplaceApis
|
|
550
|
+
let r = await syncAndReplaceApis(inp)
|
|
448
551
|
|
|
449
552
|
return r
|
|
450
553
|
}
|
package/server/provideApis.mjs
CHANGED
|
@@ -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/
|
|
8
|
-
//group: 指API
|
|
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
|
-
|
|
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>
|