# Malice

Malice is a hosted Matrix client with a Rust backend built on macltok and a
Svelte frontend. The Nix package serves both the API and the built frontend.

## NixOS module

Add this repository to your NixOS flake inputs, then include its module:

```nix
# In your flake.nix
inputs.malice.url = "git+file:///absolute/path/to/malice";

# In the modules list for your nixosSystem:
malice.nixosModules.default
```

Use a published Git URL instead of the local path if you deploy from another
machine. For a local Git flake, add new source files to Git before rebuilding;
Nix does not include untracked files.

Enable the service in your NixOS configuration. For access from another machine,
put it behind an HTTPS reverse proxy; the service binds to localhost and uses
Secure session cookies by default:

```nix
{
  services.malice.enable = true;
  # Optional: services.malice.port = 3000;

  services.nginx.enable = true;
  networking.firewall.allowedTCPPorts = [ 80 443 ];
  services.nginx.virtualHosts."chat.example.org" = {
    enableACME = true;
    forceSSL = true;
    locations."/" = {
      proxyPass = "http://127.0.0.1:3000";
      extraConfig = ''
        proxy_set_header Host $host;
        proxy_buffering off; # Keep event-stream updates timely.
      '';
    };
  };
  security.acme.acceptTerms = true;
  security.acme.defaults.email = "you@example.org";
}
```

Replace the domain and ACME email, then rebuild your NixOS configuration as
usual. Check `systemctl status malice` and visit `https://chat.example.org/`.
The module stores the master key and sessions in `/var/lib/malice`; back up that
entire directory together. Its `listenAddress`, `port`, `package`, and
`openFirewall` options can be overridden. Do not expose the HTTP listener
without a trusted TLS proxy.

## Client behavior

The home list shows non-space rooms (channels); Matrix spaces have their own
navigation and show their advertised child rooms. A Matrix homeserver is the
network address used at sign-in, not a space. Sending a message returns a queued
command, then the timeline shows whether delivery is queued, sending, confirmed
by the server, or failed. Opening a room loads its timeline; scrolling up loads
older history. Images and avatars are served through authenticated, bounded
media endpoints; SVG content is not rendered. Link previews use URL text only
and do not fetch third-party pages.

The Security panel accepts incoming device-verification requests and supports
emoji/number comparison, confirmation, rejection, and recovery-key entry.
Recovery keys and encryption state are per Matrix account; preserve the local
session data when migrating an installation.

## Development

From the repository root:

```sh
nix develop
npm --prefix web ci
```

For live frontend changes, start these in separate terminals inside `nix develop`:

```sh
MALICE_SESSION_COOKIE_SECURE=false cargo run --bin malice
npm --prefix web run dev
```

Open `http://127.0.0.1:5173/`. Vite proxies `/api` to the Rust server on port
3000. The cookie override is for local HTTP development only. By default,
Malice accepts HTTPS homeservers; set `MALICE_ALLOW_HTTP_HOMESERVER=true` only
when testing against a trusted local HTTP homeserver.

To serve the built frontend directly from Rust instead of using Vite:

```sh
npm --prefix web run build
MALICE_SESSION_COOKIE_SECURE=false cargo run --bin malice
```

Open `http://127.0.0.1:3000/`. Rust uses `web/dist` unless `MALICE_WEB_DIR`
points at another built frontend directory. Local session data defaults to
`local-data/`; set `MALICE_DATA_DIR` to use another directory. Keep its
`master.key` and session files private.

## Testing

In `nix develop`, after `npm --prefix web ci`:

```sh
cargo fmt -- --check
cargo clippy --all-targets -- -D warnings
cargo test --all-targets
npm --prefix web exec -- tsc --noEmit -p web/tsconfig.json
npm --prefix web run build
```

The Rust integration test uses a mocked Matrix homeserver; it does not require
live account credentials. To verify the deployable package and NixOS module:

```sh
nix build .#server
nix flake check
```

`nix build` creates `result/bin/malice` with the frontend bundled. On a NixOS
host, `curl -fsS http://127.0.0.1:3000/api/health` checks the local backend;
opening the proxied URL checks the frontend and TLS setup.
