History

Remove the @executor/auth-oauth2 package and its references throughout the project, including dependencies and related files, to streamline the authentication process.

Rhys Sullivan committed 7 months ago

Commit 4f7dbcc1 parent 05af42a12 files · +35 −295Browse files

Unified · Split

12 files
  1. bun.lock +0 −17
  2. packages/auth/oauth2/package.json +0 −22
  3. packages/auth/oauth2/tsconfig.json +0 −19
  4. packages/platform/sdk/package.json +0 −2
  5. packages/platform/sdk/src/runtime/auth/mcp-oauth.ts +0 −1
  6. packages/platform/sdk/src/runtime/auth/oauth-loopback.test.ts +0 −110
  7. packages/platform/sdk/src/runtime/auth/oauth-loopback.ts +0 −106
  8. packages/platform/sdk/src/runtime/auth/oauth2-pkce.ts +0 −1
  9. packages/sources/core/package.json +0 −1
  10. plugins/google-discovery/sdk/index.ts +6 −6
  11. plugins/google-discovery/sdk/oauth2.ts +29 −9
  12. plugins/google-discovery/sdk/package.json +0 −1
bun.lock+0−17
@@ -135,17 +135,6 @@ · 134 unmodified lines
135135 "bun-types": "catalog:",
136136 },
137137 },
138− "packages/auth/oauth2": {
139− "name": "@executor/auth-oauth2",
140− "version": "0.0.0",
141− "dependencies": {
142− "effect": "catalog:",
143− },
144− "devDependencies": {
145− "@types/node": "catalog:",
146− "bun-types": "catalog:",
147− },
148− },
149138 "packages/clients/react": {
150139 "name": "@executor/react",
151140 "version": "0.0.0",
@@ -351,8 +340,6 @@ · 199 unmodified lines
351340 "dependencies": {
352341 "@effect/platform": "catalog:",
353342 "@effect/platform-node": "catalog:",
354− "@executor/auth-mcp-oauth": "workspace:*",
355− "@executor/auth-oauth2": "workspace:*",
356343 "@executor/codemode-core": "workspace:*",
357344 "@executor/ir": "workspace:*",
358345 "@executor/runtime-deno-subprocess": "workspace:*",
@@ -436,7 +423,6 @@ · 77 unmodified lines
436423 "name": "@executor/source-core",
437424 "version": "0.0.0",
438425 "dependencies": {
439− "@executor/auth-oauth2": "workspace:*",
440426 "@executor/codemode-core": "workspace:*",
441427 "@executor/ir": "workspace:*",
442428 "@modelcontextprotocol/sdk": "^1.26.0",
@@ -482,7 +468,6 @@ · 39 unmodified lines
482468 "version": "0.0.0",
483469 "dependencies": {
484470 "@effect/platform": "catalog:",
485− "@executor/auth-oauth2": "workspace:*",
486471 "@executor/codemode-core": "workspace:*",
487472 "@executor/ir": "workspace:*",
488473 "@executor/platform-sdk": "workspace:*",
@@ -900,8 +885,6 @@ · 411 unmodified lines
900885
901886 "@executor/auth-mcp-oauth": ["@executor/auth-mcp-oauth@workspace:packages/auth/mcp-oauth"],
902887
903− "@executor/auth-oauth2": ["@executor/auth-oauth2@workspace:packages/auth/oauth2"],
904−
905888 "@executor/codemode-core": ["@executor/codemode-core@workspace:packages/kernel/core"],
906889
907890 "@executor/docs": ["@executor/docs@workspace:apps/docs"],
packages/auth/oauth2/package.json+0−22
@@ -1,22 +0,0 @@
1−{
2− "name": "@executor/auth-oauth2",
3− "private": true,
4− "type": "module",
5− "exports": {
6− ".": "./src/index.ts"
7− },
8− "files": [
9− "src"
10− ],
11− "scripts": {
12− "typecheck": "bunx tsc --noEmit -p tsconfig.json"
13− },
14− "dependencies": {
15− "effect": "catalog:"
16− },
17− "devDependencies": {
18− "@types/node": "catalog:",
19− "bun-types": "catalog:"
20− },
21− "version": "0.0.0"
22−}
packages/auth/oauth2/tsconfig.json+0−19
@@ -1,19 +0,0 @@
1−{
2− "compilerOptions": {
3− "target": "ES2022",
4− "module": "ESNext",
5− "moduleResolution": "Bundler",
6− "strict": true,
7− "skipLibCheck": true,
8− "noEmit": true,
9− "lib": ["ES2022"],
10− "types": ["bun-types", "node"]
11− },
12− "include": [
13− "src/**/*.ts",
14− "src/**/*.d.ts"
15− ],
16− "exclude": [
17− "src/**/*.test.ts"
18− ]
19−}
packages/platform/sdk/package.json+0−2
@@ -27,8 +27,6 @@ · 26 unmodified lines
2727 "dependencies": {
2828 "@effect/platform": "catalog:",
2929 "@effect/platform-node": "catalog:",
30− "@executor/auth-mcp-oauth": "workspace:*",
31− "@executor/auth-oauth2": "workspace:*",
3230 "@executor/codemode-core": "workspace:*",
3331 "@executor/ir": "workspace:*",
3432 "@executor/runtime-deno-subprocess": "workspace:*",
packages/platform/sdk/src/runtime/auth/mcp-oauth.ts+0−1
@@ -1 +0,0 @@
1−export * from "@executor/auth-mcp-oauth";
packages/platform/sdk/src/runtime/auth/oauth-loopback.test.ts+0−110
@@ -1,110 +0,0 @@
1−import {
2− createServer,
3−} from "node:http";
4−
5−import {
6− describe,
7− expect,
8− it,
9−} from "@effect/vitest";
10−import * as Effect from "effect/Effect";
11−
12−import {
13− startOauthLoopbackRedirectServer,
14−} from "./oauth-loopback";
15−
16−const toError = (cause: unknown): Error =>
17− cause instanceof Error ? cause : new Error(String(cause));
18−
19−const makeCompletionServer = Effect.acquireRelease(
20− Effect.tryPromise({
21− try: () =>
22− new Promise<{
23− completionUrl: string;
24− requests: string[];
25− server: ReturnType<typeof createServer>;
26− }>((resolve, reject) => {
27− const requests: string[] = [];
28− const server = createServer((request, response) => {
29− requests.push(request.url ?? "/");
30− response.statusCode = 200;
31− response.end("ok");
32− });
33−
34− server.listen(0, "127.0.0.1", (error?: Error) => {
35− if (error) {
36− reject(error);
37− return;
38− }
39−
40− const address = server.address();
41− if (!address || typeof address === "string") {
42− reject(new Error("Failed to resolve completion server address"));
43− return;
44− }
45−
46− resolve({
47− completionUrl: `http://127.0.0.1:${address.port}/oauth/complete?sessionId=test-session`,
48− requests,
49− server,
50− });
51− });
52− }),
53− catch: toError,
54− }),
55− ({ server }) =>
56− Effect.tryPromise({
57− try: () =>
58− new Promise<void>((resolve, reject) => {
59− server.close((error) => {
60− if (error) {
61− reject(error);
62− return;
63− }
64− resolve();
65− });
66− }),
67− catch: toError,
68− }),
69−);
70−
71−const withCompletionServer = <T>(
72− handler: (input: {
73− completionUrl: string;
74− requests: string[];
75− }) => Effect.Effect<T, Error, never>,
76−) => Effect.flatMap(makeCompletionServer, handler);
77−
78−describe("oauth-loopback", () => {
79− it.scoped(
80− "redirects loopback callbacks to the app completion URL with query params intact",
81− () =>
82− withCompletionServer(({ completionUrl, requests }) =>
83− Effect.gen(function* () {
84− const receiver = yield* Effect.acquireRelease(
85− startOauthLoopbackRedirectServer({
86− completionUrl,
87− }),
88− (server) => server.close,
89− );
90−
91− const response = yield* Effect.tryPromise({
92− try: () =>
93− fetch(
94− `${receiver.redirectUri}?state=oauth-state&code=oauth-code`,
95− {
96− redirect: "follow",
97− signal: AbortSignal.timeout(10_000),
98− },
99− ),
100− catch: toError,
101− });
102−
103− expect(response.ok).toBe(true);
104− expect(requests).toEqual([
105− "/oauth/complete?sessionId=test-session&state=oauth-state&code=oauth-code",
106− ]);
107− }),
108− ),
109− );
110−});
packages/platform/sdk/src/runtime/auth/oauth-loopback.ts+0−106
@@ -1,106 +0,0 @@
1−import {
2− createServer,
3−} from "node:http";
4−
5−import * as Effect from "effect/Effect";
6−
7−const DEFAULT_LOOPBACK_TIMEOUT_MS = 10 * 60_000;
8−
9−export type OauthLoopbackRedirectServer = {
10− redirectUri: string;
11− close: Effect.Effect<void, Error, never>;
12−};
13−
14−const closeServer = (
15− server: ReturnType<typeof createServer>,
16−): Promise<void> =>
17− new Promise<void>((resolve, reject) => {
18− server.close((error) => {
19− if (error) {
20− reject(error);
21− return;
22− }
23− resolve();
24− });
25− });
26−
27−export const startOauthLoopbackRedirectServer = (input: {
28− completionUrl: string;
29− publicHost?: "localhost" | "127.0.0.1";
30− listenHost?: "127.0.0.1";
31− timeoutMs?: number;
32−}): Effect.Effect<OauthLoopbackRedirectServer, Error, never> =>
33− Effect.tryPromise({
34− try: () =>
35− new Promise<OauthLoopbackRedirectServer>((resolve, reject) => {
36− const publicHost = input.publicHost ?? "127.0.0.1";
37− const listenHost = input.listenHost ?? "127.0.0.1";
38− const completionUrl = new URL(input.completionUrl);
39− const server = createServer((request, response) => {
40− try {
41− const requestUrl = new URL(
42− request.url ?? "/",
43− `http://${publicHost}`,
44− );
45− const redirectUrl = new URL(completionUrl.toString());
46−
47− for (const [key, value] of requestUrl.searchParams.entries()) {
48− redirectUrl.searchParams.set(key, value);
49− }
50−
51− response.statusCode = 302;
52− response.setHeader("cache-control", "no-store");
53− response.setHeader("location", redirectUrl.toString());
54− response.end();
55− } catch (cause) {
56− const error = cause instanceof Error ? cause : new Error(String(cause));
57− response.statusCode = 500;
58− response.setHeader("content-type", "text/plain; charset=utf-8");
59− response.end(`OAuth redirect failed: ${error.message}`);
60− } finally {
61− void closeServer(server).catch(() => {});
62− }
63− });
64−
65− let timeout: NodeJS.Timeout | null = null;
66− const cleanup = (): Promise<void> => {
67− if (timeout !== null) {
68− clearTimeout(timeout);
69− timeout = null;
70− }
71− return closeServer(server).catch(() => undefined);
72− };
73−
74− server.once("error", (cause) => {
75− reject(
76− cause instanceof Error ? cause : new Error(String(cause)),
77− );
78− });
79−
80− server.listen(0, listenHost, () => {
81− const address = server.address();
82− if (!address || typeof address === "string") {
83− reject(new Error("Failed to resolve OAuth loopback port"));
84− return;
85− }
86−
87− timeout = setTimeout(() => {
88− void cleanup();
89− }, input.timeoutMs ?? DEFAULT_LOOPBACK_TIMEOUT_MS);
90− if (typeof timeout.unref === "function") {
91− timeout.unref();
92− }
93−
94− resolve({
95− redirectUri: `http://${publicHost}:${address.port}`,
96− close: Effect.tryPromise({
97− try: cleanup,
98− catch: (cause) =>
99− cause instanceof Error ? cause : new Error(String(cause)),
100− }),
101− });
102− });
103− }),
104− catch: (cause) =>
105− cause instanceof Error ? cause : new Error(String(cause)),
106− });
packages/platform/sdk/src/runtime/auth/oauth2-pkce.ts+0−1
@@ -1 +0,0 @@
1−export * from "@executor/auth-oauth2";
packages/sources/core/package.json+0−1
@@ -12,7 +12,6 @@ · 11 unmodified lines
1212 "typecheck": "bunx tsc --noEmit -p tsconfig.json"
1313 },
1414 "dependencies": {
15− "@executor/auth-oauth2": "workspace:*",
1615 "@executor/codemode-core": "workspace:*",
1716 "@executor/ir": "workspace:*",
1817 "@modelcontextprotocol/sdk": "^1.26.0",
plugins/google-discovery/sdk/index.ts+6−6
@@ -1,12 +1,6 @@
11 import * as Effect from "effect/Effect";
22 import * as Schema from "effect/Schema";
33
4−import {
5− buildOAuth2AuthorizationUrl,
6− createPkceCodeVerifier,
7− exchangeOAuth2AuthorizationCode,
8− refreshOAuth2AccessToken,
9−} from "@executor/auth-oauth2";
104 import {
115 createCatalogImportMetadata,
126 createSourceCatalogSyncResult,
@@ -58,6 +52,12 @@ import { · 45 unmodified lines
5852 type GoogleDiscoveryToolManifest,
5953 type GoogleDiscoveryToolProviderData,
6054 } from "./types";
55+import {
56+ buildOAuth2AuthorizationUrl,
57+ createPkceCodeVerifier,
58+ exchangeOAuth2AuthorizationCode,
59+ refreshOAuth2AccessToken,
60+} from "./oauth2";
6161
6262 const decodeStoredSourceData = Schema.decodeUnknownSync(
6363 GoogleDiscoveryStoredSourceDataSchema,
plugins/google-discovery/sdk/oauth2.tsrenamed from packages/auth/oauth2/src/index.ts+29−9
@@ -42,7 +42,10 @@ export const buildOAuth2AuthorizationUrl = (input: { · 41 unmodified lines
4242 url.searchParams.set("scope", input.scopes.join(" "));
4343 url.searchParams.set("state", input.state);
4444 url.searchParams.set("code_challenge_method", "S256");
45− url.searchParams.set("code_challenge", createPkceCodeChallenge(input.codeVerifier));
45+ url.searchParams.set(
46+ "code_challenge",
47+ createPkceCodeChallenge(input.codeVerifier),
48+ );
4649
4750 for (const [key, value] of Object.entries(input.extraParams ?? {})) {
4851 url.searchParams.set(key, value);
@@ -51,17 +54,23 @@ export const buildOAuth2AuthorizationUrl = (input: { · 2 unmodified lines
5154 return url.toString();
5255 };
5356
54−const parseOAuth2TokenResponse = async (response: Response): Promise<OAuth2TokenResponse> => {
57+const parseOAuth2TokenResponse = async (
58+ response: Response,
59+): Promise<OAuth2TokenResponse> => {
5560 const rawText = await response.text();
5661 let parsed: unknown;
5762 try {
5863 parsed = JSON.parse(rawText);
5964 } catch {
60− throw new Error(`OAuth token endpoint returned non-JSON response (${response.status})`);
65+ throw new Error(
66+ `OAuth token endpoint returned non-JSON response (${response.status})`,
67+ );
6168 }
6269
6370 if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
64− throw new Error(`OAuth token endpoint returned invalid JSON payload (${response.status})`);
71+ throw new Error(
72+ `OAuth token endpoint returned invalid JSON payload (${response.status})`,
73+ );
6574 }
6675
6776 const record = parsed as Record<string, unknown>;
@@ -72,7 +81,8 @@ const parseOAuth2TokenResponse = async (response: Response): Promise<OAuth2Token · 4 unmodified lines
7281
7382 if (!response.ok) {
7483 const description =
75− typeof record.error_description === "string" && record.error_description.length > 0
84+ typeof record.error_description === "string"
85+ && record.error_description.length > 0
7686 ? record.error_description
7787 : typeof record.error === "string" && record.error.length > 0
7888 ? record.error
@@ -86,8 +96,12 @@ const parseOAuth2TokenResponse = async (response: Response): Promise<OAuth2Token · 7 unmodified lines
8696
8797 return {
8898 access_token: accessToken,
89− token_type: typeof record.token_type === "string" ? record.token_type : undefined,
90− refresh_token: typeof record.refresh_token === "string" ? record.refresh_token : undefined,
99+ token_type:
100+ typeof record.token_type === "string" ? record.token_type : undefined,
101+ refresh_token:
102+ typeof record.refresh_token === "string"
103+ ? record.refresh_token
104+ : undefined,
91105 expires_in: typeof record.expires_in === "number"
92106 ? record.expires_in
93107 : typeof record.expires_in === "string"
@@ -137,7 +151,10 @@ export const exchangeOAuth2AuthorizationCode = (input: { · 43 unmodified lines
137151 code: input.code,
138152 });
139153
140− if (input.clientAuthentication === "client_secret_post" && input.clientSecret) {
154+ if (
155+ input.clientAuthentication === "client_secret_post"
156+ && input.clientSecret
157+ ) {
141158 body.set("client_secret", input.clientSecret);
142159 }
143160
@@ -162,7 +179,10 @@ export const refreshOAuth2AccessToken = (input: { · 18 unmodified lines
162179 refresh_token: input.refreshToken,
163180 });
164181
165− if (input.clientAuthentication === "client_secret_post" && input.clientSecret) {
182+ if (
183+ input.clientAuthentication === "client_secret_post"
184+ && input.clientSecret
185+ ) {
166186 body.set("client_secret", input.clientSecret);
167187 }
168188
plugins/google-discovery/sdk/package.json+0−1
@@ -13,7 +13,6 @@ · 12 unmodified lines
1313 },
1414 "dependencies": {
1515 "@effect/platform": "catalog:",
16− "@executor/auth-oauth2": "workspace:*",
1716 "@executor/codemode-core": "workspace:*",
1817 "@executor/ir": "workspace:*",
1918 "@executor/platform-sdk": "workspace:*",