@synopackageland/sdk 0.9.4 → 0.9.6
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/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 +1922 -1908
- package/dist/src/context.d.ts +3 -0
- package/dist/src/delegate/save-copy.d.ts +3 -0
- package/dist/src/protocol/v1.d.ts +15 -1
- package/dist/style.css +1 -1
- package/dist/vue.js +1277 -1257
- package/package.json +2 -2
- package/spec/protocol/v1/README.md +51 -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/portal.jsonl +8 -0
- package/spec/protocol/v1/vectors/status.jsonl +1 -0
- package/dist/src/files/FolderIcon.vue.d.ts +0 -8
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@synopackageland/sdk",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.6",
|
|
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,46 @@ 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
|
+
|
|
76
117
|
## Grants
|
|
77
118
|
|
|
78
119
|
- A time-limited grant (`job_id`, `ttl_seconds` ≤ 30 days) covers the listed
|
|
@@ -86,11 +127,12 @@ digest MUST change only when the executor source changes.
|
|
|
86
127
|
Application Privileges, scope, directory identity and write permission
|
|
87
128
|
against DSM. A failure the user or an administrator can undo MUST fail only
|
|
88
129
|
that operation and MUST keep the grant: `PERMISSION_DENIED` (the ACL refuses
|
|
89
|
-
the write)
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
130
|
+
the write), `not-found` (the granted folder is not at its path) and, since
|
|
131
|
+
0.9.6, `APP_DENIED` (an Application Privileges rule refuses the account from
|
|
132
|
+
the checked address). Once the cause is fixed, a new operation under the same
|
|
133
|
+
grant succeeds. Any other revalidation failure (`DELEGATION_DENIED`,
|
|
134
|
+
`INELIGIBLE`, `SCOPE_DENIED`, including a different folder at the granted
|
|
135
|
+
path) MUST revoke the grant; the user then chooses the destination again.
|
|
94
136
|
- `files.taskStatus` and `files.taskCancel` follow the task's op and MUST NOT
|
|
95
137
|
be granted directly.
|
|
96
138
|
- 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
|
+
}
|
|
@@ -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}}}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
type __VLS_Props = {
|
|
2
|
-
size?: number;
|
|
3
|
-
};
|
|
4
|
-
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
5
|
-
size: number;
|
|
6
|
-
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
7
|
-
declare const _default: typeof __VLS_export;
|
|
8
|
-
export default _default;
|