@velor/remote-mouse 6.4.8

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.
Files changed (316) hide show
  1. package/.artifacts/screenshots/remote-mobile-config.png +0 -0
  2. package/.artifacts/screenshots/remote-mobile-home.png +0 -0
  3. package/.artifacts/screenshots/remote-mobile-preferences.png +0 -0
  4. package/.artifacts/screenshots/remote-mobile-server-info.png +0 -0
  5. package/.artifacts/screenshots/remote-mobile-vlc.png +0 -0
  6. package/.env.example +93 -0
  7. package/README.md +370 -0
  8. package/bin/remote-mouse.js +19 -0
  9. package/client/core/dom.js +148 -0
  10. package/client/core/init-socket-io.js +117 -0
  11. package/client/core/socket-emit.js +6 -0
  12. package/client/core/window-events.js +23 -0
  13. package/client/i18n/apply-page-translations.js +18 -0
  14. package/client/i18n/constants.js +3 -0
  15. package/client/i18n/core.js +40 -0
  16. package/client/i18n/locale-registry.js +77 -0
  17. package/client/i18n/locales/de.js +227 -0
  18. package/client/i18n/locales/en.js +389 -0
  19. package/client/i18n/locales/es.js +228 -0
  20. package/client/i18n/locales/fr.js +389 -0
  21. package/client/i18n/locales/it.js +227 -0
  22. package/client/i18n/locales/ja.js +227 -0
  23. package/client/i18n/locales/pt.js +227 -0
  24. package/client/i18n/locales/ru.js +240 -0
  25. package/client/i18n/locales/zh.js +227 -0
  26. package/client/preferences/constants.js +15 -0
  27. package/client/preferences/effects.js +24 -0
  28. package/client/preferences/load.js +19 -0
  29. package/client/preferences/render.js +26 -0
  30. package/client/preferences/rows.js +78 -0
  31. package/client/preferences/state.js +29 -0
  32. package/client/preview/create-preview-frame-receiver.js +13 -0
  33. package/client/preview/draw.js +77 -0
  34. package/client/preview/parse-preview-frame.js +39 -0
  35. package/client/preview/preview-stream.js +152 -0
  36. package/client/services/app-state/appStateKeys.js +30 -0
  37. package/client/services/app-state/createAppStateService.js +216 -0
  38. package/client/services/app-state/createPersistStoreService.js +122 -0
  39. package/client/services/app-state/createStateStoreService.js +64 -0
  40. package/client/services/app-state/localStorageBinding.js +26 -0
  41. package/client/services/app-state/normalizers.js +74 -0
  42. package/client/services/app-state/resolveEffectiveStateValue.js +58 -0
  43. package/client/services/app-state/stateDefinitions.js +107 -0
  44. package/client/services/backend/createBackendService.js +55 -0
  45. package/client/services/config/ConfigView.js +45 -0
  46. package/client/services/config/createClientConfigService.js +122 -0
  47. package/client/services/config/defaultClientConfig.js +22 -0
  48. package/client/services/createServicesContainer.js +48 -0
  49. package/client/services/createServicesRegistry.js +26 -0
  50. package/client/services/i18n/createI18nService.js +86 -0
  51. package/client/services/notifications/createNotificationService.js +56 -0
  52. package/client/services/pubsub/createPubSubService.js +20 -0
  53. package/client/services/remotes/createRemotesService.js +20 -0
  54. package/client/services/transport/createSocketIoTransportService.js +50 -0
  55. package/client/touch/bindTouchPassthrough.js +94 -0
  56. package/client/touch/createTouchList.js +18 -0
  57. package/client/touch/dispatchSyntheticTouch.js +20 -0
  58. package/client/touch/gesture-zone.js +28 -0
  59. package/client/touch/throttle.js +46 -0
  60. package/client/touch/touch-handlers.js +193 -0
  61. package/client/touch/touchpad.js +231 -0
  62. package/client/ui/config/page.js +840 -0
  63. package/client/ui/main/applyRemoteVisibilityState.js +60 -0
  64. package/client/ui/main/bind-client-notifications.js +3 -0
  65. package/client/ui/main/bindings/bindAccordion.js +121 -0
  66. package/client/ui/main/bindings/bindActionButtons.js +13 -0
  67. package/client/ui/main/bindings/bindAdminDrawer.js +137 -0
  68. package/client/ui/main/bindings/bindAdminRemoteButtons.js +77 -0
  69. package/client/ui/main/bindings/bindAdminVersion.js +27 -0
  70. package/client/ui/main/bindings/bindBrowserRemoteButtons.js +119 -0
  71. package/client/ui/main/bindings/bindRemoteAccordion.js +23 -0
  72. package/client/ui/main/bindings/bindSamsungRemoteButtons.js +320 -0
  73. package/client/ui/main/bindings/bindSystemRemoteButtons.js +41 -0
  74. package/client/ui/main/bindings/bindVlcRemoteButtons.js +64 -0
  75. package/client/ui/main/canvas-ui.js +33 -0
  76. package/client/ui/main/connection-overlay.js +57 -0
  77. package/client/ui/main/init-ui.js +54 -0
  78. package/client/ui/main/keyboard-panel.js +271 -0
  79. package/client/ui/main/mouse-buttons.js +94 -0
  80. package/client/ui/main/page.js +21 -0
  81. package/client/ui/notifications/show-toast.js +48 -0
  82. package/client/ui/preferences/bindPreferenceSwitchers.js +49 -0
  83. package/client/ui/preferences/page.js +61 -0
  84. package/client/ui/preferences/switchers.js +200 -0
  85. package/index.js +9 -0
  86. package/package.json +41 -0
  87. package/public/admin-config.css +447 -0
  88. package/public/admin-config.html +63 -0
  89. package/public/apple-touch-icon.png +0 -0
  90. package/public/brave-icon.svg +13 -0
  91. package/public/favicon.svg +30 -0
  92. package/public/icon-192.png +0 -0
  93. package/public/icon-512.png +0 -0
  94. package/public/index.html +246 -0
  95. package/public/manifest.webmanifest +45 -0
  96. package/public/preferences.html +55 -0
  97. package/public/server-info.html +574 -0
  98. package/public/styles.css +1042 -0
  99. package/public/sw.js +103 -0
  100. package/scripts/codex-commit.sh +112 -0
  101. package/scripts/generate-mobile-screenshots.mjs +244 -0
  102. package/scripts/install-linux.sh +633 -0
  103. package/scripts/install-windows.ps1 +369 -0
  104. package/server/application/createApplicationLifecycle.js +15 -0
  105. package/server/application/logger.js +216 -0
  106. package/server/application/shutdown.js +81 -0
  107. package/server/application/start.js +95 -0
  108. package/server/application/state.js +19 -0
  109. package/server/connection/api/admin-actions.router.js +65 -0
  110. package/server/connection/api/admin-configs.router.js +165 -0
  111. package/server/connection/api/admin-remotes.router.js +61 -0
  112. package/server/connection/api/admin-subs.router.js +49 -0
  113. package/server/connection/api/client.router.js +15 -0
  114. package/server/connection/api/configs.js +96 -0
  115. package/server/connection/api/qr-page.handler.js +17 -0
  116. package/server/connection/api/remotes.router.js +30 -0
  117. package/server/connection/api/server-info.router.js +149 -0
  118. package/server/connection/api/session.middleware.js +93 -0
  119. package/server/connection/api/unauthorized-response.js +73 -0
  120. package/server/connection/socket/createConnectionRegistrar.js +23 -0
  121. package/server/connection/socket/createSocketSessionAuthMiddleware.js +49 -0
  122. package/server/connection/socket/socket-action-responder.js +12 -0
  123. package/server/connection/socket/socket.timestamp-middleware.js +51 -0
  124. package/server/index.js +12 -0
  125. package/server/init/bootstrapApi.js +87 -0
  126. package/server/init/bootstrapSocket.js +79 -0
  127. package/server/init/createAdminApiRouter.js +22 -0
  128. package/server/init/createAdminUiRouter.js +21 -0
  129. package/server/init/createSocketActionRegistrars.js +52 -0
  130. package/server/init/observers/startConfigObserver.js +51 -0
  131. package/server/init/observers/startDisplaySizeObserver.js +55 -0
  132. package/server/init/observers/startNotificationObserver.js +49 -0
  133. package/server/init/observers/startQrOverlayHoverObserver.js +89 -0
  134. package/server/init/observers/startQrOverlayRefreshObserver.js +53 -0
  135. package/server/os/darwin/app.js +45 -0
  136. package/server/os/darwin/applescript.js +51 -0
  137. package/server/os/darwin/cliSocket.js +53 -0
  138. package/server/os/darwin/url.js +9 -0
  139. package/server/os/darwin/window.js +10 -0
  140. package/server/os/linux/app.js +120 -0
  141. package/server/os/linux/cliSocket.js +53 -0
  142. package/server/os/linux/process.js +69 -0
  143. package/server/os/linux/screen.js +58 -0
  144. package/server/os/linux/systemd.js +139 -0
  145. package/server/os/linux/url.js +17 -0
  146. package/server/os/linux/windows.js +144 -0
  147. package/server/os/win32/app.js +66 -0
  148. package/server/os/win32/cliSocket.js +15 -0
  149. package/server/os/win32/powershell.js +70 -0
  150. package/server/os/win32/process.js +20 -0
  151. package/server/os/win32/service.js +95 -0
  152. package/server/os/win32/url.js +9 -0
  153. package/server/os/win32/window.js +10 -0
  154. package/server/remotes/admin/createAdminEventGuardMiddleware.js +29 -0
  155. package/server/remotes/admin/createForceUpdateCheckAction.js +39 -0
  156. package/server/remotes/admin/createInstallUpdateAction.js +64 -0
  157. package/server/remotes/admin/createOpenQrBrowserAction.js +63 -0
  158. package/server/remotes/admin/createOpenServerInfoBrowserAction.js +58 -0
  159. package/server/remotes/admin/createRestartServiceAction.js +20 -0
  160. package/server/remotes/admin/createRotateEntryTokenAction.js +43 -0
  161. package/server/remotes/admin/createToggleQrOverlayAction.js +38 -0
  162. package/server/remotes/admin/index.js +32 -0
  163. package/server/remotes/admin/notifyIfRestarted.js +102 -0
  164. package/server/remotes/admin/registrar.js +94 -0
  165. package/server/remotes/browser/actions/createFocusOrLaunchBrowserAction.js +22 -0
  166. package/server/remotes/browser/actions/openUrlOnHost.js +3 -0
  167. package/server/remotes/browser/browserCatalog.js +70 -0
  168. package/server/remotes/browser/index.js +15 -0
  169. package/server/remotes/browser/listBrowsersOnHost.js +23 -0
  170. package/server/remotes/browser/registrar.js +29 -0
  171. package/server/remotes/browser/spec.js +18 -0
  172. package/server/remotes/browser/state.js +5 -0
  173. package/server/remotes/input/registrar.js +39 -0
  174. package/server/remotes/preview/bgraToRgbaBuffer.js +20 -0
  175. package/server/remotes/preview/captureAroundCursor.js +19 -0
  176. package/server/remotes/preview/createPreviewStreamer.js +85 -0
  177. package/server/remotes/preview/registrar.js +34 -0
  178. package/server/remotes/samsung/createSamsungCommandService.js +203 -0
  179. package/server/remotes/samsung/createSamsungRemote.js +26 -0
  180. package/server/remotes/samsung/createSamsungRemoteGetter.js +46 -0
  181. package/server/remotes/samsung/createSamsungTvGetter.js +102 -0
  182. package/server/remotes/samsung/device-config.js +122 -0
  183. package/server/remotes/samsung/registrar.js +59 -0
  184. package/server/remotes/samsung/utils.js +56 -0
  185. package/server/remotes/vlc/index.js +39 -0
  186. package/server/remotes/vlc/registrar.js +94 -0
  187. package/server/remotes/vlc/spec.js +15 -0
  188. package/server/remotes/vlc/state.js +5 -0
  189. package/server/remotes/window/index.js +6 -0
  190. package/server/remotes/window/registrar.js +28 -0
  191. package/server/services/application/createApplicationDaemonService.js +144 -0
  192. package/server/services/application/getDaemonServiceAdapter.js +56 -0
  193. package/server/services/application/utils.js +29 -0
  194. package/server/services/config/bootstrapConfig.js +38 -0
  195. package/server/services/config/configPaths.js +42 -0
  196. package/server/services/config/configSchema.js +297 -0
  197. package/server/services/config/configService.js +89 -0
  198. package/server/services/config/defaultConfig.js +137 -0
  199. package/server/services/config/envConfig.js +49 -0
  200. package/server/services/config/index.js +9 -0
  201. package/server/services/config/logConfig.js +54 -0
  202. package/server/services/config/system-config.js +44 -0
  203. package/server/services/createServicesContainer.js +94 -0
  204. package/server/services/createServicesRegistry.js +48 -0
  205. package/server/services/input/createInputController.js +17 -0
  206. package/server/services/input/createKeyboardController.js +146 -0
  207. package/server/services/input/createMouseController.js +182 -0
  208. package/server/services/notifier/createClientNotifier.js +23 -0
  209. package/server/services/notifier/createHostNotifier.js +41 -0
  210. package/server/services/notifier/createNotifier.js +13 -0
  211. package/server/services/notifier/createNotifierComposite.js +122 -0
  212. package/server/services/notifier/handleOpenQrBrowserEvent.js +40 -0
  213. package/server/services/notifier/handleOpenServerInfoBrowserEvent.js +40 -0
  214. package/server/services/notifier/handleRestartServiceEvent.js +37 -0
  215. package/server/services/notifier/handleRotateEntryTokenEvent.js +42 -0
  216. package/server/services/notifier/handleSessionEvent.js +24 -0
  217. package/server/services/notifier/handleToggleQrOverlayEvent.js +21 -0
  218. package/server/services/notifier/host-notifier/createLinuxHostNotifier.js +23 -0
  219. package/server/services/notifier/host-notifier/createNodeNotifierHostNotifier.js +24 -0
  220. package/server/services/notifier/host-notifier/index.js +11 -0
  221. package/server/services/notifier/mapper/handleForceUpdateCheckEvent.js +24 -0
  222. package/server/services/notifier/mapper/handleInstallUpdateEvent.js +53 -0
  223. package/server/services/notifier/mapper/handleSocketEvent.js +40 -0
  224. package/server/services/notifier/mapper/handleUpdateManagerEvent.js +24 -0
  225. package/server/services/notifier/mapper/notify.js +7 -0
  226. package/server/services/os/index.js +23 -0
  227. package/server/services/os/platforms/createFallbackAdapter.js +31 -0
  228. package/server/services/os/platforms/darwin/app.js +6 -0
  229. package/server/services/os/platforms/darwin/index.js +21 -0
  230. package/server/services/os/platforms/darwin/scripts.js +4 -0
  231. package/server/services/os/platforms/darwin/url.js +1 -0
  232. package/server/services/os/platforms/darwin/window.js +4 -0
  233. package/server/services/os/platforms/linux/app.js +6 -0
  234. package/server/services/os/platforms/linux/index.js +33 -0
  235. package/server/services/os/platforms/linux/url.js +1 -0
  236. package/server/services/os/platforms/linux/windows.js +11 -0
  237. package/server/services/os/platforms/win32/app.js +6 -0
  238. package/server/services/os/platforms/win32/index.js +21 -0
  239. package/server/services/os/platforms/win32/overlay.js +6 -0
  240. package/server/services/os/platforms/win32/powershell.js +4 -0
  241. package/server/services/os/platforms/win32/url.js +1 -0
  242. package/server/services/os/platforms/win32/window.js +4 -0
  243. package/server/services/os/shared.js +2 -0
  244. package/server/services/overlay/createNoopOverlay.js +13 -0
  245. package/server/services/overlay/createQrOverlay.js +27 -0
  246. package/server/services/overlay/createQrOverlayWin32.js +158 -0
  247. package/server/services/overlay/createQrOverlayYad.js +178 -0
  248. package/server/services/overlay/renderQrPage.js +82 -0
  249. package/server/services/persistence/createConfigDao.js +106 -0
  250. package/server/services/persistence/createDatabaseProvider.js +23 -0
  251. package/server/services/persistence/createEntryTokenDao.js +140 -0
  252. package/server/services/persistence/createRestartLogDao.js +210 -0
  253. package/server/services/persistence/index.js +19 -0
  254. package/server/services/pubsub/createEventStore.js +54 -0
  255. package/server/services/pubsub/createPubSub.js +89 -0
  256. package/server/services/pubsub/createServiceEvents.js +29 -0
  257. package/server/services/pubsub/serviceEventConstants.js +39 -0
  258. package/server/services/remotes/createRemotes.js +25 -0
  259. package/server/services/server/createHttpsServer.js +12 -0
  260. package/server/services/server/createServer.js +66 -0
  261. package/server/services/sse/createSseService.js +96 -0
  262. package/server/services/sse/utils.js +7 -0
  263. package/server/services/system/createSystemService.js +170 -0
  264. package/server/services/system/getNetworkInfo.js +18 -0
  265. package/server/services/system/getScreenInfo.js +32 -0
  266. package/server/services/system/listNetworkInterfaces.js +27 -0
  267. package/server/services/task-manager/createTaskManager.js +68 -0
  268. package/server/services/task-runner/createTaskRunner.js +114 -0
  269. package/server/services/token-manager/createTokenManager.js +244 -0
  270. package/server/services/token-manager/token-format.js +7 -0
  271. package/server/services/token-manager/token-store-utils.js +8 -0
  272. package/server/services/update-manager/CommandUpdateSource.js +70 -0
  273. package/server/services/update-manager/NpmUpdateSource.js +34 -0
  274. package/server/services/update-manager/buildNpmGlobalUpdateCommand.js +15 -0
  275. package/server/services/update-manager/chooseUpdateCheckSource.js +20 -0
  276. package/server/services/update-manager/chooseUpdateInstallSource.js +5 -0
  277. package/server/services/update-manager/createUpdateManager.js +109 -0
  278. package/server/services/update-manager/resolveInstallUpdateCommand.js +42 -0
  279. package/server/term/cli/executeLocalServiceCommand.js +42 -0
  280. package/server/term/cli/getCliSocketPath.js +5 -0
  281. package/server/term/cli/parseCliArgs.js +110 -0
  282. package/server/term/cli/printCliResult.js +18 -0
  283. package/server/term/cli/runCliCmd.js +50 -0
  284. package/server/term/cli/sendCliCommand.js +76 -0
  285. package/server/term/cliSocket.js +29 -0
  286. package/server/term/srv/commands/configCommand.js +84 -0
  287. package/server/term/srv/commands/helpCommand.js +6 -0
  288. package/server/term/srv/commands/infoCommand.js +7 -0
  289. package/server/term/srv/commands/openQrCommand.js +7 -0
  290. package/server/term/srv/commands/samsungDetectCommand.js +52 -0
  291. package/server/term/srv/commands/serviceCommand.js +25 -0
  292. package/server/term/srv/commands/systemConfigCommand.js +7 -0
  293. package/server/term/srv/commands/tasksCommand.js +24 -0
  294. package/server/term/srv/commands/tokensCommand.js +15 -0
  295. package/server/term/srv/executeCliCommand.js +44 -0
  296. package/server/term/srv/executeCliRequest.js +38 -0
  297. package/server/term/srv/startCliServer.js +140 -0
  298. package/server/utils/createRandomToken.js +11 -0
  299. package/server/utils/env.js +155 -0
  300. package/server/utils/git.js +13 -0
  301. package/server/utils/http.js +7 -0
  302. package/server/utils/network.js +45 -0
  303. package/server/utils/paths.js +10 -0
  304. package/server/utils/process.js +57 -0
  305. package/server/utils/robot.js +11 -0
  306. package/server/utils/semver.js +33 -0
  307. package/server/utils/truncateText.js +7 -0
  308. package/utils/createLazy.js +13 -0
  309. package/utils/functional.js +48 -0
  310. package/utils/math.js +26 -0
  311. package/utils/notificationSettings.js +61 -0
  312. package/utils/object.utils.js +79 -0
  313. package/utils/predicates.js +17 -0
  314. package/utils/remoteCommands.js +40 -0
  315. package/utils/sync.js +3 -0
  316. package/velor-remote-mouse-6.4.8.tgz +0 -0
@@ -0,0 +1,633 @@
1
+ #!/usr/bin/env bash
2
+
3
+ set -euo pipefail
4
+
5
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6
+ PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
7
+ DEFAULT_NPM_PACKAGE="@velor/remote-mouse"
8
+ MIN_NODE_MAJOR=20
9
+ NODESOURCE_MAJOR=22
10
+
11
+ if [[ -f "$PROJECT_ROOT/package.json" ]]; then
12
+ PACKAGE_JSON_NAME="$(sed -n 's/^[[:space:]]*"name"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' "$PROJECT_ROOT/package.json" | head -n 1)"
13
+ if [[ -n "$PACKAGE_JSON_NAME" ]]; then
14
+ DEFAULT_NPM_PACKAGE="$PACKAGE_JSON_NAME"
15
+ fi
16
+ fi
17
+
18
+ YES=0
19
+ NPM_PACKAGE="${REMOTE_MOUSE_NPM_PACKAGE:-$DEFAULT_NPM_PACKAGE}"
20
+ CONFIG_DIR="${REMOTE_MOUSE_CONFIG_DIR:-$HOME/.config/remote-mouse}"
21
+ PORT="${REMOTE_MOUSE_PORT:-3000}"
22
+ HTTPS="false"
23
+ SSL_KEY_PATH="${REMOTE_MOUSE_SSL_KEY_PATH:-}"
24
+ SSL_CERT_PATH="${REMOTE_MOUSE_SSL_CERT_PATH:-}"
25
+ INSTALL_SERVICE="false"
26
+ HTTPS_CHOICE=""
27
+ GENERATE_CERT_CHOICE=""
28
+ INSTALL_SERVICE_CHOICE=""
29
+
30
+ usage() {
31
+ cat <<'EOF'
32
+ Usage: scripts/install-linux.sh [options]
33
+
34
+ Options:
35
+ -y, --yes Answer yes to every confirmation prompt.
36
+ --package <name> npm package to install globally.
37
+ --config-dir <path> Remote Mouse config directory.
38
+ --port <port> Server port written to the generated .env.
39
+ --https Configure HTTPS without prompting.
40
+ --no-https Disable HTTPS without prompting.
41
+ --generate-cert Generate a self-signed certificate without prompting.
42
+ --no-generate-cert Use existing certificate paths without prompting.
43
+ --ssl-key-path <path> Existing PEM private key path.
44
+ --ssl-cert-path <path> Existing PEM certificate path.
45
+ --install-service Install and restart the service without prompting.
46
+ --no-service Do not install the service.
47
+ -h, --help Show this help.
48
+
49
+ Environment:
50
+ REMOTE_MOUSE_NPM_PACKAGE npm package name override.
51
+ REMOTE_MOUSE_CONFIG_DIR config directory override.
52
+ REMOTE_MOUSE_PORT server port override.
53
+ REMOTE_MOUSE_SSL_KEY_PATH existing PEM private key path.
54
+ REMOTE_MOUSE_SSL_CERT_PATH existing PEM certificate path.
55
+ EOF
56
+ }
57
+
58
+ while [[ $# -gt 0 ]]; do
59
+ case "$1" in
60
+ -y|--yes)
61
+ YES=1
62
+ shift
63
+ ;;
64
+ --package)
65
+ NPM_PACKAGE="${2:-}"
66
+ shift 2
67
+ ;;
68
+ --config-dir)
69
+ CONFIG_DIR="${2:-}"
70
+ shift 2
71
+ ;;
72
+ --port)
73
+ PORT="${2:-}"
74
+ shift 2
75
+ ;;
76
+ --https)
77
+ HTTPS_CHOICE="true"
78
+ shift
79
+ ;;
80
+ --no-https)
81
+ HTTPS_CHOICE="false"
82
+ shift
83
+ ;;
84
+ --generate-cert)
85
+ GENERATE_CERT_CHOICE="true"
86
+ shift
87
+ ;;
88
+ --no-generate-cert)
89
+ GENERATE_CERT_CHOICE="false"
90
+ shift
91
+ ;;
92
+ --ssl-key-path)
93
+ SSL_KEY_PATH="${2:-}"
94
+ shift 2
95
+ ;;
96
+ --ssl-cert-path)
97
+ SSL_CERT_PATH="${2:-}"
98
+ shift 2
99
+ ;;
100
+ --install-service)
101
+ INSTALL_SERVICE_CHOICE="true"
102
+ shift
103
+ ;;
104
+ --no-service)
105
+ INSTALL_SERVICE_CHOICE="false"
106
+ shift
107
+ ;;
108
+ -h|--help)
109
+ usage
110
+ exit 0
111
+ ;;
112
+ *)
113
+ echo "Unknown option: $1" >&2
114
+ usage >&2
115
+ exit 1
116
+ ;;
117
+ esac
118
+ done
119
+
120
+ if [[ -z "$NPM_PACKAGE" ]]; then
121
+ echo "Missing npm package name." >&2
122
+ exit 1
123
+ fi
124
+
125
+ if [[ -z "$CONFIG_DIR" ]]; then
126
+ echo "Missing config directory." >&2
127
+ exit 1
128
+ fi
129
+
130
+ if [[ -z "$PORT" ]]; then
131
+ echo "Missing port." >&2
132
+ exit 1
133
+ fi
134
+
135
+ log() {
136
+ printf '\n%s\n' "$*"
137
+ }
138
+
139
+ confirm() {
140
+ local prompt="$1"
141
+ if [[ "$YES" -eq 1 ]]; then
142
+ printf '%s [Y/n] y\n' "$prompt"
143
+ return 0
144
+ fi
145
+
146
+ if [[ ! -r /dev/tty ]]; then
147
+ echo "Cannot prompt without a terminal. Rerun with -y to accept prompts automatically." >&2
148
+ exit 1
149
+ fi
150
+
151
+ local answer
152
+ read -r -p "$prompt [y/N] " answer </dev/tty
153
+ case "$answer" in
154
+ y|Y|yes|YES|Yes)
155
+ return 0
156
+ ;;
157
+ *)
158
+ return 1
159
+ ;;
160
+ esac
161
+ }
162
+
163
+ prompt_value() {
164
+ local prompt="$1"
165
+ local default_value="${2:-}"
166
+ local value
167
+
168
+ if [[ "$YES" -eq 1 ]]; then
169
+ printf '%s [%s] %s\n' "$prompt" "$default_value" "$default_value" >&2
170
+ printf '%s\n' "$default_value"
171
+ return
172
+ fi
173
+
174
+ if [[ ! -r /dev/tty ]]; then
175
+ echo "Cannot prompt without a terminal. Rerun with -y and explicit options." >&2
176
+ exit 1
177
+ fi
178
+
179
+ if [[ -n "$default_value" ]]; then
180
+ read -r -p "$prompt [$default_value] " value </dev/tty
181
+ printf '%s\n' "${value:-$default_value}"
182
+ else
183
+ read -r -p "$prompt " value </dev/tty
184
+ printf '%s\n' "$value"
185
+ fi
186
+ }
187
+
188
+ sudo_cmd() {
189
+ if [[ "$(id -u)" -eq 0 ]]; then
190
+ "$@"
191
+ else
192
+ sudo "$@"
193
+ fi
194
+ }
195
+
196
+ require_command() {
197
+ local command_name="$1"
198
+ if ! command -v "$command_name" >/dev/null 2>&1; then
199
+ echo "Missing required command: $command_name" >&2
200
+ return 1
201
+ fi
202
+ }
203
+
204
+ detect_package_manager() {
205
+ if command -v apt-get >/dev/null 2>&1; then
206
+ echo "apt"
207
+ elif command -v dnf >/dev/null 2>&1; then
208
+ echo "dnf"
209
+ elif command -v yum >/dev/null 2>&1; then
210
+ echo "yum"
211
+ elif command -v pacman >/dev/null 2>&1; then
212
+ echo "pacman"
213
+ elif command -v zypper >/dev/null 2>&1; then
214
+ echo "zypper"
215
+ else
216
+ echo ""
217
+ fi
218
+ }
219
+
220
+ package_for_dependency() {
221
+ local manager="$1"
222
+ local dependency="$2"
223
+ case "$manager" in
224
+ apt)
225
+ case "$dependency" in
226
+ node) echo "nodejs" ;;
227
+ npm) echo "npm" ;;
228
+ build) echo "build-essential" ;;
229
+ x11) echo "libx11-dev" ;;
230
+ xtst) echo "libxtst-dev" ;;
231
+ png) echo "libpng++-dev" ;;
232
+ wmctrl) echo "wmctrl" ;;
233
+ yad) echo "yad" ;;
234
+ openssl) echo "openssl" ;;
235
+ esac
236
+ ;;
237
+ dnf|yum)
238
+ case "$dependency" in
239
+ node) echo "nodejs" ;;
240
+ npm) echo "npm" ;;
241
+ build) echo "gcc-c++ make" ;;
242
+ x11) echo "libX11-devel" ;;
243
+ xtst) echo "libXtst-devel" ;;
244
+ png) echo "libpng-devel" ;;
245
+ wmctrl) echo "wmctrl" ;;
246
+ yad) echo "yad" ;;
247
+ openssl) echo "openssl" ;;
248
+ esac
249
+ ;;
250
+ pacman)
251
+ case "$dependency" in
252
+ node) echo "nodejs" ;;
253
+ npm) echo "npm" ;;
254
+ build) echo "base-devel" ;;
255
+ x11) echo "libx11" ;;
256
+ xtst) echo "libxtst" ;;
257
+ png) echo "libpng" ;;
258
+ wmctrl) echo "wmctrl" ;;
259
+ yad) echo "yad" ;;
260
+ openssl) echo "openssl" ;;
261
+ esac
262
+ ;;
263
+ zypper)
264
+ case "$dependency" in
265
+ node) echo "nodejs" ;;
266
+ npm) echo "npm" ;;
267
+ build) echo "gcc-c++ make" ;;
268
+ x11) echo "libX11-devel" ;;
269
+ xtst) echo "libXtst-devel" ;;
270
+ png) echo "libpng16-devel" ;;
271
+ wmctrl) echo "wmctrl" ;;
272
+ yad) echo "yad" ;;
273
+ openssl) echo "openssl" ;;
274
+ esac
275
+ ;;
276
+ *)
277
+ echo ""
278
+ ;;
279
+ esac
280
+ }
281
+
282
+ node_major_version() {
283
+ local version
284
+ version="$(node --version 2>/dev/null || true)"
285
+ version="${version#v}"
286
+ version="${version%%.*}"
287
+ if [[ "$version" =~ ^[0-9]+$ ]]; then
288
+ printf '%s\n' "$version"
289
+ else
290
+ printf '0\n'
291
+ fi
292
+ }
293
+
294
+ has_supported_node() {
295
+ command -v node >/dev/null 2>&1 || return 1
296
+ [[ "$(node_major_version)" -ge "$MIN_NODE_MAJOR" ]]
297
+ }
298
+
299
+ contains_word() {
300
+ local needle="$1"
301
+ shift
302
+ local value
303
+ for value in "$@"; do
304
+ if [[ "$value" == "$needle" ]]; then
305
+ return 0
306
+ fi
307
+ done
308
+ return 1
309
+ }
310
+
311
+ install_nodesource_node_apt() {
312
+ log "Installing Node.js $NODESOURCE_MAJOR.x from NodeSource for npm package compatibility."
313
+ sudo_cmd apt-get update
314
+ sudo_cmd apt-get install -y ca-certificates curl gnupg
315
+ if [[ "$(id -u)" -eq 0 ]]; then
316
+ curl -fsSL "https://deb.nodesource.com/setup_${NODESOURCE_MAJOR}.x" | bash -
317
+ else
318
+ curl -fsSL "https://deb.nodesource.com/setup_${NODESOURCE_MAJOR}.x" | sudo bash -
319
+ fi
320
+ sudo_cmd apt-get install -y nodejs
321
+ }
322
+
323
+ append_packages_for_dependency() {
324
+ local manager="$1"
325
+ local dependency="$2"
326
+ local package_names
327
+ package_names="$(package_for_dependency "$manager" "$dependency")"
328
+ local package_name
329
+ for package_name in $package_names; do
330
+ MISSING_PACKAGES+=("$package_name")
331
+ done
332
+ }
333
+
334
+ dedupe_words() {
335
+ local seen=" "
336
+ local value
337
+ for value in "$@"; do
338
+ if [[ "$seen" != *" $value "* ]]; then
339
+ printf '%s\n' "$value"
340
+ seen="${seen}${value} "
341
+ fi
342
+ done
343
+ }
344
+
345
+ can_compile_header() {
346
+ local include_line="$1"
347
+ local compiler="${CC:-cc}"
348
+ if ! command -v "$compiler" >/dev/null 2>&1; then
349
+ return 1
350
+ fi
351
+
352
+ printf '%s\nint main(void) { return 0; }\n' "$include_line" | "$compiler" -x c - -o /tmp/remote-mouse-install-check >/dev/null 2>&1
353
+ rm -f /tmp/remote-mouse-install-check
354
+ }
355
+
356
+ check_functional_dependencies() {
357
+ MISSING_DEPS=()
358
+
359
+ has_supported_node || MISSING_DEPS+=("node")
360
+ command -v npm >/dev/null 2>&1 || MISSING_DEPS+=("npm")
361
+
362
+ if ! command -v gcc >/dev/null 2>&1 && ! command -v cc >/dev/null 2>&1; then
363
+ MISSING_DEPS+=("build")
364
+ fi
365
+ command -v make >/dev/null 2>&1 || MISSING_DEPS+=("build")
366
+
367
+ can_compile_header '#include <X11/Xlib.h>' || MISSING_DEPS+=("x11")
368
+ can_compile_header '#include <X11/extensions/XTest.h>' || MISSING_DEPS+=("xtst")
369
+ can_compile_header '#include <png.h>' || MISSING_DEPS+=("png")
370
+
371
+ command -v wmctrl >/dev/null 2>&1 || MISSING_DEPS+=("wmctrl")
372
+ command -v yad >/dev/null 2>&1 || MISSING_DEPS+=("yad")
373
+ command -v openssl >/dev/null 2>&1 || MISSING_DEPS+=("openssl")
374
+ }
375
+
376
+ install_packages() {
377
+ local manager="$1"
378
+ shift
379
+ case "$manager" in
380
+ apt)
381
+ sudo_cmd apt-get update
382
+ sudo_cmd apt-get install -y "$@"
383
+ ;;
384
+ dnf)
385
+ sudo_cmd dnf install -y "$@"
386
+ ;;
387
+ yum)
388
+ sudo_cmd yum install -y "$@"
389
+ ;;
390
+ pacman)
391
+ sudo_cmd pacman -Sy --needed --noconfirm "$@"
392
+ ;;
393
+ zypper)
394
+ sudo_cmd zypper --non-interactive install "$@"
395
+ ;;
396
+ *)
397
+ echo "Unsupported package manager." >&2
398
+ return 1
399
+ ;;
400
+ esac
401
+ }
402
+
403
+ install_system_dependencies() {
404
+ check_functional_dependencies
405
+
406
+ if [[ "${#MISSING_DEPS[@]}" -eq 0 ]]; then
407
+ log "System dependencies are already available."
408
+ return
409
+ fi
410
+
411
+ local manager
412
+ manager="$(detect_package_manager)"
413
+
414
+ if [[ -z "$manager" ]]; then
415
+ cat >&2 <<'EOF'
416
+ No supported package manager was detected.
417
+ Install the missing dependencies manually, then rerun the script.
418
+ EOF
419
+ printf 'Missing dependency checks: %s\n' "${MISSING_DEPS[*]}" >&2
420
+ if confirm "Continue without automatic dependency installation?"; then
421
+ return
422
+ fi
423
+ exit 1
424
+ fi
425
+
426
+ MISSING_PACKAGES=()
427
+ local dependency
428
+ for dependency in $(dedupe_words "${MISSING_DEPS[@]}"); do
429
+ append_packages_for_dependency "$manager" "$dependency"
430
+ done
431
+
432
+ mapfile -t MISSING_PACKAGES < <(dedupe_words "${MISSING_PACKAGES[@]}")
433
+
434
+ log "Missing dependency checks: ${MISSING_DEPS[*]}"
435
+ log "Suggested $manager packages: ${MISSING_PACKAGES[*]}"
436
+ if confirm "Install missing system dependencies with $manager?"; then
437
+ if [[ "$manager" == "apt" ]] && contains_word "node" "${MISSING_DEPS[@]}"; then
438
+ install_nodesource_node_apt
439
+ MISSING_PACKAGES=()
440
+ for dependency in $(dedupe_words "${MISSING_DEPS[@]}"); do
441
+ if [[ "$dependency" != "node" && "$dependency" != "npm" ]]; then
442
+ append_packages_for_dependency "$manager" "$dependency"
443
+ fi
444
+ done
445
+ mapfile -t MISSING_PACKAGES < <(dedupe_words "${MISSING_PACKAGES[@]}")
446
+ fi
447
+ if [[ "${#MISSING_PACKAGES[@]}" -gt 0 ]]; then
448
+ install_packages "$manager" "${MISSING_PACKAGES[@]}"
449
+ fi
450
+ check_functional_dependencies
451
+ if [[ "${#MISSING_DEPS[@]}" -ne 0 ]]; then
452
+ echo "Some dependency checks still fail after package installation: ${MISSING_DEPS[*]}" >&2
453
+ exit 1
454
+ fi
455
+ else
456
+ echo "Cannot continue without required system dependencies." >&2
457
+ exit 1
458
+ fi
459
+ }
460
+
461
+ install_npm_package() {
462
+ require_command npm
463
+ local prefix
464
+ prefix="$(npm config get prefix)"
465
+ local npm_install=(npm install -g "$NPM_PACKAGE")
466
+ if [[ -d "$NPM_PACKAGE" ]]; then
467
+ npm_install=(npm install -g --install-links "$NPM_PACKAGE")
468
+ fi
469
+
470
+ log "Installing npm package: $NPM_PACKAGE"
471
+ if [[ -w "$prefix" ]]; then
472
+ "${npm_install[@]}"
473
+ else
474
+ sudo_cmd "${npm_install[@]}"
475
+ fi
476
+ }
477
+
478
+ ensure_remote_mouse_cli() {
479
+ if command -v remote-mouse >/dev/null 2>&1; then
480
+ return
481
+ fi
482
+
483
+ echo "remote-mouse CLI was not found in PATH after npm installation." >&2
484
+ echo "Open a new terminal or check npm global bin path with: npm bin -g" >&2
485
+ exit 1
486
+ }
487
+
488
+ generate_cookie_secret() {
489
+ if command -v openssl >/dev/null 2>&1; then
490
+ openssl rand -hex 32
491
+ else
492
+ date +%s%N
493
+ fi
494
+ }
495
+
496
+ configure_https() {
497
+ if [[ "$HTTPS_CHOICE" == "false" ]]; then
498
+ HTTPS="false"
499
+ return
500
+ fi
501
+
502
+ if [[ "$HTTPS_CHOICE" != "true" ]] && ! confirm "Serve Remote Mouse over HTTPS?"; then
503
+ HTTPS="false"
504
+ return
505
+ fi
506
+
507
+ HTTPS="true"
508
+ local cert_dir="$CONFIG_DIR/certs"
509
+
510
+ if [[ "$GENERATE_CERT_CHOICE" == "true" ]] || { [[ "$GENERATE_CERT_CHOICE" != "false" ]] && confirm "Generate a local self-signed certificate?"; }; then
511
+ require_command openssl
512
+ mkdir -p "$cert_dir"
513
+ SSL_KEY_PATH="$cert_dir/remote-mouse.key"
514
+ SSL_CERT_PATH="$cert_dir/remote-mouse.crt"
515
+ openssl req -x509 -newkey rsa:4096 -sha256 -days 365 -nodes \
516
+ -keyout "$SSL_KEY_PATH" \
517
+ -out "$SSL_CERT_PATH" \
518
+ -subj "/CN=remote-mouse.local" \
519
+ -addext "subjectAltName=DNS:localhost,DNS:remote-mouse.local,IP:127.0.0.1"
520
+ else
521
+ if [[ -z "$SSL_KEY_PATH" ]]; then
522
+ SSL_KEY_PATH="$(prompt_value "Path to the existing PEM private key")"
523
+ fi
524
+ if [[ -z "$SSL_CERT_PATH" ]]; then
525
+ SSL_CERT_PATH="$(prompt_value "Path to the existing PEM certificate")"
526
+ fi
527
+ if [[ ! -f "$SSL_KEY_PATH" ]]; then
528
+ echo "Private key not found: $SSL_KEY_PATH" >&2
529
+ exit 1
530
+ fi
531
+ if [[ ! -f "$SSL_CERT_PATH" ]]; then
532
+ echo "Certificate not found: $SSL_CERT_PATH" >&2
533
+ exit 1
534
+ fi
535
+ fi
536
+ }
537
+
538
+ write_env_file() {
539
+ mkdir -p "$CONFIG_DIR"
540
+ local env_file="$CONFIG_DIR/.env"
541
+ local cookie_secret
542
+ cookie_secret="$(generate_cookie_secret)"
543
+
544
+ if [[ -f "$env_file" ]]; then
545
+ if confirm "Overwrite existing $env_file?"; then
546
+ :
547
+ else
548
+ log "Keeping existing $env_file."
549
+ return
550
+ fi
551
+ fi
552
+
553
+ cat > "$env_file" <<EOF
554
+ PORT=$PORT
555
+ SERVER_HOST=
556
+ CONFIG_DIR=$CONFIG_DIR
557
+ PERSISTENCE_DB_PATH=$CONFIG_DIR/remote-mouse.sqlite3
558
+ ENV_FILE_PATH=$env_file
559
+
560
+ HTTPS=$HTTPS
561
+ SSL_KEY_PATH=$SSL_KEY_PATH
562
+ SSL_CERT_PATH=$SSL_CERT_PATH
563
+
564
+ ENTRY_PATH_ENABLED=true
565
+ ENTRY_PATH_FIXED=
566
+ ENTRY_PATH_TOKEN_LENGTH=24
567
+ ENTRY_PATH_ROTATE_INTERVAL_MIN=60
568
+ ENTRY_PATH_GRACE_MIN=120
569
+
570
+ SESSION_COOKIE_NAME=remote_mouse_session
571
+ SESSION_COOKIE_SECRET=$cookie_secret
572
+ SESSION_COOKIE_MAX_AGE_DAYS=7
573
+ SOCKET_EVENT_MAX_AGE_MS=1200
574
+
575
+ LOG_LEVEL=info
576
+ LOG_FORMAT=json
577
+ ADMIN_ACTIONS_ENABLED=true
578
+ SERVICE_NAME=remote-mouse.service
579
+ SERVICE_RESTART_COMMAND=
580
+ EOF
581
+
582
+ chmod 600 "$env_file"
583
+ log "Wrote $env_file"
584
+ }
585
+
586
+ install_service() {
587
+ if [[ "$INSTALL_SERVICE_CHOICE" == "false" ]]; then
588
+ INSTALL_SERVICE="false"
589
+ return
590
+ fi
591
+
592
+ if [[ "$INSTALL_SERVICE_CHOICE" != "true" ]] && ! confirm "Install the user service?"; then
593
+ INSTALL_SERVICE="false"
594
+ return
595
+ fi
596
+
597
+ INSTALL_SERVICE="true"
598
+ remote-mouse service install
599
+ remote-mouse service restart
600
+ }
601
+
602
+ main() {
603
+ log "Remote Mouse Linux installer"
604
+ log "Package: $NPM_PACKAGE"
605
+ log "Config directory: $CONFIG_DIR"
606
+
607
+ install_system_dependencies
608
+ require_command node
609
+ require_command npm
610
+
611
+ log "Node: $(node --version)"
612
+ log "npm: $(npm --version)"
613
+
614
+ install_npm_package
615
+ ensure_remote_mouse_cli
616
+ configure_https
617
+ write_env_file
618
+ install_service
619
+
620
+ log "Installation complete."
621
+ if [[ "$INSTALL_SERVICE" == "true" ]]; then
622
+ echo "Service installed. Check status with: systemctl --user status remote-mouse.service"
623
+ else
624
+ echo "Start Remote Mouse with: remote-mouse"
625
+ fi
626
+
627
+ if [[ "$HTTPS" == "true" ]]; then
628
+ echo "Browsers will warn about the self-signed certificate until it is trusted locally."
629
+ echo "Use the browser advanced/details option to continue to the site."
630
+ fi
631
+ }
632
+
633
+ main "$@"