@synopackageland/cli 0.3.10 → 0.4.1
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/LICENSE +21 -0
- package/README.md +57 -9
- package/dist/bin.js +1 -2
- package/dist/build-spk/generator.d.ts +0 -3
- package/dist/build-spk/generator.js +138 -287
- package/dist/build-spk/native-lifecycle.js +0 -3
- package/dist/build-spk/native-payload.js +0 -1
- package/dist/build-spk/notices.d.ts +5 -0
- package/dist/build-spk/notices.js +60 -0
- package/dist/cli.js +178 -151
- package/dist/compose/analyze.d.ts +1 -2
- package/dist/compose/analyze.js +5 -48
- package/dist/contract/unsupported-types.d.ts +10 -0
- package/dist/contract/unsupported-types.js +49 -0
- package/dist/contract/validate.js +25 -2
- package/dist/contract/web-launch.js +0 -2
- package/dist/deploy/deploy.d.ts +1 -4
- package/dist/deploy/deploy.js +45 -156
- package/dist/deploy/homes-values.js +1 -1
- package/dist/deploy/plan.d.ts +18 -0
- package/dist/deploy/plan.js +54 -0
- package/dist/deploy/spk-version.d.ts +2 -14
- package/dist/deploy/spk-version.js +25 -111
- package/dist/dev.d.ts +1 -3
- package/dist/dev.js +14 -28
- package/dist/error-registry.js +830 -862
- package/dist/host/dsm-client.js +12 -272
- package/dist/host/dsm-port-profile.d.ts +0 -1
- package/dist/host/dsm-port-profile.js +0 -2
- package/dist/host/types.d.ts +1 -83
- package/dist/index.d.ts +0 -9
- package/dist/index.js +0 -6
- package/dist/info.d.ts +0 -1
- package/dist/info.js +3 -10
- package/dist/init.d.ts +15 -1
- package/dist/init.js +128 -12
- package/dist/log.js +2 -3
- package/dist/native/validate.js +0 -1
- package/dist/standalone/binary.d.ts +9 -0
- package/dist/standalone/binary.js +67 -0
- package/dist/standalone/build.d.ts +25 -0
- package/dist/standalone/build.js +110 -0
- package/dist/standalone/daemon.d.ts +23 -0
- package/dist/standalone/daemon.js +114 -0
- package/dist/standalone/dsm-window.d.ts +26 -0
- package/dist/standalone/dsm-window.js +291 -0
- package/dist/standalone/helper-inventory.d.ts +16 -0
- package/dist/standalone/helper-inventory.js +2 -0
- package/dist/standalone/helper.d.ts +21 -0
- package/dist/standalone/helper.js +105 -0
- package/dist/standalone/host-adapter.d.ts +5 -0
- package/dist/standalone/host-adapter.js +148 -0
- package/dist/standalone/host-platform.d.ts +13 -0
- package/dist/standalone/host-platform.js +42 -0
- package/dist/standalone/host-types.d.ts +49 -0
- package/dist/standalone/host-types.js +1 -0
- package/dist/standalone/i18n.d.ts +28 -0
- package/dist/standalone/i18n.js +161 -0
- package/dist/standalone/inspect-helper.d.ts +6 -0
- package/dist/standalone/inspect-helper.js +88 -0
- package/dist/standalone/inspect-spk.d.ts +23 -0
- package/dist/standalone/inspect-spk.js +209 -0
- package/dist/standalone/lifecycle-helper.d.ts +2 -0
- package/dist/standalone/lifecycle-helper.js +12 -0
- package/dist/standalone/lifecycle.d.ts +3 -0
- package/dist/standalone/lifecycle.js +53 -0
- package/dist/standalone/manifest.d.ts +73 -0
- package/dist/standalone/manifest.js +279 -0
- package/dist/standalone/reopen-events.d.ts +2 -0
- package/dist/standalone/reopen-events.js +28 -0
- package/dist/standalone/root-messages.d.ts +7 -0
- package/dist/standalone/root-messages.js +259 -0
- package/dist/standalone/root-ops.d.ts +42 -0
- package/dist/standalone/root-ops.js +101 -0
- package/dist/standalone/root-window.d.ts +36 -0
- package/dist/standalone/root-window.js +302 -0
- package/dist/standalone/spk.d.ts +23 -0
- package/dist/standalone/spk.js +192 -0
- package/dist/template-paths.d.ts +2 -0
- package/dist/template-paths.js +9 -0
- package/dist/templates/_daemon/fixture_linux_test.go +15 -0
- package/dist/templates/_daemon/fixture_other_test.go +7 -0
- package/dist/templates/_daemon/go.mod +3 -0
- package/dist/templates/_daemon/main.go +608 -0
- package/dist/templates/_daemon/main_test.go +242 -0
- package/dist/templates/_daemon/process_linux.go +55 -0
- package/dist/templates/_daemon/process_linux_test.go +161 -0
- package/dist/templates/_daemon/process_other.go +14 -0
- package/dist/templates/_daemon/testdata/child.go +41 -0
- package/dist/templates/_shared/GO-LICENSE +27 -0
- package/dist/templates/_shared/GO-PATENTS +22 -0
- package/dist/templates/_shared/LICENSES/TEMPLATE.txt +21 -0
- package/dist/templates/_shared/notice-overrides/index.json +14 -0
- package/dist/templates/_shared/notice-overrides/utils-0.4.2-LICENSE +21 -0
- package/dist/templates/_shared/notice-overrides/utils-0.5.0-LICENSE +21 -0
- package/dist/templates/_shared/third-party-notices.mjs +51 -0
- package/dist/templates/binary/synology-app.yaml +7 -0
- package/dist/templates/hello-files/compose.yaml +0 -1
- package/dist/templates/hello-web/compose.yaml +13 -10
- package/dist/templates/hello-web/html/app.js +1 -23
- package/dist/templates/hello-web/html/index.html +1 -3
- package/dist/templates/hello-web-page/compose.yaml +13 -10
- package/dist/templates/hello-web-page/html/app.js +1 -23
- package/dist/templates/hello-web-page/html/index.html +1 -3
- package/dist/templates/native-go/README.md +324 -0
- package/dist/templates/native-go/backend/THIRD_PARTY_NOTICES.txt +59 -0
- package/dist/templates/native-go/backend/cmd/app/main.go +49 -0
- package/dist/templates/native-go/backend/cmd/dsm-readonly-probe/main_linux.go +46 -0
- package/dist/templates/native-go/backend/cmd/helper/main.go +38 -0
- package/dist/templates/native-go/backend/go.mod +7 -0
- package/dist/templates/native-go/backend/go.sum +4 -0
- package/dist/templates/native-go/backend/internal/api/binary.go +154 -0
- package/dist/templates/native-go/backend/internal/api/binary_test.go +165 -0
- package/dist/templates/native-go/backend/internal/api/errors.go +33 -0
- package/dist/templates/native-go/backend/internal/api/registry.go +104 -0
- package/dist/templates/native-go/backend/internal/api/registry_test.go +329 -0
- package/dist/templates/native-go/backend/internal/api/server.go +159 -0
- package/dist/templates/native-go/backend/internal/app/nas_cgi_artifact_test.go +121 -0
- package/dist/templates/native-go/backend/internal/app/nas_refusal_test.go +46 -0
- package/dist/templates/native-go/backend/internal/app/root_none.go +9 -0
- package/dist/templates/native-go/backend/internal/app/routes.go +138 -0
- package/dist/templates/native-go/backend/internal/app/routes_test.go +172 -0
- package/dist/templates/native-go/backend/internal/dsm/auth.go +118 -0
- package/dist/templates/native-go/backend/internal/dsm/auth_test.go +139 -0
- package/dist/templates/native-go/backend/internal/dsmprobe/collector_linux.go +335 -0
- package/dist/templates/native-go/backend/internal/dsmprobe/collector_linux_test.go +41 -0
- package/dist/templates/native-go/backend/internal/dsmprobe/protocol.go +179 -0
- package/dist/templates/native-go/backend/internal/dsmprobe/protocol_test.go +29 -0
- package/dist/templates/native-go/backend/internal/helper/cohort.go +393 -0
- package/dist/templates/native-go/backend/internal/helper/cohort_publication.go +18 -0
- package/dist/templates/native-go/backend/internal/helper/cohort_publication_test.go +105 -0
- package/dist/templates/native-go/backend/internal/helper/cohort_test.go +372 -0
- package/dist/templates/native-go/backend/internal/helper/control.go +424 -0
- package/dist/templates/native-go/backend/internal/helper/control_test.go +250 -0
- package/dist/templates/native-go/backend/internal/helper/data_contract.go +242 -0
- package/dist/templates/native-go/backend/internal/helper/data_contract_test.go +51 -0
- package/dist/templates/native-go/backend/internal/helper/data_decode.go +184 -0
- package/dist/templates/native-go/backend/internal/helper/data_decode_pointer_test.go +30 -0
- package/dist/templates/native-go/backend/internal/helper/data_protocol.go +416 -0
- package/dist/templates/native-go/backend/internal/helper/data_protocol_test.go +449 -0
- package/dist/templates/native-go/backend/internal/helper/dsm_acl_linux.go +139 -0
- package/dist/templates/native-go/backend/internal/helper/dsm_acl_linux_test.go +121 -0
- package/dist/templates/native-go/backend/internal/helper/dsm_acl_syscall_linux.go +95 -0
- package/dist/templates/native-go/backend/internal/helper/dsm_acl_syscall_linux_test.go +56 -0
- package/dist/templates/native-go/backend/internal/helper/dsm_bridge_linux.go +144 -0
- package/dist/templates/native-go/backend/internal/helper/dsm_bridge_linux_test.go +89 -0
- package/dist/templates/native-go/backend/internal/helper/dsm_home_linux.go +107 -0
- package/dist/templates/native-go/backend/internal/helper/dsm_home_linux_test.go +82 -0
- package/dist/templates/native-go/backend/internal/helper/dsm_probe_transport_linux.go +151 -0
- package/dist/templates/native-go/backend/internal/helper/dsm_probe_transport_linux_test.go +66 -0
- package/dist/templates/native-go/backend/internal/helper/grant_authority.go +516 -0
- package/dist/templates/native-go/backend/internal/helper/grant_authority_contract.go +88 -0
- package/dist/templates/native-go/backend/internal/helper/grant_authority_test.go +510 -0
- package/dist/templates/native-go/backend/internal/helper/grant_cohort.go +389 -0
- package/dist/templates/native-go/backend/internal/helper/grant_cohort_test.go +239 -0
- package/dist/templates/native-go/backend/internal/helper/grant_delivery.go +49 -0
- package/dist/templates/native-go/backend/internal/helper/grant_delivery_methods.go +273 -0
- package/dist/templates/native-go/backend/internal/helper/grant_delivery_test.go +322 -0
- package/dist/templates/native-go/backend/internal/helper/grant_operation_contract.go +47 -0
- package/dist/templates/native-go/backend/internal/helper/grant_readonly_test.go +180 -0
- package/dist/templates/native-go/backend/internal/helper/grant_repository_linux.go +415 -0
- package/dist/templates/native-go/backend/internal/helper/grant_repository_linux_test.go +468 -0
- package/dist/templates/native-go/backend/internal/helper/grant_rpc.go +147 -0
- package/dist/templates/native-go/backend/internal/helper/grant_rpc_test.go +51 -0
- package/dist/templates/native-go/backend/internal/helper/grant_snapshot.go +75 -0
- package/dist/templates/native-go/backend/internal/helper/grant_supervisor_linux.go +134 -0
- package/dist/templates/native-go/backend/internal/helper/grant_supervisor_linux_test.go +254 -0
- package/dist/templates/native-go/backend/internal/helper/lease.go +112 -0
- package/dist/templates/native-go/backend/internal/helper/lease_linux.go +44 -0
- package/dist/templates/native-go/backend/internal/helper/lease_other.go +8 -0
- package/dist/templates/native-go/backend/internal/helper/lifecycle.go +234 -0
- package/dist/templates/native-go/backend/internal/helper/lifecycle_test.go +473 -0
- package/dist/templates/native-go/backend/internal/helper/managed_pilot.go +284 -0
- package/dist/templates/native-go/backend/internal/helper/managed_pilot_repository_linux.go +74 -0
- package/dist/templates/native-go/backend/internal/helper/managed_pilot_repository_linux_test.go +40 -0
- package/dist/templates/native-go/backend/internal/helper/managed_pilot_test.go +210 -0
- package/dist/templates/native-go/backend/internal/helper/nas_shipped_refusal_linux_test.go +97 -0
- package/dist/templates/native-go/backend/internal/helper/native_discovery.go +79 -0
- package/dist/templates/native-go/backend/internal/helper/native_identity.go +89 -0
- package/dist/templates/native-go/backend/internal/helper/native_provider.go +159 -0
- package/dist/templates/native-go/backend/internal/helper/native_provider_test.go +421 -0
- package/dist/templates/native-go/backend/internal/helper/observation.go +204 -0
- package/dist/templates/native-go/backend/internal/helper/observation_health_test.go +115 -0
- package/dist/templates/native-go/backend/internal/helper/observation_reload_budget_test.go +117 -0
- package/dist/templates/native-go/backend/internal/helper/observation_test.go +196 -0
- package/dist/templates/native-go/backend/internal/helper/observer_diagnostic.go +109 -0
- package/dist/templates/native-go/backend/internal/helper/observer_diagnostic_linux.go +76 -0
- package/dist/templates/native-go/backend/internal/helper/observer_diagnostic_linux_test.go +124 -0
- package/dist/templates/native-go/backend/internal/helper/observer_diagnostic_test.go +98 -0
- package/dist/templates/native-go/backend/internal/helper/operation_bootstrap_linux.go +193 -0
- package/dist/templates/native-go/backend/internal/helper/operation_credentials_linux.go +56 -0
- package/dist/templates/native-go/backend/internal/helper/operation_linux.go +480 -0
- package/dist/templates/native-go/backend/internal/helper/operation_linux_test.go +528 -0
- package/dist/templates/native-go/backend/internal/helper/peer_linux.go +44 -0
- package/dist/templates/native-go/backend/internal/helper/peer_other.go +7 -0
- package/dist/templates/native-go/backend/internal/helper/process_linux.go +177 -0
- package/dist/templates/native-go/backend/internal/helper/process_other.go +5 -0
- package/dist/templates/native-go/backend/internal/helper/publication_test.go +178 -0
- package/dist/templates/native-go/backend/internal/helper/read_stream_cohort_linux_test.go +156 -0
- package/dist/templates/native-go/backend/internal/helper/read_transfer.go +40 -0
- package/dist/templates/native-go/backend/internal/helper/read_transfer_linux.go +109 -0
- package/dist/templates/native-go/backend/internal/helper/read_transfer_linux_test.go +118 -0
- package/dist/templates/native-go/backend/internal/helper/read_transfer_test.go +177 -0
- package/dist/templates/native-go/backend/internal/helper/readonly.go +105 -0
- package/dist/templates/native-go/backend/internal/helper/readonly_admission.go +85 -0
- package/dist/templates/native-go/backend/internal/helper/readonly_cohort_linux_test.go +253 -0
- package/dist/templates/native-go/backend/internal/helper/readonly_linux_test.go +378 -0
- package/dist/templates/native-go/backend/internal/helper/readonly_mount_linux.go +65 -0
- package/dist/templates/native-go/backend/internal/helper/readonly_mount_proxy_linux.go +113 -0
- package/dist/templates/native-go/backend/internal/helper/readonly_operations_linux.go +168 -0
- package/dist/templates/native-go/backend/internal/helper/readonly_resolver_linux.go +241 -0
- package/dist/templates/native-go/backend/internal/helper/readonly_test.go +40 -0
- package/dist/templates/native-go/backend/internal/helper/relaxed_identity.go +252 -0
- package/dist/templates/native-go/backend/internal/helper/relaxed_identity_contract.go +105 -0
- package/dist/templates/native-go/backend/internal/helper/relaxed_identity_test.go +406 -0
- package/dist/templates/native-go/backend/internal/helper/relaxed_invalidation.go +200 -0
- package/dist/templates/native-go/backend/internal/helper/repair.go +132 -0
- package/dist/templates/native-go/backend/internal/helper/repair_test.go +271 -0
- package/dist/templates/native-go/backend/internal/helper/s1r_actor_acl_linux_test.go +303 -0
- package/dist/templates/native-go/backend/internal/helper/s1r_actor_fixture_linux_test.go +184 -0
- package/dist/templates/native-go/backend/internal/helper/s1r_actor_races_linux_test.go +231 -0
- package/dist/templates/native-go/backend/internal/helper/s1r_fixture_contract_linux_test.go +18 -0
- package/dist/templates/native-go/backend/internal/helper/server_linux.go +124 -0
- package/dist/templates/native-go/backend/internal/helper/status.go +334 -0
- package/dist/templates/native-go/backend/internal/helper/status_test.go +288 -0
- package/dist/templates/native-go/backend/internal/helper/supervision.go +107 -0
- package/dist/templates/native-go/backend/internal/helper/supervision_test.go +124 -0
- package/dist/templates/native-go/backend/internal/helper/supervisor_frame.go +76 -0
- package/dist/templates/native-go/backend/internal/helper/supervisor_frame_linux_test.go +69 -0
- package/dist/templates/native-go/backend/internal/helper/supervisor_frame_test.go +107 -0
- package/dist/templates/native-go/backend/internal/helper/supervisor_linux.go +363 -0
- package/dist/templates/native-go/backend/internal/helper/supervisor_linux_test.go +913 -0
- package/dist/templates/native-go/backend/internal/helper/supervisor_socket_eof_test.go +74 -0
- package/dist/templates/native-go/backend/internal/helper/supervisor_socket_test.go +45 -0
- package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/create.json +23 -0
- package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/frames.json +67 -0
- package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/grant-store.json +52 -0
- package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/intent.json +20 -0
- package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/list.json +20 -0
- package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/publish.json +20 -0
- package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/read.json +22 -0
- package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/stat.json +22 -0
- package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/write-stream.json +22 -0
- package/dist/templates/native-go/backend/internal/helper/unit_connection.go +75 -0
- package/dist/templates/native-go/backend/internal/helper/unit_connection_linux_test.go +135 -0
- package/dist/templates/native-go/backend/internal/helper/unit_connection_test.go +133 -0
- package/dist/templates/native-go/backend/internal/helper/unit_frame_test.go +32 -0
- package/dist/templates/native-go/backend/internal/helper/unit_linux.go +364 -0
- package/dist/templates/native-go/backend/internal/helper/unit_linux_test.go +46 -0
- package/dist/templates/native-go/backend/internal/helper/unit_mechanisms_linux_test.go +217 -0
- package/dist/templates/native-go/backend/internal/helper/unit_padding_linux_test.go +178 -0
- package/dist/templates/native-go/backend/internal/helper/unit_query_linux.go +111 -0
- package/dist/templates/native-go/backend/internal/helper/unit_reload_linux_test.go +372 -0
- package/dist/templates/native-go/backend/internal/helper/unit_reload_sequence_linux_test.go +232 -0
- package/dist/templates/native-go/backend/internal/helper/write.go +77 -0
- package/dist/templates/native-go/backend/internal/helper/write_admission.go +260 -0
- package/dist/templates/native-go/backend/internal/helper/write_admission_test.go +135 -0
- package/dist/templates/native-go/backend/internal/helper/write_cohort_linux_test.go +218 -0
- package/dist/templates/native-go/backend/internal/helper/write_files_linux.go +202 -0
- package/dist/templates/native-go/backend/internal/helper/write_files_linux_test.go +199 -0
- package/dist/templates/native-go/backend/internal/helper/write_intent_linux.go +116 -0
- package/dist/templates/native-go/backend/internal/helper/write_intent_linux_test.go +74 -0
- package/dist/templates/native-go/backend/internal/helper/write_operation_linux.go +245 -0
- package/dist/templates/native-go/backend/internal/helper/write_test.go +53 -0
- package/dist/templates/native-go/dsm-package.yaml +58 -0
- package/dist/templates/native-go/gitignore +1 -0
- package/dist/templates/native-go/i18n/glossary.json +662 -0
- package/dist/templates/native-go/i18n/messages/de.json +28 -0
- package/dist/templates/native-go/i18n/messages/en.json +28 -0
- package/dist/templates/native-go/i18n/messages/es.json +28 -0
- package/dist/templates/native-go/i18n/messages/fr.json +28 -0
- package/dist/templates/native-go/i18n/messages/it.json +28 -0
- package/dist/templates/native-go/i18n/messages/ja.json +28 -0
- package/dist/templates/native-go/i18n/messages/ko.json +28 -0
- package/dist/templates/native-go/i18n/messages/zh-CN.json +28 -0
- package/dist/templates/native-go/i18n/messages/zh-TW.json +28 -0
- package/dist/templates/native-go/ui/app.css +35 -0
- package/dist/templates/native-go/ui/app.js +101 -0
- package/dist/templates/native-go-better-auth/backend/internal/app/identity.go +208 -0
- package/dist/templates/native-go-better-auth/backend/internal/app/identity_test.go +113 -0
- package/dist/templates/native-go-better-auth/node/app.mjs +72 -0
- package/dist/templates/native-go-better-auth/node/build.mjs +4 -0
- package/dist/templates/native-go-better-auth/node/package-lock.json +862 -0
- package/dist/templates/native-go-better-auth/node/package.json +1 -0
- package/dist/templates/native-go-better-auth/node/test/auth.test.mjs +31 -0
- package/dist/templates/native-go-integration/backend/internal/app/identity_none.go +6 -0
- package/dist/templates/native-go-integration/backend/internal/app/personal.go +203 -0
- package/dist/templates/native-go-integration/backend/internal/app/personal_test.go +119 -0
- package/dist/templates/native-go-root/backend/internal/app/root.go +107 -0
- package/dist/templates/native-go-root/backend/internal/app/root_test.go +124 -0
- package/dist/templates/native-go-root/root/whoami.sh +6 -0
- package/dist/templates/native-go-vue/README.md +224 -0
- package/dist/templates/native-go-vue/frontend/DESIGN.md +78 -0
- package/dist/templates/native-go-vue/frontend/package-lock.json +2410 -0
- package/dist/templates/native-go-vue/frontend/package.json +6 -0
- package/dist/templates/native-go-vue/frontend/src/App.vue +159 -0
- package/dist/templates/native-go-vue/frontend/src/context.ts +56 -0
- package/dist/templates/native-go-vue/frontend/src/main.ts +29 -0
- package/dist/templates/native-go-vue/frontend/src/nas/NasGrantSettings.vue +74 -0
- package/dist/templates/native-go-vue/frontend/src/nas/NasPathPicker.vue +106 -0
- package/dist/templates/native-go-vue/frontend/src/nas/NasUnavailable.vue +20 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/de.json +74 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/en.json +74 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/es.json +74 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/fr.json +74 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/it.json +74 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/ja.json +74 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/ko.json +74 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/zh-CN.json +74 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/zh-TW.json +74 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n.ts +38 -0
- package/dist/templates/native-go-vue/frontend/src/nas/mock-provider.ts +119 -0
- package/dist/templates/native-go-vue/frontend/src/nas/provider.ts +59 -0
- package/dist/templates/native-go-vue/frontend/src/nas/use-request.ts +27 -0
- package/dist/templates/native-go-vue/frontend/src/style.css +31 -0
- package/dist/templates/native-go-vue/frontend/test/apps.test.ts +190 -0
- package/dist/templates/native-go-vue/frontend/test/nas-provider.test.ts +81 -0
- package/dist/templates/native-go-vue/frontend/test/nas-request.test.ts +21 -0
- package/dist/templates/native-go-vue/frontend/test/nas-ui.test.ts +261 -0
- package/dist/templates/native-go-vue/frontend/tsconfig.json +1 -0
- package/dist/templates/native-go-vue/frontend/vite.config.ts +10 -0
- package/dist/templates/native-go-vue/gitignore +2 -0
- package/dist/types.d.ts +1 -1
- package/dist/validate.js +11 -7
- package/package.json +5 -8
- package/schema/synology-app.schema.json +36 -37
- package/skills/SKILL.md +4 -48
- package/skills/reference/create.md +11 -83
- package/skills/reference/deploy.md +7 -78
- package/skills/reference/diagnose.md +4 -101
- package/skills/reference/files.md +5 -41
- package/skills/reference/identity.md +3 -29
- package/skills/reference/wrap.md +0 -2
- package/templates/_daemon/fixture_linux_test.go +15 -0
- package/templates/_daemon/fixture_other_test.go +7 -0
- package/templates/_daemon/go.mod +3 -0
- package/templates/_daemon/main.go +608 -0
- package/templates/_daemon/main_test.go +242 -0
- package/templates/_daemon/process_linux.go +55 -0
- package/templates/_daemon/process_linux_test.go +161 -0
- package/templates/_daemon/process_other.go +14 -0
- package/templates/_daemon/testdata/child.go +41 -0
- package/templates/_shared/GO-LICENSE +27 -0
- package/templates/_shared/GO-PATENTS +22 -0
- package/templates/_shared/LICENSES/TEMPLATE.txt +21 -0
- package/templates/_shared/notice-overrides/index.json +14 -0
- package/templates/_shared/notice-overrides/utils-0.4.2-LICENSE +21 -0
- package/templates/_shared/notice-overrides/utils-0.5.0-LICENSE +21 -0
- package/templates/_shared/third-party-notices.mjs +51 -0
- package/templates/binary/synology-app.yaml +7 -0
- package/templates/hello-files/compose.yaml +0 -1
- package/templates/hello-web/compose.yaml +13 -10
- package/templates/hello-web/html/app.js +1 -23
- package/templates/hello-web/html/index.html +1 -3
- package/templates/hello-web-page/compose.yaml +13 -10
- package/templates/hello-web-page/html/app.js +1 -23
- package/templates/hello-web-page/html/index.html +1 -3
- package/templates/native-go/README.md +324 -0
- package/templates/native-go/backend/THIRD_PARTY_NOTICES.txt +59 -0
- package/templates/native-go/backend/cmd/app/main.go +49 -0
- package/templates/native-go/backend/cmd/dsm-readonly-probe/main_linux.go +46 -0
- package/templates/native-go/backend/cmd/helper/main.go +38 -0
- package/templates/native-go/backend/go.mod +7 -0
- package/templates/native-go/backend/go.sum +4 -0
- package/templates/native-go/backend/internal/api/binary.go +154 -0
- package/templates/native-go/backend/internal/api/binary_test.go +165 -0
- package/templates/native-go/backend/internal/api/errors.go +33 -0
- package/templates/native-go/backend/internal/api/registry.go +104 -0
- package/templates/native-go/backend/internal/api/registry_test.go +329 -0
- package/templates/native-go/backend/internal/api/server.go +159 -0
- package/templates/native-go/backend/internal/app/nas_cgi_artifact_test.go +121 -0
- package/templates/native-go/backend/internal/app/nas_refusal_test.go +46 -0
- package/templates/native-go/backend/internal/app/root_none.go +9 -0
- package/templates/native-go/backend/internal/app/routes.go +138 -0
- package/templates/native-go/backend/internal/app/routes_test.go +172 -0
- package/templates/native-go/backend/internal/dsm/auth.go +118 -0
- package/templates/native-go/backend/internal/dsm/auth_test.go +139 -0
- package/templates/native-go/backend/internal/dsmprobe/collector_linux.go +335 -0
- package/templates/native-go/backend/internal/dsmprobe/collector_linux_test.go +41 -0
- package/templates/native-go/backend/internal/dsmprobe/protocol.go +179 -0
- package/templates/native-go/backend/internal/dsmprobe/protocol_test.go +29 -0
- package/templates/native-go/backend/internal/helper/cohort.go +393 -0
- package/templates/native-go/backend/internal/helper/cohort_publication.go +18 -0
- package/templates/native-go/backend/internal/helper/cohort_publication_test.go +105 -0
- package/templates/native-go/backend/internal/helper/cohort_test.go +372 -0
- package/templates/native-go/backend/internal/helper/control.go +424 -0
- package/templates/native-go/backend/internal/helper/control_test.go +250 -0
- package/templates/native-go/backend/internal/helper/data_contract.go +242 -0
- package/templates/native-go/backend/internal/helper/data_contract_test.go +51 -0
- package/templates/native-go/backend/internal/helper/data_decode.go +184 -0
- package/templates/native-go/backend/internal/helper/data_decode_pointer_test.go +30 -0
- package/templates/native-go/backend/internal/helper/data_protocol.go +416 -0
- package/templates/native-go/backend/internal/helper/data_protocol_test.go +449 -0
- package/templates/native-go/backend/internal/helper/dsm_acl_linux.go +139 -0
- package/templates/native-go/backend/internal/helper/dsm_acl_linux_test.go +121 -0
- package/templates/native-go/backend/internal/helper/dsm_acl_syscall_linux.go +95 -0
- package/templates/native-go/backend/internal/helper/dsm_acl_syscall_linux_test.go +56 -0
- package/templates/native-go/backend/internal/helper/dsm_bridge_linux.go +144 -0
- package/templates/native-go/backend/internal/helper/dsm_bridge_linux_test.go +89 -0
- package/templates/native-go/backend/internal/helper/dsm_home_linux.go +107 -0
- package/templates/native-go/backend/internal/helper/dsm_home_linux_test.go +82 -0
- package/templates/native-go/backend/internal/helper/dsm_probe_transport_linux.go +151 -0
- package/templates/native-go/backend/internal/helper/dsm_probe_transport_linux_test.go +66 -0
- package/templates/native-go/backend/internal/helper/grant_authority.go +516 -0
- package/templates/native-go/backend/internal/helper/grant_authority_contract.go +88 -0
- package/templates/native-go/backend/internal/helper/grant_authority_test.go +510 -0
- package/templates/native-go/backend/internal/helper/grant_cohort.go +389 -0
- package/templates/native-go/backend/internal/helper/grant_cohort_test.go +239 -0
- package/templates/native-go/backend/internal/helper/grant_delivery.go +49 -0
- package/templates/native-go/backend/internal/helper/grant_delivery_methods.go +273 -0
- package/templates/native-go/backend/internal/helper/grant_delivery_test.go +322 -0
- package/templates/native-go/backend/internal/helper/grant_operation_contract.go +47 -0
- package/templates/native-go/backend/internal/helper/grant_readonly_test.go +180 -0
- package/templates/native-go/backend/internal/helper/grant_repository_linux.go +415 -0
- package/templates/native-go/backend/internal/helper/grant_repository_linux_test.go +468 -0
- package/templates/native-go/backend/internal/helper/grant_rpc.go +147 -0
- package/templates/native-go/backend/internal/helper/grant_rpc_test.go +51 -0
- package/templates/native-go/backend/internal/helper/grant_snapshot.go +75 -0
- package/templates/native-go/backend/internal/helper/grant_supervisor_linux.go +134 -0
- package/templates/native-go/backend/internal/helper/grant_supervisor_linux_test.go +254 -0
- package/templates/native-go/backend/internal/helper/lease.go +112 -0
- package/templates/native-go/backend/internal/helper/lease_linux.go +44 -0
- package/templates/native-go/backend/internal/helper/lease_other.go +8 -0
- package/templates/native-go/backend/internal/helper/lifecycle.go +234 -0
- package/templates/native-go/backend/internal/helper/lifecycle_test.go +473 -0
- package/templates/native-go/backend/internal/helper/managed_pilot.go +284 -0
- package/templates/native-go/backend/internal/helper/managed_pilot_repository_linux.go +74 -0
- package/templates/native-go/backend/internal/helper/managed_pilot_repository_linux_test.go +40 -0
- package/templates/native-go/backend/internal/helper/managed_pilot_test.go +210 -0
- package/templates/native-go/backend/internal/helper/nas_shipped_refusal_linux_test.go +97 -0
- package/templates/native-go/backend/internal/helper/native_discovery.go +79 -0
- package/templates/native-go/backend/internal/helper/native_identity.go +89 -0
- package/templates/native-go/backend/internal/helper/native_provider.go +159 -0
- package/templates/native-go/backend/internal/helper/native_provider_test.go +421 -0
- package/templates/native-go/backend/internal/helper/observation.go +204 -0
- package/templates/native-go/backend/internal/helper/observation_health_test.go +115 -0
- package/templates/native-go/backend/internal/helper/observation_reload_budget_test.go +117 -0
- package/templates/native-go/backend/internal/helper/observation_test.go +196 -0
- package/templates/native-go/backend/internal/helper/observer_diagnostic.go +109 -0
- package/templates/native-go/backend/internal/helper/observer_diagnostic_linux.go +76 -0
- package/templates/native-go/backend/internal/helper/observer_diagnostic_linux_test.go +124 -0
- package/templates/native-go/backend/internal/helper/observer_diagnostic_test.go +98 -0
- package/templates/native-go/backend/internal/helper/operation_bootstrap_linux.go +193 -0
- package/templates/native-go/backend/internal/helper/operation_credentials_linux.go +56 -0
- package/templates/native-go/backend/internal/helper/operation_linux.go +480 -0
- package/templates/native-go/backend/internal/helper/operation_linux_test.go +528 -0
- package/templates/native-go/backend/internal/helper/peer_linux.go +44 -0
- package/templates/native-go/backend/internal/helper/peer_other.go +7 -0
- package/templates/native-go/backend/internal/helper/process_linux.go +177 -0
- package/templates/native-go/backend/internal/helper/process_other.go +5 -0
- package/templates/native-go/backend/internal/helper/publication_test.go +178 -0
- package/templates/native-go/backend/internal/helper/read_stream_cohort_linux_test.go +156 -0
- package/templates/native-go/backend/internal/helper/read_transfer.go +40 -0
- package/templates/native-go/backend/internal/helper/read_transfer_linux.go +109 -0
- package/templates/native-go/backend/internal/helper/read_transfer_linux_test.go +118 -0
- package/templates/native-go/backend/internal/helper/read_transfer_test.go +177 -0
- package/templates/native-go/backend/internal/helper/readonly.go +105 -0
- package/templates/native-go/backend/internal/helper/readonly_admission.go +85 -0
- package/templates/native-go/backend/internal/helper/readonly_cohort_linux_test.go +253 -0
- package/templates/native-go/backend/internal/helper/readonly_linux_test.go +378 -0
- package/templates/native-go/backend/internal/helper/readonly_mount_linux.go +65 -0
- package/templates/native-go/backend/internal/helper/readonly_mount_proxy_linux.go +113 -0
- package/templates/native-go/backend/internal/helper/readonly_operations_linux.go +168 -0
- package/templates/native-go/backend/internal/helper/readonly_resolver_linux.go +241 -0
- package/templates/native-go/backend/internal/helper/readonly_test.go +40 -0
- package/templates/native-go/backend/internal/helper/relaxed_identity.go +252 -0
- package/templates/native-go/backend/internal/helper/relaxed_identity_contract.go +105 -0
- package/templates/native-go/backend/internal/helper/relaxed_identity_test.go +406 -0
- package/templates/native-go/backend/internal/helper/relaxed_invalidation.go +200 -0
- package/templates/native-go/backend/internal/helper/repair.go +132 -0
- package/templates/native-go/backend/internal/helper/repair_test.go +271 -0
- package/templates/native-go/backend/internal/helper/s1r_actor_acl_linux_test.go +303 -0
- package/templates/native-go/backend/internal/helper/s1r_actor_fixture_linux_test.go +184 -0
- package/templates/native-go/backend/internal/helper/s1r_actor_races_linux_test.go +231 -0
- package/templates/native-go/backend/internal/helper/s1r_fixture_contract_linux_test.go +18 -0
- package/templates/native-go/backend/internal/helper/server_linux.go +124 -0
- package/templates/native-go/backend/internal/helper/status.go +334 -0
- package/templates/native-go/backend/internal/helper/status_test.go +288 -0
- package/templates/native-go/backend/internal/helper/supervision.go +107 -0
- package/templates/native-go/backend/internal/helper/supervision_test.go +124 -0
- package/templates/native-go/backend/internal/helper/supervisor_frame.go +76 -0
- package/templates/native-go/backend/internal/helper/supervisor_frame_linux_test.go +69 -0
- package/templates/native-go/backend/internal/helper/supervisor_frame_test.go +107 -0
- package/templates/native-go/backend/internal/helper/supervisor_linux.go +363 -0
- package/templates/native-go/backend/internal/helper/supervisor_linux_test.go +913 -0
- package/templates/native-go/backend/internal/helper/supervisor_socket_eof_test.go +74 -0
- package/templates/native-go/backend/internal/helper/supervisor_socket_test.go +45 -0
- package/templates/native-go/backend/internal/helper/testdata/protocol2/create.json +23 -0
- package/templates/native-go/backend/internal/helper/testdata/protocol2/frames.json +67 -0
- package/templates/native-go/backend/internal/helper/testdata/protocol2/grant-store.json +52 -0
- package/templates/native-go/backend/internal/helper/testdata/protocol2/intent.json +20 -0
- package/templates/native-go/backend/internal/helper/testdata/protocol2/list.json +20 -0
- package/templates/native-go/backend/internal/helper/testdata/protocol2/publish.json +20 -0
- package/templates/native-go/backend/internal/helper/testdata/protocol2/read.json +22 -0
- package/templates/native-go/backend/internal/helper/testdata/protocol2/stat.json +22 -0
- package/templates/native-go/backend/internal/helper/testdata/protocol2/write-stream.json +22 -0
- package/templates/native-go/backend/internal/helper/unit_connection.go +75 -0
- package/templates/native-go/backend/internal/helper/unit_connection_linux_test.go +135 -0
- package/templates/native-go/backend/internal/helper/unit_connection_test.go +133 -0
- package/templates/native-go/backend/internal/helper/unit_frame_test.go +32 -0
- package/templates/native-go/backend/internal/helper/unit_linux.go +364 -0
- package/templates/native-go/backend/internal/helper/unit_linux_test.go +46 -0
- package/templates/native-go/backend/internal/helper/unit_mechanisms_linux_test.go +217 -0
- package/templates/native-go/backend/internal/helper/unit_padding_linux_test.go +178 -0
- package/templates/native-go/backend/internal/helper/unit_query_linux.go +111 -0
- package/templates/native-go/backend/internal/helper/unit_reload_linux_test.go +372 -0
- package/templates/native-go/backend/internal/helper/unit_reload_sequence_linux_test.go +232 -0
- package/templates/native-go/backend/internal/helper/write.go +77 -0
- package/templates/native-go/backend/internal/helper/write_admission.go +260 -0
- package/templates/native-go/backend/internal/helper/write_admission_test.go +135 -0
- package/templates/native-go/backend/internal/helper/write_cohort_linux_test.go +218 -0
- package/templates/native-go/backend/internal/helper/write_files_linux.go +202 -0
- package/templates/native-go/backend/internal/helper/write_files_linux_test.go +199 -0
- package/templates/native-go/backend/internal/helper/write_intent_linux.go +116 -0
- package/templates/native-go/backend/internal/helper/write_intent_linux_test.go +74 -0
- package/templates/native-go/backend/internal/helper/write_operation_linux.go +245 -0
- package/templates/native-go/backend/internal/helper/write_test.go +53 -0
- package/templates/native-go/dsm-package.yaml +58 -0
- package/templates/native-go/gitignore +1 -0
- package/templates/native-go/i18n/glossary.json +662 -0
- package/templates/native-go/i18n/messages/de.json +28 -0
- package/templates/native-go/i18n/messages/en.json +28 -0
- package/templates/native-go/i18n/messages/es.json +28 -0
- package/templates/native-go/i18n/messages/fr.json +28 -0
- package/templates/native-go/i18n/messages/it.json +28 -0
- package/templates/native-go/i18n/messages/ja.json +28 -0
- package/templates/native-go/i18n/messages/ko.json +28 -0
- package/templates/native-go/i18n/messages/zh-CN.json +28 -0
- package/templates/native-go/i18n/messages/zh-TW.json +28 -0
- package/templates/native-go/ui/app.css +35 -0
- package/templates/native-go/ui/app.js +101 -0
- package/templates/native-go-better-auth/backend/internal/app/identity.go +208 -0
- package/templates/native-go-better-auth/backend/internal/app/identity_test.go +113 -0
- package/templates/native-go-better-auth/node/app.mjs +72 -0
- package/templates/native-go-better-auth/node/build.mjs +4 -0
- package/templates/native-go-better-auth/node/package-lock.json +862 -0
- package/templates/native-go-better-auth/node/package.json +1 -0
- package/templates/native-go-better-auth/node/test/auth.test.mjs +31 -0
- package/templates/native-go-integration/backend/internal/app/identity_none.go +6 -0
- package/templates/native-go-integration/backend/internal/app/personal.go +203 -0
- package/templates/native-go-integration/backend/internal/app/personal_test.go +119 -0
- package/templates/native-go-root/backend/internal/app/root.go +107 -0
- package/templates/native-go-root/backend/internal/app/root_test.go +124 -0
- package/templates/native-go-root/root/whoami.sh +6 -0
- package/templates/native-go-vue/README.md +224 -0
- package/templates/native-go-vue/frontend/DESIGN.md +78 -0
- package/templates/native-go-vue/frontend/package-lock.json +2410 -0
- package/templates/native-go-vue/frontend/package.json +6 -0
- package/templates/native-go-vue/frontend/src/App.vue +159 -0
- package/templates/native-go-vue/frontend/src/context.ts +56 -0
- package/templates/native-go-vue/frontend/src/main.ts +29 -0
- package/templates/native-go-vue/frontend/src/nas/NasGrantSettings.vue +74 -0
- package/templates/native-go-vue/frontend/src/nas/NasPathPicker.vue +106 -0
- package/templates/native-go-vue/frontend/src/nas/NasUnavailable.vue +20 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/de.json +74 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/en.json +74 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/es.json +74 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/fr.json +74 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/it.json +74 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/ja.json +74 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/ko.json +74 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/zh-CN.json +74 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/zh-TW.json +74 -0
- package/templates/native-go-vue/frontend/src/nas/i18n.ts +38 -0
- package/templates/native-go-vue/frontend/src/nas/mock-provider.ts +119 -0
- package/templates/native-go-vue/frontend/src/nas/provider.ts +59 -0
- package/templates/native-go-vue/frontend/src/nas/use-request.ts +27 -0
- package/templates/native-go-vue/frontend/src/style.css +31 -0
- package/templates/native-go-vue/frontend/test/apps.test.ts +190 -0
- package/templates/native-go-vue/frontend/test/nas-provider.test.ts +81 -0
- package/templates/native-go-vue/frontend/test/nas-request.test.ts +21 -0
- package/templates/native-go-vue/frontend/test/nas-ui.test.ts +261 -0
- package/templates/native-go-vue/frontend/tsconfig.json +1 -0
- package/templates/native-go-vue/frontend/vite.config.ts +10 -0
- package/templates/native-go-vue/gitignore +2 -0
- package/dist/attestation/app-package.d.ts +0 -86
- package/dist/attestation/app-package.js +0 -206
- package/dist/attestation/install-on-host.d.ts +0 -14
- package/dist/attestation/install-on-host.js +0 -52
- package/dist/attestation/keyring.d.ts +0 -21
- package/dist/attestation/keyring.js +0 -168
- package/dist/attestation/platform-service.d.ts +0 -70
- package/dist/attestation/platform-service.js +0 -250
- package/dist/build-spk/broker-glue.d.ts +0 -16
- package/dist/build-spk/broker-glue.js +0 -40
- package/dist/deploy/catalog-publish.d.ts +0 -3
- package/dist/deploy/catalog-publish.js +0 -7
- package/dist/doctor.d.ts +0 -22
- package/dist/doctor.js +0 -822
- package/dist/error-collector.d.ts +0 -2
- package/dist/error-collector.js +0 -46
- package/dist/host/broker-paths.d.ts +0 -1
- package/dist/host/broker-paths.js +0 -1
- package/dist/host/broker-upgrade-preflight.d.ts +0 -61
- package/dist/host/broker-upgrade-preflight.js +0 -156
- package/dist/host/digests.d.ts +0 -5
- package/dist/host/digests.js +0 -63
- package/dist/host/fake-nas.d.ts +0 -49
- package/dist/host/fake-nas.js +0 -193
- package/dist/mock-broker/bootstrap.d.ts +0 -2
- package/dist/mock-broker/bootstrap.js +0 -8
- package/dist/mock-broker/files.d.ts +0 -60
- package/dist/mock-broker/files.js +0 -408
- package/dist/mock-broker/oidc.d.ts +0 -31
- package/dist/mock-broker/oidc.js +0 -161
- package/dist/mock-broker/path.d.ts +0 -9
- package/dist/mock-broker/path.js +0 -50
- package/dist/mock-broker/server.d.ts +0 -19
- package/dist/mock-broker/server.js +0 -350
- package/dist/publish/build-ledger.d.ts +0 -22
- package/dist/publish/build-ledger.js +0 -26
- package/dist/publish/community-path.d.ts +0 -6
- package/dist/publish/community-path.js +0 -41
- package/dist/publish/curated-release.d.ts +0 -78
- package/dist/publish/curated-release.js +0 -883
- package/dist/publish/file-build-ledger.d.ts +0 -18
- package/dist/publish/file-build-ledger.js +0 -268
- package/dist/publish/github-pr.d.ts +0 -25
- package/dist/publish/github-pr.js +0 -85
- package/dist/publish/github-repo.d.ts +0 -8
- package/dist/publish/github-repo.js +0 -21
- package/dist/publish/platform-service-release.d.ts +0 -60
- package/dist/publish/platform-service-release.js +0 -333
- package/dist/publish/preflight.d.ts +0 -24
- package/dist/publish/preflight.js +0 -138
- package/dist/publish/publish.d.ts +0 -27
- package/dist/publish/publish.js +0 -136
- package/dist/publish/sync-definition.d.ts +0 -4
- package/dist/publish/sync-definition.js +0 -48
- package/dist/release-bin.d.ts +0 -2
- package/dist/release-bin.js +0 -23
- package/dist/templates/hello-web/html/sdk.js +0 -68
- package/dist/templates/hello-web-page/html/sdk.js +0 -68
- package/dist/templates/native/synology-app.yaml +0 -7
- package/dist/test-host.d.ts +0 -15
- package/dist/test-host.js +0 -37
- package/templates/hello-web/html/sdk.js +0 -68
- package/templates/hello-web-page/html/sdk.js +0 -68
- package/templates/native/synology-app.yaml +0 -7
- /package/dist/templates/{native → binary}/native.yaml +0 -0
- /package/templates/{native → binary}/native.yaml +0 -0
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
// @vitest-environment jsdom
|
|
2
|
+
import {expect, test, vi} from 'vitest'
|
|
3
|
+
import {nextTick} from 'vue'
|
|
4
|
+
import {mount} from '../src/main'
|
|
5
|
+
import {createMockNasService} from '../src/nas/mock-provider'
|
|
6
|
+
import {catalogs, nasCopy, format, errorCopy} from '../src/nas/i18n'
|
|
7
|
+
import type {NasProvider} from '../src/nas/provider'
|
|
8
|
+
import type {Context} from '../src/context'
|
|
9
|
+
|
|
10
|
+
async function settle() {for(let i=0;i<20;i++){await Promise.resolve();await nextTick()}await new Promise(r=>setTimeout(r,25))}
|
|
11
|
+
function click(root:HTMLElement, text:string) {const b=[...root.querySelectorAll('button')].find(b=>b.textContent?.trim()===text || b.getAttribute('aria-label')===text);expect(b,text).toBeTruthy();b!.click()}
|
|
12
|
+
function fixture(nas:NasProvider | undefined, user='normal1', locale='en') {
|
|
13
|
+
const root=document.createElement('div');document.body.append(root)
|
|
14
|
+
const reopen:Array<()=>void>=[]
|
|
15
|
+
const ctx={locale,reopen(fn:()=>void){reopen.push(fn)},call:vi.fn(async(method:string)=> {
|
|
16
|
+
if(method==='app.status') return {package:'SamePackage',version:'1',user,admin:user==='admin'}
|
|
17
|
+
if(method==='integration.status') return {state:'not-enabled',reason:'not-requested',packageRunning:'unknown',scheduler:'not-probed'}
|
|
18
|
+
throw {code:'unknown_method'}
|
|
19
|
+
})} as Context
|
|
20
|
+
const app=mount(root,ctx,{nasProvider:nas})
|
|
21
|
+
return {root,app,ctx,reopen}
|
|
22
|
+
}
|
|
23
|
+
function cleanup(...fixtures:ReturnType<typeof fixture>[]) {for(const f of fixtures){f.app.unmount();f.root.remove()}}
|
|
24
|
+
|
|
25
|
+
test('managed account pilot stays visibly off with maintenance and approval restrictions',async()=> {
|
|
26
|
+
const f=fixture(createMockNasService().connect('admin'),'admin')
|
|
27
|
+
try {
|
|
28
|
+
await settle()
|
|
29
|
+
expect(f.root.textContent).toContain('Managed account pilot: off')
|
|
30
|
+
expect(f.root.textContent).toContain('Account changes or unverified identity revoke access')
|
|
31
|
+
expect(f.root.textContent).toContain('Enabling this pilot is unavailable in this build')
|
|
32
|
+
expect([...f.root.querySelectorAll('button')].some(b=>b.textContent?.includes('Enable managed'))).toBe(false)
|
|
33
|
+
} finally {cleanup(f)}
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
test('nine complete catalogs resolve DSM locale aliases with English fallback',()=> {
|
|
37
|
+
expect(Object.keys(catalogs)).toEqual(['en','zh-TW','zh-CN','ja','ko','de','fr','es','it'])
|
|
38
|
+
for(const catalog of Object.values(catalogs)) {
|
|
39
|
+
expect(Object.keys(catalog).sort()).toEqual(Object.keys(catalogs.en).sort())
|
|
40
|
+
expect(Object.values(catalog).every(s=>typeof s==='string' && s.trim().length>0)).toBe(true)
|
|
41
|
+
for(const key of Object.keys(catalogs.en) as Array<keyof typeof catalogs.en>) {
|
|
42
|
+
expect(catalog[key].match(/\{\w+\}/g) ?? []).toEqual(catalogs.en[key].match(/\{\w+\}/g) ?? [])
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
expect(nasCopy('cht')).toEqual(catalogs['zh-TW'])
|
|
46
|
+
expect(nasCopy('zh_CN')).toEqual(catalogs['zh-CN'])
|
|
47
|
+
expect(nasCopy('unknown')).toEqual(catalogs.en)
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
test('account changes discard the bound provider UI and its pending candidate context',async()=> {
|
|
51
|
+
const provider=createMockNasService().connect('normal1'), cancel=vi.spyOn(provider,'cancel'), f=fixture(provider)
|
|
52
|
+
try {
|
|
53
|
+
await settle();click(f.root,'Choose my folder');await settle()
|
|
54
|
+
f.ctx.call=vi.fn(async(method:string)=>method==='app.status'?{package:'SamePackage',version:'1',user:'normal2',admin:false}:{state:'not-enabled',reason:'not-requested',packageRunning:'unknown',scheduler:'not-probed'})
|
|
55
|
+
f.reopen.forEach(fn=>fn());await settle()
|
|
56
|
+
expect(f.root.textContent).toContain('normal2')
|
|
57
|
+
expect(f.root.querySelector('[role="dialog"]')).toBeNull()
|
|
58
|
+
expect(f.root.textContent).not.toContain('Choose my folder')
|
|
59
|
+
expect(cancel).toHaveBeenCalled()
|
|
60
|
+
} finally {cleanup(f)}
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
test('all nine locale UIs localize dialog controls and allow keyboard review without mouse-only actions',async()=> {
|
|
64
|
+
for(const locale of Object.keys(catalogs)) {
|
|
65
|
+
const copy=nasCopy(locale), f=fixture(createMockNasService().connect('normal1'),'normal1',locale)
|
|
66
|
+
try {
|
|
67
|
+
await settle();click(f.root,copy.choosePersonal);await settle()
|
|
68
|
+
const selected=[...f.root.querySelectorAll('button')].find(b=>b.getAttribute('aria-label')===format(copy.select,'Projects'))!
|
|
69
|
+
selected.focus();expect(document.activeElement).toBe(selected)
|
|
70
|
+
// Native Button remains a keyboard-activatable button (browser verifies Enter).
|
|
71
|
+
expect(selected.tagName).toBe('BUTTON');selected.click();await settle()
|
|
72
|
+
click(f.root,copy.review);await settle();expect(f.root.textContent).toContain(copy.persistent)
|
|
73
|
+
expect(f.root.querySelector(`button[aria-label="${copy.close}"]`)).toBeTruthy()
|
|
74
|
+
click(f.root,copy.cancel);await settle()
|
|
75
|
+
} finally {cleanup(f)}
|
|
76
|
+
}
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
test('home unavailable is recoverable and native diagnostics are never rendered',async()=> {
|
|
80
|
+
const provider=createMockNasService({homeAvailable:false}).connect('normal1'), f=fixture(provider)
|
|
81
|
+
try {
|
|
82
|
+
await settle();click(f.root,'Choose my folder');await settle()
|
|
83
|
+
expect(f.root.textContent).toContain('Required native identity or permission proof is unavailable')
|
|
84
|
+
provider.begin=async()=>{throw {code:'unknown',message:'/volume1/private-secret stderr'}}
|
|
85
|
+
click(f.root,'Retry');await settle()
|
|
86
|
+
expect(f.root.textContent).toContain('The request failed')
|
|
87
|
+
expect(f.root.textContent).not.toMatch(/private-secret|stderr/)
|
|
88
|
+
} finally {cleanup(f)}
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
test('picker browse, separate selection/summary, cancel, empty and confirm use injected provider only',async()=> {
|
|
92
|
+
const service=createMockNasService(), provider=service.connect('normal1'), cancel=vi.spyOn(provider,'cancel'), f=fixture(provider)
|
|
93
|
+
try {
|
|
94
|
+
await settle();click(f.root,'Choose my folder');await settle()
|
|
95
|
+
expect(f.root.textContent).toContain('Mock preview')
|
|
96
|
+
expect(f.root.querySelector('[role="dialog"]')).toBeTruthy()
|
|
97
|
+
click(f.root,'Select Projects');await settle()
|
|
98
|
+
expect(f.root.textContent).not.toContain('Persistent access')
|
|
99
|
+
click(f.root,'Review access');await settle()
|
|
100
|
+
expect(f.root.textContent).toContain('Persistent access')
|
|
101
|
+
click(f.root,'Cancel');await settle()
|
|
102
|
+
expect(cancel).toHaveBeenCalled()
|
|
103
|
+
expect(await provider.grants(new AbortController().signal)).toEqual([])
|
|
104
|
+
click(f.root,'Choose my folder');await settle();click(f.root,'Open Empty folder');await settle()
|
|
105
|
+
expect(f.root.textContent).toContain('This folder is empty')
|
|
106
|
+
click(f.root,'Back');await settle();click(f.root,'Select Projects');await settle();click(f.root,'Review access');await settle();click(f.root,'Confirm access');await settle()
|
|
107
|
+
expect(f.root.querySelector('[role="dialog"]')).toBeNull()
|
|
108
|
+
expect(f.root.textContent).toContain('Active')
|
|
109
|
+
} finally {cleanup(f)}
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
test('two same-package apps retain local modality, unique ARIA IDs and cancellation isolation',async()=> {
|
|
113
|
+
const service=createMockNasService(), a=fixture(service.connect('normal1')), b=fixture(service.connect('normal2'))
|
|
114
|
+
const body=document.body.getAttribute('style')
|
|
115
|
+
try {
|
|
116
|
+
await settle();click(a.root,'Choose my folder');click(b.root,'Choose my folder');await settle()
|
|
117
|
+
const ids=[...document.querySelectorAll('[id]')].map(n=>n.id).filter(Boolean)
|
|
118
|
+
expect(new Set(ids).size).toBe(ids.length)
|
|
119
|
+
for(const f of [a,b]) {
|
|
120
|
+
const dialog=f.root.querySelector('[role="dialog"]')!
|
|
121
|
+
expect(dialog.hasAttribute('aria-modal')).toBe(false)
|
|
122
|
+
for(const name of ['aria-labelledby','aria-describedby']) expect(f.root.querySelector(`[id="${dialog.getAttribute(name)}"]`)).toBeTruthy()
|
|
123
|
+
}
|
|
124
|
+
expect(getComputedStyle(b.root).pointerEvents).not.toBe('none')
|
|
125
|
+
click(a.root,'Cancel');await settle()
|
|
126
|
+
expect(a.root.querySelector('[role="dialog"]')).toBeNull()
|
|
127
|
+
expect(b.root.querySelector('[role="dialog"]')).toBeTruthy()
|
|
128
|
+
expect(document.body.getAttribute('style')).toBe(body)
|
|
129
|
+
} finally {cleanup(a,b)}
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
test('intent expiry is actionable; revoked but not drained never claims transfers stopped',async()=> {
|
|
133
|
+
let now=1000
|
|
134
|
+
const service=createMockNasService({now:()=>now,drained:false}), provider=service.connect('normal1'), f=fixture(provider)
|
|
135
|
+
try {
|
|
136
|
+
await settle();click(f.root,'Choose my folder');await settle();click(f.root,'Select Projects');await settle();click(f.root,'Review access');await settle()
|
|
137
|
+
now+=30_000;click(f.root,'Confirm access');await settle()
|
|
138
|
+
expect(f.root.textContent).toContain('expired')
|
|
139
|
+
expect(await provider.grants(new AbortController().signal)).toEqual([])
|
|
140
|
+
click(f.root,'Cancel');await settle();click(f.root,'Choose my folder');await settle();click(f.root,'Select Projects');await settle();click(f.root,'Review access');await settle();click(f.root,'Confirm access');await settle()
|
|
141
|
+
click(f.root,'Revoke');await settle()
|
|
142
|
+
expect(f.root.textContent).toContain('already sent or written')
|
|
143
|
+
click(f.root,'Confirm revoke');await settle()
|
|
144
|
+
expect(f.root.textContent).toContain('Revoked; stopping transfers')
|
|
145
|
+
} finally {cleanup(f)}
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
test('unmount aborts late browse and cancels its context without creating a grant',async()=> {
|
|
149
|
+
const provider=createMockNasService().connect('normal1'), base=provider.list.bind(provider)
|
|
150
|
+
let resolve!:()=>void, requestSignal!:AbortSignal
|
|
151
|
+
provider.list=async(...args)=>{requestSignal=args[3];await new Promise<void>(r=>resolve=r);return base(...args)}
|
|
152
|
+
const cancel=vi.spyOn(provider,'cancel'), f=fixture(provider)
|
|
153
|
+
await settle();click(f.root,'Choose my folder');await settle();f.app.unmount()
|
|
154
|
+
expect(requestSignal.aborted).toBe(true);expect(cancel).toHaveBeenCalled()
|
|
155
|
+
resolve();await settle();expect(f.root.childElementCount).toBe(0);f.root.remove()
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
test('late begin after close is canceled and rapid double review consumes one intent',async()=> {
|
|
159
|
+
const provider=createMockNasService().connect('normal1'), begin=provider.begin.bind(provider)
|
|
160
|
+
let release!:()=>void
|
|
161
|
+
provider.begin=async(kind,signal)=>{await new Promise<void>(r=>release=r);return begin(kind,new AbortController().signal)}
|
|
162
|
+
const cancel=vi.spyOn(provider,'cancel'), prepare=vi.spyOn(provider,'prepare'), f=fixture(provider)
|
|
163
|
+
try {
|
|
164
|
+
await settle();click(f.root,'Choose my folder');await settle();click(f.root,'Cancel');await settle()
|
|
165
|
+
release();await settle();expect(cancel).toHaveBeenCalled();expect(f.root.querySelector('[role="dialog"]')).toBeNull()
|
|
166
|
+
provider.begin=begin
|
|
167
|
+
click(f.root,'Choose my folder');await settle();click(f.root,'Select Projects');await settle()
|
|
168
|
+
click(f.root,'Review access');click(f.root,'Review access');await settle()
|
|
169
|
+
expect(prepare).toHaveBeenCalledTimes(1)
|
|
170
|
+
} finally {cleanup(f)}
|
|
171
|
+
})
|
|
172
|
+
|
|
173
|
+
test('long folder names stay text, and revoked without Q uses pending cleanup copy',async()=> {
|
|
174
|
+
const name='<img src=x onerror=alert(1)> '+ '\u5e74\u5ea6\u5831\u544a'.repeat(20)
|
|
175
|
+
const provider=createMockNasService({personalFolders:[name]}).connect('normal1'), f=fixture(provider)
|
|
176
|
+
try {
|
|
177
|
+
await settle();click(f.root,'Choose my folder');await settle()
|
|
178
|
+
expect(f.root.textContent).toContain(name);expect(f.root.querySelector('img')).toBeNull()
|
|
179
|
+
click(f.root,'Cancel');await settle()
|
|
180
|
+
provider.settings=async()=>({canManageShared:false,items:[{grantId:'fixture',revision:2,scopeKind:'user-personal',displayName:name,targetKind:'directory',actions:['nas.files.read'],effectiveState:'revoked',createdAt:1000,canRevoke:true,cleanupRequired:true}]})
|
|
181
|
+
click(f.root,'Refresh access');await settle()
|
|
182
|
+
expect(f.root.textContent).toContain('Revoked; cleanup needs verification')
|
|
183
|
+
expect(f.root.textContent).toContain('Read files')
|
|
184
|
+
expect(f.root.textContent).not.toContain('List folders')
|
|
185
|
+
} finally {cleanup(f)}
|
|
186
|
+
})
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
test('S8 production defaults display unavailable for normal/admin even when lifecycle is ready',async()=> {
|
|
190
|
+
for(const user of ['normal1','admin']) for(const locale of Object.keys(catalogs)) {
|
|
191
|
+
const f=fixture(undefined,user,locale),copy=nasCopy(locale)
|
|
192
|
+
try {
|
|
193
|
+
f.ctx.call=vi.fn(async(method:string)=> {
|
|
194
|
+
if(method==='app.status') return {package:'SamePackage',version:'1',user,admin:user==='admin'}
|
|
195
|
+
if(method==='integration.status') return {state:'ready',packageRunning:'running',scheduler:'ready'}
|
|
196
|
+
if(method==='personal.list') return {items:[]}
|
|
197
|
+
throw {code:'unknown_method'}
|
|
198
|
+
})
|
|
199
|
+
f.reopen.forEach(fn=>fn());await settle()
|
|
200
|
+
expect(f.root.textContent).toContain(copy.unavailableMessage)
|
|
201
|
+
expect(f.root.textContent).toContain(copy.pilotUnavailable)
|
|
202
|
+
expect(f.root.textContent).toContain(copy.noUnlock)
|
|
203
|
+
expect(f.root.textContent).not.toContain(copy.choosePersonal)
|
|
204
|
+
expect(f.root.textContent).not.toContain(copy.chooseShared)
|
|
205
|
+
expect(f.root.textContent).not.toContain(copy.emptyGrant)
|
|
206
|
+
expect(f.ctx.call.mock.calls.some(([method])=>method.startsWith('nas.'))).toBe(false)
|
|
207
|
+
} finally {cleanup(f)}
|
|
208
|
+
}
|
|
209
|
+
})
|
|
210
|
+
|
|
211
|
+
test('S8 unavailable connected providers are ignored; only development mocks have a picker',async()=> {
|
|
212
|
+
const connected=createMockNasService().connect('normal1')
|
|
213
|
+
Object.defineProperty(connected,'mode',{value:'connected'})
|
|
214
|
+
const settings=vi.spyOn(connected,'settings'),f=fixture(connected)
|
|
215
|
+
try {
|
|
216
|
+
await settle()
|
|
217
|
+
expect(f.root.textContent).toContain(nasCopy('en').unavailableMessage)
|
|
218
|
+
expect(f.root.textContent).not.toContain('Choose my folder')
|
|
219
|
+
expect(settings).not.toHaveBeenCalled()
|
|
220
|
+
} finally {cleanup(f)}
|
|
221
|
+
})
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
test('S8 safe error codes distinguish missing proof, denial, missing method and app authentication',()=> {
|
|
225
|
+
for(const copy of Object.values(catalogs)) {
|
|
226
|
+
for(const [code,key] of [['unavailable','errorNativeProof'],['denied','errorDenied'],['unknown_method','errorUnknownMethod'],['unsupported','errorUnsupported'],['session_required','errorSession'],['auth_unavailable','errorAuthentication']] as const) {
|
|
227
|
+
expect(errorCopy({code,message:'/volume1/private cookie=sid'},copy)).toBe(copy[key])
|
|
228
|
+
expect(errorCopy({code,message:'/volume1/private cookie=sid'},copy)).not.toMatch(/volume1|cookie=sid/)
|
|
229
|
+
}
|
|
230
|
+
expect(new Set(['unavailable','denied','unknown_method','unsupported'].map(code=>errorCopy({code},copy))).size).toBe(4)
|
|
231
|
+
}
|
|
232
|
+
})
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
test('S8 app request failures use localized safe-code copy without native diagnostics',async()=> {
|
|
236
|
+
for(const code of ['denied','unknown_method','unavailable','unsupported','session_required','auth_unavailable']) {
|
|
237
|
+
const f=fixture(undefined,'normal1','cht')
|
|
238
|
+
try {
|
|
239
|
+
await settle()
|
|
240
|
+
f.ctx.call=vi.fn(async()=>{throw {code,message:'/volume1/private cookie=sid'}})
|
|
241
|
+
f.reopen.forEach(fn=>fn());await settle()
|
|
242
|
+
expect(f.root.querySelector('[role="alert"]')?.textContent).toBe(errorCopy({code},nasCopy('cht')))
|
|
243
|
+
expect(f.root.textContent).not.toMatch(/volume1|cookie=sid/)
|
|
244
|
+
} finally {cleanup(f)}
|
|
245
|
+
}
|
|
246
|
+
})
|
|
247
|
+
|
|
248
|
+
test('S1R risk and reauthorization are disclosed in nine unavailable UIs without data actions',async()=> {
|
|
249
|
+
for(const locale of Object.keys(catalogs)) {
|
|
250
|
+
const copy=nasCopy(locale) as any, f=fixture(undefined,'normal1',locale)
|
|
251
|
+
try {
|
|
252
|
+
await settle()
|
|
253
|
+
for(const key of ['relaxedRisk','relaxedReauthorize','relaxedPermissions']) {
|
|
254
|
+
expect(copy[key],`${locale}:${key}`).toBeTypeOf('string')
|
|
255
|
+
expect(f.root.textContent).toContain(copy[key])
|
|
256
|
+
}
|
|
257
|
+
expect(f.root.textContent).not.toContain(copy.choosePersonal)
|
|
258
|
+
expect(f.ctx.call.mock.calls.some(([method])=>method.startsWith('nas.'))).toBe(false)
|
|
259
|
+
} finally {cleanup(f)}
|
|
260
|
+
}
|
|
261
|
+
})
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"compilerOptions":{"target":"ES2022","module":"ESNext","moduleResolution":"Bundler","resolveJsonModule":true,"strict":true,"lib":["ES2022","DOM"],"skipLibCheck":true,"types":["vite/client"]},"include":["src/**/*.ts","src/**/*.vue","vite.config.ts"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { defineConfig } from 'vite'
|
|
2
|
+
import vue from '@vitejs/plugin-vue'
|
|
3
|
+
// @ts-expect-error The shared notice tool is a plain Node module.
|
|
4
|
+
import { writeThirdPartyNotices } from './third-party-notices.mjs'
|
|
5
|
+
export default defineConfig(({command}) => ({
|
|
6
|
+
plugins: [vue(), {name: 'dependency-notices', closeBundle() {writeThirdPartyNotices('.', 'dist/LICENSES', {ui: true})}}],
|
|
7
|
+
// Library mode must replace Vue dependency env guards for the DSM browser.
|
|
8
|
+
define: command === 'build' ? {'process.env.NODE_ENV': JSON.stringify('production')} : {},
|
|
9
|
+
build: {lib: {entry: 'src/main.ts', formats: ['iife'], name: 'DsmVueApp', fileName: () => 'app.js'}, cssCodeSplit: false, rollupOptions: {output: {assetFileNames: 'app.[ext]'}}},
|
|
10
|
+
}))
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import { type JWK } from "jose";
|
|
2
|
-
export declare const PLATFORM_ATTESTATION_ISSUER = "synopkgland-curated";
|
|
3
|
-
export declare const APP_PACKAGE_ATTESTATION_TYP = "app-package-attestation";
|
|
4
|
-
export declare const APP_PACKAGE_ATTESTATION_VERSION: 2;
|
|
5
|
-
export declare const CURATED_RELEASE_ATTESTATION_TYP = "curated-release-attestation";
|
|
6
|
-
export declare const CURATED_RELEASE_ATTESTATION_VERSION: 1;
|
|
7
|
-
export interface AppPackageSigningKey {
|
|
8
|
-
kid: string;
|
|
9
|
-
privateKey: CryptoKey;
|
|
10
|
-
}
|
|
11
|
-
export interface LabAttestationKeys extends AppPackageSigningKey {
|
|
12
|
-
publicKey: CryptoKey;
|
|
13
|
-
publicJwk: JWK;
|
|
14
|
-
}
|
|
15
|
-
/** Inputs for the token embedded in the generated SPK. */
|
|
16
|
-
export interface CuratedAppPackageAttestationInput {
|
|
17
|
-
packageIdentity: string;
|
|
18
|
-
packageVersion: string;
|
|
19
|
-
packageBuild: number;
|
|
20
|
-
contractDigest: string;
|
|
21
|
-
bundleDigest: string;
|
|
22
|
-
capabilities: string[];
|
|
23
|
-
}
|
|
24
|
-
/** Inputs for the detached token published beside the final SPK. */
|
|
25
|
-
export interface CuratedReleaseAttestationInput {
|
|
26
|
-
packageIdentity: string;
|
|
27
|
-
packageVersion: string;
|
|
28
|
-
packageBuild: number;
|
|
29
|
-
artifactDigest: string;
|
|
30
|
-
embeddedAttestationDigest: string;
|
|
31
|
-
}
|
|
32
|
-
export interface AppPackageAttestationClaims {
|
|
33
|
-
typ: typeof APP_PACKAGE_ATTESTATION_TYP;
|
|
34
|
-
version: typeof APP_PACKAGE_ATTESTATION_VERSION;
|
|
35
|
-
packageIdentity: string;
|
|
36
|
-
packageVersion: string;
|
|
37
|
-
packageBuild: number;
|
|
38
|
-
contractDigest: string;
|
|
39
|
-
bundleDigest: string;
|
|
40
|
-
capabilities: string[];
|
|
41
|
-
issuedAt: string;
|
|
42
|
-
}
|
|
43
|
-
export interface CuratedReleaseAttestationClaims {
|
|
44
|
-
typ: typeof CURATED_RELEASE_ATTESTATION_TYP;
|
|
45
|
-
version: typeof CURATED_RELEASE_ATTESTATION_VERSION;
|
|
46
|
-
packageIdentity: string;
|
|
47
|
-
packageVersion: string;
|
|
48
|
-
packageBuild: number;
|
|
49
|
-
artifactDigest: string;
|
|
50
|
-
embeddedAttestationDigest: string;
|
|
51
|
-
issuedAt: string;
|
|
52
|
-
}
|
|
53
|
-
export declare function loadOrCreateLabAttestationKeys(filePath: string): Promise<LabAttestationKeys>;
|
|
54
|
-
/**
|
|
55
|
-
* Sign the local development token used by the inner-loop flow.
|
|
56
|
-
* Curated releases must use the v2 function below and never this helper.
|
|
57
|
-
*/
|
|
58
|
-
export declare function signAppPackageAttestationToken(input: {
|
|
59
|
-
packageIdentity: string;
|
|
60
|
-
contractDigest: string;
|
|
61
|
-
bundleDigest: string;
|
|
62
|
-
capabilities: string[];
|
|
63
|
-
}, keys: LabAttestationKeys): Promise<{
|
|
64
|
-
token: string;
|
|
65
|
-
attestationDigest: string;
|
|
66
|
-
}>;
|
|
67
|
-
/** Sign the v2 App Package Attestation embedded in a Curated SPK. */
|
|
68
|
-
export declare function signCuratedAppPackageAttestationToken(input: CuratedAppPackageAttestationInput, key: AppPackageSigningKey): Promise<{
|
|
69
|
-
token: string;
|
|
70
|
-
attestationDigest: string;
|
|
71
|
-
claims: AppPackageAttestationClaims;
|
|
72
|
-
}>;
|
|
73
|
-
/** Sign the v1 detached release attestation for a final SPK archive. */
|
|
74
|
-
export declare function signCuratedReleaseAttestationToken(input: CuratedReleaseAttestationInput, key: AppPackageSigningKey): Promise<{
|
|
75
|
-
token: string;
|
|
76
|
-
attestationDigest: string;
|
|
77
|
-
claims: CuratedReleaseAttestationClaims;
|
|
78
|
-
}>;
|
|
79
|
-
/** Stable JSON representation used by the embedded token's jti binding. */
|
|
80
|
-
export declare function canonicalAppPackageClaims(claims: AppPackageAttestationClaims): string;
|
|
81
|
-
export declare function digestAppPackageClaims(claims: AppPackageAttestationClaims): string;
|
|
82
|
-
/** Stable JSON representation used by the detached token's jti binding. */
|
|
83
|
-
export declare function canonicalCuratedReleaseClaims(claims: CuratedReleaseAttestationClaims): string;
|
|
84
|
-
export declare function digestCuratedReleaseClaims(claims: CuratedReleaseAttestationClaims): string;
|
|
85
|
-
export declare function normalizeCapabilities(capabilities: string[]): string[];
|
|
86
|
-
export declare function assertPackageVersionBinding(packageVersion: string, packageBuild: number): void;
|
|
@@ -1,206 +0,0 @@
|
|
|
1
|
-
import { createHash } from "node:crypto";
|
|
2
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
|
-
import { dirname } from "node:path";
|
|
4
|
-
import { SignJWT, exportJWK, generateKeyPair, importJWK } from "jose";
|
|
5
|
-
import { CURATED_BUILD_OFFSET } from "@synopackageland/package-source/index-manifest";
|
|
6
|
-
export const PLATFORM_ATTESTATION_ISSUER = "synopkgland-curated";
|
|
7
|
-
export const APP_PACKAGE_ATTESTATION_TYP = "app-package-attestation";
|
|
8
|
-
export const APP_PACKAGE_ATTESTATION_VERSION = 2;
|
|
9
|
-
export const CURATED_RELEASE_ATTESTATION_TYP = "curated-release-attestation";
|
|
10
|
-
export const CURATED_RELEASE_ATTESTATION_VERSION = 1;
|
|
11
|
-
export async function loadOrCreateLabAttestationKeys(filePath) {
|
|
12
|
-
mkdirSync(dirname(filePath), { recursive: true });
|
|
13
|
-
if (existsSync(filePath)) {
|
|
14
|
-
const parsed = JSON.parse(readFileSync(filePath, "utf8"));
|
|
15
|
-
return {
|
|
16
|
-
kid: parsed.kid,
|
|
17
|
-
privateKey: (await importJWK(parsed.privateJwk, "RS256")),
|
|
18
|
-
publicKey: (await importJWK(parsed.publicJwk, "RS256")),
|
|
19
|
-
publicJwk: parsed.publicJwk,
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
const { publicKey, privateKey } = await generateKeyPair("RS256", { extractable: true });
|
|
23
|
-
const publicJwk = await exportJWK(publicKey);
|
|
24
|
-
const privateJwk = await exportJWK(privateKey);
|
|
25
|
-
const kid = createHash("sha256").update(JSON.stringify(publicJwk)).digest("hex").slice(0, 16);
|
|
26
|
-
publicJwk.kid = kid;
|
|
27
|
-
privateJwk.kid = kid;
|
|
28
|
-
writeFileSync(filePath, `${JSON.stringify({ kid, privateJwk, publicJwk }, null, 2)}\n`, { mode: 0o600 });
|
|
29
|
-
return { kid, privateKey, publicKey, publicJwk };
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Sign the local development token used by the inner-loop flow.
|
|
33
|
-
* Curated releases must use the v2 function below and never this helper.
|
|
34
|
-
*/
|
|
35
|
-
export async function signAppPackageAttestationToken(input, keys) {
|
|
36
|
-
const claims = {
|
|
37
|
-
typ: APP_PACKAGE_ATTESTATION_TYP,
|
|
38
|
-
version: 1,
|
|
39
|
-
packageIdentity: input.packageIdentity,
|
|
40
|
-
contractDigest: input.contractDigest,
|
|
41
|
-
bundleDigest: input.bundleDigest,
|
|
42
|
-
capabilities: normalizeCapabilities(input.capabilities),
|
|
43
|
-
issuedAt: new Date().toISOString(),
|
|
44
|
-
};
|
|
45
|
-
const canonical = JSON.stringify({
|
|
46
|
-
artifactDigest: null,
|
|
47
|
-
bundleDigest: claims.bundleDigest,
|
|
48
|
-
capabilities: claims.capabilities,
|
|
49
|
-
contractDigest: claims.contractDigest,
|
|
50
|
-
issuedAt: claims.issuedAt,
|
|
51
|
-
packageBuild: null,
|
|
52
|
-
packageIdentity: claims.packageIdentity,
|
|
53
|
-
typ: claims.typ,
|
|
54
|
-
version: claims.version,
|
|
55
|
-
});
|
|
56
|
-
const attestationDigest = sha256(canonical);
|
|
57
|
-
const token = await signClaims(claims, keys, attestationDigest);
|
|
58
|
-
return { token, attestationDigest };
|
|
59
|
-
}
|
|
60
|
-
/** Sign the v2 App Package Attestation embedded in a Curated SPK. */
|
|
61
|
-
export async function signCuratedAppPackageAttestationToken(input, key) {
|
|
62
|
-
assertCuratedAppPackageInput(input);
|
|
63
|
-
const claims = {
|
|
64
|
-
typ: APP_PACKAGE_ATTESTATION_TYP,
|
|
65
|
-
version: APP_PACKAGE_ATTESTATION_VERSION,
|
|
66
|
-
packageIdentity: input.packageIdentity,
|
|
67
|
-
packageVersion: input.packageVersion,
|
|
68
|
-
packageBuild: input.packageBuild,
|
|
69
|
-
contractDigest: input.contractDigest,
|
|
70
|
-
bundleDigest: input.bundleDigest,
|
|
71
|
-
capabilities: normalizeCapabilities(input.capabilities),
|
|
72
|
-
issuedAt: new Date().toISOString(),
|
|
73
|
-
};
|
|
74
|
-
const attestationDigest = digestAppPackageClaims(claims);
|
|
75
|
-
const token = await signClaims(claims, key, attestationDigest);
|
|
76
|
-
return { token, attestationDigest, claims };
|
|
77
|
-
}
|
|
78
|
-
/** Sign the v1 detached release attestation for a final SPK archive. */
|
|
79
|
-
export async function signCuratedReleaseAttestationToken(input, key) {
|
|
80
|
-
assertCuratedReleaseInput(input);
|
|
81
|
-
const claims = {
|
|
82
|
-
typ: CURATED_RELEASE_ATTESTATION_TYP,
|
|
83
|
-
version: CURATED_RELEASE_ATTESTATION_VERSION,
|
|
84
|
-
packageIdentity: input.packageIdentity,
|
|
85
|
-
packageVersion: input.packageVersion,
|
|
86
|
-
packageBuild: input.packageBuild,
|
|
87
|
-
artifactDigest: input.artifactDigest,
|
|
88
|
-
embeddedAttestationDigest: input.embeddedAttestationDigest,
|
|
89
|
-
issuedAt: new Date().toISOString(),
|
|
90
|
-
};
|
|
91
|
-
const attestationDigest = digestCuratedReleaseClaims(claims);
|
|
92
|
-
const token = await signClaims(claims, key, attestationDigest);
|
|
93
|
-
return { token, attestationDigest, claims };
|
|
94
|
-
}
|
|
95
|
-
/** Stable JSON representation used by the embedded token's jti binding. */
|
|
96
|
-
export function canonicalAppPackageClaims(claims) {
|
|
97
|
-
return JSON.stringify({
|
|
98
|
-
bundleDigest: claims.bundleDigest,
|
|
99
|
-
capabilities: normalizeCapabilities(claims.capabilities),
|
|
100
|
-
contractDigest: claims.contractDigest,
|
|
101
|
-
issuedAt: claims.issuedAt,
|
|
102
|
-
packageBuild: claims.packageBuild,
|
|
103
|
-
packageIdentity: claims.packageIdentity,
|
|
104
|
-
packageVersion: claims.packageVersion,
|
|
105
|
-
typ: claims.typ,
|
|
106
|
-
version: claims.version,
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
export function digestAppPackageClaims(claims) {
|
|
110
|
-
return sha256(canonicalAppPackageClaims(claims));
|
|
111
|
-
}
|
|
112
|
-
/** Stable JSON representation used by the detached token's jti binding. */
|
|
113
|
-
export function canonicalCuratedReleaseClaims(claims) {
|
|
114
|
-
return JSON.stringify({
|
|
115
|
-
artifactDigest: claims.artifactDigest,
|
|
116
|
-
embeddedAttestationDigest: claims.embeddedAttestationDigest,
|
|
117
|
-
issuedAt: claims.issuedAt,
|
|
118
|
-
packageBuild: claims.packageBuild,
|
|
119
|
-
packageIdentity: claims.packageIdentity,
|
|
120
|
-
packageVersion: claims.packageVersion,
|
|
121
|
-
typ: claims.typ,
|
|
122
|
-
version: claims.version,
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
export function digestCuratedReleaseClaims(claims) {
|
|
126
|
-
return sha256(canonicalCuratedReleaseClaims(claims));
|
|
127
|
-
}
|
|
128
|
-
export function normalizeCapabilities(capabilities) {
|
|
129
|
-
if (!Array.isArray(capabilities)) {
|
|
130
|
-
throw new Error("capabilities must be an array");
|
|
131
|
-
}
|
|
132
|
-
const normalized = new Set();
|
|
133
|
-
for (const capability of capabilities) {
|
|
134
|
-
if (typeof capability !== "string" || capability.length === 0) {
|
|
135
|
-
throw new Error("capabilities must contain non-empty strings");
|
|
136
|
-
}
|
|
137
|
-
normalized.add(capability);
|
|
138
|
-
}
|
|
139
|
-
return [...normalized].sort();
|
|
140
|
-
}
|
|
141
|
-
export function assertPackageVersionBinding(packageVersion, packageBuild) {
|
|
142
|
-
if (typeof packageVersion !== "string" || packageVersion.length === 0) {
|
|
143
|
-
throw new Error("packageVersion must be a non-empty string");
|
|
144
|
-
}
|
|
145
|
-
if (!Number.isSafeInteger(packageBuild) ||
|
|
146
|
-
packageBuild < 1 ||
|
|
147
|
-
packageBuild >= CURATED_BUILD_OFFSET) {
|
|
148
|
-
throw new Error("packageBuild must be a positive safe integer below the Curated offset");
|
|
149
|
-
}
|
|
150
|
-
const match = /-(\d+)$/.exec(packageVersion);
|
|
151
|
-
const parsed = match ? Number(match[1]) : NaN;
|
|
152
|
-
if (parsed !== packageBuild && parsed !== packageBuild + CURATED_BUILD_OFFSET) {
|
|
153
|
-
throw new Error("packageVersion and packageBuild must agree");
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
async function signClaims(claims, key, attestationDigest) {
|
|
157
|
-
if (typeof key.kid !== "string" || key.kid.length === 0) {
|
|
158
|
-
throw new Error("attestation signing key kid is required");
|
|
159
|
-
}
|
|
160
|
-
const packageIdentity = claims.packageIdentity;
|
|
161
|
-
if (typeof packageIdentity !== "string") {
|
|
162
|
-
throw new Error("attestation package identity is required");
|
|
163
|
-
}
|
|
164
|
-
return new SignJWT({ ...claims })
|
|
165
|
-
.setProtectedHeader({ alg: "RS256", kid: key.kid, typ: "JWT" })
|
|
166
|
-
.setIssuer(PLATFORM_ATTESTATION_ISSUER)
|
|
167
|
-
.setSubject(packageIdentity)
|
|
168
|
-
.setJti(attestationDigest)
|
|
169
|
-
.sign(key.privateKey);
|
|
170
|
-
}
|
|
171
|
-
function assertCuratedAppPackageInput(input) {
|
|
172
|
-
assertIdentityAndVersion(input.packageIdentity, input.packageVersion);
|
|
173
|
-
assertPackageBuild(input.packageBuild);
|
|
174
|
-
assertPackageVersionBinding(input.packageVersion, input.packageBuild);
|
|
175
|
-
assertSha256Digest(input.contractDigest, "contractDigest");
|
|
176
|
-
assertSha256Digest(input.bundleDigest, "bundleDigest");
|
|
177
|
-
normalizeCapabilities(input.capabilities);
|
|
178
|
-
}
|
|
179
|
-
function assertCuratedReleaseInput(input) {
|
|
180
|
-
assertIdentityAndVersion(input.packageIdentity, input.packageVersion);
|
|
181
|
-
assertPackageBuild(input.packageBuild);
|
|
182
|
-
assertPackageVersionBinding(input.packageVersion, input.packageBuild);
|
|
183
|
-
assertSha256Digest(input.artifactDigest, "artifactDigest");
|
|
184
|
-
assertSha256Digest(input.embeddedAttestationDigest, "embeddedAttestationDigest");
|
|
185
|
-
}
|
|
186
|
-
function assertIdentityAndVersion(packageIdentity, packageVersion) {
|
|
187
|
-
if (typeof packageIdentity !== "string" || packageIdentity.trim().length === 0) {
|
|
188
|
-
throw new Error("packageIdentity must be a non-empty string");
|
|
189
|
-
}
|
|
190
|
-
if (typeof packageVersion !== "string" || packageVersion.trim().length === 0) {
|
|
191
|
-
throw new Error("packageVersion must be a non-empty string");
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
function assertPackageBuild(packageBuild) {
|
|
195
|
-
if (!Number.isSafeInteger(packageBuild) || packageBuild < 1) {
|
|
196
|
-
throw new Error("packageBuild must be a positive safe integer");
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
function assertSha256Digest(value, name) {
|
|
200
|
-
if (!/^[a-f0-9]{64}$/.test(value)) {
|
|
201
|
-
throw new Error(`${name} must be a lowercase SHA-256 digest`);
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
function sha256(value) {
|
|
205
|
-
return createHash("sha256").update(value).digest("hex");
|
|
206
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import type { JWK } from "jose";
|
|
2
|
-
import type { HostCredentials } from "../host/types.js";
|
|
3
|
-
export declare function loginDsmCookie(credentials: HostCredentials): Promise<string>;
|
|
4
|
-
export declare function installAppPackageAttestationOnNas(options: {
|
|
5
|
-
credentials: HostCredentials;
|
|
6
|
-
token: string;
|
|
7
|
-
publicJwk: JWK;
|
|
8
|
-
}): Promise<{
|
|
9
|
-
ok: boolean;
|
|
10
|
-
status: number;
|
|
11
|
-
code?: string;
|
|
12
|
-
message?: string;
|
|
13
|
-
kind?: string;
|
|
14
|
-
}>;
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { IDENTITY_CGI_PATH } from "../host/broker-paths.js";
|
|
2
|
-
export async function loginDsmCookie(credentials) {
|
|
3
|
-
const dsmOrigin = credentials.dsmOrigin.replace(/\/$/, "");
|
|
4
|
-
const query = new URLSearchParams({
|
|
5
|
-
api: "SYNO.API.Auth",
|
|
6
|
-
version: "3",
|
|
7
|
-
method: "login",
|
|
8
|
-
account: credentials.username,
|
|
9
|
-
passwd: credentials.password,
|
|
10
|
-
session: "FileStation",
|
|
11
|
-
format: "cookie",
|
|
12
|
-
});
|
|
13
|
-
const response = await fetch(`${dsmOrigin}/webapi/entry.cgi?${query.toString()}`);
|
|
14
|
-
const setCookie = typeof response.headers.getSetCookie === "function"
|
|
15
|
-
? response.headers.getSetCookie()
|
|
16
|
-
: response.headers.get("set-cookie")
|
|
17
|
-
? [response.headers.get("set-cookie")]
|
|
18
|
-
: [];
|
|
19
|
-
return setCookie
|
|
20
|
-
.map((line) => line.split(";")[0]?.trim())
|
|
21
|
-
.filter((pair) => Boolean(pair))
|
|
22
|
-
.join("; ");
|
|
23
|
-
}
|
|
24
|
-
export async function installAppPackageAttestationOnNas(options) {
|
|
25
|
-
const dsmOrigin = options.credentials.dsmOrigin.replace(/\/$/, "");
|
|
26
|
-
const cookie = await loginDsmCookie(options.credentials);
|
|
27
|
-
const response = await fetch(`${dsmOrigin}${IDENTITY_CGI_PATH}/api/v1/inner-loop/accept-app-package`, {
|
|
28
|
-
method: "POST",
|
|
29
|
-
headers: {
|
|
30
|
-
cookie,
|
|
31
|
-
"content-type": "application/json",
|
|
32
|
-
},
|
|
33
|
-
body: JSON.stringify({ token: options.token, publicJwk: options.publicJwk }),
|
|
34
|
-
});
|
|
35
|
-
const text = await response.text();
|
|
36
|
-
let body;
|
|
37
|
-
try {
|
|
38
|
-
body = JSON.parse(text);
|
|
39
|
-
}
|
|
40
|
-
catch {
|
|
41
|
-
return { ok: false, status: response.status, code: "INNER_LOOP_API_MISSING", message: text.slice(0, 200) };
|
|
42
|
-
}
|
|
43
|
-
if (!response.ok) {
|
|
44
|
-
return {
|
|
45
|
-
ok: false,
|
|
46
|
-
status: response.status,
|
|
47
|
-
code: body.error?.code,
|
|
48
|
-
message: body.error?.message,
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
return { ok: true, status: response.status, kind: body.kind };
|
|
52
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { type JWK } from "jose";
|
|
2
|
-
export declare const CURATED_ATTESTATION_KEYRING_PATH_ENV = "SYNOPKGLAND_CURATED_ATTESTATION_KEYRING_PATH";
|
|
3
|
-
export declare const CURATED_ATTESTATION_KEYRING_ENV = "SYNOPKGLAND_CURATED_ATTESTATION_KEYRING";
|
|
4
|
-
export type CuratedTrustRootStatus = "active" | "verify-only" | "revoked";
|
|
5
|
-
export type CuratedTrustRootErrorCode = "CURATED_TRUST_ROOT_MISSING" | "CURATED_TRUST_ROOT_INVALID" | "CURATED_SIGNING_KEY_UNKNOWN" | "CURATED_SIGNING_KEY_REVOKED" | "CURATED_SIGNING_KEY_NOT_ACTIVE" | "CURATED_SIGNING_KEY_MISMATCH";
|
|
6
|
-
export interface CuratedTrustRootEntry {
|
|
7
|
-
kid: string;
|
|
8
|
-
status: CuratedTrustRootStatus;
|
|
9
|
-
publicJwk: JWK;
|
|
10
|
-
}
|
|
11
|
-
export interface CuratedTrustRoot {
|
|
12
|
-
version: 1;
|
|
13
|
-
keys: CuratedTrustRootEntry[];
|
|
14
|
-
}
|
|
15
|
-
export declare class CuratedTrustRootError extends Error {
|
|
16
|
-
readonly code: CuratedTrustRootErrorCode;
|
|
17
|
-
constructor(code: CuratedTrustRootErrorCode, message?: string);
|
|
18
|
-
}
|
|
19
|
-
export declare function loadCuratedTrustRoot(env?: NodeJS.Dict<string>): Promise<CuratedTrustRoot>;
|
|
20
|
-
export declare function parseCuratedTrustRoot(value: unknown): CuratedTrustRoot;
|
|
21
|
-
export declare function resolveCuratedSigningTrust(root: CuratedTrustRoot, kid: string, signingPublicJwk: JWK): Promise<CryptoKey>;
|