mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-09 13:01:00 +00:00
fix: warn about mismatched OAuth callback URLs
This commit is contained in:
1 parent
f0ccd9db38
commit
3453bfe101
8 files changed
+74
-1
No files matched your search
@@ -4636,6 +4636,7 @@
|
||||
"remainingMany": "Noch {count} Messungen bis zum Trend."
|
||||
},
|
||||
"settings": {
|
||||
"oauthCallbackPreflightItem": "{provider}: Die Callback-Adresse {configuredOrigin} unterscheidet sich von der App-Adresse {currentOrigin}.",
|
||||
"shell": {
|
||||
"sectionsNav": "Einstellungs-Bereiche",
|
||||
"groups": {
|
||||
|
||||
@@ -4636,6 +4636,7 @@
|
||||
"remainingMany": "{count} more readings to go."
|
||||
},
|
||||
"settings": {
|
||||
"oauthCallbackPreflightItem": "{provider}: callback address {configuredOrigin} differs from this app address {currentOrigin}.",
|
||||
"shell": {
|
||||
"sectionsNav": "Settings sections",
|
||||
"groups": {
|
||||
|
||||
@@ -65,8 +65,10 @@ import {
|
||||
type SyncOutcomeState,
|
||||
} from "./sync-outcome";
|
||||
import {
|
||||
CallbackMismatchNotice,
|
||||
IntegrationCardDescription,
|
||||
IntegrationRedirectGuide,
|
||||
integrationCallbackUrl,
|
||||
} from "./setup-guide-link";
|
||||
|
||||
export function FitbitCard({
|
||||
@@ -521,6 +523,10 @@ export function FitbitCard({
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<CallbackMismatchNotice
|
||||
provider={t("settings.fitbit")}
|
||||
callbackUrl={integrationCallbackUrl("fitbit")}
|
||||
/>
|
||||
</SettingsCard>
|
||||
);
|
||||
}
|
||||
@@ -80,7 +80,11 @@ import {
|
||||
type SyncOutcomeResource,
|
||||
type SyncOutcomeState,
|
||||
} from "./sync-outcome";
|
||||
import { IntegrationCardDescription } from "./setup-guide-link";
|
||||
import {
|
||||
CallbackMismatchNotice,
|
||||
IntegrationCardDescription,
|
||||
integrationCallbackUrl,
|
||||
} from "./setup-guide-link";
|
||||
|
||||
export function GoogleHealthCard({
|
||||
viewModel,
|
||||
@@ -758,6 +762,10 @@ export function GoogleHealthCard({
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<CallbackMismatchNotice
|
||||
provider={t("settings.googleHealth")}
|
||||
callbackUrl={integrationCallbackUrl("google-health")}
|
||||
/>
|
||||
</SettingsCard>
|
||||
);
|
||||
}
|
||||
@@ -65,9 +65,11 @@ import {
|
||||
pillStateForVerdict,
|
||||
} from "./shared";
|
||||
import {
|
||||
CallbackMismatchNotice,
|
||||
IntegrationCardDescription,
|
||||
IntegrationRedirectGuide,
|
||||
type IntegrationDocsProvider,
|
||||
integrationCallbackUrl,
|
||||
} from "./setup-guide-link";
|
||||
|
||||
export interface OAuthProviderStatus {
|
||||
@@ -522,6 +524,10 @@ export function OAuthProviderCard({
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<CallbackMismatchNotice
|
||||
provider={t(i18nPrefix)}
|
||||
callbackUrl={integrationCallbackUrl(provider)}
|
||||
/>
|
||||
</SettingsCard>
|
||||
);
|
||||
}
|
||||
@@ -11,6 +11,7 @@
|
||||
* destination now so a user who is mid-setup always knows where to go.
|
||||
*/
|
||||
|
||||
import { useSyncExternalStore } from "react";
|
||||
import { ExternalLink } from "lucide-react";
|
||||
|
||||
import { useTranslations } from "@/lib/i18n/context";
|
||||
@@ -51,6 +52,44 @@ export function integrationCallbackUrl(
|
||||
return `${base}/api/${provider}/callback`;
|
||||
}
|
||||
|
||||
/** Shows a compact warning when the callback origin differs from the app. */
|
||||
export function CallbackMismatchNotice({
|
||||
provider,
|
||||
callbackUrl,
|
||||
}: {
|
||||
provider: string;
|
||||
callbackUrl: string;
|
||||
}) {
|
||||
// Get the current origin of the app
|
||||
const { t } = useTranslations();
|
||||
const currentOrigin = useSyncExternalStore(
|
||||
() => () => {},
|
||||
() => window.location.origin,
|
||||
() => null,
|
||||
);
|
||||
// Get the origin of the callback URL
|
||||
const callbackOrigin = (() => {
|
||||
try {
|
||||
return new URL(callbackUrl).origin;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
})();
|
||||
if (!currentOrigin || !callbackOrigin || callbackOrigin === currentOrigin) {
|
||||
return null;
|
||||
}
|
||||
// If the callback origin differs from the app, show a warning
|
||||
return (
|
||||
<span className="text-warning border-warning/30 bg-warning/5 block rounded-md border px-2 py-1 text-xs">
|
||||
{t("settings.oauthCallbackPreflightItem", {
|
||||
provider,
|
||||
configuredOrigin: callbackOrigin,
|
||||
currentOrigin,
|
||||
})}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* v1.29.x (UX audit H2) — compact 3-step BYO-developer-app guide for the
|
||||
* six providers that require a self-hoster to register their own vendor
|
||||
|
||||
@@ -56,8 +56,10 @@ import {
|
||||
type SyncOutcomeState,
|
||||
} from "./sync-outcome";
|
||||
import {
|
||||
CallbackMismatchNotice,
|
||||
IntegrationCardDescription,
|
||||
IntegrationRedirectGuide,
|
||||
integrationCallbackUrl,
|
||||
} from "./setup-guide-link";
|
||||
|
||||
export function WhoopCard({
|
||||
@@ -503,6 +505,10 @@ export function WhoopCard({
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<CallbackMismatchNotice
|
||||
provider={t("settings.whoop")}
|
||||
callbackUrl={integrationCallbackUrl("whoop")}
|
||||
/>
|
||||
</SettingsCard>
|
||||
);
|
||||
}
|
||||
@@ -55,8 +55,10 @@ import {
|
||||
type SyncOutcomeState,
|
||||
} from "./sync-outcome";
|
||||
import {
|
||||
CallbackMismatchNotice,
|
||||
IntegrationCardDescription,
|
||||
IntegrationRedirectGuide,
|
||||
integrationCallbackUrl,
|
||||
} from "./setup-guide-link";
|
||||
|
||||
export function WithingsCard({
|
||||
@@ -552,6 +554,10 @@ export function WithingsCard({
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<CallbackMismatchNotice
|
||||
provider={t("settings.withings")}
|
||||
callbackUrl={integrationCallbackUrl("withings")}
|
||||
/>
|
||||
</SettingsCard>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user