1import * as Effect from "effect/Effect";
2import * as Schema from "effect/Schema";
3import * as Option from "effect/Option";
4import {
5 receiveCodexAuthCallback,
6 cancelCodexAuthCallback,
7 CodexAuthCallbackError,
8} from "../../app/CodexAuthCallback.ts";
9import * as ElectronShell from "../../electron/ElectronShell.ts";
10import * as ElectronWindow from "../../electron/ElectronWindow.ts";
11import * as DesktopIpc from "../DesktopIpc.ts";
12import * as IpcChannels from "../channels.ts";
13
14const Request = Schema.String.check(Schema.isMaxLength(16_384));
15
16export const receiveProviderAuthCallback = DesktopIpc.makeIpcMethod({
17 channel: IpcChannels.RECEIVE_PROVIDER_AUTH_CALLBACK_CHANNEL,
18 payload: Request,
19 result: Schema.String,
20 handler: Effect.fn("desktop.ipc.providerAuth.receive")(function* (authorizationUrl) {
21 const shell = yield* ElectronShell.ElectronShell;
22 const windows = yield* ElectronWindow.ElectronWindow;
23 const context = yield* Effect.context<ElectronShell.ElectronShell>();
24 const runPromise = Effect.runPromiseWith(context);
25 const callbackUrl = yield* Effect.tryPromise({
26 try: () =>
27 receiveCodexAuthCallback(authorizationUrl, (url) => runPromise(shell.openExternal(url))),
28 catch: () =>
29 new CodexAuthCallbackError({
30 detail:
31 "Could not receive ChatGPT sign-in on this computer. Try again or paste the redirect URL.",
32 }),
33 });
34 const window = yield* windows.currentMainOrFirst;
35 if (Option.isSome(window)) yield* windows.reveal(window.value);
36 return callbackUrl;
37 }),
38});
39
40export const cancelProviderAuthCallback = DesktopIpc.makeIpcMethod({
41 channel: IpcChannels.CANCEL_PROVIDER_AUTH_CALLBACK_CHANNEL,
42 payload: Request,
43 result: Schema.Void,
44 handler: (authorizationUrl) =>
45 Effect.try({
46 try: () => cancelCodexAuthCallback(authorizationUrl),
47 catch: () => new CodexAuthCallbackError({ detail: "Invalid ChatGPT sign-in request." }),
48 }),
49});