diff --git a/packages/ui/app/src/resolver/ApiDefinitionResolver.ts b/packages/ui/app/src/resolver/ApiDefinitionResolver.ts index f799e7995e..3242c941a9 100644 --- a/packages/ui/app/src/resolver/ApiDefinitionResolver.ts +++ b/packages/ui/app/src/resolver/ApiDefinitionResolver.ts @@ -429,24 +429,21 @@ export class ApiDefinitionResolver { return { auth, headers }; } - const filteredHeaders: ResolvedObjectProperty[] = []; - for (const header of headers) { if ( header.key.toLowerCase() === "authorization" || header.key.toLowerCase().includes("api-key") || header.key.toLowerCase().includes("apikey") ) { - auth = { + const auth: APIV1Read.ApiAuth = { type: "header", headerWireValue: header.key, }; - continue; + return { auth, headers: headers.filter((h) => h.key !== header.key) }; } - filteredHeaders.push(header); } - return { auth, headers: filteredHeaders }; + return { auth: undefined, headers }; } async resolveWebsocketChannel(websocket: FlattenedWebSocketChannel): Promise { diff --git a/packages/ui/app/src/resolver/__test__/ApiDefinitionResolver.test.ts b/packages/ui/app/src/resolver/__test__/ApiDefinitionResolver.test.ts index 51ec94d0cc..6bda955e12 100644 --- a/packages/ui/app/src/resolver/__test__/ApiDefinitionResolver.test.ts +++ b/packages/ui/app/src/resolver/__test__/ApiDefinitionResolver.test.ts @@ -4,6 +4,7 @@ import fs from "fs"; import path from "path"; import { DEFAULT_FEATURE_FLAGS } from "../../contexts/FeatureFlagContext"; import { ApiDefinitionResolver } from "../ApiDefinitionResolver"; +import { ResolvedEndpointDefinition } from "../types"; describe("resolveApiDefinition", () => { it("should finish resolving", async () => { @@ -22,4 +23,27 @@ describe("resolveApiDefinition", () => { ); expect(resolved).toMatchSnapshot(); }); + + it("should resolve authed and unauthed endpoints", async () => { + const fixturePath = path.join(__dirname, "fixtures/authed.json"); + const content = fs.readFileSync(fixturePath, "utf-8"); + + const fixture = JSON.parse(content) as APIV1Read.ApiDefinition; + const flattened = flattenApiDefinition(fixture, [], undefined, "documentation.sayari.com"); + const resolved = await ApiDefinitionResolver.resolve( + "API Reference", + flattened, + {}, + undefined, + DEFAULT_FEATURE_FLAGS, + "documentation.sayari.com", + ); + expect(resolved).toMatchSnapshot(); + expect((resolved.items[0] as ResolvedEndpointDefinition).auth).toBeUndefined(); + expect((resolved.items[1] as ResolvedEndpointDefinition).auth?.type).toBe("bearerAuth"); + expect((resolved.items[2] as ResolvedEndpointDefinition).auth).toEqual({ + type: "header", + headerWireValue: "test-api-key", + }); + }); }); diff --git a/packages/ui/app/src/resolver/__test__/__snapshots__/ApiDefinitionResolver.test.ts.snap b/packages/ui/app/src/resolver/__test__/__snapshots__/ApiDefinitionResolver.test.ts.snap index dcca7b3e46..5cc8b1d5b8 100644 --- a/packages/ui/app/src/resolver/__test__/__snapshots__/ApiDefinitionResolver.test.ts.snap +++ b/packages/ui/app/src/resolver/__test__/__snapshots__/ApiDefinitionResolver.test.ts.snap @@ -125,3 +125,312 @@ exports[`resolveApiDefinition > should finish resolving 1`] = ` }, } `; + +exports[`resolveApiDefinition > should resolve authed and unauthed endpoints 1`] = ` +{ + "api": "054ca3d6-33a5-4d53-a813-f2a33e4062cc", + "auth": { + "tokenName": "token", + "type": "bearerAuth", + }, + "items": [ + { + "apiPackageId": "054ca3d6-33a5-4d53-a813-f2a33e4062cc", + "apiSectionId": "054ca3d6-33a5-4d53-a813-f2a33e4062cc", + "auth": undefined, + "availability": undefined, + "defaultEnvironment": { + "baseUrl": "https://api.sayari.com", + "id": "Production", + }, + "description": "Hit the auth endpoint to get a bearer token", + "environments": [ + { + "baseUrl": "https://api.sayari.com", + "id": "Production", + }, + ], + "errors": [], + "examples": [], + "headers": [], + "id": "getToken", + "method": "POST", + "path": [ + { + "type": "literal", + "value": "", + }, + { + "type": "literal", + "value": "/oauth/token", + }, + ], + "pathParameters": [], + "queryParameters": [], + "requestBody": { + "availability": undefined, + "contentType": "application/json", + "description": undefined, + "shape": { + "availability": undefined, + "description": undefined, + "extends": [], + "name": undefined, + "properties": [ + { + "availability": undefined, + "description": undefined, + "hidden": false, + "key": "client_id", + "valueShape": { + "availability": undefined, + "description": undefined, + "type": "primitive", + "value": { + "type": "string", + }, + }, + }, + { + "availability": undefined, + "description": undefined, + "hidden": false, + "key": "client_secret", + "valueShape": { + "availability": undefined, + "description": undefined, + "type": "primitive", + "value": { + "type": "string", + }, + }, + }, + { + "availability": undefined, + "description": undefined, + "hidden": false, + "key": "audience", + "valueShape": { + "availability": undefined, + "description": undefined, + "type": "literal", + "value": { + "type": "stringLiteral", + "value": "sayari.com", + }, + }, + }, + { + "availability": undefined, + "description": undefined, + "hidden": false, + "key": "grant_type", + "valueShape": { + "availability": undefined, + "description": undefined, + "type": "literal", + "value": { + "type": "stringLiteral", + "value": "client_credentials", + }, + }, + }, + ], + "type": "object", + }, + }, + "responseBody": { + "availability": undefined, + "description": undefined, + "shape": { + "type": "reference", + "typeId": "type_auth:AuthResponse", + }, + "statusCode": 200, + }, + "slug": [ + "get-token", + ], + "snippetTemplates": undefined, + "stream": undefined, + "title": "Get Token", + "type": "endpoint", + }, + { + "apiPackageId": "054ca3d6-33a5-4d53-a813-f2a33e4062cc", + "apiSectionId": "054ca3d6-33a5-4d53-a813-f2a33e4062cc", + "auth": { + "tokenName": "token", + "type": "bearerAuth", + }, + "availability": undefined, + "defaultEnvironment": { + "baseUrl": "https://api.sayari.com", + "id": "Production", + }, + "description": undefined, + "environments": [ + { + "baseUrl": "https://api.sayari.com", + "id": "Production", + }, + ], + "errors": [], + "examples": [], + "headers": [], + "id": "testAuth", + "method": "POST", + "path": [ + { + "type": "literal", + "value": "/test/authed", + }, + ], + "pathParameters": [], + "queryParameters": [], + "requestBody": { + "availability": undefined, + "contentType": "text/plain", + "description": undefined, + "shape": { + "availability": undefined, + "description": undefined, + "type": "unknown", + }, + }, + "responseBody": { + "availability": undefined, + "description": undefined, + "shape": { + "availability": undefined, + "description": undefined, + "type": "unknown", + }, + "statusCode": 200, + }, + "slug": [ + "test-authed", + ], + "snippetTemplates": undefined, + "stream": undefined, + "title": "Get Token", + "type": "endpoint", + }, + { + "apiPackageId": "054ca3d6-33a5-4d53-a813-f2a33e4062cc", + "apiSectionId": "054ca3d6-33a5-4d53-a813-f2a33e4062cc", + "auth": { + "headerWireValue": "test-api-key", + "type": "header", + }, + "availability": undefined, + "defaultEnvironment": { + "baseUrl": "https://api.sayari.com", + "id": "Production", + }, + "description": undefined, + "environments": [ + { + "baseUrl": "https://api.sayari.com", + "id": "Production", + }, + ], + "errors": [], + "examples": [], + "headers": [], + "id": "testHeaderAuth", + "method": "POST", + "path": [ + { + "type": "literal", + "value": "/test/authed", + }, + ], + "pathParameters": [], + "queryParameters": [], + "requestBody": { + "availability": undefined, + "contentType": "text/plain", + "description": undefined, + "shape": { + "availability": undefined, + "description": undefined, + "type": "unknown", + }, + }, + "responseBody": { + "availability": undefined, + "description": undefined, + "shape": { + "availability": undefined, + "description": undefined, + "type": "unknown", + }, + "statusCode": 200, + }, + "slug": [ + "test-header-auth", + ], + "snippetTemplates": undefined, + "stream": undefined, + "title": "Get Token", + "type": "endpoint", + }, + ], + "slug": [], + "type": "rootPackage", + "types": { + "type_auth:AuthResponse": { + "availability": undefined, + "description": undefined, + "extends": [], + "name": "AuthResponse", + "properties": [ + { + "availability": undefined, + "description": "The bearer token you will pass in to subsequent API calls to authenticate.", + "hidden": false, + "key": "access_token", + "valueShape": { + "availability": undefined, + "description": undefined, + "type": "primitive", + "value": { + "type": "string", + }, + }, + }, + { + "availability": undefined, + "description": "Tells you how long (in seconds) until your bearer token expires.", + "hidden": false, + "key": "expires_in", + "valueShape": { + "availability": undefined, + "description": undefined, + "type": "primitive", + "value": { + "type": "integer", + }, + }, + }, + { + "availability": undefined, + "description": "Will always be "Bearer"", + "hidden": false, + "key": "token_type", + "valueShape": { + "availability": undefined, + "description": undefined, + "type": "primitive", + "value": { + "type": "string", + }, + }, + }, + ], + "type": "object", + }, + }, +} +`; diff --git a/packages/ui/app/src/resolver/__test__/fixtures/authed.json b/packages/ui/app/src/resolver/__test__/fixtures/authed.json new file mode 100644 index 0000000000..5cf380b15f --- /dev/null +++ b/packages/ui/app/src/resolver/__test__/fixtures/authed.json @@ -0,0 +1,251 @@ +{ + "id": "054ca3d6-33a5-4d53-a813-f2a33e4062cc", + "rootPackage": { + "endpoints": [ + { + "environments": [ + { + "id": "Production", + "baseUrl": "https://api.sayari.com" + } + ], + "defaultEnvironment": "Production", + "urlSlug": "get-token", + "method": "POST", + "id": "getToken", + "originalEndpointId": "getToken", + "name": "Get Token", + "path": { + "pathParameters": [], + "parts": [ + { + "type": "literal", + "value": "" + }, + { + "type": "literal", + "value": "/oauth/token" + } + ] + }, + "queryParameters": [], + "headers": [], + "request": { + "contentType": "application/json", + "type": { + "type": "object", + "extends": [], + "properties": [ + { + "key": "client_id", + "valueType": { + "type": "primitive", + "value": { + "type": "string" + } + } + }, + { + "key": "client_secret", + "valueType": { + "type": "primitive", + "value": { + "type": "string" + } + } + }, + { + "key": "audience", + "valueType": { + "type": "literal", + "value": { + "type": "stringLiteral", + "value": "sayari.com" + } + } + }, + { + "key": "grant_type", + "valueType": { + "type": "literal", + "value": { + "type": "stringLiteral", + "value": "client_credentials" + } + } + } + ] + } + }, + "response": { + "type": { + "type": "reference", + "value": { + "type": "id", + "value": "type_auth:AuthResponse" + } + } + }, + "errors": [], + "errorsV2": [], + "examples": [], + "description": "Hit the auth endpoint to get a bearer token", + "authed": false + }, + { + "environments": [ + { + "id": "Production", + "baseUrl": "https://api.sayari.com" + } + ], + "defaultEnvironment": "Production", + "urlSlug": "test-authed", + "method": "POST", + "id": "testAuth", + "originalEndpointId": "testAuth", + "name": "Get Token", + "path": { + "pathParameters": [], + "parts": [ + { + "type": "literal", + "value": "/test/authed" + } + ] + }, + "queryParameters": [], + "headers": [], + "request": { + "contentType": "text/plain", + "type": { + "type": "primitive", + "value": { + "type": "string" + } + } + }, + "response": { + "type": { + "type": "primitive", + "value": { + "type": "string" + } + } + }, + "errors": [], + "errorsV2": [], + "examples": [], + "authed": true + }, + { + "environments": [ + { + "id": "Production", + "baseUrl": "https://api.sayari.com" + } + ], + "defaultEnvironment": "Production", + "urlSlug": "test-header-auth", + "method": "POST", + "id": "testHeaderAuth", + "originalEndpointId": "testHeaderAuth", + "name": "Get Token", + "path": { + "pathParameters": [], + "parts": [ + { + "type": "literal", + "value": "/test/authed" + } + ] + }, + "queryParameters": [], + "headers": [ + { + "key": "test-api-key", + "type": { + "type": "primitive", + "value": { + "type": "string" + } + } + } + ], + "request": { + "contentType": "text/plain", + "type": { + "type": "primitive", + "value": { + "type": "string" + } + } + }, + "response": { + "type": { + "type": "primitive", + "value": { + "type": "string" + } + } + }, + "errors": [], + "errorsV2": [], + "examples": [], + "authed": false + } + ], + "subpackages": [], + "types": [], + "webhooks": [], + "websockets": [] + }, + "types": { + "type_auth:AuthResponse": { + "name": "AuthResponse", + "shape": { + "type": "object", + "extends": [], + "properties": [ + { + "description": "The bearer token you will pass in to subsequent API calls to authenticate.", + "key": "access_token", + "valueType": { + "type": "primitive", + "value": { + "type": "string" + } + } + }, + { + "description": "Tells you how long (in seconds) until your bearer token expires.", + "key": "expires_in", + "valueType": { + "type": "primitive", + "value": { + "type": "integer" + } + } + }, + { + "description": "Will always be \"Bearer\"", + "key": "token_type", + "valueType": { + "type": "primitive", + "value": { + "type": "string" + } + } + } + ] + } + } + }, + "subpackages": {}, + "auth": { + "type": "bearerAuth", + "tokenName": "token" + }, + "hasMultipleBaseUrls": false, + "globalHeaders": [] +}