Skip to content

Commit

Permalink
fix auth inheritance
Browse files Browse the repository at this point in the history
  • Loading branch information
jackkav committed Jun 10, 2024
1 parent 723d4b3 commit 02205c0
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 51 deletions.
3 changes: 2 additions & 1 deletion packages/insomnia/src/network/network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { MockServer } from '../models/mock-server';
import type { Request, RequestAuthentication, RequestHeader, RequestParameter } from '../models/request';
import { isRequestGroup, RequestGroup } from '../models/request-group';
import type { Settings } from '../models/settings';
import { WebSocketRequest } from '../models/websocket-request';
import { isWorkspace, Workspace } from '../models/workspace';
import * as pluginContexts from '../plugins/context/index';
import * as plugins from '../plugins/index';
Expand All @@ -41,7 +42,7 @@ import { cancellableCurlRequest, cancellableRunScript } from './cancellation';
import { filterClientCertificates } from './certificate';
import { addSetCookiesToToughCookieJar } from './set-cookie-util';

export const getOrInheritAuthentication = ({ request, requestGroups }: { request: Request; requestGroups: RequestGroup[] }): RequestAuthentication | {} => {
export const getOrInheritAuthentication = ({ request, requestGroups }: { request: Request | WebSocketRequest; requestGroups: RequestGroup[] }): RequestAuthentication | {} => {
const hasValidAuth = getAuthObjectOrNull(request.authentication) && isAuthEnabled(request.authentication);
if (hasValidAuth) {
return request.authentication;
Expand Down
122 changes: 72 additions & 50 deletions packages/insomnia/src/ui/components/rendered-query-string.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import classNames from 'classnames';
import React, { FC, useState } from 'react';
import { useAsync } from 'react-use';
import React, { FC, useEffect, useState } from 'react';
import styled from 'styled-components';

import { database as db } from '../../common/database';
import * as models from '../../models';
import { PATH_PARAMETER_REGEX, Request, RequestAuthentication, RequestParameter } from '../../models/request';
import { isRequestGroup, RequestGroup } from '../../models/request-group';
import { WebSocketRequest } from '../../models/websocket-request';
import { getAuthObjectOrNull, isAuthEnabled } from '../../network/authentication';
import { getOrInheritAuthentication } from '../../network/network';
import { buildQueryStringFromParams, joinUrlAndQueryString, smartEncodeUrl } from '../../utils/url/querystring';
import { useNunjucks } from '../context/nunjucks/use-nunjucks';
import { CopyButton as _CopyButton } from './base/copy-button';
Expand Down Expand Up @@ -33,65 +37,83 @@ interface Props {

const defaultPreview = '...';

function getQueryParamsFromAuth(auth: RequestAuthentication | {}): RequestParameter[] {
if (!('type' in auth)) {
return [];
const addApiKeyToParams = (requestAuth: RequestAuthentication) => {
const shouldAddAuthParamsToQuery = requestAuth.type === 'apikey' && requestAuth.addTo === 'queryParams';
return shouldAddAuthParamsToQuery && requestAuth.key && requestAuth.value ?
[{ name: requestAuth.key, value: requestAuth.value }] : [];
};

async function getQueryParamsFromAuth(request: Request | WebSocketRequest): Promise<RequestParameter[]> {
const requestAuth = getAuthObjectOrNull(request.authentication);
const hasAuthSetOnRequest = requestAuth !== null && isAuthEnabled(request.authentication);
if (hasAuthSetOnRequest) {
return addApiKeyToParams(requestAuth);
}

const shouldAddAuthParamsToQuery = auth.type === 'apikey' && auth.addTo === 'queryParams';
return shouldAddAuthParamsToQuery && auth.key && auth.value ?
[{ name: auth.key, value: auth.value }] :
[];
const ancestors = await db.withAncestors<Request | WebSocketRequest | RequestGroup>(request, [
models.requestGroup.type,
]);
const requestGroups = ancestors.filter(isRequestGroup);
const auth = getOrInheritAuthentication({ request, requestGroups });
const closestAuth = getAuthObjectOrNull(auth);
if (!closestAuth) {
return [];
}
return addApiKeyToParams(closestAuth);
}

export const RenderedQueryString: FC<Props> = ({ request }) => {
const [previewString, setPreviewString] = useState(defaultPreview);
const { handleRender } = useNunjucks();

useAsync(async () => {
const enabledParameters = request.parameters.filter(({ disabled }) => !disabled);
const authQueryParams = getQueryParamsFromAuth(request.authentication);

try {
const result = await handleRender({
url: request.url,
parameters: enabledParameters,
pathParameters: request.pathParameters,
authQueryParams,
});

if (!result) {
return;
}

const { parameters, pathParameters, authQueryParams: renderedAuthQueryParams } = result;
let { url } = result;

if (pathParameters) {
// Replace path parameters in URL with their rendered values
// Path parameters are path segments that start with a colon, e.g. :id
url = url.replace(PATH_PARAMETER_REGEX, match => {
const pathParam = match.replace('\/:', '');
const param = pathParameters?.find(p => p.name === pathParam);

if (param && param.value) {
return `/${encodeURIComponent(param.value)}`;
}
// The parameter should also be URL encoded
return match;
useEffect(() => {
const fn = async () => {
const enabledParameters = request.parameters.filter(({ disabled }) => !disabled);
const authQueryParams = await getQueryParamsFromAuth(request);

try {
const result = await handleRender({
url: request.url,
parameters: enabledParameters,
pathParameters: request.pathParameters,
authQueryParams,
});

if (!result) {
return;
}

const { parameters, pathParameters, authQueryParams: renderedAuthQueryParams } = result;
let { url } = result;

if (pathParameters) {
// Replace path parameters in URL with their rendered values
// Path parameters are path segments that start with a colon, e.g. :id
url = url.replace(PATH_PARAMETER_REGEX, match => {
const pathParam = match.replace('\/:', '');
const param = pathParameters?.find(p => p.name === pathParam);

if (param && param.value) {
return `/${encodeURIComponent(param.value)}`;
}
// The parameter should also be URL encoded
return match;
});
}

const mergedParams = [...parameters, ...renderedAuthQueryParams];
const qs = buildQueryStringFromParams(mergedParams);
const fullUrl = joinUrlAndQueryString(url, qs);
const encoded = smartEncodeUrl(fullUrl, request.settingEncodeUrl);
setPreviewString(encoded === '' ? defaultPreview : encoded);
} catch (error: unknown) {
console.error(error);
setPreviewString(defaultPreview);
}
};
fn();

const mergedParams = [...parameters, ...renderedAuthQueryParams];
const qs = buildQueryStringFromParams(mergedParams);
const fullUrl = joinUrlAndQueryString(url, qs);
const encoded = smartEncodeUrl(fullUrl, request.settingEncodeUrl);
setPreviewString(encoded === '' ? defaultPreview : encoded);
} catch (error: unknown) {
console.error(error);
setPreviewString(defaultPreview);
}
}, [request.parameters, request.url, request.pathParameters, request.settingEncodeUrl, handleRender, request.authentication]);
}, [request.parameters, request.url, request.pathParameters, request.settingEncodeUrl, handleRender, request.authentication, request]);

const className = previewString === defaultPreview ? 'super-duper-faint' : 'selectable force-wrap';

Expand Down

0 comments on commit 02205c0

Please sign in to comment.