mirror of
https://github.com/Kong/insomnia
synced 2024-11-07 14:19:58 +00:00
Hawk improvements and fuzzy filtering everywhere
This commit is contained in:
parent
2fcf98536f
commit
7c4800023e
@ -143,6 +143,9 @@ export const AUTH_HAWK = 'hawk';
|
||||
export const AUTH_AWS_IAM = 'iam';
|
||||
export const AUTH_NETRC = 'netrc';
|
||||
|
||||
export const HAWK_ALGORITHM_SHA256 = 'sha256';
|
||||
export const HAWK_ALGORITHM_SHA1 = 'sha1';
|
||||
|
||||
const authTypesMap = {
|
||||
[AUTH_BASIC]: ['Basic', 'Basic Auth'],
|
||||
[AUTH_DIGEST]: ['Digest', 'Digest Auth'],
|
||||
|
@ -326,3 +326,9 @@ export function jsonParseOr (str: string, fallback: any): any {
|
||||
export function escapeRegex (str: string): string {
|
||||
return str.replace(ESCAPE_REGEX_MATCH, '\\$&');
|
||||
}
|
||||
|
||||
export function fuzzyMatch (searchString: string, text: string): boolean {
|
||||
const regexSearchString = escapeRegex(searchString.toLowerCase()).split('').join('.*');
|
||||
const toMatch = new RegExp(regexSearchString);
|
||||
return toMatch.test(text.toLowerCase());
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
// @flow
|
||||
import type {BaseModel} from './index';
|
||||
import {AUTH_BASIC, AUTH_DIGEST, AUTH_NONE, AUTH_NTLM, AUTH_OAUTH_2, AUTH_HAWK, AUTH_AWS_IAM, AUTH_NETRC, CONTENT_TYPE_FILE, CONTENT_TYPE_FORM_DATA, CONTENT_TYPE_FORM_URLENCODED, CONTENT_TYPE_OTHER, getContentTypeFromHeaders, METHOD_GET, CONTENT_TYPE_GRAPHQL, CONTENT_TYPE_JSON, METHOD_POST} from '../common/constants';
|
||||
import {AUTH_BASIC, AUTH_DIGEST, AUTH_NONE, AUTH_NTLM, AUTH_OAUTH_2, AUTH_HAWK, AUTH_AWS_IAM, AUTH_NETRC, CONTENT_TYPE_FILE, CONTENT_TYPE_FORM_DATA, CONTENT_TYPE_FORM_URLENCODED, CONTENT_TYPE_OTHER, getContentTypeFromHeaders, METHOD_GET, CONTENT_TYPE_GRAPHQL, CONTENT_TYPE_JSON, METHOD_POST, HAWK_ALGORITHM_SHA256} from '../common/constants';
|
||||
import * as db from '../common/database';
|
||||
import {getContentTypeHeader} from '../common/misc';
|
||||
import {buildFromParams, deconstructToParams} from '../common/querystring';
|
||||
@ -118,7 +118,7 @@ export function newAuth (type: string, oldAuth: RequestAuthentication = {}): Req
|
||||
|
||||
// hawk
|
||||
case AUTH_HAWK:
|
||||
return {type, algorithm: 'sha256'};
|
||||
return {type, algorithm: HAWK_ALGORITHM_SHA256};
|
||||
|
||||
// Types needing no defaults
|
||||
default:
|
||||
|
@ -9,21 +9,32 @@
|
||||
"author": "Insomnia <support@insomnia.rest>",
|
||||
"main": "main.min.js",
|
||||
"dependencies": {
|
||||
"aws4": "^1.6.0",
|
||||
"clone": "^2.1.0",
|
||||
"deep-equal": "^1.0.1",
|
||||
"electron-context-menu": "^0.9.0",
|
||||
"electron-devtools-installer": "^2.2.0",
|
||||
"electron-squirrel-startup": "^1.0.0",
|
||||
"deep-equal": "^1.0.1",
|
||||
"hawk": "^6.0.2",
|
||||
"hkdf": "^0.0.2",
|
||||
"html-entities": "^1.2.0",
|
||||
"iconv-lite": "^0.4.15",
|
||||
"insomnia-httpsnippet": "^1.16.5",
|
||||
"insomnia-importers": "^1.3.9",
|
||||
"insomnia-node-libcurl": "^1.2.3",
|
||||
"jsonpath": "^0.2.11",
|
||||
"marked": "^0.3.6",
|
||||
"mkdirp": "^0.5.1",
|
||||
"moment": "^2.18.1",
|
||||
"mime-types": "^2.1.14",
|
||||
"nedb": "^1.8.0",
|
||||
"node-forge": "^0.7.0",
|
||||
"simple-react-pdf": "^1.0.8",
|
||||
"srp-js": "^0.2.0",
|
||||
"tar": "^3.1.7",
|
||||
"tough-cookie": "^2.3.1",
|
||||
"vkbeautify": "^0.99.1"
|
||||
"vkbeautify": "^0.99.1",
|
||||
"whatwg-fetch": "^2.0.1",
|
||||
"xmldom": "^0.1.22"
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import classnames from 'classnames';
|
||||
import DropdownButton from './dropdown-button';
|
||||
import DropdownItem from './dropdown-item';
|
||||
import DropdownDivider from './dropdown-divider';
|
||||
import {fuzzyMatch} from '../../../../common/misc';
|
||||
|
||||
@autobind
|
||||
class Dropdown extends PureComponent {
|
||||
@ -59,7 +60,7 @@ class Dropdown extends PureComponent {
|
||||
const listItemTextWithoutSpaces = listItem.textContent.toLowerCase().replace(/[^\w_]*/g, '');
|
||||
const filterWithoutSpaces = newFilter.toLowerCase().replace(/[^\w_]*/g, '');
|
||||
|
||||
if (!newFilter || listItemTextWithoutSpaces.includes(filterWithoutSpaces)) {
|
||||
if (!newFilter || fuzzyMatch(filterWithoutSpaces, listItemTextWithoutSpaces)) {
|
||||
const filterIndex = listItem.getAttribute('data-filter-index');
|
||||
filterItems.push(parseInt(filterIndex, 10));
|
||||
}
|
||||
|
@ -1,10 +1,12 @@
|
||||
// @flow
|
||||
import type { Request } from '../../../../models/request';
|
||||
import type {Request} from '../../../../models/request';
|
||||
|
||||
import React from 'react';
|
||||
import autobind from 'autobind-decorator';
|
||||
import OneLineEditor from '../../codemirror/one-line-editor';
|
||||
import * as misc from '../../../../common/misc';
|
||||
import {HAWK_ALGORITHM_SHA1, HAWK_ALGORITHM_SHA256} from '../../../../common/constants';
|
||||
import HelpTooltip from '../../help-tooltip';
|
||||
|
||||
@autobind
|
||||
class HawkAuth extends React.PureComponent {
|
||||
@ -43,29 +45,69 @@ class HawkAuth extends React.PureComponent {
|
||||
|
||||
renderHawkAuthenticationFields (): Array<React.Element<*>> {
|
||||
const hawkAuthId = this.renderInputRow(
|
||||
'Hawk Auth ID',
|
||||
'Auth ID',
|
||||
'id',
|
||||
this._handleChangeHawkAuthId
|
||||
);
|
||||
|
||||
const hawkAuthKey = this.renderInputRow(
|
||||
'Hawk Auth Key',
|
||||
'Auth Key',
|
||||
'key',
|
||||
this._handleChangeHawkAuthKey
|
||||
);
|
||||
|
||||
const algorithm = this.renderInputRow(
|
||||
const algorithm = this.renderSelectRow(
|
||||
'Algorithm',
|
||||
'algorithm',
|
||||
[
|
||||
{name: HAWK_ALGORITHM_SHA256, value: HAWK_ALGORITHM_SHA256},
|
||||
{name: HAWK_ALGORITHM_SHA1, value: HAWK_ALGORITHM_SHA1}
|
||||
],
|
||||
this._handleChangeAlgorithm
|
||||
);
|
||||
|
||||
return [hawkAuthId, hawkAuthKey, algorithm];
|
||||
}
|
||||
|
||||
renderInputRow (label: string,
|
||||
property: string,
|
||||
onChange: Function): React.Element<*> {
|
||||
renderSelectRow (
|
||||
label: string,
|
||||
property: string,
|
||||
options: Array<{name: string, value: string}>,
|
||||
onChange: Function,
|
||||
help: string | null = null
|
||||
): React.Element<*> {
|
||||
const {request} = this.props;
|
||||
const id = label.replace(/ /g, '-');
|
||||
const value = request.authentication.hasOwnProperty(property)
|
||||
? request.authentication[property]
|
||||
: options[0];
|
||||
|
||||
return (
|
||||
<tr key={id}>
|
||||
<td className="pad-right no-wrap valign-middle">
|
||||
<label htmlFor={id} className="label--small no-pad">
|
||||
{label}
|
||||
{help && <HelpTooltip>{help}</HelpTooltip>}
|
||||
</label>
|
||||
</td>
|
||||
<td className="wide">
|
||||
<div className="form-control form-control--outlined no-margin">
|
||||
<select id={id} onChange={onChange} value={value}>
|
||||
{options.map(({name, value}) => (
|
||||
<option key={value} value={value}>{name}</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
|
||||
renderInputRow (
|
||||
label: string,
|
||||
property: string,
|
||||
onChange: Function
|
||||
): React.Element<*> {
|
||||
const {handleRender, handleGetRenderContext, request} = this.props;
|
||||
const id = label.replace(/ /g, '-');
|
||||
return (
|
||||
|
@ -8,6 +8,7 @@ import ModalHeader from '../base/modal-header';
|
||||
import ModalBody from '../base/modal-body';
|
||||
import MethodTag from '../tags/method-tag';
|
||||
import * as models from '../../../models';
|
||||
import {fuzzyMatch} from '../../../common/misc';
|
||||
|
||||
@autobind
|
||||
class RequestSwitcherModal extends PureComponent {
|
||||
@ -128,25 +129,14 @@ class RequestSwitcherModal extends PureComponent {
|
||||
// OPTIMIZATION: This only filters if we have a filter
|
||||
let matchedRequests = workspaceChildren.filter(d => d.type === models.request.type);
|
||||
if (searchString) {
|
||||
const specialCharacters = ['.', '^', '$', '*', '+', '-', '?', '(', ')', '[', ']', '{', '}', '\\', '|'];
|
||||
|
||||
const regexSearchString = searchString
|
||||
.toLowerCase()
|
||||
.split('')
|
||||
.map((c) => specialCharacters.includes(c) ? `\\${c}` : c)
|
||||
.join('.*');
|
||||
|
||||
const toMatch = new RegExp(regexSearchString);
|
||||
|
||||
matchedRequests = matchedRequests.filter(r => {
|
||||
const name = r.name.toLowerCase();
|
||||
const id = r._id.toLowerCase();
|
||||
|
||||
// Fuzzy match searchString to name
|
||||
const matchesName = toMatch.test(name);
|
||||
const matchesName = fuzzyMatch(searchString, name);
|
||||
|
||||
// Match exact Id
|
||||
const matchesId = id === toMatch;
|
||||
const matchesId = r._id === searchString;
|
||||
|
||||
return matchesName || matchesId;
|
||||
});
|
||||
|
@ -1,4 +1,5 @@
|
||||
import {createSelector} from 'reselect';
|
||||
import {fuzzyMatch} from '../../common/misc';
|
||||
|
||||
// ~~~~~~~~~ //
|
||||
// Selectors //
|
||||
@ -106,13 +107,13 @@ export const selectSidebarChildren = createSelector(
|
||||
// Build the monster string to match on
|
||||
const method = child.doc.method || '';
|
||||
const name = child.doc.name;
|
||||
const toMatch = `${method}❅${name}❅${parentNames.join('❅')}`.toLowerCase();
|
||||
const toMatch = `${method}❅${name}❅${parentNames.join('❅')}`;
|
||||
|
||||
// Try to match name
|
||||
let hasMatchedName = true;
|
||||
for (const token of sidebarFilter.trim().toLowerCase().split(' ')) {
|
||||
for (const token of sidebarFilter.trim().split(' ')) {
|
||||
// Filter failed. Don't render children
|
||||
if (toMatch.indexOf(token) === -1) {
|
||||
if (!fuzzyMatch(token, toMatch)) {
|
||||
hasMatchedName = false;
|
||||
break;
|
||||
}
|
||||
|
@ -59,8 +59,6 @@ module.exports = {
|
||||
// To get jsonlint working...
|
||||
'file', 'system'
|
||||
],
|
||||
plugins: [
|
||||
new webpack.optimize.ModuleConcatenationPlugin(),
|
||||
],
|
||||
plugins: [],
|
||||
target: 'electron-renderer'
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user