From 7c63132a8524eef5a9832501945b41236e459e94 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Wed, 8 May 2019 13:36:55 -0400 Subject: [PATCH] Add new encoding type to template tag args --- .../app/templating/__tests__/utils.test.js | 21 +++++++++++++++ .../app/templating/base-extension.js | 6 ++++- packages/insomnia-app/app/templating/utils.js | 27 +++++++++++++++++++ .../ui/components/templating/tag-editor.js | 21 +++++++++++---- 4 files changed, 69 insertions(+), 6 deletions(-) diff --git a/packages/insomnia-app/app/templating/__tests__/utils.test.js b/packages/insomnia-app/app/templating/__tests__/utils.test.js index ed1f51bb0..08daf84f5 100644 --- a/packages/insomnia-app/app/templating/__tests__/utils.test.js +++ b/packages/insomnia-app/app/templating/__tests__/utils.test.js @@ -158,3 +158,24 @@ describe('unTokenizeTag()', () => { expect(result).toEqual(`{% name 'foo/bar/baz', 'foo' %}`); }); }); + +describe('encodeEncoding()', () => { + beforeEach(globalBeforeEach); + it('encodes things', () => { + expect(utils.encodeEncoding('hello', 'base64')).toBe('b64::aGVsbG8=::46b'); + expect(utils.encodeEncoding(null, 'base64')).toBe(null); + expect(utils.encodeEncoding('hello', 'unknown')).toBe('hello'); + expect(utils.encodeEncoding('hello')).toBe('hello'); + expect(utils.encodeEncoding('hello', 'utf8')).toBe('hello'); + }); +}); + +describe('decodeEncoding()', () => { + beforeEach(globalBeforeEach); + it('encodes things', () => { + expect(utils.decodeEncoding('b64::aGVsbG8=::46b')).toBe('hello'); + expect(utils.decodeEncoding('aGVsbG8=')).toBe('aGVsbG8='); + expect(utils.decodeEncoding('hello')).toBe('hello'); + expect(utils.decodeEncoding(null)).toBe(null); + }); +}); diff --git a/packages/insomnia-app/app/templating/base-extension.js b/packages/insomnia-app/app/templating/base-extension.js index a177c8d4d..8f90bcaa7 100644 --- a/packages/insomnia-app/app/templating/base-extension.js +++ b/packages/insomnia-app/app/templating/base-extension.js @@ -2,6 +2,7 @@ import * as models from '../models/index'; import * as templating from './index'; import * as pluginContexts from '../plugins/context'; import * as db from '../common/database'; +import { decodeEncoding } from './utils'; const EMPTY_ARG = '__EMPTY_NUNJUCKS_ARG__'; @@ -74,7 +75,10 @@ export default class BaseExtension { const environmentId = renderContext.getEnvironmentId ? renderContext.getEnvironmentId() : 'n/a'; // Extract the rest of the args - const args = runArgs.slice(0, runArgs.length - 1).filter(a => a !== EMPTY_ARG); + const args = runArgs + .slice(0, runArgs.length - 1) + .filter(a => a !== EMPTY_ARG) + .map(decodeEncoding); // Define a helper context with utils const helperContext = { diff --git a/packages/insomnia-app/app/templating/utils.js b/packages/insomnia-app/app/templating/utils.js index 53643825a..da73494fa 100644 --- a/packages/insomnia-app/app/templating/utils.js +++ b/packages/insomnia-app/app/templating/utils.js @@ -13,6 +13,7 @@ export type NunjucksParsedTagArg = { | 'enum' | 'file' | 'model', + encoding?: 'base64', value: string | number | boolean, defaultValue?: string | number | boolean, forceVariable?: boolean, @@ -208,3 +209,29 @@ export function getDefaultFill(name: string, args: Array): return `${name} ${stringArgs.join(', ')}`; } + +export function encodeEncoding(value: string, encoding: 'base64'): string { + if (typeof value !== 'string') { + return value; + } + + if (encoding === 'base64') { + const encodedValue = Buffer.from(value, 'utf8').toString('base64'); + return `b64::${encodedValue}::46b`; + } + + return value; +} + +export function decodeEncoding(value: string): string { + if (typeof value !== 'string') { + return value; + } + + const results = value.match(/^b64::(.+)::46b$/); + if (results) { + return Buffer.from(results[1], 'base64').toString('utf8'); + } + + return value; +} diff --git a/packages/insomnia-app/app/ui/components/templating/tag-editor.js b/packages/insomnia-app/app/ui/components/templating/tag-editor.js index 0701ddb0d..538dcf2a5 100644 --- a/packages/insomnia-app/app/ui/components/templating/tag-editor.js +++ b/packages/insomnia-app/app/ui/components/templating/tag-editor.js @@ -117,7 +117,7 @@ class TagEditor extends React.PureComponent { this.setState({ allDocs, loadingDocs: false }); } - _updateArg( + async _updateArg( argValue: string | number | boolean, argIndex: number, forceNewType: string | null = null, @@ -167,7 +167,7 @@ class TagEditor extends React.PureComponent { Object.assign((argData: any), { type: forceNewType }, patch); } - this._update(tagDefinitions, activeTagDefinition, tagData, false); + await this._update(tagDefinitions, activeTagDefinition, tagData, false); } async _handleChangeArgVariable(options: { argIndex: number, variable: boolean }) { @@ -208,6 +208,15 @@ class TagEditor extends React.PureComponent { argIndex = typeof index === 'string' ? parseInt(index, 10) : -1; } + // Handle special types + if (e.currentTarget.getAttribute('data-encoding') === 'base64') { + return this._updateArg( + templateUtils.encodeEncoding(e.currentTarget.value, 'base64'), + argIndex, + ); + } + + // Handle normal types if (e.currentTarget.type === 'number') { return this._updateArg(parseFloat(e.currentTarget.value), argIndex); } else if (e.currentTarget.type === 'checkbox') { @@ -342,13 +351,14 @@ class TagEditor extends React.PureComponent { ); } - renderArgString(value: string, placeholder: string) { + renderArgString(value: string, placeholder: string, encoding: string) { return ( ); } @@ -499,7 +509,7 @@ class TagEditor extends React.PureComponent { return null; } - const strValue = argData.value.toString(); + const strValue = templateUtils.decodeEncoding(argData.value.toString()); const isVariable = argData.type === 'variable'; const argInputVariable = isVariable ? this.renderArgVariable(strValue) : null; @@ -508,7 +518,8 @@ class TagEditor extends React.PureComponent { if (argDefinition.type === 'string') { const placeholder = typeof argDefinition.placeholder === 'string' ? argDefinition.placeholder : ''; - argInput = this.renderArgString(strValue, placeholder); + const encoding = argDefinition.encoding || 'utf8'; + argInput = this.renderArgString(strValue, placeholder, encoding); } else if (argDefinition.type === 'enum') { const { options } = argDefinition; argInput = this.renderArgEnum(strValue, options || []);