Adiciona autenticação opcional, VNC integrado, GPU por stream, proxy HLS e melhorias de segurança
---
- Adicionado sistema de autenticação opcional via AUTH_USER/AUTH_PASS: middleware Next.js, página de login, cookie rolling de
30 dias, timingSafeEqual para comparação segura de credenciais;
- Adicionado proxy HLS em /api/hls/[...path] que roteia para localhost:8888 internamente; player e player-static atualizados
para usar a rota proxy;
- Adicionada página /vnc/[id] integrada na UI (iframe + botão Back com auto-hide), substituindo abertura em nova aba;
- Adicionado campo gpu: boolean por stream; controlado via {{GPU_FLAGS}} no template do Chromium e no reprovision.mjs;
- Ajustado delay da primeira thumbnail para stream.delay + 60 para garantir conclusão do autologin antes da captura;
- Atualizado docker-compose.yml: porta 6080 vinculada a localhost, portas 1935 e 8888 comentadas por padrão;
- Traduzidos todos os comentários de código do português para o inglês;
- Adicionado crédito riguetto.dev no header com underline no hover;
- README e CLAUDE.md atualizados com arquitetura, portas e features corretas;
---
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
// Edge-compatible — no Node.js imports here (used in middleware)
|
||||
|
||||
export const AUTH_ENABLED = !!(process.env.AUTH_USER && process.env.AUTH_PASS)
|
||||
export const COOKIE_NAME = "ds_session"
|
||||
|
||||
// HMAC-SHA256(user, key=pass) — deterministic, no in-memory state, survives restarts
|
||||
// Works in both Edge (SubtleCrypto) and Node.js runtime
|
||||
export async function computeSessionToken(): Promise<string> {
|
||||
const user = process.env.AUTH_USER ?? ""
|
||||
const pass = process.env.AUTH_PASS ?? ""
|
||||
const enc = new TextEncoder()
|
||||
const key = await globalThis.crypto.subtle.importKey(
|
||||
"raw", enc.encode(pass),
|
||||
{ name: "HMAC", hash: "SHA-256" },
|
||||
false, ["sign"]
|
||||
)
|
||||
const sig = await globalThis.crypto.subtle.sign("HMAC", key, enc.encode(user))
|
||||
return Array.from(new Uint8Array(sig), b => b.toString(16).padStart(2, "0")).join("")
|
||||
}
|
||||
+2
-2
@@ -13,7 +13,7 @@ function ensureFile() {
|
||||
export function readStreams(): Stream[] {
|
||||
ensureFile()
|
||||
const streams = JSON.parse(fs.readFileSync(STREAMS_FILE, "utf-8")) as Stream[]
|
||||
// migrate: assign order to streams that don't have it yet
|
||||
// migration: assign order to streams that don't have it yet
|
||||
let dirty = false
|
||||
streams.forEach((s, i) => {
|
||||
if (s.order === undefined) { s.order = i; dirty = true }
|
||||
@@ -43,7 +43,7 @@ export function deleteStream(id: string): void {
|
||||
writeStreams(readStreams().filter((s) => s.id !== id))
|
||||
}
|
||||
|
||||
// Aloca display, portas VNC, noVNC e debug sem conflito com streams existentes
|
||||
// Allocates display number and VNC/debug ports without conflicting with existing streams
|
||||
export function allocatePorts(): {
|
||||
display: string
|
||||
vncPort: number
|
||||
|
||||
@@ -25,16 +25,16 @@ function supervisorctl(cmd: string) {
|
||||
try {
|
||||
execSync(`supervisorctl -c /etc/supervisor/supervisord.conf ${cmd}`, { stdio: "pipe" })
|
||||
} catch {
|
||||
// supervisorctl retorna exit 1 em alguns casos não-fatais
|
||||
// supervisorctl returns exit 1 in some non-fatal cases
|
||||
}
|
||||
}
|
||||
|
||||
// #6 — converte "1920x1080" → "1920,1080" para o Chrome
|
||||
// converts "1920x1080" → "1920,1080" for Chrome --window-size flag
|
||||
function resolutionToChrome(res: string): string {
|
||||
return res.replace("x", ",")
|
||||
}
|
||||
|
||||
// #13 — normaliza scale: aceita "1280x720" ou "1280:720", sempre salva "1280:720"
|
||||
// normalizes scale: accepts "1280x720" or "1280:720", always saves as "1280:720"
|
||||
export function normalizeScale(scale: string): string {
|
||||
return scale.replace("x", ":")
|
||||
}
|
||||
@@ -63,6 +63,7 @@ export function provisionStream(stream: Stream): void {
|
||||
THREADS: stream.threads ?? 0,
|
||||
USER: stream.user ?? "",
|
||||
PASS: stream.pass ?? "",
|
||||
GPU_FLAGS: stream.gpu ? "" : " --disable-gpu \\\n",
|
||||
}
|
||||
|
||||
const confTpl = fs.readFileSync("/opt/scripts/stream.template.conf", "utf-8")
|
||||
|
||||
Reference in New Issue
Block a user