IC-Webhosting: Domaenen, Webseiten und Postfaecher ueber Anmeldungen
Ein IC-Hostinganbieter im Spiel. Er vergibt Domaenen, richtet je Domaene einen Zugang ein, und die Inhaber pflegen darauf ihre Webseite. Die gesamte Verwaltung haengt an einer Anmeldung, nicht an Job oder Serverrechten. Ein Zugang ist zugleich ein Postfach: wer sich anmeldet, bekommt das Postfach dieser Adresse. Mehrere Personen koennen denselben Zugang benutzen und dasselbe Postfach gleichzeitig offen haben - ein Firmenpostfach gehoert der Firma, nicht einer Person. Drei Ebenen: superadmin vergibt Domaenen und setzt je Domaene einen Admin ein admin pflegt die Seiten seiner Domaene und legt dort Zugaenge an editor pflegt nur die Seiten Seiteninhalte sind kein HTML, sondern typisierte Bloecke. Die Seiten werden im NUI des IC-Computers angezeigt, also im selben Kontext wie dieser selbst - wer dort Markup einschleusen kann, kann auch dessen Callbacks aufrufen. Ein Blockmodell schliesst das konstruktiv aus, statt es filtern zu muessen. Passwoerter liegen gesalzen und gehasht in der Datenbank, gerechnet wird in der Datenbank. Fuenf Fehlversuche je Benutzername sperren den Namen kurzzeitig. Enthaelt README.md mit Einrichtung und Anbindung an den IC-Computer sowie ANLEITUNG.md fuer die Bedienung im Spiel.
This commit is contained in:
commit
a2ce3a69fd
14 changed files with 3018 additions and 0 deletions
335
README.md
Normal file
335
README.md
Normal file
|
|
@ -0,0 +1,335 @@
|
|||
# ic-web — IC-Webhosting
|
||||
|
||||
Ein IC-Hostinganbieter: er vergibt Domänen, richtet je Domäne einen Zugang
|
||||
ein, und die Domäneninhaber pflegen darauf ihre Webseite und ihre Postfächer.
|
||||
Aufgerufen werden die Seiten im Browser von **pc-live** unter `ic://domäne`.
|
||||
|
||||
## Die drei Ebenen
|
||||
|
||||
| Rolle | Zugang | Darf |
|
||||
|---|---|---|
|
||||
| **Anbieter** (`superadmin`) | `admin@liveinvader.ls` | Domänen anlegen, übertragen, sperren, löschen; überall Zugänge und Seiten |
|
||||
| **Domänenadmin** (`admin`) | `<name>@<domäne>` | Seiten der eigenen Domäne pflegen, dort Zugänge anlegen und verwalten |
|
||||
| **Redakteur** (`editor`) | `<name>@<domäne>` | nur Seiten der eigenen Domäne pflegen |
|
||||
|
||||
Job und Serverrechte spielen keine Rolle. Wer den Zugang kennt, verwaltet die
|
||||
Seite — unabhängig davon, welchen Charakter er gerade spielt.
|
||||
|
||||
## Ein Zugang ist ein Postfach
|
||||
|
||||
`presse@weazel-news.ls` ist Benutzername, Passwort **und** Mailadresse in einem.
|
||||
Beim Anmelden wird der Zugriff auf das Postfach in `ic-mail` erteilt, beim
|
||||
Abmelden wieder entzogen. Deshalb können **mehrere Personen gleichzeitig
|
||||
dasselbe Postfach offen haben** — ein Firmenpostfach gehört der Firma, nicht
|
||||
einer Person.
|
||||
|
||||
Wird ein Zugang gelöscht, bleibt das Postfach mit seinen Nachrichten bestehen.
|
||||
|
||||
Aufgeräumt wird **beim Start**, nicht beim Herunterfahren: ic-web widerruft
|
||||
dann alle Postfachzugriffe, die es je erteilt hat (`granted_by = 'ic-web'`).
|
||||
Beim Stoppen ginge das nicht — der Aufruf nach ic-mail wartet auf eine
|
||||
Datenbankantwort, und eine wartende Koroutine lässt sich während des
|
||||
Herunterfahrens nicht mehr fortsetzen; der Server meldet dann
|
||||
„Execution of function reference in script host failed". Der Umweg über den
|
||||
Start deckt außerdem den Fall ab, den ein Stop-Handler nie erwischt: den
|
||||
Absturz.
|
||||
|
||||
## Postfächer im Mailclient
|
||||
|
||||
Der Mailclient von pc-live kann weitere Postfächer aufnehmen: *Postfächer →
|
||||
**+ Postfach hinzufügen*** fragt Adresse und Passwort ab — dieselbe Prüfung
|
||||
wie die Anmeldung, aber **ohne Verwaltungsrechte**. Man kann zehn Postfächer
|
||||
offen haben (`Config.MaxOpenMailboxes`) und trotzdem nur für eines Seiten
|
||||
pflegen dürfen.
|
||||
|
||||
Freigeschaltete Postfächer tragen ein ✕ zum Entfernen; das eigene und
|
||||
dienstlich zugewiesene nicht — die gehören einem nicht. Beim Verlassen des
|
||||
Servers werden alle wieder geschlossen, ebenso beim nächsten Start von ic-web.
|
||||
|
||||
Das Abmelden von der Verwaltung nimmt ein eigenständig geöffnetes Postfach
|
||||
nicht weg.
|
||||
|
||||
## Signaturen
|
||||
|
||||
Die Signatur gehört zum **Postfach**, nicht zur Person: eine Firmenadresse
|
||||
trägt dieselbe Fußzeile, egal wer sie gerade bedient. Ändern darf sie jeder mit
|
||||
Zugriff auf das Postfach (*Signatur* im Mailclient).
|
||||
|
||||
Beim Schreiben wird sie unter den Text gesetzt, getrennt durch eine Zeile mit
|
||||
`--`. Beim Wechsel des Absenders tauscht sie sich aus, der geschriebene Text
|
||||
bleibt stehen.
|
||||
|
||||
Gespeichert wird in `ic_mail_accounts.signature` (ic-mail, Migration
|
||||
`sql/migration_signaturen.sql`).
|
||||
|
||||
## Ordner je Postfach
|
||||
|
||||
Ordner gehören zum Postfach, nicht zur Person (`pc_live_mail_folders.address`,
|
||||
Migration `pc-live/sql/migration_postfach_ordner.sql`). Ein geteiltes Postfach
|
||||
hat für alle dieselbe Struktur.
|
||||
|
||||
Eine Mail an ein geteiltes Postfach wird je Empfänger einmal gespeichert. Damit
|
||||
das Einsortieren trotzdem für alle gilt, tragen alle Kopien einer Zustellung
|
||||
dieselbe `delivery_id`: wird eine Kopie verschoben, wandern die anderen mit.
|
||||
Gelesen und gelöscht bleibt persönlich — das ist keine Eigenschaft der
|
||||
Nachricht, sondern der Person.
|
||||
|
||||
Welches Postfach gemeint ist, schickt der Client mit; der Server prüft es über
|
||||
`ic-mail:CanAccessAddress` und fällt ohne Zugriff auf das persönliche Postfach
|
||||
zurück, statt fremde Ordner herauszugeben.
|
||||
|
||||
## Kalender
|
||||
|
||||
Dieselbe Mechanik wie bei Postfächern und Ordnern
|
||||
(`pc_live_calendar.address` + `visibility`, Migration
|
||||
`pc-live/sql/migration_kalender.sql`):
|
||||
|
||||
| Sichtbarkeit | gehört | sieht | bearbeitet |
|
||||
|---|---|---|---|
|
||||
| `private` | der Person | nur sie | nur sie |
|
||||
| `shared` | einem Postfach | wer es bedient | wer es bedient |
|
||||
| `public` | einem Postfach | jeder auf dem Server | wer es bedient |
|
||||
|
||||
Ein öffentlicher Termin hängt bewusst auch an einem Postfach — sonst gäbe es
|
||||
niemanden, der ihn später ändern oder absagen könnte. Wer ein Postfach bedient,
|
||||
darf dessen Termine auch dann ändern, wenn jemand anderes sie eingetragen hat;
|
||||
genau das macht sie geteilt.
|
||||
|
||||
Änderungen erreichen alle Beteiligten sofort, sonst hätte jeder eine andere
|
||||
Vorstellung vom Dienstplan, bis er den PC neu öffnet.
|
||||
|
||||
## Ablauf
|
||||
|
||||
1. Der Anbieter meldet sich in der App **Webhosting** mit `admin@liveinvader.ls`
|
||||
an (Startpasswort siehe unten) und ändert sein Passwort.
|
||||
2. Er legt unter *Verwaltung* eine Domäne an, wählt den Besitzer-Job und den
|
||||
ersten Zugang. Benutzername und Passwort werden **einmal** angezeigt.
|
||||
3. Der Domänenadmin meldet sich damit an, ändert sein Passwort und legt unter
|
||||
*Zugänge* weitere Zugänge für seine Leute an.
|
||||
4. Alle Zugänge dieser Domäne pflegen die Seiten unter *Meine Seite* und
|
||||
veröffentlichen sie.
|
||||
|
||||
## Ersteinrichtung
|
||||
|
||||
Beim ersten Start legt ic-web den Anbieterzugang aus `Config.MainAdmin` an und
|
||||
schreibt Benutzername und Startpasswort in die Serverkonsole. Vorgabe:
|
||||
|
||||
```
|
||||
admin@liveinvader.ls / liveinvader
|
||||
```
|
||||
|
||||
Beim ersten Anmelden wird zum Ändern aufgefordert.
|
||||
|
||||
Passwort vergessen? In der Serverkonsole:
|
||||
|
||||
```
|
||||
webpasswd admin@liveinvader.ls neues-passwort
|
||||
```
|
||||
|
||||
## Inhalte sind kein HTML
|
||||
|
||||
Seiten bestehen aus **typisierten Blöcken** (`shared/blocks.lua`), nicht aus
|
||||
Markup. Der Grund: die Seiten werden im NUI von pc-live angezeigt — im selben
|
||||
Kontext wie der PC selbst. Wer dort Markup einschleusen kann, kann auch dessen
|
||||
NUI-Callbacks aufrufen. Ein Blockmodell schließt das konstruktiv aus, statt es
|
||||
filtern zu müssen; HTML zu filtern ist ein Wettlauf, den man langfristig
|
||||
verliert.
|
||||
|
||||
`B.Validate` baut jeden Block aus dem Schema **neu auf**. Was nicht im Schema
|
||||
steht, fällt weg — es wird nicht bereinigt, sondern verworfen.
|
||||
|
||||
Blocktypen: `heading`, `text`, `image`, `list`, `button`, `contact`, `divider`.
|
||||
|
||||
Der Renderer in pc-live setzt Text ausschließlich über `textContent`, niemals
|
||||
über `innerHTML`. Deshalb bleiben `<` und `>` im Text erhalten statt
|
||||
verstümmelt zu werden.
|
||||
|
||||
## Domänennamen
|
||||
|
||||
Form: `name.endung`, nur Kleinbuchstaben, Ziffern und Bindestriche, 3–30
|
||||
Zeichen, Endung aus `Config.Domain.allowedTlds` (`.ls .sa .gov .org .net`).
|
||||
|
||||
`Config.Domain.reserved` sperrt Namen **nur gegen die Selbstanmeldung** — der
|
||||
Anbieter darf `lspd.ls` sehr wohl vergeben, dafür ist er da.
|
||||
|
||||
Unabhängig davon gesperrt sind Domänen des Mailsystems: existiert der Realm
|
||||
schon in ic-mail als `is_default`, `system` oder `citizen` (etwa `mail.ls`),
|
||||
lehnt `D.EnsureRealm` ab — für alle. Sonst hinge eine Firmenwebseite an der
|
||||
Domäne sämtlicher persönlicher Postfächer. Eine herrenlose *Firmen*-Domäne
|
||||
(`type = company`) wird dagegen übernommen.
|
||||
|
||||
## Bilder und Meldungen
|
||||
|
||||
Bilder werden extern verlinkt — NUI kann keine Dateien hochladen. Erlaubt sind
|
||||
nur `https` und die Hosts aus `Config.ImageHosts` (Subdomains eingeschlossen).
|
||||
Die Hostliste ist der Rahmen, die Meldefunktion fängt den Rest — sie greift
|
||||
aber erst nachträglich.
|
||||
|
||||
Jeder Spieler kann eine Seite melden (Link unten auf jeder Seite), einmal je
|
||||
Seite und Stunde. Der Anbieter sieht die Meldungen unter *Meldungen*.
|
||||
|
||||
## Passwörter
|
||||
|
||||
Gespeichert wird `SHA2(salt || passwort)`, gerechnet in der Datenbank — das
|
||||
Passwort läuft nur als Abfrageparameter durch den Server. Fünf Fehlversuche je
|
||||
Benutzername innerhalb von fünf Minuten sperren den Namen kurzzeitig
|
||||
(`Config.Login`).
|
||||
|
||||
Das ist ein **IC-Passwort**, keine Sicherheitsgrenze gegen Serveradmins: wer
|
||||
Datenbankzugriff hat, kann jeden Zugang zurücksetzen. Es verhindert, dass
|
||||
Mitspieler fremde Seiten ändern — nicht mehr.
|
||||
|
||||
## Installation
|
||||
|
||||
### 1. Ordner
|
||||
|
||||
Der Ordner `ic-web` gehört in dein Resource-Verzeichnis, zum Beispiel:
|
||||
|
||||
```
|
||||
resources/[haleoe]/ic-web/
|
||||
```
|
||||
|
||||
### 2. Datenbank
|
||||
|
||||
```bash
|
||||
mysql -u BENUTZER -p DATENBANK < sql/ic_web.sql
|
||||
```
|
||||
|
||||
Legt an: `ic_web_sites`, `ic_web_pages`, `ic_web_accounts`,
|
||||
`ic_web_login_fails`, `ic_web_reports`. Wiederholt ausführbar.
|
||||
|
||||
### 3. server.cfg
|
||||
|
||||
```
|
||||
ensure oxmysql
|
||||
ensure es_extended
|
||||
ensure ic-mail
|
||||
ensure ic-web # nach ic-mail
|
||||
```
|
||||
|
||||
Liegt alles in einem Ordner mit eckigen Klammern, genügt `ensure [haleoe]` —
|
||||
dann startet ic-web automatisch mit. Die Reihenfolge stimmt dabei von selbst,
|
||||
weil ic-mail alphabetisch vorher kommt.
|
||||
|
||||
### 4. Anbindung an pc-live
|
||||
|
||||
ic-web bringt keine eigene Oberfläche mit — sie sitzt im PC. Diese Dateien
|
||||
gehören nach `pc-live`:
|
||||
|
||||
| Datei | Ziel in pc-live | Zweck |
|
||||
|---|---|---|
|
||||
| `client/webhosting.lua` | `client/` | Brücke zwischen NUI und Server |
|
||||
| `nui/js/apps/webhosting.js` | `nui/js/apps/` | die App selbst |
|
||||
|
||||
Dazu in pc-live eintragen:
|
||||
|
||||
**`fxmanifest.lua`**
|
||||
```lua
|
||||
client_scripts { …, 'client/webhosting.lua' }
|
||||
files { …, 'nui/js/apps/webhosting.js' }
|
||||
```
|
||||
|
||||
**`nui/index.html`** — vor `desktop.js`, weil andere Apps den Dialogbaukasten
|
||||
daraus benutzen:
|
||||
```html
|
||||
<script src="js/apps/webhosting.js"></script>
|
||||
```
|
||||
|
||||
**`nui/js/desktop.js`** — App eintragen und den Antwortkanal anschließen:
|
||||
```js
|
||||
'pc.webhosting': { name: 'Webhosting', icon: '🌍', open: () => WebhostingApp.open() },
|
||||
…
|
||||
case 'icweb_response': ICWebNet.onResponse(data); break;
|
||||
```
|
||||
|
||||
**`server/apps.lua`** — damit die App auf dem Schreibtisch erscheint:
|
||||
```lua
|
||||
AppRegistry.Register({
|
||||
app_id = "pc.webhosting", name = "Webhosting", icon = "🌍",
|
||||
version = "1.0.0", category = "system", default = true,
|
||||
permissions = {}, dependencies = {}, price = 0,
|
||||
description = "IC-Domänen und Webseiten verwalten. Anmeldung erforderlich.",
|
||||
})
|
||||
```
|
||||
|
||||
**`nui/js/apps/browser.js`** — damit `ic://domäne.ls` im Browser aufgeht:
|
||||
der Zweig, der Adressen der Form `name.endung` an `ICWebNet.call('getSite', …)`
|
||||
gibt und mit `ICWebRender.renderPage` zeichnet.
|
||||
|
||||
### 5. Erste Anmeldung
|
||||
|
||||
Beim ersten Start legt ic-web den Anbieterzugang an und schreibt ihn in die
|
||||
Serverkonsole. Vorgabe: `admin@liveinvader.ls` / `liveinvader`. Beim ersten
|
||||
Anmelden wird ein eigenes Passwort verlangt.
|
||||
|
||||
## Voraussetzungen
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| `oxmysql` | Datenbankzugriff |
|
||||
| `es_extended` | Spielername, Jobliste, Benachrichtigungen |
|
||||
| `ic-mail` | Domänen und Postfächer. Fehlt es, laufen die Webseiten trotzdem – nur ohne Mailadressen |
|
||||
| `pc-live` | die Oberfläche |
|
||||
| `fmsdk` | Protokoll. Fehlt es, wird verworfen statt zu scheitern |
|
||||
|
||||
ic-mail braucht dafür sechs Exports, die dieses Projekt voraussetzt:
|
||||
`GetRealmByName`, `CreateRealm`, `EnsureSharedAddress`, `GrantAddressAccess`,
|
||||
`RevokeAddressAccess`, `RevokeAccessGrantedBy`.
|
||||
|
||||
## Selbstanmeldung (optional, aus)
|
||||
|
||||
`Config.SelfRegistration.enabled = true` erlaubt Behörden und Unternehmen, sich
|
||||
ohne Anbieter selbst eine Domäne zu holen — Grundlage ist dann der ESX-Job ab
|
||||
`minGrade`. Der Zugang wird dabei automatisch erzeugt und einmalig angezeigt.
|
||||
Standardmäßig aus, weil die Vergabe über den Anbieter läuft.
|
||||
|
||||
## Konsolenbefehle
|
||||
|
||||
Notbremse des Serverbetreibers, kein IC-Weg. Erlaubt sind Serverkonsole sowie
|
||||
ESX-Gruppe `admin`/`superadmin` bzw. ACE `ic_web.admin` (`Config.Console`).
|
||||
|
||||
| Befehl | Wirkung |
|
||||
|---|---|
|
||||
| `webpasswd <benutzer@domäne> <passwort>` | Passwort setzen |
|
||||
| `webaccounts` | alle Zugänge auflisten |
|
||||
| `webreports` | offene Meldungen |
|
||||
| `webblock <domäne>` | Seite sperren bzw. freigeben |
|
||||
| `webreport done\|dismiss <id>` | Meldung abschließen |
|
||||
|
||||
## Exports
|
||||
|
||||
```lua
|
||||
exports['ic-web']:GetSite(domain, slug) -- (seite, nil) oder (nil, fehlertext)
|
||||
exports['ic-web']:DomainExists(domain)
|
||||
exports['ic-web']:GetSitesForJob(job)
|
||||
exports['ic-web']:GetSession(src) -- wer ist an diesem PC angemeldet
|
||||
```
|
||||
|
||||
`ic-mail` wurde um vier Exports ergänzt, die ic-web benutzt:
|
||||
`EnsureSharedAddress`, `GrantAddressAccess`, `RevokeAddressAccess`,
|
||||
`DeleteAddress` — sowie `GetRealmByName` und `CreateRealm` für die Domänen.
|
||||
|
||||
## Netzwerkereignisse
|
||||
|
||||
Jedes Ereignis bekommt eine Anfrage-Id und antwortet über
|
||||
`ic-web:client:response` mit `{ ok, data, error }`. Alle sind gedrosselt;
|
||||
Rechte werden ausnahmslos serverseitig aus der Anmeldung abgeleitet.
|
||||
|
||||
Anmeldung: `login`, `logout`, `session`, `changePassword`.
|
||||
Seiten: `getSite`, `listMine`, `getEditable`, `savePage`, `deletePage`,
|
||||
`updateSite`, `report`.
|
||||
Zugänge: `listAccounts`, `createAccount`, `setAccountPassword`,
|
||||
`setAccountActive`, `setAccountRole`, `deleteAccount`.
|
||||
Anbieter: `adminListSites`, `adminListAccounts`, `adminListJobs`,
|
||||
`adminRegister`, `adminSetBlocked`, `adminSetOwner`, `adminDeleteSite`,
|
||||
`adminListReports`, `adminSetReportStatus`.
|
||||
|
||||
## Tabellen
|
||||
|
||||
`ic_web_sites`, `ic_web_pages`, `ic_web_accounts`, `ic_web_login_fails`,
|
||||
`ic_web_reports`.
|
||||
|
||||
Die Domäne wird über den **Namen** referenziert, nicht über einen
|
||||
Fremdschlüssel auf `ic_mail_realms` — Fremdschlüssel über Resource-Grenzen
|
||||
hinweg koppeln zwei Lebenszyklen aneinander, die unabhängig voneinander
|
||||
installiert werden.
|
||||
Loading…
Add table
Add a link
Reference in a new issue