Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
39 changes: 37 additions & 2 deletions DEPLOY.md
Original file line number Diff line number Diff line change
Expand Up @@ -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://<your-domain>/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://<your-domain>/` → it redirects to `/admin/`. On a fresh database
you'll be guided through **first-run setup** (create the owner account). Then:
Expand All @@ -306,7 +340,7 @@ first event type + availability.

---

## 9. Troubleshooting
## 10. Troubleshooting

| Symptom | Likely cause |
|---|---|
Expand All @@ -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. |
6 changes: 4 additions & 2 deletions frontend/src/routes/settings/zoom/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,10 @@
<li class="flex gap-3">
<span class="flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-muted text-xs font-semibold text-muted-foreground">2</span>
<div>
Choose a <span class="font-medium">General App</span> (User-managed OAuth). You can keep it
unpublished — your own team's Zoom users can still connect.
Choose a <span class="font-medium">General App</span> (User-managed OAuth). While it is
unpublished, Zoom only lets users <span class="font-medium">inside the Zoom account that owns
the app</span> connect; hosts with their own separate Zoom accounts need a published app
(see DEPLOY.md, "Zoom meeting links").
</div>
</li>
<li class="flex gap-3">
Expand Down
Loading