OAC Wiki

Getting started, server setup, and website development (Java WebPages + Lua)

Wiki tree

Use this as a map. Every node below links to a detailed section.

1) Getting started

Choose what you want to do: operate servers (INS/WebServer) or build a website (Java WebPages + Lua).

INS Operator WebServer Operator Java WebPages Lua (FX Client)

1.1 Prerequisites

  • OpenSSL (certificate generation)
  • For INS: MySQL/MariaDB compatible database
  • Download archive (contains SQL + start scripts)
  • For FX clients: JavaFX WebView (WebEngine DOM) no JavaScript

1.2 Downloads & start scripts

The download archive includes .sh (Linux) and .bat (Windows) scripts for execution.

Important: Missing certificates or wrong certificate filenames are the most common cause of startup errors.

2) Server setup

Server setup is split into a global TLS section and per-server setup (INS, WebServer).

2.1 Certificates (Root-CA + Server)

Certificates are required for secure communication in OAC. You generate a Root-CA and then generate server certificates based on it.

Security: Keep *.key files private. Distribute only Root-CA *.pem to clients.

2.1.1 Folder layout

certificates/
  ca/      # Root-CA (.pem) must exist on server AND client
  key/     # Server private key (.key)
  server/  # Server certificate (.crt)

2.2 INS Server

INS requires a database, INS-specific certificate naming, and an INS config.properties. The download contains the SQL file and start scripts (.sh/.bat).

2.2.1 Database

Import the SQL file from the download into your DB. Then configure DB credentials via config.properties.

2.2.2 INS certificates (naming rules)

Create Root-CA (INS)

openssl genrsa -out myCA.key 4096
openssl req -x509 -new -nodes -key myCA.key -sha256 -days 3650 -out myCA.pem

myCA.key = private Key for CA (keep secret)
myCA.pem = public Root-Certificate for signing server and client certificates

Required filenames: ca_ins_[public ip].[extension]

# Example for public IP 203.0.113.10
ca_ins_203.0.113.10.key
ca_ins_203.0.113.10.pem

Create Server Certificate based on Root-CA (INS)

openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr
openssl x509 -req -in server.csr -CA myCA.pem -CAkey myCA.key -CAcreateserial -out server.crt -days 825 -sha256

server.key = private Key for Server
server.crt = Server-Certificate signed by Root-CA

Required filenames: cert_ins_[public ip].[extension]

# Example for public IP 203.0.113.10
cert_ins_203.0.113.10.key
cert_ins_203.0.113.10.crt
Placement:
Root-CA → certificates/ca
Server key → certificates/key
Server cert → certificates/server

2.2.3 config.properties

Generated on first run. Fill it like this:

db.password=DB PASSWORT
db.url=jdbc:mysql://localhost:3306/DATABASE?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
db.user=USER
ins.frontend=INS FRONTEND SITE (HOST) # Erreichbar über register.oac
ins.info=INS INFO SITE (HOST) # Erreichbar über info.oac
port.tcp=1026
port.udp=1025

2.3 WebServer

WebServer uses a config.properties and access control via rules.ini + auth.ini.

2.3.1 config.properties

#Sun Jan 18 21:55:38 UTC 2026
maxuploadmb=1024 # max upload in mb
port.tcp=1028
port.udp=1027
sessionexpiremin=1000 #session expiration in min

2.3.2 rules.ini (allow/deny/auth)

{
  "allow": [
    "index.html",
    "css/*",
    "private/info.php"
  ],
  "deny": [
    "private/*"
  ],
  "auth": [
    "private/*",
    "admin/*"
  ]
}

2.3.3 auth.ini (users/hashes)

admin:5e884898da28047151d0e56f8dc6292773603d0d6aabbddab8f91d8e5f99f6c7
user:e99a18c428cb38d5f260853678922e03abd8335f

3) Website development

Websites are built with Java WebPages (server-side rendering) and Lua (client-side behavior).

Client rule: JavaScript is not executed. All client-side behavior is implemented in Lua.

3.1 Java WebPages

Every page implements WebPage and is mapped via @Route(path="/..."). The handler receives WebPageContext (client, request, session, params, hasher).

3.1.1 Routing (@Route)

@Retention(RUNTIME)
@Target(TYPE)
public @interface Route {
  String path(); // must start with '/'
}

3.1.2 WebPageContext

Context fields:

  • client (ConnectedWebClient)
  • request (WebRequestPacket)
  • session (SessionContext)
  • params (RequestParams)
  • hasher (WebHasher)

3.1.3 RequestParams

Reads parameters from request headers (case-insensitive) and can hash values:

String user = ctx.params.getTrimmed("user");
String sha = ctx.params.getSha256Hex(ctx.hasher, "user");

3.1.4 SessionContext

if (ctx.session.isValid()) {
  String user = ctx.session.getUser();
  String sessionId = ctx.session.getSessionId();
}

3.1.5 Html helpers

String body = "<h1>" + Html.esc("Hello") + "</h1>";
String html = Html.page("Title", body);
byte[] bytes = Html.utf8(html);

3.1.6 HttpsProxy

WebResponsePacket resp = HttpsProxy.proxyGet(ctx, "https://example.com/");
Limitation: No URL rewriting for HTML/CSS subresources.

3.1.7 ContentTypeResolver

String ct = ContentTypeResolver.resolve("index.html"); // text/html
boolean img = ContentTypeResolver.isImage("logo.png");

Files like .js, .ts, .php, .py, .java are served as text/plain.

3.2 LuaScript (FX / no JavaScript / no jsoup)

The client executes Lua from standard HTML <script> tags. JavaScript is disabled and is never evaluated.

Important change: The client treats <script> as Lua. You do not need type="lua". The previous type-based detection is replaced.
Compatibility: If your page contains JavaScript <script> blocks, they will not run and may break behavior. Use Lua for client logic.

3.2.1 Script tags & bootstrap

Two forms are supported:

  • Inline: Lua code is read from the script element text content.
  • External: Lua is loaded via src using the client ResourceHost.
<!-- Inline Lua -->
<script>
console.log.info("hello from lua")
</script>

<!-- External Lua (loaded by the client via ResourceHost) -->
<script src="/scripts/app.lua"></script>
Rule: The client reads src by itself (no JavaScript, no browser fetch logic). You control how/where scripts are allowed to load in your ResourceHost.

3.2.2 DOM access (dom.*)

DOM access is backed by the JavaFX WebView DOM (WebEngine.getDocument() / W3C DOM). jsoup is not used.

  • Element identity is the HTML attribute id.
  • Missing ids are auto-assigned (__auto_*) so every element is addressable.
  • Query helpers: by tag / by class, parent/children traversal, attributes and text content.
Note: Without JavaScript, features like innerHTML/classList/computed styles are not standard W3C DOM APIs. Use ui.* helpers for common UI mutations.

3.2.3 Events (on:* + events.*)

Auto-binding via DOM attributes:

<button id="saveBtn" on:click="handlers.save">Save</button>

<script>
handlers = {}

function handlers.save(e)
  console.log.info("clicked: " .. e.target)
end
</script>

Manual binding via API:

<script>
handlers = {}

events.on("saveBtn", "click", "handlers.save")
events.onGlobal("ready", "handlers.ready")
</script>
Event payload: handlers receive a Lua table e with e.target, e.type and e.data.

3.2.4 UI (ui.*)

<script>
ui.alert("Hello OAC")
ui.setText("title", "Updated title")
ui.addClass("box", "active")
ui.setStyle("box", "opacity", "0.9")
</script>

3.2.5 Security policy

Default UI policy:
- timeout: 50ms
- instructionLimit: 200_000
- hookStep: 5_000
Sandbox: recommended to disable os, io, debug, luajava, and module loading (package/require/loadfile/dofile) in production clients.

3.2.6 FX notes (threading & limitations)

  • Threading: DOM reads/writes must happen on the JavaFX Application Thread.
  • Lua execution: Lua runs guarded on a dedicated thread (timeout + instruction budget).
  • Bridging: Event callbacks must forward into Lua via the router (host → LuaEventRouter).
  • No JS: do not rely on browser JS features (fetch, DOM APIs exposed only to JS, etc.).
Rule of thumb: UI/DOM mutations should go through ui.* and dom.*, not through JavaScript attributes or JS libraries.

4) Conventions & INS

OAC relies on consistent hostnames and dedicated pages for discovery and trust.

4.1 Info pages (info.<tld>)

For every website operator: each InfoName needs an info page reachable via info.<top level name>.

Example: If the top-level name is example, the info page must be available at info.example.

5) FAQ

Why is JavaScript not executed?

OAC does not execute JS. Client-side behavior is implemented in Lua only.

Do I need type="lua" for scripts?

No. The FX client executes Lua from standard <script> tags. Use src for external Lua files.

Why was jsoup removed?

DOM access is now backed by JavaFX WebView DOM (W3C DOM). This removes the need for jsoup and avoids parsing mismatches.

What breaks TLS setup most often?

Wrong filenames or wrong folder placement. Follow the naming formats exactly.

Do I need an info page for my InfoName?

Yes. Each InfoName should expose an info page reachable via info.<top level name>.