@synopackageland/sdk 0.9.5 → 0.9.7
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 +29 -0
- package/dist/i18n/background/de.json +10 -0
- package/dist/i18n/background/en.json +10 -0
- package/dist/i18n/background/es.json +10 -0
- package/dist/i18n/background/fr.json +10 -0
- package/dist/i18n/background/it.json +10 -0
- package/dist/i18n/background/ja.json +9 -0
- package/dist/i18n/background/ko.json +9 -0
- package/dist/i18n/background/zh-CN.json +9 -0
- package/dist/i18n/background/zh-TW.json +9 -0
- package/dist/i18n/save/de.json +1 -0
- package/dist/i18n/save/en.json +1 -0
- package/dist/i18n/save/es.json +1 -0
- package/dist/i18n/save/fr.json +1 -0
- package/dist/i18n/save/it.json +1 -0
- package/dist/i18n/save/ja.json +1 -0
- package/dist/i18n/save/ko.json +1 -0
- package/dist/i18n/save/zh-CN.json +1 -0
- package/dist/i18n/save/zh-TW.json +1 -0
- package/dist/index.js +2165 -2048
- package/dist/src/background/i18n.d.ts +10 -0
- package/dist/src/context.d.ts +3 -0
- package/dist/src/delegate/save-copy.d.ts +3 -0
- package/dist/src/dsm/file-station.d.ts +27 -0
- package/dist/src/i18n.d.ts +17 -0
- package/dist/src/index.d.ts +2 -2
- package/dist/src/protocol/v1.d.ts +15 -1
- package/dist/style.css +1 -1
- package/dist/vue.js +1378 -1305
- package/package.json +2 -2
- package/spec/protocol/v1/README.md +72 -9
- package/spec/protocol/v1/errors.json +8 -0
- package/spec/protocol/v1/schema/portal.register.json +11 -0
- package/spec/protocol/v1/schema/portal.unregister.json +11 -0
- package/spec/protocol/v1/vectors/files.jsonl +1 -0
- package/spec/protocol/v1/vectors/portal.jsonl +8 -0
- package/spec/protocol/v1/vectors/status.jsonl +1 -0
- package/dist/src/nas/i18n.d.ts +0 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@synopackageland/sdk",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.7",
|
|
4
4
|
"description": "Frontend SDK for DSM packages built with synopkgland: headless client and Vue components",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/synopackageland/syno-pkg-land-sdk/tree/main/ts#readme",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@lucide/vue": "1.48.0",
|
|
56
|
-
"@synopackageland/ui": "0.9.
|
|
56
|
+
"@synopackageland/ui": "0.9.2",
|
|
57
57
|
"@types/node": "24.19.2",
|
|
58
58
|
"@vitejs/plugin-vue": "6.0.9",
|
|
59
59
|
"jsdom": "27.4.0",
|
|
@@ -40,9 +40,13 @@ the executor against the vectors here.
|
|
|
40
40
|
`dsm_synotoken` and `remote_addr` (since 0.9.4), the browser's address
|
|
41
41
|
(REMOTE_ADDR). DSM's Application Privileges are evaluated for that address;
|
|
42
42
|
an op that checks them MUST be refused with `APP_DENIED` when a present
|
|
43
|
-
`auth` has no usable `remote_addr`.
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
`auth` has no usable `remote_addr`. A grant records the `remote_addr` of the
|
|
44
|
+
`delegate.create` that made it (creating it again records the new one), and
|
|
45
|
+
an operation records the address of its `files.moveFromStaging` (since
|
|
46
|
+
0.9.6). A request without `auth` under a grant, and the operation's
|
|
47
|
+
background revalidation, are checked from that recorded address; work with no
|
|
48
|
+
recorded address is checked as coming from 127.0.0.1. A present `auth` is
|
|
49
|
+
always treated as caller authentication, never ignored, even when empty. Ops whose schema says
|
|
46
50
|
`"auth": "required"` MUST be refused with `AUTH_DENIED` without a valid DSM
|
|
47
51
|
session.
|
|
48
52
|
- `params` MUST be an object valid against `schema/<op>.json`. A member that
|
|
@@ -70,9 +74,67 @@ the executor against the vectors here.
|
|
|
70
74
|
## Status
|
|
71
75
|
|
|
72
76
|
`status` answers `version` (`"1"`), `ready`, `disabled`, `executor_digest`
|
|
73
|
-
and `policy_digest`.
|
|
77
|
+
and `policy_digest`. With `auth` (since 0.9.6) it also answers `allowed`:
|
|
78
|
+
whether DSM's Application Privileges let the caller use the App and File
|
|
79
|
+
Station from `remote_addr`, the check `delegate.create` makes; an invalid
|
|
80
|
+
session is `AUTH_DENIED`. A CGI sends the caller's `auth` so an App the
|
|
81
|
+
executor would refuse is never shown as ready. The executor MUST NOT report the SDK version; the binary
|
|
74
82
|
digest MUST change only when the executor source changes.
|
|
75
83
|
|
|
84
|
+
## Application Portal
|
|
85
|
+
|
|
86
|
+
Since 0.9.6. A policy MAY carry `"portal": {"application": "<display name>",
|
|
87
|
+
"alias": "<default alias>"}` together with both `portal.register` and
|
|
88
|
+
`portal.unregister`; a policy with only some of the three is invalid. The
|
|
89
|
+
executor then registers the App's Application Portal entry the way DSM's
|
|
90
|
+
web-config worker does, on every DSM version: an App whose `os_min_ver` is
|
|
91
|
+
below 7.2 cannot declare that resource, since DSM 7.1 refuses it for unsigned
|
|
92
|
+
packages.
|
|
93
|
+
|
|
94
|
+
- Both ops take no params and require the session of an administrator whom
|
|
95
|
+
Application Privileges allow to use the App (`ADMIN_REQUIRED`,
|
|
96
|
+
`APP_DENIED`). The alias itself stays an administrator's
|
|
97
|
+
`SYNO.Core.AppPortal set`; the executor never writes it.
|
|
98
|
+
- `portal.register` writes `/usr/syno/etc/www/app.d/<package>.mustache`, then
|
|
99
|
+
`<package>.json` (id `SYNO.SDS.<package>.Instance`), runs
|
|
100
|
+
`synow3tool --gen-app=<package>`, and requires `nginx -t` and the App in
|
|
101
|
+
`SYNO.Core.AppPortal list`. Registering again rewrites the same files.
|
|
102
|
+
- `portal.unregister` removes both app.d files and
|
|
103
|
+
`/usr/syno/etc/packages/<package>/AppPortal.json`, disables and
|
|
104
|
+
unregisters every `{dsm,www,alias,.alias}.syno-app-portal.<package>.conf`
|
|
105
|
+
conf and `{server,.server}` site still enabled or still in DSM's registry,
|
|
106
|
+
and reloads nginx once `nginx -t` passes. A step with nothing to remove is
|
|
107
|
+
skipped, so the op MAY be repeated.
|
|
108
|
+
- A failed change is `PORTAL_FAILED`. A failed register is undone the same
|
|
109
|
+
way. Until a later `portal.unregister` succeeds, `status` reports
|
|
110
|
+
`portal` `cleanup-required`.
|
|
111
|
+
- The executor MUST remove the entry when it purges for an uninstall; DSM
|
|
112
|
+
does not.
|
|
113
|
+
- `status` answers `portal` for such a policy: `registered` (the executor's
|
|
114
|
+
own files and DSM's generated conf), `unregistered`, or `cleanup-required`
|
|
115
|
+
(anything else, including a failed change).
|
|
116
|
+
|
|
117
|
+
## Uninstall purge step
|
|
118
|
+
|
|
119
|
+
Since 0.9.7. A policy MAY carry `"purge": "<name>"`, naming one of its `root`
|
|
120
|
+
ops as the App's root step at uninstall; any other value makes the policy
|
|
121
|
+
invalid. Approving that policy is the administrator's consent that the op
|
|
122
|
+
runs as root at uninstall, with no session.
|
|
123
|
+
|
|
124
|
+
- `root.run` MUST refuse that op with `POLICY_DENIED`: a session cannot start
|
|
125
|
+
the uninstall step early.
|
|
126
|
+
- When the package account requests purge, the executor MUST run the op
|
|
127
|
+
before it removes Application Privileges rules, its portal entry and its
|
|
128
|
+
approval tasks, and only while the approval is live: the package ships the
|
|
129
|
+
approved executor and policy pins, and both approval tasks of that policy
|
|
130
|
+
stand with their exact scripts. Otherwise, and on an offline purge, it MUST
|
|
131
|
+
skip the op and log `purge root step skipped: not approved`.
|
|
132
|
+
- The op gets the argument `delete-state` when the package account wrote
|
|
133
|
+
`delete-state` to `var/executor/uninstall` before its request (the
|
|
134
|
+
`executor/lifecycle purge --delete-state` helper does), and no argument
|
|
135
|
+
otherwise. It runs for at most 60 seconds; its exit status and output go to
|
|
136
|
+
the purge log, and a failure MUST NOT stop the rest of the purge.
|
|
137
|
+
|
|
76
138
|
## Grants
|
|
77
139
|
|
|
78
140
|
- A time-limited grant (`job_id`, `ttl_seconds` ≤ 30 days) covers the listed
|
|
@@ -86,11 +148,12 @@ digest MUST change only when the executor source changes.
|
|
|
86
148
|
Application Privileges, scope, directory identity and write permission
|
|
87
149
|
against DSM. A failure the user or an administrator can undo MUST fail only
|
|
88
150
|
that operation and MUST keep the grant: `PERMISSION_DENIED` (the ACL refuses
|
|
89
|
-
the write)
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
151
|
+
the write), `not-found` (the granted folder is not at its path) and, since
|
|
152
|
+
0.9.6, `APP_DENIED` (an Application Privileges rule refuses the account from
|
|
153
|
+
the checked address). Once the cause is fixed, a new operation under the same
|
|
154
|
+
grant succeeds. Any other revalidation failure (`DELEGATION_DENIED`,
|
|
155
|
+
`INELIGIBLE`, `SCOPE_DENIED`, including a different folder at the granted
|
|
156
|
+
path) MUST revoke the grant; the user then chooses the destination again.
|
|
94
157
|
- `files.taskStatus` and `files.taskCancel` follow the task's op and MUST NOT
|
|
95
158
|
be granted directly.
|
|
96
159
|
- An administrator MAY turn the integration off with `delegate.disable`; then
|
|
@@ -154,6 +154,14 @@
|
|
|
154
154
|
"en": "The root operation exited with a non-zero status or failed to run.",
|
|
155
155
|
"zh-TW": "root 操作以非零狀態結束,或無法執行。"
|
|
156
156
|
},
|
|
157
|
+
{
|
|
158
|
+
"code": "PORTAL_FAILED",
|
|
159
|
+
"kind": "refusal",
|
|
160
|
+
"retryable": true,
|
|
161
|
+
"httpStatus": 502,
|
|
162
|
+
"en": "DSM did not accept the Application Portal change; status portal says whether the entry needs another removal.",
|
|
163
|
+
"zh-TW": "DSM 未接受應用程式入口的變更;status 的 portal 說明是否需要再移除一次。"
|
|
164
|
+
},
|
|
157
165
|
{
|
|
158
166
|
"code": "NO_SPACE",
|
|
159
167
|
"kind": "refusal",
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://github.com/synopackageland/syno-pkg-land-sdk/spec/protocol/v1/schema/portal.register.json",
|
|
4
|
+
"title": "portal.register",
|
|
5
|
+
"description": "Administrator: register the policy's Application Portal entry in DSM's app.d (DSM before 7.2 refuses the web-config resource of unsigned packages).",
|
|
6
|
+
"since": "0.9.6",
|
|
7
|
+
"auth": "required",
|
|
8
|
+
"type": "object",
|
|
9
|
+
"properties": {},
|
|
10
|
+
"additionalProperties": false
|
|
11
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://github.com/synopackageland/syno-pkg-land-sdk/spec/protocol/v1/schema/portal.unregister.json",
|
|
4
|
+
"title": "portal.unregister",
|
|
5
|
+
"description": "Administrator: remove the App's Application Portal entry, its saved alias and every nginx conf DSM generated for it.",
|
|
6
|
+
"since": "0.9.6",
|
|
7
|
+
"auth": "required",
|
|
8
|
+
"type": "object",
|
|
9
|
+
"properties": {},
|
|
10
|
+
"additionalProperties": false
|
|
11
|
+
}
|
|
@@ -7,4 +7,5 @@
|
|
|
7
7
|
{"name":"move-missing-size","request":{"v":1,"op":"files.moveFromStaging","params":{"delegation_id":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","job_id":"export-20261009","staging":"exports/report.csv","name":"report.csv"}},"policy":{"v":1,"package":"contract","app":"app","scope":"home","operations":["status","delegate.create","delegate.list","delegate.revoke","files.list","files.write","files.moveFromStaging","files.operationStatus","files.cancelOperation","delegate.disable","delegate.enable","delegate.audit","root.run"],"destinations":["save"],"lifetime":"until-revoked","root":{}},"state":{"grants":[{"id":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","username":"alice","key":"save","path":"/home/exports"}]},"expect":{"ok":false,"code":"INVALID_REQUEST"}}
|
|
8
8
|
{"name":"operation-status-unknown","request":{"v":1,"op":"files.operationStatus","params":{"delegation_id":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","job_id":"export-20261009"}},"policy":{"v":1,"package":"contract","app":"app","scope":"home","operations":["status","delegate.create","delegate.list","delegate.revoke","files.list","files.write","files.moveFromStaging","files.operationStatus","files.cancelOperation","delegate.disable","delegate.enable","delegate.audit","root.run"],"destinations":["save"],"lifetime":"until-revoked","root":{}},"state":{"grants":[{"id":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","username":"alice","key":"save","path":"/home/exports"}]},"expect":{"ok":false,"code":"operation-not-found"}}
|
|
9
9
|
{"name":"root-run-unpinned","request":{"v":1,"op":"root.run","auth":{"dsm_cookie":"admin","dsm_synotoken":"contract-token"},"params":{"name":"whoami"}},"policy":{"v":1,"package":"contract","app":"app","scope":"home","operations":["status","delegate.create","delegate.list","delegate.revoke","files.list","files.write","files.moveFromStaging","files.operationStatus","files.cancelOperation","delegate.disable","delegate.enable","delegate.audit","root.run"],"destinations":["save"],"lifetime":"until-revoked","root":{}},"state":{},"expect":{"ok":false,"code":"POLICY_DENIED"}}
|
|
10
|
+
{"name":"root-run-purge-step","request":{"v":1,"op":"root.run","auth":{"dsm_cookie":"admin","dsm_synotoken":"contract-token"},"params":{"name":"purge"}},"policy":{"v":1,"package":"contract","app":"app","scope":"home","operations":["status","delegate.create","delegate.list","delegate.revoke","files.list","files.write","files.moveFromStaging","files.operationStatus","files.cancelOperation","delegate.disable","delegate.enable","delegate.audit","root.run"],"destinations":["save"],"lifetime":"until-revoked","root":{"purge":"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"},"purge":"purge"},"state":{},"expect":{"ok":false,"code":"POLICY_DENIED"}}
|
|
10
11
|
{"name":"root-run-bad-name","request":{"v":1,"op":"root.run","auth":{"dsm_cookie":"admin","dsm_synotoken":"contract-token"},"params":{"name":"../x"}},"policy":{"v":1,"package":"contract","app":"app","scope":"home","operations":["status","delegate.create","delegate.list","delegate.revoke","files.list","files.write","files.moveFromStaging","files.operationStatus","files.cancelOperation","delegate.disable","delegate.enable","delegate.audit","root.run"],"destinations":["save"],"lifetime":"until-revoked","root":{}},"state":{},"expect":{"ok":false,"code":"INVALID_REQUEST"}}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
{"name":"register","request":{"v":1,"op":"portal.register","auth":{"dsm_cookie":"admin","dsm_synotoken":"contract-token","remote_addr":"192.0.2.1"},"params":{}},"policy":{"v":1,"package":"contract","app":"app","operations":["status","portal.register","portal.unregister"],"portal":{"application":"Contract","alias":"contract"}},"state":{},"expect":{"ok":true,"result":{"entry":"registered"}}}
|
|
2
|
+
{"name":"unregister","request":{"v":1,"op":"portal.unregister","auth":{"dsm_cookie":"admin","dsm_synotoken":"contract-token","remote_addr":"192.0.2.1"},"params":{}},"policy":{"v":1,"package":"contract","app":"app","operations":["status","portal.register","portal.unregister"],"portal":{"application":"Contract","alias":"contract"}},"state":{},"expect":{"ok":true,"result":{"entry":"unregistered"}}}
|
|
3
|
+
{"name":"register-not-admin","request":{"v":1,"op":"portal.register","auth":{"dsm_cookie":"alice","dsm_synotoken":"contract-token","remote_addr":"192.0.2.1"},"params":{}},"policy":{"v":1,"package":"contract","app":"app","operations":["status","portal.register","portal.unregister"],"portal":{"application":"Contract","alias":"contract"}},"state":{},"expect":{"ok":false,"code":"ADMIN_REQUIRED"}}
|
|
4
|
+
{"name":"unregister-not-admin","request":{"v":1,"op":"portal.unregister","auth":{"dsm_cookie":"alice","dsm_synotoken":"contract-token","remote_addr":"192.0.2.1"},"params":{}},"policy":{"v":1,"package":"contract","app":"app","operations":["status","portal.register","portal.unregister"],"portal":{"application":"Contract","alias":"contract"}},"state":{},"expect":{"ok":false,"code":"ADMIN_REQUIRED"}}
|
|
5
|
+
{"name":"register-without-auth","request":{"v":1,"op":"portal.register","params":{}},"policy":{"v":1,"package":"contract","app":"app","operations":["status","portal.register","portal.unregister"],"portal":{"application":"Contract","alias":"contract"}},"state":{},"expect":{"ok":false,"code":"AUTH_DENIED"}}
|
|
6
|
+
{"name":"register-outside-policy","request":{"v":1,"op":"portal.register","auth":{"dsm_cookie":"admin","dsm_synotoken":"contract-token","remote_addr":"192.0.2.1"},"params":{}},"policy":{"v":1,"package":"contract","app":"app","scope":"home","operations":["status","delegate.create","delegate.list","delegate.revoke","files.list","files.write","files.moveFromStaging","files.operationStatus","files.cancelOperation","delegate.disable","delegate.enable","delegate.audit","root.run"],"destinations":["save"],"lifetime":"until-revoked","root":{}},"state":{},"expect":{"ok":false,"code":"POLICY_DENIED"}}
|
|
7
|
+
{"name":"register-with-params","request":{"v":1,"op":"portal.register","auth":{"dsm_cookie":"admin","dsm_synotoken":"contract-token","remote_addr":"192.0.2.1"},"params":{"alias":"x"}},"policy":{"v":1,"package":"contract","app":"app","operations":["status","portal.register","portal.unregister"],"portal":{"application":"Contract","alias":"contract"}},"state":{},"expect":{"ok":false,"code":"INVALID_REQUEST"}}
|
|
8
|
+
{"name":"status-entry","request":{"v":1,"op":"status","params":{}},"policy":{"v":1,"package":"contract","app":"app","operations":["status","portal.register","portal.unregister"],"portal":{"application":"Contract","alias":"contract"}},"state":{},"expect":{"ok":true,"result":{"portal":"unregistered"}}}
|
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
{"name":"ready","request":{"v":1,"op":"status","params":{}},"policy":{"v":1,"package":"contract","app":"app","scope":"home","operations":["status","delegate.create","delegate.list","delegate.revoke","files.list","files.write","files.moveFromStaging","files.operationStatus","files.cancelOperation","delegate.disable","delegate.enable","delegate.audit","root.run"],"destinations":["save"],"lifetime":"until-revoked","root":{}},"state":{},"expect":{"ok":true,"result":{"version":"1","ready":true,"disabled":false,"executor_digest":"<any>","policy_digest":"<any>"}}}
|
|
2
2
|
{"name":"disabled","request":{"v":1,"op":"status","params":{}},"policy":{"v":1,"package":"contract","app":"app","scope":"home","operations":["status","delegate.create","delegate.list","delegate.revoke","files.list","files.write","files.moveFromStaging","files.operationStatus","files.cancelOperation","delegate.disable","delegate.enable","delegate.audit","root.run"],"destinations":["save"],"lifetime":"until-revoked","root":{}},"state":{"disabled":true},"expect":{"ok":true,"result":{"version":"1","ready":true,"disabled":true,"executor_digest":"<any>","policy_digest":"<any>"}}}
|
|
3
|
+
{"name":"caller-allowed","request":{"v":1,"op":"status","params":{},"auth":{"dsm_cookie":"alice","dsm_synotoken":"contract-token","remote_addr":"192.0.2.1"}},"policy":{"v":1,"package":"contract","app":"app","scope":"home","operations":["status","delegate.create","delegate.list","delegate.revoke","files.list","files.write","files.moveFromStaging","files.operationStatus","files.cancelOperation","delegate.disable","delegate.enable","delegate.audit","root.run"],"destinations":["save"],"lifetime":"until-revoked","root":{}},"state":{},"expect":{"ok":true,"result":{"allowed":true}}}
|
package/dist/src/nas/i18n.d.ts
DELETED