History

fix openapi oauth cleanup (#418)

Rhys Sullivan committed 6 months ago

Commit 96a33621 parent b965f7b4 files · +34 −4Browse files

Unified · Split

4 files
  1. packages/plugins/openapi/src/react/AddOpenApiSource.tsx +1 −1
  2. packages/plugins/openapi/src/react/EditOpenApiSource.tsx +2 −3
  3. packages/plugins/workos-vault/src/sdk/secret-store.test.ts +30 −0
  4. packages/plugins/workos-vault/src/sdk/secret-store.ts +1 −0
packages/plugins/openapi/src/react/AddOpenApiSource.tsx+1−1
@@ -95,7 +95,7 @@ const substituteUrlVariables = (url: string, values: Record<string, string>): st · 94 unmodified lines
95 return out;95 return out;
96};96};
97 97
98const openApiOAuthConnectionId = (98export const openApiOAuthConnectionId = (
99 namespaceSlug: string,99 namespaceSlug: string,
100 flow: OAuth2Preset["flow"],100 flow: OAuth2Preset["flow"],
101): string =>101): string =>
packages/plugins/openapi/src/react/EditOpenApiSource.tsx+2−3
@@ -41,6 +41,7 @@ import { · 40 unmodified lines
41 OPENAPI_OAUTH_CALLBACK_PATH,41 OPENAPI_OAUTH_CALLBACK_PATH,
42 OPENAPI_OAUTH_CHANNEL,42 OPENAPI_OAUTH_CHANNEL,
43 OPENAPI_OAUTH_POPUP_NAME,43 OPENAPI_OAUTH_POPUP_NAME,
44 openApiOAuthConnectionId,
44 resolveOAuthUrl,45 resolveOAuthUrl,
45} from "./AddOpenApiSource";46} from "./AddOpenApiSource";
46import { oauth2ClientSecretSlot } from "../sdk/store";47import { oauth2ClientSecretSlot } from "../sdk/store";
@@ -393,9 +394,7 @@ export default function EditOpenApiSource(props: { · 346 unmodified lines
393 const connectionId =394 const connectionId =
394 existingConnection && isConnectionBindingValue(existingConnection.value)395 existingConnection && isConnectionBindingValue(existingConnection.value)
395 ? existingConnection.value.connectionId396 ? existingConnection.value.connectionId
396 : ConnectionId.make(397 : ConnectionId.make(openApiOAuthConnectionId(props.sourceId, oauth2.flow));
397 `openapi-oauth-${slugify(props.sourceId)}-${slugify(oauth2.securitySchemeName)}-${slugify(targetScope)}`,
398 );
399 398
400 setBusyKey(`${targetScope}:${oauth2.connectionSlot}:connect`);399 setBusyKey(`${targetScope}:${oauth2.connectionSlot}:connect`);
401 setError(null);400 setError(null);
packages/plugins/workos-vault/src/sdk/secret-store.test.ts+30−0
@@ -64,6 +64,7 @@ const makeMetadata = ( · 63 unmodified lines
64const makeFakeClient = (options?: {64const makeFakeClient = (options?: {
65 readonly conflictOnNextSecretUpdate?: boolean;65 readonly conflictOnNextSecretUpdate?: boolean;
66 readonly rejectNamesWithColon?: boolean;66 readonly rejectNamesWithColon?: boolean;
67 readonly rejectReadNamesLongerThan?: number;
67}): WorkOSVaultClient => {68}): WorkOSVaultClient => {
68 const objects = new Map<string, WorkOSVaultObject>();69 const objects = new Map<string, WorkOSVaultObject>();
69 let sequence = 0;70 let sequence = 0;
@@ -106,6 +107,12 @@ const makeFakeClient = (options?: { · 36 unmodified lines
106 if (options?.rejectNamesWithColon && name.includes(":")) {107 if (options?.rejectNamesWithColon && name.includes(":")) {
107 throw new FakeInvalidRequestError(`Invalid object name "${name}"`);108 throw new FakeInvalidRequestError(`Invalid object name "${name}"`);
108 }109 }
110 if (
111 options?.rejectReadNamesLongerThan !== undefined &&
112 name.length > options.rejectReadNamesLongerThan
113 ) {
114 throw new FakeInvalidRequestError(`Invalid object name "${name}"`);
115 }
109 const object = objects.get(name);116 const object = objects.get(name);
110 if (!object) throw new FakeNotFoundError(`Object "${name}" not found`);117 if (!object) throw new FakeNotFoundError(`Object "${name}" not found`);
111 return object;118 return object;
@@ -260,6 +267,29 @@ describe("WorkOS Vault secret provider", () => { · 148 unmodified lines
260 }),267 }),
261 );268 );
262 269
270 it.effect("treats invalid Vault object names as missing during removal", () =>
271 Effect.gen(function* () {
272 const client = makeFakeClient({ rejectReadNamesLongerThan: 80 });
273 const executor = yield* makeExecutor(client);
274 const longSecretId = SecretId.make(
275 "openapi-oauth-dealcloud-api-oauth2-user-org-user-01kp6xm1zpvqvtpj77f0yv4eax.access_token",
276 );
277
278 yield* executor.secrets.set(
279 new SetSecretInput({
280 id: longSecretId,
281 scope: ScopeId.make("test-scope"),
282 name: "Long connection token",
283 value: "token",
284 }),
285 );
286
287 yield* executor.secrets.remove(longSecretId);
288
289 expect(yield* executor.secrets.list()).toHaveLength(0);
290 }),
291 );
292
263 it.effect("retries secret value writes on 409 version conflicts", () =>293 it.effect("retries secret value writes on 409 version conflicts", () =>
264 Effect.gen(function* () {294 Effect.gen(function* () {
265 // Inject one conflict on the next update against `/secrets/conflict`.295 // Inject one conflict on the next update against `/secrets/conflict`.
packages/plugins/workos-vault/src/sdk/secret-store.ts+1−0
@@ -238,6 +238,7 @@ const loadSecretObject = ( · 237 unmodified lines
238): Effect.Effect<WorkOSVaultObject | null, WorkOSVaultClientError, never> =>238): Effect.Effect<WorkOSVaultObject | null, WorkOSVaultClientError, never> =>
239 client.readObjectByName(secretObjectName(prefix, scopeId, secretId)).pipe(239 client.readObjectByName(secretObjectName(prefix, scopeId, secretId)).pipe(
240 Effect.catchAll((error) => {240 Effect.catchAll((error) => {
241 if (isStatusError(error, 400)) return Effect.succeed(null);
241 if (!isStatusError(error, 404)) return Effect.fail(error);242 if (!isStatusError(error, 404)) return Effect.fail(error);
242 243
243 const encodedName = secretObjectName(prefix, scopeId, secretId);244 const encodedName = secretObjectName(prefix, scopeId, secretId);