From f87f3b96b96e820c58906b6adaadf91bc5f7a953 Mon Sep 17 00:00:00 2001 From: Saurav Sahu Date: Mon, 2 Aug 2021 10:15:12 +0530 Subject: [PATCH] (feat) add request options strict ssl (#27) * (wip) add request options tab * (improv) make options value setter dynamic * (improv) make strictSSL option a string * (improv) expose request options from webview * (feat) modify axios call based on strictSSL option --- src/extension.ts | 10 ++++- webview/components/RequestBar/index.tsx | 3 ++ .../components/RequestOptionsWindow/index.tsx | 3 ++ webview/constants/request-options.ts | 4 ++ .../requestOptions/RequestOptions/index.tsx | 42 +++++++++++++++++++ .../requestOptions/RequestOptions/styles.css | 27 ++++++++++++ .../requestOptions/requestOptionsSlice.ts | 39 +++++++++++++++++ webview/redux/store.ts | 2 + 8 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 webview/features/requestOptions/RequestOptions/index.tsx create mode 100644 webview/features/requestOptions/RequestOptions/styles.css create mode 100644 webview/features/requestOptions/requestOptionsSlice.ts diff --git a/src/extension.ts b/src/extension.ts index 0927a51..565fabd 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -3,6 +3,8 @@ import * as vscode from "vscode"; import * as fs from "fs"; import axios from "axios"; +import * as https from 'https'; +import { RequestOptions } from "../webview/features/requestOptions/requestOptionsSlice"; // this method is called when your extension is activated // your extension is activated the very first time the command is executed @@ -56,7 +58,7 @@ export function activate(context: vscode.ExtensionContext) { ); panel.webview.onDidReceiveMessage( - ({ method, url, headers, body, auth }) => { + ({ method, url, headers, body, auth, options }) => { if (!url) { panel.webview.postMessage({ type: "response", @@ -116,6 +118,12 @@ export function activate(context: vscode.ExtensionContext) { headersObj["Content-Type"] = "application/json"; } + // Options Section + let requestOptions = options as RequestOptions; + + // Option 1. StrictSSL + https.globalAgent.options.rejectUnauthorized = (requestOptions.strictSSL === "yes"); + axios({ method, url, diff --git a/webview/components/RequestBar/index.tsx b/webview/components/RequestBar/index.tsx index c944d52..4421260 100644 --- a/webview/components/RequestBar/index.tsx +++ b/webview/components/RequestBar/index.tsx @@ -8,6 +8,7 @@ import { selectRequestBody } from "../../features/requestBody/requestBodySlice"; import { selectRequestHeaders } from "../../features/requestHeader/requestHeaderSlice"; import { selectRequestUrl } from "../../features/requestUrl/requestUrlSlice"; import { selectRequestMethod } from "../../features/requestMethod/requestMethodSlice"; +import { selectRequestOptions } from "../../features/requestOptions/requestOptionsSlice"; import { useAppDispatch, useAppSelector } from "../../redux/hooks"; import "./styles.css"; @@ -19,6 +20,7 @@ export const RequestBar = () => { const requestBody = useAppSelector(selectRequestBody); const requestUrl = useAppSelector(selectRequestUrl); const requestAuth = useAppSelector(selectRequestAuth); + const requestOptions = useAppSelector(selectRequestOptions); return (
{ body: requestBody, headers: requestHeaders, url: requestUrl, + options: requestOptions }); e.preventDefault(); }} diff --git a/webview/components/RequestOptionsWindow/index.tsx b/webview/components/RequestOptionsWindow/index.tsx index bcbf6c7..6232a97 100644 --- a/webview/components/RequestOptionsWindow/index.tsx +++ b/webview/components/RequestOptionsWindow/index.tsx @@ -4,6 +4,7 @@ import { RequestAuth } from "../../features/requestAuth/RequestAuth"; import { Body } from "../../features/requestBody/RequestBody"; import { Headers } from "../../features/requestHeader/HeadersWindow"; import { CodeSnippet } from "../../features/codeGen/CodeSnippet"; +import { RequestOptions } from "../../features/requestOptions/RequestOptions"; import * as propTypes from "prop-types"; import "./styles.css"; @@ -21,6 +22,8 @@ export const RequestOptionsWindow = (props) => { ) : selected === "code" ? ( + ) : selected === "options" ? ( + ) : null} ); diff --git a/webview/constants/request-options.ts b/webview/constants/request-options.ts index 9e794f7..c05368d 100644 --- a/webview/constants/request-options.ts +++ b/webview/constants/request-options.ts @@ -15,4 +15,8 @@ export const requestOptions = [ name: "Body", value: "body", }, + { + name: "Options", + value: "options", + }, ]; diff --git a/webview/features/requestOptions/RequestOptions/index.tsx b/webview/features/requestOptions/RequestOptions/index.tsx new file mode 100644 index 0000000..aebea98 --- /dev/null +++ b/webview/features/requestOptions/RequestOptions/index.tsx @@ -0,0 +1,42 @@ +import * as React from 'react'; +import { useDispatch } from 'react-redux'; +import { useAppSelector } from '../../../redux/hooks'; +import { requestOptionsUpdated, selectRequestOptions, requestOptionsList } from '../requestOptionsSlice'; +import "./styles.css"; + +export const RequestOptions = () => { + const requestOptions = useAppSelector(selectRequestOptions) + const dispatch = useDispatch() + + return ( +
+
+ { + requestOptionsList.map(({ name, value, type, ...optionDetails }) => ( + +
{`${name}: `}
+ { + type === 'select' ? ( + + ) : null + // Note: Augment this switch later with different renderers for + // different types of options + } +
+ )) + } +
+
+ ) +} \ No newline at end of file diff --git a/webview/features/requestOptions/RequestOptions/styles.css b/webview/features/requestOptions/RequestOptions/styles.css new file mode 100644 index 0000000..2bb19e4 --- /dev/null +++ b/webview/features/requestOptions/RequestOptions/styles.css @@ -0,0 +1,27 @@ +.req-options-wrapper { + margin-top: 15px; +} + +.options { + display: flex; + align-items: center; +} + +.req-option-label { + font-size: var(--default-font-size); + color: var(--default-text); + padding-right: 12px; +} + +.req-option-switch { + padding: 4px; + display: inline-block; + font-weight: 600; + outline: none; + border: var(--default-border-size) solid var(--border); + border-radius: 2px; + background-color: var(--background); + color: var(--default-text-light); + cursor: pointer; + font-size: var(--default-font-size); + } \ No newline at end of file diff --git a/webview/features/requestOptions/requestOptionsSlice.ts b/webview/features/requestOptions/requestOptionsSlice.ts new file mode 100644 index 0000000..69e3825 --- /dev/null +++ b/webview/features/requestOptions/requestOptionsSlice.ts @@ -0,0 +1,39 @@ +import { createSlice, PayloadAction } from "@reduxjs/toolkit"; +import { RootState } from "../../redux/store"; + +export const requestOptionsList = [ + { + name: "Strict SSL", + value: "strictSSL", + type: 'select', + options: [ + { key: "yes", value: "Yes" }, + { key: "no", value: "No" } + ], + default: "Yes" + } +] + +export interface RequestOptions { + strictSSL: string +} + +const initialState = { + strictSSL: "yes" +}; + +const requestOptionsSlice = createSlice({ + name: "requestOptions", + initialState, + reducers: { + requestOptionsUpdated(_, action: PayloadAction) { + return action.payload; + }, + }, +}); + +export const { requestOptionsUpdated } = requestOptionsSlice.actions; + +export const selectRequestOptions = (state: RootState) => state.requestOptions; + +export default requestOptionsSlice.reducer; diff --git a/webview/redux/store.ts b/webview/redux/store.ts index 23d12b6..bcf5ab2 100644 --- a/webview/redux/store.ts +++ b/webview/redux/store.ts @@ -6,6 +6,7 @@ import requestMethodReducer from "../features/requestMethod/requestMethodSlice"; import requestUrlReducer from "../features/requestUrl/requestUrlSlice"; import responseReducer from "../features/response/responseSlice"; import codeGenOptionsReducer from "../features/codeGen/codeGenSlice"; +import requestOptionsReducer from '../features/requestOptions/requestOptionsSlice'; let preloadedState; if (typeof window !== "undefined") { @@ -22,6 +23,7 @@ export const store = configureStore({ requestUrl: requestUrlReducer, response: responseReducer, codeGenOptions: codeGenOptionsReducer, + requestOptions: requestOptionsReducer }, preloadedState, });