refactor(integrations): read the OAuth redirect URIs through the env helpers

The seven integration clients now read their redirect URI and the app URL
through envValue/envOr instead of a local ?.trim() ||. The empty-env guard
drops its pending entry and floors its walk, and proves its matcher still
fires on a real client with the old read put back.
This commit is contained in:
Marc-André Bombeck committed 2026-09-26 17:08:47 +02:00
1 parent 903f0a9a22
commit cc60b82d84
8 files changed
+45 -38

No files matched your search

+3 -2
View File
@@ -42,6 +42,7 @@ import { safeFetch } from "@/lib/safe-fetch";
import { canonicalDailyTimestamp } from "@/lib/measurements/consolidation-tz";
import { zonedWallClockToUtc } from "@/lib/tz/wall-clock";
import { FitbitApiError, classifyFitbitResponse } from "./response-classifier";
import { envValue } from "@/lib/env";
/** Classic Fitbit Web API base. */
export const FITBIT_API_BASE = "https://api.fitbit.com";
@@ -80,8 +81,8 @@ export function getFitbitRedirectUri(): string {
// An empty or blank value counts as unset: the compose whitelist
// materialises an unset var as an empty string, which must fall through to
// the derived URI rather than read as "not configured".
const explicit = process.env.FITBIT_REDIRECT_URI?.trim() || undefined;
const appUrl = process.env.NEXT_PUBLIC_APP_URL?.trim() || undefined;
const explicit = envValue("FITBIT_REDIRECT_URI");
const appUrl = envValue("NEXT_PUBLIC_APP_URL");
const raw =
explicit ?? (appUrl ? `${appUrl}/api/fitbit/callback` : undefined);
+3 -2
View File
@@ -48,6 +48,7 @@ import type {
GoogleHealthDataType,
GoogleHealthRollupPoint,
} from "./mappers";
import { envValue } from "@/lib/env";
export * from "./mappers";
@@ -150,8 +151,8 @@ export function getGoogleHealthRedirectUri(): string {
// An empty or blank value counts as unset: the compose whitelist
// materialises an unset var as an empty string, which must fall through to
// the derived URI rather than read as "not configured".
const explicit = process.env.GOOGLE_HEALTH_REDIRECT_URI?.trim() || undefined;
const appUrl = process.env.NEXT_PUBLIC_APP_URL?.trim() || undefined;
const explicit = envValue("GOOGLE_HEALTH_REDIRECT_URI");
const appUrl = envValue("NEXT_PUBLIC_APP_URL");
const raw =
explicit ?? (appUrl ? `${appUrl}/api/google-health/callback` : undefined);
+4 -3
View File
@@ -18,6 +18,7 @@ import { canonicalDailyTimestamp } from "@/lib/measurements/consolidation-tz";
import { dayDiff } from "@/lib/cycle/day-math";
import { safeFetch } from "@/lib/safe-fetch";
import { OuraApiError, classifyOuraResponse } from "./response-classifier";
import { envOr, envValue } from "@/lib/env";
const OURA_API_BASE = "https://api.ouraring.com";
const OURA_OAUTH_AUTH_URL = "https://cloud.ouraring.com/oauth/authorize";
@@ -44,9 +45,9 @@ export function getOuraCredentials(): OuraCredentials | null {
export function getOuraRedirectUri(): string {
// An empty or blank value counts as unset (the compose whitelist
// materialises an unset var as an empty string).
return (
process.env.OURA_REDIRECT_URI?.trim() ||
`${process.env.NEXT_PUBLIC_APP_URL?.trim()}/api/oura/callback`
return envOr(
"OURA_REDIRECT_URI",
`${envValue("NEXT_PUBLIC_APP_URL")}/api/oura/callback`,
);
}
+4 -3
View File
@@ -31,6 +31,7 @@ import type { Prisma } from "@/generated/prisma/client";
import type { WorkoutSportType } from "@/lib/validations/workout";
import { PolarApiError, classifyPolarResponse } from "./response-classifier";
import { mapPolarSportType } from "./sport-map";
import { envOr, envValue } from "@/lib/env";
const POLAR_API_BASE = "https://www.polaraccesslink.com";
const POLAR_OAUTH_AUTH_URL = "https://flow.polar.com/oauth2/authorization";
@@ -57,9 +58,9 @@ export function getPolarRedirectUri(): string {
// An empty or blank value counts as unset: the compose whitelist
// materialises an unset var as an empty string, which must still fall
// through to the derived URI.
return (
process.env.POLAR_REDIRECT_URI?.trim() ||
`${process.env.NEXT_PUBLIC_APP_URL?.trim()}/api/polar/callback`
return envOr(
"POLAR_REDIRECT_URI",
`${envValue("NEXT_PUBLIC_APP_URL")}/api/polar/callback`,
);
}
+4 -3
View File
@@ -27,6 +27,7 @@ import type { Prisma } from "@/generated/prisma/client";
import { StravaApiError, classifyStravaResponse } from "./response-classifier";
import { mapStravaSportType } from "./sport-map";
import type { WorkoutSportType } from "@/lib/validations/workout";
import { envOr, envValue } from "@/lib/env";
const STRAVA_API_BASE = "https://www.strava.com/api/v3";
const STRAVA_OAUTH_AUTH_URL = "https://www.strava.com/oauth/authorize";
@@ -55,9 +56,9 @@ export function getStravaRedirectUri(): string {
// An empty or blank value counts as unset: the compose whitelist
// materialises an unset var as an empty string, which must still fall
// through to the derived URI.
return (
process.env.STRAVA_REDIRECT_URI?.trim() ||
`${process.env.NEXT_PUBLIC_APP_URL?.trim()}/api/strava/callback`
return envOr(
"STRAVA_REDIRECT_URI",
`${envValue("NEXT_PUBLIC_APP_URL")}/api/strava/callback`,
);
}
+4 -3
View File
@@ -19,6 +19,7 @@ import { getEvent } from "@/lib/logging/context";
import { safeFetch } from "@/lib/safe-fetch";
import { reconstructContiguousSleepTimeline } from "@/lib/sleep/reconstruct-timeline";
import { WhoopApiError, classifyWhoopResponse } from "./response-classifier";
import { envOr, envValue } from "@/lib/env";
const WHOOP_API_BASE = "https://api.prod.whoop.com/developer";
const WHOOP_OAUTH_AUTH_URL = "https://api.prod.whoop.com/oauth/oauth2/auth";
@@ -36,9 +37,9 @@ export function getWhoopRedirectUri(): string {
// An empty or blank value counts as unset: the compose whitelist
// materialises the var as an empty string when unset, which must still fall
// through to the derived URI.
return (
process.env.WHOOP_REDIRECT_URI?.trim() ||
`${process.env.NEXT_PUBLIC_APP_URL?.trim()}/api/whoop/callback`
return envOr(
"WHOOP_REDIRECT_URI",
`${envValue("NEXT_PUBLIC_APP_URL")}/api/whoop/callback`,
);
}
+4 -3
View File
@@ -8,6 +8,7 @@ import {
WithingsApiError,
classifyWithingsResponse,
} from "./response-classifier";
import { envOr, envValue } from "@/lib/env";
const WITHINGS_OAUTH_URL =
"https://account.withings.com/oauth2_user/authorize2";
@@ -24,9 +25,9 @@ export function getWithingsRedirectUri(): string {
// An empty or blank value counts as unset: the compose whitelist
// materialises an unset var as an empty string, which must fall through to
// the derived URI rather than go out as `redirect_uri=`.
return (
process.env.WITHINGS_REDIRECT_URI?.trim() ||
`${process.env.NEXT_PUBLIC_APP_URL?.trim()}/api/withings/callback`
return envOr(
"WITHINGS_REDIRECT_URI",
`${envValue("NEXT_PUBLIC_APP_URL")}/api/withings/callback`,
);
}