mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-09 21:10:59 +00:00
Polar and Oura resolved their OAuth client id/secret from the server
environment only, forcing every user on a deploy to share one app. Both
now read per-user BYO keys first, falling back to the shared env app when
unset, mirroring the WHOOP and Fitbit model.
- Add DB-first-then-env resolvers in src/lib/{polar,oura}/credentials.ts,
encrypting the client id/secret at rest on User.
- Repoint the connect, callback, status routes and the Oura refresh path
to the user-scoped resolver.
- Add /api/{polar,oura}/credentials (GET/PUT/DELETE) with Zod-validated
input and userId narrowed from the session.
- Render an optional 'your OAuth app credentials' form on the Polar and
Oura cards; the status read exposes hasOwnCredentials for the saved
placeholder. Existing env-only deploys keep working unchanged.
- Cover both resolvers (DB hit, env fallback, no creds) and the card form
with unit tests; add the new strings across all six locales.
17 lines
641 B
TypeScript
17 lines
641 B
TypeScript
import { z } from "zod/v4";
|
|
|
|
/**
|
|
* Per-user Oura BYO-key credentials. Each self-hoster registers their own Oura
|
|
* app and pastes the client id/secret into Settings. Stored encrypted on
|
|
* `User`. When unset, the integration falls back to the shared env-configured
|
|
* OAuth app.
|
|
*/
|
|
export const ouraCredentialsSchema = z.object({
|
|
// Trimmed: a trailing space or newline from the portal's copy button reaches
|
|
// Oura verbatim and answers as "unknown client".
|
|
clientId: z.string().trim().min(1).max(200),
|
|
clientSecret: z.string().trim().min(1).max(200),
|
|
});
|
|
|
|
export type OuraCredentialsInput = z.infer<typeof ouraCredentialsSchema>;
|