@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,95 @@
1
+ import {
2
+ getEntrypoint,
3
+ getPlatformKind,
4
+ isDaemonProcess
5
+ } from "../../services/application/utils.js";
6
+ import {
7
+ execFileAsync,
8
+ spawnDetached
9
+ } from "../../utils/process.js";
10
+
11
+ function buildWindowsTaskCommand() {
12
+ const nodePath = process.execPath.replace(/'/g, "''");
13
+ const entrypoint = getEntrypoint().replace(/'/g, "''");
14
+ return `powershell -NoProfile -WindowStyle Hidden -Command "$env:REMOTE_MOUSE_DAEMON='1'; & '${nodePath}' '${entrypoint}'"`;
15
+ }
16
+
17
+ export async function installWindowsDaemon(serviceName) {
18
+ const result = await execFileAsync('schtasks', [
19
+ '/Create',
20
+ '/F',
21
+ '/SC', 'ONLOGON',
22
+ '/TN', serviceName,
23
+ '/TR', buildWindowsTaskCommand(),
24
+ ], {timeout: 30000});
25
+
26
+ if (!result.ok) {
27
+ return {ok: false, message: result.stderr || `Impossible d'installer la tache ${serviceName}.`};
28
+ }
29
+
30
+ const run = await execFileAsync('schtasks', ['/Run', '/TN', serviceName], {timeout: 10000});
31
+ if (!run.ok) {
32
+ return {ok: false, message: run.stderr || `Tache ${serviceName} creee mais non lancee.`};
33
+ }
34
+
35
+ return {
36
+ ok: true,
37
+ message: `Tache ${serviceName} installee et lancee.`,
38
+ };
39
+ }
40
+
41
+ export async function disableWindowsDaemon(serviceName) {
42
+ await execFileAsync('schtasks', ['/End', '/TN', serviceName], {timeout: 10000});
43
+ const result = await execFileAsync('schtasks', ['/Change', '/TN', serviceName, '/Disable'], {timeout: 30000});
44
+ if (!result.ok) {
45
+ return {ok: false, message: result.stderr || `Impossible de desactiver la tache ${serviceName}.`};
46
+ }
47
+
48
+ return {
49
+ ok: true,
50
+ message: `Tache ${serviceName} desactivee.`,
51
+ };
52
+ }
53
+
54
+ export async function uninstallWindowsDaemon(serviceName) {
55
+ await execFileAsync('schtasks', ['/End', '/TN', serviceName], {timeout: 10000});
56
+ const result = await execFileAsync('schtasks', ['/Delete', '/TN', serviceName, '/F'], {timeout: 30000});
57
+ if (!result.ok) {
58
+ return {ok: false, message: result.stderr || `Impossible de supprimer la tache ${serviceName}.`};
59
+ }
60
+
61
+ return {
62
+ ok: true,
63
+ message: `Tache ${serviceName} desinstallee.`,
64
+ };
65
+ }
66
+
67
+ export async function restartWindowsDaemon(serviceName) {
68
+ const command = `Start-Sleep -Milliseconds 800; schtasks /End /TN "${serviceName}" 2>$null; schtasks /Run /TN "${serviceName}"`;
69
+ const spawned = await spawnDetached('powershell', ['-NoProfile', '-Command', command]);
70
+
71
+ if (!spawned) {
72
+ return {
73
+ ok: false,
74
+ message: 'Impossible de lancer la tache de redemarrage.',
75
+ details: {message: 'spawn schtasks failed'},
76
+ };
77
+ }
78
+
79
+ return {
80
+ ok: true,
81
+ message: `Redemarrage demande pour ${serviceName}.`,
82
+ };
83
+ }
84
+
85
+ export async function getWindowsDaemonInfo(serviceName) {
86
+ const result = await execFileAsync('schtasks', ['/Query', '/TN', serviceName], {timeout: 5000});
87
+
88
+ return {
89
+ serviceName,
90
+ platform: process.platform,
91
+ platformKind: getPlatformKind(),
92
+ runningAsDaemon: isDaemonProcess(),
93
+ installed: result.ok,
94
+ };
95
+ }
@@ -0,0 +1,9 @@
1
+ import {spawnDetached} from '../../utils/process.js';
2
+
3
+ export async function openWin32Url(url) {
4
+ const safeUrl = String(url || '').trim();
5
+ if (!safeUrl) {
6
+ return false;
7
+ }
8
+ return spawnDetached('cmd', ['/c', 'start', '', safeUrl]);
9
+ }
@@ -0,0 +1,10 @@
1
+ import {execFileAsync} from '../../utils/process.js';
2
+ import {buildForegroundWindowPowerShell} from './powershell.js';
3
+
4
+ export async function toggleWin32ActiveWindow() {
5
+ return (await execFileAsync('powershell', ['-NoProfile', '-Command', buildForegroundWindowPowerShell('toggle')])).ok;
6
+ }
7
+
8
+ export async function closeWin32ActiveWindow() {
9
+ return (await execFileAsync('powershell', ['-NoProfile', '-Command', buildForegroundWindowPowerShell('close')])).ok;
10
+ }
@@ -0,0 +1,29 @@
1
+ import { REMOTE_EVENT_ADMIN_PREFIX } from '../../../utils/remoteCommands.js';
2
+
3
+ export function createAdminEventGuardMiddleware({
4
+ isAdminActionsEnabled,
5
+ client,
6
+ log,
7
+ respondAdminAction,
8
+ }) {
9
+ return function adminEventGuard(packet, next) {
10
+ const eventName = String(packet?.[0] || '');
11
+ if (!eventName.startsWith(REMOTE_EVENT_ADMIN_PREFIX)) {
12
+ next();
13
+ return;
14
+ }
15
+
16
+ if (isAdminActionsEnabled) {
17
+ next();
18
+ return;
19
+ }
20
+
21
+ const action = eventName.replace(REMOTE_EVENT_ADMIN_PREFIX, '');
22
+ log.warn({ client, action }, 'Action admin refusée: ADMIN_ACTIONS_ENABLED=false');
23
+ respondAdminAction(action, {
24
+ ok: false,
25
+ message: 'Actions admin desactivees.',
26
+ });
27
+ next(new Error('admin_actions_disabled'));
28
+ };
29
+ }
@@ -0,0 +1,39 @@
1
+ import {createLogger} from '../../application/logger.js';
2
+ import {
3
+ PUBSUB_EVENT_ADMIN_COMPLETED,
4
+ PUBSUB_SERVICE_ADMIN_FORCE_UPDATE_CHECK
5
+ } from "../../services/pubsub/serviceEventConstants.js";
6
+
7
+ let log;
8
+ function getModuleLog() {
9
+ log ??= createLogger('admin:force-update-check');
10
+ return log;
11
+ }
12
+
13
+ export function createForceUpdateCheckAction(services) {
14
+ const log = getModuleLog();
15
+ const {
16
+ getEvents,
17
+ getUpdateManager
18
+ } = services;
19
+ return async function forceUpdateCheck({clientId} = {}) {
20
+ log.info('Début force update check');
21
+ const result = await getUpdateManager().check();
22
+
23
+ if (result && result.checked && result.hasUpdate) {
24
+ log.info('Force update check: mise à jour détectée');
25
+ getEvents().publishEvent(PUBSUB_SERVICE_ADMIN_FORCE_UPDATE_CHECK, PUBSUB_EVENT_ADMIN_COMPLETED, {
26
+ clientId,
27
+ hasUpdate: true,
28
+ });
29
+ return {ok: true, message: 'Mise a jour detectee.'};
30
+ }
31
+
32
+ log.info('Force update check: aucune mise à jour détectée');
33
+ getEvents().publishEvent(PUBSUB_SERVICE_ADMIN_FORCE_UPDATE_CHECK, PUBSUB_EVENT_ADMIN_COMPLETED, {
34
+ clientId,
35
+ hasUpdate: false,
36
+ });
37
+ return {ok: true, message: 'Aucune mise a jour detectee.'};
38
+ };
39
+ }
@@ -0,0 +1,64 @@
1
+ import {createLogger} from '../../application/logger.js';
2
+ import {
3
+ PUBSUB_EVENT_ADMIN_COMPLETED,
4
+ PUBSUB_EVENT_ADMIN_FAILED,
5
+ PUBSUB_EVENT_ADMIN_REJECTED_NO_COMMAND,
6
+ PUBSUB_EVENT_ADMIN_STARTED,
7
+ PUBSUB_SERVICE_ADMIN_INSTALL_UPDATE,
8
+ } from '../../services/pubsub/serviceEventConstants.js';
9
+
10
+ let log;
11
+ function getModuleLog() {
12
+ log ??= createLogger('admin:install-update');
13
+ return log;
14
+ }
15
+
16
+ export function createInstallUpdateAction(services) {
17
+ const log = getModuleLog();
18
+ return async function installUpdate({ clientId } = {}) {
19
+ const events = services.getEvents();
20
+ const updateManager = services.getUpdateManager();
21
+ const restartService = services.getRemotes().adminActions.restartService;
22
+ log.info('Début install update');
23
+
24
+ events.publishEvent(PUBSUB_SERVICE_ADMIN_INSTALL_UPDATE, PUBSUB_EVENT_ADMIN_STARTED, {
25
+ clientId,
26
+ });
27
+
28
+ const result = await updateManager.update();
29
+ if (result?.ok) {
30
+ events.publishEvent(PUBSUB_SERVICE_ADMIN_INSTALL_UPDATE, PUBSUB_EVENT_ADMIN_COMPLETED, {
31
+ clientId,
32
+ });
33
+ const restartResult = await restartService({ clientId });
34
+ if (!restartResult?.ok) {
35
+ return {
36
+ ok: false,
37
+ message: restartResult?.message || 'Installation terminee, mais le redemarrage a echoue.',
38
+ };
39
+ }
40
+ return {
41
+ ok: true,
42
+ message: result.message || 'Installation terminee. Redemarrage demande.',
43
+ };
44
+ }
45
+
46
+ if (result?.status === 'no-command') {
47
+ log.warn('Install update impossible: aucune commande disponible');
48
+ events.publishEvent(PUBSUB_SERVICE_ADMIN_INSTALL_UPDATE, PUBSUB_EVENT_ADMIN_REJECTED_NO_COMMAND, {
49
+ clientId,
50
+ });
51
+ return {
52
+ ok: false,
53
+ message: result.message || 'Aucune commande update disponible.',
54
+ };
55
+ }
56
+
57
+ events.publishEvent(PUBSUB_SERVICE_ADMIN_INSTALL_UPDATE, PUBSUB_EVENT_ADMIN_FAILED, {
58
+ clientId,
59
+ details: result?.details,
60
+ });
61
+
62
+ return { ok: false, message: result?.message || 'Echec installation: Erreur inconnue' };
63
+ };
64
+ }
@@ -0,0 +1,63 @@
1
+ import {createLogger} from '../../application/logger.js';
2
+ import {
3
+ NOTIFIER_TARGET_CLIENT,
4
+ NOTIFIER_TARGET_SERVER,
5
+ } from '../../services/notifier/createNotifierComposite.js';
6
+ import {
7
+ PUBSUB_EVENT_ADMIN_CLIENT_OPENED,
8
+ PUBSUB_EVENT_ADMIN_SERVER_OPEN_FAILED,
9
+ PUBSUB_EVENT_ADMIN_SERVER_OPENED,
10
+ PUBSUB_SERVICE_ADMIN_OPEN_QR_BROWSER,
11
+ } from '../../services/pubsub/serviceEventConstants.js';
12
+
13
+ let log;
14
+ function getModuleLog() {
15
+ log ??= createLogger('admin:open-qr-browser');
16
+ return log;
17
+ }
18
+
19
+ function publishClientEvent(events, type, clientId) {
20
+ if (!clientId) {
21
+ return;
22
+ }
23
+ events.publishEvent(PUBSUB_SERVICE_ADMIN_OPEN_QR_BROWSER, type, {
24
+ clientId,
25
+ });
26
+ }
27
+
28
+ export function createOpenQrBrowserAction(services, options = {}) {
29
+ const log = getModuleLog();
30
+ const browser = options.browser;
31
+ const target = options.target || NOTIFIER_TARGET_SERVER;
32
+
33
+ return async function openQrBrowser({ clientId } = {}) {
34
+ const events = services.getEvents();
35
+ const isClientTarget = target === NOTIFIER_TARGET_CLIENT;
36
+ const clientQrUrl = '/qr';
37
+
38
+ if (isClientTarget) {
39
+ log.info({ clientId, clientQrUrl }, 'Ouverture de la page QR sur le client');
40
+ events.publishEvent(PUBSUB_SERVICE_ADMIN_OPEN_QR_BROWSER, PUBSUB_EVENT_ADMIN_CLIENT_OPENED, {
41
+ clientId,
42
+ });
43
+ return {
44
+ ok: true,
45
+ message: 'Page QR ouverte sur le client.',
46
+ openUrl: clientQrUrl,
47
+ };
48
+ }
49
+
50
+ const config = services.getSystemConfig();
51
+ const localQrUrl = `${config.protocol}://127.0.0.1:${config.port}/qr`;
52
+ log.info({ localQrUrl }, 'Ouverture de la page QR sur le serveur');
53
+
54
+ const ok = await browser.openUrlOnHost(localQrUrl);
55
+ if (!ok) {
56
+ publishClientEvent(events, PUBSUB_EVENT_ADMIN_SERVER_OPEN_FAILED, clientId);
57
+ return {ok: false, message: 'Impossible d’ouvrir /qr sur le serveur.'};
58
+ }
59
+
60
+ publishClientEvent(events, PUBSUB_EVENT_ADMIN_SERVER_OPENED, clientId);
61
+ return {ok: true, message: 'Page QR ouverte sur le serveur.'};
62
+ };
63
+ }
@@ -0,0 +1,58 @@
1
+ import {createLogger} from '../../application/logger.js';
2
+ import {
3
+ NOTIFIER_TARGET_CLIENT,
4
+ NOTIFIER_TARGET_SERVER,
5
+ } from '../../services/notifier/createNotifierComposite.js';
6
+ import {
7
+ PUBSUB_EVENT_ADMIN_CLIENT_OPENED,
8
+ PUBSUB_EVENT_ADMIN_SERVER_OPEN_FAILED,
9
+ PUBSUB_EVENT_ADMIN_SERVER_OPENED,
10
+ PUBSUB_SERVICE_ADMIN_OPEN_SERVER_INFO_BROWSER,
11
+ } from '../../services/pubsub/serviceEventConstants.js';
12
+
13
+ let log;
14
+ function getModuleLog() {
15
+ log ??= createLogger('admin:open-server-info-browser');
16
+ return log;
17
+ }
18
+
19
+ export function createOpenServerInfoBrowserAction(services, options = {}) {
20
+ const log = getModuleLog();
21
+ const browser = options.browser;
22
+ const target = options.target || NOTIFIER_TARGET_SERVER;
23
+
24
+ return async function openServerInfoBrowser({ clientId } = {}) {
25
+ const events = services.getEvents();
26
+ const isClientTarget = target === NOTIFIER_TARGET_CLIENT;
27
+ const clientInfoUrl = '/ui/admin/server-info';
28
+
29
+ if (isClientTarget) {
30
+ log.info({ clientId, clientInfoUrl }, 'Ouverture de la page server info sur le client');
31
+ events.publishEvent(PUBSUB_SERVICE_ADMIN_OPEN_SERVER_INFO_BROWSER, PUBSUB_EVENT_ADMIN_CLIENT_OPENED, {
32
+ clientId,
33
+ });
34
+ return {
35
+ ok: true,
36
+ message: 'Page server info ouverte sur le client.',
37
+ openUrl: clientInfoUrl,
38
+ };
39
+ }
40
+
41
+ const config = services.getSystemConfig();
42
+ const localInfoUrl = `${config.protocol}://127.0.0.1:${config.port}/ui/admin/server-info`;
43
+ log.info({ localInfoUrl }, 'Ouverture de la page server info sur le serveur');
44
+
45
+ const ok = await browser.openUrlOnHost(localInfoUrl);
46
+ if (!ok) {
47
+ events.publishEvent(PUBSUB_SERVICE_ADMIN_OPEN_SERVER_INFO_BROWSER, PUBSUB_EVENT_ADMIN_SERVER_OPEN_FAILED, {
48
+ clientId,
49
+ });
50
+ return {ok: false, message: "Impossible d'ouvrir server info sur le serveur."};
51
+ }
52
+
53
+ events.publishEvent(PUBSUB_SERVICE_ADMIN_OPEN_SERVER_INFO_BROWSER, PUBSUB_EVENT_ADMIN_SERVER_OPENED, {
54
+ clientId,
55
+ });
56
+ return {ok: true, message: 'Page server info ouverte sur le serveur.'};
57
+ };
58
+ }
@@ -0,0 +1,20 @@
1
+ import {
2
+ PUBSUB_EVENT_ADMIN_STARTED,
3
+ PUBSUB_SERVICE_ADMIN_RESTART_SERVICE,
4
+ } from '../../services/pubsub/serviceEventConstants.js';
5
+
6
+ export function createRestartServiceAction(services) {
7
+ return async function restartService({ clientId } = {}) {
8
+ const events = services.getEvents();
9
+ const config = services.getSystemConfig();
10
+ events.publishEvent(PUBSUB_SERVICE_ADMIN_RESTART_SERVICE, PUBSUB_EVENT_ADMIN_STARTED, {
11
+ clientId,
12
+ serviceName: config.serviceName,
13
+ });
14
+
15
+ return services.getApplicationDaemonService().restart({
16
+ cause: 'user',
17
+ source: 'admin-remote',
18
+ });
19
+ };
20
+ }
@@ -0,0 +1,43 @@
1
+ import {
2
+ PUBSUB_EVENT_ADMIN_REJECTED_DISABLED,
3
+ PUBSUB_EVENT_ADMIN_ROTATED,
4
+ PUBSUB_EVENT_ADMIN_UNCHANGED,
5
+ PUBSUB_SERVICE_ADMIN_ROTATE_ENTRY_TOKEN,
6
+ } from '../../services/pubsub/serviceEventConstants.js';
7
+ import {createLogger} from '../../application/logger.js';
8
+
9
+ let log;
10
+ function getModuleLog() {
11
+ log ??= createLogger('admin:rotate-entry-token');
12
+ return log;
13
+ }
14
+
15
+ export function createRotateEntryTokenAction(services) {
16
+ const log = getModuleLog();
17
+ return async function rotateEntryToken({ clientId } = {}) {
18
+ const events = services.getEvents();
19
+ const tokenManager = services.getTokenManager();
20
+ const before = String(tokenManager.getToken());
21
+ const after = String(tokenManager.createToken());
22
+
23
+ if (!after) {
24
+ events.publishEvent(PUBSUB_SERVICE_ADMIN_ROTATE_ENTRY_TOKEN, PUBSUB_EVENT_ADMIN_REJECTED_DISABLED, {
25
+ clientId,
26
+ });
27
+ return { ok: false, message: 'Entry path desactive.' };
28
+ }
29
+
30
+ if (after === before) {
31
+ events.publishEvent(PUBSUB_SERVICE_ADMIN_ROTATE_ENTRY_TOKEN, PUBSUB_EVENT_ADMIN_UNCHANGED, {
32
+ clientId,
33
+ });
34
+ return { ok: false, message: 'Token non change (mode fixe ou rotation indisponible).' };
35
+ }
36
+
37
+ log.info('Token d entree force en rotation');
38
+ events.publishEvent(PUBSUB_SERVICE_ADMIN_ROTATE_ENTRY_TOKEN, PUBSUB_EVENT_ADMIN_ROTATED, {
39
+ clientId,
40
+ });
41
+ return { ok: true, message: 'Token d entree rotation forcee.' };
42
+ };
43
+ }
@@ -0,0 +1,38 @@
1
+ import {createLogger} from '../../application/logger.js';
2
+ import {
3
+ PUBSUB_EVENT_ADMIN_TOGGLED,
4
+ PUBSUB_SERVICE_ADMIN_TOGGLE_QR_OVERLAY,
5
+ } from '../../services/pubsub/serviceEventConstants.js';
6
+
7
+ let log;
8
+ function getModuleLog() {
9
+ log ??= createLogger('admin:toggle-qr-overlay');
10
+ return log;
11
+ }
12
+
13
+ export function createToggleQrOverlayAction(services) {
14
+ const log = getModuleLog();
15
+ const getEvents = services.getEvents;
16
+ const getQrOverlay = services.getQrOverlay;
17
+
18
+ return async function toggleQrOverlay({ clientId } = {}) {
19
+ const events = getEvents();
20
+ const qrOverlay = getQrOverlay();
21
+ if (!qrOverlay || typeof qrOverlay.toggle !== 'function') {
22
+ return { ok: false, message: 'QR overlay indisponible.' };
23
+ }
24
+
25
+ const visible = await qrOverlay.toggle();
26
+ const message = visible
27
+ ? 'QR overlay affiche.'
28
+ : 'QR overlay masque.';
29
+
30
+ log.info({ visible }, 'Toggle QR overlay');
31
+ events.publishEvent(PUBSUB_SERVICE_ADMIN_TOGGLE_QR_OVERLAY, PUBSUB_EVENT_ADMIN_TOGGLED, {
32
+ clientId,
33
+ visible,
34
+ });
35
+
36
+ return { ok: true, message };
37
+ };
38
+ }
@@ -0,0 +1,32 @@
1
+ import {createForceUpdateCheckAction} from './createForceUpdateCheckAction.js';
2
+ import {createInstallUpdateAction} from './createInstallUpdateAction.js';
3
+ import {createRestartServiceAction} from './createRestartServiceAction.js';
4
+ import {createOpenQrBrowserAction} from './createOpenQrBrowserAction.js';
5
+ import {createOpenServerInfoBrowserAction} from './createOpenServerInfoBrowserAction.js';
6
+ import {createRotateEntryTokenAction} from './createRotateEntryTokenAction.js';
7
+ import {createToggleQrOverlayAction} from './createToggleQrOverlayAction.js';
8
+ import {notifyIfRestarted} from './notifyIfRestarted.js';
9
+
10
+ export {notifyIfRestarted};
11
+
12
+ import {
13
+ NOTIFIER_TARGET_CLIENT,
14
+ NOTIFIER_TARGET_SERVER
15
+ } from '../../services/notifier/createNotifierComposite.js';
16
+ import {createBrowser} from '../browser/index.js';
17
+
18
+ export function createAdminActions(services) {
19
+ const browser = createBrowser(services.getOs());
20
+
21
+ return {
22
+ forceUpdateCheck: createForceUpdateCheckAction(services),
23
+ installUpdate: createInstallUpdateAction(services),
24
+ restartService: createRestartServiceAction(services),
25
+ openQrBrowserServer: createOpenQrBrowserAction(services, {browser, target: NOTIFIER_TARGET_SERVER}),
26
+ openQrBrowserClient: createOpenQrBrowserAction(services, {browser, target: NOTIFIER_TARGET_CLIENT}),
27
+ openServerInfoBrowserServer: createOpenServerInfoBrowserAction(services, {browser, target: NOTIFIER_TARGET_SERVER}),
28
+ openServerInfoBrowserClient: createOpenServerInfoBrowserAction(services, {browser, target: NOTIFIER_TARGET_CLIENT}),
29
+ rotateEntryToken: createRotateEntryTokenAction(services),
30
+ toggleQrOverlay: createToggleQrOverlayAction(services),
31
+ };
32
+ }
@@ -0,0 +1,102 @@
1
+ import fs from 'node:fs';
2
+ import os from 'node:os';
3
+ import path from 'node:path';
4
+ import {isDaemonProcess} from '../../services/application/utils.js';
5
+ import {
6
+ PUBSUB_EVENT_ADMIN_RESTART_DETECTED,
7
+ PUBSUB_SERVICE_ADMIN_RESTART_SERVICE,
8
+ } from '../../services/pubsub/serviceEventConstants.js';
9
+
10
+ const RESTART_MARKER_FILE = path.join(os.tmpdir(), 'remote-mouse-restarted.marker');
11
+ const RECENT_RESTART_WINDOW_MS = 60_000;
12
+ let lastRestartDetectedAt = 0;
13
+
14
+ export function writeRestartMarker(payload = {}) {
15
+ try {
16
+ fs.writeFileSync(RESTART_MARKER_FILE, JSON.stringify({
17
+ requestedAt: Date.now(),
18
+ ...payload,
19
+ }), 'utf8');
20
+ } catch (_error) {
21
+ // best effort
22
+ }
23
+ }
24
+
25
+ function readAndClearRestartMarker() {
26
+ try {
27
+ if (!fs.existsSync(RESTART_MARKER_FILE)) {
28
+ return null;
29
+ }
30
+ const raw = fs.readFileSync(RESTART_MARKER_FILE, 'utf8');
31
+ fs.unlinkSync(RESTART_MARKER_FILE);
32
+ return JSON.parse(raw || '{}');
33
+ } catch (_error) {
34
+ return null;
35
+ }
36
+ }
37
+
38
+ function getDaemonStartupCause() {
39
+ return os.uptime() <= 300 ? 'reboot' : 'unexpected';
40
+ }
41
+
42
+ export function notifyIfRestarted(services) {
43
+ const restartLogDao = services.getPersistence().restartLogDao;
44
+ const marker = readAndClearRestartMarker();
45
+ const startupAt = Date.now();
46
+ const startupCause = isDaemonProcess() ? getDaemonStartupCause() : 'user';
47
+
48
+ const lastEvent = restartLogDao?.getLastLifecycleEvent?.();
49
+ if (lastEvent?.eventType === 'start') {
50
+ restartLogDao.createLifecycleEvent({
51
+ eventAt: startupAt,
52
+ eventType: 'stop',
53
+ cause: startupCause,
54
+ source: 'inferred-stop',
55
+ status: 'completed',
56
+ details: {
57
+ inferred: true,
58
+ previousStartAt: lastEvent.requestedAt,
59
+ systemUptimeSec: Math.floor(os.uptime()),
60
+ },
61
+ });
62
+ }
63
+
64
+ if (marker) {
65
+ lastRestartDetectedAt = startupAt;
66
+ restartLogDao?.updateRestartStatus(marker.restartId, {
67
+ detectedAt: lastRestartDetectedAt,
68
+ status: 'completed',
69
+ details: {
70
+ restartDetectedAt: lastRestartDetectedAt,
71
+ },
72
+ });
73
+ restartLogDao?.createLifecycleEvent({
74
+ eventAt: startupAt,
75
+ eventType: 'start',
76
+ cause: String(marker.cause || 'user'),
77
+ source: 'restart-marker',
78
+ status: 'completed',
79
+ details: {
80
+ restartId: marker.restartId ?? null,
81
+ },
82
+ });
83
+ services.getEvents().publishEvent(PUBSUB_SERVICE_ADMIN_RESTART_SERVICE, PUBSUB_EVENT_ADMIN_RESTART_DETECTED, {});
84
+ return;
85
+ }
86
+
87
+ restartLogDao?.createLifecycleEvent({
88
+ eventAt: startupAt,
89
+ eventType: 'start',
90
+ cause: startupCause,
91
+ source: isDaemonProcess() ? 'daemon-startup' : 'manual-startup',
92
+ status: 'completed',
93
+ details: {
94
+ restartDetectedAt: startupAt,
95
+ systemUptimeSec: Math.floor(os.uptime()),
96
+ },
97
+ });
98
+ }
99
+
100
+ export function hasRecentRestart() {
101
+ return lastRestartDetectedAt > 0 && (Date.now() - lastRestartDetectedAt) <= RECENT_RESTART_WINDOW_MS;
102
+ }