(
owner: Owner,
slug: OAuthClientSlug,
)
| 933 | // Load an oauth_client row by (owner, slug). |
| 934 | // ----------------------------------------------------------------------- |
| 935 | const loadClient = ( |
| 936 | owner: Owner, |
| 937 | slug: OAuthClientSlug, |
| 938 | ): Effect.Effect<LoadedOAuthClient | null, StorageFailure> => |
| 939 | deps.fuma |
| 940 | .use("oauth_client.findFirst", (db) => |
| 941 | looseDb(db).findFirst("oauth_client", { |
| 942 | where: (b: any) => b.and(b("owner", "=", owner), b("slug", "=", String(slug))), |
| 943 | }), |
| 944 | ) |
| 945 | .pipe( |
| 946 | Effect.flatMap((row) => { |
| 947 | if (!row) return Effect.succeed(null); |
| 948 | const grant = parseGrant(row.grant); |
| 949 | // EXPLICIT — this row drives the token exchange. An unknown grant is a |
| 950 | // corrupt row; fail loudly rather than guessing authorization_code and |
| 951 | // running the wrong flow. |
| 952 | if (grant === null) { |
| 953 | return Effect.fail( |
| 954 | new StorageError({ |
| 955 | message: `oauth_client ${String(slug)} has an unknown grant: ${String(row.grant)}`, |
| 956 | cause: undefined, |
| 957 | }), |
| 958 | ); |
| 959 | } |
| 960 | // `client_secret_item_id` is null for DCR-minted / public PKCE clients; |
| 961 | // the token exchange treats a missing secret as "public client, omit |
| 962 | // client_secret" (see pickClientAuth). A confidential client persisted |
| 963 | // its secret to the provider in createClient; resolve it back here. |
| 964 | return Effect.gen(function* () { |
| 965 | let clientSecret = ""; |
| 966 | if (row.client_secret_item_id != null) { |
| 967 | const provider = deps.defaultWritableProvider(); |
| 968 | if (provider) { |
| 969 | clientSecret = |
| 970 | (yield* provider.get(ProviderItemId.make(String(row.client_secret_item_id)))) ?? |
| 971 | ""; |
| 972 | } |
| 973 | } |
| 974 | return { |
| 975 | slug: String(row.slug), |
| 976 | authorizationUrl: String(row.authorization_url), |
| 977 | tokenUrl: String(row.token_url), |
| 978 | grant, |
| 979 | clientId: String(row.client_id), |
| 980 | clientSecret, |
| 981 | resource: row.resource == null ? null : String(row.resource), |
| 982 | } satisfies LoadedOAuthClient; |
| 983 | }); |
| 984 | }), |
| 985 | ); |
| 986 | |
| 987 | // ----------------------------------------------------------------------- |
| 988 | // start — begin a flow through a client to mint a connection. |
no test coverage detected