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").