fix(google-health): store the account's id, not the word "profile"

The profile's resource name is `users/{user}/profile`, and the connect
stored its last segment, the same constant for every account. Since the
one-account-per-record check, a second record on an instance could not
connect or reconnect Google Health: it was refused as `already_linked`.

The connect now stores the `{user}` segment, reads `users/me/identity`
when the profile answers through the `me` alias, and stores the id as
unknown when neither names the account. A migration makes the column
nullable and clears the placeholder, so the next connect stores the
real id.
This commit is contained in:
Marc-André Bombeck committed 2026-10-30 13:17:54 +01:00
1 parent 8f8f98eac7
commit cd6cbc06f5
8 files changed
+326 -27

No files matched your search

+2 -5
View File
@@ -9,10 +9,7 @@ import { verifyCallbackActor } from "@/lib/integrations/oauth-kit/connect-target
import { annotate, getEvent } from "@/lib/logging/context";
import { auditLog } from "@/lib/auth/audit";
import { encrypt } from "@/lib/crypto";
import {
fetchProfile,
resolveGoogleHealthUserId,
} from "@/lib/google-health/client";
import { fetchProfile, accountIdFor } from "@/lib/google-health/client";
import { googleHealthOAuth } from "@/lib/google-health/oauth";
import { getGoogleHealthScopeString } from "@/lib/google-health/oauth";
import { getUserGoogleHealthCredentials } from "@/lib/google-health/credentials";
@@ -179,7 +176,7 @@ export const GET = apiHandler(async (request: NextRequest) => {
}
const profile = await fetchProfile(tokens.access_token);
const googleUserId = resolveGoogleHealthUserId(profile);
const googleUserId = await accountIdFor(profile, tokens.access_token);
// One Google account, one record.
if (
await accountLinkedElsewhere(