(
owner: Owner,
slug: OAuthClientSlug,
)
| 987 | // Load an oauth_client row by (owner, slug). |
| 988 | // ----------------------------------------------------------------------- |
| 989 | const loadClient = ( |
| 990 | owner: Owner, |
| 991 | slug: OAuthClientSlug, |
| 992 | ): Effect.Effect<LoadedOAuthClient | null, StorageFailure> => |
| 993 | deps.fuma |
| 994 | .use("oauth_client.findFirst", (db) => |
| 995 | looseDb(db).findFirst("oauth_client", { |
| 996 | where: (b: any) => b.and(b("owner", "=", owner), b("slug", "=", String(slug))), |
| 997 | }), |
| 998 | ) |
| 999 | .pipe( |
| 1000 | Effect.flatMap((row) => { |
| 1001 | if (!row) return Effect.succeed(null); |
| 1002 | const grant = parseGrant(row.grant); |
| 1003 | // EXPLICIT — this row drives the token exchange. An unknown grant is a |
| 1004 | // corrupt row; fail loudly rather than guessing authorization_code and |
| 1005 | // running the wrong flow. |
| 1006 | if (grant === null) { |
| 1007 | return Effect.fail( |
| 1008 | new StorageError({ |
| 1009 | message: `oauth_client ${String(slug)} has an unknown grant: ${String(row.grant)}`, |
| 1010 | cause: undefined, |
| 1011 | }), |
| 1012 | ); |
| 1013 | } |
| 1014 | // `client_secret_item_id` is null for DCR-minted / public PKCE clients; |
| 1015 | // the token exchange treats a missing secret as "public client, omit |
| 1016 | // client_secret" (see pickClientAuth). A confidential client persisted |
| 1017 | // its secret to the provider in createClient; resolve it back here. |
| 1018 | return Effect.gen(function* () { |
| 1019 | let clientSecret = ""; |
| 1020 | if (row.client_secret_item_id != null) { |
| 1021 | const provider = deps.defaultWritableProvider(); |
| 1022 | if (provider) { |
| 1023 | clientSecret = |
| 1024 | (yield* provider.get(ProviderItemId.make(String(row.client_secret_item_id)))) ?? |
| 1025 | ""; |
| 1026 | } |
| 1027 | } |
| 1028 | return { |
| 1029 | slug: String(row.slug), |
| 1030 | authorizationUrl: String(row.authorization_url), |
| 1031 | tokenUrl: String(row.token_url), |
| 1032 | grant, |
| 1033 | clientId: String(row.client_id), |
| 1034 | clientSecret, |
| 1035 | resource: row.resource == null ? null : String(row.resource), |
| 1036 | } satisfies LoadedOAuthClient; |
| 1037 | }); |
| 1038 | }), |
| 1039 | ); |
| 1040 | |
| 1041 | // ----------------------------------------------------------------------- |
| 1042 | // start — begin a flow through a client to mint a connection. |
no test coverage detected