Add secure configuration bootstrap flow

This commit is contained in:
Lorenzune
2026-04-25 13:29:48 +02:00
parent 6c7d78c156
commit 3c9a599505
27 changed files with 962 additions and 3616 deletions
+236
View File
@@ -0,0 +1,236 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Nitro Secure Runtime Modes</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-slate-950 text-slate-100">
<div class="mx-auto max-w-6xl px-6 py-10">
<div class="mb-8 rounded-3xl border border-cyan-500/20 bg-slate-900/80 p-8 shadow-2xl shadow-cyan-950/30">
<div class="flex flex-wrap items-center gap-3">
<span class="rounded-full border border-cyan-400/30 bg-cyan-500/10 px-3 py-1 text-xs font-semibold uppercase tracking-[0.25em] text-cyan-300">Nitro V3</span>
<span class="rounded-full border border-emerald-400/30 bg-emerald-500/10 px-3 py-1 text-xs font-semibold uppercase tracking-[0.25em] text-emerald-300">Secure Runtime</span>
</div>
<h1 class="mt-5 text-4xl font-black tracking-tight text-white">Runtime configuration guide</h1>
<p class="mt-4 max-w-3xl text-sm leading-7 text-slate-300">
This page gives you a cleaner, readable overview of runtime toggles, example files and the values that belong in config files
rather than hardcoded inside <code class="rounded bg-slate-800 px-1.5 py-0.5 text-cyan-300">src</code>.
</p>
</div>
<div class="grid gap-6 lg:grid-cols-[280px_minmax(0,1fr)]">
<aside class="rounded-3xl border border-slate-800 bg-slate-900/70 p-5 lg:sticky lg:top-6 lg:h-fit">
<h2 class="mb-4 text-sm font-bold uppercase tracking-[0.2em] text-slate-400">Contents</h2>
<nav class="space-y-2 text-sm">
<a class="block rounded-xl px-3 py-2 text-slate-300 transition hover:bg-slate-800 hover:text-white" href="#overview">Overview</a>
<a class="block rounded-xl px-3 py-2 text-slate-300 transition hover:bg-slate-800 hover:text-white" href="#files">Files to use</a>
<a class="block rounded-xl px-3 py-2 text-slate-300 transition hover:bg-slate-800 hover:text-white" href="#client-mode">client-mode</a>
<a class="block rounded-xl px-3 py-2 text-slate-300 transition hover:bg-slate-800 hover:text-white" href="#renderer-config">renderer-config</a>
<a class="block rounded-xl px-3 py-2 text-slate-300 transition hover:bg-slate-800 hover:text-white" href="#ui-config">ui-config</a>
<a class="block rounded-xl px-3 py-2 text-slate-300 transition hover:bg-slate-800 hover:text-white" href="#runtime-code">Runtime code</a>
<a class="block rounded-xl px-3 py-2 text-slate-300 transition hover:bg-slate-800 hover:text-white" href="#emulator">Emulator</a>
<a class="block rounded-xl px-3 py-2 text-slate-300 transition hover:bg-slate-800 hover:text-white" href="#scenarios">Scenarios</a>
<a class="block rounded-xl px-3 py-2 text-slate-300 transition hover:bg-slate-800 hover:text-white" href="#checklist">Checklist</a>
</nav>
</aside>
<main class="space-y-6">
<section id="overview" class="rounded-3xl border border-slate-800 bg-slate-900/70 p-8">
<h2 class="text-2xl font-bold text-white">Overview</h2>
<div class="mt-5 grid gap-4 md:grid-cols-3">
<div class="rounded-2xl border border-slate-800 bg-slate-950/70 p-5">
<h3 class="text-sm font-semibold uppercase tracking-wide text-cyan-300">Dist Obfuscation</h3>
<p class="mt-3 text-sm leading-7 text-slate-300">Chooses whether the client loads <code class="rounded bg-slate-800 px-1">app.js/app.css</code> or the obfuscated <code class="rounded bg-slate-800 px-1">.dat</code> versions.</p>
</div>
<div class="rounded-2xl border border-slate-800 bg-slate-950/70 p-5">
<h3 class="text-sm font-semibold uppercase tracking-wide text-emerald-300">Secure Assets</h3>
<p class="mt-3 text-sm leading-7 text-slate-300">Controls whether <code class="rounded bg-slate-800 px-1">renderer-config</code>, <code class="rounded bg-slate-800 px-1">ui-config</code> and gamedata go through <code class="rounded bg-slate-800 px-1">/nitro-sec/file</code>.</p>
</div>
<div class="rounded-2xl border border-slate-800 bg-slate-950/70 p-5">
<h3 class="text-sm font-semibold uppercase tracking-wide text-fuchsia-300">Secure API</h3>
<p class="mt-3 text-sm leading-7 text-slate-300">Enables or disables runtime encryption for <code class="rounded bg-slate-800 px-1">/api/*</code> requests.</p>
</div>
</div>
</section>
<section id="files" class="rounded-3xl border border-slate-800 bg-slate-900/70 p-8">
<h2 class="text-2xl font-bold text-white">Files to use</h2>
<div class="mt-5 overflow-hidden rounded-2xl border border-slate-800">
<table class="min-w-full divide-y divide-slate-800 text-sm">
<thead class="bg-slate-950/80">
<tr>
<th class="px-4 py-3 text-left font-semibold text-slate-200">File</th>
<th class="px-4 py-3 text-left font-semibold text-slate-200">Purpose</th>
<th class="px-4 py-3 text-left font-semibold text-slate-200">Note</th>
</tr>
</thead>
<tbody class="divide-y divide-slate-800">
<tr class="bg-slate-900/60">
<td class="px-4 py-3"><code>public/configuration/client-mode.example</code></td>
<td class="px-4 py-3">Template for runtime toggles</td>
<td class="px-4 py-3 text-slate-300">Copy it into a real <code>configuration/client-mode.json</code> in deployment; that real file stays ignored by Git</td>
</tr>
<tr class="bg-slate-950/40">
<td class="px-4 py-3"><code>public/configuration/renderer-config.example</code></td>
<td class="px-4 py-3">Clean renderer config template</td>
<td class="px-4 py-3 text-slate-300">Does not touch your local <code>configuration/renderer-config.json</code></td>
</tr>
<tr class="bg-slate-900/60">
<td class="px-4 py-3"><code>public/configuration/ui-config.example</code></td>
<td class="px-4 py-3">UI config reference template</td>
<td class="px-4 py-3 text-slate-300">Use it as the source of truth for UI URLs and widgets</td>
</tr>
<tr class="bg-slate-950/40">
<td class="px-4 py-3"><code>Latest_Compiled_Version/config.ini.example</code></td>
<td class="px-4 py-3">Backend secure flags</td>
<td class="px-4 py-3 text-slate-300">Defines the emulator-side runtime settings</td>
</tr>
</tbody>
</table>
</div>
</section>
<section id="client-mode" class="rounded-3xl border border-slate-800 bg-slate-900/70 p-8">
<h2 class="text-2xl font-bold text-white">client-mode.example</h2>
<p class="mt-3 text-sm leading-7 text-slate-300">This is the main runtime switchboard. You can enable or disable behavior without editing client source code.</p>
<pre class="mt-5 overflow-x-auto rounded-2xl border border-slate-800 bg-slate-950/90 p-5 text-sm text-cyan-300"><code>{
"distObfuscationEnabled": true,
"secureAssetsEnabled": true,
"secureApiEnabled": true,
"apiBaseUrl": "https://nitro.example.com:2096",
"plainConfigBaseUrl": "https://hotel.example.com/configuration/",
"plainGamedataBaseUrl": "https://hotel.example.com/client/nitro/gamedata/"
}</code></pre>
<div class="mt-5 grid gap-4 md:grid-cols-2">
<div class="rounded-2xl border border-slate-800 bg-slate-950/60 p-5">
<h3 class="font-semibold text-white">Fields</h3>
<ul class="mt-3 space-y-2 text-sm leading-7 text-slate-300">
<li><code class="rounded bg-slate-800 px-1">distObfuscationEnabled</code>: use <code>.dat</code> or plain assets</li>
<li><code class="rounded bg-slate-800 px-1">secureAssetsEnabled</code>: enables <code>/nitro-sec/file</code></li>
<li><code class="rounded bg-slate-800 px-1">secureApiEnabled</code>: encrypts <code>/api/*</code> requests</li>
<li><code class="rounded bg-slate-800 px-1">apiBaseUrl</code>: emulator/API base URL</li>
</ul>
</div>
<div class="rounded-2xl border border-amber-500/20 bg-amber-500/10 p-5">
<h3 class="font-semibold text-amber-200">Recommendation</h3>
<p class="mt-3 text-sm leading-7 text-amber-100/90">Always set <code>apiBaseUrl</code> explicitly so you do not rely on fallback logic.</p>
</div>
</div>
</section>
<section id="renderer-config" class="rounded-3xl border border-slate-800 bg-slate-900/70 p-8">
<h2 class="text-2xl font-bold text-white">renderer-config.example</h2>
<p class="mt-3 text-sm leading-7 text-slate-300">Socket, API, asset and gamedata URLs should live here, not inside React components.</p>
<div class="mt-5 grid gap-4 md:grid-cols-2">
<div class="rounded-2xl border border-slate-800 bg-slate-950/60 p-5">
<h3 class="font-semibold text-white">Main keys</h3>
<ul class="mt-3 space-y-2 text-sm leading-7 text-slate-300">
<li><code>socket.url</code></li>
<li><code>api.url</code></li>
<li><code>asset.url</code></li>
<li><code>image.library.url</code></li>
<li><code>images.url</code></li>
<li><code>gamedata.url</code></li>
</ul>
</div>
<div class="rounded-2xl border border-slate-800 bg-slate-950/60 p-5">
<h3 class="font-semibold text-white">Translations</h3>
<ul class="mt-3 space-y-2 text-sm leading-7 text-slate-300">
<li><code>external.texts.translation.url</code></li>
<li><code>furnidata.translation.url</code></li>
<li>Uses <code>%locale%</code> and <code>%timestamp%</code></li>
</ul>
</div>
</div>
</section>
<section id="ui-config" class="rounded-3xl border border-slate-800 bg-slate-900/70 p-8">
<h2 class="text-2xl font-bold text-white">ui-config.example</h2>
<p class="mt-3 text-sm leading-7 text-slate-300">UI image and login view sources should come from config values here or from renderer config, never from hardcoded URLs in components.</p>
<div class="mt-5 rounded-2xl border border-slate-800 bg-slate-950/60 p-5">
<h3 class="font-semibold text-white">Login view</h3>
<ul class="mt-3 space-y-2 text-sm leading-7 text-slate-300">
<li><code>loginview.images.background</code></li>
<li><code>loginview.images.drape</code></li>
<li><code>loginview.images.left</code></li>
<li><code>loginview.images.right</code></li>
<li><code>loginview.widgets</code> for promotional blocks</li>
</ul>
</div>
</section>
<section id="runtime-code" class="rounded-3xl border border-slate-800 bg-slate-900/70 p-8">
<h2 class="text-2xl font-bold text-white">Runtime code involved</h2>
<div class="mt-5 grid gap-4 md:grid-cols-2">
<div class="rounded-2xl border border-slate-800 bg-slate-950/60 p-5">
<h3 class="font-semibold text-white"><code>src/bootstrap.ts</code></h3>
<p class="mt-3 text-sm leading-7 text-slate-300">Reads <code>client-mode</code>, builds <code>NitroConfig['config.urls']</code> and prepares client bootstrap.</p>
</div>
<div class="rounded-2xl border border-slate-800 bg-slate-950/60 p-5">
<h3 class="font-semibold text-white"><code>src/secure-assets.ts</code></h3>
<p class="mt-3 text-sm leading-7 text-slate-300">Handles ECDH, decrypt/encrypt, plain fallback and secure API runtime behavior.</p>
</div>
<div class="rounded-2xl border border-slate-800 bg-slate-950/60 p-5">
<h3 class="font-semibold text-white"><code>scripts/write-asset-loader.mjs</code></h3>
<p class="mt-3 text-sm leading-7 text-slate-300">Generates <code>public/configuration/asset-loader.js</code> and decides between plain assets and <code>.dat</code>.</p>
</div>
<div class="rounded-2xl border border-slate-800 bg-slate-950/60 p-5">
<h3 class="font-semibold text-white"><code>scripts/minify-dist.mjs</code></h3>
<p class="mt-3 text-sm leading-7 text-slate-300">Generates <code>.dat</code> files while keeping plain files available for runtime switching.</p>
</div>
</div>
</section>
<section id="emulator" class="rounded-3xl border border-slate-800 bg-slate-900/70 p-8">
<h2 class="text-2xl font-bold text-white">Emulator</h2>
<pre class="mt-5 overflow-x-auto rounded-2xl border border-slate-800 bg-slate-950/90 p-5 text-sm text-emerald-300"><code>nitro.secure.assets.enabled=true
nitro.secure.api.enabled=true
nitro.secure.config.root=C:/path/to/Nitro-V3/public
nitro.secure.gamedata.root=C:/path/to/gamedata
nitro.secure.master_key=change-me-to-a-long-random-secret</code></pre>
<ul class="mt-5 space-y-2 text-sm leading-7 text-slate-300">
<li><code>nitro.secure.assets.enabled</code>: enables <code>/nitro-sec/bootstrap</code> and <code>/nitro-sec/file</code></li>
<li><code>nitro.secure.api.enabled</code>: enables secure handling for <code>/api/*</code></li>
<li><code>nitro.secure.config.root</code>: path to live config files</li>
<li><code>nitro.secure.gamedata.root</code>: path to live gamedata</li>
<li><code>nitro.secure.master_key</code>: persistent server-side secret</li>
</ul>
</section>
<section id="scenarios" class="rounded-3xl border border-slate-800 bg-slate-900/70 p-8">
<h2 class="text-2xl font-bold text-white">Quick scenarios</h2>
<div class="mt-5 grid gap-4 md:grid-cols-3">
<div class="rounded-2xl border border-cyan-500/20 bg-cyan-500/10 p-5">
<h3 class="font-semibold text-cyan-200">Everything enabled</h3>
<p class="mt-3 text-sm leading-7 text-cyan-50/90">Secure assets, secure API and dist obfuscation all enabled.</p>
</div>
<div class="rounded-2xl border border-emerald-500/20 bg-emerald-500/10 p-5">
<h3 class="font-semibold text-emerald-200">Only .dat</h3>
<p class="mt-3 text-sm leading-7 text-emerald-50/90">Uses obfuscated assets but leaves config/API in plain mode.</p>
</div>
<div class="rounded-2xl border border-slate-700 bg-slate-950/60 p-5">
<h3 class="font-semibold text-white">Everything plain</h3>
<p class="mt-3 text-sm leading-7 text-slate-300">Complete fallback mode for local testing or debugging.</p>
</div>
</div>
</section>
<section id="checklist" class="rounded-3xl border border-slate-800 bg-slate-900/70 p-8">
<h2 class="text-2xl font-bold text-white">Final checklist</h2>
<div class="mt-5 grid gap-3">
<div class="rounded-2xl border border-slate-800 bg-slate-950/60 px-5 py-4 text-sm text-slate-300">You created real files from <code>client-mode.example</code>, <code>renderer-config.example</code> and <code>ui-config.example</code></div>
<div class="rounded-2xl border border-slate-800 bg-slate-950/60 px-5 py-4 text-sm text-slate-300">Public URLs live in config files, not in React components</div>
<div class="rounded-2xl border border-slate-800 bg-slate-950/60 px-5 py-4 text-sm text-slate-300">Both plain files and <code>.dat</code> files are deployed</div>
<div class="rounded-2xl border border-slate-800 bg-slate-950/60 px-5 py-4 text-sm text-slate-300">Your server exposes a proper MIME type for <code>.dat</code></div>
<div class="rounded-2xl border border-slate-800 bg-slate-950/60 px-5 py-4 text-sm text-slate-300">You set <code>nitro.secure.master_key</code> on the emulator side</div>
</div>
</section>
</main>
</div>
</div>
</body>
</html>
+23 -21
View File
@@ -3,11 +3,11 @@
This document summarizes all values you may need to configure for:
- `dist` bundle obfuscation (`app.js` / `app.css``.dat`)
- secure runtime assets (`renderer-config.json`, `ui-config.json`, `gamedata`)
- secure runtime assets (`configuration/renderer-config.json`, `configuration/ui-config.json`, `gamedata`)
- secure runtime API (`/api/*`)
- plain fallbacks when you want to disable the secure layer without removing the code
## 1. `Nitro-V3/public/client-mode.json`
## 1. `Nitro-V3/public/configuration/client-mode.json`
This file controls everything at runtime.
@@ -17,7 +17,7 @@ This file controls everything at runtime.
"secureAssetsEnabled": true,
"secureApiEnabled": true,
"apiBaseUrl": "https://nitro.example.com:2096",
"plainConfigBaseUrl": "https://hotel.example.com/",
"plainConfigBaseUrl": "https://hotel.example.com/configuration/",
"plainGamedataBaseUrl": "https://hotel.example.com/client/nitro/gamedata/"
}
```
@@ -30,7 +30,7 @@ This file controls everything at runtime.
- `secureAssetsEnabled`
- `true`: `bootstrap.ts` and `secure-assets.ts` use `/nitro-sec/file`
- `false`: `renderer-config.json`, `ui-config.json`, and gamedata are loaded in plain mode
- `false`: `configuration/renderer-config.json`, `configuration/ui-config.json`, and gamedata are loaded in plain mode
- `secureApiEnabled`
- `true`: the `fetch` wrapper encrypts `/api/*` requests
@@ -43,7 +43,7 @@ This file controls everything at runtime.
- `plainConfigBaseUrl`
- base URL for plain config files
- usually: `https://hotel.example.com/`
- usually: `https://hotel.example.com/configuration/`
- `plainGamedataBaseUrl`
- base URL for plain gamedata files
@@ -74,7 +74,7 @@ The current fallback is:
(window as any).NitroSecureApiUrl = clientMode.apiBaseUrl || 'https://nitro.example.com:2096/';
```
So in production it is better to always set `apiBaseUrl` inside `client-mode.json`.
So in production it is better to always set `apiBaseUrl` inside `configuration/client-mode.json`.
## 3. `Nitro-V3/src/secure-assets.ts`
@@ -95,7 +95,7 @@ This file contains the runtime logic for:
Normally you should not need to touch it unless you want to change the secure protocol itself.
## 4. `Nitro-V3/public/renderer-config.json`
## 4. `Nitro-V3/public/configuration/renderer-config.json`
This file still defines the paths used by the renderer.
@@ -129,7 +129,7 @@ You can use plain classic paths, for example:
or you can keep the renderer config as-is and let `secure-assets.ts` handle the fallback conversion.
## 5. `Nitro-V3/public/ui-config.json`
## 5. `Nitro-V3/public/configuration/ui-config.json`
There is no secure logic here, but it is one of the files loaded through `config.urls`.
@@ -140,12 +140,12 @@ So you only need to maintain the content itself correctly.
## 6. `Nitro-V3/scripts/write-asset-loader.mjs`
This script generates `public/asset-loader.js`.
This script generates `public/configuration/asset-loader.js`.
### What it does now
- renders the initial shell
- reads `client-mode.json`
- reads `configuration/client-mode.json`
- decides whether to load:
- `app.css.dat` / `app.js.dat`
- or `assets/app.css` / `assets/app.js`
@@ -194,7 +194,7 @@ nitro.secure.master_key=change-me-to-a-long-random-secret
- enables the secure layer for `/api/*`
- `nitro.secure.config.root`
- folder used to read `renderer-config.json` and `ui-config.json`
- folder used to read `configuration/renderer-config.json` and `configuration/ui-config.json`
- `nitro.secure.gamedata.root`
- folder used to read live gamedata
@@ -207,7 +207,7 @@ nitro.secure.master_key=change-me-to-a-long-random-secret
### Everything enabled
`client-mode.json`
`configuration/client-mode.json`
```json
{
@@ -215,7 +215,7 @@ nitro.secure.master_key=change-me-to-a-long-random-secret
"secureAssetsEnabled": true,
"secureApiEnabled": true,
"apiBaseUrl": "https://nitro.example.com:2096",
"plainConfigBaseUrl": "https://hotel.example.com/",
"plainConfigBaseUrl": "https://hotel.example.com/configuration/",
"plainGamedataBaseUrl": "https://hotel.example.com/client/nitro/gamedata/"
}
```
@@ -232,7 +232,7 @@ nitro.secure.master_key=a-long-random-secret
### `.dat` only, no secure assets/API
`client-mode.json`
`configuration/client-mode.json`
```json
{
@@ -240,7 +240,7 @@ nitro.secure.master_key=a-long-random-secret
"secureAssetsEnabled": false,
"secureApiEnabled": false,
"apiBaseUrl": "https://nitro.example.com:2096",
"plainConfigBaseUrl": "https://hotel.example.com/",
"plainConfigBaseUrl": "https://hotel.example.com/configuration/",
"plainGamedataBaseUrl": "https://hotel.example.com/client/nitro/gamedata/"
}
```
@@ -254,7 +254,7 @@ nitro.secure.api.enabled=false
### Everything plain
`client-mode.json`
`configuration/client-mode.json`
```json
{
@@ -262,7 +262,7 @@ nitro.secure.api.enabled=false
"secureAssetsEnabled": false,
"secureApiEnabled": false,
"apiBaseUrl": "https://nitro.example.com:2096",
"plainConfigBaseUrl": "https://hotel.example.com/",
"plainConfigBaseUrl": "https://hotel.example.com/configuration/",
"plainGamedataBaseUrl": "https://hotel.example.com/client/nitro/gamedata/"
}
```
@@ -273,9 +273,9 @@ nitro.secure.api.enabled=false
For changes to:
- `client-mode.json`
- `renderer-config.json`
- `ui-config.json`
- `configuration/client-mode.json`
- `configuration/renderer-config.json`
- `configuration/ui-config.json`
- live gamedata
- `config.ini`
@@ -298,10 +298,12 @@ To make the toggles work properly:
## 12. Quick checklist
- `client-mode.json` configured
- `configuration/client-mode.json` configured
- `apiBaseUrl` correct
- `nitro.secure.master_key` set
- `nitro.secure.config.root` correct
- `nitro.secure.gamedata.root` correct
- both `.dat` and plain files deployed
- `.dat` MIME type configured on the web server
+236
View File
@@ -0,0 +1,236 @@
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Nitro Secure Runtime Modes</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-slate-950 text-slate-100">
<div class="mx-auto max-w-6xl px-6 py-10">
<div class="mb-8 rounded-3xl border border-cyan-500/20 bg-slate-900/80 p-8 shadow-2xl shadow-cyan-950/30">
<div class="flex flex-wrap items-center gap-3">
<span class="rounded-full border border-cyan-400/30 bg-cyan-500/10 px-3 py-1 text-xs font-semibold uppercase tracking-[0.25em] text-cyan-300">Nitro V3</span>
<span class="rounded-full border border-emerald-400/30 bg-emerald-500/10 px-3 py-1 text-xs font-semibold uppercase tracking-[0.25em] text-emerald-300">Secure Runtime</span>
</div>
<h1 class="mt-5 text-4xl font-black tracking-tight text-white">Documentazione configurazione runtime</h1>
<p class="mt-4 max-w-3xl text-sm leading-7 text-slate-300">
Questa pagina riassume in modo ordinato come configurare i toggle runtime, i file example e i parametri lato client / emulatore
senza sporcare i componenti in <code class="rounded bg-slate-800 px-1.5 py-0.5 text-cyan-300">src</code>.
</p>
</div>
<div class="grid gap-6 lg:grid-cols-[280px_minmax(0,1fr)]">
<aside class="rounded-3xl border border-slate-800 bg-slate-900/70 p-5 lg:sticky lg:top-6 lg:h-fit">
<h2 class="mb-4 text-sm font-bold uppercase tracking-[0.2em] text-slate-400">Indice</h2>
<nav class="space-y-2 text-sm">
<a class="block rounded-xl px-3 py-2 text-slate-300 transition hover:bg-slate-800 hover:text-white" href="#overview">Overview</a>
<a class="block rounded-xl px-3 py-2 text-slate-300 transition hover:bg-slate-800 hover:text-white" href="#files">File da usare</a>
<a class="block rounded-xl px-3 py-2 text-slate-300 transition hover:bg-slate-800 hover:text-white" href="#client-mode">client-mode</a>
<a class="block rounded-xl px-3 py-2 text-slate-300 transition hover:bg-slate-800 hover:text-white" href="#renderer-config">renderer-config</a>
<a class="block rounded-xl px-3 py-2 text-slate-300 transition hover:bg-slate-800 hover:text-white" href="#ui-config">ui-config</a>
<a class="block rounded-xl px-3 py-2 text-slate-300 transition hover:bg-slate-800 hover:text-white" href="#runtime-code">Codice runtime</a>
<a class="block rounded-xl px-3 py-2 text-slate-300 transition hover:bg-slate-800 hover:text-white" href="#emulator">Emulatore</a>
<a class="block rounded-xl px-3 py-2 text-slate-300 transition hover:bg-slate-800 hover:text-white" href="#scenarios">Scenari</a>
<a class="block rounded-xl px-3 py-2 text-slate-300 transition hover:bg-slate-800 hover:text-white" href="#checklist">Checklist</a>
</nav>
</aside>
<main class="space-y-6">
<section id="overview" class="rounded-3xl border border-slate-800 bg-slate-900/70 p-8">
<h2 class="text-2xl font-bold text-white">Overview</h2>
<div class="mt-5 grid gap-4 md:grid-cols-3">
<div class="rounded-2xl border border-slate-800 bg-slate-950/70 p-5">
<h3 class="text-sm font-semibold uppercase tracking-wide text-cyan-300">Dist Obfuscation</h3>
<p class="mt-3 text-sm leading-7 text-slate-300">Sceglie se caricare <code class="rounded bg-slate-800 px-1">app.js/app.css</code> oppure <code class="rounded bg-slate-800 px-1">.dat</code>.</p>
</div>
<div class="rounded-2xl border border-slate-800 bg-slate-950/70 p-5">
<h3 class="text-sm font-semibold uppercase tracking-wide text-emerald-300">Secure Assets</h3>
<p class="mt-3 text-sm leading-7 text-slate-300">Controlla se <code class="rounded bg-slate-800 px-1">renderer-config</code>, <code class="rounded bg-slate-800 px-1">ui-config</code> e gamedata passano da <code class="rounded bg-slate-800 px-1">/nitro-sec/file</code>.</p>
</div>
<div class="rounded-2xl border border-slate-800 bg-slate-950/70 p-5">
<h3 class="text-sm font-semibold uppercase tracking-wide text-fuchsia-300">Secure API</h3>
<p class="mt-3 text-sm leading-7 text-slate-300">Attiva o disattiva la cifratura runtime automatica su <code class="rounded bg-slate-800 px-1">/api/*</code>.</p>
</div>
</div>
</section>
<section id="files" class="rounded-3xl border border-slate-800 bg-slate-900/70 p-8">
<h2 class="text-2xl font-bold text-white">File da usare</h2>
<div class="mt-5 overflow-hidden rounded-2xl border border-slate-800">
<table class="min-w-full divide-y divide-slate-800 text-sm">
<thead class="bg-slate-950/80">
<tr>
<th class="px-4 py-3 text-left font-semibold text-slate-200">File</th>
<th class="px-4 py-3 text-left font-semibold text-slate-200">Scopo</th>
<th class="px-4 py-3 text-left font-semibold text-slate-200">Nota</th>
</tr>
</thead>
<tbody class="divide-y divide-slate-800">
<tr class="bg-slate-900/60">
<td class="px-4 py-3"><code>public/configuration/client-mode.example</code></td>
<td class="px-4 py-3">Template per i toggle runtime</td>
<td class="px-4 py-3 text-slate-300">Da copiare in <code>configuration/client-mode.json</code> nel deploy reale, che resta ignorato da Git</td>
</tr>
<tr class="bg-slate-950/40">
<td class="px-4 py-3"><code>public/configuration/renderer-config.example</code></td>
<td class="px-4 py-3">Template sicuro del renderer config</td>
<td class="px-4 py-3 text-slate-300">Non tocca il tuo <code>configuration/renderer-config.json</code> locale</td>
</tr>
<tr class="bg-slate-900/60">
<td class="px-4 py-3"><code>public/configuration/ui-config.example</code></td>
<td class="px-4 py-3">Template UI config</td>
<td class="px-4 py-3 text-slate-300">Da mantenere come riferimento pulito</td>
</tr>
<tr class="bg-slate-950/40">
<td class="px-4 py-3"><code>Latest_Compiled_Version/config.ini.example</code></td>
<td class="px-4 py-3">Flag backend secure</td>
<td class="px-4 py-3 text-slate-300">Specifica la parte lato emulatore</td>
</tr>
</tbody>
</table>
</div>
</section>
<section id="client-mode" class="rounded-3xl border border-slate-800 bg-slate-900/70 p-8">
<h2 class="text-2xl font-bold text-white">client-mode.example</h2>
<p class="mt-3 text-sm leading-7 text-slate-300">È il punto centrale per attivare o disattivare il comportamento runtime senza dover modificare il codice.</p>
<pre class="mt-5 overflow-x-auto rounded-2xl border border-slate-800 bg-slate-950/90 p-5 text-sm text-cyan-300"><code>{
"distObfuscationEnabled": true,
"secureAssetsEnabled": true,
"secureApiEnabled": true,
"apiBaseUrl": "https://nitro.example.com:2096",
"plainConfigBaseUrl": "https://hotel.example.com/configuration/",
"plainGamedataBaseUrl": "https://hotel.example.com/client/nitro/gamedata/"
}</code></pre>
<div class="mt-5 grid gap-4 md:grid-cols-2">
<div class="rounded-2xl border border-slate-800 bg-slate-950/60 p-5">
<h3 class="font-semibold text-white">Campi</h3>
<ul class="mt-3 space-y-2 text-sm leading-7 text-slate-300">
<li><code class="rounded bg-slate-800 px-1">distObfuscationEnabled</code>: usa <code>.dat</code> oppure file plain</li>
<li><code class="rounded bg-slate-800 px-1">secureAssetsEnabled</code>: attiva <code>/nitro-sec/file</code></li>
<li><code class="rounded bg-slate-800 px-1">secureApiEnabled</code>: cifra le richieste <code>/api/*</code></li>
<li><code class="rounded bg-slate-800 px-1">apiBaseUrl</code>: base URL emulatore/API</li>
</ul>
</div>
<div class="rounded-2xl border border-amber-500/20 bg-amber-500/10 p-5">
<h3 class="font-semibold text-amber-200">Suggerimento</h3>
<p class="mt-3 text-sm leading-7 text-amber-100/90">Conviene impostare sempre <code>apiBaseUrl</code> in modo esplicito, così non dipendi da fallback impliciti del runtime.</p>
</div>
</div>
</section>
<section id="renderer-config" class="rounded-3xl border border-slate-800 bg-slate-900/70 p-8">
<h2 class="text-2xl font-bold text-white">renderer-config.example</h2>
<p class="mt-3 text-sm leading-7 text-slate-300">Qui definisci URL di socket, API, asset library e gamedata. Tutti i link pubblici dovrebbero vivere qui, non nei componenti React.</p>
<div class="mt-5 grid gap-4 md:grid-cols-2">
<div class="rounded-2xl border border-slate-800 bg-slate-950/60 p-5">
<h3 class="font-semibold text-white">Chiavi principali</h3>
<ul class="mt-3 space-y-2 text-sm leading-7 text-slate-300">
<li><code>socket.url</code></li>
<li><code>api.url</code></li>
<li><code>asset.url</code></li>
<li><code>image.library.url</code></li>
<li><code>images.url</code></li>
<li><code>gamedata.url</code></li>
</ul>
</div>
<div class="rounded-2xl border border-slate-800 bg-slate-950/60 p-5">
<h3 class="font-semibold text-white">Traduzioni</h3>
<ul class="mt-3 space-y-2 text-sm leading-7 text-slate-300">
<li><code>external.texts.translation.url</code></li>
<li><code>furnidata.translation.url</code></li>
<li>Usano <code>%locale%</code> e <code>%timestamp%</code></li>
</ul>
</div>
</div>
</section>
<section id="ui-config" class="rounded-3xl border border-slate-800 bg-slate-900/70 p-8">
<h2 class="text-2xl font-bold text-white">ui-config.example</h2>
<p class="mt-3 text-sm leading-7 text-slate-300">Per la login view e altre immagini UI, la sorgente deve stare qui o in renderer config, non hardcoded nei componenti.</p>
<div class="mt-5 rounded-2xl border border-slate-800 bg-slate-950/60 p-5">
<h3 class="font-semibold text-white">Login view</h3>
<ul class="mt-3 space-y-2 text-sm leading-7 text-slate-300">
<li><code>loginview.images.background</code></li>
<li><code>loginview.images.drape</code></li>
<li><code>loginview.images.left</code></li>
<li><code>loginview.images.right</code></li>
<li><code>loginview.widgets</code> per i blocchi promozionali</li>
</ul>
</div>
</section>
<section id="runtime-code" class="rounded-3xl border border-slate-800 bg-slate-900/70 p-8">
<h2 class="text-2xl font-bold text-white">Codice runtime coinvolto</h2>
<div class="mt-5 grid gap-4 md:grid-cols-2">
<div class="rounded-2xl border border-slate-800 bg-slate-950/60 p-5">
<h3 class="font-semibold text-white"><code>src/bootstrap.ts</code></h3>
<p class="mt-3 text-sm leading-7 text-slate-300">Legge <code>client-mode</code>, costruisce <code>NitroConfig['config.urls']</code> e prepara il bootstrap del client.</p>
</div>
<div class="rounded-2xl border border-slate-800 bg-slate-950/60 p-5">
<h3 class="font-semibold text-white"><code>src/secure-assets.ts</code></h3>
<p class="mt-3 text-sm leading-7 text-slate-300">Gestisce ECDH, decrypt/encrypt, fallback plain e secure API runtime.</p>
</div>
<div class="rounded-2xl border border-slate-800 bg-slate-950/60 p-5">
<h3 class="font-semibold text-white"><code>scripts/write-asset-loader.mjs</code></h3>
<p class="mt-3 text-sm leading-7 text-slate-300">Genera <code>public/configuration/asset-loader.js</code> e decide se usare file plain o <code>.dat</code>.</p>
</div>
<div class="rounded-2xl border border-slate-800 bg-slate-950/60 p-5">
<h3 class="font-semibold text-white"><code>scripts/minify-dist.mjs</code></h3>
<p class="mt-3 text-sm leading-7 text-slate-300">Genera i <code>.dat</code> ma mantiene anche i file plain per il toggle runtime.</p>
</div>
</div>
</section>
<section id="emulator" class="rounded-3xl border border-slate-800 bg-slate-900/70 p-8">
<h2 class="text-2xl font-bold text-white">Emulatore</h2>
<pre class="mt-5 overflow-x-auto rounded-2xl border border-slate-800 bg-slate-950/90 p-5 text-sm text-emerald-300"><code>nitro.secure.assets.enabled=true
nitro.secure.api.enabled=true
nitro.secure.config.root=C:/path/to/Nitro-V3/public
nitro.secure.gamedata.root=C:/path/to/gamedata
nitro.secure.master_key=change-me-to-a-long-random-secret</code></pre>
<ul class="mt-5 space-y-2 text-sm leading-7 text-slate-300">
<li><code>nitro.secure.assets.enabled</code>: abilita <code>/nitro-sec/bootstrap</code> e <code>/nitro-sec/file</code></li>
<li><code>nitro.secure.api.enabled</code>: abilita la cifratura su <code>/api/*</code></li>
<li><code>nitro.secure.config.root</code>: cartella dei config live</li>
<li><code>nitro.secure.gamedata.root</code>: cartella del gamedata live</li>
<li><code>nitro.secure.master_key</code>: chiave persistente server-side</li>
</ul>
</section>
<section id="scenarios" class="rounded-3xl border border-slate-800 bg-slate-900/70 p-8">
<h2 class="text-2xl font-bold text-white">Scenari rapidi</h2>
<div class="mt-5 grid gap-4 md:grid-cols-3">
<div class="rounded-2xl border border-cyan-500/20 bg-cyan-500/10 p-5">
<h3 class="font-semibold text-cyan-200">Tutto attivo</h3>
<p class="mt-3 text-sm leading-7 text-cyan-50/90">Secure assets, secure API e dist obfuscation tutti attivi.</p>
</div>
<div class="rounded-2xl border border-emerald-500/20 bg-emerald-500/10 p-5">
<h3 class="font-semibold text-emerald-200">Solo .dat</h3>
<p class="mt-3 text-sm leading-7 text-emerald-50/90">Usi i <code>.dat</code>, ma lasci config/API in plain.</p>
</div>
<div class="rounded-2xl border border-slate-700 bg-slate-950/60 p-5">
<h3 class="font-semibold text-white">Tutto plain</h3>
<p class="mt-3 text-sm leading-7 text-slate-300">Modalità fallback completa per debug o test locali.</p>
</div>
</div>
</section>
<section id="checklist" class="rounded-3xl border border-slate-800 bg-slate-900/70 p-8">
<h2 class="text-2xl font-bold text-white">Checklist finale</h2>
<div class="mt-5 grid gap-3">
<div class="rounded-2xl border border-slate-800 bg-slate-950/60 px-5 py-4 text-sm text-slate-300">Hai creato i file reali partendo da <code>client-mode.example</code>, <code>renderer-config.example</code> e <code>ui-config.example</code></div>
<div class="rounded-2xl border border-slate-800 bg-slate-950/60 px-5 py-4 text-sm text-slate-300">Gli URL pubblici stanno nei file config, non nei componenti React</div>
<div class="rounded-2xl border border-slate-800 bg-slate-950/60 px-5 py-4 text-sm text-slate-300">Hai deployato sia i file plain sia i <code>.dat</code></div>
<div class="rounded-2xl border border-slate-800 bg-slate-950/60 px-5 py-4 text-sm text-slate-300">Il server espone correttamente il MIME type per <code>.dat</code></div>
<div class="rounded-2xl border border-slate-800 bg-slate-950/60 px-5 py-4 text-sm text-slate-300">Hai impostato <code>nitro.secure.master_key</code> lato emulatore</div>
</div>
</section>
</main>
</div>
</div>
</body>
</html>
+23 -21
View File
@@ -3,11 +3,11 @@
Questa doc riassume tutti i dati da impostare per:
- offuscamento bundle `dist` (`app.js` / `app.css``.dat`)
- secure assets runtime (`renderer-config.json`, `ui-config.json`, `gamedata`)
- secure assets runtime (`configuration/renderer-config.json`, `configuration/ui-config.json`, `gamedata`)
- secure API runtime (`/api/*`)
- fallback plain quando vuoi spegnere tutto senza togliere il codice
## 1. `Nitro-V3/public/client-mode.json`
## 1. `Nitro-V3/public/configuration/client-mode.json`
Questo file controlla tutto a runtime.
@@ -17,7 +17,7 @@ Questo file controlla tutto a runtime.
"secureAssetsEnabled": true,
"secureApiEnabled": true,
"apiBaseUrl": "https://nitro.example.com:2096",
"plainConfigBaseUrl": "https://hotel.example.com/",
"plainConfigBaseUrl": "https://hotel.example.com/configuration/",
"plainGamedataBaseUrl": "https://hotel.example.com/client/nitro/gamedata/"
}
```
@@ -30,7 +30,7 @@ Questo file controlla tutto a runtime.
- `secureAssetsEnabled`
- `true`: `bootstrap.ts` e `secure-assets.ts` usano `/nitro-sec/file`
- `false`: `renderer-config.json`, `ui-config.json` e gamedata vengono letti in plain
- `false`: `configuration/renderer-config.json`, `configuration/ui-config.json` e gamedata vengono letti in plain
- `secureApiEnabled`
- `true`: il wrapper `fetch` cifra le chiamate `/api/*`
@@ -43,7 +43,7 @@ Questo file controlla tutto a runtime.
- `plainConfigBaseUrl`
- base URL dei file config plain
- normalmente: `https://hotel.example.com/`
- normalmente: `https://hotel.example.com/configuration/`
- `plainGamedataBaseUrl`
- base URL del gamedata plain
@@ -74,7 +74,7 @@ Il fallback attuale è:
(window as any).NitroSecureApiUrl = clientMode.apiBaseUrl || 'https://nitro.example.com:2096/';
```
Quindi in produzione conviene sempre valorizzare `apiBaseUrl` dentro `client-mode.json`.
Quindi in produzione conviene sempre valorizzare `apiBaseUrl` dentro `configuration/client-mode.json`.
## 3. `Nitro-V3/src/secure-assets.ts`
@@ -95,7 +95,7 @@ Qui vive tutta la logica runtime:
Normalmente non serve toccarlo, a meno che tu non voglia cambiare il protocollo secure.
## 4. `Nitro-V3/public/renderer-config.json`
## 4. `Nitro-V3/public/configuration/renderer-config.json`
Questo file continua a definire i path usati dal renderer.
@@ -129,7 +129,7 @@ Conviene usare i path plain classici, per esempio:
oppure lasciare il renderer configurato com’è e demandare il fallback a `secure-assets.ts`.
## 5. `Nitro-V3/public/ui-config.json`
## 5. `Nitro-V3/public/configuration/ui-config.json`
Qui non c’è logica secure, ma è uno dei file caricati da `config.urls`.
@@ -140,12 +140,12 @@ Quindi basta mantenerlo corretto come contenuto, non serve altro.
## 6. `Nitro-V3/scripts/write-asset-loader.mjs`
Questo script genera `public/asset-loader.js`.
Questo script genera `public/configuration/asset-loader.js`.
### Cosa fa ora
- mostra la shell iniziale
- legge `client-mode.json`
- legge `configuration/client-mode.json`
- decide se caricare:
- `app.css.dat` / `app.js.dat`
- oppure `assets/app.css` / `assets/app.js`
@@ -194,7 +194,7 @@ nitro.secure.master_key=change-me-to-a-long-random-secret
- abilita il layer secure per `/api/*`
- `nitro.secure.config.root`
- cartella dove leggere `renderer-config.json` e `ui-config.json`
- cartella dove leggere `configuration/renderer-config.json` e `configuration/ui-config.json`
- `nitro.secure.gamedata.root`
- cartella dove leggere il gamedata live
@@ -207,7 +207,7 @@ nitro.secure.master_key=change-me-to-a-long-random-secret
### Tutto attivo
`client-mode.json`
`configuration/client-mode.json`
```json
{
@@ -215,7 +215,7 @@ nitro.secure.master_key=change-me-to-a-long-random-secret
"secureAssetsEnabled": true,
"secureApiEnabled": true,
"apiBaseUrl": "https://nitro.example.com:2096",
"plainConfigBaseUrl": "https://hotel.example.com/",
"plainConfigBaseUrl": "https://hotel.example.com/configuration/",
"plainGamedataBaseUrl": "https://hotel.example.com/client/nitro/gamedata/"
}
```
@@ -232,7 +232,7 @@ nitro.secure.master_key=una-chiave-lunga-random
### Solo `.dat`, senza secure assets/api
`client-mode.json`
`configuration/client-mode.json`
```json
{
@@ -240,7 +240,7 @@ nitro.secure.master_key=una-chiave-lunga-random
"secureAssetsEnabled": false,
"secureApiEnabled": false,
"apiBaseUrl": "https://nitro.example.com:2096",
"plainConfigBaseUrl": "https://hotel.example.com/",
"plainConfigBaseUrl": "https://hotel.example.com/configuration/",
"plainGamedataBaseUrl": "https://hotel.example.com/client/nitro/gamedata/"
}
```
@@ -254,7 +254,7 @@ nitro.secure.api.enabled=false
### Tutto plain
`client-mode.json`
`configuration/client-mode.json`
```json
{
@@ -262,7 +262,7 @@ nitro.secure.api.enabled=false
"secureAssetsEnabled": false,
"secureApiEnabled": false,
"apiBaseUrl": "https://nitro.example.com:2096",
"plainConfigBaseUrl": "https://hotel.example.com/",
"plainConfigBaseUrl": "https://hotel.example.com/configuration/",
"plainGamedataBaseUrl": "https://hotel.example.com/client/nitro/gamedata/"
}
```
@@ -273,9 +273,9 @@ nitro.secure.api.enabled=false
Per cambiare:
- `client-mode.json`
- `renderer-config.json`
- `ui-config.json`
- `configuration/client-mode.json`
- `configuration/renderer-config.json`
- `configuration/ui-config.json`
- gamedata live
- `config.ini`
@@ -298,10 +298,12 @@ Per usare bene i toggle:
## 12. Checklist veloce
- `client-mode.json` configurato
- `configuration/client-mode.json` configurato
- `apiBaseUrl` corretto
- `nitro.secure.master_key` valorizzata
- `nitro.secure.config.root` corretto
- `nitro.secure.gamedata.root` corretto
- `.dat` e file plain entrambi deployati
- MIME `.dat` presente sul web server