first commit
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
# 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.
|
||||
Viittaa uudesa ongelmassa
Block a user