| author | |
| committer | |
| log | 4d3fcacd840d7b710f8415b4bebf3826df358c91 |
| tree | c0689d6dd0bb2cf94d9aa9369c73df663235753a |
| parent | 4d790f0064ab99287d3ccb17d2f003f5ed8e8d3e |
| signature | Signed by PGP key B5690EEEBB952194 |
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 @@ | ... | @@ -1,6 +1,7 @@ |
| 1 | import { assert, it } from "@effect/vitest"; | 1 | import { assert, it } from "@effect/vitest"; |
| 2 | import * as ConfigProvider from "effect/ConfigProvider"; | 2 | import * as ConfigProvider from "effect/ConfigProvider"; |
| 3 | import * as Effect from "effect/Effect"; | 3 | import * as Effect from "effect/Effect"; |
| 4 | import * as Result from "effect/Result"; | ||
| 4 | 5 | ||
| 5 | import { | 6 | import { |
| 6 | makeCloudCliOAuthConfig, | 7 | makeCloudCliOAuthConfig, |
| ... | @@ -88,6 +89,27 @@ it.effect("requires Clerk OAuth config when the server bundle has no injected va | ... | @@ -88,6 +89,27 @@ it.effect("requires Clerk OAuth config when the server bundle has no injected va |
| 88 | }).pipe(provideEnv({}), Effect.flip), | 89 | }).pipe(provideEnv({}), Effect.flip), |
| 89 | ); | 90 | ); |
| 90 | 91 | ||
| 92 | it.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 | |||
| 91 | it("resolves relay client tracing from runtime config with build-time fallback", () => { | 113 | it("resolves relay client tracing from runtime config with build-time fallback", () => { |
| 92 | const fallback = { | 114 | const fallback = { |
| 93 | tracesUrl: "https://embedded.example.test/v1/traces", | 115 | tracesUrl: "https://embedded.example.test/v1/traces", |
apps/server/src/cloud/publicConfig.ts+24-10| ... | @@ -1,6 +1,7 @@ | ... | @@ -1,6 +1,7 @@ |
| 1 | import { clerkFrontendApiUrlFromPublishableKey } from "@t3tools/shared/relayAuth"; | 1 | import { clerkFrontendApiUrlFromPublishableKey } from "@t3tools/shared/relayAuth"; |
| 2 | import { normalizeSecureRelayUrl } from "@t3tools/shared/relayUrl"; | 2 | import { normalizeSecureRelayUrl } from "@t3tools/shared/relayUrl"; |
| 3 | import * as Config from "effect/Config"; | 3 | import * as Config from "effect/Config"; |
| 4 | import * as ConfigProvider from "effect/ConfigProvider"; | ||
| 4 | import * as Effect from "effect/Effect"; | 5 | import * as Effect from "effect/Effect"; |
| 5 | import * as Option from "effect/Option"; | 6 | import * as Option from "effect/Option"; |
| 6 | import * as Schema from "effect/Schema"; | 7 | import * as Schema from "effect/Schema"; |
| ... | @@ -131,16 +132,29 @@ export function makeCloudCliOAuthConfig({ | ... | @@ -131,16 +132,29 @@ export function makeCloudCliOAuthConfig({ |
| 131 | clerkCliOAuthClientIdFallback, | 132 | clerkCliOAuthClientIdFallback, |
| 132 | ), | 133 | ), |
| 133 | }).pipe( | 134 | }).pipe( |
| 134 | Config.map(({ clerkPublishableKey, clientId }) => { | 135 | Config.mapOrFail(({ clerkPublishableKey, clientId }) => |
| 135 | const clerkFrontendApiUrl = clerkFrontendApiUrlFromPublishableKey(clerkPublishableKey); | 136 | Effect.try({ |
| 136 | return { | 137 | try: () => clerkFrontendApiUrlFromPublishableKey(clerkPublishableKey), |
| 137 | authorizationEndpoint: `${clerkFrontendApiUrl}/oauth/authorize`, | 138 | catch: (cause) => |
| 138 | tokenEndpoint: `${clerkFrontendApiUrl}/oauth/token`, | 139 | new Config.ConfigError( |
| 139 | clientId, | 140 | new ConfigProvider.SourceError({ |
| 140 | redirectUri: CLOUD_CLI_OAUTH_REDIRECT_URI, | 141 | message: "Failed to derive Clerk Frontend API URL from the publishable key.", |
| 141 | scopes: CLOUD_CLI_OAUTH_SCOPES, | 142 | cause, |
| 142 | } satisfies CloudCliOAuthConfig; | 143 | }), |
| 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 | ), | ||
| 144 | ); | 158 | ); |
| 145 | } | 159 | } |
| 146 | 160 |