mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-10 13:22:14 +00:00
fix(fitbit): correct the setup guide to the classic Fitbit Web API
The Fitbit integration connects through the classic Fitbit Web API, so a self-hoster registers a Fitbit developer app at dev.fitbit.com — but the setup guide walked users through creating a Google Cloud OAuth client, whose client id the Fitbit sign-in rejects (unauthorized_client). Rewrite the guide for the dev.fitbit.com flow (app type, HTTPS callback, scopes, PKCE), leave the old page as a pointer, and add a test that keeps the documented scopes and endpoints in sync with the client so the guide cannot drift from the code again. Flags the September 2026 sunset of the classic Fitbit Web API.
This commit is contained in:
1 parent
3bceb61aed
commit
46db21dbeb
4 files changed
+162
-77
No files matched your search
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
// v1.12.0 — Google Health (Fitbit & Pixel) card. Mirrors the WHOOP card: a
|
||||
// v1.12.0 — Fitbit (Fitbit & Pixel) card. Mirrors the WHOOP card: a
|
||||
// BYO-key credentials form first, then an OAuth connect, then the
|
||||
// sync/test/disconnect action row + parked-resume banner. v1.12.1 — status
|
||||
// reads off the consolidated /api/integrations/status envelope (the per-card
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
import { readFileSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { FITBIT_OAUTH_SCOPE } from "../client";
|
||||
|
||||
/**
|
||||
* Guard against the class of bug reported in #396: the setup docs drifting away
|
||||
* from what the code actually does. The Fitbit integration uses the CLASSIC
|
||||
* Fitbit Web API (an app from dev.fitbit.com), not a Google Cloud OAuth client —
|
||||
* a doc that says otherwise sends users to the wrong registry and fails with
|
||||
* `unauthorized_client — Invalid client_id`.
|
||||
*/
|
||||
const readDoc = (name: string): string =>
|
||||
readFileSync(join(process.cwd(), "docs", "integrations", name), "utf8");
|
||||
|
||||
describe("Fitbit setup docs stay in sync with the code", () => {
|
||||
const fitbitDoc = readDoc("fitbit.md");
|
||||
|
||||
it("documents every OAuth scope the client actually requests", () => {
|
||||
for (const scope of FITBIT_OAUTH_SCOPE.split(" ")) {
|
||||
expect(fitbitDoc).toContain(scope);
|
||||
}
|
||||
});
|
||||
|
||||
it("points at the classic Fitbit endpoints and dev.fitbit.com", () => {
|
||||
expect(fitbitDoc).toContain("dev.fitbit.com");
|
||||
expect(fitbitDoc).toContain("www.fitbit.com/oauth2/authorize");
|
||||
expect(fitbitDoc).toContain("api.fitbit.com/oauth2/token");
|
||||
expect(fitbitDoc).toContain("/api/fitbit/callback");
|
||||
});
|
||||
|
||||
it("never instructs the user to create a Google Cloud OAuth client (the #396 mistake)", () => {
|
||||
// The "do this" markers of the wrong walkthrough: the Google Cloud console
|
||||
// and the Google Health scope URLs. Mentioning `apps.googleusercontent.com`
|
||||
// as a "don't paste this" warning is allowed and intentional.
|
||||
expect(fitbitDoc).not.toContain("console.cloud.google");
|
||||
expect(fitbitDoc).not.toContain("googleapis.com/auth/googlehealth");
|
||||
});
|
||||
|
||||
it("keeps the old google-health page as a pointer to the Fitbit setup", () => {
|
||||
const legacy = readDoc("google-health.md");
|
||||
expect(legacy).toContain("fitbit.md");
|
||||
// The legacy page must not re-introduce the wrong Google Cloud walkthrough.
|
||||
expect(legacy).not.toContain("console.cloud.google");
|
||||
expect(legacy).not.toContain("googleapis.com/auth/googlehealth");
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user