ic-web/README.md
Bjoern Flessing a2ce3a69fd 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.
2026-08-09 11:50:53 +00:00

13 KiB
Raw Blame History

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, 330 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

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

client_scripts { , 'client/webhosting.lua' }
files          { , 'nui/js/apps/webhosting.js' }

nui/index.html — vor desktop.js, weil andere Apps den Dialogbaukasten daraus benutzen:

<script src="js/apps/webhosting.js"></script>

nui/js/desktop.js — App eintragen und den Antwortkanal anschließen:

'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:

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

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.