w-web-sso 1.1.4 → 1.1.5
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 +45 -1
- package/dist/css/{app.f3340e10.css → app.ca802c2f.css} +1 -1
- package/dist/css/{chunk-vendors.fb994638.css → chunk-vendors.08637abb.css} +1 -1
- package/dist/index.tmp +2 -2
- package/dist/js/app-legacy.0f41cc7e.js +1 -0
- package/dist/js/app.0f41cc7e.js +1 -0
- package/dist/js/{chunk-vendors-legacy.1b21d2c1.js → chunk-vendors-legacy.e06dd3c7.js} +3 -18
- package/dist/js/{chunk-vendors.1b21d2c1.js → chunk-vendors.e06dd3c7.js} +3 -18
- package/dist/w-web-sso.umd.js +4 -4
- package/dist/w-web-sso.umd.js.map +1 -1
- package/docs/WWebSso.html +2 -2
- package/docs/global.html +706 -4
- package/docs/index.html +2 -2
- package/docs/server_WWebSso.mjs.html +30 -26
- package/docs/src_components_Common_CheckYesNo.vue.html +2 -2
- package/docs/src_fetchSsoMsg.mjs.html +211 -0
- package/docs/src_httpGetJson.mjs.html +7 -5
- package/docs/src_maskUrl.mjs.html +112 -0
- package/g_initialData.mjs +1 -0
- package/package.json +5 -5
- package/public/index.html +2 -0
- package/server/WWebSso.mjs +28 -24
- package/server/procCore.mjs +115 -23
- package/server/procLang.mjs +104 -0
- package/server/procProtect.mjs +2 -2
- package/server/procStaInfor.mjs +1 -1
- package/server/srLog.mjs +37 -2
- package/src/appPerms.mjs +88 -0
- package/src/components/AppPermsTags.vue +133 -0
- package/src/components/LayoutContentTokens.vue +210 -1
- package/src/fetchSsoMsg.mjs +139 -0
- package/src/getUserByToken.mjs +49 -101
- package/src/getUserByUserId.mjs +49 -101
- package/src/getUsersByToken.mjs +52 -102
- package/src/httpGetJson.mjs +5 -3
- package/src/maskUrl.mjs +40 -0
- package/src/schema/tables/tokens.mjs +8 -0
- package/dist/js/app-legacy.0ae704c9.js +0 -1
- package/dist/js/app.0ae704c9.js +0 -1
package/README.md
CHANGED
|
@@ -13,6 +13,50 @@ To view documentation or get support, visit [docs](https://yuda-lyu.github.io/w-
|
|
|
13
13
|
|
|
14
14
|
## Upgrade Notes
|
|
15
15
|
|
|
16
|
+
### Upgrading from 1.1.4 and earlier
|
|
17
|
+
|
|
18
|
+
**修正說明**:1.1.4(含)以前,對外查詢 helper 失敗時會把已代入權杖之完整網址放進 reject 值與 console;消費端若把錯誤原樣回應,送出無效權杖即可取得該系統向 SSO 介接用之 app token。本版起 helper 之 reject 值與 console 皆不含權杖(下述),且 app token 改為依權限授權、預設只能查使用者(見下方「應用系統金鑰權限」)。
|
|
19
|
+
|
|
20
|
+
**應用系統金鑰(app token,`isApp='y'`)改為依權限授權(破壞性變更)**:原本 app token 通過全部需管理者之功能(視同管理者),本版起依 tokens 表新增之 `perms` 欄(權限字串陣列,多元素即多權限聯集)授權,**預設只提供查使用者**:
|
|
21
|
+
|
|
22
|
+
| 權限字串 | 名稱 | 可呼叫之功能 |
|
|
23
|
+
|---|---|---|
|
|
24
|
+
| `readUsers` | 讀使用者(基本權限,恆具備) | HTTP `/api/getSsoUserInfor`、`/api/getSsoUsersList`;後台 `getUserInfor`、`getUsersList` |
|
|
25
|
+
| `writeUsers` | 寫使用者 | 後台 `updateUsersList`、`adminResetUserPassword` |
|
|
26
|
+
| `readTokens` | 讀金鑰 | 後台 `getTokensList` |
|
|
27
|
+
| `writeTokens` | 寫金鑰 | 後台 `updateTokensList` |
|
|
28
|
+
| `readIps` | 讀IP | 後台 `getIpsList` |
|
|
29
|
+
| `writeIps` | 寫IP | 後台 `updateIpsList` |
|
|
30
|
+
| `readStats` | 讀統計 | 後台 `getStaUserSummary`、`getStaTokenSummary`、`getStaIpSummary`、`getStaUserAccountLogin`、`getStaToken`、`getStaIp` |
|
|
31
|
+
|
|
32
|
+
- 升級前既有之 app token 無 `perms` 欄,升級後只具 `readUsers`。本套件之對外查詢 helper 只用 `readUsers`,不受影響;介接系統若呼叫其他後台功能,請管理者於後台「金鑰清單」之「應用系統權限」欄勾選授予。
|
|
33
|
+
- `writeUsers`、`readTokens`、`writeTokens` 可讓持有者取得管理者層級之能力(讀取管理者之 session 金鑰、改寫金鑰或使用者後接管帳號),後台以「等同管理者權限」標註,請僅授予確有需要之系統。
|
|
34
|
+
- 缺權限時對外回 `tokenExpired`(與非管理者相同),SSO 之 srLog 記 `appTokenPermDenied`(含所需權限)供排錯。
|
|
35
|
+
- 以 API 寫入 `perms` 時須為權限字串陣列(未設定視同空陣列),含未登錄之字串則整批 reject `tokenPermsInvalid`。
|
|
36
|
+
- 使用者 token 不受 `perms` 影響,仍依使用者之 `isAdmin` 判斷;app token 之速率豁免(不受 token 調用次數封鎖)不變。
|
|
37
|
+
|
|
38
|
+
**對外查詢 helper(`src/getUserByToken.mjs` / `getUserByUserId.mjs` / `getUsersByToken.mjs`)之 reject 值改為固定 key(破壞性變更)**:reject 值不再含網址與權杖,詞彙與 w-web-perm 之 helper 一致;各 key 之 eng / cht 文字見 `server/procLang.mjs`。
|
|
39
|
+
|
|
40
|
+
| 舊 reject 字串 | 新 key |
|
|
41
|
+
|---|---|
|
|
42
|
+
| `invalid url` / `invalid tokenSelf` / `invalid tokenTar` / `invalid userIdTar` | `invalidUrl` / `invalidTokenSelf` / `invalidTokenTar` / `invalidUserIdTar` |
|
|
43
|
+
| `no 'token={sysToken}', 'key=token', 'value={token}' in url` | `noTokenKeyValueInUrl` |
|
|
44
|
+
| `no 'token={sysToken}', 'key=id', 'value={userId}' in url` | `noTokenKeyUserIdInUrl` |
|
|
45
|
+
| `no 'token={sysToken}' in url` | `noTokenInUrl` |
|
|
46
|
+
| `can not get user by url[...]` / `can not get users by url[...]` | `cannotGetUserByUrl` / `cannotGetUsersByUrl` |
|
|
47
|
+
| `can not get user data by url[...]` / `can not get users data by url[...]` | `cannotGetUserDataByUrl` / `cannotGetUsersDataByUrl` |
|
|
48
|
+
| `no user data by url[...]` / `no users data by url[...]` | `noUserDataByUrl` / `noUsersDataByUrl` |
|
|
49
|
+
| `no user data after funConvertUser`(含 `funConvertUser` 拋錯或 reject) | `noUserDataAfterConvert` |
|
|
50
|
+
|
|
51
|
+
- 呼叫端請以 key 判斷,並映射為自家語系之錯誤 key 後再回前端;helper 之 reject 值不得原樣回前端。
|
|
52
|
+
- `tokenSelf` 為 app token 時,helper 只可在伺服端呼叫(放進瀏覽器即等於公開 app token)。
|
|
53
|
+
- 代入值改經 `encodeURIComponent`(對 UUID、英數與 `-_.~` 不變),`getUsersByToken` 之清單須為非空陣列。
|
|
54
|
+
- 失敗時之 console 由多行改為一行 `[w-web-sso] <helper> <key> {...}`,不含任何權杖字元。
|
|
55
|
+
|
|
56
|
+
**`/api/getSsoUsersList`(及 `getUsersByToken`)不再輸出 `tokenVerify`**(憑證欄;`password` 原即不輸出)。後台使用者清單不受影響。
|
|
57
|
+
|
|
58
|
+
**log**:權杖遮罩對 16 字元以下之權杖露出更少字元(36 字元 session token 格式不變),陣列與非字串一律遮罩;資料通道之 `referer` 只記 origin + pathname;`getSsoUserInfor` 以非識別欄(id / account / email / name 以外)查詢時之查詢值遮罩。
|
|
59
|
+
|
|
16
60
|
### Upgrading from 1.0.3x / 1.0.5x
|
|
17
61
|
|
|
18
62
|
**Settings (啟動契約)**: 舊版 settings 原封不動即可啟動——新增之設定鍵皆有內建預設:
|
|
@@ -22,7 +66,7 @@ To view documentation or get support, visit [docs](https://yuda-lyu.github.io/w-
|
|
|
22
66
|
- 信件文字鍵**全數繼續生效**(各欄位逐語系物件,語意同舊版):`chpwEmTitle` / `chpwEmContent`(變更密碼通知信,`{sender}`/`{name}` 置換符)、`regVerifyEmTitle` / `regVerifyEmContent`(註冊驗證信,`{sender}`/`{name}`/`{verifyUrl}` 置換符);另新增 `resetPwEmTitle` / `resetPwEmContent`(重設密碼通知信,`{sender}`/`{name}`/`{account}`/`{newPassword}` 置換符)與 `verifyEmailResultContent`(驗證結果頁,`{title}`/`{message}` 置換符);2026-09-15 起結果頁之三則訊息 `userRegistrationVerifySuccess` / `verifyEmailAlreadyVerified` / `verifyEmailInvalidToken` 亦可以同名 settings 鍵逐語系覆寫(代入 `{message}`;部署方須點名自家系統時於此覆寫,不改套件內建)。各值可直接給文字,**亦可給檔案路徑**(絕對或基於啟動路徑之相對,檔案存在即讀檔作為內容,不存在則原樣視為文字)。既有客製不需任何搬移;未給時採內建語系文字(結果頁採內建模板,另可用 `pathTemplate` 指定自訂結果頁模板資料夾)。套件自帶 `settings.json` 已含全部鍵與預設文字可直接參考。
|
|
23
67
|
- settings 內 `salt` 為伺服器端 pepper(範例值 `'{salt}'`,正式部署請自行改為高熵字串;亦可以環境變數 `SALT` 覆寫);套件不檢查其內容。
|
|
24
68
|
|
|
25
|
-
**API (授權收緊, 1.0.5x 起)**: `/api/getSsoUserInfor` 與 `/api/getSsoUsersList` 由「任何有效 token」收緊為須 **admin token 或 app token(`isApp='y'
|
|
69
|
+
**API (授權收緊, 1.0.5x 起)**: `/api/getSsoUserInfor` 與 `/api/getSsoUsersList` 由「任何有效 token」收緊為須 **admin token 或 app token(`isApp='y'`;1.1.4 之後之版本改為具 `readUsers` 之 app token,此為其基本權限)**。以 app token 做系統介接者不受影響;若既有整合以一般使用者 token 呼叫這兩支,請改用 app token。錯誤訊息字串已改為 i18n key(呼叫端請以 `state==='success'` 判斷成敗,勿比對錯誤字串)。
|
|
26
70
|
|
|
27
71
|
**Database (資料契約, 1.0.5x 起之破壞性變更)**: 密碼雜湊改為 `scrypt:{saltHex}:{hashHex}` 自描述格式且**不相容舊格式**,並新增 `timeVerified` 必填欄位(為空視為未完成信箱驗證、拒絕登入)。舊 DB 之使用者(含 admin)升級後將全數無法登入——請重建 DB 並重匯入使用者資料(以新版 `hashPassword` 產生密碼並補 `timeVerified`),或自行撰寫一次性遷移(重設密碼+補 `timeVerified`+可標 `isForceChangePw='y'` 要求使用者改密)。
|
|
28
72
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.bg-blue-100[data-v-0a60b8c6]{--tw-bg-opacity:1;background-color:rgb(219 234 254/var(--tw-bg-opacity,1))}.bg-gray-100[data-v-0a60b8c6]{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity,1))}.bg-gray-50[data-v-0a60b8c6]{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity,1))}.bg-green-100[data-v-0a60b8c6]{--tw-bg-opacity:1;background-color:rgb(220 252 231/var(--tw-bg-opacity,1))}.bg-red-100[data-v-0a60b8c6]{--tw-bg-opacity:1;background-color:rgb(254 226 226/var(--tw-bg-opacity,1))}.bg-white[data-v-0a60b8c6]{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.bg-yellow-100[data-v-0a60b8c6]{--tw-bg-opacity:1;background-color:rgb(254 249 195/var(--tw-bg-opacity,1))}.border[data-v-0a60b8c6]{border-width:1px}.border-collapse[data-v-0a60b8c6]{border-collapse:collapse}.border-gray-200[data-v-0a60b8c6]{--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity,1))}.border-gray-300[data-v-0a60b8c6]{--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity,1))}.border-solid[data-v-0a60b8c6]{border-style:solid}.cursor-pointer[data-v-0a60b8c6]{cursor:pointer}.flex[data-v-0a60b8c6]{display:-webkit-box;display:-ms-flexbox;display:flex}.focus\:ring-blue-500[data-v-0a60b8c6]:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(59 130 246/var(--tw-ring-opacity,1))}.font-bold[data-v-0a60b8c6]{font-weight:700}.font-medium[data-v-0a60b8c6]{font-weight:500}.font-semibold[data-v-0a60b8c6]{font-weight:600}.gap-5[data-v-0a60b8c6]{gap:1.25rem}.gap-6[data-v-0a60b8c6]{gap:1.5rem}.h-4[data-v-0a60b8c6]{height:1rem}.hover\:bg-gray-50[data-v-0a60b8c6]:hover{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity,1))}.hover\:underline[data-v-0a60b8c6]:hover{text-decoration-line:underline}.items-center[data-v-0a60b8c6]{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.justify-between[data-v-0a60b8c6]{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.mb-2[data-v-0a60b8c6]{margin-bottom:.5rem}.mb-4[data-v-0a60b8c6]{margin-bottom:1rem}.mb-8[data-v-0a60b8c6]{margin-bottom:2rem}.ml-2[data-v-0a60b8c6]{margin-left:.5rem}.ml-4[data-v-0a60b8c6]{margin-left:1rem}.mr-2[data-v-0a60b8c6]{margin-right:.5rem}.mt-2[data-v-0a60b8c6]{margin-top:.5rem}.mt-4[data-v-0a60b8c6]{margin-top:1rem}.overflow-x-auto[data-v-0a60b8c6]{overflow-x:auto}.p-3[data-v-0a60b8c6]{padding:.75rem}.p-5[data-v-0a60b8c6]{padding:1.25rem}.pb-1[data-v-0a60b8c6]{padding-bottom:.25rem}.pb-2[data-v-0a60b8c6]{padding-bottom:.5rem}.pb-3[data-v-0a60b8c6]{padding-bottom:.75rem}.px-2[data-v-0a60b8c6]{padding-left:.5rem;padding-right:.5rem}.px-6[data-v-0a60b8c6]{padding-left:1.5rem;padding-right:1.5rem}.py-1[data-v-0a60b8c6]{padding-top:.25rem;padding-bottom:.25rem}.py-3[data-v-0a60b8c6]{padding-top:.75rem;padding-bottom:.75rem}.py-4[data-v-0a60b8c6]{padding-top:1rem;padding-bottom:1rem}.relative[data-v-0a60b8c6]{position:relative}.rounded[data-v-0a60b8c6]{border-radius:.25rem}.rounded-full[data-v-0a60b8c6]{border-radius:9999px}.rounded-lg[data-v-0a60b8c6]{border-radius:.5rem}.shadow-md[data-v-0a60b8c6]{--tw-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1);--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color)}.shadow-md[data-v-0a60b8c6],.shadow-sm[data-v-0a60b8c6]{-webkit-box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-sm[data-v-0a60b8c6]{--tw-shadow:0 1px 2px 0 rgba(0,0,0,.05);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color)}.space-x-4[data-v-0a60b8c6]>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(1rem*var(--tw-space-x-reverse));margin-left:calc(1rem*(1 - var(--tw-space-x-reverse)))}.space-y-2[data-v-0a60b8c6]>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem*var(--tw-space-y-reverse))}.space-y-8[data-v-0a60b8c6]>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(2rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2rem*var(--tw-space-y-reverse))}.sticky[data-v-0a60b8c6]{position:sticky}.text-2xl[data-v-0a60b8c6]{font-size:1.5rem;line-height:2rem}.text-blue-600[data-v-0a60b8c6]{--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity,1))}.text-gray-500[data-v-0a60b8c6]{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity,1))}.text-gray-700[data-v-0a60b8c6]{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity,1))}.text-gray-900[data-v-0a60b8c6]{--tw-text-opacity:1;color:rgb(17 24 39/var(--tw-text-opacity,1))}.text-green-600[data-v-0a60b8c6]{--tw-text-opacity:1;color:rgb(22 163 74/var(--tw-text-opacity,1))}.text-indigo-600[data-v-0a60b8c6]{--tw-text-opacity:1;color:rgb(79 70 229/var(--tw-text-opacity,1))}.text-left[data-v-0a60b8c6]{text-align:left}.text-lg[data-v-0a60b8c6]{font-size:1.125rem;line-height:1.75rem}.text-purple-600[data-v-0a60b8c6]{--tw-text-opacity:1;color:rgb(147 51 234/var(--tw-text-opacity,1))}.text-red-600[data-v-0a60b8c6]{--tw-text-opacity:1;color:rgb(220 38 38/var(--tw-text-opacity,1))}.text-right[data-v-0a60b8c6]{text-align:right}.text-sm[data-v-0a60b8c6]{font-size:.875rem;line-height:1.25rem}.text-teal-600[data-v-0a60b8c6]{--tw-text-opacity:1;color:rgb(13 148 136/var(--tw-text-opacity,1))}.text-xs[data-v-0a60b8c6]{font-size:.75rem;line-height:1rem}.text-yellow-600[data-v-0a60b8c6]{--tw-text-opacity:1;color:rgb(202 138 4/var(--tw-text-opacity,1))}.top-0[data-v-0a60b8c6]{top:0}.transition-colors[data-v-0a60b8c6]{-webkit-transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;-webkit-transition-timing-function:cubic-bezier(.4,0,.2,1);transition-timing-function:cubic-bezier(.4,0,.2,1);-webkit-transition-duration:.15s;transition-duration:.15s}.w-4[data-v-0a60b8c6]{width:1rem}.w-7[data-v-0a60b8c6]{width:1.75rem}.w-full[data-v-0a60b8c6]{width:100%}.z-10[data-v-0a60b8c6]{z-index:10}.grid[data-v-0a60b8c6]{display:grid}.grid-cols-1[data-v-0a60b8c6]{grid-template-columns:repeat(1,minmax(0,1fr))}@media (min-width:640px){.sm\:grid-cols-2[data-v-0a60b8c6]{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:1024px){.lg\:grid-cols-1[data-v-0a60b8c6]{grid-template-columns:repeat(1,minmax(0,1fr))}.lg\:grid-cols-3[data-v-0a60b8c6]{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4[data-v-0a60b8c6]{grid-template-columns:repeat(4,minmax(0,1fr))}}.bg-blue-100[data-v-3796caa5]{--tw-bg-opacity:1;background-color:rgb(219 234 254/var(--tw-bg-opacity,1))}.bg-gray-100[data-v-3796caa5]{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity,1))}.border-gray-200[data-v-3796caa5]{--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity,1))}.border-t[data-v-3796caa5]{border-top-width:1px}.break-all[data-v-3796caa5]{word-break:break-all}.flex[data-v-3796caa5]{display:-webkit-box;display:-ms-flexbox;display:flex}.flex-shrink-0[data-v-3796caa5]{-ms-flex-negative:0;flex-shrink:0}.font-medium[data-v-3796caa5]{font-weight:500}.font-semibold[data-v-3796caa5]{font-weight:600}.gap-3[data-v-3796caa5]{gap:.75rem}.gap-4[data-v-3796caa5]{gap:1rem}.gap-x-8[data-v-3796caa5]{-webkit-column-gap:2rem;-moz-column-gap:2rem;column-gap:2rem}.gap-y-6[data-v-3796caa5]{row-gap:1.5rem}.inline-block[data-v-3796caa5]{display:inline-block}.items-center[data-v-3796caa5]{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.items-start[data-v-3796caa5]{-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.mb-2[data-v-3796caa5]{margin-bottom:.5rem}.mr-3[data-v-3796caa5]{margin-right:.75rem}.mt-1[data-v-3796caa5]{margin-top:.25rem}.p-3[data-v-3796caa5]{padding:.75rem}.pt-6[data-v-3796caa5]{padding-top:1.5rem}.px-2[data-v-3796caa5]{padding-left:.5rem;padding-right:.5rem}.py-1[data-v-3796caa5]{padding-top:.25rem;padding-bottom:.25rem}.rounded-lg[data-v-3796caa5]{border-radius:.5rem}.rounded-md[data-v-3796caa5]{border-radius:.375rem}.space-y-8[data-v-3796caa5]>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(2rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2rem*var(--tw-space-y-reverse))}.text-base[data-v-3796caa5]{font-size:1rem;line-height:1.5rem}.text-blue-700[data-v-3796caa5]{--tw-text-opacity:1;color:rgb(29 78 216/var(--tw-text-opacity,1))}.text-gray-400[data-v-3796caa5]{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity,1))}.text-gray-500[data-v-3796caa5]{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity,1))}.text-gray-700[data-v-3796caa5]{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity,1))}.text-gray-900[data-v-3796caa5]{--tw-text-opacity:1;color:rgb(17 24 39/var(--tw-text-opacity,1))}.text-sm[data-v-3796caa5]{font-size:.875rem;line-height:1.25rem}.text-xs[data-v-3796caa5]{font-size:.75rem;line-height:1rem}.text-red-800\/80[data-v-3796caa5]{color:rgba(153,27,27,.8)}.text-green-800\/80[data-v-3796caa5]{color:rgba(22,101,52,.8)}.grid[data-v-3796caa5]{display:grid}.grid-cols-1[data-v-3796caa5]{grid-template-columns:repeat(1,minmax(0,1fr))}@media (min-width:640px){.sm\:grid-cols-2[data-v-3796caa5]{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:768px){.md\:grid-cols-2[data-v-3796caa5]{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:col-span-2[data-v-3796caa5]{grid-column:span 2/span 2}}@media (min-width:1024px){.lg\:grid-cols-4[data-v-3796caa5]{grid-template-columns:repeat(4,minmax(0,1fr))}}.status-danger[data-v-3796caa5]{background-color:#fef2f2;color:#b91c1c;border:1px solid #fecaca}.status-warning[data-v-3796caa5]{background-color:#fffbeb;color:#b45309;border:1px solid #fde68a}.status-success[data-v-3796caa5]{background-color:#f0fdf4;color:#15803d;border:1px solid #bbf7d0}.status-info[data-v-3796caa5]{background-color:#f8fafc;color:#475569;border:1px solid #e2e8f0}.menu-row-click[data-v-782a9333]{-webkit-transition:background .2s;transition:background .2s}.menu-row-click[data-v-782a9333]:focus,.menu-row-click[data-v-782a9333]:hover{background:#f2f2f2}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}.sb{-webkit-transition:opacity .3s;transition:opacity .3s;scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.3) transparent}.sb::-webkit-scrollbar{width:8px;height:8px}.sb::-webkit-scrollbar-track{background:transparent}.sb::-webkit-scrollbar-thumb{background:rgba(0,0,0,.3);border-radius:20px;border:3px solid transparent}
|
|
1
|
+
.bg-blue-100[data-v-0a60b8c6]{--tw-bg-opacity:1;background-color:rgb(219 234 254/var(--tw-bg-opacity,1))}.bg-gray-100[data-v-0a60b8c6]{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity,1))}.bg-gray-50[data-v-0a60b8c6]{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity,1))}.bg-green-100[data-v-0a60b8c6]{--tw-bg-opacity:1;background-color:rgb(220 252 231/var(--tw-bg-opacity,1))}.bg-red-100[data-v-0a60b8c6]{--tw-bg-opacity:1;background-color:rgb(254 226 226/var(--tw-bg-opacity,1))}.bg-white[data-v-0a60b8c6]{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.bg-yellow-100[data-v-0a60b8c6]{--tw-bg-opacity:1;background-color:rgb(254 249 195/var(--tw-bg-opacity,1))}.border[data-v-0a60b8c6]{border-width:1px}.border-collapse[data-v-0a60b8c6]{border-collapse:collapse}.border-gray-200[data-v-0a60b8c6]{--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity,1))}.border-gray-300[data-v-0a60b8c6]{--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity,1))}.border-solid[data-v-0a60b8c6]{border-style:solid}.cursor-pointer[data-v-0a60b8c6]{cursor:pointer}.flex[data-v-0a60b8c6]{display:-webkit-box;display:-ms-flexbox;display:flex}.focus\:ring-blue-500[data-v-0a60b8c6]:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(59 130 246/var(--tw-ring-opacity,1))}.font-bold[data-v-0a60b8c6]{font-weight:700}.font-medium[data-v-0a60b8c6]{font-weight:500}.font-semibold[data-v-0a60b8c6]{font-weight:600}.gap-5[data-v-0a60b8c6]{gap:1.25rem}.gap-6[data-v-0a60b8c6]{gap:1.5rem}.h-4[data-v-0a60b8c6]{height:1rem}.hover\:bg-gray-50[data-v-0a60b8c6]:hover{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity,1))}.hover\:underline[data-v-0a60b8c6]:hover{text-decoration-line:underline}.items-center[data-v-0a60b8c6]{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.justify-between[data-v-0a60b8c6]{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.mb-2[data-v-0a60b8c6]{margin-bottom:.5rem}.mb-4[data-v-0a60b8c6]{margin-bottom:1rem}.mb-8[data-v-0a60b8c6]{margin-bottom:2rem}.ml-2[data-v-0a60b8c6]{margin-left:.5rem}.ml-4[data-v-0a60b8c6]{margin-left:1rem}.mr-2[data-v-0a60b8c6]{margin-right:.5rem}.mt-2[data-v-0a60b8c6]{margin-top:.5rem}.mt-4[data-v-0a60b8c6]{margin-top:1rem}.overflow-x-auto[data-v-0a60b8c6]{overflow-x:auto}.p-3[data-v-0a60b8c6]{padding:.75rem}.p-5[data-v-0a60b8c6]{padding:1.25rem}.pb-1[data-v-0a60b8c6]{padding-bottom:.25rem}.pb-2[data-v-0a60b8c6]{padding-bottom:.5rem}.pb-3[data-v-0a60b8c6]{padding-bottom:.75rem}.px-2[data-v-0a60b8c6]{padding-left:.5rem;padding-right:.5rem}.px-6[data-v-0a60b8c6]{padding-left:1.5rem;padding-right:1.5rem}.py-1[data-v-0a60b8c6]{padding-top:.25rem;padding-bottom:.25rem}.py-3[data-v-0a60b8c6]{padding-top:.75rem;padding-bottom:.75rem}.py-4[data-v-0a60b8c6]{padding-top:1rem;padding-bottom:1rem}.relative[data-v-0a60b8c6]{position:relative}.rounded[data-v-0a60b8c6]{border-radius:.25rem}.rounded-full[data-v-0a60b8c6]{border-radius:9999px}.rounded-lg[data-v-0a60b8c6]{border-radius:.5rem}.shadow-md[data-v-0a60b8c6]{--tw-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1);--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color)}.shadow-md[data-v-0a60b8c6],.shadow-sm[data-v-0a60b8c6]{-webkit-box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-sm[data-v-0a60b8c6]{--tw-shadow:0 1px 2px 0 rgba(0,0,0,.05);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color)}.space-x-4[data-v-0a60b8c6]>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(1rem*var(--tw-space-x-reverse));margin-left:calc(1rem*(1 - var(--tw-space-x-reverse)))}.space-y-2[data-v-0a60b8c6]>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem*var(--tw-space-y-reverse))}.space-y-8[data-v-0a60b8c6]>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(2rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2rem*var(--tw-space-y-reverse))}.sticky[data-v-0a60b8c6]{position:sticky}.text-2xl[data-v-0a60b8c6]{font-size:1.5rem;line-height:2rem}.text-blue-600[data-v-0a60b8c6]{--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity,1))}.text-gray-500[data-v-0a60b8c6]{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity,1))}.text-gray-700[data-v-0a60b8c6]{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity,1))}.text-gray-900[data-v-0a60b8c6]{--tw-text-opacity:1;color:rgb(17 24 39/var(--tw-text-opacity,1))}.text-green-600[data-v-0a60b8c6]{--tw-text-opacity:1;color:rgb(22 163 74/var(--tw-text-opacity,1))}.text-indigo-600[data-v-0a60b8c6]{--tw-text-opacity:1;color:rgb(79 70 229/var(--tw-text-opacity,1))}.text-left[data-v-0a60b8c6]{text-align:left}.text-lg[data-v-0a60b8c6]{font-size:1.125rem;line-height:1.75rem}.text-purple-600[data-v-0a60b8c6]{--tw-text-opacity:1;color:rgb(147 51 234/var(--tw-text-opacity,1))}.text-red-600[data-v-0a60b8c6]{--tw-text-opacity:1;color:rgb(220 38 38/var(--tw-text-opacity,1))}.text-right[data-v-0a60b8c6]{text-align:right}.text-sm[data-v-0a60b8c6]{font-size:.875rem;line-height:1.25rem}.text-teal-600[data-v-0a60b8c6]{--tw-text-opacity:1;color:rgb(13 148 136/var(--tw-text-opacity,1))}.text-xs[data-v-0a60b8c6]{font-size:.75rem;line-height:1rem}.text-yellow-600[data-v-0a60b8c6]{--tw-text-opacity:1;color:rgb(202 138 4/var(--tw-text-opacity,1))}.top-0[data-v-0a60b8c6]{top:0}.transition-colors[data-v-0a60b8c6]{-webkit-transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;-webkit-transition-timing-function:cubic-bezier(.4,0,.2,1);transition-timing-function:cubic-bezier(.4,0,.2,1);-webkit-transition-duration:.15s;transition-duration:.15s}.w-4[data-v-0a60b8c6]{width:1rem}.w-7[data-v-0a60b8c6]{width:1.75rem}.w-full[data-v-0a60b8c6]{width:100%}.z-10[data-v-0a60b8c6]{z-index:10}.grid[data-v-0a60b8c6]{display:grid}.grid-cols-1[data-v-0a60b8c6]{grid-template-columns:repeat(1,minmax(0,1fr))}@media (min-width:640px){.sm\:grid-cols-2[data-v-0a60b8c6]{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:1024px){.lg\:grid-cols-1[data-v-0a60b8c6]{grid-template-columns:repeat(1,minmax(0,1fr))}.lg\:grid-cols-3[data-v-0a60b8c6]{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4[data-v-0a60b8c6]{grid-template-columns:repeat(4,minmax(0,1fr))}}.bg-blue-100[data-v-3796caa5]{--tw-bg-opacity:1;background-color:rgb(219 234 254/var(--tw-bg-opacity,1))}.bg-gray-100[data-v-3796caa5]{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity,1))}.border-gray-200[data-v-3796caa5]{--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity,1))}.border-t[data-v-3796caa5]{border-top-width:1px}.break-all[data-v-3796caa5]{word-break:break-all}.flex[data-v-3796caa5]{display:-webkit-box;display:-ms-flexbox;display:flex}.flex-shrink-0[data-v-3796caa5]{-ms-flex-negative:0;flex-shrink:0}.font-medium[data-v-3796caa5]{font-weight:500}.font-semibold[data-v-3796caa5]{font-weight:600}.gap-3[data-v-3796caa5]{gap:.75rem}.gap-4[data-v-3796caa5]{gap:1rem}.gap-x-8[data-v-3796caa5]{-webkit-column-gap:2rem;-moz-column-gap:2rem;column-gap:2rem}.gap-y-6[data-v-3796caa5]{row-gap:1.5rem}.inline-block[data-v-3796caa5]{display:inline-block}.items-center[data-v-3796caa5]{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.items-start[data-v-3796caa5]{-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.mb-2[data-v-3796caa5]{margin-bottom:.5rem}.mr-3[data-v-3796caa5]{margin-right:.75rem}.mt-1[data-v-3796caa5]{margin-top:.25rem}.p-3[data-v-3796caa5]{padding:.75rem}.pt-6[data-v-3796caa5]{padding-top:1.5rem}.px-2[data-v-3796caa5]{padding-left:.5rem;padding-right:.5rem}.py-1[data-v-3796caa5]{padding-top:.25rem;padding-bottom:.25rem}.rounded-lg[data-v-3796caa5]{border-radius:.5rem}.rounded-md[data-v-3796caa5]{border-radius:.375rem}.space-y-8[data-v-3796caa5]>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(2rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2rem*var(--tw-space-y-reverse))}.text-base[data-v-3796caa5]{font-size:1rem;line-height:1.5rem}.text-blue-700[data-v-3796caa5]{--tw-text-opacity:1;color:rgb(29 78 216/var(--tw-text-opacity,1))}.text-gray-400[data-v-3796caa5]{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity,1))}.text-gray-500[data-v-3796caa5]{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity,1))}.text-gray-700[data-v-3796caa5]{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity,1))}.text-gray-900[data-v-3796caa5]{--tw-text-opacity:1;color:rgb(17 24 39/var(--tw-text-opacity,1))}.text-sm[data-v-3796caa5]{font-size:.875rem;line-height:1.25rem}.text-xs[data-v-3796caa5]{font-size:.75rem;line-height:1rem}.text-red-800\/80[data-v-3796caa5]{color:rgba(153,27,27,.8)}.text-green-800\/80[data-v-3796caa5]{color:rgba(22,101,52,.8)}.grid[data-v-3796caa5]{display:grid}.grid-cols-1[data-v-3796caa5]{grid-template-columns:repeat(1,minmax(0,1fr))}@media (min-width:640px){.sm\:grid-cols-2[data-v-3796caa5]{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:768px){.md\:grid-cols-2[data-v-3796caa5]{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:col-span-2[data-v-3796caa5]{grid-column:span 2/span 2}}@media (min-width:1024px){.lg\:grid-cols-4[data-v-3796caa5]{grid-template-columns:repeat(4,minmax(0,1fr))}}.status-danger[data-v-3796caa5]{background-color:#fef2f2;color:#b91c1c;border:1px solid #fecaca}.status-warning[data-v-3796caa5]{background-color:#fffbeb;color:#b45309;border:1px solid #fde68a}.status-success[data-v-3796caa5]{background-color:#f0fdf4;color:#15803d;border:1px solid #bbf7d0}.status-info[data-v-3796caa5]{background-color:#f8fafc;color:#475569;border:1px solid #e2e8f0}.perms-trigger[data-v-25542ce2]{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:2px;border:1px solid #767676;border-radius:4px;background:#f0f0f0;cursor:pointer;-webkit-transition:background-color .2s;transition:background-color .2s}.perms-trigger[data-v-25542ce2]:hover{background:#e5e5e5}.menu-row-click[data-v-782a9333]{-webkit-transition:background .2s;transition:background .2s}.menu-row-click[data-v-782a9333]:focus,.menu-row-click[data-v-782a9333]:hover{background:#f2f2f2}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}.sb{-webkit-transition:opacity .3s;transition:opacity .3s;scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.3) transparent}.sb::-webkit-scrollbar{width:8px;height:8px}.sb::-webkit-scrollbar-track{background:transparent}.sb::-webkit-scrollbar-thumb{background:rgba(0,0,0,.3);border-radius:20px;border:3px solid transparent}
|