Show the callback path, not 'undefined/api/…', on an unset app URL

With NEXT_PUBLIC_APP_URL unset, some providers spliced the missing value
into their redirect template and the integration cards told the reader to
register 'undefined/api/polar/callback'. A callback that is not an
absolute http(s) URL now counts as not configured, so the card shows the
fixed path it shows for every other unconfigured provider.
This commit is contained in:
Marc-André Bombeck committed 2026-10-08 17:13:49 +02:00
1 parent 0f51a828c4
commit ec272c9150
2 files changed
+18 -1

No files matched your search

@@ -110,4 +110,16 @@ describe("getIntegrationCallbackUrls", () => {
expect(urls.withings).toBe("http://health.example/api/withings/callback");
expect(urls.whoop).toBe("http://health.example/api/whoop/callback");
});
it("reports null rather than 'undefined/api/…' when the app URL is unset", () => {
// A resolver that splices the unset variable into its template would
// otherwise hand the card "undefined/api/polar/callback" to show.
const urls = getIntegrationCallbackUrls();
for (const provider of INTEGRATION_CALLBACK_PROVIDERS) {
expect(urls[provider] ?? "", provider).not.toMatch(/^undefined/);
if (urls[provider] !== null) {
expect(urls[provider], provider).toMatch(/^https?:\/\//);
}
}
});
});
+6 -1
View File
@@ -59,7 +59,12 @@ const RESOLVERS: Record<IntegrationCallbackProvider, () => string> = {
function resolve(provider: IntegrationCallbackProvider): string | null {
try {
return RESOLVERS[provider]();
const url = RESOLVERS[provider]();
// Some resolvers splice an unset NEXT_PUBLIC_APP_URL into the template
// and hand back "undefined/api/…/callback". That is not a URL anyone can
// paste into a vendor form; report it as not configured so the card
// shows the path instead.
return /^https?:\/\//i.test(url) ? url : null;
} catch {
return null;
}