lightman-agent 1.0.18 → 1.0.21
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/agent.config.json +22 -23
- package/agent.config.template.json +30 -31
- package/bin/cms-agent.js +269 -248
- package/package.json +1 -1
- package/public/assets/index-CcBNCz6h.css +1 -1
- package/public/assets/index-D9QHMG8k.js +1 -1
- package/public/assets/index-H-8HDl46.js +1 -1
- package/public/assets/index-YodeiCia.css +1 -1
- package/public/assets/index-legacy-DWtNM8y7.js +41 -41
- package/public/assets/polyfills-legacy-DyVYWHbW.js +4 -4
- package/scripts/guardian.ps1 +50 -124
- package/scripts/install-windows.ps1 +60 -116
- package/scripts/lightman-agent.logrotate +12 -12
- package/scripts/lightman-agent.service +38 -38
- package/scripts/reinstall-windows.ps1 +26 -26
- package/scripts/restore-desktop.ps1 +32 -32
- package/scripts/setup.ps1 +17 -22
- package/scripts/sync-display.mjs +20 -20
- package/scripts/uninstall-windows.ps1 +54 -54
- package/src/commands/display.ts +177 -177
- package/src/commands/kiosk.ts +113 -113
- package/src/commands/maintenance.ts +106 -106
- package/src/commands/network.ts +129 -129
- package/src/commands/power.ts +163 -163
- package/src/commands/rpi.ts +45 -45
- package/src/commands/screenshot.ts +166 -166
- package/src/commands/serial.ts +17 -17
- package/src/commands/update.ts +124 -124
- package/src/index.ts +173 -90
- package/src/lib/config.ts +2 -3
- package/src/lib/identity.ts +40 -40
- package/src/lib/logger.ts +137 -137
- package/src/lib/platform.ts +10 -10
- package/src/lib/rpi.ts +180 -180
- package/src/lib/screenMap.ts +135 -0
- package/src/lib/screens.ts +128 -128
- package/src/lib/types.ts +176 -177
- package/src/services/commands.ts +107 -107
- package/src/services/health.ts +161 -161
- package/src/services/localEvents.ts +60 -60
- package/src/services/logForwarder.ts +72 -72
- package/src/services/multiScreenKiosk.ts +116 -83
- package/src/services/oscBridge.ts +186 -186
- package/src/services/powerScheduler.ts +260 -260
- package/src/services/provisioning.ts +120 -122
- package/src/services/serialBridge.ts +230 -230
- package/src/services/serviceLauncher.ts +183 -183
- package/src/services/staticServer.ts +226 -226
- package/src/services/updater.ts +249 -249
- package/src/services/watchdog.ts +310 -310
- package/src/services/websocket.ts +152 -152
- package/tsconfig.json +28 -28
package/scripts/guardian.ps1
CHANGED
|
@@ -2,88 +2,30 @@
|
|
|
2
2
|
# Runs every 5 minutes via Task Scheduler.
|
|
3
3
|
# Restarts the NSSM service if it's down. Checks Chrome kiosk health.
|
|
4
4
|
|
|
5
|
-
$LogDir = "C:\ProgramData\Lightman\logs"
|
|
6
|
-
$LogFile = Join-Path $LogDir "guardian.log"
|
|
7
|
-
$ServiceName = "LightmanAgent"
|
|
8
|
-
$NssmExe = "C:\ProgramData\Lightman\nssm\nssm.exe"
|
|
9
|
-
|
|
10
|
-
$
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
try {
|
|
15
|
-
if (-not (Test-Path $LogDir)) { New-Item -ItemType Directory -Force -Path $LogDir | Out-Null }
|
|
5
|
+
$LogDir = "C:\ProgramData\Lightman\logs"
|
|
6
|
+
$LogFile = Join-Path $LogDir "guardian.log"
|
|
7
|
+
$ServiceName = "LightmanAgent"
|
|
8
|
+
$NssmExe = "C:\ProgramData\Lightman\nssm\nssm.exe"
|
|
9
|
+
|
|
10
|
+
function Write-GuardianLog($msg) {
|
|
11
|
+
$ts = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
|
12
|
+
try {
|
|
13
|
+
if (-not (Test-Path $LogDir)) { New-Item -ItemType Directory -Force -Path $LogDir | Out-Null }
|
|
16
14
|
Add-Content -Path $LogFile -Value "[$ts] $msg" -ErrorAction SilentlyContinue
|
|
17
15
|
if ((Get-Item $LogFile -ErrorAction SilentlyContinue).Length -gt 1MB) {
|
|
18
16
|
$rotated = "$LogFile.old"
|
|
19
17
|
if (Test-Path $rotated) { Remove-Item $rotated -Force }
|
|
20
18
|
Rename-Item $LogFile $rotated -Force
|
|
21
19
|
}
|
|
22
|
-
} catch { }
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
)
|
|
32
|
-
})
|
|
33
|
-
} catch {
|
|
34
|
-
@()
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function Stop-LightmanNodeProcesses {
|
|
39
|
-
$procs = Get-LightmanNodeProcesses
|
|
40
|
-
if (-not $procs -or $procs.Count -eq 0) {
|
|
41
|
-
Write-GuardianLog "No LIGHTMAN-owned node.exe process found"
|
|
42
|
-
return
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
foreach ($proc in $procs) {
|
|
46
|
-
try {
|
|
47
|
-
Stop-Process -Id $proc.ProcessId -Force -ErrorAction Stop
|
|
48
|
-
Write-GuardianLog "Stopped LIGHTMAN node.exe PID $($proc.ProcessId)"
|
|
49
|
-
} catch {
|
|
50
|
-
Write-GuardianLog "Failed to stop LIGHTMAN node.exe PID $($proc.ProcessId): $_"
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function Get-LightmanShellMode {
|
|
56
|
-
$configPath = Join-Path $InstallDir "agent.config.json"
|
|
57
|
-
try {
|
|
58
|
-
if (-not (Test-Path $configPath)) { return $false }
|
|
59
|
-
$config = Get-Content $configPath -Raw | ConvertFrom-Json
|
|
60
|
-
return [bool]($config.kiosk.shellMode)
|
|
61
|
-
} catch {
|
|
62
|
-
return $false
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
function Get-LightmanChromeProcesses {
|
|
67
|
-
try {
|
|
68
|
-
@(Get-CimInstance Win32_Process -Filter "Name = 'chrome.exe'" -ErrorAction SilentlyContinue | Where-Object {
|
|
69
|
-
$_.CommandLine -and (
|
|
70
|
-
$_.CommandLine -like "*$ChromeDataDir*" -or
|
|
71
|
-
$_.CommandLine -like "*chrome-kiosk*"
|
|
72
|
-
)
|
|
73
|
-
})
|
|
74
|
-
} catch {
|
|
75
|
-
@()
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
try {
|
|
80
|
-
$shellMode = Get-LightmanShellMode
|
|
81
|
-
|
|
82
|
-
# 1. Check LIGHTMAN service
|
|
83
|
-
$svc = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
|
|
84
|
-
if (-not $svc) {
|
|
85
|
-
$svc = Get-Service -DisplayName "LIGHTMAN*" -ErrorAction SilentlyContinue | Select-Object -First 1
|
|
86
|
-
}
|
|
20
|
+
} catch { }
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
# 1. Check LIGHTMAN service
|
|
25
|
+
$svc = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
|
|
26
|
+
if (-not $svc) {
|
|
27
|
+
$svc = Get-Service -DisplayName "LIGHTMAN*" -ErrorAction SilentlyContinue | Select-Object -First 1
|
|
28
|
+
}
|
|
87
29
|
|
|
88
30
|
if (-not $svc) {
|
|
89
31
|
Write-GuardianLog "CRITICAL: Service not found!"
|
|
@@ -99,51 +41,35 @@ try {
|
|
|
99
41
|
} else {
|
|
100
42
|
Start-Service -Name $svc.Name -ErrorAction SilentlyContinue
|
|
101
43
|
}
|
|
102
|
-
Start-Sleep -Seconds 5
|
|
103
|
-
$svc.Refresh()
|
|
104
|
-
Write-GuardianLog "After restart: $($svc.Status)"
|
|
105
|
-
}
|
|
106
|
-
elseif ($svc.Status -in @('StartPending', 'StopPending')) {
|
|
107
|
-
Write-GuardianLog "Service
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
if ($
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
Write-GuardianLog "LIGHTMAN kiosk Chrome not running, but shell mode is enabled. Shell will relaunch it."
|
|
135
|
-
} else {
|
|
136
|
-
$vbsPath = Join-Path $InstallDir "launch-kiosk.vbs"
|
|
137
|
-
if (Test-Path $vbsPath) {
|
|
138
|
-
Start-Sleep -Seconds 10
|
|
139
|
-
$chromeRecheck = Get-LightmanChromeProcesses
|
|
140
|
-
if (-not $chromeRecheck) {
|
|
141
|
-
Write-GuardianLog "LIGHTMAN Chrome not running. Launching via VBS..."
|
|
142
|
-
Start-Process "wscript.exe" -ArgumentList """$vbsPath""" -WindowStyle Hidden
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
} catch {
|
|
148
|
-
Write-GuardianLog "Guardian error: $_"
|
|
149
|
-
}
|
|
44
|
+
Start-Sleep -Seconds 5
|
|
45
|
+
$svc.Refresh()
|
|
46
|
+
Write-GuardianLog "After restart: $($svc.Status)"
|
|
47
|
+
}
|
|
48
|
+
elseif ($svc.Status -in @('StartPending', 'StopPending')) {
|
|
49
|
+
Write-GuardianLog "Service stuck in $($svc.Status). Force killing node.exe..."
|
|
50
|
+
Get-Process -Name "node" -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
|
|
51
|
+
Start-Sleep -Seconds 3
|
|
52
|
+
if (Test-Path $NssmExe) { & $NssmExe start $ServiceName 2>$null }
|
|
53
|
+
else { Start-Service -Name $svc.Name -ErrorAction SilentlyContinue }
|
|
54
|
+
Start-Sleep -Seconds 5
|
|
55
|
+
$svc.Refresh()
|
|
56
|
+
Write-GuardianLog "After force restart: $($svc.Status)"
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
# 2. Check Chrome kiosk
|
|
61
|
+
$chrome = Get-Process -Name "chrome" -ErrorAction SilentlyContinue
|
|
62
|
+
if (-not $chrome) {
|
|
63
|
+
$vbsPath = "C:\Program Files\Lightman\Agent\launch-kiosk.vbs"
|
|
64
|
+
if (Test-Path $vbsPath) {
|
|
65
|
+
Start-Sleep -Seconds 10
|
|
66
|
+
$chromeRecheck = Get-Process -Name "chrome" -ErrorAction SilentlyContinue
|
|
67
|
+
if (-not $chromeRecheck) {
|
|
68
|
+
Write-GuardianLog "Chrome not running. Launching via VBS..."
|
|
69
|
+
Start-Process "wscript.exe" -ArgumentList """$vbsPath""" -WindowStyle Hidden
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
} catch {
|
|
74
|
+
Write-GuardianLog "Guardian error: $_"
|
|
75
|
+
}
|
|
@@ -9,14 +9,13 @@
|
|
|
9
9
|
# powershell -ExecutionPolicy Bypass -File install-windows.ps1 -Slug "F-AV01" -Server "http://..." -ShellReplace
|
|
10
10
|
#Requires -RunAsAdministrator
|
|
11
11
|
|
|
12
|
-
param(
|
|
13
|
-
[Parameter(Mandatory=$true)] [string]$Slug,
|
|
14
|
-
[Parameter(Mandatory=$true)] [string]$Server,
|
|
15
|
-
[string]$Timezone = "Asia/Kolkata",
|
|
16
|
-
[
|
|
17
|
-
[
|
|
18
|
-
|
|
19
|
-
)
|
|
12
|
+
param(
|
|
13
|
+
[Parameter(Mandatory=$true)] [string]$Slug,
|
|
14
|
+
[Parameter(Mandatory=$true)] [string]$Server,
|
|
15
|
+
[string]$Timezone = "Asia/Kolkata",
|
|
16
|
+
[string]$Username = "",
|
|
17
|
+
[switch]$ShellReplace = $false
|
|
18
|
+
)
|
|
20
19
|
|
|
21
20
|
$ErrorActionPreference = "Stop"
|
|
22
21
|
|
|
@@ -26,113 +25,47 @@ $ChromeData = "C:\ProgramData\Lightman\chrome-kiosk"
|
|
|
26
25
|
$NssmDir = "C:\ProgramData\Lightman\nssm"
|
|
27
26
|
$NssmExe = "$NssmDir\nssm.exe"
|
|
28
27
|
$ServiceName = "LightmanAgent"
|
|
29
|
-
$GuardianTask = "LIGHTMAN Guardian"
|
|
30
|
-
$KioskTask = "LIGHTMAN Kiosk Browser"
|
|
28
|
+
$GuardianTask = "LIGHTMAN Guardian"
|
|
29
|
+
$KioskTask = "LIGHTMAN Kiosk Browser"
|
|
31
30
|
$AgentTask = "LIGHTMAN Agent"
|
|
32
31
|
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
|
33
32
|
$AgentDir = Split-Path -Parent $ScriptDir
|
|
34
33
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
function Get-LightmanNodeProcesses {
|
|
38
|
-
try {
|
|
39
|
-
@(Get-CimInstance Win32_Process -Filter "Name = 'node.exe'" -ErrorAction SilentlyContinue | Where-Object {
|
|
40
|
-
$_.CommandLine -and (
|
|
41
|
-
$_.CommandLine -like "*$InstallDir*" -or
|
|
42
|
-
$_.CommandLine -like "*$AgentDir*" -or
|
|
43
|
-
$_.CommandLine -match 'dist\\index\.js|src\\index\.ts|cms-agent\.js'
|
|
44
|
-
)
|
|
45
|
-
})
|
|
46
|
-
} catch {
|
|
47
|
-
@()
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function Get-InstallerParentNodePid {
|
|
52
|
-
try {
|
|
53
|
-
$self = Get-CimInstance Win32_Process -Filter "ProcessId=$PID" -ErrorAction SilentlyContinue
|
|
54
|
-
if (-not $self) { return $null }
|
|
55
|
-
|
|
56
|
-
$parentPid = $self.ParentProcessId
|
|
57
|
-
if (-not $parentPid) { return $null }
|
|
58
|
-
|
|
59
|
-
$parent = Get-CimInstance Win32_Process -Filter "ProcessId=$parentPid" -ErrorAction SilentlyContinue
|
|
60
|
-
if ($parent -and $parent.Name -eq "node.exe") {
|
|
61
|
-
return [int]$parent.ProcessId
|
|
62
|
-
}
|
|
63
|
-
} catch {
|
|
64
|
-
return $null
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
return $null
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function Stop-LightmanNodeProcesses {
|
|
34
|
+
function Ensure-PathContains {
|
|
71
35
|
param(
|
|
72
|
-
[
|
|
36
|
+
[Parameter(Mandatory=$true)][ValidateSet('Machine','User')] [string]$Scope,
|
|
37
|
+
[Parameter(Mandatory=$true)] [string]$Entry
|
|
73
38
|
)
|
|
74
|
-
|
|
75
|
-
$
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
Write-Host " Keeping installer parent node.exe PID $($proc.ProcessId)" -ForegroundColor DarkGray
|
|
84
|
-
continue
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
try {
|
|
88
|
-
Stop-Process -Id $proc.ProcessId -Force -ErrorAction Stop
|
|
89
|
-
Write-Host " Stopped LIGHTMAN node.exe PID $($proc.ProcessId)" -ForegroundColor DarkGray
|
|
90
|
-
} catch {
|
|
91
|
-
Write-Host " Failed to stop LIGHTMAN node.exe PID $($proc.ProcessId): $_" -ForegroundColor Yellow
|
|
39
|
+
$current = [System.Environment]::GetEnvironmentVariable("Path", $Scope)
|
|
40
|
+
if (-not $current) { $current = "" }
|
|
41
|
+
$parts = $current -split ';' | Where-Object { $_ -and $_.Trim() -ne "" }
|
|
42
|
+
$normalizedEntry = $Entry.TrimEnd('\')
|
|
43
|
+
$exists = $false
|
|
44
|
+
foreach ($p in $parts) {
|
|
45
|
+
if ($p.TrimEnd('\') -ieq $normalizedEntry) {
|
|
46
|
+
$exists = $true
|
|
47
|
+
break
|
|
92
48
|
}
|
|
93
49
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
@(Get-CimInstance Win32_Process -Filter "Name = 'chrome.exe'" -ErrorAction SilentlyContinue | Where-Object {
|
|
99
|
-
$_.CommandLine -and (
|
|
100
|
-
$_.CommandLine -like "*$ChromeData*" -or
|
|
101
|
-
$_.CommandLine -like "*chrome-kiosk*"
|
|
102
|
-
)
|
|
103
|
-
})
|
|
104
|
-
} catch {
|
|
105
|
-
@()
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
function Stop-LightmanChromeProcesses {
|
|
110
|
-
$procs = Get-LightmanChromeProcesses
|
|
111
|
-
if (-not $procs -or $procs.Count -eq 0) {
|
|
112
|
-
Write-Host " No LIGHTMAN kiosk Chrome processes found" -ForegroundColor DarkGray
|
|
113
|
-
return
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
foreach ($proc in $procs) {
|
|
117
|
-
try {
|
|
118
|
-
Stop-Process -Id $proc.ProcessId -Force -ErrorAction Stop
|
|
119
|
-
Write-Host " Stopped LIGHTMAN Chrome PID $($proc.ProcessId)" -ForegroundColor DarkGray
|
|
120
|
-
} catch {
|
|
121
|
-
Write-Host " Failed to stop LIGHTMAN Chrome PID $($proc.ProcessId): $_" -ForegroundColor Yellow
|
|
122
|
-
}
|
|
50
|
+
if (-not $exists) {
|
|
51
|
+
$newPath = if ($current -and $current.Trim() -ne "") { "$current;$Entry" } else { $Entry }
|
|
52
|
+
[System.Environment]::SetEnvironmentVariable("Path", $newPath, $Scope)
|
|
53
|
+
return $true
|
|
123
54
|
}
|
|
55
|
+
return $false
|
|
124
56
|
}
|
|
125
57
|
|
|
58
|
+
if (-not $Username) { $Username = $env:USERNAME }
|
|
59
|
+
|
|
126
60
|
Write-Host ""
|
|
127
61
|
Write-Host "=============================================" -ForegroundColor Cyan
|
|
128
62
|
Write-Host " LIGHTMAN Agent - Complete Windows Installer" -ForegroundColor Cyan
|
|
129
63
|
Write-Host "=============================================" -ForegroundColor Cyan
|
|
130
|
-
Write-Host " Device slug : $Slug"
|
|
131
|
-
Write-Host " Server URL : $Server"
|
|
132
|
-
Write-Host " Username : $Username"
|
|
133
|
-
Write-Host " Mode : $(if ($ShellReplace) { 'Shell Replacement' } else { 'Standard' })"
|
|
134
|
-
Write-Host "
|
|
135
|
-
Write-Host ""
|
|
64
|
+
Write-Host " Device slug : $Slug"
|
|
65
|
+
Write-Host " Server URL : $Server"
|
|
66
|
+
Write-Host " Username : $Username"
|
|
67
|
+
Write-Host " Mode : $(if ($ShellReplace) { 'Shell Replacement' } else { 'Standard' })"
|
|
68
|
+
Write-Host ""
|
|
136
69
|
|
|
137
70
|
# ============================================================
|
|
138
71
|
# PHASE 0: NUKE EVERYTHING FROM PREVIOUS INSTALLS
|
|
@@ -158,13 +91,12 @@ foreach ($tn in @($AgentTask, $KioskTask, $GuardianTask)) {
|
|
|
158
91
|
$t = Get-ScheduledTask -TaskName $tn -ErrorAction SilentlyContinue
|
|
159
92
|
if ($t) { Stop-ScheduledTask -TaskName $tn -ErrorAction SilentlyContinue; Unregister-ScheduledTask -TaskName $tn -Confirm:$false -ErrorAction SilentlyContinue }
|
|
160
93
|
}
|
|
161
|
-
|
|
162
|
-
# Kill
|
|
163
|
-
Write-Host "[0c]
|
|
164
|
-
|
|
165
|
-
Stop-
|
|
166
|
-
|
|
167
|
-
Start-Sleep -Seconds 2
|
|
94
|
+
|
|
95
|
+
# Kill processes
|
|
96
|
+
Write-Host "[0c] Killing node.exe and Chrome..." -ForegroundColor Yellow
|
|
97
|
+
Get-Process -Name "node" -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
|
|
98
|
+
Get-Process -Name "chrome" -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
|
|
99
|
+
Start-Sleep -Seconds 2
|
|
168
100
|
|
|
169
101
|
# Remove old files (keep NSSM and logs)
|
|
170
102
|
Write-Host "[0d] Removing old agent files..." -ForegroundColor Yellow
|
|
@@ -183,9 +115,9 @@ Write-Host ""
|
|
|
183
115
|
# PART 1: BUILD & INSTALL
|
|
184
116
|
# ============================================================
|
|
185
117
|
|
|
186
|
-
# --- 1. Node.js ---
|
|
187
|
-
Write-Host "[1/19] Checking Node.js..." -ForegroundColor Yellow
|
|
188
|
-
try {
|
|
118
|
+
# --- 1. Node.js ---
|
|
119
|
+
Write-Host "[1/19] Checking Node.js..." -ForegroundColor Yellow
|
|
120
|
+
try {
|
|
189
121
|
$nodeVersion = (node -v) -replace 'v', ''
|
|
190
122
|
if ([int]($nodeVersion.Split('.')[0]) -lt 20) { throw "old" }
|
|
191
123
|
Write-Host " Found Node.js v$nodeVersion"
|
|
@@ -198,7 +130,19 @@ try {
|
|
|
198
130
|
$env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
|
|
199
131
|
if (-not (Get-Command node -ErrorAction SilentlyContinue)) { Write-Host " FATAL: Node.js install failed!" -ForegroundColor Red; exit 1 }
|
|
200
132
|
Write-Host " Node.js installed" -ForegroundColor Green
|
|
201
|
-
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
# Always ensure Node path remains available after kiosk conversion
|
|
136
|
+
$nodePath = (Get-Command node).Source
|
|
137
|
+
$nodeDir = Split-Path -Parent $nodePath
|
|
138
|
+
$addedMachine = Ensure-PathContains -Scope "Machine" -Entry $nodeDir
|
|
139
|
+
$addedUser = Ensure-PathContains -Scope "User" -Entry $nodeDir
|
|
140
|
+
$env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
|
|
141
|
+
if ($addedMachine -or $addedUser) {
|
|
142
|
+
Write-Host " Ensured Node.js path in PATH: $nodeDir" -ForegroundColor Green
|
|
143
|
+
} else {
|
|
144
|
+
Write-Host " Node.js path already present in PATH"
|
|
145
|
+
}
|
|
202
146
|
|
|
203
147
|
# --- 2. Build ---
|
|
204
148
|
Write-Host "[2/19] Building agent..." -ForegroundColor Yellow
|
|
@@ -234,11 +178,11 @@ Pop-Location
|
|
|
234
178
|
|
|
235
179
|
# --- 6. Generate config ---
|
|
236
180
|
Write-Host "[6/19] Generating config..." -ForegroundColor Yellow
|
|
237
|
-
if ($ShellReplace) {
|
|
238
|
-
& "$ScriptDir\setup.ps1" -Slug $Slug -Server $Server -Timezone $Timezone -
|
|
239
|
-
} else {
|
|
240
|
-
& "$ScriptDir\setup.ps1" -Slug $Slug -Server $Server -Timezone $Timezone -
|
|
241
|
-
}
|
|
181
|
+
if ($ShellReplace) {
|
|
182
|
+
& "$ScriptDir\setup.ps1" -Slug $Slug -Server $Server -Timezone $Timezone -InstallDir $InstallDir -ShellMode
|
|
183
|
+
} else {
|
|
184
|
+
& "$ScriptDir\setup.ps1" -Slug $Slug -Server $Server -Timezone $Timezone -InstallDir $InstallDir
|
|
185
|
+
}
|
|
242
186
|
|
|
243
187
|
# --- 7. Fix BOM ---
|
|
244
188
|
Write-Host "[7/19] Fixing config encoding..." -ForegroundColor Yellow
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
/var/log/lightman/*.log {
|
|
2
|
-
daily
|
|
3
|
-
rotate 7
|
|
4
|
-
compress
|
|
5
|
-
delaycompress
|
|
6
|
-
missingok
|
|
7
|
-
notifempty
|
|
8
|
-
create 0640 lightman lightman
|
|
9
|
-
postrotate
|
|
10
|
-
systemctl reload lightman-agent > /dev/null 2>&1 || true
|
|
11
|
-
endscript
|
|
12
|
-
}
|
|
1
|
+
/var/log/lightman/*.log {
|
|
2
|
+
daily
|
|
3
|
+
rotate 7
|
|
4
|
+
compress
|
|
5
|
+
delaycompress
|
|
6
|
+
missingok
|
|
7
|
+
notifempty
|
|
8
|
+
create 0640 lightman lightman
|
|
9
|
+
postrotate
|
|
10
|
+
systemctl reload lightman-agent > /dev/null 2>&1 || true
|
|
11
|
+
endscript
|
|
12
|
+
}
|
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
[Unit]
|
|
2
|
-
Description=LIGHTMAN Agent - Museum Display Management
|
|
3
|
-
Documentation=https://github.com/sagrkv/lightman-app01
|
|
4
|
-
After=network-online.target
|
|
5
|
-
Wants=network-online.target
|
|
6
|
-
|
|
7
|
-
[Service]
|
|
8
|
-
Type=simple
|
|
9
|
-
User=lightman
|
|
10
|
-
Group=lightman
|
|
11
|
-
WorkingDirectory=/opt/lightman/agent
|
|
12
|
-
ExecStart=/usr/bin/node dist/index.js
|
|
13
|
-
Restart=always
|
|
14
|
-
RestartSec=10
|
|
15
|
-
StartLimitIntervalSec=300
|
|
16
|
-
StartLimitBurst=5
|
|
17
|
-
|
|
18
|
-
# Environment
|
|
19
|
-
Environment=NODE_ENV=production
|
|
20
|
-
EnvironmentFile=-/opt/lightman/agent/.env
|
|
21
|
-
|
|
22
|
-
# Security hardening
|
|
23
|
-
ProtectSystem=strict
|
|
24
|
-
ReadWritePaths=/opt/lightman/agent /var/log/lightman /tmp
|
|
25
|
-
PrivateTmp=true
|
|
26
|
-
NoNewPrivileges=true
|
|
27
|
-
ProtectHome=true
|
|
28
|
-
ProtectKernelTunables=true
|
|
29
|
-
ProtectControlGroups=true
|
|
30
|
-
RestrictSUIDSGID=true
|
|
31
|
-
|
|
32
|
-
# Logging
|
|
33
|
-
StandardOutput=journal
|
|
34
|
-
StandardError=journal
|
|
35
|
-
SyslogIdentifier=lightman-agent
|
|
36
|
-
|
|
37
|
-
[Install]
|
|
38
|
-
WantedBy=multi-user.target
|
|
1
|
+
[Unit]
|
|
2
|
+
Description=LIGHTMAN Agent - Museum Display Management
|
|
3
|
+
Documentation=https://github.com/sagrkv/lightman-app01
|
|
4
|
+
After=network-online.target
|
|
5
|
+
Wants=network-online.target
|
|
6
|
+
|
|
7
|
+
[Service]
|
|
8
|
+
Type=simple
|
|
9
|
+
User=lightman
|
|
10
|
+
Group=lightman
|
|
11
|
+
WorkingDirectory=/opt/lightman/agent
|
|
12
|
+
ExecStart=/usr/bin/node dist/index.js
|
|
13
|
+
Restart=always
|
|
14
|
+
RestartSec=10
|
|
15
|
+
StartLimitIntervalSec=300
|
|
16
|
+
StartLimitBurst=5
|
|
17
|
+
|
|
18
|
+
# Environment
|
|
19
|
+
Environment=NODE_ENV=production
|
|
20
|
+
EnvironmentFile=-/opt/lightman/agent/.env
|
|
21
|
+
|
|
22
|
+
# Security hardening
|
|
23
|
+
ProtectSystem=strict
|
|
24
|
+
ReadWritePaths=/opt/lightman/agent /var/log/lightman /tmp
|
|
25
|
+
PrivateTmp=true
|
|
26
|
+
NoNewPrivileges=true
|
|
27
|
+
ProtectHome=true
|
|
28
|
+
ProtectKernelTunables=true
|
|
29
|
+
ProtectControlGroups=true
|
|
30
|
+
RestrictSUIDSGID=true
|
|
31
|
+
|
|
32
|
+
# Logging
|
|
33
|
+
StandardOutput=journal
|
|
34
|
+
StandardError=journal
|
|
35
|
+
SyslogIdentifier=lightman-agent
|
|
36
|
+
|
|
37
|
+
[Install]
|
|
38
|
+
WantedBy=multi-user.target
|
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
#Requires -RunAsAdministrator
|
|
2
|
-
<#
|
|
3
|
-
.SYNOPSIS
|
|
4
|
-
LIGHTMAN Agent - Reinstall (install-windows.ps1 handles cleanup automatically)
|
|
5
|
-
.EXAMPLE
|
|
6
|
-
powershell -ExecutionPolicy Bypass -File scripts\reinstall-windows.ps1 -Slug "F-AV04" -Server "http://192.168.10.100:3401" -ShellReplace
|
|
7
|
-
#>
|
|
8
|
-
param(
|
|
9
|
-
[Parameter(Mandatory=$true)] [string]$Slug,
|
|
10
|
-
[Parameter(Mandatory=$true)] [string]$Server,
|
|
11
|
-
[switch]$ShellReplace = $false,
|
|
12
|
-
[string]$Timezone = "Asia/Kolkata",
|
|
13
|
-
[switch]$NoReboot = $false
|
|
14
|
-
)
|
|
15
|
-
|
|
16
|
-
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
|
17
|
-
|
|
18
|
-
$args = @("-ExecutionPolicy", "Bypass", "-File", "$ScriptDir\install-windows.ps1", "-Slug", $Slug, "-Server", $Server, "-Timezone", $Timezone)
|
|
19
|
-
if ($ShellReplace) { $args += "-ShellReplace" }
|
|
20
|
-
& powershell @args
|
|
21
|
-
|
|
22
|
-
if (-not $NoReboot) {
|
|
23
|
-
Write-Host " Rebooting in 10 seconds... (Ctrl+C to cancel)" -ForegroundColor Yellow
|
|
24
|
-
Start-Sleep -Seconds 10
|
|
25
|
-
Restart-Computer -Force
|
|
26
|
-
}
|
|
1
|
+
#Requires -RunAsAdministrator
|
|
2
|
+
<#
|
|
3
|
+
.SYNOPSIS
|
|
4
|
+
LIGHTMAN Agent - Reinstall (install-windows.ps1 handles cleanup automatically)
|
|
5
|
+
.EXAMPLE
|
|
6
|
+
powershell -ExecutionPolicy Bypass -File scripts\reinstall-windows.ps1 -Slug "F-AV04" -Server "http://192.168.10.100:3401" -ShellReplace
|
|
7
|
+
#>
|
|
8
|
+
param(
|
|
9
|
+
[Parameter(Mandatory=$true)] [string]$Slug,
|
|
10
|
+
[Parameter(Mandatory=$true)] [string]$Server,
|
|
11
|
+
[switch]$ShellReplace = $false,
|
|
12
|
+
[string]$Timezone = "Asia/Kolkata",
|
|
13
|
+
[switch]$NoReboot = $false
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
|
17
|
+
|
|
18
|
+
$args = @("-ExecutionPolicy", "Bypass", "-File", "$ScriptDir\install-windows.ps1", "-Slug", $Slug, "-Server", $Server, "-Timezone", $Timezone)
|
|
19
|
+
if ($ShellReplace) { $args += "-ShellReplace" }
|
|
20
|
+
& powershell @args
|
|
21
|
+
|
|
22
|
+
if (-not $NoReboot) {
|
|
23
|
+
Write-Host " Rebooting in 10 seconds... (Ctrl+C to cancel)" -ForegroundColor Yellow
|
|
24
|
+
Start-Sleep -Seconds 10
|
|
25
|
+
Restart-Computer -Force
|
|
26
|
+
}
|
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
# LIGHTMAN - Restore Windows Desktop
|
|
2
|
-
# Reverses shell replacement: sets explorer.exe back as the Windows shell.
|
|
3
|
-
# Run via RDP with admin account, or from Safe Mode:
|
|
4
|
-
# powershell -ExecutionPolicy Bypass -File restore-desktop.ps1
|
|
5
|
-
#Requires -RunAsAdministrator
|
|
6
|
-
|
|
7
|
-
$ErrorActionPreference = "Stop"
|
|
8
|
-
|
|
9
|
-
Write-Host ""
|
|
10
|
-
Write-Host "=== LIGHTMAN - Restore Windows Desktop ===" -ForegroundColor Cyan
|
|
11
|
-
Write-Host ""
|
|
12
|
-
|
|
13
|
-
# Restore HKLM shell
|
|
14
|
-
$HKLMPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
|
|
15
|
-
$original = (Get-ItemProperty -Path $HKLMPath -Name "Shell_Original" -ErrorAction SilentlyContinue).Shell_Original
|
|
16
|
-
if ($original) {
|
|
17
|
-
Set-ItemProperty -Path $HKLMPath -Name "Shell" -Value $original
|
|
18
|
-
Write-Host " HKLM shell restored to: $original" -ForegroundColor Green
|
|
19
|
-
} else {
|
|
20
|
-
Set-ItemProperty -Path $HKLMPath -Name "Shell" -Value "explorer.exe"
|
|
21
|
-
Write-Host " HKLM shell restored to: explorer.exe" -ForegroundColor Green
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
# Remove HKCU shell override
|
|
25
|
-
$HKCUPath = "HKCU:\Software\Microsoft\Windows NT\CurrentVersion\Winlogon"
|
|
26
|
-
Remove-ItemProperty -Path $HKCUPath -Name "Shell" -ErrorAction SilentlyContinue
|
|
27
|
-
Write-Host " HKCU shell override removed" -ForegroundColor Green
|
|
28
|
-
|
|
29
|
-
Write-Host ""
|
|
30
|
-
Write-Host " Desktop will be restored on next reboot." -ForegroundColor Yellow
|
|
31
|
-
Write-Host " Run: Restart-Computer" -ForegroundColor Yellow
|
|
32
|
-
Write-Host ""
|
|
1
|
+
# LIGHTMAN - Restore Windows Desktop
|
|
2
|
+
# Reverses shell replacement: sets explorer.exe back as the Windows shell.
|
|
3
|
+
# Run via RDP with admin account, or from Safe Mode:
|
|
4
|
+
# powershell -ExecutionPolicy Bypass -File restore-desktop.ps1
|
|
5
|
+
#Requires -RunAsAdministrator
|
|
6
|
+
|
|
7
|
+
$ErrorActionPreference = "Stop"
|
|
8
|
+
|
|
9
|
+
Write-Host ""
|
|
10
|
+
Write-Host "=== LIGHTMAN - Restore Windows Desktop ===" -ForegroundColor Cyan
|
|
11
|
+
Write-Host ""
|
|
12
|
+
|
|
13
|
+
# Restore HKLM shell
|
|
14
|
+
$HKLMPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
|
|
15
|
+
$original = (Get-ItemProperty -Path $HKLMPath -Name "Shell_Original" -ErrorAction SilentlyContinue).Shell_Original
|
|
16
|
+
if ($original) {
|
|
17
|
+
Set-ItemProperty -Path $HKLMPath -Name "Shell" -Value $original
|
|
18
|
+
Write-Host " HKLM shell restored to: $original" -ForegroundColor Green
|
|
19
|
+
} else {
|
|
20
|
+
Set-ItemProperty -Path $HKLMPath -Name "Shell" -Value "explorer.exe"
|
|
21
|
+
Write-Host " HKLM shell restored to: explorer.exe" -ForegroundColor Green
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
# Remove HKCU shell override
|
|
25
|
+
$HKCUPath = "HKCU:\Software\Microsoft\Windows NT\CurrentVersion\Winlogon"
|
|
26
|
+
Remove-ItemProperty -Path $HKCUPath -Name "Shell" -ErrorAction SilentlyContinue
|
|
27
|
+
Write-Host " HKCU shell override removed" -ForegroundColor Green
|
|
28
|
+
|
|
29
|
+
Write-Host ""
|
|
30
|
+
Write-Host " Desktop will be restored on next reboot." -ForegroundColor Yellow
|
|
31
|
+
Write-Host " Run: Restart-Computer" -ForegroundColor Yellow
|
|
32
|
+
Write-Host ""
|