w-web-api 1.0.52 → 1.0.53
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/_gh-pages-deploy/.nojekyll +0 -0
- package/_gh-pages-deploy/WWebApi.html +898 -0
- package/_gh-pages-deploy/fonts/Montserrat/Montserrat-Bold.eot +0 -0
- package/_gh-pages-deploy/fonts/Montserrat/Montserrat-Bold.ttf +0 -0
- package/_gh-pages-deploy/fonts/Montserrat/Montserrat-Bold.woff +0 -0
- package/_gh-pages-deploy/fonts/Montserrat/Montserrat-Bold.woff2 +0 -0
- package/_gh-pages-deploy/fonts/Montserrat/Montserrat-Regular.eot +0 -0
- package/_gh-pages-deploy/fonts/Montserrat/Montserrat-Regular.ttf +0 -0
- package/_gh-pages-deploy/fonts/Montserrat/Montserrat-Regular.woff +0 -0
- package/_gh-pages-deploy/fonts/Montserrat/Montserrat-Regular.woff2 +0 -0
- package/_gh-pages-deploy/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.eot +0 -0
- package/_gh-pages-deploy/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg +978 -0
- package/_gh-pages-deploy/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.ttf +0 -0
- package/_gh-pages-deploy/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff +0 -0
- package/_gh-pages-deploy/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff2 +0 -0
- package/_gh-pages-deploy/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.eot +0 -0
- package/_gh-pages-deploy/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +1049 -0
- package/_gh-pages-deploy/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.ttf +0 -0
- package/_gh-pages-deploy/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff +0 -0
- package/_gh-pages-deploy/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff2 +0 -0
- package/_gh-pages-deploy/index.html +84 -0
- package/_gh-pages-deploy/scripts/collapse.js +39 -0
- package/_gh-pages-deploy/scripts/commonNav.js +28 -0
- package/_gh-pages-deploy/scripts/linenumber.js +25 -0
- package/_gh-pages-deploy/scripts/nav.js +12 -0
- package/_gh-pages-deploy/scripts/polyfill.js +4 -0
- package/_gh-pages-deploy/scripts/prettify/Apache-License-2.0.txt +202 -0
- package/_gh-pages-deploy/scripts/prettify/lang-css.js +2 -0
- package/_gh-pages-deploy/scripts/prettify/prettify.js +28 -0
- package/_gh-pages-deploy/scripts/search.js +99 -0
- package/{docs/WWebApi.mjs.html → _gh-pages-deploy/server_WWebApi.mjs.html} +96 -39
- package/_gh-pages-deploy/src_components_Common_CheckYesNo.vue.html +187 -0
- package/_gh-pages-deploy/styles/jsdoc.css +776 -0
- package/_gh-pages-deploy/styles/prettify.css +80 -0
- package/dist/css/app.fe69497a.css +1 -0
- package/dist/index.tmp +4 -2
- package/dist/js/app-legacy.15819aa7.js +1 -0
- package/dist/js/app.15819aa7.js +1 -0
- package/dist/js/chunk-vendors-legacy.c1a32dd1.js +15 -0
- package/dist/js/chunk-vendors.c1a32dd1.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/server_WWebApi.mjs.html +1012 -0
- package/docs/src_components_Common_CheckYesNo.vue.html +187 -0
- package/g.getSettings.mjs +3 -0
- package/package.json +15 -11
- package/public/index.html +9 -2
- package/server/WWebApi.mjs +93 -36
- package/server/procApis.mjs +62 -0
- package/server/procLang.mjs +386 -0
- package/server/procProxy.mjs +120 -0
- package/server/srLog.mjs +30 -0
- package/server/staLogs/staEvent.mjs +129 -0
- package/server/staLogs/test_staEvent.mjs +132 -0
- package/settings.json +14 -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 -7
- package/src/components/LayoutContent.vue +308 -333
- package/src/components/LayoutContentEdit.vue +577 -0
- package/src/components/LayoutContentStats.vue +485 -0
- package/src/components/LayoutContentTest.vue +799 -0
- package/src/components/MdPanel.vue +80 -58
- package/src/main.js +8 -0
- package/src/plugins/mUI.mjs +19 -4
- package/src/schema/tables/apis.mjs +30 -0
- package/srv.mjs +47 -19
- package/tableTags.json +1 -1
- 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/tableTags-web-api.json +0 -1
- package/test/all.test.mjs +0 -10
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
</template>
|
|
6
6
|
|
|
7
7
|
<script>
|
|
8
|
-
// import get from 'lodash-es/get.js'
|
|
9
|
-
// import find from 'lodash-es/find.js'
|
|
10
|
-
// import each from 'lodash-es/each.js'
|
|
11
|
-
// import map from 'lodash-es/map.js'
|
|
12
|
-
// import size from 'lodash-es/size.js'
|
|
13
|
-
// import sortBy from 'lodash-es/sortBy.js'
|
|
14
|
-
// import isNumber from 'lodash-es/isNumber.js'
|
|
15
|
-
// import cloneDeep from 'lodash-es/cloneDeep.js'
|
|
8
|
+
// import get from 'lodash-es/get.js'
|
|
9
|
+
// import find from 'lodash-es/find.js'
|
|
10
|
+
// import each from 'lodash-es/each.js'
|
|
11
|
+
// import map from 'lodash-es/map.js'
|
|
12
|
+
// import size from 'lodash-es/size.js'
|
|
13
|
+
// import sortBy from 'lodash-es/sortBy.js'
|
|
14
|
+
// import isNumber from 'lodash-es/isNumber.js'
|
|
15
|
+
// import cloneDeep from 'lodash-es/cloneDeep.js'
|
|
16
16
|
// import sep from 'wsemi/src/sep.mjs'
|
|
17
17
|
// import isobj from 'wsemi/src/isobj.mjs'
|
|
18
18
|
// import iseobj from 'wsemi/src/iseobj.mjs'
|
|
@@ -73,80 +73,102 @@ export default {
|
|
|
73
73
|
</script>
|
|
74
74
|
|
|
75
75
|
<style scoped>
|
|
76
|
+
/* Scalar 風格 markdown 渲染:無外框、細列分隔、等寬欄、名稱欄加粗、標題退場感 */
|
|
77
|
+
.md {
|
|
78
|
+
font-size: 13px;
|
|
79
|
+
color: var(--c-1, #1b1b1b);
|
|
80
|
+
}
|
|
76
81
|
|
|
77
82
|
.md >>> table {
|
|
78
83
|
border-collapse: collapse;
|
|
79
|
-
|
|
80
|
-
|
|
84
|
+
width: 100%;
|
|
85
|
+
font-size: 13px;
|
|
86
|
+
margin: 2px 0 8px;
|
|
81
87
|
word-break: initial;
|
|
82
88
|
}
|
|
83
89
|
|
|
84
|
-
.md >>> tr {
|
|
85
|
-
margin: 0;
|
|
86
|
-
padding: 0;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
90
|
.md >>> table tr th {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
91
|
+
text-align: left;
|
|
92
|
+
font-weight: 600;
|
|
93
|
+
font-size: 11.5px;
|
|
94
|
+
letter-spacing: .03em;
|
|
95
|
+
color: var(--c-2, #6b7280);
|
|
96
|
+
background: transparent;
|
|
97
|
+
border: none;
|
|
98
|
+
border-bottom: 1px solid var(--border, #e6e8ec);
|
|
94
99
|
margin: 0;
|
|
95
|
-
padding:
|
|
100
|
+
padding: 8px 18px 8px 0;
|
|
96
101
|
}
|
|
97
102
|
|
|
98
103
|
.md >>> table tr td {
|
|
99
|
-
border:
|
|
104
|
+
border: none;
|
|
105
|
+
border-bottom: 1px solid var(--border-soft, #eef0f3);
|
|
106
|
+
color: var(--c-1, #1b1b1b);
|
|
107
|
+
font-family: var(--font-code, ui-monospace, Menlo, Consolas, monospace);
|
|
108
|
+
font-size: 12.5px;
|
|
109
|
+
vertical-align: top;
|
|
100
110
|
margin: 0;
|
|
101
|
-
padding:
|
|
111
|
+
padding: 8px 18px 8px 0;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.md >>> table tbody tr:last-child td {
|
|
115
|
+
border-bottom: none;
|
|
102
116
|
}
|
|
103
117
|
|
|
104
|
-
.md >>>
|
|
105
|
-
font-weight:
|
|
106
|
-
|
|
107
|
-
line-height: 1.2rem;
|
|
108
|
-
margin-top: 0.5rem;
|
|
109
|
-
margin-bottom: 0.5rem;
|
|
118
|
+
.md >>> table tr td:first-child {
|
|
119
|
+
font-weight: 600;
|
|
120
|
+
color: var(--c-1, #1b1b1b);
|
|
110
121
|
}
|
|
111
122
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
line-height: 1.1rem;
|
|
116
|
-
margin-top: 0.5rem;
|
|
117
|
-
margin-bottom: 0.5rem;
|
|
123
|
+
/* 對齊 mockup:型別欄(第2欄)綠字、範例欄(第3欄)灰字 */
|
|
124
|
+
.md >>> table tr td:nth-child(2) {
|
|
125
|
+
color: var(--m-post, #069061);
|
|
118
126
|
}
|
|
119
127
|
|
|
120
|
-
.md >>>
|
|
121
|
-
|
|
122
|
-
font-size: 1rem;
|
|
123
|
-
line-height: 1rem;
|
|
124
|
-
margin-top: 0.5rem;
|
|
125
|
-
margin-bottom: 0.5rem;
|
|
128
|
+
.md >>> table tr td:nth-child(3) {
|
|
129
|
+
color: var(--c-2, #6b7280);
|
|
126
130
|
}
|
|
127
131
|
|
|
128
|
-
.md >>>
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
132
|
+
.md >>> h1,
|
|
133
|
+
.md >>> h2,
|
|
134
|
+
.md >>> h3,
|
|
135
|
+
.md >>> h4,
|
|
136
|
+
.md >>> h5,
|
|
137
|
+
.md >>> h6 {
|
|
138
|
+
font-weight: 600;
|
|
139
|
+
font-size: 13px;
|
|
140
|
+
line-height: 1.4;
|
|
141
|
+
color: var(--c-2, #6b7280);
|
|
142
|
+
margin: 8px 0 6px;
|
|
134
143
|
}
|
|
135
144
|
|
|
136
|
-
.md >>>
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
margin-top: 0.5rem;
|
|
141
|
-
margin-bottom: 0.5rem;
|
|
145
|
+
.md >>> p {
|
|
146
|
+
color: var(--c-2, #6b7280);
|
|
147
|
+
line-height: 1.6;
|
|
148
|
+
margin: 4px 0;
|
|
142
149
|
}
|
|
143
150
|
|
|
144
|
-
.md >>>
|
|
145
|
-
font-
|
|
146
|
-
font-size:
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
151
|
+
.md >>> code {
|
|
152
|
+
font-family: var(--font-code, ui-monospace, Menlo, Consolas, monospace);
|
|
153
|
+
font-size: 12px;
|
|
154
|
+
background: var(--bg-3, #eceef1);
|
|
155
|
+
border-radius: 4px;
|
|
156
|
+
padding: 1px 5px;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.md >>> pre {
|
|
160
|
+
font-family: var(--font-code, ui-monospace, Menlo, Consolas, monospace);
|
|
161
|
+
font-size: 12px;
|
|
162
|
+
background: var(--bg-2, #f7f8fa);
|
|
163
|
+
border: 1px solid var(--border, #e6e8ec);
|
|
164
|
+
border-radius: 8px;
|
|
165
|
+
padding: 12px 14px;
|
|
166
|
+
overflow: auto;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
.md >>> pre code {
|
|
170
|
+
background: transparent;
|
|
171
|
+
padding: 0;
|
|
150
172
|
}
|
|
151
173
|
|
|
152
174
|
</style>
|
package/src/main.js
CHANGED
|
@@ -4,6 +4,7 @@ import get from 'lodash-es/get.js'
|
|
|
4
4
|
// import 'regenerator-runtime/runtime'
|
|
5
5
|
// import 'intersection-observer' //需供Vuetify的Intersection Observer, 專案內有使用v-intersect才需引入, 而w-component-vue沒用v-intersect
|
|
6
6
|
import Vue from 'vue'
|
|
7
|
+
import './assets/scalar-ui.css'
|
|
7
8
|
import WServHapiClient from 'w-serv-hapi/src/WServHapiClient.mjs'
|
|
8
9
|
import WAlert from 'w-component-vue/src/components/WAlert.mjs'
|
|
9
10
|
import domMutation from 'w-component-vue/src/js/domMutation.mjs'
|
|
@@ -37,6 +38,13 @@ let dssm = mDataSelectorSchema(ds)
|
|
|
37
38
|
//prototype
|
|
38
39
|
Vue.prototype.$ui = ui
|
|
39
40
|
Vue.prototype.$t = ui.getKpText
|
|
41
|
+
//$transErr:後端 reject 之 err-key → 依當前 lang 反查顯示文字。
|
|
42
|
+
//非字串或查無對應 key(getKpText 查不到會原樣回 key)則 fallback 'anUnexpectedErrorOccurred',避免顯示生 key。
|
|
43
|
+
Vue.prototype.$transErr = (err) => {
|
|
44
|
+
let key = (typeof err === 'string' && err) ? err : 'anUnexpectedErrorOccurred'
|
|
45
|
+
let msg = ui.getKpText(key)
|
|
46
|
+
return (msg && msg !== key) ? msg : ui.getKpText('anUnexpectedErrorOccurred')
|
|
47
|
+
}
|
|
40
48
|
Vue.prototype.$s = s
|
|
41
49
|
Vue.prototype.$dssm = dssm
|
|
42
50
|
Vue.prototype.$ds = ds
|
package/src/plugins/mUI.mjs
CHANGED
|
@@ -132,16 +132,31 @@ function validLang(lang) {
|
|
|
132
132
|
function getLang() {
|
|
133
133
|
let lang = ''
|
|
134
134
|
|
|
135
|
-
//from
|
|
135
|
+
//from URL ?lang=(最高優先;供「以指定語系載入初始畫面」用,如分享連結 /?lang=cht,對齊 w-web-sso getLang)
|
|
136
|
+
if (!isestr(lang)) {
|
|
137
|
+
let _lang = ''
|
|
138
|
+
try {
|
|
139
|
+
_lang = new URLSearchParams(get(window, 'location.search', '')).get('lang') || ''
|
|
140
|
+
}
|
|
141
|
+
catch (err) {
|
|
142
|
+
_lang = ''
|
|
143
|
+
}
|
|
144
|
+
if (isestr(_lang)) {
|
|
145
|
+
lang = validLang(_lang) //URL 帶非預期 lang 時 validLang 退回 eng
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
//from window ___pmwperm___.language(server 注入之初始語系;對齊 w-web-sso window 注入來源)。
|
|
150
|
+
//須在 store 之前:store.state.lang 預設為非空 'eng'(mutations.mjs),若 store 在前會永遠 shadow 掉 window 注入值。
|
|
151
|
+
//dev 未注入時為模板符號 {language} → validLang 退回 eng。
|
|
136
152
|
if (!isestr(lang)) {
|
|
137
153
|
let _lang = get(window, '___pmwperm___.language', '')
|
|
138
|
-
// console.log('_lang(from window)', _lang)
|
|
139
154
|
if (isestr(_lang)) {
|
|
140
|
-
lang = validLang(_lang)
|
|
155
|
+
lang = validLang(_lang)
|
|
141
156
|
}
|
|
142
157
|
}
|
|
143
158
|
|
|
144
|
-
//from store
|
|
159
|
+
//from store(使用者執行期切換之語系;切換以 setLang(明確值) 直接寫入、其後無 setLang(null) 故能持久)
|
|
145
160
|
if (!isestr(lang)) {
|
|
146
161
|
let _lang = get(vo, '$store.state.lang', '')
|
|
147
162
|
// console.log('_lang(from store)', _lang)
|
|
@@ -86,6 +86,34 @@ let settings = {
|
|
|
86
86
|
name: '輸出範例',
|
|
87
87
|
type: 'STRING',
|
|
88
88
|
},
|
|
89
|
+
'testBaseUrl': {
|
|
90
|
+
name: '測試基底網址',
|
|
91
|
+
type: 'STRING',
|
|
92
|
+
},
|
|
93
|
+
'authType': {
|
|
94
|
+
name: '認證類型',
|
|
95
|
+
type: 'STRING',
|
|
96
|
+
},
|
|
97
|
+
'authConfigJson': {
|
|
98
|
+
name: '認證設定JSON',
|
|
99
|
+
type: 'TEXT',
|
|
100
|
+
},
|
|
101
|
+
'defaultHeadersJson': {
|
|
102
|
+
name: '預設標頭JSON',
|
|
103
|
+
type: 'TEXT',
|
|
104
|
+
},
|
|
105
|
+
'defaultQueryJson': {
|
|
106
|
+
name: '預設查詢參數JSON',
|
|
107
|
+
type: 'TEXT',
|
|
108
|
+
},
|
|
109
|
+
'defaultBodyJson': {
|
|
110
|
+
name: '預設請求內容JSON',
|
|
111
|
+
type: 'TEXT',
|
|
112
|
+
},
|
|
113
|
+
'contentType': {
|
|
114
|
+
name: '內容類型',
|
|
115
|
+
type: 'STRING',
|
|
116
|
+
},
|
|
89
117
|
'timeCreate': {
|
|
90
118
|
name: '創建時間',
|
|
91
119
|
type: 'STRING',
|
|
@@ -106,6 +134,8 @@ let funNew = (ndata = {}) => {
|
|
|
106
134
|
o.timeCreate = nowms2str()
|
|
107
135
|
o.timeUpdate = o.timeCreate
|
|
108
136
|
o.isActive = 'y'
|
|
137
|
+
o.authType = isestr(o.authType) ? o.authType : 'none'
|
|
138
|
+
o.contentType = isestr(o.contentType) ? o.contentType : 'application/json'
|
|
109
139
|
return o
|
|
110
140
|
}
|
|
111
141
|
|
package/srv.mjs
CHANGED
|
@@ -1,22 +1,44 @@
|
|
|
1
1
|
import WOrm from 'w-orm-lmdb/src/WOrmLmdb.mjs'
|
|
2
2
|
import WWebApi from './server/WWebApi.mjs'
|
|
3
3
|
import getSettings from './g.getSettings.mjs'
|
|
4
|
+
import get from 'lodash-es/get.js'
|
|
5
|
+
import iseobj from 'wsemi/src/iseobj.mjs'
|
|
6
|
+
import axios from 'axios'
|
|
7
|
+
import JSON5 from 'json5'
|
|
8
|
+
import fs from 'fs'
|
|
4
9
|
|
|
5
10
|
|
|
6
|
-
//st
|
|
11
|
+
//st(db 等系統參數由 g.getSettings 提供,供 g.mOrm 共用)
|
|
7
12
|
let st = getSettings()
|
|
8
13
|
|
|
14
|
+
//pathSettings:app 設定檔路徑,預設 ./settings.json;可由 `node srv.mjs <path>` 覆寫
|
|
15
|
+
//(供 e2e restartBackend / 部署帶不同設定,日後更細緻功能便於擴充)。settings.json 為 JSON5 格式。
|
|
16
|
+
let pathSettings = process.argv[2] || './settings.json'
|
|
17
|
+
let stApp = JSON5.parse(fs.readFileSync(pathSettings, 'utf8'))
|
|
18
|
+
|
|
9
19
|
let url = st.dbUrl
|
|
10
20
|
let db = st.dbName
|
|
21
|
+
let ssoBaseUrl = st.ssoBaseUrl
|
|
22
|
+
let ssoAppToken = st.ssoAppToken
|
|
23
|
+
let ssoLoginUrl = st.ssoLoginUrl
|
|
11
24
|
let opt = {
|
|
12
25
|
|
|
13
26
|
useCheckUser: false,
|
|
14
27
|
getUserById: null,
|
|
15
28
|
useExcludeWhenNotAdmin: false,
|
|
16
29
|
|
|
17
|
-
serverPort: 11005,
|
|
30
|
+
serverPort: get(stApp, 'serverPort', 11005),
|
|
18
31
|
subfolder: '', //mapi
|
|
19
|
-
urlRedirect:
|
|
32
|
+
urlRedirect: ssoLoginUrl, //未登入時導向SSO登入頁, 本機測試時得先編譯, 再瀏覽: http://localhost:11005/
|
|
33
|
+
|
|
34
|
+
//語系(來自 settings.json):language 由 WWebApi 注入 index.html ({language}) → 初始畫面即此語系;
|
|
35
|
+
//showLanguage 控右上語系選單顯隱。e2e 可用 restartBackend(genTempSettings({language})) 改 server 初始語系。
|
|
36
|
+
showLanguage: get(stApp, 'showLanguage', 'y'),
|
|
37
|
+
language: get(stApp, 'language', 'eng'),
|
|
38
|
+
|
|
39
|
+
//log 資料夾與輪檔間隔(srLog 寫入 + staEvent 統計皆讀此)。e2e 可用 genTempSettings({logFd}) 指向合成 log 達 hermetic。
|
|
40
|
+
logFd: get(stApp, 'logFd', './_logs'),
|
|
41
|
+
logInterval: get(stApp, 'logInterval', 'hr'),
|
|
20
42
|
|
|
21
43
|
webName: {
|
|
22
44
|
'eng': 'API Service',
|
|
@@ -32,25 +54,31 @@ let opt = {
|
|
|
32
54
|
|
|
33
55
|
let getUserByToken = async (token) => {
|
|
34
56
|
// return {} //測試無法登入
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
57
|
+
//開發階段 w-ui-loginout 於 localhost 自動給 token 'sys'
|
|
58
|
+
if (token === 'sys') {
|
|
59
|
+
return { id: 'id-for-admin', name: '測試者', email: 'admin@example.com', isAdmin: 'y' }
|
|
60
|
+
}
|
|
61
|
+
//未設定 SSO app token 時(本機開發未接SSO), 不打SSO直接拒絕
|
|
62
|
+
if (!ssoAppToken) {
|
|
63
|
+
console.log('ssoAppToken 未設定, 略過 SSO 驗證')
|
|
64
|
+
return {}
|
|
42
65
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
66
|
+
//呼叫 SSO 解析 token -> user
|
|
67
|
+
try {
|
|
68
|
+
let url = `${ssoBaseUrl}/api/getSsoUserInfor?token=${encodeURIComponent(ssoAppToken)}&key=token&value=${encodeURIComponent(token)}`
|
|
69
|
+
let res = await axios.get(url)
|
|
70
|
+
let state = get(res, 'data.state', '')
|
|
71
|
+
let u = get(res, 'data.msg', null)
|
|
72
|
+
if (state !== 'success' || !iseobj(u)) {
|
|
73
|
+
console.log('SSO getSsoUserInfor 失敗', state)
|
|
74
|
+
return {}
|
|
49
75
|
}
|
|
76
|
+
return { id: u.id, name: u.name, email: u.email, isAdmin: u.isAdmin }
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
console.log('SSO getSsoUserInfor error', err.message)
|
|
80
|
+
return {}
|
|
50
81
|
}
|
|
51
|
-
console.log('invalid token', token)
|
|
52
|
-
console.log('於生產環境時得加入SSO等驗證token機制')
|
|
53
|
-
return {}
|
|
54
82
|
}
|
|
55
83
|
|
|
56
84
|
let verifyClientUser = (user, from) => {
|
package/tableTags.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"apis":"2026-
|
|
1
|
+
{"apis":"2026-06-22T12:43:06+08:00|Yl6xfX"}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
name: Node.js CI
|
|
2
|
-
|
|
3
|
-
on: [push]
|
|
4
|
-
|
|
5
|
-
jobs:
|
|
6
|
-
build:
|
|
7
|
-
|
|
8
|
-
runs-on: ubuntu-latest
|
|
9
|
-
|
|
10
|
-
strategy:
|
|
11
|
-
matrix:
|
|
12
|
-
node-version: [22.x]
|
|
13
|
-
|
|
14
|
-
steps:
|
|
15
|
-
- uses: actions/checkout@v4
|
|
16
|
-
- name: Use Node.js ${{ matrix.node-version }}
|
|
17
|
-
uses: actions/setup-node@v1
|
|
18
|
-
with:
|
|
19
|
-
node-version: ${{ matrix.node-version }}
|
|
20
|
-
- run: npm cache clean -f
|
|
21
|
-
- run: npm install
|
|
22
|
-
- run: npm test
|
|
23
|
-
env:
|
|
24
|
-
CI: true
|
package/.vscode/launch.json
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
// 使用 IntelliSense 以得知可用的屬性。
|
|
3
|
-
// 暫留以檢視現有屬性的描述。
|
|
4
|
-
// 如需詳細資訊,請瀏覽: https://go.microsoft.com/fwlink/?linkid=830387
|
|
5
|
-
"version": "0.2.0",
|
|
6
|
-
"configurations": [
|
|
7
|
-
{
|
|
8
|
-
"type": "node",
|
|
9
|
-
"request": "launch",
|
|
10
|
-
"name": "啟動程式",
|
|
11
|
-
"skipFiles": [
|
|
12
|
-
"<node_internals>/**"
|
|
13
|
-
],
|
|
14
|
-
"program": "${workspaceFolder}/srv.mjs",
|
|
15
|
-
"runtimeArgs": []
|
|
16
|
-
}
|
|
17
|
-
]
|
|
18
|
-
}
|
package/db/wapis/apis/data.mdb
DELETED
|
Binary file
|
package/db/wapis/apis/lock.mdb
DELETED
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
.pgc-rotate[data-v-5b4e8bee]{width:100%;height:100%;margin:auto;position:absolute;top:0;bottom:0;left:0;right:0;z-index:1;-webkit-transition:all .6s ease-in-out;transition:all .6s ease-in-out;-webkit-animation:progress-circular-rotate-5b4e8bee 1.4s linear infinite;animation:progress-circular-rotate-5b4e8bee 1.4s linear infinite;-webkit-transform-origin:center center;transform-origin:center center}.pgc-dash[data-v-5b4e8bee]{-webkit-animation:progress-circular-dash-5b4e8bee 1.4s ease-in-out infinite;animation:progress-circular-dash-5b4e8bee 1.4s ease-in-out infinite;stroke-linecap:round;stroke-dasharray:80,200;stroke-dashoffset:0px}@-webkit-keyframes progress-circular-dash-5b4e8bee{0%{stroke-dasharray:1,200;stroke-dashoffset:0px}50%{stroke-dasharray:100,200;stroke-dashoffset:-15px}to{stroke-dasharray:100,200;stroke-dashoffset:-124px}}@keyframes progress-circular-dash-5b4e8bee{0%{stroke-dasharray:1,200;stroke-dashoffset:0px}50%{stroke-dasharray:100,200;stroke-dashoffset:-15px}to{stroke-dasharray:100,200;stroke-dashoffset:-124px}}@-webkit-keyframes progress-circular-rotate-5b4e8bee{to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes progress-circular-rotate-5b4e8bee{to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.WPopperFix[data-popper-reference-hidden][data-v-14d6bcb4]{visibility:hidden;pointer-events:none}.sb[data-v-6ce5bdb1]{-webkit-transition:opacity .3s;transition:opacity .3s;scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.3) transparent}.sb[data-v-6ce5bdb1]::-webkit-scrollbar{width:8px;height:8px}.sb[data-v-6ce5bdb1]::-webkit-scrollbar-track{background:transparent}.sb[data-v-6ce5bdb1]::-webkit-scrollbar-thumb{background:rgba(0,0,0,.3);border-radius:20px;border:3px solid transparent}.ts[data-v-9a483320]{-webkit-transition:all .3s cubic-bezier(.25,.8,.5,1);transition:all .3s cubic-bezier(.25,.8,.5,1)}.bs[data-v-9a483320]{-webkit-box-shadow:0 8px 2px -8px rgba(0,0,0,.3),0 16px 24px 2px rgba(0,0,0,.3),0 6px 30px 5px rgba(0,0,0,.3);box-shadow:0 8px 2px -8px rgba(0,0,0,.3),0 16px 24px 2px rgba(0,0,0,.3),0 6px 30px 5px rgba(0,0,0,.3)}.fade-enter-active[data-v-a0c94508],.fade-leave-active[data-v-a0c94508]{-webkit-transition:all .3s;transition:all .3s}.fade-enter[data-v-a0c94508],.fade-leave-to[data-v-a0c94508]{-webkit-transform:scaleX(0);transform:scaleX(0)}.fade-enter-to[data-v-a0c94508],.fade-leave[data-v-a0c94508]{-webkit-transform:scaleX(100%);transform:scaleX(100%)}.caretRight[data-v-26dfca3e]{cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;display:inline-block}.cc[data-v-26dfca3e]{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.circle[data-v-26dfca3e]{width:22px;height:22px;min-width:22px;min-height:22px;max-width:22px;max-height:22px;border-radius:50%}.md[data-v-1a0f86f5] table{border-collapse:collapse;margin:0;padding:0;word-break:normal}.md[data-v-1a0f86f5] tr{margin:0;padding:0}.md[data-v-1a0f86f5] table tr th{font-weight:700;background:#eee;border:1px solid #ddd;border-bottom:0;margin:0;padding:6px 13px}.md[data-v-1a0f86f5] table tr td{border:1px solid #ddd;margin:0;padding:6px 13px}.md[data-v-1a0f86f5] h1{font-size:1.2rem;line-height:1.2rem}.md[data-v-1a0f86f5] h1,.md[data-v-1a0f86f5] h2{font-weight:700;margin-top:.5rem;margin-bottom:.5rem}.md[data-v-1a0f86f5] h2{font-size:1.1rem;line-height:1.1rem}.md[data-v-1a0f86f5] h3,.md[data-v-1a0f86f5] h4,.md[data-v-1a0f86f5] h5,.md[data-v-1a0f86f5] h6{font-weight:700;font-size:1rem;line-height:1rem;margin-top:.5rem;margin-bottom:.5rem}.bk[data-v-56f2385e]{display:inline-block;width:200px;padding:0 10px 10px 0;vertical-align:top}.bk-title[data-v-56f2385e]{padding:3px;font-size:.8rem;color:#888}.bk-item[data-v-56f2385e]{padding:3px 5px;font-size:.9rem;line-height:.9rem;border-radius:5px;border:1px solid #ddd;background:#fff}body,html{font-family:微軟正黑體,Microsoft JhengHei,MicrosoftJhengHeiRegular,Avenir,Helvetica,Arial,sans-serif;overflow-y:hidden}a,button,div,input,p,pre,span,textarea{font-family:inherit}.fade-enter-active{-webkit-animation:go 1s;animation:go 1s}.fade-leave-active{-webkit-animation:back 1s;animation:back 1s}@-webkit-keyframes go{0%{opacity:0}to{opacity:1}}@keyframes go{0%{opacity:0}to{opacity:1}}@-webkit-keyframes back{0%{opacity:1}to{opacity:0}}@keyframes back{0%{opacity:1}to{opacity:0}}
|