# Remote Access Platform — Alpha

A self-hostable remote support platform for IT teams: technicians log in to a web
console, see their team's machines, and start a screen-share + remote-control
session to any online machine after the end user grants consent. Built to the
spec in `PRD-remote-access-platform.md`.

This alpha implements the PRD's P0 requirements: authenticated console, **MFA**,
**RBAC**, **machine enrollment**, **per-session consent**, **WebRTC screen
streaming + remote input**, and an **immutable audit log**.

```
remote-access-app/
├── server/        Backend: HTTP API + WebSocket signaling + SQLite
│   ├── server.js  Auth, MFA, machines, audit API + signaling broker
│   ├── auth.js    scrypt passwords, TOTP MFA, tokens (no external auth deps)
│   ├── db.js      Schema via Node's built-in node:sqlite
│   ├── public/    Web console (index.html) + remote viewer (viewer.html)
│   └── test/e2e.js  26-check end-to-end test of the whole backend flow
└── agent/         Native host agent (Electron)
    ├── main.js          Consent window, screen source, OS input injection
    ├── input/inject.js  Mouse/keyboard injection via nut-js (Win32 SendInput)
    └── renderer/        Agent UI + WebRTC screen capture
```

## Quick start

### 1. Server (any OS, Node 22.5+)

```bash
cd server
npm install        # only dependency is `ws`
npm start          # serves http://localhost:8090
```

Open **http://localhost:8090**, click **Register team**, then set up MFA
(add the shown secret to Google Authenticator / Authy / 1Password and enter a code).
Log in, and enroll a machine — you'll get an `AGENT_ENROLL_TOKEN`.

### 2. Agent (on the Windows/macOS PC to be controlled)

```bash
cd agent
npm install                     # installs Electron + nut-js (input injection)
set SERVER_URL=http://<server-ip>:8090     # Windows
set AGENT_ENROLL_TOKEN=<token from console>
npm start
```

The agent window comes online; the machine shows green in the console.
Click **Connect** in the console — the agent shows a consent prompt. On **Allow**,
the technician sees the live screen and can control it. A red banner stays on the
host screen for the whole session, and every step is written to the audit log.

> Set a machine to **unattended** at enrollment to skip the consent prompt
> (for servers / headless machines), per the PRD's unattended-access policy.

## What's tested (in this sandbox)

```
cd server && npm test            # 26/26 checks pass
cd agent  && npm run test:input  # 5/5 input-mapping checks pass
```

The e2e test drives the real backend: register → enable MFA → login (password +
TOTP) → enroll machine → agent connects → technician requests session → consent →
SDP/ICE relay → session end → audit verification → consent-denial path.

## What requires real hardware (not testable in a headless sandbox)

- **OS input injection** runs through `nut-js` (Win32 `SendInput` on Windows,
  `CGEvent` on macOS). Without it installed, `inject.js` degrades to a safe
  logging no-op so the agent still runs. Verify on a real desktop.
- **Screen capture** uses Electron's `desktopCapturer` / `getDisplayMedia`.

## Architecture notes

- **Media is peer-to-peer.** The server only brokers signaling (SDP/ICE) and
  consent; screen frames and input never pass through it. Channels are
  DTLS-encrypted by WebRTC.
- **NAT traversal** uses a public STUN server. ~10–15% of connections behind
  symmetric NATs will need a **TURN relay** (coturn) — the next infra item.
- **Auth** uses scrypt password hashing and RFC-6238 TOTP, implemented on Node's
  built-in `crypto` — no `bcrypt`/`jsonwebtoken`/`speakeasy` dependencies.
- **Storage** is `node:sqlite` (built into Node 22.5+), so the backend has a
  single runtime dependency (`ws`).

## Gaps before production (from PRD §5)

1. **TURN relay** for non-P2P connections (coturn).
2. **macOS/Linux agents** + code-signed installers; packaged Windows binary.
3. **File transfer, clipboard sync, multi-monitor** (PRD P1).
4. **SSO, session recording, SOC 2** (PRD P1/T8).
5. Harden signaling: rate limiting, per-session authz checks, CSRF on cookie API.
