w-web-perm 1.1.10 → 1.1.12
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 +14 -0
- package/dist/index.tmp +1 -1
- package/dist/js/app-legacy.7cb7e394.js +1 -0
- package/dist/js/app.7cb7e394.js +1 -0
- package/dist/js/{chunk-vendors-legacy.b43f5548.js → chunk-vendors-legacy.3e9e3ef1.js} +1 -1
- package/dist/js/{chunk-vendors.b43f5548.js → chunk-vendors.3e9e3ef1.js} +1 -1
- package/dist/w-web-perm.umd.js +2 -2
- package/dist/w-web-perm.umd.js.map +1 -1
- package/docs/WWebPerm.html +2 -2
- package/docs/global.html +2764 -105
- package/docs/index.html +2 -2
- package/docs/server_WWebPerm.mjs.html +36 -3
- package/docs/server_dataChannel.mjs.html +2 -2
- package/docs/server_lockSave.mjs.html +2 -2
- package/docs/server_maskLog.mjs.html +2 -2
- package/docs/server_procCore.mjs.html +28 -12
- package/docs/server_staLogs_resolveShellWorker.mjs.html +2 -2
- package/docs/server_validateRows.mjs.html +28 -16
- package/docs/server_wrapInjected.mjs.html +2 -2
- package/docs/src_fetchJson.mjs.html +2 -2
- package/docs/src_js_cvKpToArr.mjs.html +125 -0
- package/docs/src_js_cvKpToObj.mjs.html +199 -0
- package/docs/src_js_eachOwn.mjs.html +119 -0
- package/docs/src_js_fmtLossyMsg.mjs.html +95 -0
- package/docs/src_js_getKeyOrderLost.mjs.html +121 -0
- package/docs/src_js_getKpLossy.mjs.html +160 -0
- package/docs/src_js_getKpWriteLost.mjs.html +100 -0
- package/docs/src_js_getOwn.mjs.html +110 -0
- package/docs/src_js_getRuleEnable.mjs.html +96 -0
- package/docs/src_js_isAuthMode.mjs.html +92 -0
- package/docs/src_js_joinNames.mjs.html +96 -0
- package/docs/src_js_keepKeyOrder.mjs.html +139 -0
- package/docs/src_js_legendFit.mjs.html +2 -2
- package/docs/src_plugins_reuseDeletedIds.mjs.html +2 -2
- package/docs/src_plugins_submitGuard.mjs.html +2 -2
- package/package.json +1 -1
- package/server/WWebPerm.mjs +34 -1
- package/server/procCore.mjs +26 -10
- package/server/procLang.mjs +4 -0
- package/server/validateRows.mjs +26 -14
- package/src/components/LayoutContentGrups.vue +7 -5
- package/src/components/LayoutContentPemis.vue +9 -6
- package/src/components/LayoutContentUsers.vue +4 -2
- package/src/components/VeCgrups.vue +51 -5
- package/src/components/VeCpemis.vue +51 -5
- package/src/components/VeCrules.vue +11 -5
- package/src/components/VeGrupBlngUsers.vue +65 -10
- package/src/components/VePemiBlngGrups.vue +65 -10
- package/src/js/cvKpToArr.mjs +53 -0
- package/src/js/cvKpToObj.mjs +127 -0
- package/src/js/eachOwn.mjs +47 -0
- package/src/js/fmtLossyMsg.mjs +23 -0
- package/src/js/getKeyOrderLost.mjs +49 -0
- package/src/js/getKpLossy.mjs +88 -0
- package/src/js/getKpWriteLost.mjs +28 -0
- package/src/js/getOwn.mjs +38 -0
- package/src/js/getRuleEnable.mjs +24 -0
- package/src/js/isAuthMode.mjs +20 -0
- package/src/js/joinNames.mjs +24 -0
- package/src/js/keepKeyOrder.mjs +67 -0
- package/src/perm.mjs +6 -3
- package/src/plugins/mShare.mjs +17 -35
- package/dist/js/app-legacy.26e909d6.js +0 -1
- package/dist/js/app.26e909d6.js +0 -1
package/README.md
CHANGED
|
@@ -96,6 +96,20 @@ instWWebPerm.on('error', (err) => {
|
|
|
96
96
|
|
|
97
97
|
## Upgrade Notes
|
|
98
98
|
|
|
99
|
+
### Unreleased: objects carrying a numeric `length` key, and non-array `rows` (2026-10-20)
|
|
100
|
+
- **`rows` must be an array (behavior change)**: `updateTargets`, `updatePemis`, `updateGrups` and `updateUsers` now reject a `rows` argument that is not an array (a string, number, `null`, `undefined`, a plain object, or an object carrying a numeric `length` key), or whose elements are not non-empty objects (`[null]`, `[{}]`, `[""]`, `[[]]`), with `saveRowFieldInvalid` and leave the table unchanged. Previously such input was treated as an empty table: the whole table was cleared and the call reported success (in the `modeEditUsers: 'for:grups'` mode it was silently ignored). An empty array `[]` is still accepted (it clears the table). The bundled front end and `/syncAndReplaceTabs` (which already required a non-empty array) are not affected.
|
|
101
|
+
- **Objects are iterated by their own keys**: a field or key named `length` is an ordinary key everywhere user-supplied objects are walked (write validation, the `cgrups` / `cpemis` / `crules` JSON strings evaluated by `getPerm` / `getPermUserInfor`, and the list pages). Before, lodash treated such an object as an array-like of that length: real keys were skipped (for example a group listed next to `"length": 0` was ignored, so its rules evaluated to `n`) and a huge `length` made the call spin or run out of memory.
|
|
102
|
+
- **`/syncAndReplaceTabs` rows must be non-empty objects (behavior change)**: every element of `rows` must be an object with at least one key. A push containing a string, number, `null`, array, boolean or an empty object `{}` is rejected as a whole with `invalidRows` before anything is deleted. Before, a non-object element made the call fail with an engine message (for example `Cannot create property 'from' on string 'abc'`) that was returned to the application, and an empty object in a multi-row push was written as a blank row with a generated id. A row that carries no schema field at all (for example `{"foo":1}`; it would map to an all-empty row) is rejected the same way.
|
|
103
|
+
- **Authorization lookups use the exact id, not a lodash path (behavior change, tightening)**: `getUserRules` (used by `getPerm` / `getPermUserInfor`), the SDK `perm().active(name)` and the edit dialogs of user groups, group permissions and permission rules now look a target, group or permission up by its exact name as an own property. Before, a name containing `.` or `[` was resolved as a path: when only `A` was granted, targets `A.0` and `A[0]` evaluated to `y` (and `A.length` to `1`), and inherited names such as `toString` could be returned. Names that are themselves keys (for example a target called `A.0` granted by a rule named `A.0`, or one called `constructor` / `__proto__`) are granted as usual. In the admin session of `modeEditUsers: 'for:grups'`, a database id containing `.` or `[` can no longer be taken over by another row's nested field. The edit dialogs also keep an item named `__proto__` when saving (before, it was shown as enabled but silently dropped from the saved JSON).
|
|
104
|
+
- **Object-form entries are named by their key (behavior change, tightening)**: in the `cgrups` / `cpemis` / `crules` JSON of the form `{"<name>": …}`, an inner `name` field no longer renames the entry (before, `{"A":{"name":"B","isActive":"y"}}` granted `B` while the edit dialogs showed `A`). The array form `[{"name":"A","isActive":"y"}]` is unchanged. The permission-rule edit dialog also reads object-form values (`{"A":{"isActive":"y"}}`) the same way as the server, so such a rule is no longer shown as disabled (and revoked on save).
|
|
105
|
+
- **`/syncAndReplaceTabs` blank rows**: a row that carries no content outside the server-managed fields is rejected with `invalidRows`. Server-managed fields are `from`, `userId`, `timeCreate`, `userIdUpdate` and `timeUpdate` (the server overwrites them); a field value counts as content when it is a non-empty string, a finite number (`0` included) or a boolean (`""`, `null`, `[]` and `{}` do not).
|
|
106
|
+
- **Field values must be scalar (behavior change)**: every field of a row written by `updateTargets`, `updatePemis`, `updateGrups`, `updateUsers` or `/syncAndReplaceTabs` must be a string, number, boolean, `null` or absent. An object, array or other non-scalar value is rejected as a whole before anything is deleted (`saveRowFieldInvalid` for the admin pages, `invalidRows` for `/syncAndReplaceTabs`; the existing rows stay unchanged). No table has an object-typed field: `cgrups`, `cpemis` and `crules` are JSON **strings**. Before, a nested string such as `{ "description": { "value": "<script>" } }` slipped past the write validation and was silently rewritten when stored.
|
|
107
|
+
- **Edit dialogs decode authorization data exactly like the server (behavior change, tightening)**: `cgrups` / `cpemis` / `crules` may also be written in the array form `[{ "name": "A", "isActive": "y" }]` (an external application writing directly; `getPerm` / `getPermUserInfor` already honor it). The edit dialogs for user groups, group permissions and permission rules (and the two "belongs to" dialogs) used to look entries up by name, showed such entries as disabled, and saving revoked the authorization. They now decode both forms with the same function as the server, so what a dialog shows matches what is authorized, and saving keeps the authorization unchanged. Details: (1) in `cgrups` / `cpemis`, an entry with `isActive: "y"` but a missing or invalid `mode` (anything other than `"OR"` / `"AND"`) is not honored by the server; the dialogs now show it as disabled (before, object-form entries like that were shown as enabled and saving filled in `OR`, silently granting it); (2) in the object form `{ "<name>": { "name": …, … } }` the outer key is the name and an inner `name` is ignored, also in the "belongs to" dialogs (before, saving there re-pointed the grant to the inner name); (3) the three direct editors always save the object form `{ "<name>": … }`, the two "belongs to" dialogs rewrite the stored string only when its decoded content changes; (4) see the next two items for the cases the object form cannot hold (the same name active as both `AND` and `OR`) and for the order of `AND` entries.
|
|
108
|
+
- **Saving keeps the order of the stored entries (behavior change, fix)**: `mergeRules` starts the `AND` combination from the first `AND` entry when there is no active `OR` entry, so the order of the keys in `cgrups` / `cpemis` decides the result. The edit dialogs used to rewrite the keys in the order of the group / permission table, so with two or more `AND` entries of different rule sets a save with no visible change could gain or lose a grant. Entries already stored now keep their relative order and new ones are appended; for the array form the order is that of the first active entry of each name. `crules` is order independent and is handled the same way for consistency.
|
|
109
|
+
- **Data that the object form cannot hold is not rewritten (behavior change, fail-closed)**: when a `cgrups` / `cpemis` array (written directly by an external application) has the same name active as both `OR` and `AND`, or has two or more active `AND` names where the first `AND` name cannot keep its place in the object form (integer-like names such as `"1"` always sort first), the edit dialogs refuse to write it. A direct editor with changes, or a "belongs to" dialog with a change on such a row, is not saved and shows a fixed message naming the affected names; the stored string is left untouched, and a dialog opened and saved without changes returns the original string. The data has to be corrected at its source. Data written by the dialogs themselves (the object form) is never affected. The same refusal applies when a dialog would have to write an `AND` entry whose position JavaScript cannot keep: an integer-like name (for example a group called `1`) always sorts first in an object, so enabling it as `AND` in a dialog is refused when it would move ahead of the existing `AND` entries and change which one is evaluated first (as `OR`, or disabled, it saves normally).
|
|
110
|
+
- **List pages decode like the server**: the user, group and permission lists count and name the groups, permissions and rules of an array-form `cgrups` / `cpemis` / `crules` the same way as the server (before, the user list used the array index as the group name and the permission list counted 0 rules). Display only; nothing is written.
|
|
111
|
+
- **`/syncAndReplaceTabs` requires non-empty string names and ids (behavior change)**: for `grups` and `pemis` the `name` of every row, and for `targets` the `id` of every row, must be a non-empty string (as the admin pages already required). A missing value, an empty string, or a non-string (number, boolean, `null`) rejects the whole push with `invalidRows` before anything is deleted. Before, a group or permission with `name: ""` was stored and honored by `getPerm` / `getPermUserInfor`, but the edit dialogs treated it as invalid and removed it on the next save. `users` rows are not affected.
|
|
112
|
+
|
|
99
113
|
### Upgrading to w-serv-orm 1.1.11 / w-syslog 1.0.33 (2026-10-14)
|
|
100
114
|
- **Numeric ids are stored as strings**: a numeric row id sent to `/syncAndReplaceTabs` (or to `updatePemis`, `updateGrups`, `updateUsers`) is stored as its string form (`123` is stored as `'123'`) and the success response lists it as a string. Before, the number was replaced by a generated id while the response still showed the number. A number and its string form are the same id; `NaN` and `Infinity` count as no id (a new id is generated). `updateTargets` still accepts string ids only and rejects other ids with `saveRowFieldInvalid`.
|
|
101
115
|
- **Ids owned by another source are rejected**: if an id pushed to `/syncAndReplaceTabs` already belongs to another `from`, the whole push is rejected with `invalidRows` before anything is deleted (before, the row was skipped while the push still returned success). External applications must use ids that do not overlap with other sources.
|
package/dist/index.tmp
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
<!doctype html><html xmlns="http://www.w3.org/1999/xhtml" lang="zh-tw"><head><meta http-equiv="content-type" content="text/html; charset=UTF-8"/><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no,minimal-ui"><meta http-equiv="X-UA-Compatible" content="ie=edge"><meta name="referrer" content="strict-origin"><title></title><link _href="https://cdn.jsdelivr.net/npm/@mdi/font@7.4.47/css/materialdesignicons.min.css" rel="stylesheet"><link _href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.4.2/css/all.min.css" rel="stylesheet"><script>window.___pmwperm___={
|
|
2
2
|
urlRedirect: '{urlRedirect}',
|
|
3
3
|
language: '{language}',
|
|
4
|
-
}</script><script defer="defer" src="{sfd}/js/chunk-vendors.
|
|
4
|
+
}</script><script defer="defer" src="{sfd}/js/chunk-vendors.3e9e3ef1.js" type="module"></script><script defer="defer" src="{sfd}/js/app.7cb7e394.js" type="module"></script><link href="{sfd}/css/chunk-vendors.3c580e72.css" rel="stylesheet"><link href="{sfd}/css/app.6918ec45.css" rel="stylesheet"><script defer="defer" src="{sfd}/js/chunk-vendors-legacy.3e9e3ef1.js" nomodule></script><script defer="defer" src="{sfd}/js/app-legacy.7cb7e394.js" nomodule></script></head><body style="font-family:'Microsoft JhengHei','Avenir','Helvetica', 'Arial', 'sans-serif'; padding:0px; margin:0px;"><noscript><strong>We're sorry but w-component-vue doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>
|