# Web Interface (/cweb)

Built-in web panel with no external dependencies: `/cweb` creates a personal one-time link, in the browser the player manages homes, claims, jobs, teams, warps and economy. No login, no password; the player must stay online during the session.

## Commands & permissions

| Command | Syntax | Permission | Default | Description |
|---|---|---|---|---|
| `/cweb` | `/cweb` | `mira.web.use` | `true` | Creates/renews the personal one-time link |

| Additional permissions | Default | Description |
|---|---|---|
| `mira.web.category.homes` / `claims` / `jobs` / `teams` / `warps` / `economy` / `inventory` / `profile` / `shops` | `true` | Shows the respective category |
| `mira.web.category.moderation` / `admin` | op | Staff categories Moderation and Admin (deliberately not part of `mira.web.*`) |
| `mira.web.cooldown.bypass` | op | Bypass the link cooldown |

## Layout

The category list sits on the left, the selected page on the right. On phones the bar sits at the bottom; it shows the first categories directly and opens a list of every area behind **More**, grouped like the sidebar. The categories are grouped the same way as this wiki: Teleportation (homes, warps), Economy & Jobs (balance, shops, jobs), Claims, Teams & Chat (teams, profile), World & Utility (inventory) and the staff area (moderation, admin, only visible with the right permissions). Each group carries its wiki color, which tints the whole panel, so it is obvious where you are. Larger categories are split into sections shown as tabs above the content; on phones they sit as a grid. The selected page is part of the address (`#teams/members`), so the back button and a reload land in the same place; the back button walks through the categories you visited. Messages (success, errors, hints) appear as dismissable notifications in the bottom right and never block the page; only the end of the session is a fixed screen. The panel follows the browser language: English and German are built in, other languages fall back to English.

**Teams** is split into four sections instead of one long list:

| Section | Content |
|---|---|
| Overview | Team bank (deposit and withdraw), level progress with a bar and the level-up, member preview, allies |
| Members | Invite, assign rank, promote, demote, kick, ban; ban list; full rank management with the permission grid |
| Assets | Land claims with the block pool and purchases, containers, shops, team warps |
| Settings | Name, tag, color, description, open team, friendly fire and the danger zone (transfer ownership, leave the team) |

Above all of it sits a team card with name, tag, level, your rank and the key numbers, tinted in the team color.

## How it works

The link is single-use and expires after `link-expiry-seconds`; a new `/cweb` ends the old session. Opening the link shows a small page that redeems it, so link previews in chat apps cannot burn it. Everything in the browser is display only: only on **Apply** does the server verify every change live against permissions, team ranks, balance and cooldowns and saves it only on success (multiple changes are checked individually, one failure does not discard the others). Staged changes survive switching between categories until they are applied or discarded; each apply has an upper limit per kind of change (for example 10 moderation actions), which the panel shows while staging. If the server does not answer in time, everything stays staged and applying again never repeats what already went through. The session ends after `session-timeout-minutes` of inactivity or when the player leaves the server. The web server is protected against request floods with rate limiting.

**Categories:** homes (view, rename, delete, see blocked worlds; setting only ingame), claims (view, abandon, manage trust for players, public or [group], buy and sell claim blocks, switch claim flags such as explosions or public access, view and restrict subclaims, hand your own claims to the team, buy or rent admin plots for the team, accept or decline handback requests from the team owner; giving pets away stays ingame (/givepet) because the animal has to be clicked; needs the [claim module](claim-overview.md) on), jobs (levels, earnings, quests, top lists with a job filter, active boosts, point shop: purchases land in the inventory on apply), teams (see the layout above; team warps can be renamed, given an icon by item id and a description, switched in visibility and deleted, all by team rank, including team creation under the same rules as ingame; without a team you can accept or decline invitations and join open teams, with a team request, accept and dissolve alliances, remove the team home and, as owner, disband the team after typing its name), warps (manage the public list: rename, icon by item id like `cobblestone`, description, category, delete, buy sponsor slots for your own warps; creating and moving happens ingame on purpose because the position comes from the player), economy (balance, look up other balances, paged top list, `/pay`), inventory (apply and remove cosmetics, overview of cosmetics still locked), profile (set and remove your nickname, your own join and leave messages, toggle teleport requests and mobs riding along, manage ignored players), shops (your chest shops and the shops of your team: change the price, switch between selling and buying, remove a shop; creating one stays ingame with a sign on the chest).

**Staff area:** With the permission `mira.web.category.moderation` (default: op only, deliberately not part of `mira.web.*`) the Moderation category appears: online list with server load, player details and warning history, active bans, IP bans, mutes and jail entries with forms to set and lift them. Every action additionally needs the matching `mod.*` node and takes effect on apply; online players get kicked or teleported like with the command. Jail positions and vanish stay ingame. With `mira.web.category.admin` (also op by default) the Admin category is added: server status with module overview and reload, broadcast, look up and change other balances (`economy.admin`), set and reset nicknames (`nick.admin`), remove group spawns (`spawn.admin`), and time, weather and gamerules per world (`world.time`, `world.weather`, `world.gamerules`), team administration like /teama (members, ranks, owner, name, description, tag, color, score, treasury, disband after typing the name; `team.admin.*`) and jobs administration like /jobsa (join, level, XP, points, earning limit, quests, admin boosts; `jobs.admin.*`), claim administration (global claim list with owner filter, delete, transfer, adjust block accounts; `mira.claim.deleteclaims`, `mira.claim.transferclaim`, `mira.claim.adjustclaimblocks`) and holograms (edit, add and remove lines, delete a hologram; `holo.edit`, `holo.delete`; creating and moving stays ingame).

## Setup on public servers

Locally `/cweb` works instantly on `http://localhost:8196`. Publicly, set the `public-url` once:

1. Open `plugins/Mira/modules/websession.yml` and set `public-url` to your IP/domain (without `http://`).
2. Open port 8196 (TCP) in your firewall/host panel.
3. Restart or `/mira reload`; the log must show your address in `[WebSession] /cweb links will use: http://...`.

For HTTPS: reverse proxy (nginx/Caddy) on 443, `bind-address: "127.0.0.1"`, `public-url: "https://panel.yourserver.com"`, `behind-proxy: true`. If your host does not allow extra ports, set `websession.enabled: false` so players do not get dead links.

## Configuration (modules/websession.yml)

```yaml
# Enables or disables the web interface module.
enabled: true

websession:
  # Web interface individually toggleable.
  enabled: true
  # Port of the embedded HTTP server.
  port: 8196
  # Bind address. 127.0.0.1 for reverse proxy setups.
  bind-address: "0.0.0.0"
  # Address in the links. IP/domain is enough (http:// and port are
  # added), full URLs like https://... are used unchanged.
  # Required on public servers, otherwise links point to localhost.
  public-url: ""
  # Trust X-Forwarded headers (ONLY behind a reverse proxy).
  behind-proxy: false
  # Seconds an unused link stays valid.
  link-expiry-seconds: 300
  # Cooldown for NEW links; a still-valid link is reused.
  # Bypass: mira.web.cooldown.bypass.
  command-cooldown-seconds: 10
  # Session ends after N minutes of browser inactivity.
  session-timeout-minutes: 20
  # Optional website link in the panel footer.
  website-url: ""
```

## Troubleshooting

| Problem | Cause | Fix |
|---|---|---|
| Link shows `localhost` | `public-url` empty or in the wrong file | Set it in `modules/websession.yml` (not `config.yml`), reload, check the log |
| Link loads forever | Port not reachable | Open port 8196 (TCP) |
| "Web interface not available" | Module off or port taken | `websession.enabled: true`; check the log for `Could not start web server` |
| "Link expired" | Older than 5 minutes or already used | Type `/cweb` again |
| Session ends suddenly | Player offline or inactivity | Connect and run `/cweb` again |
| Category missing | Permission missing or module disabled | Grant `mira.web.category.<name>`, enable the module |
| "CSRF failure" | Cookie/browser problem | Clear cache, open a new link |
| Rate limit blocks | Too many requests/failures | Wait 10 minutes |

## Complete example config

```yaml
enabled: true

websession:
  enabled: true
  port: 8196
  bind-address: "127.0.0.1"
  public-url: "https://panel.myserver.com"
  behind-proxy: true
  link-expiry-seconds: 180
  command-cooldown-seconds: 30
  session-timeout-minutes: 15
  website-url: "https://myserver.com"
```
