authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-06-20 11:18:38-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-06-20 11:18:38-07:00
log4d3fcacd840d7b710f8415b4bebf3826df358c91
treec0689d6dd0bb2cf94d9aa9369c73df663235753a
parent4d790f0064ab99287d3ccb17d2f003f5ed8e8d3e
signature Signed by PGP key B5690EEEBB952194

[codex] Type malformed Clerk public config failures (#3422)

Co-authored-by: codex <codex@users.noreply.github.com>

2 files changed, 46 insertions(+), 10 deletions(-)

apps/server/src/cloud/publicConfig.test.ts+22
......@@ -1,6 +1,7 @@
11import { assert, it } from "@effect/vitest";
22import * as ConfigProvider from "effect/ConfigProvider";
33import * as Effect from "effect/Effect";
4import * as Result from "effect/Result";
45
56import {
67 makeCloudCliOAuthConfig,
......@@ -88,6 +89,27 @@ it.effect("requires Clerk OAuth config when the server bundle has no injected va
8889 }).pipe(provideEnv({}), Effect.flip),
8990);
9091
92it.effect("reports malformed Clerk publishable keys as typed configuration failures", () =>
93 Effect.gen(function* () {
94 const result = yield* makeCloudCliOAuthConfig({
95 clerkPublishableKeyFallback: "pk_test_not-base64!!",
96 clerkCliOAuthClientIdFallback: "oauth_client_embedded",
97 }).pipe(provideEnv({}), Effect.result);
98
99 assert.isTrue(Result.isFailure(result));
100 if (Result.isFailure(result)) {
101 assert.equal(result.failure.cause._tag, "SourceError");
102 if (result.failure.cause._tag === "SourceError") {
103 assert.equal(
104 result.failure.cause.message,
105 "Failed to derive Clerk Frontend API URL from the publishable key.",
106 );
107 assert.instanceOf(result.failure.cause.cause, Error);
108 }
109 }
110 }),
111);
112
91113it("resolves relay client tracing from runtime config with build-time fallback", () => {
92114 const fallback = {
93115 tracesUrl: "https://embedded.example.test/v1/traces",
apps/server/src/cloud/publicConfig.ts+24-10
......@@ -1,6 +1,7 @@
11import { clerkFrontendApiUrlFromPublishableKey } from "@t3tools/shared/relayAuth";
22import { normalizeSecureRelayUrl } from "@t3tools/shared/relayUrl";
33import * as Config from "effect/Config";
4import * as ConfigProvider from "effect/ConfigProvider";
45import * as Effect from "effect/Effect";
56import * as Option from "effect/Option";
67import * as Schema from "effect/Schema";
......@@ -131,16 +132,29 @@ export function makeCloudCliOAuthConfig({
131132 clerkCliOAuthClientIdFallback,
132133 ),
133134 }).pipe(
134 Config.map(({ clerkPublishableKey, clientId }) => {
135 const clerkFrontendApiUrl = clerkFrontendApiUrlFromPublishableKey(clerkPublishableKey);
136 return {
137 authorizationEndpoint: `${clerkFrontendApiUrl}/oauth/authorize`,
138 tokenEndpoint: `${clerkFrontendApiUrl}/oauth/token`,
139 clientId,
140 redirectUri: CLOUD_CLI_OAUTH_REDIRECT_URI,
141 scopes: CLOUD_CLI_OAUTH_SCOPES,
142 } satisfies CloudCliOAuthConfig;
143 }),
135 Config.mapOrFail(({ clerkPublishableKey, clientId }) =>
136 Effect.try({
137 try: () => clerkFrontendApiUrlFromPublishableKey(clerkPublishableKey),
138 catch: (cause) =>
139 new Config.ConfigError(
140 new ConfigProvider.SourceError({
141 message: "Failed to derive Clerk Frontend API URL from the publishable key.",
142 cause,
143 }),
144 ),
145 }).pipe(
146 Effect.map(
147 (clerkFrontendApiUrl) =>
148 ({
149 authorizationEndpoint: `${clerkFrontendApiUrl}/oauth/authorize`,
150 tokenEndpoint: `${clerkFrontendApiUrl}/oauth/token`,
151 clientId,
152 redirectUri: CLOUD_CLI_OAUTH_REDIRECT_URI,
153 scopes: CLOUD_CLI_OAUTH_SCOPES,
154 }) satisfies CloudCliOAuthConfig,
155 ),
156 ),
157 ),
144158 );
145159}
146160