From 3c905a10cceb682d89fd1ef0586d43a166749cf9 Mon Sep 17 00:00:00 2001 From: Distronode <254259913+distronode-com@users.noreply.github.com> Date: Wed, 16 Sep 2026 20:04:09 -0400 Subject: [PATCH] docs: say who can connect an unpublished Zoom app, and what to do otherwise MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Settings → Zoom told operators they could keep the Zoom app unpublished because "your own team's Zoom users can still connect". Read in Calnode, "team" means the people on the Members page, and that is not what Zoom allows: an unpublished General app can only be authorized by users inside the Zoom account that created it. A member with their own Zoom account is refused on marketplace.zoom.us/error before the request ever reaches /v1/zoom/callback, so nothing in Calnode can catch or explain it (#35). The settings step now says who can connect, and DEPLOY.md gains a Zoom section: the account rule, Zoom's three ways past it (bring hosts into the app's account, beta sharing, publishing) with Zoom's own limits and links, and the fallback that needs no Zoom app at all, a Zoom link on the event type, which mintMeetingLink already uses when a host has not connected. A troubleshooting row names the symptom. First run and Troubleshooting move to §9 and §10; nothing referred to them by number. Co-Authored-By: Claude Opus 5 (1M context) --- CHANGELOG.md | 9 +++++ DEPLOY.md | 39 ++++++++++++++++++- .../src/routes/settings/zoom/+page.svelte | 6 ++- 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f45a54ce..6d8f8a49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,15 @@ exact tag (`ghcr.io/calnode/calnode:0.1.0`) if you need stability between upgrad ## [Unreleased] +### Fixed +- **The Zoom setup text no longer promises that an unpublished app works for "your own + team".** Zoom only lets users inside the Zoom account that owns an unpublished app + authorize it, so a member with their own Zoom account was refused on a Zoom error page + that Calnode never sees. Settings → Zoom now says so, and `DEPLOY.md` gains a Zoom + section with Zoom's three ways around it (same account, beta sharing, publishing) and + the link-only fallback that needs no Zoom app. Answers + [#35](https://github.com/Calnode/calnode/issues/35). + ## [0.9.0] - 2026-09-10 ### Added diff --git a/DEPLOY.md b/DEPLOY.md index 3ad7cbb2..f45a1b4d 100644 --- a/DEPLOY.md +++ b/DEPLOY.md @@ -297,7 +297,41 @@ Full setup guide, including recording consent, the AI notetaker, and host contro --- -## 8. First run +## 8. Zoom meeting links + +Optional. With a Zoom app configured in **Settings → Zoom**, each host connects their own +Zoom account (Calendar page) and a Zoom-located booking gets a meeting minted under the +assigned host's account. The settings page shows the exact **Redirect URL** to register +(`https:///v1/zoom/callback`). + +**Who can connect depends on how the Zoom app is distributed, and that is Zoom's rule, +not Calnode's.** A Zoom **General app** that is not published to the Zoom App Marketplace +can only be authorized by users inside the Zoom account that created it. A member who signs +in with their own, separate Zoom account is refused by Zoom before the request ever reaches +Calnode (they land on a Marketplace "Something went wrong" page). Zoom offers three ways +around that, none of them a Calnode setting: + +- **Bring the hosts into your Zoom account.** Members of the app's own Zoom account can + connect an unpublished app. Joining puts their Zoom user under your account's + administration and licensing, so this suits a team that already shares one Zoom + account, not independent people. +- **Beta sharing.** On request, Zoom's review team can approve an authorization URL for + users outside your account: up to 100 of them for a user-level app, valid for 4 weeks + with two further 4-week extensions. It is a test channel, not a permanent one. +- **Publish the app** to the Zoom App Marketplace, which requires passing Zoom's app + review. + +Details: Zoom's [App distribution](https://developers.zoom.us/docs/distribute/) and +[Sharing private and beta apps](https://developers.zoom.us/docs/distribute/sharing-private-and-beta-apps/). + +If none of those fits, a Zoom-located event type still works without any Zoom app: set a +**Zoom link** on the event type and every booking carries that link (one link per event +type, so it suits a personal meeting room rather than a rotation of hosts). The built-in +video rooms (§7) need no per-host account at all. + +--- + +## 9. First run Open `https:///` → it redirects to `/admin/`. On a fresh database you'll be guided through **first-run setup** (create the owner account). Then: @@ -306,7 +340,7 @@ first event type + availability. --- -## 9. Troubleshooting +## 10. Troubleshooting | Symptom | Likely cause | |---|---| @@ -315,6 +349,7 @@ first event type + availability. | `ERR_CERT_COMMON_NAME_INVALID` on a new domain | Cert not issued yet — wait; ensure the DNS record is **DNS-only**, not proxied. | | 403 on admin actions behind a proxy | Proxy not forwarding the original `Host` header (CSRF same-origin check). | | OAuth `redirect_uri_mismatch` | Registered URI doesn't match `BASE_URL` + `/v1/...callback` exactly. | +| Connecting Zoom works for you but a member lands on Zoom's "Something went wrong" page | The Zoom app is unpublished and the member's Zoom account is not in the account that owns it (§8). | | Email `550 domain not verified` | From address domain isn't verified with your email provider. | | Logo broken in email when testing locally | Gmail's image proxy can't reach `localhost` — only loads from a public URL. | | Litestream `InvalidAccessKeyId` / 403, log shows `endpoint=""` | `LITESTREAM_ENDPOINT` unset (or the running build predates the endpoint/region config) → Litestream defaults to AWS. Set the **account** endpoint (no bucket) + `region=auto` for R2, and redeploy so the config is live. | diff --git a/frontend/src/routes/settings/zoom/+page.svelte b/frontend/src/routes/settings/zoom/+page.svelte index 8a9c4328..b4062c68 100644 --- a/frontend/src/routes/settings/zoom/+page.svelte +++ b/frontend/src/routes/settings/zoom/+page.svelte @@ -59,8 +59,10 @@
  • 2
    - Choose a General App (User-managed OAuth). You can keep it - unpublished — your own team's Zoom users can still connect. + Choose a General App (User-managed OAuth). While it is + unpublished, Zoom only lets users inside the Zoom account that owns + the app connect; hosts with their own separate Zoom accounts need a published app + (see DEPLOY.md, "Zoom meeting links").