fix(oura): name the issuer refusal on the integrations page

This commit is contained in:
Marc-André Bombeck committed 2026-10-11 13:59:05 +02:00
1 parent 5d7e0248b6
commit 9a86a9427b
9 files changed
+53 -1

No files matched your search

@@ -61,9 +61,42 @@ describe("oauthReasonKey", () => {
);
});
it("names Oura's issuer refusal with its own copy, and only for Oura", () => {
expect(oauthReasonKey("oura", "issuer")).toBe(
"settings.ouraOauthError.issuer",
);
// No other callback emits it, and no other subtree carries the copy.
expect(oauthReasonKey("polar", "issuer")).toBe(
"settings.polarOauthError.generic",
);
});
it("falls back to generic for an unknown tag", () => {
expect(oauthReasonKey("whoop", "totally_unknown")).toBe(
"settings.whoopOauthError.generic",
);
});
});
describe("the Oura callback's reasons", () => {
it("each has its own copy, none falls back to generic", async () => {
const { readFileSync } = await import("node:fs");
const { join } = await import("node:path");
const route = readFileSync(
join(process.cwd(), "src/app/api/oura/callback/route.ts"),
"utf8",
);
const reasons = [...route.matchAll(/ERR\("([a-z_0-9]+)"\)/g)].map(
(m) => m[1],
);
expect(reasons).toContain("issuer");
const en = JSON.parse(
readFileSync(join(process.cwd(), "messages/en.json"), "utf8"),
) as { settings: { ouraOauthError: Record<string, string> } };
for (const reason of reasons) {
const key = oauthReasonKey("oura", reason);
expect(key, reason).toBe(`settings.ouraOauthError.${reason}`);
expect(en.settings.ouraOauthError[reason], reason).toBeTruthy();
}
});
});
@@ -127,6 +127,17 @@ const OAUTH_OUTCOME_REASONS = new Set([
"expired",
]);
/**
* Reason tags only one provider's callback emits, with copy under that
* provider's subtree alone. Oura's `issuer`: the authorization response named
* an issuer that is not Oura's (RFC 9207), so the callback refused the code.
*/
const PROVIDER_ONLY_REASONS: Partial<
Record<OAuthOutcomeProvider, ReadonlySet<string>>
> = {
oura: new Set(["issuer"]),
};
type OAuthOutcome =
| { provider: OAuthOutcomeProvider; kind: "connected" }
| { provider: OAuthOutcomeProvider; kind: "error"; reason: string };
@@ -162,7 +173,8 @@ export function oauthReasonKey(
reason: string,
): string {
const base = OAUTH_ERROR_KEY_BASE[provider];
return OAUTH_OUTCOME_REASONS.has(reason)
return OAUTH_OUTCOME_REASONS.has(reason) ||
PROVIDER_ONLY_REASONS[provider]?.has(reason)
? `${base}.${reason}`
: `${base}.generic`;
}