w-web-api 1.0.52 → 1.0.55
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 +1 -1
- package/dist/css/app.cad4a1ca.css +1 -0
- package/dist/index.tmp +4 -2
- package/dist/js/app-legacy.7687b23b.js +1 -0
- package/dist/js/app.7687b23b.js +1 -0
- package/dist/js/chunk-vendors-legacy.4c27cf51.js +15 -0
- package/dist/js/chunk-vendors.4c27cf51.js +15 -0
- package/dist/w-web-api.umd.js +2 -2
- package/dist/w-web-api.umd.js.map +1 -1
- package/docs/WWebApi.html +2 -2
- package/docs/index.html +1 -1
- package/docs/{WWebApi.mjs.html → server_WWebApi.mjs.html} +113 -66
- package/docs/src_components_Common_CheckYesNo.vue.html +187 -0
- package/g.getSettings.mjs +3 -0
- package/logs/2026-06-19T16.log +6 -0
- package/logs/2026-06-20T11.log +4 -0
- package/logs/2026-06-20T14.log +2 -0
- package/logs/2026-06-21T20.log +1 -0
- package/logs/2026-06-21T21.log +4 -0
- package/logs/2026-06-22T07.log +12 -0
- package/logs/2026-06-22T08.log +808 -0
- package/logs/2026-06-22T09.log +104 -0
- package/logs/2026-06-22T10.log +26 -0
- package/logs/2026-06-22T11.log +860 -0
- package/logs/2026-06-22T12.log +430 -0
- package/logs/2026-06-22T23.log +1547 -0
- package/logs/2026-06-23T00.log +473 -0
- package/logs/2026-06-23T08.log +231 -0
- package/logs/2026-06-23T09.log +179 -0
- package/logs/2026-07-01T11.log +488 -0
- package/logs/2026-07-09T22.log +370 -0
- package/logs/2026-07-09T23.log +370 -0
- package/logs/2026-07-10T12.log +284 -0
- package/logs/2026-07-10T13.log +777 -0
- package/logs/2026-07-11T17.log +2 -0
- package/package.json +20 -15
- package/public/index.html +9 -2
- package/server/WWebApi.mjs +110 -63
- package/server/procApis.mjs +62 -0
- package/server/procLang.mjs +372 -66
- package/server/procProxy.mjs +120 -0
- package/server/srLog.mjs +30 -0
- package/server/staLogs/filterVpfsByWindow.mjs +27 -0
- package/server/staLogs/staEvent.mjs +131 -0
- package/server/staLogs/test_staEvent.mjs +198 -0
- package/settings.json +18 -0
- package/src/App.vue +11 -7
- package/src/assets/scalar-ui.css +113 -0
- package/src/components/Common/CheckYes.vue +102 -0
- package/src/components/Common/CheckYesNo.vue +115 -0
- package/src/components/Common/LoadingWinBar.vue +114 -0
- package/src/components/Layout.vue +8 -26
- package/src/components/LayoutContent.vue +299 -350
- package/src/components/LayoutContentEdit.vue +577 -0
- package/src/components/LayoutContentStats.vue +485 -0
- package/src/components/LayoutContentTest.vue +781 -0
- package/src/components/MdPanel.vue +80 -58
- package/src/main.js +11 -8
- package/src/plugins/mUI.mjs +19 -39
- package/src/schema/tables/apis.mjs +30 -0
- package/src/store/mutations.mjs +0 -14
- package/src/store/types.mjs +0 -3
- package/srv.mjs +50 -20
- package/tableTags.json +1 -1
- package/z/344/277/256/346/255/243/350/246/217/345/212/203/346/233/270.md +246 -0
- package/.github/workflows/ci-test.yml +0 -24
- package/.vscode/launch.json +0 -18
- package/db/wapis/apis/data.mdb +0 -0
- package/db/wapis/apis/lock.mdb +0 -0
- package/dist/css/app.b5cf2ef5.css +0 -1
- package/dist/js/app-legacy.927b5679.js +0 -1
- package/dist/js/app.927b5679.js +0 -1
- package/dist/js/chunk-vendors-legacy.ffb0c6c5.js +0 -13
- package/dist/js/chunk-vendors.ffb0c6c5.js +0 -13
- package/src/plugins/mDataSelectorSchema.mjs +0 -30
- package/src/plugins/mShare.mjs +0 -44
- package/tableTags-web-api.json +0 -1
- package/test/all.test.mjs +0 -10
package/package.json
CHANGED
|
@@ -1,40 +1,45 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "w-web-api",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.55",
|
|
4
4
|
"main": "dist/w-web-api.umd.js",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@mdi/js": "^7.4.47",
|
|
7
|
-
"axios": "^1.
|
|
8
|
-
"lodash-es": "^4.
|
|
7
|
+
"axios": "^1.18.1",
|
|
8
|
+
"lodash-es": "^4.18.1",
|
|
9
9
|
"showdown": "^2.1.0",
|
|
10
|
-
"w-component-vue": "^2.4.
|
|
11
|
-
"w-data-collector": "^1.0.
|
|
12
|
-
"w-serv-hapi": "^1.0.
|
|
13
|
-
"w-serv-orm": "^1.0.
|
|
14
|
-
"w-ui-loginout": "^1.0.
|
|
15
|
-
"
|
|
10
|
+
"w-component-vue": "^2.4.74",
|
|
11
|
+
"w-data-collector": "^1.0.23",
|
|
12
|
+
"w-serv-hapi": "^1.0.73",
|
|
13
|
+
"w-serv-orm": "^1.0.40",
|
|
14
|
+
"w-ui-loginout": "^1.0.11",
|
|
15
|
+
"w-syslog": "^1.0.10",
|
|
16
|
+
"wsemi": "^1.8.66"
|
|
16
17
|
},
|
|
17
18
|
"devDependencies": {
|
|
18
19
|
"@vue/cli-plugin-babel": "^5.0.8",
|
|
19
20
|
"@vue/cli-plugin-eslint": "^5.0.8",
|
|
20
21
|
"@vue/cli-service": "^5.0.8",
|
|
21
22
|
"eslint": "^8.37.0",
|
|
22
|
-
"eslint-config-standard": "^17.
|
|
23
|
+
"eslint-config-standard": "^17.1.0",
|
|
23
24
|
"eslint-friendly-formatter": "^4.0.1",
|
|
24
25
|
"eslint-plugin-import": "^2.27.5",
|
|
25
|
-
"eslint-plugin-
|
|
26
|
+
"eslint-plugin-n": "^16.6.2",
|
|
26
27
|
"eslint-plugin-promise": "^6.1.1",
|
|
27
|
-
"eslint-plugin-standard": "^4.1.0",
|
|
28
28
|
"eslint-plugin-vue": "^9.10.0",
|
|
29
|
+
"pixelmatch": "^7.2.0",
|
|
30
|
+
"playwright": "^1.61.1",
|
|
31
|
+
"pngjs": "^7.0.0",
|
|
29
32
|
"vue": "^2.6.14",
|
|
30
33
|
"vuex": "^3.6.2",
|
|
31
|
-
"w-orm-lmdb": "^1.0.
|
|
32
|
-
"w-
|
|
34
|
+
"w-orm-lmdb": "^1.0.8",
|
|
35
|
+
"w-screenctl": "^1.0.4",
|
|
36
|
+
"w-package-tools": "^1.1.11"
|
|
33
37
|
},
|
|
34
38
|
"scripts": {
|
|
35
39
|
"serve": "vue-cli-service serve",
|
|
36
40
|
"build": "vue-cli-service build",
|
|
37
|
-
"test": "
|
|
41
|
+
"test:unit": "node server/staLogs/test_staEvent.mjs",
|
|
42
|
+
"test": "node server/staLogs/test_staEvent.mjs && mocha --timeout 300000",
|
|
38
43
|
"lint": "vue-cli-service lint",
|
|
39
44
|
"deploy": "gh-pages -d docs"
|
|
40
45
|
},
|
package/public/index.html
CHANGED
|
@@ -7,10 +7,10 @@
|
|
|
7
7
|
<title></title>
|
|
8
8
|
|
|
9
9
|
<!-- mdi font -->
|
|
10
|
-
<link
|
|
10
|
+
<link _href="https://cdn.jsdelivr.net/npm/@mdi/font@7.4.47/css/materialdesignicons.min.css" rel="stylesheet">
|
|
11
11
|
|
|
12
12
|
<!-- fontawesome -->
|
|
13
|
-
<link
|
|
13
|
+
<link _href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.4.2/css/all.min.css" rel="stylesheet">
|
|
14
14
|
|
|
15
15
|
<!-- ___pmwapi___ -->
|
|
16
16
|
<script>
|
|
@@ -19,6 +19,13 @@
|
|
|
19
19
|
}
|
|
20
20
|
</script>
|
|
21
21
|
|
|
22
|
+
<!-- ___pmwperm___ -->
|
|
23
|
+
<script>
|
|
24
|
+
window.___pmwperm___={
|
|
25
|
+
language: '{language}',
|
|
26
|
+
}
|
|
27
|
+
</script>
|
|
28
|
+
|
|
22
29
|
</head>
|
|
23
30
|
<body style="font-family:'Microsoft JhengHei','Avenir','Helvetica', 'Arial', 'sans-serif'; padding:0px; margin:0px;">
|
|
24
31
|
<noscript>
|
package/server/WWebApi.mjs
CHANGED
|
@@ -26,6 +26,10 @@ import replace from 'wsemi/src/replace.mjs'
|
|
|
26
26
|
import WServHapiServer from 'w-serv-hapi/src/WServHapiServer.mjs'
|
|
27
27
|
import WServOrm from 'w-serv-orm/src/WServOrm.mjs'
|
|
28
28
|
import procLang from './procLang.mjs'
|
|
29
|
+
import procProxy from './procProxy.mjs'
|
|
30
|
+
import procApis from './procApis.mjs'
|
|
31
|
+
import staEvent from './staLogs/staEvent.mjs'
|
|
32
|
+
import srLogInit from './srLog.mjs'
|
|
29
33
|
import ds from '../src/schema/index.mjs'
|
|
30
34
|
|
|
31
35
|
|
|
@@ -226,6 +230,7 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyClientUser, verifyAppUser,
|
|
|
226
230
|
//params
|
|
227
231
|
let showLanguage = get(opt, 'showLanguage', 'y')
|
|
228
232
|
let language = get(opt, 'language', 'eng')
|
|
233
|
+
let logFd = get(opt, 'logFd', './logs') //srLog 寫入 + staEvent 統計共用之 log 資料夾
|
|
229
234
|
|
|
230
235
|
|
|
231
236
|
//kpLangExt
|
|
@@ -247,11 +252,45 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyClientUser, verifyAppUser,
|
|
|
247
252
|
wp = WServOrm(ds, WOrm, url, db, optWServOrm)
|
|
248
253
|
}
|
|
249
254
|
catch (err) {
|
|
250
|
-
|
|
255
|
+
//ORM 為必要依賴:初始化失敗即 fail-fast,不以 wp={} 帶 undefined woItems/procOrm 殘缺啟動(與建構子其餘必要依賴一致)
|
|
256
|
+
console.log('WServOrm init failed', err)
|
|
257
|
+
throw err
|
|
251
258
|
}
|
|
252
259
|
let { woItems, procOrm } = wp
|
|
253
260
|
|
|
254
261
|
|
|
262
|
+
//srLog(後端 log;錯誤一律 log err-key 供識別,對齊 w-web-sso)
|
|
263
|
+
let srLog = srLogInit(opt)
|
|
264
|
+
|
|
265
|
+
//maskTok:debug console.log 不印完整 token/authorization(憑證),僅前 4 碼 + ***,避免憑證落入 stdout
|
|
266
|
+
let maskTok = (t) => isestr(t) ? (strleft(t, 4) + '***') : t
|
|
267
|
+
|
|
268
|
+
//kpFunExt 邊界統一處理:成功記 info(供 staEvent 統計呼叫頻率);catch 後端錯誤 → srLog 該 err-key →
|
|
269
|
+
//原樣 re-reject(前端依 key 查自己 lang 顯示)。event 統一加 'kpfun-' 前綴 → 專用事件、與 api/verifyConn 區分。
|
|
270
|
+
let wrapErrLog = (event, fn) => {
|
|
271
|
+
let ev = 'kpfun-' + event
|
|
272
|
+
return async (...args) => {
|
|
273
|
+
try {
|
|
274
|
+
let result = await fn(...args)
|
|
275
|
+
srLog.info({ event: ev }) //成功也記 info
|
|
276
|
+
return result
|
|
277
|
+
}
|
|
278
|
+
catch (err) {
|
|
279
|
+
srLog.error({ event: ev, err })
|
|
280
|
+
return Promise.reject(err)
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
//procProxy
|
|
287
|
+
let { proxyRequest } = procProxy({ srLog })
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
//procApis
|
|
291
|
+
let { getApisList, saveApi, deleteApi } = procApis({ woItems, procOrm, ds })
|
|
292
|
+
|
|
293
|
+
|
|
255
294
|
//getWebInfor
|
|
256
295
|
let getWebInfor = (userId) => {
|
|
257
296
|
return {
|
|
@@ -274,26 +313,26 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyClientUser, verifyAppUser,
|
|
|
274
313
|
if (!isestr(id)) {
|
|
275
314
|
console.log('user', user)
|
|
276
315
|
console.log('can not get the userId')
|
|
277
|
-
return Promise.reject(
|
|
316
|
+
return Promise.reject('errUserIdMissing')
|
|
278
317
|
}
|
|
279
318
|
let email = get(user, 'email', '')
|
|
280
319
|
if (!isestr(email)) {
|
|
281
320
|
console.log('user', user)
|
|
282
321
|
console.log('can not get the email of user')
|
|
283
|
-
return Promise.reject(
|
|
322
|
+
return Promise.reject('errUserEmailMissing')
|
|
284
323
|
}
|
|
285
324
|
let name = get(user, 'name', '')
|
|
286
325
|
if (!isestr(name)) {
|
|
287
326
|
console.log('user', user)
|
|
288
327
|
console.log('can not get userName')
|
|
289
|
-
return Promise.reject(
|
|
328
|
+
return Promise.reject('errUserNameMissing')
|
|
290
329
|
}
|
|
291
330
|
let isAdmin = get(user, 'isAdmin', '')
|
|
292
331
|
if (isAdmin !== 'y' && isAdmin !== 'n') {
|
|
293
332
|
console.log('user', user)
|
|
294
333
|
console.log('user.isAdmin is not y or n', user.isAdmin)
|
|
295
334
|
console.log('can not get the role of user')
|
|
296
|
-
return Promise.reject(
|
|
335
|
+
return Promise.reject('errUserRoleMissing')
|
|
297
336
|
}
|
|
298
337
|
return true
|
|
299
338
|
}
|
|
@@ -309,14 +348,7 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyClientUser, verifyAppUser,
|
|
|
309
348
|
}
|
|
310
349
|
|
|
311
350
|
//check
|
|
312
|
-
|
|
313
|
-
// if (!iseobj(userSelf)) {
|
|
314
|
-
// console.log(`token`, token)
|
|
315
|
-
// console.log(`can not find the user from token`)
|
|
316
|
-
// return Promise.reject(`can not find the user from token`)
|
|
317
|
-
// }
|
|
318
|
-
await checkUser(userSelf)
|
|
319
|
-
}
|
|
351
|
+
await checkUser(userSelf)
|
|
320
352
|
|
|
321
353
|
return userSelf
|
|
322
354
|
}
|
|
@@ -355,9 +387,10 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyClientUser, verifyAppUser,
|
|
|
355
387
|
if (!b) {
|
|
356
388
|
console.log('user', user)
|
|
357
389
|
console.log(`user does not have permission`)
|
|
358
|
-
return Promise.reject(
|
|
390
|
+
return Promise.reject('errUserNoPermission')
|
|
359
391
|
}
|
|
360
392
|
|
|
393
|
+
srLog.info({ event: 'verifyClientUser', from, userId: get(user, 'id', '') }) //瀏覽使用者驗證通過
|
|
361
394
|
return user
|
|
362
395
|
}
|
|
363
396
|
|
|
@@ -380,7 +413,7 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyClientUser, verifyAppUser,
|
|
|
380
413
|
if (!iseobj(user)) {
|
|
381
414
|
console.log(`token`, token)
|
|
382
415
|
console.log(`can not find the user from token`)
|
|
383
|
-
return Promise.reject(
|
|
416
|
+
return Promise.reject('errUserNotFound')
|
|
384
417
|
}
|
|
385
418
|
|
|
386
419
|
//verifyAppUser
|
|
@@ -393,9 +426,10 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyClientUser, verifyAppUser,
|
|
|
393
426
|
if (!b) {
|
|
394
427
|
console.log('user', user)
|
|
395
428
|
console.log(`user does not have permission`)
|
|
396
|
-
return Promise.reject(
|
|
429
|
+
return Promise.reject('errUserNoPermission')
|
|
397
430
|
}
|
|
398
431
|
|
|
432
|
+
srLog.info({ event: 'verifyAppUser', from, userId: get(user, 'id', '') }) //應用程式使用者驗證通過
|
|
399
433
|
return user
|
|
400
434
|
}
|
|
401
435
|
|
|
@@ -422,7 +456,7 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyClientUser, verifyAppUser,
|
|
|
422
456
|
if (!iseobj(payload)) {
|
|
423
457
|
console.log('payload', payload)
|
|
424
458
|
console.log(`invalid payload in req`)
|
|
425
|
-
return Promise.reject(
|
|
459
|
+
return Promise.reject('errPayloadInvalid')
|
|
426
460
|
}
|
|
427
461
|
|
|
428
462
|
//group
|
|
@@ -432,7 +466,7 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyClientUser, verifyAppUser,
|
|
|
432
466
|
if (!isestr(group)) {
|
|
433
467
|
console.log('payload', payload)
|
|
434
468
|
console.log(`invalid group in payload`)
|
|
435
|
-
return Promise.reject(
|
|
469
|
+
return Promise.reject('errGroupInvalid')
|
|
436
470
|
}
|
|
437
471
|
|
|
438
472
|
//rows
|
|
@@ -442,7 +476,7 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyClientUser, verifyAppUser,
|
|
|
442
476
|
if (!isearr(rows)) {
|
|
443
477
|
console.log('payload', payload)
|
|
444
478
|
console.log(`invalid rows in payload`)
|
|
445
|
-
return Promise.reject(
|
|
479
|
+
return Promise.reject('errRowsInvalid')
|
|
446
480
|
}
|
|
447
481
|
|
|
448
482
|
//r
|
|
@@ -482,7 +516,7 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyClientUser, verifyAppUser,
|
|
|
482
516
|
console.log('inp', inp)
|
|
483
517
|
console.log('group', group)
|
|
484
518
|
console.log(`invalid group`)
|
|
485
|
-
return Promise.reject(
|
|
519
|
+
return Promise.reject('errGroupInvalid')
|
|
486
520
|
}
|
|
487
521
|
|
|
488
522
|
//rows
|
|
@@ -493,7 +527,7 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyClientUser, verifyAppUser,
|
|
|
493
527
|
if (!isearr(rows)) {
|
|
494
528
|
console.log('inp', inp)
|
|
495
529
|
console.log('keyTable', keyTable)
|
|
496
|
-
return Promise.reject(
|
|
530
|
+
return Promise.reject('errRowsInvalid')
|
|
497
531
|
}
|
|
498
532
|
|
|
499
533
|
//save from
|
|
@@ -564,6 +598,7 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyClientUser, verifyAppUser,
|
|
|
564
598
|
c = replace(c, '/mapi/', '{sfd}/') //方法同genEntry
|
|
565
599
|
c = replace(c, '{sfd}', subfolder)
|
|
566
600
|
c = replace(c, '{urlRedirect}', urlRedirect)
|
|
601
|
+
c = replace(c, '{language}', language) //注入初始語系 → window.___pmwperm___.language(前端 getLang 之來源之一)
|
|
567
602
|
fs.writeFileSync(fpEntryOut, c, 'utf8')
|
|
568
603
|
}
|
|
569
604
|
catch (err) {
|
|
@@ -589,10 +624,9 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyClientUser, verifyAppUser,
|
|
|
589
624
|
//check
|
|
590
625
|
if (!isestr(token)) {
|
|
591
626
|
console.log('req.query', get(req, 'query'))
|
|
592
|
-
console.log('token', token)
|
|
627
|
+
console.log('token', maskTok(token))
|
|
593
628
|
console.log('[API]getUserByToken/check token: invalid token')
|
|
594
|
-
|
|
595
|
-
return Promise.reject(`token does not have permission`)
|
|
629
|
+
return Promise.reject('errTokenNoPermission')
|
|
596
630
|
}
|
|
597
631
|
|
|
598
632
|
//getAndVerifyClientUser
|
|
@@ -600,12 +634,12 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyClientUser, verifyAppUser,
|
|
|
600
634
|
|
|
601
635
|
//check
|
|
602
636
|
if (!iseobj(user)) {
|
|
603
|
-
console.log('token', token)
|
|
637
|
+
console.log('token', maskTok(token))
|
|
604
638
|
console.log('[API]getUserByToken/check user: invalid user')
|
|
605
|
-
|
|
606
|
-
return Promise.reject(`token does not have permission`)
|
|
639
|
+
return Promise.reject('errTokenNoPermission')
|
|
607
640
|
}
|
|
608
641
|
|
|
642
|
+
srLog.info({ event: 'api/getUserByToken', userId: get(user, 'id', '') })
|
|
609
643
|
return user
|
|
610
644
|
}
|
|
611
645
|
|
|
@@ -636,8 +670,7 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyClientUser, verifyAppUser,
|
|
|
636
670
|
// console.log('req.query', get(req, 'query'))
|
|
637
671
|
// console.log('token', token)
|
|
638
672
|
// console.log('[API]getAPIsList/check token: invalid token')
|
|
639
|
-
//
|
|
640
|
-
// return Promise.reject(`token does not have permission`)
|
|
673
|
+
// return Promise.reject('errTokenNoPermission')
|
|
641
674
|
// }
|
|
642
675
|
|
|
643
676
|
// //getAndVerifyClientUser
|
|
@@ -647,8 +680,7 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyClientUser, verifyAppUser,
|
|
|
647
680
|
// if (!iseobj(user)) {
|
|
648
681
|
// console.log('token', token)
|
|
649
682
|
// console.log('[API]getAPIsList/check user: invalid user')
|
|
650
|
-
//
|
|
651
|
-
// return Promise.reject(`token does not have permission`)
|
|
683
|
+
// return Promise.reject('errTokenNoPermission')
|
|
652
684
|
// }
|
|
653
685
|
|
|
654
686
|
// //getAPIsList
|
|
@@ -685,8 +717,7 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyClientUser, verifyAppUser,
|
|
|
685
717
|
// console.log('req.query', get(req, 'query'))
|
|
686
718
|
// console.log('token', token)
|
|
687
719
|
// console.log('[API]updateAPIs/check token: invalid token')
|
|
688
|
-
//
|
|
689
|
-
// return Promise.reject(`token does not have permission`)
|
|
720
|
+
// return Promise.reject('errTokenNoPermission')
|
|
690
721
|
// }
|
|
691
722
|
|
|
692
723
|
// //getAndVerifyClientUser
|
|
@@ -696,8 +727,7 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyClientUser, verifyAppUser,
|
|
|
696
727
|
// if (!iseobj(user)) {
|
|
697
728
|
// console.log('token', token)
|
|
698
729
|
// console.log('[API]updateAPIs/check user: invalid user')
|
|
699
|
-
//
|
|
700
|
-
// return Promise.reject(`token does not have permission`)
|
|
730
|
+
// return Promise.reject('errTokenNoPermission')
|
|
701
731
|
// }
|
|
702
732
|
|
|
703
733
|
// //parsePayload
|
|
@@ -735,10 +765,9 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyClientUser, verifyAppUser,
|
|
|
735
765
|
//check
|
|
736
766
|
if (!isestr(token)) {
|
|
737
767
|
console.log('req.query', get(req, 'query'))
|
|
738
|
-
console.log('token', token)
|
|
768
|
+
console.log('token', maskTok(token))
|
|
739
769
|
console.log('[API]syncAndReplaceTabs/check token: invalid token')
|
|
740
|
-
|
|
741
|
-
return Promise.reject(`token does not have permission`)
|
|
770
|
+
return Promise.reject('errTokenNoPermission')
|
|
742
771
|
}
|
|
743
772
|
|
|
744
773
|
//keyTable
|
|
@@ -749,15 +778,14 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyClientUser, verifyAppUser,
|
|
|
749
778
|
console.log('req.query', get(req, 'query'))
|
|
750
779
|
console.log('keyTable', keyTable)
|
|
751
780
|
console.log('[API]syncAndReplaceTabs/check keyTable: invalid keyTable')
|
|
752
|
-
|
|
753
|
-
return Promise.reject(`token does not have permission`)
|
|
781
|
+
return Promise.reject('errKeyTableInvalid')
|
|
754
782
|
}
|
|
755
783
|
|
|
756
784
|
//check keyTable
|
|
757
785
|
let allowedTables = ['apis']
|
|
758
786
|
if (!allowedTables.includes(keyTable)) {
|
|
759
787
|
console.log('[API]syncAndReplaceTabs/check keyTable: unexpected keyTable', keyTable)
|
|
760
|
-
return Promise.reject(
|
|
788
|
+
return Promise.reject('errKeyTableInvalid')
|
|
761
789
|
}
|
|
762
790
|
|
|
763
791
|
//getAndVerifyAppUser
|
|
@@ -765,10 +793,9 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyClientUser, verifyAppUser,
|
|
|
765
793
|
|
|
766
794
|
//check
|
|
767
795
|
if (!iseobj(user)) {
|
|
768
|
-
console.log('token', token)
|
|
796
|
+
console.log('token', maskTok(token))
|
|
769
797
|
console.log('[API]syncAndReplaceTabs/check user: invalid user')
|
|
770
|
-
|
|
771
|
-
return Promise.reject(`token does not have permission`)
|
|
798
|
+
return Promise.reject('errTokenNoPermission')
|
|
772
799
|
}
|
|
773
800
|
|
|
774
801
|
//userId
|
|
@@ -776,11 +803,10 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyClientUser, verifyAppUser,
|
|
|
776
803
|
|
|
777
804
|
//check userId
|
|
778
805
|
if (!isestr(userId)) {
|
|
779
|
-
console.log('token', token)
|
|
806
|
+
console.log('token', maskTok(token))
|
|
780
807
|
console.log('user', user)
|
|
781
808
|
console.log('[API]syncAndReplaceTabs/check userId: invalid userId')
|
|
782
|
-
|
|
783
|
-
return Promise.reject(`token does not have permission`)
|
|
809
|
+
return Promise.reject('errTokenNoPermission')
|
|
784
810
|
}
|
|
785
811
|
|
|
786
812
|
//parsePayload
|
|
@@ -789,6 +815,7 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyClientUser, verifyAppUser,
|
|
|
789
815
|
//syncAndReplaceTabs
|
|
790
816
|
let r = await syncAndReplaceTabs(userId, inp, keyTable)
|
|
791
817
|
|
|
818
|
+
srLog.info({ event: 'api/syncAndReplaceTabs', userId, keyTable })
|
|
792
819
|
return r
|
|
793
820
|
}
|
|
794
821
|
|
|
@@ -816,7 +843,7 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyClientUser, verifyAppUser,
|
|
|
816
843
|
|
|
817
844
|
//WServHapiServer
|
|
818
845
|
instWServHapiServer = new WServHapiServer({
|
|
819
|
-
port:
|
|
846
|
+
port: serverPort,
|
|
820
847
|
pathStaticFiles,
|
|
821
848
|
apiName: 'api',
|
|
822
849
|
apis,
|
|
@@ -831,28 +858,28 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyClientUser, verifyAppUser,
|
|
|
831
858
|
//check
|
|
832
859
|
if (!isestr(token)) {
|
|
833
860
|
console.log('apiType', apiType)
|
|
834
|
-
console.log('authorization', authorization)
|
|
861
|
+
console.log('authorization', maskTok(authorization))
|
|
835
862
|
console.log('invalid token')
|
|
836
863
|
return false
|
|
837
864
|
}
|
|
838
865
|
|
|
839
|
-
//checkToken
|
|
866
|
+
//checkToken:套件層連線閘僅做「token 認證」(解析 user + 驗欄位齊備)。**授權**(如限管理員)屬
|
|
867
|
+
//套件使用者之責——由其提供之 getUserByToken(可對非授權者回 {})/ verifyClientUser / verifyAppUser,
|
|
868
|
+
//或 WServOrm 之 useCheckUser/useExcludeWhenNotAdmin 等鉤子決定;套件不對連線層強加特定授權政策(避免越界、
|
|
869
|
+
//保留使用者彈性)。詳見 spec/設計要點與取捨.md「套件授權責任」。
|
|
840
870
|
let b = await p.checkToken(token)
|
|
841
|
-
// console.log('b', b)
|
|
842
871
|
|
|
872
|
+
srLog.info({ event: 'verifyConn', apiType }) //連線之 token 認證通過(checkToken 失敗會 throw 不到此)
|
|
843
873
|
return b
|
|
844
874
|
},
|
|
845
875
|
getUserIdByToken: async (token) => { //可使用async或sync函數
|
|
846
876
|
// console.log('getUserIdByToken', token)
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
// return Promise.reject(`can not find user.id`)
|
|
854
|
-
// }
|
|
855
|
-
// return userId
|
|
877
|
+
if (!isestr(token)) {
|
|
878
|
+
return ''
|
|
879
|
+
}
|
|
880
|
+
let user = await getUserByToken(token)
|
|
881
|
+
let userId = get(user, 'id', '')
|
|
882
|
+
return userId
|
|
856
883
|
},
|
|
857
884
|
useDbOrm: true,
|
|
858
885
|
kpOrm: woItems,
|
|
@@ -860,9 +887,29 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyClientUser, verifyAppUser,
|
|
|
860
887
|
tableNamesExec,
|
|
861
888
|
methodsExec: ['select', 'insert', 'save', 'del'], //mix需於procOrm內註冊以提供
|
|
862
889
|
tableNamesSync,
|
|
863
|
-
kpFunExt: { //接收參數第1個為userId,
|
|
864
|
-
|
|
865
|
-
getWebInfor,
|
|
890
|
+
kpFunExt: { //接收參數第1個為userId, 之後才是前端給予參數(皆經 wrapErrLog:錯誤 srLog err-key 後 re-reject)
|
|
891
|
+
|
|
892
|
+
getWebInfor: wrapErrLog('getWebInfor', getWebInfor),
|
|
893
|
+
|
|
894
|
+
proxyRequest: wrapErrLog('proxyRequest', (userId, reqSpec) => {
|
|
895
|
+
return proxyRequest(reqSpec)
|
|
896
|
+
}),
|
|
897
|
+
|
|
898
|
+
getApisList: wrapErrLog('getApisList', (userId) => {
|
|
899
|
+
return getApisList(userId)
|
|
900
|
+
}),
|
|
901
|
+
saveApi: wrapErrLog('saveApi', (userId, row) => {
|
|
902
|
+
return saveApi(userId, row)
|
|
903
|
+
}),
|
|
904
|
+
deleteApi: wrapErrLog('deleteApi', (userId, id) => {
|
|
905
|
+
return deleteApi(userId, id)
|
|
906
|
+
}),
|
|
907
|
+
|
|
908
|
+
//統計資訊頁:回傳各 event 之時段發生頻率(讀 logFd 之 log)。連線之 token 認證由 verifyConn 把關;
|
|
909
|
+
//授權(限管理員)屬套件使用者責任(見 verifyConn 註解與設計要點與取捨「套件授權責任」)。timeLength 天數 / timeInterval 'hr'|'day'。
|
|
910
|
+
getStaEvent: wrapErrLog('getStaEvent', (userId, timeLength = 7, timeInterval = 'hr') => {
|
|
911
|
+
return staEvent(timeLength, timeInterval, { fdLog: logFd })
|
|
912
|
+
}),
|
|
866
913
|
|
|
867
914
|
// getAPIsList: (userId, query = {}) => { //待提供api管理系統界面使用
|
|
868
915
|
// return getAPIsList(query)
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import iseobj from 'wsemi/src/iseobj.mjs'
|
|
2
|
+
import isestr from 'wsemi/src/isestr.mjs'
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
function procApis(deps = {}) {
|
|
6
|
+
|
|
7
|
+
//deps
|
|
8
|
+
let { woItems, procOrm, ds } = deps
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
let getApisList = async (userId) => {
|
|
12
|
+
return await woItems.apis.select({})
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
let saveApi = async (userId, row) => {
|
|
17
|
+
|
|
18
|
+
//check(reject err-key,由前端依 lang 反查顯示;邊界 kpFunExt 會 srLog 此 key)
|
|
19
|
+
if (!iseobj(row)) {
|
|
20
|
+
return Promise.reject('errApiRowInvalid')
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
//正規化:funNew 配 id/時間/預設並過濾欄位
|
|
24
|
+
let o = ds.apis.funNew(row)
|
|
25
|
+
|
|
26
|
+
//保留原 id 與創建時間(既有筆)
|
|
27
|
+
if (isestr(row.id)) {
|
|
28
|
+
o.id = row.id
|
|
29
|
+
if (isestr(row.timeCreate)) {
|
|
30
|
+
o.timeCreate = row.timeCreate
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
//save
|
|
35
|
+
let r = await procOrm(userId, 'apis', 'save', [o])
|
|
36
|
+
|
|
37
|
+
return r
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
let deleteApi = async (userId, id) => {
|
|
42
|
+
|
|
43
|
+
//check(reject err-key,由前端依 lang 反查顯示)
|
|
44
|
+
if (!isestr(id)) {
|
|
45
|
+
return Promise.reject('errApiIdInvalid')
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
let r = await procOrm(userId, 'apis', 'del', { id })
|
|
49
|
+
|
|
50
|
+
return r
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
getApisList,
|
|
56
|
+
saveApi,
|
|
57
|
+
deleteApi,
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
export default procApis
|