mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-14 22:50:51 +00:00
refactor(integrations): start and end every OAuth connection through the kit
Minting the state, building the consent URL and dropping a grant each had a copy per provider route. The routes keep their auth, rate limits and redirects and hand the rest to one implementation, which the managed-profile routes reuse.
This commit is contained in:
1 parent
b60fa0123b
commit
65e0cba0bf
14 files changed
+483
-344
No files matched your search
@@ -1,14 +1,10 @@
|
||||
import { apiHandler, requireAuth } from "@/lib/api-handler";
|
||||
import { annotate } from "@/lib/logging/context";
|
||||
import { shouldEmitSecureCookie } from "@/lib/auth/secure-cookie";
|
||||
import { checkRateLimit } from "@/lib/rate-limit";
|
||||
import { getAuthorizationUrl } from "@/lib/strava/client";
|
||||
import { getStravaClientCredentials } from "@/lib/strava/credentials";
|
||||
import {
|
||||
OAUTH_STATE_TTL_MS,
|
||||
mintSignedState,
|
||||
oauthStateCookieName,
|
||||
} from "@/lib/oauth/signed-state";
|
||||
setConnectStateCookie,
|
||||
startOAuthConnect,
|
||||
} from "@/lib/integrations/oauth-kit/connect-start";
|
||||
import { annotate } from "@/lib/logging/context";
|
||||
import { checkRateLimit } from "@/lib/rate-limit";
|
||||
import { NextResponse } from "next/server";
|
||||
|
||||
/**
|
||||
@@ -45,8 +41,8 @@ export const GET = apiHandler(async () => {
|
||||
);
|
||||
}
|
||||
|
||||
const creds = await getStravaClientCredentials(user.id);
|
||||
if (!creds) {
|
||||
const started = await startOAuthConnect("strava", user.id);
|
||||
if (!started.ok) {
|
||||
annotate({ action: { name: "strava.connect.no_credentials" } });
|
||||
return NextResponse.redirect(
|
||||
new URL(
|
||||
@@ -56,16 +52,8 @@ export const GET = apiHandler(async () => {
|
||||
);
|
||||
}
|
||||
|
||||
const state = mintSignedState("strava", user.id);
|
||||
const url = getAuthorizationUrl(state, creds);
|
||||
|
||||
const response = NextResponse.redirect(url);
|
||||
response.cookies.set(oauthStateCookieName("strava"), state, {
|
||||
httpOnly: true,
|
||||
secure: shouldEmitSecureCookie(),
|
||||
sameSite: "lax",
|
||||
maxAge: Math.floor(OAUTH_STATE_TTL_MS / 1000),
|
||||
path: "/",
|
||||
});
|
||||
return response;
|
||||
return setConnectStateCookie(
|
||||
NextResponse.redirect(started.authorizationUrl),
|
||||
started.cookie,
|
||||
);
|
||||
});
|
||||
@@ -1,15 +1,8 @@
|
||||
import { prisma } from "@/lib/db";
|
||||
import { apiHandler, requireAuth } from "@/lib/api-handler";
|
||||
import { auditLog } from "@/lib/auth/audit";
|
||||
import { disconnectOAuth } from "@/lib/integrations/oauth-kit/disconnect";
|
||||
import { apiSuccess, apiError } from "@/lib/api-response";
|
||||
import { annotate, getEvent } from "@/lib/logging/context";
|
||||
import { annotate } from "@/lib/logging/context";
|
||||
import { checkRateLimit, rateLimitHeaders } from "@/lib/rate-limit";
|
||||
import { markDisconnected } from "@/lib/integrations/status";
|
||||
import { deauthorize } from "@/lib/strava/client";
|
||||
import {
|
||||
getStravaConnection,
|
||||
STRAVA_DISCONNECTED,
|
||||
} from "@/lib/strava/credentials";
|
||||
|
||||
/**
|
||||
* v1.28.x — disconnect Strava for the current user.
|
||||
@@ -30,26 +23,9 @@ export const POST = apiHandler(async () => {
|
||||
});
|
||||
}
|
||||
|
||||
const connection = await getStravaConnection(user.id);
|
||||
if (!connection) {
|
||||
if ((await disconnectOAuth("strava", user.id)) === "not_connected") {
|
||||
return apiError("No Strava connection", 404);
|
||||
}
|
||||
|
||||
// Best-effort revoke at Strava; a Strava-side outage must never block the
|
||||
// local disconnect.
|
||||
try {
|
||||
await deauthorize(connection.accessToken);
|
||||
} catch (err) {
|
||||
getEvent()?.addWarning(`strava: deauthorize failed on disconnect: ${err}`);
|
||||
}
|
||||
|
||||
await prisma.user.update({
|
||||
where: { id: user.id },
|
||||
data: STRAVA_DISCONNECTED,
|
||||
});
|
||||
|
||||
await auditLog("strava.disconnect", { userId: user.id });
|
||||
await markDisconnected(user.id, "strava");
|
||||
|
||||
return apiSuccess({ disconnected: true });
|
||||
});
|
||||
Reference in new issue
Block a user