mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-13 06:32:03 +00:00
Long-overdue prettier sweep; prettier had drifted vs. checked-in code across ~130 files (mostly long-argument line-break wrapping in TS and table-padding in markdown). Pure formatting — no semantic changes — and required to clear the v1.4.6 release gate's `pnpm format:check`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
91 lines
2.7 KiB
TypeScript
91 lines
2.7 KiB
TypeScript
import { prisma } from "@/lib/db";
|
|
import { apiHandler, requireAuth } from "@/lib/api-handler";
|
|
import { annotate, getEvent } from "@/lib/logging/context";
|
|
import { apiSuccess } from "@/lib/api-response";
|
|
import { decrypt, encrypt } from "@/lib/crypto";
|
|
import { getUserWithingsCredentials } from "@/lib/withings/credentials";
|
|
import { refreshAccessToken } from "@/lib/withings/client";
|
|
|
|
/**
|
|
* Get Withings connection status for the current user.
|
|
* "configured" now checks per-user credentials instead of env vars.
|
|
*/
|
|
export const GET = apiHandler(async () => {
|
|
const { user } = await requireAuth();
|
|
annotate({ action: { name: "withings.status" } });
|
|
|
|
const dbUser = await prisma.user.findUnique({
|
|
where: { id: user.id },
|
|
select: {
|
|
withingsClientIdEncrypted: true,
|
|
withingsClientSecretEncrypted: true,
|
|
},
|
|
});
|
|
|
|
const configured =
|
|
!!dbUser?.withingsClientIdEncrypted &&
|
|
!!dbUser?.withingsClientSecretEncrypted;
|
|
|
|
const connection = await prisma.withingsConnection.findUnique({
|
|
where: { userId: user.id },
|
|
select: {
|
|
withingsUserId: true,
|
|
accessToken: true,
|
|
refreshToken: true,
|
|
lastSyncedAt: true,
|
|
tokenExpiresAt: true,
|
|
createdAt: true,
|
|
},
|
|
});
|
|
|
|
if (!connection) {
|
|
return apiSuccess({ connected: false, configured });
|
|
}
|
|
|
|
let tokenExpiresAt = connection.tokenExpiresAt;
|
|
const now = Date.now();
|
|
let tokenExpired = tokenExpiresAt.getTime() <= now;
|
|
let tokenRefreshFailed = false;
|
|
|
|
// Keep status reliable: if token is expired (or about to expire), refresh it
|
|
// before reporting "abgelaufen" in the UI.
|
|
const shouldRefresh = tokenExpiresAt.getTime() - 60_000 <= now;
|
|
if (shouldRefresh) {
|
|
try {
|
|
const creds = await getUserWithingsCredentials(user.id);
|
|
if (creds) {
|
|
const refreshToken = decrypt(connection.refreshToken);
|
|
const refreshed = await refreshAccessToken(refreshToken, creds);
|
|
tokenExpiresAt = new Date(Date.now() + refreshed.expires_in * 1000);
|
|
tokenExpired = tokenExpiresAt.getTime() <= Date.now();
|
|
|
|
await prisma.withingsConnection.update({
|
|
where: { userId: user.id },
|
|
data: {
|
|
accessToken: encrypt(refreshed.access_token),
|
|
refreshToken: encrypt(refreshed.refresh_token),
|
|
tokenExpiresAt,
|
|
},
|
|
});
|
|
} else if (tokenExpired) {
|
|
tokenRefreshFailed = true;
|
|
}
|
|
} catch (error) {
|
|
if (tokenExpired) {
|
|
tokenRefreshFailed = true;
|
|
}
|
|
getEvent()?.addWarning("Token refresh failed");
|
|
}
|
|
}
|
|
|
|
return apiSuccess({
|
|
connected: true,
|
|
configured,
|
|
lastSyncedAt: connection.lastSyncedAt,
|
|
connectedAt: connection.createdAt,
|
|
tokenExpired,
|
|
tokenRefreshFailed,
|
|
tokenExpiresAt,
|
|
});
|
|
});
|