diff --git a/.gitignore b/.gitignore index a25082e..3bf520c 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,6 @@ client/dist/ # Local planning scratch plans/ + +# Host-local notes +local/ diff --git a/README.md b/README.md index ddd56ca..093dfbb 100644 --- a/README.md +++ b/README.md @@ -40,8 +40,8 @@ Common server overrides: Use `deploy/README.md`. Summary: -1. Copy repo to `/home//chgrid`. -2. Build client and publish `client/dist/` to `/home//public_html/chgrid/`. +1. Copy repo to your server. +2. Build client and publish `client/dist/` to your web root/subdirectory. 3. Configure server `config.toml` and run it via `systemd`. 4. Add Apache `/ws` websocket proxy from `deploy/apache/chgrid-vhost-snippet.conf`. diff --git a/client/index.html b/client/index.html index fbe3787..f652c7e 100644 --- a/client/index.html +++ b/client/index.html @@ -46,6 +46,7 @@
+ diff --git a/client/public/version.js b/client/public/version.js index c74f6db..22b3f66 100644 --- a/client/public/version.js +++ b/client/public/version.js @@ -1,5 +1,5 @@ // Maintainer-controlled web client version. // Format: YYYY.MM.DD Rn (example: 2026.02.20 R2) -window.CHGRID_WEB_VERSION = "2026.02.25 R255"; +window.CHGRID_WEB_VERSION = "2026.02.25 R256"; // Optional display timezone for timestamps. Falls back to America/Detroit if unset/invalid. window.CHGRID_TIME_ZONE = "America/Detroit"; diff --git a/client/src/main.ts b/client/src/main.ts index ee0b19b..330e0d4 100644 --- a/client/src/main.ts +++ b/client/src/main.ts @@ -102,6 +102,7 @@ type Dom = { authPolicyHintRegister: HTMLParagraphElement; authSessionView: HTMLElement; authSessionText: HTMLParagraphElement; + authModeSeparator: HTMLElement; showRegisterButton: HTMLButtonElement; updatesSection: HTMLElement; updatesToggle: HTMLButtonElement; @@ -136,6 +137,7 @@ const dom: Dom = { authPolicyHintRegister: requiredById('authPolicyHintRegister'), authSessionView: requiredById('authSessionView'), authSessionText: requiredById('authSessionText'), + authModeSeparator: requiredById('authModeSeparator'), showRegisterButton: requiredById('showRegisterButton'), updatesSection: requiredById('updatesSection'), updatesToggle: requiredById('updatesToggle'), @@ -599,11 +601,13 @@ function updateConnectAvailability(): void { const label = sanitizeAuthUsername(authUsername) || 'current account'; dom.authSessionText.textContent = `Logged in as ${label}.`; dom.showRegisterButton.classList.add('hidden'); + dom.authModeSeparator.classList.add('hidden'); dom.loginView.classList.add('hidden'); dom.registerView.classList.add('hidden'); dom.authSessionView.classList.remove('hidden'); } else { dom.showRegisterButton.classList.remove('hidden'); + dom.authModeSeparator.classList.remove('hidden'); dom.showRegisterButton.textContent = authMode === 'login' ? 'Register' : 'Login'; dom.loginView.classList.toggle('hidden', authMode !== 'login'); dom.registerView.classList.toggle('hidden', authMode !== 'register'); @@ -1525,11 +1529,6 @@ function getConnectionFlowDeps(): ConnectFlowDeps { updateConnectAvailability, mediaIsConnecting: () => mediaSession.isConnecting(), mediaSetConnecting: (value) => mediaSession.setConnecting(value), - mediaCheckMicPermission: () => checkMicPermission(), - mediaPopulateAudioDevices: () => populateAudioDevices(), - mediaGetPreferredInputDeviceId: () => mediaSession.getPreferredInputDeviceId(), - mediaSetupLocalMedia: (audioDeviceId) => setupLocalMedia(audioDeviceId), - mediaDescribeError: (error) => describeMediaError(error), mediaStopLocalMedia: () => stopLocalMedia(), signalingConnect: (handler) => signaling.connect(handler as (message: IncomingMessage) => Promise), signalingSendAuth: () => sendAuthRequest(), @@ -1671,6 +1670,9 @@ async function onSignalingMessage(message: IncomingMessage): Promise { startHeartbeat(); } await onAppMessage(message); + if (message.type === 'welcome') { + void setupMediaAfterAuth(); + } itemBehaviorRegistry.onUseResultMessage(message); itemBehaviorRegistry.onWorldUpdate(); applyConfiguredPeerListenGains(); @@ -1685,6 +1687,28 @@ async function onSignalingMessage(message: IncomingMessage): Promise { } } +/** Requests microphone access and initializes local media after successful auth/welcome. */ +async function setupMediaAfterAuth(): Promise { + if (!state.running) return; + const canProceed = await checkMicPermission(); + if (!canProceed) { + setConnectionStatus('Microphone access is required.'); + return; + } + try { + await populateAudioDevices(); + if (dom.audioInputSelect.options.length === 0) { + setConnectionStatus('No audio input device found. Open Audio setup or connect a microphone.'); + return; + } + const inputDeviceId = dom.audioInputSelect.value || mediaSession.getPreferredInputDeviceId(); + await setupLocalMedia(inputDeviceId); + } catch (error) { + console.error(error); + setConnectionStatus(describeMediaError(error)); + } +} + /** Toggles local microphone track mute state. */ function toggleMute(): void { state.isMuted = !state.isMuted; diff --git a/client/src/session/connectionFlow.ts b/client/src/session/connectionFlow.ts index adf6964..ed7d23f 100644 --- a/client/src/session/connectionFlow.ts +++ b/client/src/session/connectionFlow.ts @@ -19,11 +19,6 @@ export type ConnectFlowDeps = { updateConnectAvailability: () => void; mediaIsConnecting: () => boolean; mediaSetConnecting: (value: boolean) => void; - mediaCheckMicPermission: () => Promise; - mediaPopulateAudioDevices: () => Promise; - mediaGetPreferredInputDeviceId: () => string; - mediaSetupLocalMedia: (audioDeviceId: string) => Promise; - mediaDescribeError: (error: unknown) => string; mediaStopLocalMedia: () => void; signalingConnect: (onMessage: (message: unknown) => Promise) => Promise; signalingSendAuth: () => void; @@ -36,7 +31,7 @@ export type ConnectFlowDeps = { }; /** - * Runs connect flow: preflight media setup, then signaling connect/auth. + * Runs connect flow: signaling connect/auth first, media setup after auth/welcome. */ export async function runConnectFlow(deps: ConnectFlowDeps): Promise { if (deps.mediaIsConnecting() || deps.state.running) { @@ -47,32 +42,6 @@ export async function runConnectFlow(deps: ConnectFlowDeps): Promise { deps.mediaSetConnecting(true); deps.updateConnectAvailability(); - const canProceed = await deps.mediaCheckMicPermission(); - if (!canProceed) { - deps.updateStatus('Microphone access is required.'); - deps.mediaSetConnecting(false); - deps.updateConnectAvailability(); - return; - } - - try { - await deps.mediaPopulateAudioDevices(); - if (deps.dom.audioInputSelect.options.length === 0) { - deps.updateStatus('No audio input device found. Open Settings or connect a microphone.'); - deps.mediaSetConnecting(false); - deps.updateConnectAvailability(); - return; - } - const inputDeviceId = deps.dom.audioInputSelect.value || deps.mediaGetPreferredInputDeviceId(); - await deps.mediaSetupLocalMedia(inputDeviceId); - } catch (error) { - console.error(error); - deps.updateStatus(deps.mediaDescribeError(error)); - deps.mediaSetConnecting(false); - deps.updateConnectAvailability(); - return; - } - try { await deps.signalingConnect(deps.onMessage); deps.signalingSendAuth(); diff --git a/client/src/styles.css b/client/src/styles.css index 633fbec..56437a7 100644 --- a/client/src/styles.css +++ b/client/src/styles.css @@ -77,6 +77,11 @@ body { justify-content: center; gap: 0.75rem; margin-bottom: 0.75rem; + align-items: center; +} + +#authModeSeparator { + color: #94a3b8; } .auth-panel { diff --git a/deploy/README.md b/deploy/README.md index b925da3..f074c05 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -1,256 +1,118 @@ # Deployment Guide -Target example: AlmaLinux/cPanel host with files under `/home/`. +This guide is intentionally host-agnostic. -## 1) Place project files -- Repo root: `/home//chgrid` +## 1) Choose Your Paths Once -## 2) Make deploy scripts executable (once) +Pick your own repo path, publish path, base URL path, and service name. + +Example values: ```bash -cd /home//chgrid -chmod +x deploy/scripts/*.sh +REPO_ROOT=/srv/chgrid +PUBLISH_DIR=/var/www/html/chgrid +BASE_PATH=/chgrid/ +UNIT_NAME=chat-grid.service ``` -## 3) Install server (uv) +Use your own paths for your host. -Verify server files first: +## 2) Install Server Runtime ```bash -ls -l /home//chgrid/server/pyproject.toml +cd "$REPO_ROOT" +./deploy/scripts/install_server.sh "$REPO_ROOT" ``` -Run install scripts from repo root (`/home//chgrid`), not from `server/`. +What this sets up: +- Python venv under `server/.venv` +- `server/config.toml` (if missing) +- `server/.env` with `CHGRID_AUTH_SECRET` (if missing) +- `server/run_server.sh` (loads `.env` and starts server) +- first-run admin bootstrap prompt (if no admin exists) + +## 3) Publish Client ```bash -cd /home//chgrid -./deploy/scripts/install_server.sh /home//chgrid +cd "$REPO_ROOT" +./deploy/scripts/deploy_client.sh "$REPO_ROOT" "$PUBLISH_DIR" "$BASE_PATH" ``` -Notes: -- Script defaults to Python `3.13` (`PYTHON_SPEC=3.13`). -- It reuses existing `.venv` instead of replacing it interactively. -- If you need to force a fresh 3.13 env: - - `rm -rf /home//chgrid/server/.venv` - - rerun `./deploy/scripts/install_server.sh /home//chgrid` - -This creates: -- `/home//chgrid/server/.venv` -- `/home//chgrid/server/config.toml` (if missing) -- `/home//chgrid/server/.env` with `CHGRID_AUTH_SECRET` (if missing) -- `/home//chgrid/server/run_server.sh` (loads `.env` then starts server) -- On first run only, if no admin exists, it prompts to create one immediately. - -Edit `/home//chgrid/server/config.toml`: -- `server.bind_ip = "127.0.0.1"` -- `server.port = 8765` -- `network.allow_insecure_ws = true` -- `tls.cert_file = ""` -- `tls.key_file = ""` -- `storage.state_file = "runtime/items.json"` -- `auth.db_file = "runtime/chatgrid.db"` - -If you skip first-run admin creation, run later: +## 4) Install/Reload Service Unit ```bash -cd /home//chgrid/server -source .env -.venv/bin/python main.py --config config.toml --bootstrap-admin +cd "$REPO_ROOT" +./deploy/scripts/install_service.sh "$REPO_ROOT" "$UNIT_NAME" ``` -## 4) Build and publish client +Service logs: ```bash -cd /home//chgrid -./deploy/scripts/deploy_client.sh /home//chgrid /home//public_html/chgrid /chgrid/ +journalctl -u "$UNIT_NAME" -f +tail -f "$REPO_ROOT/server/runtime/server.log" ``` -Notes: -- Third arg is Vite base path for production assets. -- For `https://example.com/chgrid/`, use `/chgrid/`. -- For site root deploy (`https://example.com/`), use `/`. -- Deploy script normalizes publish permissions to avoid shared-host PHP soft exceptions: - - directories `755` - - files `644` - -Shortcut (client deploy + service restart): +## 5) One-Command Update ```bash -cd /home//chgrid -./deploy/scripts/up.sh /home//chgrid /home//public_html/chgrid /chgrid/ +cd "$REPO_ROOT" +./deploy/scripts/up.sh "$REPO_ROOT" "$PUBLISH_DIR" "$BASE_PATH" "$UNIT_NAME" ``` -## 5) Install/restart signaling service (systemd) +## 6) Apache Websocket Proxy + +Install your vhost include from the provided snippet: ```bash -cd /home//chgrid -./deploy/scripts/install_service.sh /home//chgrid +cd "$REPO_ROOT" +./deploy/scripts/install_apache.sh "$REPO_ROOT" /path/to/apache/include/chgrid.conf ``` -Notes: -- Service startup uses `/home//chgrid/server/run_server.sh`, which sources local - `/home//chgrid/server/.env` before launching Python. +Expected proxy endpoint: -Logs: - -```bash -journalctl -u chat-grid.service -f -tail -f /home//chgrid/server/runtime/server.log +```apache +ProxyPass /ws ws://127.0.0.1:8765 +ProxyPassReverse /ws ws://127.0.0.1:8765 ``` -If you previously used `chgrid-signaling.service`, migrate once: +After Apache changes, reload Apache using your host's command. -```bash -sudo systemctl disable --now chgrid-signaling.service -sudo systemctl daemon-reload -``` +## 7) Optional HTTP Stream Relay -## 6) Apache websocket proxy - -Install using script: - -```bash -cd /home//chgrid -./deploy/scripts/install_apache.sh \ - /home//chgrid \ - /etc/apache2/conf.d/userdata/ssl/2_4//yourdomain.com/chgrid.conf -``` - -Notes: -- Replace `yourdomain.com` with your real domain. -- Script copies `deploy/apache/chgrid-vhost-snippet.conf`, runs `rebuildhttpdconf`, then restarts Apache via WHM restart command. -- Snippet now includes no-cache headers for `/chgrid/` and `/chgrid/index.html` so client updates are not stuck on stale HTML. -- `deploy_client.sh` also installs `/chgrid/.htaccess` from `deploy/apache/chgrid-public-htaccess` - to force no-cache on `index.html` and `version.js` in shared-host setups. - -## 7) Optional HTTPS relay for HTTP radio streams - -If stream sources are plain HTTP (for example ports `8000`, `8010`, `8020`, `8030`), add relays in: - -`/etc/apache2/conf.d/userdata/ssl/2_4//example.com/chgrid.conf` - -Example: +If you need HTTPS relays for plain HTTP streams, add vhost relays such as: ```apache ProxyPass /listen/8000/ http://127.0.0.1:8000/ ProxyPassReverse /listen/8000/ http://127.0.0.1:8000/ -ProxyPass /listen/8010/ http://127.0.0.1:8010/ -ProxyPassReverse /listen/8010/ http://127.0.0.1:8010/ -ProxyPass /listen/8020/ http://127.0.0.1:8020/ -ProxyPassReverse /listen/8020/ http://127.0.0.1:8020/ -ProxyPass /listen/8030/ http://127.0.0.1:8030/ -ProxyPassReverse /listen/8030/ http://127.0.0.1:8030/ ``` -Apply changes: +## 8) PHP Media Proxy -```bash -sudo /usr/local/cpanel/scripts/rebuildhttpdconf -sudo /usr/local/cpanel/scripts/restartsrv_httpd -``` +`deploy/php/media_proxy.php` is copied into your publish directory by `deploy_client.sh`. -Usage example in Chat Grid: -- `https://example.com/listen/8000/stream` - -## 8) PHP media proxy (Dropbox + HTTP stream passthrough) - -`deploy/php/media_proxy.php` is a lightweight same-origin proxy for stream URLs. - -It is auto-copied to your publish dir by `deploy_client.sh` (and `up.sh`), so after deploy it should be available at: - -- `https://example.com/chgrid/media_proxy.php` - -Use in Chat Grid `streamUrl`: +Use: ```text -https://example.com/chgrid/media_proxy.php?url= +https://example.com/chgrid/media_proxy.php?url=urlencoded_upstream_url ``` -Examples: - -- Dropbox: - `https://example.com/chgrid/media_proxy.php?url=https%3A%2F%2Fwww.dropbox.com%2Fscl%2Ffi%2Fa7s3n15bgj043rr54k3n9%2FMario-Hold-Music.mp3%3Frlkey%3Ddfr3dybr7s7nndudag0k8xflc%26dl%3D1` -- HTTP stream: - `https://example.com/chgrid/media_proxy.php?url=http%3A%2F%2Fstream.rpgamers.net%3A8000%2Frpgn` - -Troubleshooting checks: +## 9) Git Update Flow ```bash -curl -I "https://example.com/chgrid/media_proxy.php?url=https%3A%2F%2Fwww.dropbox.com%2Fscl%2Ffi%2Fa7s3n15bgj043rr54k3n9%2FMario-Hold-Music.mp3%3Frlkey%3Ddfr3dybr7s7nndudag0k8xflc%26dl%3D1" -curl -I "https://example.com/chgrid/media_proxy.php?url=http%3A%2F%2Fstream.rpgamers.net%3A8000%2Frpgn" -``` - -Optional hardening: - -- Set env var `CHGRID_MEDIA_PROXY_ALLOWLIST` (comma-separated hosts/suffixes) in Apache/PHP-FPM. - - Example: `dropbox.com,dropboxusercontent.com,stream.rpgamers.net` - -## 9) GitHub-based update flow - -Initial clone (one time): - -```bash -cd /home/ -git clone https://github.com/jage9/chat_grid.git chgrid -``` - -Update and redeploy: - -```bash -cd /home//chgrid +cd "$REPO_ROOT" git fetch origin git switch main git pull --ff-only origin main - -# Rebuild/publish web client -./deploy/scripts/deploy_client.sh /home//chgrid /home//public_html/chgrid /chgrid/ - -# Reconcile server env/deps (safe to rerun on updates) -./deploy/scripts/install_server.sh /home//chgrid - -# Restart signaling service -sudo systemctl restart chat-grid.service -journalctl -u chat-grid.service -n 50 --no-pager +./deploy/scripts/install_server.sh "$REPO_ROOT" +./deploy/scripts/up.sh "$REPO_ROOT" "$PUBLISH_DIR" "$BASE_PATH" "$UNIT_NAME" ``` -Typical quick update: - -```bash -cd /home//chgrid -./deploy/scripts/up.sh /home//chgrid /home//public_html/chgrid /chgrid/ -``` - -Notes: -- Run Apache install/reload steps again only if proxy config changed. -- If your checkout has local changes, stash or commit before `git pull`. -- For HTTPS GitHub auth, use your GitHub username plus a Personal Access Token (PAT) as the password. -- SSH key passphrases are only used for `git@github.com:` remotes, not `https://` remotes. - -## 10) Save GitHub PAT for HTTPS pulls/pushes - -Persistent storage (simple, plaintext in `~/.git-credentials`): +## 10) HTTPS Git Auth (PAT) ```bash git config --global credential.helper store ``` -Memory cache only (not persisted across reboot): - -```bash -git config --global credential.helper "cache --timeout=28800" -``` - -Then run one authenticated command and enter: -- Username: `jage9` +Then run one authenticated pull/push and enter: +- Username: your GitHub username - Password: your GitHub PAT - -```bash -cd /home//chgrid -git pull --ff-only origin main -``` - -If you saved the wrong token and need to re-enter it: - -```bash -printf "protocol=https\nhost=github.com\n" | git credential reject -``` diff --git a/local/bestmidi.md b/local/bestmidi.md deleted file mode 100644 index 6926e27..0000000 --- a/local/bestmidi.md +++ /dev/null @@ -1,256 +0,0 @@ -# Deployment Guide - -Target example: AlmaLinux/cPanel host with files under `/home/bestmidi`. - -## 1) Place project files -- Repo root: `/home/bestmidi/chgrid` - -## 2) Make deploy scripts executable (once) - -```bash -cd /home/bestmidi/chgrid -chmod +x deploy/scripts/*.sh -``` - -## 3) Install server (uv) - -Verify server files first: - -```bash -ls -l /home/bestmidi/chgrid/server/pyproject.toml -``` - -Run install scripts from repo root (`/home/bestmidi/chgrid`), not from `server/`. - -```bash -cd /home/bestmidi/chgrid -./deploy/scripts/install_server.sh /home/bestmidi/chgrid -``` - -Notes: -- Script defaults to Python `3.13` (`PYTHON_SPEC=3.13`). -- It reuses existing `.venv` instead of replacing it interactively. -- If you need to force a fresh 3.13 env: - - `rm -rf /home/bestmidi/chgrid/server/.venv` - - rerun `./deploy/scripts/install_server.sh /home/bestmidi/chgrid` - -This creates: -- `/home/bestmidi/chgrid/server/.venv` -- `/home/bestmidi/chgrid/server/config.toml` (if missing) -- `/home/bestmidi/chgrid/server/.env` with `CHGRID_AUTH_SECRET` (if missing) -- `/home/bestmidi/chgrid/server/run_server.sh` (loads `.env` then starts server) -- On first run only, if no admin exists, it prompts to create one immediately. - -Edit `/home/bestmidi/chgrid/server/config.toml`: -- `server.bind_ip = "127.0.0.1"` -- `server.port = 8765` -- `network.allow_insecure_ws = true` -- `tls.cert_file = ""` -- `tls.key_file = ""` -- `storage.state_file = "runtime/items.json"` -- `auth.db_file = "runtime/chatgrid.db"` - -If you skip first-run admin creation, run later: - -```bash -cd /home/bestmidi/chgrid/server -source .env -.venv/bin/python main.py --config config.toml --bootstrap-admin -``` - -## 4) Build and publish client - -```bash -cd /home/bestmidi/chgrid -./deploy/scripts/deploy_client.sh /home/bestmidi/chgrid /home/bestmidi/public_html/chgrid /chgrid/ -``` - -Notes: -- Third arg is Vite base path for production assets. -- For `https://bestmidi.com/chgrid/`, use `/chgrid/`. -- For site root deploy (`https://bestmidi.com/`), use `/`. -- Deploy script normalizes publish permissions to avoid shared-host PHP soft exceptions: - - directories `755` - - files `644` - -Shortcut (client deploy + service restart): - -```bash -cd /home/bestmidi/chgrid -./deploy/scripts/up.sh /home/bestmidi/chgrid /home/bestmidi/public_html/chgrid /chgrid/ -``` - -## 5) Install/restart signaling service (systemd) - -```bash -cd /home/bestmidi/chgrid -./deploy/scripts/install_service.sh /home/bestmidi/chgrid -``` - -Notes: -- Service startup uses `/home/bestmidi/chgrid/server/run_server.sh`, which sources local - `/home/bestmidi/chgrid/server/.env` before launching Python. - -Logs: - -```bash -journalctl -u chat-grid.service -f -tail -f /home/bestmidi/chgrid/server/runtime/server.log -``` - -If you previously used `chgrid-signaling.service`, migrate once: - -```bash -sudo systemctl disable --now chgrid-signaling.service -sudo systemctl daemon-reload -``` - -## 6) Apache websocket proxy - -Install using script: - -```bash -cd /home/bestmidi/chgrid -./deploy/scripts/install_apache.sh \ - /home/bestmidi/chgrid \ - /etc/apache2/conf.d/userdata/ssl/2_4/bestmidi/yourdomain.com/chgrid.conf -``` - -Notes: -- Replace `yourdomain.com` with your real domain. -- Script copies `deploy/apache/chgrid-vhost-snippet.conf`, runs `rebuildhttpdconf`, then restarts Apache via WHM restart command. -- Snippet now includes no-cache headers for `/chgrid/` and `/chgrid/index.html` so client updates are not stuck on stale HTML. -- `deploy_client.sh` also installs `/chgrid/.htaccess` from `deploy/apache/chgrid-public-htaccess` - to force no-cache on `index.html` and `version.js` in shared-host setups. - -## 7) Optional HTTPS relay for HTTP radio streams - -If stream sources are plain HTTP (for example ports `8000`, `8010`, `8020`, `8030`), add relays in: - -`/etc/apache2/conf.d/userdata/ssl/2_4/bestmidi/bestmidi.com/chgrid.conf` - -Example: - -```apache -ProxyPass /listen/8000/ http://127.0.0.1:8000/ -ProxyPassReverse /listen/8000/ http://127.0.0.1:8000/ -ProxyPass /listen/8010/ http://127.0.0.1:8010/ -ProxyPassReverse /listen/8010/ http://127.0.0.1:8010/ -ProxyPass /listen/8020/ http://127.0.0.1:8020/ -ProxyPassReverse /listen/8020/ http://127.0.0.1:8020/ -ProxyPass /listen/8030/ http://127.0.0.1:8030/ -ProxyPassReverse /listen/8030/ http://127.0.0.1:8030/ -``` - -Apply changes: - -```bash -sudo /usr/local/cpanel/scripts/rebuildhttpdconf -sudo /usr/local/cpanel/scripts/restartsrv_httpd -``` - -Usage example in Chat Grid: -- `https://bestmidi.com/listen/8000/stream` - -## 8) PHP media proxy (Dropbox + HTTP stream passthrough) - -`deploy/php/media_proxy.php` is a lightweight same-origin proxy for stream URLs. - -It is auto-copied to your publish dir by `deploy_client.sh` (and `up.sh`), so after deploy it should be available at: - -- `https://bestmidi.com/chgrid/media_proxy.php` - -Use in Chat Grid `streamUrl`: - -```text -https://bestmidi.com/chgrid/media_proxy.php?url= -``` - -Examples: - -- Dropbox: - `https://bestmidi.com/chgrid/media_proxy.php?url=https%3A%2F%2Fwww.dropbox.com%2Fscl%2Ffi%2Fa7s3n15bgj043rr54k3n9%2FMario-Hold-Music.mp3%3Frlkey%3Ddfr3dybr7s7nndudag0k8xflc%26dl%3D1` -- HTTP stream: - `https://bestmidi.com/chgrid/media_proxy.php?url=http%3A%2F%2Fstream.rpgamers.net%3A8000%2Frpgn` - -Troubleshooting checks: - -```bash -curl -I "https://bestmidi.com/chgrid/media_proxy.php?url=https%3A%2F%2Fwww.dropbox.com%2Fscl%2Ffi%2Fa7s3n15bgj043rr54k3n9%2FMario-Hold-Music.mp3%3Frlkey%3Ddfr3dybr7s7nndudag0k8xflc%26dl%3D1" -curl -I "https://bestmidi.com/chgrid/media_proxy.php?url=http%3A%2F%2Fstream.rpgamers.net%3A8000%2Frpgn" -``` - -Optional hardening: - -- Set env var `CHGRID_MEDIA_PROXY_ALLOWLIST` (comma-separated hosts/suffixes) in Apache/PHP-FPM. - - Example: `dropbox.com,dropboxusercontent.com,stream.rpgamers.net` - -## 9) GitHub-based update flow (`bestmidi`) - -Initial clone (one time): - -```bash -cd /home/bestmidi -git clone https://github.com/jage9/chat_grid.git chgrid -``` - -Update and redeploy: - -```bash -cd /home/bestmidi/chgrid -git fetch origin -git switch main -git pull --ff-only origin main - -# Rebuild/publish web client -./deploy/scripts/deploy_client.sh /home/bestmidi/chgrid /home/bestmidi/public_html/chgrid /chgrid/ - -# Reconcile server env/deps (safe to rerun on updates) -./deploy/scripts/install_server.sh /home/bestmidi/chgrid - -# Restart signaling service -sudo systemctl restart chat-grid.service -journalctl -u chat-grid.service -n 50 --no-pager -``` - -Typical quick update: - -```bash -cd /home/bestmidi/chgrid -./deploy/scripts/up.sh /home/bestmidi/chgrid /home/bestmidi/public_html/chgrid /chgrid/ -``` - -Notes: -- Run Apache install/reload steps again only if proxy config changed. -- If your checkout has local changes, stash or commit before `git pull`. -- For HTTPS GitHub auth, use your GitHub username plus a Personal Access Token (PAT) as the password. -- SSH key passphrases are only used for `git@github.com:` remotes, not `https://` remotes. - -## 10) Save GitHub PAT for HTTPS pulls/pushes - -Persistent storage (simple, plaintext in `~/.git-credentials`): - -```bash -git config --global credential.helper store -``` - -Memory cache only (not persisted across reboot): - -```bash -git config --global credential.helper "cache --timeout=28800" -``` - -Then run one authenticated command and enter: -- Username: `jage9` -- Password: your GitHub PAT - -```bash -cd /home/bestmidi/chgrid -git pull --ff-only origin main -``` - -If you saved the wrong token and need to re-enter it: - -```bash -printf "protocol=https\nhost=github.com\n" | git credential reject -```