@synopackageland/cli 0.5.0 → 0.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/authorization-sdk.d.ts +5 -0
- package/dist/authorization-sdk.js +5 -0
- package/dist/build-spk/delete-app-data.d.ts +1 -1
- package/dist/build-spk/uninstall-wizard.d.ts +1 -1
- package/dist/build-spk/uninstall-wizard.js +1 -1
- package/dist/cli.js +2 -2
- package/dist/error-registry.js +3 -3
- package/dist/host/dsm-port-profile.d.ts +1 -1
- package/dist/host/dsm-port-profile.js +1 -1
- package/dist/init.js +25 -4
- package/dist/standalone/authorization-window.d.ts +2 -0
- package/dist/standalone/authorization-window.js +28 -0
- package/dist/standalone/authorization.d.ts +48 -0
- package/dist/standalone/authorization.js +116 -0
- package/dist/standalone/build.js +18 -6
- package/dist/standalone/dsm-window.js +8 -1
- package/dist/standalone/helper.js +1 -1
- package/dist/standalone/inspect-helper.js +12 -2
- package/dist/standalone/inspect-spk.js +11 -0
- package/dist/standalone/lifecycle-helper.d.ts +1 -1
- package/dist/standalone/lifecycle-helper.js +2 -2
- package/dist/standalone/lifecycle.d.ts +1 -1
- package/dist/standalone/lifecycle.js +3 -3
- package/dist/standalone/root-ops.d.ts +2 -0
- package/dist/standalone/root-ops.js +10 -0
- package/dist/standalone/root-window.js +1 -1
- package/dist/standalone/spk.d.ts +2 -0
- package/dist/standalone/spk.js +14 -0
- package/dist/templates/_authorization/main.go +104 -0
- package/dist/templates/_authorization/main_test.go +35 -0
- package/dist/templates/native-go/README.md +25 -1
- package/dist/templates/native-go/backend/cmd/app/main.go +8 -6
- package/dist/templates/native-go/backend/cmd/app/sdk_main.go +8 -6
- package/dist/templates/native-go/backend/cmd/helper/main.go +18 -1
- package/dist/templates/native-go/backend/internal/app/authorization_none.go +5 -0
- package/dist/templates/native-go/backend/internal/app/routes.go +5 -2
- package/dist/templates/native-go/backend/internal/app/sdk_routes.go +5 -2
- package/dist/templates/native-go/backend/internal/helper/management.go +8 -1
- package/dist/templates/native-go/backend/internal/helper/purge.go +115 -0
- package/dist/templates/native-go/backend/internal/helper/purge_test.go +59 -0
- package/dist/templates/native-go/backend/internal/helper/revoke.go +109 -0
- package/dist/templates/native-go/backend/internal/helper/revoke_test.go +121 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_server_linux.go +11 -2
- package/dist/templates/native-go/backend/internal/helper/server_linux.go +11 -2
- package/dist/templates/native-go/dsm-package.yaml +1 -1
- package/dist/templates/native-go-authorization/backend/internal/app/authorization.go +298 -0
- package/dist/templates/native-go-authorization/backend/internal/app/authorization_test.go +96 -0
- package/dist/templates/native-go-authorization/frontend/src/authorization/AuthorizationGate.vue +89 -0
- package/dist/templates/native-go-authorization/frontend/src/authorization/i18n/de.json +36 -0
- package/dist/templates/native-go-authorization/frontend/src/authorization/i18n/en.json +36 -0
- package/dist/templates/native-go-authorization/frontend/src/authorization/i18n/es.json +36 -0
- package/dist/templates/native-go-authorization/frontend/src/authorization/i18n/fr.json +36 -0
- package/dist/templates/native-go-authorization/frontend/src/authorization/i18n/index.ts +15 -0
- package/dist/templates/native-go-authorization/frontend/src/authorization/i18n/it.json +36 -0
- package/dist/templates/native-go-authorization/frontend/src/authorization/i18n/ja.json +36 -0
- package/dist/templates/native-go-authorization/frontend/src/authorization/i18n/ko.json +36 -0
- package/dist/templates/native-go-authorization/frontend/src/authorization/i18n/zh-CN.json +36 -0
- package/dist/templates/native-go-authorization/frontend/src/authorization/i18n/zh-TW.json +36 -0
- package/dist/templates/native-go-authorization/frontend/test/authorization-preview.html +14 -0
- package/dist/templates/native-go-authorization/frontend/test/authorization.test.ts +59 -0
- package/dist/templates/native-go-vue/frontend/src/context.ts +3 -0
- package/dist/types.d.ts +1 -1
- package/package.json +5 -2
- package/skills/reference/create.md +2 -2
- package/templates/_authorization/main.go +104 -0
- package/templates/_authorization/main_test.go +35 -0
- package/templates/native-go/README.md +25 -1
- package/templates/native-go/backend/cmd/app/main.go +8 -6
- package/templates/native-go/backend/cmd/app/sdk_main.go +8 -6
- package/templates/native-go/backend/cmd/helper/main.go +18 -1
- package/templates/native-go/backend/internal/app/authorization_none.go +5 -0
- package/templates/native-go/backend/internal/app/routes.go +5 -2
- package/templates/native-go/backend/internal/app/sdk_routes.go +5 -2
- package/templates/native-go/backend/internal/helper/management.go +8 -1
- package/templates/native-go/backend/internal/helper/purge.go +115 -0
- package/templates/native-go/backend/internal/helper/purge_test.go +59 -0
- package/templates/native-go/backend/internal/helper/revoke.go +109 -0
- package/templates/native-go/backend/internal/helper/revoke_test.go +121 -0
- package/templates/native-go/backend/internal/helper/sdk_server_linux.go +11 -2
- package/templates/native-go/backend/internal/helper/server_linux.go +11 -2
- package/templates/native-go/dsm-package.yaml +1 -1
- package/templates/native-go-authorization/backend/internal/app/authorization.go +298 -0
- package/templates/native-go-authorization/backend/internal/app/authorization_test.go +96 -0
- package/templates/native-go-authorization/frontend/src/authorization/AuthorizationGate.vue +89 -0
- package/templates/native-go-authorization/frontend/src/authorization/i18n/de.json +36 -0
- package/templates/native-go-authorization/frontend/src/authorization/i18n/en.json +36 -0
- package/templates/native-go-authorization/frontend/src/authorization/i18n/es.json +36 -0
- package/templates/native-go-authorization/frontend/src/authorization/i18n/fr.json +36 -0
- package/templates/native-go-authorization/frontend/src/authorization/i18n/index.ts +15 -0
- package/templates/native-go-authorization/frontend/src/authorization/i18n/it.json +36 -0
- package/templates/native-go-authorization/frontend/src/authorization/i18n/ja.json +36 -0
- package/templates/native-go-authorization/frontend/src/authorization/i18n/ko.json +36 -0
- package/templates/native-go-authorization/frontend/src/authorization/i18n/zh-CN.json +36 -0
- package/templates/native-go-authorization/frontend/src/authorization/i18n/zh-TW.json +36 -0
- package/templates/native-go-authorization/frontend/test/authorization-preview.html +14 -0
- package/templates/native-go-authorization/frontend/test/authorization.test.ts +59 -0
- package/templates/native-go-vue/frontend/src/context.ts +3 -0
- package/dist/templates/hello-web/compose.yaml +0 -24
- package/dist/templates/hello-web/html/app.js +0 -1
- package/dist/templates/hello-web/html/index.html +0 -13
- package/dist/templates/hello-web/synology-app.yaml +0 -16
- package/dist/templates/hello-web-page/compose.yaml +0 -24
- package/dist/templates/hello-web-page/html/app.js +0 -1
- package/dist/templates/hello-web-page/html/index.html +0 -13
- package/dist/templates/hello-web-page/synology-app.yaml +0 -16
- package/templates/hello-web/compose.yaml +0 -24
- package/templates/hello-web/html/app.js +0 -1
- package/templates/hello-web/html/index.html +0 -13
- package/templates/hello-web/synology-app.yaml +0 -16
- package/templates/hello-web-page/compose.yaml +0 -24
- package/templates/hello-web-page/html/app.js +0 -1
- package/templates/hello-web-page/html/index.html +0 -13
- package/templates/hello-web-page/synology-app.yaml +0 -16
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"authorization.title": "{package} benötigt Ihre Erlaubnis",
|
|
3
|
+
"authorization.purpose": "Dieses Paket benötigt eine Genehmigung für feste Root-Operationen. DSM verarbeitet Ihr Passwort; das Paket sieht oder speichert es nicht.",
|
|
4
|
+
"authorization.reason.grant_missing": "Root-Operationen sind noch nicht autorisiert.",
|
|
5
|
+
"authorization.reason.helper_untrusted": "Dem privilegierten Helfer konnte nicht vertraut werden.",
|
|
6
|
+
"authorization.reason.cli_untrusted": "Dem privilegierten Befehl konnte nicht vertraut werden.",
|
|
7
|
+
"authorization.reason.grant_incompatible": "Der privilegierte Helfer muss aktualisiert werden.",
|
|
8
|
+
"authorization.reason.package_identity_changed": "Das Paketkonto hat sich geändert.",
|
|
9
|
+
"authorization.reason.maintenance_task_missing": "Die Wartungsaufgabe fehlt.",
|
|
10
|
+
"authorization.reason.maintenance_task_mismatch": "Die Wartungsaufgabe passt nicht mehr zur Berechtigung.",
|
|
11
|
+
"authorization.reason.helper_health_rejected": "Der privilegierte Helfer hat seine Integritätsprüfung nicht bestanden.",
|
|
12
|
+
"authorization.reason.capability_missing": "Dem privilegierten Helfer fehlt eine erforderliche Fähigkeit.",
|
|
13
|
+
"authorization.reason.unknown": "Die Berechtigung fehlt oder ist nicht mehr gültig.",
|
|
14
|
+
"authorization.next.install": "Wählen Sie Autorisieren und bestätigen Sie Ihr DSM-Passwort, um diesen Build zu genehmigen.",
|
|
15
|
+
"authorization.next.update": "Dieser Build benötigt eine neue Autorisierung. Wählen Sie Autorisieren und bestätigen Sie Ihr DSM-Passwort.",
|
|
16
|
+
"authorization.next.repair": "Prüfen Sie die Aufgaben dieses Pakets im Aufgabenplaner und versuchen Sie es erneut.",
|
|
17
|
+
"authorization.authorize": "Berechtigen",
|
|
18
|
+
"authorization.authorizing": "Warten auf DSM…",
|
|
19
|
+
"authorization.failed": "Die Berechtigung wurde nicht abgeschlossen. Sie können es erneut versuchen.",
|
|
20
|
+
"authorization.unavailable.title": "Berechtigung konnte nicht geprüft werden",
|
|
21
|
+
"authorization.unavailable.body": "Das ist meist vorübergehend. Versuchen Sie es erneut; {package} fragt nicht nach Ihrem Passwort.",
|
|
22
|
+
"authorization.credential.title": "Die DSM-Anmeldeinformationen sind nicht bereit",
|
|
23
|
+
"authorization.credential.body": "Diese DSM-Sitzung wurde ohne Anmeldung mit Kennwort wiederhergestellt, daher kann DSM die Anfragen von {package} nicht bestätigen. Melden Sie sich bei DSM ab, melden Sie sich erneut mit Ihrem Kennwort an und öffnen Sie dann {package} erneut.",
|
|
24
|
+
"authorization.retry": "Erneut versuchen",
|
|
25
|
+
"authorization.next.reinstall": "Die installierten Dateien stimmen nicht mit diesem Build überein. Installieren Sie das Paket aus einer vertrauenswürdigen Quelle neu.",
|
|
26
|
+
"authorization.not_admin.title": "Administrator erforderlich",
|
|
27
|
+
"authorization.not_admin.body": "Bitten Sie einen DSM-Administrator, dieses Paket zu öffnen und zu autorisieren.",
|
|
28
|
+
"authorization.session_expired.title": "Sitzung abgelaufen",
|
|
29
|
+
"authorization.session_expired.body": "Melden Sie sich erneut bei DSM an und öffnen Sie dieses Paket wieder.",
|
|
30
|
+
"authorization.ready": "Autorisiert",
|
|
31
|
+
"authorization.revoke": "Autorisierung widerrufen",
|
|
32
|
+
"authorization.revoke.title": "Autorisierung widerrufen?",
|
|
33
|
+
"authorization.revoke.body": "Neuer Helper-Zugriff wird deaktiviert. Paketdaten und bisherige Ergebnisse bleiben erhalten.",
|
|
34
|
+
"authorization.cancel": "Abbrechen",
|
|
35
|
+
"authorization.checking": "Autorisierung wird geprüft…"
|
|
36
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"authorization.title": "{package} needs your permission",
|
|
3
|
+
"authorization.purpose": "This package needs approval for its fixed root operations. DSM handles your password; the package never sees or stores it.",
|
|
4
|
+
"authorization.reason.grant_missing": "Root operations are not authorized yet.",
|
|
5
|
+
"authorization.reason.helper_untrusted": "The privileged helper could not be trusted.",
|
|
6
|
+
"authorization.reason.cli_untrusted": "The privileged command could not be trusted.",
|
|
7
|
+
"authorization.reason.grant_incompatible": "The privileged helper needs an update.",
|
|
8
|
+
"authorization.reason.package_identity_changed": "The package account changed.",
|
|
9
|
+
"authorization.reason.maintenance_task_missing": "The maintenance task is missing.",
|
|
10
|
+
"authorization.reason.maintenance_task_mismatch": "The maintenance task no longer matches the authorization.",
|
|
11
|
+
"authorization.reason.helper_health_rejected": "The privileged helper did not pass its health check.",
|
|
12
|
+
"authorization.reason.capability_missing": "The privileged helper lacks a required capability.",
|
|
13
|
+
"authorization.reason.unknown": "The authorization is missing or no longer valid.",
|
|
14
|
+
"authorization.next.install": "Choose Authorize and confirm your DSM password to approve this build.",
|
|
15
|
+
"authorization.next.update": "This build needs fresh authorization. Choose Authorize and confirm your DSM password.",
|
|
16
|
+
"authorization.next.repair": "Review this package and its tasks in Task Scheduler, then retry.",
|
|
17
|
+
"authorization.authorize": "Authorize",
|
|
18
|
+
"authorization.authorizing": "Waiting for DSM…",
|
|
19
|
+
"authorization.failed": "Authorization did not finish. You can try again.",
|
|
20
|
+
"authorization.unavailable.title": "Authorization could not be checked",
|
|
21
|
+
"authorization.unavailable.body": "This is usually temporary. Try again — {package} will not ask for your password.",
|
|
22
|
+
"authorization.credential.title": "DSM's sign-in credential is not ready",
|
|
23
|
+
"authorization.credential.body": "This DSM session was restored without a password sign-in, so DSM cannot vouch for {package}'s requests. Sign out of DSM, sign in again with your password, then reopen {package}.",
|
|
24
|
+
"authorization.retry": "Try again",
|
|
25
|
+
"authorization.next.reinstall": "The installed files do not match this build. Reinstall the package from a trusted source, then retry.",
|
|
26
|
+
"authorization.not_admin.title": "Administrator needed",
|
|
27
|
+
"authorization.not_admin.body": "Ask a DSM administrator to open this package and authorize it.",
|
|
28
|
+
"authorization.session_expired.title": "Session expired",
|
|
29
|
+
"authorization.session_expired.body": "Sign in to DSM again, then reopen this package.",
|
|
30
|
+
"authorization.ready": "Authorized",
|
|
31
|
+
"authorization.revoke": "Revoke authorization",
|
|
32
|
+
"authorization.revoke.title": "Revoke authorization?",
|
|
33
|
+
"authorization.revoke.body": "New helper access will be disabled. Package data and past results are retained.",
|
|
34
|
+
"authorization.cancel": "Cancel",
|
|
35
|
+
"authorization.checking": "Checking authorization…"
|
|
36
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"authorization.title": "{package} necesita su permiso",
|
|
3
|
+
"authorization.purpose": "Este paquete requiere aprobación para sus operaciones root fijas. DSM gestiona su contraseña; el paquete no la ve ni la almacena.",
|
|
4
|
+
"authorization.reason.grant_missing": "Las operaciones root aún no están autorizadas.",
|
|
5
|
+
"authorization.reason.helper_untrusted": "No se pudo confiar en el asistente privilegiado.",
|
|
6
|
+
"authorization.reason.cli_untrusted": "No se pudo confiar en el comando privilegiado.",
|
|
7
|
+
"authorization.reason.grant_incompatible": "El asistente privilegiado necesita una actualización.",
|
|
8
|
+
"authorization.reason.package_identity_changed": "La cuenta del paquete ha cambiado.",
|
|
9
|
+
"authorization.reason.maintenance_task_missing": "Falta la tarea de mantenimiento.",
|
|
10
|
+
"authorization.reason.maintenance_task_mismatch": "La tarea de mantenimiento ya no coincide con la autorización.",
|
|
11
|
+
"authorization.reason.helper_health_rejected": "El asistente privilegiado no superó su comprobación de estado.",
|
|
12
|
+
"authorization.reason.capability_missing": "Al asistente privilegiado le falta una capacidad necesaria.",
|
|
13
|
+
"authorization.reason.unknown": "La autorización falta o ya no es válida.",
|
|
14
|
+
"authorization.next.install": "Elija Autorizar y confirme su contraseña de DSM para aprobar esta versión.",
|
|
15
|
+
"authorization.next.update": "Esta versión requiere una nueva autorización. Elija Autorizar y confirme su contraseña de DSM.",
|
|
16
|
+
"authorization.next.repair": "Revise las tareas de este paquete en el Programador de tareas y vuelva a intentarlo.",
|
|
17
|
+
"authorization.authorize": "Autorizar",
|
|
18
|
+
"authorization.authorizing": "Esperando a DSM…",
|
|
19
|
+
"authorization.failed": "La autorización no se completó. Puede intentarlo de nuevo.",
|
|
20
|
+
"authorization.unavailable.title": "No se pudo comprobar la autorización",
|
|
21
|
+
"authorization.unavailable.body": "Suele ser temporal. Inténtelo de nuevo; {package} no le pedirá la contraseña.",
|
|
22
|
+
"authorization.credential.title": "Las credenciales de inicio de sesión de DSM no están listas",
|
|
23
|
+
"authorization.credential.body": "Esta sesión de DSM se restauró sin iniciar sesión con contraseña, por lo que DSM no puede avalar las solicitudes de {package}. Cierre sesión en DSM, inicie sesión de nuevo con su contraseña y vuelva a abrir {package}.",
|
|
24
|
+
"authorization.retry": "Reintentar",
|
|
25
|
+
"authorization.next.reinstall": "Los archivos instalados no coinciden con esta versión. Reinstale el paquete desde una fuente fiable y vuelva a intentarlo.",
|
|
26
|
+
"authorization.not_admin.title": "Se requiere un administrador",
|
|
27
|
+
"authorization.not_admin.body": "Pida a un administrador de DSM que abra y autorice este paquete.",
|
|
28
|
+
"authorization.session_expired.title": "Sesión caducada",
|
|
29
|
+
"authorization.session_expired.body": "Inicie sesión de nuevo en DSM y vuelva a abrir este paquete.",
|
|
30
|
+
"authorization.ready": "Autorizado",
|
|
31
|
+
"authorization.revoke": "Revocar autorización",
|
|
32
|
+
"authorization.revoke.title": "¿Revocar autorización?",
|
|
33
|
+
"authorization.revoke.body": "Se desactivarán los nuevos accesos del helper. Se conservan los datos del paquete y los resultados anteriores.",
|
|
34
|
+
"authorization.cancel": "Cancelar",
|
|
35
|
+
"authorization.checking": "Comprobando autorización…"
|
|
36
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"authorization.title": "{package} demande votre autorisation",
|
|
3
|
+
"authorization.purpose": "Ce paquet nécessite une autorisation pour ses opérations root fixes. DSM traite votre mot de passe ; le paquet ne le voit ni ne le stocke.",
|
|
4
|
+
"authorization.reason.grant_missing": "Les opérations root ne sont pas encore autorisées.",
|
|
5
|
+
"authorization.reason.helper_untrusted": "L'assistant privilégié n'a pas pu être approuvé.",
|
|
6
|
+
"authorization.reason.cli_untrusted": "La commande privilégiée n'a pas pu être approuvée.",
|
|
7
|
+
"authorization.reason.grant_incompatible": "L'assistant privilégié doit être mis à jour.",
|
|
8
|
+
"authorization.reason.package_identity_changed": "Le compte du paquet a changé.",
|
|
9
|
+
"authorization.reason.maintenance_task_missing": "La tâche de maintenance est introuvable.",
|
|
10
|
+
"authorization.reason.maintenance_task_mismatch": "La tâche de maintenance ne correspond plus à l'autorisation.",
|
|
11
|
+
"authorization.reason.helper_health_rejected": "L'assistant privilégié n'a pas réussi son contrôle d'intégrité.",
|
|
12
|
+
"authorization.reason.capability_missing": "Il manque à l'assistant privilégié une capacité requise.",
|
|
13
|
+
"authorization.reason.unknown": "L'autorisation est absente ou n'est plus valide.",
|
|
14
|
+
"authorization.next.install": "Choisissez Autoriser et confirmez votre mot de passe DSM pour approuver cette version.",
|
|
15
|
+
"authorization.next.update": "Cette version nécessite une nouvelle autorisation. Choisissez Autoriser et confirmez votre mot de passe DSM.",
|
|
16
|
+
"authorization.next.repair": "Vérifiez les tâches de ce paquet dans le Planificateur de tâches, puis réessayez.",
|
|
17
|
+
"authorization.authorize": "Autoriser",
|
|
18
|
+
"authorization.authorizing": "En attente de DSM…",
|
|
19
|
+
"authorization.failed": "L'autorisation ne s'est pas terminée. Vous pouvez réessayer.",
|
|
20
|
+
"authorization.unavailable.title": "Impossible de vérifier l'autorisation",
|
|
21
|
+
"authorization.unavailable.body": "C'est généralement temporaire. Réessayez ; {package} ne demandera pas votre mot de passe.",
|
|
22
|
+
"authorization.credential.title": "Les identifiants de connexion DSM ne sont pas prêts",
|
|
23
|
+
"authorization.credential.body": "Cette session DSM a été restaurée sans connexion par mot de passe : DSM ne peut donc pas authentifier les requêtes de {package}. Déconnectez-vous de DSM, reconnectez-vous avec votre mot de passe, puis rouvrez {package}.",
|
|
24
|
+
"authorization.retry": "Réessayer",
|
|
25
|
+
"authorization.next.reinstall": "Les fichiers installés ne correspondent pas à cette version. Réinstallez le paquet depuis une source fiable, puis réessayez.",
|
|
26
|
+
"authorization.not_admin.title": "Administrateur requis",
|
|
27
|
+
"authorization.not_admin.body": "Demandez à un administrateur DSM d’ouvrir ce paquet et de l’autoriser.",
|
|
28
|
+
"authorization.session_expired.title": "Session expirée",
|
|
29
|
+
"authorization.session_expired.body": "Reconnectez-vous à DSM, puis rouvrez ce paquet.",
|
|
30
|
+
"authorization.ready": "Autorisé",
|
|
31
|
+
"authorization.revoke": "Révoquer l’autorisation",
|
|
32
|
+
"authorization.revoke.title": "Révoquer l’autorisation ?",
|
|
33
|
+
"authorization.revoke.body": "Les nouveaux accès helper seront désactivés. Les données du paquet et les résultats précédents sont conservés.",
|
|
34
|
+
"authorization.cancel": "Annuler",
|
|
35
|
+
"authorization.checking": "Vérification de l’autorisation…"
|
|
36
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import en from './en.json'
|
|
2
|
+
import zhTW from './zh-TW.json'
|
|
3
|
+
import zhCN from './zh-CN.json'
|
|
4
|
+
import ja from './ja.json'
|
|
5
|
+
import ko from './ko.json'
|
|
6
|
+
import de from './de.json'
|
|
7
|
+
import fr from './fr.json'
|
|
8
|
+
import es from './es.json'
|
|
9
|
+
import it from './it.json'
|
|
10
|
+
const catalogs:Record<string,Record<string,string>>={en,'zh-TW':zhTW,'zh-CN':zhCN,ja,ko,de,fr,es,it}
|
|
11
|
+
/** Copy follows Reclaim T0156; root-task semantics are template-owned. */
|
|
12
|
+
export function authorizationCopy(locale:string,packageName:string){
|
|
13
|
+
const catalog={...en,...catalogs[locale]}
|
|
14
|
+
return (key:string)=>((catalog as Record<string,string>)[`authorization.${key}`]||key).replaceAll('{package}',packageName)
|
|
15
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"authorization.title": "{package} richiede il tuo permesso",
|
|
3
|
+
"authorization.purpose": "Questo pacchetto richiede l’approvazione per le sue operazioni root fisse. DSM gestisce la password; il pacchetto non la vede né la memorizza.",
|
|
4
|
+
"authorization.reason.grant_missing": "Le operazioni root non sono ancora autorizzate.",
|
|
5
|
+
"authorization.reason.helper_untrusted": "Non è stato possibile considerare attendibile l'helper privilegiato.",
|
|
6
|
+
"authorization.reason.cli_untrusted": "Non è stato possibile considerare attendibile il comando privilegiato.",
|
|
7
|
+
"authorization.reason.grant_incompatible": "L'helper privilegiato deve essere aggiornato.",
|
|
8
|
+
"authorization.reason.package_identity_changed": "L'account del pacchetto è cambiato.",
|
|
9
|
+
"authorization.reason.maintenance_task_missing": "L'attività di manutenzione non è presente.",
|
|
10
|
+
"authorization.reason.maintenance_task_mismatch": "L'attività di manutenzione non corrisponde più all'autorizzazione.",
|
|
11
|
+
"authorization.reason.helper_health_rejected": "L'helper privilegiato non ha superato il controllo di integrità.",
|
|
12
|
+
"authorization.reason.capability_missing": "All'helper privilegiato manca una capacità necessaria.",
|
|
13
|
+
"authorization.reason.unknown": "L'autorizzazione è mancante o non più valida.",
|
|
14
|
+
"authorization.next.install": "Scegli Autorizza e conferma la password DSM per approvare questa versione.",
|
|
15
|
+
"authorization.next.update": "Questa versione richiede una nuova autorizzazione. Scegli Autorizza e conferma la password DSM.",
|
|
16
|
+
"authorization.next.repair": "Controlla le attività del pacchetto nell’Utilità di pianificazione e riprova.",
|
|
17
|
+
"authorization.authorize": "Autorizza",
|
|
18
|
+
"authorization.authorizing": "In attesa di DSM…",
|
|
19
|
+
"authorization.failed": "L'autorizzazione non è stata completata. Puoi riprovare.",
|
|
20
|
+
"authorization.unavailable.title": "Impossibile verificare l'autorizzazione",
|
|
21
|
+
"authorization.unavailable.body": "Di solito è temporaneo. Riprova; {package} non chiederà la password.",
|
|
22
|
+
"authorization.credential.title": "Le credenziali di accesso di DSM non sono pronte",
|
|
23
|
+
"authorization.credential.body": "Questa sessione DSM è stata ripristinata senza accesso con password, quindi DSM non può garantire per le richieste di {package}. Disconnettiti da DSM, accedi di nuovo con la password e riapri {package}.",
|
|
24
|
+
"authorization.retry": "Riprova",
|
|
25
|
+
"authorization.next.reinstall": "I file installati non corrispondono a questa versione. Reinstalla il pacchetto da una fonte attendibile e riprova.",
|
|
26
|
+
"authorization.not_admin.title": "Amministratore necessario",
|
|
27
|
+
"authorization.not_admin.body": "Chiedi a un amministratore DSM di aprire e autorizzare questo pacchetto.",
|
|
28
|
+
"authorization.session_expired.title": "Sessione scaduta",
|
|
29
|
+
"authorization.session_expired.body": "Accedi nuovamente a DSM e riapri questo pacchetto.",
|
|
30
|
+
"authorization.ready": "Autorizzato",
|
|
31
|
+
"authorization.revoke": "Revoca autorizzazione",
|
|
32
|
+
"authorization.revoke.title": "Revocare l’autorizzazione?",
|
|
33
|
+
"authorization.revoke.body": "I nuovi accessi helper saranno disabilitati. I dati del pacchetto e i risultati precedenti vengono conservati.",
|
|
34
|
+
"authorization.cancel": "Annulla",
|
|
35
|
+
"authorization.checking": "Verifica dell’autorizzazione…"
|
|
36
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"authorization.title": "{package} に承認が必要です",
|
|
3
|
+
"authorization.purpose": "このパッケージの固定 root 操作には承認が必要です。パスワードは DSM が処理し、パッケージは閲覧も保存もしません。",
|
|
4
|
+
"authorization.reason.grant_missing": "root 操作はまだ承認されていません。",
|
|
5
|
+
"authorization.reason.helper_untrusted": "特権ヘルパーを信頼できませんでした。",
|
|
6
|
+
"authorization.reason.cli_untrusted": "特権コマンドを信頼できませんでした。",
|
|
7
|
+
"authorization.reason.grant_incompatible": "特権ヘルパーの更新が必要です。",
|
|
8
|
+
"authorization.reason.package_identity_changed": "パッケージ アカウントが変更されました。",
|
|
9
|
+
"authorization.reason.maintenance_task_missing": "メンテナンス タスクが見つかりません。",
|
|
10
|
+
"authorization.reason.maintenance_task_mismatch": "メンテナンス タスクが認可と一致しません。",
|
|
11
|
+
"authorization.reason.helper_health_rejected": "特権ヘルパーがヘルス チェックに合格しませんでした。",
|
|
12
|
+
"authorization.reason.capability_missing": "特権ヘルパーに必要な機能がありません。",
|
|
13
|
+
"authorization.reason.unknown": "認可が見つからないか、無効になっています。",
|
|
14
|
+
"authorization.next.install": "「承認」を選び、DSM パスワードでこのビルドを承認してください。",
|
|
15
|
+
"authorization.next.update": "このビルドには再承認が必要です。「承認」を選び、DSM パスワードで確認してください。",
|
|
16
|
+
"authorization.next.repair": "タスク スケジューラでこのパッケージのタスクを確認し、再試行してください。",
|
|
17
|
+
"authorization.authorize": "認可",
|
|
18
|
+
"authorization.authorizing": "DSM を待機しています…",
|
|
19
|
+
"authorization.failed": "認可が完了しませんでした。もう一度お試しください。",
|
|
20
|
+
"authorization.unavailable.title": "認可を確認できませんでした",
|
|
21
|
+
"authorization.unavailable.body": "通常は一時的な問題です。もう一度お試しください。{package} がパスワードを求めることはありません。",
|
|
22
|
+
"authorization.credential.title": "DSM のサインイン資格情報が準備できていません",
|
|
23
|
+
"authorization.credential.body": "この DSM セッションはパスワードによるサインインなしで復元されたため、DSM は {package} のリクエストを保証できません。DSM からサインアウトし、パスワードで再度サインインしてから、{package} を開き直してください。",
|
|
24
|
+
"authorization.retry": "再試行",
|
|
25
|
+
"authorization.next.reinstall": "インストールされたファイルがこのビルドと一致しません。信頼できる配布元から再インストールし、再試行してください。",
|
|
26
|
+
"authorization.not_admin.title": "管理者が必要です",
|
|
27
|
+
"authorization.not_admin.body": "DSM 管理者にこのパッケージの承認を依頼してください。",
|
|
28
|
+
"authorization.session_expired.title": "セッションが期限切れです",
|
|
29
|
+
"authorization.session_expired.body": "DSM に再ログインし、このパッケージを開き直してください。",
|
|
30
|
+
"authorization.ready": "承認済み",
|
|
31
|
+
"authorization.revoke": "承認を取り消す",
|
|
32
|
+
"authorization.revoke.title": "承認を取り消しますか?",
|
|
33
|
+
"authorization.revoke.body": "新しい helper アクセスを無効にします。パッケージのデータと過去の結果は保持されます。",
|
|
34
|
+
"authorization.cancel": "キャンセル",
|
|
35
|
+
"authorization.checking": "承認を確認中…"
|
|
36
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"authorization.title": "{package} 승인 필요",
|
|
3
|
+
"authorization.purpose": "이 패키지의 고정 root 작업에는 승인이 필요합니다. 비밀번호는 DSM이 처리하며 패키지는 비밀번호를 보거나 저장하지 않습니다.",
|
|
4
|
+
"authorization.reason.grant_missing": "root 작업이 아직 승인되지 않았습니다.",
|
|
5
|
+
"authorization.reason.helper_untrusted": "권한 있는 도우미를 신뢰할 수 없습니다.",
|
|
6
|
+
"authorization.reason.cli_untrusted": "권한 있는 명령을 신뢰할 수 없습니다.",
|
|
7
|
+
"authorization.reason.grant_incompatible": "권한 있는 도우미를 업데이트해야 합니다.",
|
|
8
|
+
"authorization.reason.package_identity_changed": "패키지 계정이 변경되었습니다.",
|
|
9
|
+
"authorization.reason.maintenance_task_missing": "유지 관리 작업이 없습니다.",
|
|
10
|
+
"authorization.reason.maintenance_task_mismatch": "유지 관리 작업이 권한과 일치하지 않습니다.",
|
|
11
|
+
"authorization.reason.helper_health_rejected": "권한 있는 도우미가 상태 검사를 통과하지 못했습니다.",
|
|
12
|
+
"authorization.reason.capability_missing": "권한 있는 도우미에 필요한 기능이 없습니다.",
|
|
13
|
+
"authorization.reason.unknown": "권한이 없거나 더 이상 유효하지 않습니다.",
|
|
14
|
+
"authorization.next.install": "승인을 선택하고 DSM 비밀번호로 이 빌드를 승인하세요.",
|
|
15
|
+
"authorization.next.update": "이 빌드는 새 승인이 필요합니다. 승인을 선택하고 DSM 비밀번호로 확인하세요.",
|
|
16
|
+
"authorization.next.repair": "작업 스케줄러에서 패키지 작업을 확인한 후 다시 시도하세요.",
|
|
17
|
+
"authorization.authorize": "권한 부여",
|
|
18
|
+
"authorization.authorizing": "DSM을 기다리는 중…",
|
|
19
|
+
"authorization.failed": "권한 부여가 완료되지 않았습니다. 다시 시도할 수 있습니다.",
|
|
20
|
+
"authorization.unavailable.title": "권한을 확인할 수 없습니다",
|
|
21
|
+
"authorization.unavailable.body": "일반적으로 일시적인 문제입니다. 다시 시도하세요. {package}은 비밀번호를 요구하지 않습니다.",
|
|
22
|
+
"authorization.credential.title": "DSM 로그인 자격 증명이 준비되지 않았습니다",
|
|
23
|
+
"authorization.credential.body": "이 DSM 세션은 비밀번호 로그인 없이 복원되었으므로 DSM이 {package}의 요청을 보증할 수 없습니다. DSM에서 로그아웃한 후 비밀번호로 다시 로그인하고 {package}을 다시 여세요.",
|
|
24
|
+
"authorization.retry": "다시 시도",
|
|
25
|
+
"authorization.next.reinstall": "설치된 파일이 이 빌드와 일치하지 않습니다. 신뢰할 수 있는 출처에서 패키지를 다시 설치한 후 다시 시도하세요.",
|
|
26
|
+
"authorization.not_admin.title": "관리자가 필요합니다",
|
|
27
|
+
"authorization.not_admin.body": "DSM 관리자에게 이 패키지를 열고 승인하도록 요청하세요.",
|
|
28
|
+
"authorization.session_expired.title": "세션이 만료되었습니다",
|
|
29
|
+
"authorization.session_expired.body": "DSM에 다시 로그인한 후 패키지를 다시 여세요.",
|
|
30
|
+
"authorization.ready": "승인됨",
|
|
31
|
+
"authorization.revoke": "승인 취소",
|
|
32
|
+
"authorization.revoke.title": "승인을 취소하시겠습니까?",
|
|
33
|
+
"authorization.revoke.body": "새 helper 액세스가 비활성화됩니다. 패키지 데이터와 이전 결과는 유지됩니다.",
|
|
34
|
+
"authorization.cancel": "취소",
|
|
35
|
+
"authorization.checking": "승인 확인 중…"
|
|
36
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"authorization.title": "{package} 需要您的授权",
|
|
3
|
+
"authorization.purpose": "此套件执行固定的 root 操作前需要批准。密码由 DSM 处理,套件不会看到或存储。",
|
|
4
|
+
"authorization.reason.grant_missing": "尚未授权 root 操作。",
|
|
5
|
+
"authorization.reason.helper_untrusted": "无法信任特权 helper。",
|
|
6
|
+
"authorization.reason.cli_untrusted": "无法信任特权命令。",
|
|
7
|
+
"authorization.reason.grant_incompatible": "特权 helper 需要更新。",
|
|
8
|
+
"authorization.reason.package_identity_changed": "套件账号已更改。",
|
|
9
|
+
"authorization.reason.maintenance_task_missing": "找不到维护任务。",
|
|
10
|
+
"authorization.reason.maintenance_task_mismatch": "维护任务已与授权不符。",
|
|
11
|
+
"authorization.reason.helper_health_rejected": "特权 helper 未通过健康检查。",
|
|
12
|
+
"authorization.reason.capability_missing": "特权 helper 缺少必要的能力。",
|
|
13
|
+
"authorization.reason.unknown": "授权已丢失或不再有效。",
|
|
14
|
+
"authorization.next.install": "选择“授权”,并使用您的 DSM 密码确认,即可批准此版本。",
|
|
15
|
+
"authorization.next.update": "此版本需要重新授权。请选择“授权”,并使用您的 DSM 密码确认。",
|
|
16
|
+
"authorization.next.repair": "请在任务计划中检查此套件的任务,再重试。",
|
|
17
|
+
"authorization.authorize": "授权",
|
|
18
|
+
"authorization.authorizing": "正在等待 DSM…",
|
|
19
|
+
"authorization.failed": "授权未完成,您可以重试。",
|
|
20
|
+
"authorization.unavailable.title": "无法检查授权",
|
|
21
|
+
"authorization.unavailable.body": "这通常是暂时的。请重试,{package} 不会要求您的密码。",
|
|
22
|
+
"authorization.credential.title": "DSM 的登录凭据尚未就绪",
|
|
23
|
+
"authorization.credential.body": "此 DSM 会话是恢复而来,并未使用密码登录,因此 DSM 无法为 {package} 的请求作证。请注销 DSM,使用密码重新登录,然后再打开 {package}。",
|
|
24
|
+
"authorization.retry": "重试",
|
|
25
|
+
"authorization.next.reinstall": "安装的文件与此版本不符。请从可信任的来源重新安装套件,再重试。",
|
|
26
|
+
"authorization.not_admin.title": "需要管理员处理",
|
|
27
|
+
"authorization.not_admin.body": "请 DSM 管理员打开此套件并完成授权。",
|
|
28
|
+
"authorization.session_expired.title": "登录已超时",
|
|
29
|
+
"authorization.session_expired.body": "请重新登录 DSM,再打开此套件。",
|
|
30
|
+
"authorization.ready": "已授权",
|
|
31
|
+
"authorization.revoke": "撤销授权",
|
|
32
|
+
"authorization.revoke.title": "撤销授权?",
|
|
33
|
+
"authorization.revoke.body": "新的 helper 访问将被禁用。套件数据与过往结果会保留。",
|
|
34
|
+
"authorization.cancel": "取消",
|
|
35
|
+
"authorization.checking": "正在检查授权…"
|
|
36
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"authorization.title": "{package} 需要您的授權",
|
|
3
|
+
"authorization.purpose": "此套件執行固定的 root 操作前需要核准。密碼由 DSM 處理,套件不會看到或儲存。",
|
|
4
|
+
"authorization.reason.grant_missing": "尚未授權 root 操作。",
|
|
5
|
+
"authorization.reason.helper_untrusted": "無法信任特權 helper。",
|
|
6
|
+
"authorization.reason.cli_untrusted": "無法信任特權命令。",
|
|
7
|
+
"authorization.reason.grant_incompatible": "特權 helper 需要更新。",
|
|
8
|
+
"authorization.reason.package_identity_changed": "套件帳號已變更。",
|
|
9
|
+
"authorization.reason.maintenance_task_missing": "找不到維護任務。",
|
|
10
|
+
"authorization.reason.maintenance_task_mismatch": "維護任務已與授權不符。",
|
|
11
|
+
"authorization.reason.helper_health_rejected": "特權 helper 未通過健康檢查。",
|
|
12
|
+
"authorization.reason.capability_missing": "特權 helper 缺少必要的能力。",
|
|
13
|
+
"authorization.reason.unknown": "授權已遺失或不再有效。",
|
|
14
|
+
"authorization.next.install": "選擇「授權」,並以您的 DSM 密碼確認,即可核准此版本。",
|
|
15
|
+
"authorization.next.update": "此版本需要重新授權。請選擇「授權」,並以您的 DSM 密碼確認。",
|
|
16
|
+
"authorization.next.repair": "請在任務排程表中檢查此套件的任務,再重試。",
|
|
17
|
+
"authorization.authorize": "授權",
|
|
18
|
+
"authorization.authorizing": "正在等待 DSM…",
|
|
19
|
+
"authorization.failed": "授權未完成,您可以再試一次。",
|
|
20
|
+
"authorization.unavailable.title": "無法檢查授權",
|
|
21
|
+
"authorization.unavailable.body": "這通常是暫時的。請再試一次,{package} 不會要求您的密碼。",
|
|
22
|
+
"authorization.credential.title": "DSM 的登入憑證尚未就緒",
|
|
23
|
+
"authorization.credential.body": "此 DSM 工作階段是還原而來,並未使用密碼登入,因此 DSM 無法為 {package} 的要求作證。請登出 DSM,以密碼重新登入,然後再開啟 {package}。",
|
|
24
|
+
"authorization.retry": "重試",
|
|
25
|
+
"authorization.next.reinstall": "安裝的檔案與此版本不符。請從可信任的來源重新安裝套件,再重試。",
|
|
26
|
+
"authorization.not_admin.title": "需要管理員處理",
|
|
27
|
+
"authorization.not_admin.body": "請 DSM 管理員開啟此套件並完成授權。",
|
|
28
|
+
"authorization.session_expired.title": "登入已逾時",
|
|
29
|
+
"authorization.session_expired.body": "請重新登入 DSM,再開啟此套件。",
|
|
30
|
+
"authorization.ready": "已授權",
|
|
31
|
+
"authorization.revoke": "撤銷授權",
|
|
32
|
+
"authorization.revoke.title": "撤銷授權?",
|
|
33
|
+
"authorization.revoke.body": "新的 helper 存取將被停用。套件資料與過往結果會保留。",
|
|
34
|
+
"authorization.cancel": "取消",
|
|
35
|
+
"authorization.checking": "正在檢查授權…"
|
|
36
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><style>html,body,#app{height:100%;margin:0}</style><title>Authorization template preview</title></head><body style="margin:0"><div id="app"></div><script type="module">
|
|
2
|
+
import {createApp,h} from 'vue'
|
|
3
|
+
import {AppRoot,ConfigProvider} from '@synopackageland/ui'
|
|
4
|
+
import Gate from '../src/authorization/AuthorizationGate.vue'
|
|
5
|
+
import App from '../src/App.vue'
|
|
6
|
+
import {uiLocale} from '../src/nas/m2-i18n'
|
|
7
|
+
import '@synopackageland/ui/themes/dsm7-embedded.css'
|
|
8
|
+
const q=new URLSearchParams(location.search),locale=q.get('locale')||'en'
|
|
9
|
+
const state=q.get('state')||'authorization_required',reason=q.get('reason')||'grant_missing'
|
|
10
|
+
const documentStatus=()=>({command:'authorization',schema_version:1,state,reason:state==='ready'?null:reason})
|
|
11
|
+
const ctx={locale,displayName:'__DISPLAY_NAME__',call:async(method)=>{if(method==='app.status')return {package:'RootDemo',version:'0.1.0-0001',user:'admin',admin:true};if(method==='integration.status')return {state:'not-enabled',reason:'not-requested',packageRunning:'unknown',scheduler:'not-probed'};throw {code:'unknown_method'}},reopen:()=>()=>{},authorization:{canManage:()=>true,status:async()=>documentStatus(),request:async()=>{if(q.has('pending'))return new Promise(()=>{});if(q.has('fail'))throw Error('Preview failure');return {command:'authorization',schema_version:1,state:'ready',reason:null}},revoke:async()=>({command:'authorization',schema_version:1,state:'authorization_required',reason:'grant_missing'})}}
|
|
12
|
+
if(q.get('app')==='1')createApp(App,{ctx}).mount('#app');
|
|
13
|
+
else createApp({render:()=>h(AppRoot,{style:'height:100vh',modalScope:'app'},()=>h(ConfigProvider,{locale:uiLocale(locale)},()=>h(Gate,{ctx},()=>h('p',{style:'text-align:center'},'Preview fixture: application content'))))}).mount('#app')
|
|
14
|
+
</script></body></html>
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// @vitest-environment jsdom
|
|
2
|
+
import {expect,test,vi} from 'vitest'
|
|
3
|
+
import {createApp,nextTick} from 'vue'
|
|
4
|
+
import Gate from '../src/authorization/AuthorizationGate.vue'
|
|
5
|
+
import type {AuthorizationStatus,Context} from '../src/context'
|
|
6
|
+
const status=(state:AuthorizationStatus['state'],reason:string|null=null):AuthorizationStatus=>({command:'authorization',schema_version:1,state,reason})
|
|
7
|
+
async function settle(){for(let n=0;n<10;n++){await Promise.resolve();await nextTick()}}
|
|
8
|
+
function fixture(value:AuthorizationStatus){
|
|
9
|
+
let reopen=()=>{}
|
|
10
|
+
const authorization={canManage:()=>true,status:vi.fn(async()=>value),request:vi.fn(async()=>status('ready')),revoke:vi.fn(async()=>status('authorization_required','grant_missing'))}
|
|
11
|
+
const dispose=vi.fn()
|
|
12
|
+
const ctx={locale:'en',authorization,reopen:(fn:()=>void)=>{reopen=fn;return dispose}} as unknown as Context
|
|
13
|
+
const root=document.createElement('div');document.body.append(root)
|
|
14
|
+
const onReady=vi.fn()
|
|
15
|
+
const app=createApp(Gate,{ctx,onReady});app.mount(root)
|
|
16
|
+
return {authorization,root,dispose,onReady,reopen:()=>reopen(),stop(){app.unmount();root.remove()}}
|
|
17
|
+
}
|
|
18
|
+
test.each(['helper_untrusted','cli_untrusted'])('untrusted %s offers reinstall instructions and no password action',async(reason)=>{
|
|
19
|
+
const f=fixture(status('authorization_required',reason));await settle()
|
|
20
|
+
expect(f.root.textContent).toContain('Reinstall');expect(f.root.textContent).not.toContain('Authorize');expect(f.authorization.request).not.toHaveBeenCalled();f.stop()
|
|
21
|
+
})
|
|
22
|
+
test.each(['not_admin','session_expired','unavailable'] as const)('%s never offers password authorization',async(state)=>{
|
|
23
|
+
const f=fixture(status(state));await settle();expect(f.root.textContent).not.toContain('Authorize');expect(f.root.querySelector('button')?.textContent).toBe('Try again');f.stop()
|
|
24
|
+
})
|
|
25
|
+
test('missing grant is approved through host flow and reveals app only after ready readback',async()=>{
|
|
26
|
+
const f=fixture(status('authorization_required','grant_missing'));await settle()
|
|
27
|
+
const button=[...f.root.querySelectorAll('button')].find(b=>b.textContent==='Authorize')!;button.click();await settle()
|
|
28
|
+
expect(f.authorization.request).toHaveBeenCalledOnce();expect(f.root.querySelector('[data-authorization-state]')).toBeNull();f.stop();expect(f.dispose).toHaveBeenCalledOnce()
|
|
29
|
+
})
|
|
30
|
+
test('refreshes product data only after a fresh ready readback',async()=>{
|
|
31
|
+
const f=fixture(status('authorization_required','grant_missing'));await settle()
|
|
32
|
+
expect(f.onReady).not.toHaveBeenCalled()
|
|
33
|
+
f.root.querySelector('button')!.click();await settle()
|
|
34
|
+
expect(f.onReady).toHaveBeenCalledOnce();f.stop()
|
|
35
|
+
})
|
|
36
|
+
test('reopen hides ready content until a fresh status completes and unmount discards its reply',async()=>{
|
|
37
|
+
const f=fixture(status('ready'));await settle()
|
|
38
|
+
let finish!:(value:AuthorizationStatus)=>void
|
|
39
|
+
f.authorization.status.mockImplementation(()=>new Promise(resolve=>{finish=resolve}))
|
|
40
|
+
f.reopen();await nextTick();expect(f.root.querySelector('[data-authorization-state="checking"]')).toBeTruthy()
|
|
41
|
+
f.stop();finish(status('ready'));await settle();expect(f.root.childNodes.length).toBe(0)
|
|
42
|
+
})
|
|
43
|
+
test('revocation closes the gate immediately and queues a reopen that arrives while busy',async()=>{
|
|
44
|
+
const f=fixture(status('ready'));await settle()
|
|
45
|
+
let finish!:(value:AuthorizationStatus)=>void
|
|
46
|
+
f.authorization.revoke.mockImplementation(()=>new Promise(resolve=>{finish=resolve}))
|
|
47
|
+
const revoke=[...f.root.querySelectorAll('button')].find(b=>b.textContent==='Revoke authorization')!;revoke.click();await settle()
|
|
48
|
+
const confirm=[...document.querySelectorAll('button')].find(b=>b.textContent==='Revoke authorization'&&b!==revoke)!
|
|
49
|
+
confirm.click();await nextTick();expect(f.root.querySelector('[data-authorization-state="checking"]')).toBeTruthy()
|
|
50
|
+
f.reopen();finish(status('authorization_required','grant_missing'));await settle()
|
|
51
|
+
expect(f.authorization.status).toHaveBeenCalledTimes(2);f.stop()
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
test('DSM credential recovery explains password sign-in without offering authorization',async()=>{
|
|
55
|
+
const f=fixture(status('unavailable','credential_not_ready'));await settle()
|
|
56
|
+
expect(f.root.textContent).toContain("DSM's sign-in credential is not ready")
|
|
57
|
+
expect(f.root.textContent).toContain('Sign out of DSM')
|
|
58
|
+
expect(f.root.querySelector('button')?.textContent).toBe('Try again');f.stop()
|
|
59
|
+
})
|
|
@@ -37,7 +37,10 @@ export interface HostAdapter {
|
|
|
37
37
|
subscribe(event: HostEvent, listener: () => void): HostSubscriptionResult
|
|
38
38
|
dispose(): void
|
|
39
39
|
}
|
|
40
|
+
export interface AuthorizationStatus {command: "authorization"; schema_version: 1; state: "ready" | "authorization_required" | "not_admin" | "session_expired" | "unavailable"; reason: string | null}
|
|
40
41
|
export interface Context {
|
|
42
|
+
displayName?: string
|
|
43
|
+
authorization?: {canManage?(): boolean; status(): Promise<AuthorizationStatus>; request(): Promise<AuthorizationStatus>; revoke(): Promise<AuthorizationStatus>}
|
|
41
44
|
call<T = unknown>(method: string, params?: Record<string, unknown>): Promise<T>
|
|
42
45
|
reopen(fn: () => void): () => void
|
|
43
46
|
locale: string
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
services:
|
|
2
|
-
web:
|
|
3
|
-
image: busybox:1.36@sha256:73aaf090f3d85aa34ee199857f03fa3a95c8ede2ffd4cc2cdb5b94e566b11662
|
|
4
|
-
# DSM worker constraints to preserve when changing this service:
|
|
5
|
-
# 1) command/entrypoint arrays must not contain bare numeric elements
|
|
6
|
-
# (such as "18333"). DSM's docker-project worker drops the quotes on a
|
|
7
|
-
# YAML round-trip and turns them into integers, so postinst acquire
|
|
8
|
-
# fails (error 276 -> package broken/150, with an empty worker_msg that
|
|
9
|
-
# tells the developer nothing). Keep the port inside one string.
|
|
10
|
-
# `synopkgland validate` already rejects the bare form.
|
|
11
|
-
# 2) The default is not 8080: that port is often taken by an existing
|
|
12
|
-
# container on a real NAS, and the conflict shows up as the same
|
|
13
|
-
# unexplained broken/150.
|
|
14
|
-
# The official nginx image cannot be used either: the resource worker
|
|
15
|
-
# injects an arbitrary package UID/GID, and the nginx entrypoint needs
|
|
16
|
-
# root during startup, so it exits immediately under that identity.
|
|
17
|
-
command: ["sh","-c","httpd -f -p 18333 -h /usr/share/nginx/html"]
|
|
18
|
-
# Bound to loopback on purpose: the DSM-authenticated gateway generated by
|
|
19
|
-
# `synopkgland build-spk` is the only way in. A port on every interface would
|
|
20
|
-
# bypass DSM sign-in, and `synopkgland validate` rejects it.
|
|
21
|
-
ports:
|
|
22
|
-
- "127.0.0.1:18333:18333"
|
|
23
|
-
volumes:
|
|
24
|
-
- "./html:/usr/share/nginx/html:ro"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
document.getElementById("status").textContent = "Your app is running.";
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
-
<title>Hello Web</title>
|
|
7
|
-
</head>
|
|
8
|
-
<body>
|
|
9
|
-
<h1>Hello Web</h1>
|
|
10
|
-
<p id="status">Loading…</p>
|
|
11
|
-
<script type="module" src="./app.js"></script>
|
|
12
|
-
</body>
|
|
13
|
-
</html>
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
schema: 1
|
|
2
|
-
package: com.synology.hello.web
|
|
3
|
-
version: 0.1.0
|
|
4
|
-
displayname: Hello Web
|
|
5
|
-
description: A minimal Syno Package Land web app template.
|
|
6
|
-
maintainer: Syno Package Land
|
|
7
|
-
os_min_ver: "7.2.1-69057"
|
|
8
|
-
adminprotocol: http
|
|
9
|
-
adminport: 18333
|
|
10
|
-
adminurl: /
|
|
11
|
-
integration:
|
|
12
|
-
web:
|
|
13
|
-
launch: dsm-window
|
|
14
|
-
# Who may open the app: dsm-users (any signed-in DSM user), dsm-admins,
|
|
15
|
-
# dsm-groups (with groups: [...]) or public (no DSM sign-in).
|
|
16
|
-
access: dsm-users
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
services:
|
|
2
|
-
web:
|
|
3
|
-
image: busybox:1.36@sha256:73aaf090f3d85aa34ee199857f03fa3a95c8ede2ffd4cc2cdb5b94e566b11662
|
|
4
|
-
# DSM worker constraints to preserve when changing this service:
|
|
5
|
-
# 1) command/entrypoint arrays must not contain bare numeric elements
|
|
6
|
-
# (such as "18333"). DSM's docker-project worker drops the quotes on a
|
|
7
|
-
# YAML round-trip and turns them into integers, so postinst acquire
|
|
8
|
-
# fails (error 276 -> package broken/150, with an empty worker_msg that
|
|
9
|
-
# tells the developer nothing). Keep the port inside one string.
|
|
10
|
-
# `synopkgland validate` already rejects the bare form.
|
|
11
|
-
# 2) The default is not 8080: that port is often taken by an existing
|
|
12
|
-
# container on a real NAS, and the conflict shows up as the same
|
|
13
|
-
# unexplained broken/150.
|
|
14
|
-
# The official nginx image cannot be used either: the resource worker
|
|
15
|
-
# injects an arbitrary package UID/GID, and the nginx entrypoint needs
|
|
16
|
-
# root during startup, so it exits immediately under that identity.
|
|
17
|
-
command: ["sh","-c","httpd -f -p 18333 -h /usr/share/nginx/html"]
|
|
18
|
-
# Bound to loopback on purpose: the DSM-authenticated gateway generated by
|
|
19
|
-
# `synopkgland build-spk` is the only way in. A port on every interface would
|
|
20
|
-
# bypass DSM sign-in, and `synopkgland validate` rejects it.
|
|
21
|
-
ports:
|
|
22
|
-
- "127.0.0.1:18333:18333"
|
|
23
|
-
volumes:
|
|
24
|
-
- "./html:/usr/share/nginx/html:ro"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
document.getElementById("status").textContent = "Your app is running.";
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
-
<title>Hello Web Page</title>
|
|
7
|
-
</head>
|
|
8
|
-
<body>
|
|
9
|
-
<h1>Hello Web Page</h1>
|
|
10
|
-
<p id="status">Loading…</p>
|
|
11
|
-
<script type="module" src="./app.js"></script>
|
|
12
|
-
</body>
|
|
13
|
-
</html>
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
schema: 1
|
|
2
|
-
package: com.synology.hello.web.page
|
|
3
|
-
version: 0.1.0
|
|
4
|
-
displayname: Hello Web Page
|
|
5
|
-
description: A Syno Package Land web app template that opens in a new browser page.
|
|
6
|
-
maintainer: Syno Package Land
|
|
7
|
-
os_min_ver: "7.2.1-69057"
|
|
8
|
-
adminprotocol: http
|
|
9
|
-
adminport: 18333
|
|
10
|
-
adminurl: /
|
|
11
|
-
integration:
|
|
12
|
-
web:
|
|
13
|
-
launch: new-page
|
|
14
|
-
# Who may open the app: dsm-users (any signed-in DSM user), dsm-admins,
|
|
15
|
-
# dsm-groups (with groups: [...]) or public (no DSM sign-in).
|
|
16
|
-
access: dsm-users
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
services:
|
|
2
|
-
web:
|
|
3
|
-
image: busybox:1.36@sha256:73aaf090f3d85aa34ee199857f03fa3a95c8ede2ffd4cc2cdb5b94e566b11662
|
|
4
|
-
# DSM worker constraints to preserve when changing this service:
|
|
5
|
-
# 1) command/entrypoint arrays must not contain bare numeric elements
|
|
6
|
-
# (such as "18333"). DSM's docker-project worker drops the quotes on a
|
|
7
|
-
# YAML round-trip and turns them into integers, so postinst acquire
|
|
8
|
-
# fails (error 276 -> package broken/150, with an empty worker_msg that
|
|
9
|
-
# tells the developer nothing). Keep the port inside one string.
|
|
10
|
-
# `synopkgland validate` already rejects the bare form.
|
|
11
|
-
# 2) The default is not 8080: that port is often taken by an existing
|
|
12
|
-
# container on a real NAS, and the conflict shows up as the same
|
|
13
|
-
# unexplained broken/150.
|
|
14
|
-
# The official nginx image cannot be used either: the resource worker
|
|
15
|
-
# injects an arbitrary package UID/GID, and the nginx entrypoint needs
|
|
16
|
-
# root during startup, so it exits immediately under that identity.
|
|
17
|
-
command: ["sh","-c","httpd -f -p 18333 -h /usr/share/nginx/html"]
|
|
18
|
-
# Bound to loopback on purpose: the DSM-authenticated gateway generated by
|
|
19
|
-
# `synopkgland build-spk` is the only way in. A port on every interface would
|
|
20
|
-
# bypass DSM sign-in, and `synopkgland validate` rejects it.
|
|
21
|
-
ports:
|
|
22
|
-
- "127.0.0.1:18333:18333"
|
|
23
|
-
volumes:
|
|
24
|
-
- "./html:/usr/share/nginx/html:ro"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
document.getElementById("status").textContent = "Your app is running.";
|