1import * as Effect from "effect/Effect";
2import * as Layer from "effect/Layer";
3import * as Binding from "../Binding.ts";
4import type { RuntimeContext } from "../RuntimeContext.ts";
5import type { Auth } from "./Auth.ts";
6import {
7 backendEnvKey,
8 backendString,
9 bindBackendEnvironment,
10} from "./BackendConnection.ts";
11
12export interface ConnectAuthClient {
13 /** Public managed Better Auth URL for the standard Neon auth client. */
14 baseUrl: Effect.Effect<string, never, RuntimeContext>;
15 /** Public JWKS endpoint. Verify signature, issuer, audience and expiry with an established JWT library. */
16 jwksUrl: Effect.Effect<string, never, RuntimeContext>;
17}
18
19/**
20 * Bind managed Auth's public connection configuration. This does not create an
21 * admin credential, verify a JWT, or replace the standard Neon Auth SDK.
22 *
23 * ### Connect managed authentication
24 * **Example:** Obtain configuration inside a Function
25 * ```typescript
26 * const authClient = yield* Neon.ConnectAuth(auth);
27 * // In the request handler:
28 * const baseUrl = yield* authClient.baseUrl;
29 * ```
30 *
31 * @binding
32 * @product Auth
33 */
34export interface ConnectAuth extends Binding.Service<
35 ConnectAuth,
36 "Neon.ConnectAuth",
37 (auth: Auth) => Effect.Effect<ConnectAuthClient>
38> {}
39export const ConnectAuth = Binding.Service<ConnectAuth>("Neon.ConnectAuth");
40
41/** Bind public Auth URLs on Neon Functions, Workers, Lambda and other env hosts. */
42export const ConnectAuthHttp = Layer.succeed(
43 ConnectAuth,
44 Effect.fn(function* (auth: Auth) {
45 const baseUrl = backendEnvKey(auth.FQN, "AUTH_URL");
46 const jwksUrl = backendEnvKey(auth.FQN, "AUTH_JWKS_URL");
47 yield* bindBackendEnvironment(`Neon.ConnectAuth:${auth.FQN}`, {
48 [baseUrl]: auth.baseUrl,
49 [jwksUrl]: auth.jwksUrl,
50 });
51 return {
52 baseUrl: backendString(baseUrl),
53 jwksUrl: backendString(jwksUrl),
54 } satisfies ConnectAuthClient;
55 }),
56);