- Shipped
- September 5, 2026 at 6:31 AM UTC
- Author
- Kamo
- Commit
- a00ddbe
The per-member credential card had exactly one control: paste a RingCentral JWT. A RingCentral JWT is minted per user inside the developer console, by a user who has been granted access to it, so a card shaped this way tells an organization to create a developer key for every person who answers a phone. It reads as a required setup step too — "Not connected" on every member — when in truth only the in-browser softphone needs it, and an assigned extension already carries call history, voicemail, presence and forwarding. The card now leads with Connect RingCentral, the ordinary sign-in voipservice gained alongside this, and folds the JWT box away behind "Use a JWT credential instead" for the case it is actually right for: a service account nobody signs in as, or an app with only the JWT flow enabled. A connected member gets Reconnect and Disconnect, and a member connected by a pasted JWT is told so — that is the one credential somebody had to make by hand, so it is the one an admin may want to replace. The return-from-consent toast now serves both providers rather than naming Microsoft, and shows the server's own sentence when it sent one: a RingCentral refusal is nearly always a redirect URI the customer has not registered or an app without the auth-code flow, and neither is guessable from "connection failed". The phone server's own settings gained that redirect URI as a read-only field, fetched from the server rather than written in here — RingCentral compares it byte for byte and answers a mismatch with an opaque invalid_request, so a second copy of the string in the frontend is a copy that can be wrong. Tests render the card. The defect was never a rendering fault, but "which credential does this ask a member for" is exactly what the markup decides, so it is worth pinning: a sign-in offered first, no textarea until the fallback is opened, and no developer-console link in front of a member who cannot open one. vitest.config.ts collects app/settings tests so they run at all.