Skip to content

feat(discord): hosted OAuth relay for secure credential management#76

Merged
tech-stack-studios merged 4 commits into
developfrom
feature/discord-rpc-migration
Jun 8, 2026
Merged

feat(discord): hosted OAuth relay for secure credential management#76
tech-stack-studios merged 4 commits into
developfrom
feature/discord-rpc-migration

Conversation

@tech-stack-studios

Copy link
Copy Markdown
Owner

Summary

Adds a zero-cost hosted OAuth relay (Cloudflare Worker + KV) so the Discord client secret and refresh tokens are stored server-side, not in local Stream Deck profiles.

Changes

  • discord-relay/ — New Cloudflare Worker relay scaffold:
    • worker.mjs — endpoints: POST /oauth/discord/exchange, /access, /revoke, GET /health
    • wrangler.toml — Wrangler deployment config (KV namespace binding, env vars)
    • README.md — deployment instructions and security notes
  • discord-rpc.cjs — Relay-aware exchangeAuthCode and refreshAccessToken with backward-compatible direct Discord fallback when no relay URL is configured
  • plugin.cjsrelayUrl, relayApiKey, relaySessionId added to settings; client secret and refresh token cleared from local settings after auth in hosted mode
  • inspector.html — New "Relay URL" and "Relay API Key" fields; client secret relabeled as legacy fallback; save/authorize/refresh respect relay-first flow
  • README.md and docs/installation-guide.md — Hosted relay quickstart docs added

Testing

  • 115/115 unit tests pass (npx vitest run)
  • test:local Napi abort is pre-existing (hardware not present in CI environment), confirmed by reproducing identically against pre-change state

What you need to deploy the relay

  1. Run wrangler login
  2. wrangler kv namespace create DISCORD_SESSIONS (and --preview)
  3. Paste KV IDs into discord-relay/wrangler.toml
  4. wrangler secret put DISCORD_CLIENT_SECRET
  5. wrangler secret put RELAY_API_KEY (optional but recommended)
  6. wrangler deploy
  7. Paste Worker URL into Discord inspector Relay URL field

Backward compatibility

Existing users with clientSecret in settings continue to work — relay is opt-in. Legacy direct exchange/refresh path remains intact.

tech-stack-studios and others added 4 commits June 4, 2026 10:22
- Add Cloudflare Worker relay scaffold (discord-relay/) with endpoints:
  POST /oauth/discord/exchange, /access, /revoke; GET /health
- Add relay-aware token exchange/refresh in discord-rpc.cjs with
  backward-compatible direct Discord fallback when no relay URL set
- Add relayUrl, relayApiKey, relaySessionId to plugin settings/auth flow;
  client secret and refresh token cleared from local settings in hosted mode
- Add Relay URL and Relay API Key fields to inspector UI; client secret
  relabeled as legacy fallback
- Document hosted relay quickstart in README and installation guide
- 115/115 unit tests pass; test:local crash is pre-existing (hardware absent)
@tech-stack-studios
tech-stack-studios merged commit e8fa483 into develop Jun 8, 2026
2 checks passed
tech-stack-studios added a commit that referenced this pull request Jun 8, 2026
* fix(obs-plugin): fix inspector→plugin message routing (#62)

Two bugs prevented the OBS inspector from ever receiving OBS data:

1. App.jsx forwarded sdpi:sendToPlugin with event name
   'sendToPropertyInspector' — the plugin only handles 'sendToPlugin'.
   Fixed the event name to 'sendToPlugin'.

2. plugin.cjs read msg.payload for the sendToPlugin handler, but
   main.cjs packs the payload into msg.settings. Fixed to msg.settings.

Combined effect: inspector sent getScenes/getInputs/etc. → messages
silently dropped → inspector never received OBS data → status stuck
on 'Connecting to OBS…' indefinitely despite WebSocket being up.

Fixes: OBS Scene (and all other OBS actions) now populate dropdowns
and show 'OBS connected' status correctly.

* chore: bump version to 0.0.1.9 [skip ci]

* fix(plugins): handle reinstall cleanly in installPlugin handler

Previously, reinstalling an already-installed plugin would start a
second process without stopping the first one (duplicate processes
sharing the same UUID key in pluginProcesses Map, old process leaked).

Now the handler stops and removes the existing plugin entry before
copying the new files, so reinstalling cleanly replaces the running
process. Also adds force:true to cp so files are always overwritten.

* chore: bump version to 0.0.1.10 [skip ci]

* feat: white transparent tray icon for Linux Mint (#63)

* chore: bump version to 0.0.1.11 [skip ci]

* feat: remove help/docs menu links until wiki pages exist (#64)

* chore: bump version to 0.0.1.12 [skip ci]

* docs: remove guide links; add prominent plugin install callout (#65)

* chore: bump version to 0.0.1.13 [skip ci]

* fix: Discord mute toggle fails on second press — use --name search for main window (#66)

* chore: bump version to 0.0.1.14 [skip ci]

* feat: add stress test functionality for Discord mute/unmute actions

* chore: bump version to 0.0.1.15 [skip ci]

* Add GNU General Public License v3

* chore: bump version to 0.0.1.16 [skip ci]

* fix: update license badge from Proprietary to GPL-3.0

* chore: bump version to 0.0.1.17 [skip ci]

* chore: rename GitHub owner from FritzBlignaut to tech-stack-studios (#68)

* chore: bump version to 0.0.1.18 [skip ci]

* chore: bump version to 1.0.0.0 [skip ci]

* chore(deps-dev): bump the dev-dependencies group with 4 updates

Bumps the dev-dependencies group with 4 updates: [electron](https://github.com/electron/electron), [eslint](https://github.com/eslint/eslint), [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) and [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest).


Updates `electron` from 42.2.0 to 42.3.1
- [Release notes](https://github.com/electron/electron/releases)
- [Commits](electron/electron@v42.2.0...v42.3.1)

Updates `eslint` from 10.4.0 to 10.4.1
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](eslint/eslint@v10.4.0...v10.4.1)

Updates `vite` from 8.0.14 to 8.0.16
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v8.0.16/packages/vite)

Updates `vitest` from 4.1.7 to 4.1.8
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.8/packages/vitest)

---
updated-dependencies:
- dependency-name: electron
  dependency-version: 42.3.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: eslint
  dependency-version: 10.4.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: vite
  dependency-version: 8.0.16
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: vitest
  dependency-version: 4.1.8
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump the production-dependencies group across 1 directory with 3 updates

Bumps the production-dependencies group with 3 updates in the / directory: [@elgato-stream-deck/node](https://github.com/Julusian/node-elgato-stream-deck/tree/HEAD/packages/node), [react](https://github.com/facebook/react/tree/HEAD/packages/react) and [react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom).


Updates `@elgato-stream-deck/node` from 7.6.2 to 7.6.3
- [Release notes](https://github.com/Julusian/node-elgato-stream-deck/releases)
- [Changelog](https://github.com/Julusian/node-elgato-stream-deck/blob/main/CHANGELOG.md)
- [Commits](https://github.com/Julusian/node-elgato-stream-deck/commits/v7.6.3/packages/node)

Updates `react` from 19.2.6 to 19.2.7
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v19.2.7/packages/react)

Updates `react-dom` from 19.2.6 to 19.2.7
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v19.2.7/packages/react-dom)

---
updated-dependencies:
- dependency-name: "@elgato-stream-deck/node"
  dependency-version: 7.6.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
- dependency-name: react
  dependency-version: 19.2.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
- dependency-name: react-dom
  dependency-version: 19.2.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore: update workflow and Discord RPC migration integration (#73)

* Feature/discord rpc migration (#75)

* chore: update workflow and Discord RPC migration integration

* fix(ci): stop pushing version bumps from protected branch workflows

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>

* feat(discord): hosted OAuth relay for secure credential management (#76)

* chore: update workflow and Discord RPC migration integration

* fix(ci): stop pushing version bumps from protected branch workflows

* feat(discord): add hosted OAuth relay for secure credential management

- Add Cloudflare Worker relay scaffold (discord-relay/) with endpoints:
  POST /oauth/discord/exchange, /access, /revoke; GET /health
- Add relay-aware token exchange/refresh in discord-rpc.cjs with
  backward-compatible direct Discord fallback when no relay URL set
- Add relayUrl, relayApiKey, relaySessionId to plugin settings/auth flow;
  client secret and refresh token cleared from local settings in hosted mode
- Add Relay URL and Relay API Key fields to inspector UI; client secret
  relabeled as legacy fallback
- Document hosted relay quickstart in README and installation guide
- 115/115 unit tests pass; test:local crash is pre-existing (hardware absent)

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>

* chore(deps-dev): bump the dev-dependencies group with 3 updates (#77)

Bumps the dev-dependencies group with 3 updates: [electron](https://github.com/electron/electron), [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) and [electron-builder](https://github.com/electron-userland/electron-builder/tree/HEAD/packages/electron-builder).


Updates `electron` from 42.3.1 to 42.3.3
- [Release notes](https://github.com/electron/electron/releases)
- [Commits](electron/electron@v42.3.1...v42.3.3)

Updates `@types/react` from 19.2.16 to 19.2.17
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

Updates `electron-builder` from 26.8.1 to 26.15.2
- [Release notes](https://github.com/electron-userland/electron-builder/releases)
- [Changelog](https://github.com/electron-userland/electron-builder/blob/master/packages/electron-builder/CHANGELOG.md)
- [Commits](https://github.com/electron-userland/electron-builder/commits/electron-builder@26.15.2/packages/electron-builder)

---
updated-dependencies:
- dependency-name: electron
  dependency-version: 42.3.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: "@types/react"
  dependency-version: 19.2.17
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: electron-builder
  dependency-version: 26.15.2
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* feat(discord): enhance local relay setup and configuration options (#79)

* chore: update workflow and Discord RPC migration integration

* fix(ci): stop pushing version bumps from protected branch workflows

* feat(discord): add hosted OAuth relay for secure credential management

- Add Cloudflare Worker relay scaffold (discord-relay/) with endpoints:
  POST /oauth/discord/exchange, /access, /revoke; GET /health
- Add relay-aware token exchange/refresh in discord-rpc.cjs with
  backward-compatible direct Discord fallback when no relay URL set
- Add relayUrl, relayApiKey, relaySessionId to plugin settings/auth flow;
  client secret and refresh token cleared from local settings in hosted mode
- Add Relay URL and Relay API Key fields to inspector UI; client secret
  relabeled as legacy fallback
- Document hosted relay quickstart in README and installation guide
- 115/115 unit tests pass; test:local crash is pre-existing (hardware absent)

* feat(discord): enhance local relay setup and configuration options

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants