depository-deploy 1.2.4 → 1.3.5

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.
@@ -93,6 +93,10 @@ $OPENAI_API_KEY = if ($conf.ContainsKey("OPENAI_API_KEY")) { $conf["OPENAI_API_K
93
93
 
94
94
  $WINDOWS_AUTH_ENABLED = if ($conf.ContainsKey("WINDOWS_AUTH_ENABLED")) { $conf["WINDOWS_AUTH_ENABLED"].ToLower() } else { "false" }
95
95
  $WEBSERVER_TYPE = if ($conf.ContainsKey("WEBSERVER_TYPE")) { $conf["WEBSERVER_TYPE"].ToLower() } else { "iis" }
96
+ $IIS_SITE_NAME = if ($conf.ContainsKey("IIS_SITE_NAME")) { $conf["IIS_SITE_NAME"] } else { "Depository" }
97
+ $IIS_VIRTUAL_PATH = if ($conf.ContainsKey("IIS_VIRTUAL_PATH")) { $conf["IIS_VIRTUAL_PATH"].Trim('/').Trim() } else { "" }
98
+ $IIS_REMOTE_HOST = if ($conf.ContainsKey("IIS_REMOTE_HOST")) { $conf["IIS_REMOTE_HOST"].Trim() } else { "" }
99
+ $IIS_BACKEND_HOST = if ($conf.ContainsKey("IIS_BACKEND_HOST")) { $conf["IIS_BACKEND_HOST"].Trim() } else { "localhost" }
96
100
  $AD_EMAIL_DOMAIN = if ($conf.ContainsKey("AD_EMAIL_DOMAIN")) { $conf["AD_EMAIL_DOMAIN"] } else { "company.local" }
97
101
  $AD_GROUP_ADMIN = if ($conf.ContainsKey("AD_GROUP_ADMIN")) { $conf["AD_GROUP_ADMIN"] } else { "Depository-Admins" }
98
102
  $AD_GROUP_ORG_ADMIN = if ($conf.ContainsKey("AD_GROUP_ORG_ADMIN")) { $conf["AD_GROUP_ORG_ADMIN"] } else { "Depository-OrgAdmins" }
@@ -144,6 +148,7 @@ function Apply-Template {
144
148
  -replace '\{\{GATHERER_EXE\}\}', $GATHERER_EXE.Replace("\","\\") `
145
149
  -replace '\{\{OPENAI_API_KEY\}\}', $OPENAI_API_KEY `
146
150
  -replace '\{\{WINDOWS_AUTH_ENABLED\}\}', $WINDOWS_AUTH_ENABLED `
151
+ -replace '\{\{IIS_BACKEND_HOST\}\}', $IIS_BACKEND_HOST `
147
152
  -replace '\{\{AD_EMAIL_DOMAIN\}\}', $AD_EMAIL_DOMAIN `
148
153
  -replace '\{\{AD_GROUP_ADMIN\}\}', $AD_GROUP_ADMIN `
149
154
  -replace '\{\{AD_GROUP_ORG_ADMIN\}\}', $AD_GROUP_ORG_ADMIN `
@@ -482,47 +487,112 @@ if ($WEBSERVER_TYPE -eq "iis") {
482
487
  Write-OK "web.config deployed to $INSTALL_DIR\ui\"
483
488
  }
484
489
 
485
- # Application Pool
486
490
  Import-Module WebAdministration -ErrorAction SilentlyContinue
487
491
  $poolName = "Depository"
488
- if (Test-Path "IIS:\AppPools\$poolName") {
489
- Remove-WebAppPool -Name $poolName -ErrorAction SilentlyContinue
490
- }
491
- New-WebAppPool -Name $poolName | Out-Null
492
- Set-ItemProperty "IIS:\AppPools\$poolName" -Name managedRuntimeVersion -Value ""
493
- Set-ItemProperty "IIS:\AppPools\$poolName" -Name startMode -Value "AlwaysRunning"
494
- Set-ItemProperty "IIS:\AppPools\$poolName" -Name processModel.idleTimeout -Value ([TimeSpan]::Zero)
495
- Write-OK "App pool '$poolName' created"
496
-
497
- # Website
498
- $siteName = "Depository"
499
- if (Get-Website -Name $siteName -ErrorAction SilentlyContinue) {
500
- Remove-Website -Name $siteName
501
- }
502
- # Remove anything else using UI_PORT on binding *
503
- Get-Website | Where-Object {
504
- $_.Bindings.Collection | Where-Object { $_.bindingInformation -like "*:${UI_PORT}:*" }
505
- } | ForEach-Object { Remove-Website -Name $_.Name -ErrorAction SilentlyContinue }
506
-
507
- New-Website -Name $siteName `
508
- -Port ([int]$UI_PORT) `
509
- -PhysicalPath "$INSTALL_DIR\ui" `
510
- -ApplicationPool $poolName `
511
- -Force | Out-Null
512
- Write-OK "IIS website '$siteName' on port $UI_PORT -> $INSTALL_DIR\ui"
513
-
514
- # Ensure Default Website doesn't conflict on port 80
515
- if ($UI_PORT -eq "80") {
516
- $defSite = Get-Website -Name "Default Web Site" -ErrorAction SilentlyContinue
517
- if ($defSite -and $defSite.State -eq "Started") {
518
- Stop-Website -Name "Default Web Site" -ErrorAction SilentlyContinue
519
- Write-Warn "Stopped 'Default Web Site' (was using port 80)"
492
+
493
+ # ---- Helper: configure IIS site/virtual-app (used locally and remotely) ----
494
+ $ConfigureIIS = {
495
+ param($PoolName, $SiteName, $VirtualPath, $UiPath, $UiPort)
496
+ Import-Module WebAdministration -ErrorAction SilentlyContinue
497
+
498
+ # App pool
499
+ if (Test-Path "IIS:\AppPools\$PoolName") {
500
+ Remove-WebAppPool -Name $PoolName -ErrorAction SilentlyContinue
501
+ }
502
+ New-WebAppPool -Name $PoolName | Out-Null
503
+ Set-ItemProperty "IIS:\AppPools\$PoolName" -Name managedRuntimeVersion -Value ""
504
+ Set-ItemProperty "IIS:\AppPools\$PoolName" -Name startMode -Value "AlwaysRunning"
505
+ Set-ItemProperty "IIS:\AppPools\$PoolName" -Name processModel.idleTimeout -Value ([TimeSpan]::Zero)
506
+
507
+ if ($VirtualPath -eq "") {
508
+ # Root site mode
509
+ if (Get-Website -Name $SiteName -ErrorAction SilentlyContinue) {
510
+ Remove-Website -Name $SiteName
511
+ }
512
+ Get-Website | Where-Object {
513
+ $_.Bindings.Collection | Where-Object { $_.bindingInformation -like "*:${UiPort}:*" }
514
+ } | ForEach-Object { Remove-Website -Name $_.Name -ErrorAction SilentlyContinue }
515
+ New-Website -Name $SiteName `
516
+ -Port ([int]$UiPort) `
517
+ -PhysicalPath $UiPath `
518
+ -ApplicationPool $PoolName `
519
+ -Force | Out-Null
520
+ if ($UiPort -eq "80" -and $SiteName -ne "Default Web Site") {
521
+ $defSite = Get-Website -Name "Default Web Site" -ErrorAction SilentlyContinue
522
+ if ($defSite -and $defSite.State -eq "Started") {
523
+ Stop-Website -Name "Default Web Site" -ErrorAction SilentlyContinue
524
+ }
525
+ }
526
+ } else {
527
+ # Virtual application mode
528
+ $parentSite = $SiteName
529
+ if (-not (Get-Website -Name $parentSite -ErrorAction SilentlyContinue)) {
530
+ New-Website -Name $parentSite `
531
+ -Port ([int]$UiPort) `
532
+ -PhysicalPath (Split-Path -Parent $UiPath) `
533
+ -ApplicationPool $PoolName `
534
+ -Force | Out-Null
535
+ }
536
+ if (Get-WebApplication -Site $parentSite -Name $VirtualPath -ErrorAction SilentlyContinue) {
537
+ Remove-WebApplication -Site $parentSite -Name $VirtualPath -ErrorAction SilentlyContinue
538
+ }
539
+ New-WebApplication -Name $VirtualPath `
540
+ -Site $parentSite `
541
+ -PhysicalPath $UiPath `
542
+ -ApplicationPool $PoolName | Out-Null
520
543
  }
544
+
545
+ & iisreset /restart 2>&1 | Out-Null
521
546
  }
522
547
 
523
- # Restart IIS to apply all changes
524
- & iisreset /restart 2>&1 | Out-Null
525
- Write-OK "IIS restarted"
548
+ # Website / Virtual Application
549
+ if ($IIS_REMOTE_HOST -ne "") {
550
+ # ── Remote IIS mode: copy files via UNC + configure via PowerShell Remoting ──
551
+ Write-Info "Deploying UI to remote IIS server: $IIS_REMOTE_HOST ..."
552
+
553
+ # Build UNC path from local INSTALL_DIR (e.g. C:\Depository -> \\host\c$\Depository)
554
+ $localInstall = $INSTALL_DIR.Replace("/", "\").TrimStart("\")
555
+ $driveLetter = $localInstall[0]
556
+ $pathRemainder = $localInstall.Substring(2) # e.g. \Depository
557
+ $uncUi = "\\$IIS_REMOTE_HOST\${driveLetter}`$$pathRemainder\ui"
558
+
559
+ Write-Info "Copying UI files to $uncUi ..."
560
+ try {
561
+ if (-not (Test-Path $uncUi)) { New-Item -ItemType Directory -Path $uncUi -Force | Out-Null }
562
+ Copy-Item "$INSTALL_DIR\ui\*" $uncUi -Recurse -Force
563
+ Write-OK "UI files copied to $uncUi"
564
+ } catch {
565
+ Write-Fail "Failed to copy UI files to remote host. Ensure admin share access (\\$IIS_REMOTE_HOST\$driveLetter`$) is available and the account has write permissions."
566
+ }
567
+
568
+ # Configure IIS remotely via PowerShell Remoting
569
+ Write-Info "Configuring IIS on $IIS_REMOTE_HOST via PowerShell Remoting..."
570
+ try {
571
+ $remoteUiPath = "$localInstall\ui"
572
+ Invoke-Command -ComputerName $IIS_REMOTE_HOST -ScriptBlock $ConfigureIIS `
573
+ -ArgumentList $poolName, $IIS_SITE_NAME, $IIS_VIRTUAL_PATH, $remoteUiPath, $UI_PORT -ErrorAction Stop
574
+ Write-OK "IIS configured on $IIS_REMOTE_HOST"
575
+ } catch {
576
+ Write-Warn "PowerShell Remoting to '$IIS_REMOTE_HOST' failed: $_"
577
+ Write-Warn "Ensure WinRM is enabled on the remote host: winrm quickconfig"
578
+ Write-Warn "Then re-run the IIS configuration manually on $IIS_REMOTE_HOST"
579
+ }
580
+
581
+ if ($IIS_VIRTUAL_PATH -eq "") {
582
+ Write-OK "Remote IIS website '$IIS_SITE_NAME' on port $UI_PORT -> $remoteUiPath"
583
+ } else {
584
+ Write-OK "Remote IIS virtual application '/$IIS_VIRTUAL_PATH' under '$IIS_SITE_NAME' -> $remoteUiPath"
585
+ }
586
+ } else {
587
+ # ── Local IIS mode ──────────────────────────────────────────
588
+ & $ConfigureIIS $poolName $IIS_SITE_NAME $IIS_VIRTUAL_PATH "$INSTALL_DIR\ui" $UI_PORT
589
+ if ($IIS_VIRTUAL_PATH -eq "") {
590
+ Write-OK "IIS website '$IIS_SITE_NAME' on port $UI_PORT -> $INSTALL_DIR\ui"
591
+ } else {
592
+ Write-OK "IIS virtual application '/$IIS_VIRTUAL_PATH' under '$IIS_SITE_NAME' -> $INSTALL_DIR\ui"
593
+ }
594
+ Write-OK "IIS restarted"
595
+ }
526
596
 
527
597
  } elseif ($WEBSERVER_TYPE -eq "nginx") {
528
598
  Write-Info "nginx selected -- skipping IIS setup."
@@ -24,7 +24,7 @@
24
24
  <add input="{CACHE_URL}" pattern="^(.*)$" />
25
25
  </conditions>
26
26
  <action type="Rewrite"
27
- url="http://localhost:{{API_PORT}}/api/{R:1}"
27
+ url="http://{{IIS_BACKEND_HOST}}:{{API_PORT}}/api/{R:1}"
28
28
  appendQueryString="true" />
29
29
  </rule>
30
30
 
@@ -32,7 +32,7 @@
32
32
  <rule name="Depository Auth" stopProcessing="true">
33
33
  <match url="^auth/(.*)" />
34
34
  <action type="Rewrite"
35
- url="http://localhost:{{AUTH_PORT}}/auth/{R:1}"
35
+ url="http://{{IIS_BACKEND_HOST}}:{{AUTH_PORT}}/auth/{R:1}"
36
36
  appendQueryString="true" />
37
37
  </rule>
38
38
 
@@ -40,7 +40,7 @@
40
40
  <rule name="Depository Hubs" stopProcessing="true">
41
41
  <match url="^hubs/(.*)" />
42
42
  <action type="Rewrite"
43
- url="http://localhost:{{API_PORT}}/hubs/{R:1}"
43
+ url="http://{{IIS_BACKEND_HOST}}:{{API_PORT}}/hubs/{R:1}"
44
44
  appendQueryString="true" />
45
45
  </rule>
46
46
 
@@ -51,7 +51,7 @@
51
51
  <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
52
52
  <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
53
53
  </conditions>
54
- <action type="Rewrite" url="/index.html" />
54
+ <action type="Rewrite" url="index.html" />
55
55
  </rule>
56
56
 
57
57
  </rules>
@@ -99,17 +99,5 @@
99
99
  <!-- ── Error handling ────────────────────────────────────── -->
100
100
  <httpErrors existingResponse="PassThrough" />
101
101
 
102
- <!-- ── Authentication — override server-level defaults ──── -->
103
- <!-- Explicitly allow anonymous and disable all challenge-based -->
104
- <!-- auth so IIS never pops a browser credential dialog. -->
105
- <security>
106
- <authentication>
107
- <anonymousAuthentication enabled="true" />
108
- <windowsAuthentication enabled="false" />
109
- <basicAuthentication enabled="false" />
110
- <digestAuthentication enabled="false" />
111
- </authentication>
112
- </security>
113
-
114
102
  </system.webServer>
115
103
  </configuration>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "depository-deploy",
3
- "version": "1.2.4",
3
+ "version": "1.3.5",
4
4
  "description": "Depository document management system – deployment wizard and installers",
5
5
  "license": "UNLICENSED",
6
6
  "publishConfig": {
@@ -25,9 +25,9 @@
25
25
  "scripts/publish.mjs"
26
26
  ],
27
27
  "optionalDependencies": {
28
- "depository-deploy-linux": "1.2.4",
29
- "depository-deploy-macos": "1.2.4",
30
- "depository-deploy-windows": "1.2.4"
28
+ "depository-deploy-linux": "1.3.5",
29
+ "depository-deploy-macos": "1.3.5",
30
+ "depository-deploy-windows": "1.3.5"
31
31
  },
32
32
  "scripts": {
33
33
  "start": "node wizard-server.mjs"
package/wizard-server.mjs CHANGED
@@ -347,13 +347,14 @@ const server = createServer((req, res) => {
347
347
  for (const sub of job.subs) sendSSE(sub, 'line', { text });
348
348
  }
349
349
 
350
- const cmd = ['npm', ['install', '-g', `${PKG_NAME}@latest`]];
350
+ const npmBin = os.platform() === 'win32' ? 'npm.cmd' : 'npm';
351
+ const npmArgs = ['install', '-g', `${PKG_NAME}@latest`];
351
352
 
352
353
  pushLine(`Updating ${PKG_NAME} → latest...`);
353
- pushLine(`Running: ${cmd[0]} ${cmd[1].join(' ')}`);
354
+ pushLine(`Running: npm ${npmArgs.join(' ')}`);
354
355
 
355
- const proc = spawn(cmd[0], cmd[1], {
356
- cwd: __dirname, shell: true, stdio: 'pipe',
356
+ const proc = spawn(npmBin, npmArgs, {
357
+ cwd: __dirname, shell: false, stdio: 'pipe',
357
358
  });
358
359
 
359
360
  proc.stdout.on('data', d => d.toString().split(/\r?\n/).forEach(pushLine));
package/wizard.html CHANGED
@@ -819,6 +819,32 @@ input.err { border-color: var(--err) !important; box-shadow: 0 0 0 3px rgba(220,
819
819
  </label>
820
820
  </div>
821
821
  <div class="field-note" id="wsNote" style="margin-top:-8px;margin-bottom:12px"></div>
822
+ <div id="iisFields" style="display:none">
823
+ <div class="field-row">
824
+ <div class="field">
825
+ <label data-i18n="iis_site_name_lbl">IIS Site Name</label>
826
+ <input type="text" id="iis_site_name" value="Depository">
827
+ <div class="field-note" data-i18n="iis_site_name_note">Name of the IIS website to create. When using a virtual path, enter the name of the parent IIS site (e.g. Default Web Site).</div>
828
+ </div>
829
+ <div class="field">
830
+ <label data-i18n="iis_virtual_path_lbl">Virtual Path</label>
831
+ <input type="text" id="iis_virtual_path" placeholder="e.g. depository" value="">
832
+ <div class="field-note" data-i18n="iis_virtual_path_note">Leave empty to host at the site root, or enter a sub-path (e.g. depository) to install as a virtual application under the parent site.</div>
833
+ </div>
834
+ </div>
835
+ <div class="field-row">
836
+ <div class="field">
837
+ <label data-i18n="iis_remote_host_lbl">Remote IIS Host</label>
838
+ <input type="text" id="iis_remote_host" placeholder="e.g. webserver.company.local" value="" oninput="toggleIisBackendHost()">
839
+ <div class="field-note" data-i18n="iis_remote_host_note">Leave empty to configure IIS on this machine. Enter a hostname or IP to deploy the UI to a remote IIS server via PowerShell Remoting (WinRM).</div>
840
+ </div>
841
+ <div class="field" id="iisBackendHostField" style="display:none">
842
+ <label data-i18n="iis_backend_host_lbl">Backend Services Host</label>
843
+ <input type="text" id="iis_backend_host" placeholder="e.g. 10.0.0.10" value="">
844
+ <div class="field-note" data-i18n="iis_backend_host_note">Hostname or IP of the server running the API/Auth services, as reachable from the remote IIS server. Used in the IIS reverse-proxy rules.</div>
845
+ </div>
846
+ </div>
847
+ </div>
822
848
  </div>
823
849
 
824
850
  <!-- Step 4: Directories -->
@@ -1080,6 +1106,14 @@ const T = {
1080
1106
  webserver_sect:"Web Server",
1081
1107
  webserver_note_iis:"IIS will serve the React UI and proxy /api/, /auth/, and /hubs/ to the backend services. Requires URL Rewrite + ARR modules.",
1082
1108
  webserver_note_nginx:"nginx will serve the React UI and proxy backend routes. Recommended for Linux; also works on Windows.",
1109
+ iis_site_name_lbl:"IIS Site Name",
1110
+ iis_site_name_note:"Name of the IIS website to create. When using a virtual path, enter the name of the parent IIS site (e.g. Default Web Site).",
1111
+ iis_virtual_path_lbl:"Virtual Path",
1112
+ iis_virtual_path_note:"Leave empty to host at the site root, or enter a sub-path (e.g. depository) to install as a virtual application under the parent site.",
1113
+ iis_remote_host_lbl:"Remote IIS Host",
1114
+ iis_remote_host_note:"Leave empty to configure IIS on this machine. Enter a hostname or IP to deploy the UI to a remote IIS server via PowerShell Remoting (WinRM).",
1115
+ iis_backend_host_lbl:"Backend Services Host",
1116
+ iis_backend_host_note:"Hostname or IP of the server running the API/Auth services, as reachable from the remote IIS server. Used in the IIS reverse-proxy rules.",
1083
1117
  generate:"Generate", back_btn:"‹ Back", next_btn:"Next ›",
1084
1118
  review_db:"Database", review_db_user:"DB Username", review_auth_db:"Auth Database",
1085
1119
  review_auth_user:"Auth DB User", review_install:"Install Directory",
@@ -1193,6 +1227,14 @@ const T = {
1193
1227
  webserver_sect:"Web Sunucusu",
1194
1228
  webserver_note_iis:"IIS, React arayüzünü sunar ve /api/, /auth/, /hubs/ yollarını arka uç servislerine yönlendirir. URL Rewrite + ARR modülleri gereklidir.",
1195
1229
  webserver_note_nginx:"nginx, React arayüzünü sunar ve arka uç yollarını yönlendirir. Linux için önerilir; Windows'ta da çalışır.",
1230
+ iis_site_name_lbl:"IIS Site Adı",
1231
+ iis_site_name_note:"Oluşturulacak IIS web sitesinin adı. Sanal yol kullanılıyorsa üst IIS sitesinin adını girin (ör. Default Web Site).",
1232
+ iis_virtual_path_lbl:"Sanal Yol",
1233
+ iis_virtual_path_note:"Site kökünde barındırmak için boş bırakın. Bir alt yol girerek (ör. depository) üst sitenin altında sanal uygulama olarak kurabilirsiniz.",
1234
+ iis_remote_host_lbl:"Uzak IIS Sunucusu",
1235
+ iis_remote_host_note:"Bu makineye IIS kurmak için boş bırakın. Uzak bir IIS sunucusuna PowerShell Remoting (WinRM) ile dağıtmak için sunucu adı veya IP girin.",
1236
+ iis_backend_host_lbl:"Arka Uç Servis Sunucusu",
1237
+ iis_backend_host_note:"API/Auth servislerini çalıştıran sunucunun uzak IIS sunucusundan erişilebilir adı veya IP'si. IIS ters proxy kurallarında kullanılır.",
1196
1238
  generate:"Oluştur", back_btn:"‹ Geri", next_btn:"İleri ›",
1197
1239
  review_db:"Veritabanı", review_db_user:"VT Kullanıcısı", review_auth_db:"Kimlik VT",
1198
1240
  review_auth_user:"Kimlik VT Kullanıcısı", review_install:"Kurulum Dizini",
@@ -1306,6 +1348,14 @@ const T = {
1306
1348
  webserver_sect:"Serveur web",
1307
1349
  webserver_note_iis:"IIS servira l'interface React et proxifiera /api/, /auth/ et /hubs/ vers les services backend. Nécessite les modules URL Rewrite + ARR.",
1308
1350
  webserver_note_nginx:"nginx servira l'interface React et proxifiera les routes backend. Recommandé pour Linux ; fonctionne aussi sous Windows.",
1351
+ iis_site_name_lbl:"Nom du site IIS",
1352
+ iis_site_name_note:"Nom du site IIS à créer. Si vous utilisez un chemin virtuel, saisissez le nom du site IIS parent (ex. Default Web Site).",
1353
+ iis_virtual_path_lbl:"Chemin virtuel",
1354
+ iis_virtual_path_note:"Laissez vide pour héberger à la racine du site, ou saisissez un sous-chemin (ex. depository) pour installer en tant qu'application virtuelle sous le site parent.",
1355
+ iis_remote_host_lbl:"Hôte IIS distant",
1356
+ iis_remote_host_note:"Laissez vide pour configurer IIS sur cette machine. Saisissez un nom d'hôte ou une IP pour déployer l'interface sur un serveur IIS distant via PowerShell Remoting (WinRM).",
1357
+ iis_backend_host_lbl:"Hôte des services backend",
1358
+ iis_backend_host_note:"Nom d'hôte ou IP du serveur exécutant les services API/Auth, tel qu'accessible depuis le serveur IIS distant. Utilisé dans les règles de proxy inverse IIS.",
1309
1359
  generate:"Générer", back_btn:"‹ Retour", next_btn:"Suivant ›",
1310
1360
  review_db:"Base de données", review_db_user:"Utilisateur BDD", review_auth_db:"BDD Auth",
1311
1361
  review_auth_user:"Utilisateur BDD Auth", review_install:"Répertoire d'installation",
@@ -1419,6 +1469,14 @@ const T = {
1419
1469
  webserver_sect:"Webserver",
1420
1470
  webserver_note_iis:"IIS stellt die React-Oberfläche bereit und leitet /api/, /auth/ und /hubs/ an die Backend-Dienste weiter. Benötigt URL Rewrite + ARR-Module.",
1421
1471
  webserver_note_nginx:"nginx stellt die React-Oberfläche bereit und leitet Backend-Routen weiter. Empfohlen für Linux; funktioniert auch unter Windows.",
1472
+ iis_site_name_lbl:"IIS-Websitename",
1473
+ iis_site_name_note:"Name der zu erstellenden IIS-Website. Bei Verwendung eines virtuellen Pfads geben Sie den Namen der übergeordneten IIS-Site ein (z. B. Default Web Site).",
1474
+ iis_virtual_path_lbl:"Virtueller Pfad",
1475
+ iis_virtual_path_note:"Leer lassen, um am Website-Stamm zu hosten, oder einen Unterpfad eingeben (z. B. depository), um als virtuelle Anwendung unter der übergeordneten Site zu installieren.",
1476
+ iis_remote_host_lbl:"Entfernter IIS-Server",
1477
+ iis_remote_host_note:"Leer lassen, um IIS auf diesem Computer zu konfigurieren. Hostname oder IP eingeben, um die Oberfläche via PowerShell Remoting (WinRM) auf einem entfernten IIS-Server bereitzustellen.",
1478
+ iis_backend_host_lbl:"Backend-Dienste-Server",
1479
+ iis_backend_host_note:"Hostname oder IP des Servers mit den API/Auth-Diensten, erreichbar vom entfernten IIS-Server. Wird in den IIS-Reverse-Proxy-Regeln verwendet.",
1422
1480
  generate:"Generieren", back_btn:"‹ Zurück", next_btn:"Weiter ›",
1423
1481
  review_db:"Datenbank", review_db_user:"DB-Benutzer", review_auth_db:"Auth-DB",
1424
1482
  review_auth_user:"Auth-DB-Benutzer", review_install:"Installationsverzeichnis",
@@ -1532,6 +1590,14 @@ const T = {
1532
1590
  webserver_sect:"Servidor web",
1533
1591
  webserver_note_iis:"IIS servirá la interfaz React y enrutará /api/, /auth/ y /hubs/ hacia los servicios backend. Requiere los módulos URL Rewrite + ARR.",
1534
1592
  webserver_note_nginx:"nginx servirá la interfaz React y enrutará las rutas backend. Recomendado para Linux; también funciona en Windows.",
1593
+ iis_site_name_lbl:"Nombre del sitio IIS",
1594
+ iis_site_name_note:"Nombre del sitio IIS a crear. Si usa una ruta virtual, introduzca el nombre del sitio IIS padre (p. ej. Default Web Site).",
1595
+ iis_virtual_path_lbl:"Ruta virtual",
1596
+ iis_virtual_path_note:"Déjelo vacío para alojar en la raíz del sitio, o introduzca una subruta (p. ej. depository) para instalar como aplicación virtual bajo el sitio padre.",
1597
+ iis_remote_host_lbl:"Host IIS remoto",
1598
+ iis_remote_host_note:"Déjelo vacío para configurar IIS en esta máquina. Introduzca un nombre de host o IP para desplegar la UI en un servidor IIS remoto mediante PowerShell Remoting (WinRM).",
1599
+ iis_backend_host_lbl:"Host de servicios backend",
1600
+ iis_backend_host_note:"Nombre de host o IP del servidor que ejecuta los servicios API/Auth, accesible desde el servidor IIS remoto. Se usa en las reglas de proxy inverso de IIS.",
1535
1601
  generate:"Generar", back_btn:"‹ Atrás", next_btn:"Siguiente ›",
1536
1602
  review_db:"Base de datos", review_db_user:"Usuario BD", review_auth_db:"BD Auth",
1537
1603
  review_auth_user:"Usuario BD Auth", review_install:"Directorio de instalación",
@@ -1645,6 +1711,14 @@ const T = {
1645
1711
  webserver_sect:"خادم الويب",
1646
1712
  webserver_note_iis:"سيقوم IIS بتقديم واجهة React وتوجيه /api/ و/auth/ و/hubs/ إلى خدمات الخلفية. يتطلب وحدتي URL Rewrite وARR.",
1647
1713
  webserver_note_nginx:"سيقوم nginx بتقديم واجهة React وتوجيه مسارات الخلفية. مُوصى به على Linux ويعمل أيضاً على Windows.",
1714
+ iis_site_name_lbl:"اسم موقع IIS",
1715
+ iis_site_name_note:"اسم موقع IIS المراد إنشاؤه. عند استخدام مسار افتراضي، أدخل اسم موقع IIS الأصلي (مثل Default Web Site).",
1716
+ iis_virtual_path_lbl:"المسار الافتراضي",
1717
+ iis_virtual_path_note:"اتركه فارغاً للاستضافة في جذر الموقع، أو أدخل مساراً فرعياً (مثل depository) للتثبيت كتطبيق افتراضي تحت الموقع الأصلي.",
1718
+ iis_remote_host_lbl:"مضيف IIS البعيد",
1719
+ iis_remote_host_note:"اتركه فارغاً لتكوين IIS على هذه الآلة. أدخل اسم مضيف أو IP لنشر الواجهة على خادم IIS بعيد عبر PowerShell Remoting (WinRM).",
1720
+ iis_backend_host_lbl:"مضيف خدمات الخلفية",
1721
+ iis_backend_host_note:"اسم مضيف أو IP الخادم الذي يشغّل خدمات API/Auth، كما يمكن الوصول إليه من خادم IIS البعيد. يُستخدم في قواعد الوكيل العكسي لـ IIS.",
1648
1722
  generate:"إنشاء", back_btn:"‹ رجوع", next_btn:"التالي ›",
1649
1723
  review_db:"قاعدة البيانات", review_db_user:"مستخدم قاعدة البيانات", review_auth_db:"قاعدة بيانات المصادقة",
1650
1724
  review_auth_user:"مستخدم قاعدة المصادقة", review_install:"دليل التثبيت",
@@ -1899,6 +1973,13 @@ function selectWs(val) {
1899
1973
  if (card) { card.classList.add('selected'); card.querySelector('input').checked = true; }
1900
1974
  document.getElementById('wsNote').innerHTML =
1901
1975
  `<span style="font-size:11px;color:var(--muted)">${t('webserver_note_' + val) || ''}</span>`;
1976
+ document.getElementById('iisFields').style.display = val === 'iis' ? '' : 'none';
1977
+ if (val !== 'iis') document.getElementById('iisBackendHostField').style.display = 'none';
1978
+ }
1979
+
1980
+ function toggleIisBackendHost() {
1981
+ const hasRemote = document.getElementById('iis_remote_host').value.trim() !== '';
1982
+ document.getElementById('iisBackendHostField').style.display = hasRemote ? '' : 'none';
1902
1983
  }
1903
1984
 
1904
1985
  document.querySelectorAll('#wsGroup .radio-card').forEach(card => {
@@ -1946,6 +2027,10 @@ function buildConf() {
1946
2027
  JWT_SECRET: val('jwt_secret'), SITE_URL: val('site_url'),
1947
2028
  INSTALL_DIR: val('install_dir'), DATA_DIR: val('data_dir'),
1948
2029
  WEBSERVER_TYPE: wsType(),
2030
+ IIS_SITE_NAME: val('iis_site_name') || 'Depository',
2031
+ IIS_VIRTUAL_PATH: val('iis_virtual_path') || '',
2032
+ IIS_REMOTE_HOST: val('iis_remote_host') || '',
2033
+ IIS_BACKEND_HOST: val('iis_backend_host') || 'localhost',
1949
2034
  WINDOWS_AUTH_ENABLED: document.getElementById('ad_enabled').checked?'true':'false',
1950
2035
  AD_EMAIL_DOMAIN: val('ad_domain'),
1951
2036
  AD_GROUP_ADMIN: val('ad_admin'), AD_GROUP_ORG_ADMIN: val('ad_orgadmin'),
@@ -2025,6 +2110,11 @@ function downloadConf() {
2025
2110
  'INSTALL_DIR=' + c.INSTALL_DIR, 'DATA_DIR=' + c.DATA_DIR,
2026
2111
  '', '# Web server (iis | nginx)',
2027
2112
  'WEBSERVER_TYPE=' + c.WEBSERVER_TYPE,
2113
+ '# IIS: site name, virtual path, and optional remote deployment (IIS only)',
2114
+ 'IIS_SITE_NAME=' + c.IIS_SITE_NAME,
2115
+ 'IIS_VIRTUAL_PATH=' + c.IIS_VIRTUAL_PATH,
2116
+ 'IIS_REMOTE_HOST=' + c.IIS_REMOTE_HOST,
2117
+ 'IIS_BACKEND_HOST=' + c.IIS_BACKEND_HOST,
2028
2118
  '', '# Active Directory',
2029
2119
  'WINDOWS_AUTH_ENABLED=' + c.WINDOWS_AUTH_ENABLED, 'AD_EMAIL_DOMAIN=' + c.AD_EMAIL_DOMAIN,
2030
2120
  'AD_GROUP_ADMIN=' + c.AD_GROUP_ADMIN, 'AD_GROUP_ORG_ADMIN=' + c.AD_GROUP_ORG_ADMIN,
@@ -2614,6 +2704,7 @@ const PERSIST_FIELDS = [
2614
2704
  'jwt_secret','site_url',
2615
2705
  'install_dir','data_dir',
2616
2706
  'ad_domain','ad_admin','ad_orgadmin','ad_user','ad_readonly',
2707
+ 'iis_site_name','iis_virtual_path','iis_remote_host','iis_backend_host',
2617
2708
  ];
2618
2709
  const PERSIST_RADIOS = ['dbType','wsType'];
2619
2710
  const PERSIST_CHECKS = ['ad_enabled'];