diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..ce2ff0aded --- /dev/null +++ b/.editorconfig @@ -0,0 +1,4 @@ +[*.{js,json,html}] +charset = utf-8 +indent_style = space +indent_size = 2 \ No newline at end of file diff --git a/app/__mocks__/node-libcurl.js b/app/__mocks__/node-libcurl.js index 2ce64d1511..22571b27ac 100644 --- a/app/__mocks__/node-libcurl.js +++ b/app/__mocks__/node-libcurl.js @@ -88,6 +88,7 @@ Curl.option = { DEBUGFUNCTION: 'DEBUGFUNCTION', ACCEPT_ENCODING: 'ACCEPT_ENCODING', FOLLOWLOCATION: 'FOLLOWLOCATION', + NOBODY: 'NOBODY', HTTPAUTH: 'HTTPAUTH', HTTPHEADER: 'HTTPHEADER', HTTPPOST: 'HTTPPOST', diff --git a/app/models/__tests__/request.test.js b/app/models/__tests__/request.test.js index 1284c250d9..0008caf3aa 100644 --- a/app/models/__tests__/request.test.js +++ b/app/models/__tests__/request.test.js @@ -121,6 +121,7 @@ describe('updateMimeType()', async () => { expect(request).not.toBeNull(); const newRequest = await requestModel.updateMimeType(request, null); + expect(newRequest.body).toEqual({}); expect(newRequest.headers).toEqual([]); }); }); diff --git a/app/models/request.js b/app/models/request.js index 14b6fc7163..52dc5e7f52 100644 --- a/app/models/request.js +++ b/app/models/request.js @@ -144,12 +144,12 @@ export function updateMimeType (request, mimeType, doCreate = false) { // 1. Update Content-Type header // // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // - if (!mimeType) { - // Remove the contentType header if we are un-setting it + const hasBody = typeof mimeType === 'string'; + if (!hasBody) { headers = headers.filter(h => h !== contentTypeHeader); - } else if (contentTypeHeader) { + } else if (mimeType && contentTypeHeader) { contentTypeHeader.value = mimeType; - } else { + } else if (mimeType && !contentTypeHeader) { headers.push({name: 'Content-Type', value: mimeType}); } diff --git a/app/network/__tests__/network.test.js b/app/network/__tests__/network.test.js index 49ba879952..ea0c12d17a 100644 --- a/app/network/__tests__/network.test.js +++ b/app/network/__tests__/network.test.js @@ -71,6 +71,7 @@ describe('actuallySend()', () => { ], CUSTOMREQUEST: 'POST', ACCEPT_ENCODING: '', + NOBODY: 0, FOLLOWLOCATION: true, HTTPHEADER: [ 'Content-Type: application/json', @@ -161,6 +162,7 @@ describe('actuallySend()', () => { USERNAME: 'user', PASSWORD: 'pass', POSTFIELDS: 'foo=bar', + NOBODY: 0, PROXY: '', TIMEOUT_MS: 0, URL: 'http://localhost/?foo%20bar=hello%26world', @@ -214,6 +216,7 @@ describe('actuallySend()', () => { ], NOPROGRESS: false, PROXY: '', + NOBODY: 0, TIMEOUT_MS: 0, UPLOAD: 1, URL: 'http://localhost/', @@ -273,6 +276,7 @@ describe('actuallySend()', () => { ], NOPROGRESS: false, PROXY: '', + NOBODY: 0, TIMEOUT_MS: 0, URL: 'http://localhost/', USERAGENT: `insomnia/${getAppVersion()}`, diff --git a/app/network/network.js b/app/network/network.js index df88487cb0..3617dcfa1b 100644 --- a/app/network/network.js +++ b/app/network/network.js @@ -8,7 +8,7 @@ import * as models from '../models'; import * as querystring from '../common/querystring'; import * as util from '../common/misc.js'; import {AUTH_BASIC, AUTH_DIGEST, AUTH_NTLM, CONTENT_TYPE_FORM_DATA, CONTENT_TYPE_FORM_URLENCODED, DEBOUNCE_MILLIS, getAppVersion} from '../common/constants'; -import {describeByteSize, hasAcceptHeader, hasAuthHeader, hasContentTypeHeader, hasUserAgentHeader, setDefaultProtocol} from '../common/misc'; +import {describeByteSize, hasAuthHeader, hasContentTypeHeader, hasUserAgentHeader, setDefaultProtocol} from '../common/misc'; import {getRenderedRequest} from '../common/render'; import fs from 'fs'; import * as db from '../common/database'; @@ -84,10 +84,12 @@ export function _actuallySend (renderedRequest, workspace, settings) { // Set all the basic options setOpt(Curl.option.CUSTOMREQUEST, renderedRequest.method); + setOpt(Curl.option.NOBODY, renderedRequest.method.toLowerCase() === 'head' ? 1 : 0); setOpt(Curl.option.FOLLOWLOCATION, settings.followRedirects); setOpt(Curl.option.TIMEOUT_MS, settings.timeout); // 0 for no timeout setOpt(Curl.option.VERBOSE, true); // True so debug function works setOpt(Curl.option.NOPROGRESS, false); // False so progress function works + setOpt(Curl.option.ACCEPT_ENCODING, ''); // Auto decode everything // Setup debug handler setOpt(Curl.option.DEBUGFUNCTION, (infoType, content) => { @@ -371,11 +373,6 @@ export function _actuallySend (renderedRequest, workspace, settings) { setOpt(Curl.option.USERAGENT, `insomnia/${getAppVersion()}`); } - // Set Accept encoding - if (!hasAcceptHeader(headers)) { - setOpt(Curl.option.ACCEPT_ENCODING, ''); // Accept anything - } - // Prevent curl from adding default content-type header if (!hasContentTypeHeader(headers)) { headers.push({name: 'content-type', value: ''}); diff --git a/app/network/o-auth-2/constants.js b/app/network/o-auth-2/constants.js index 68467ad5bf..e60ad0b647 100644 --- a/app/network/o-auth-2/constants.js +++ b/app/network/o-auth-2/constants.js @@ -2,6 +2,7 @@ export const GRANT_TYPE_AUTHORIZATION_CODE = 'authorization_code'; export const GRANT_TYPE_IMPLICIT = 'implicit'; export const GRANT_TYPE_PASSWORD = 'password'; export const GRANT_TYPE_CLIENT_CREDENTIALS = 'client_credentials'; +export const GRANT_TYPE_REFRESH = 'refresh_token'; export const RESPONSE_TYPE_CODE = 'code'; export const RESPONSE_TYPE_TOKEN = 'token'; diff --git a/app/network/o-auth-2/get-token.js b/app/network/o-auth-2/get-token.js index ede307c45f..f2342c9cd5 100644 --- a/app/network/o-auth-2/get-token.js +++ b/app/network/o-auth-2/get-token.js @@ -139,7 +139,7 @@ async function _getAccessToken (requestId, authentication, forceRefresh) { authentication.credentialsInBody, authentication.clientId, authentication.clientSecret, - authentication.refreshToken, + token.refreshToken, authentication.scope ); diff --git a/app/network/o-auth-2/misc.js b/app/network/o-auth-2/misc.js index 6ceb89e656..0505d35aba 100644 --- a/app/network/o-auth-2/misc.js +++ b/app/network/o-auth-2/misc.js @@ -17,7 +17,7 @@ export function responseToObject (body, keys) { let results = {}; for (const key of keys) { - const value = typeof data[key] === 'string' ? data[key] : null; + const value = data[key] !== undefined ? data[key] : null; results[key] = value; } diff --git a/app/network/o-auth-2/refresh-token.js b/app/network/o-auth-2/refresh-token.js index dfdd24d35f..4d8e811003 100644 --- a/app/network/o-auth-2/refresh-token.js +++ b/app/network/o-auth-2/refresh-token.js @@ -10,7 +10,7 @@ export default async function (accessTokenUrl, refreshToken, scope = '') { const params = [ - {name: c.P_GRANT_TYPE, value: c.GRANT_TYPE_IMPLICIT}, + {name: c.P_GRANT_TYPE, value: c.GRANT_TYPE_REFRESH}, {name: c.P_REFRESH_TOKEN, value: refreshToken} ]; diff --git a/app/sync/storage.js b/app/sync/storage.js index 63f0e8e7b0..ab386832f1 100644 --- a/app/sync/storage.js +++ b/app/sync/storage.js @@ -3,6 +3,7 @@ import NeDB from 'nedb'; import fsPath from 'path'; import crypto from 'crypto'; import * as util from '../common/misc'; +import {DB_PERSIST_INTERVAL} from '../common/constants'; const TYPE_RESOURCE = 'Resource'; const TYPE_CONFIG = 'Config'; @@ -181,6 +182,10 @@ export function initDB (config, forceReset) { Object.assign({filename: configPath, autoload: true}, config) ); + for (const key of Object.keys(_database)) { + _database[key].persistence.setAutocompactionInterval(DB_PERSIST_INTERVAL); + } + // Done console.log(`-- Initialize Sync DB at ${basePath} --`); } diff --git a/app/ui/components/codemirror/extensions/environments-autocomplete.js b/app/ui/components/codemirror/extensions/environments-autocomplete.js index 0276d967b2..65066d33e5 100644 --- a/app/ui/components/codemirror/extensions/environments-autocomplete.js +++ b/app/ui/components/codemirror/extensions/environments-autocomplete.js @@ -178,6 +178,7 @@ function hint (cm, options) { const nameMatchLong = previousText.match(NAME_MATCH_FLEXIBLE); const nameSegment = nameMatch ? nameMatch[0] : fallbackSegment; const nameSegmentLong = nameMatchLong ? nameMatchLong[0] : fallbackSegment; + const nameSegmentFull = previousText; // Actually try to match the list of things const allShortMatches = []; @@ -195,9 +196,8 @@ function hint (cm, options) { // TODO: Make this more flexible. This is really only here as a hack to make // constants only match full string prefixes. if (allowMatchingConstants) { - // matchSegments(constantsToMatch, nameSegment, TYPE_CONSTANT, MAX_CONSTANTS) - // .map(m => allShortMatches.push(m)); - matchSegments(constantsToMatch, nameSegmentLong, TYPE_CONSTANT, MAX_CONSTANTS) + // Only match full segments with constants + matchSegments(constantsToMatch, nameSegmentFull, TYPE_CONSTANT, MAX_CONSTANTS) .map(m => allLongMatches.push(m)); } diff --git a/app/ui/components/codemirror/one-line-editor.js b/app/ui/components/codemirror/one-line-editor.js index 58f12002a5..e192694267 100644 --- a/app/ui/components/codemirror/one-line-editor.js +++ b/app/ui/components/codemirror/one-line-editor.js @@ -190,6 +190,8 @@ class OneLineEditor extends PureComponent { for (let i = 0; i < 20 && node; i++) { if (node.tagName === 'FORM') { node.dispatchEvent(new window.Event('submit')); + e.preventDefault(); + e.stopPropagation(); break; } node = node.parentNode; @@ -254,7 +256,7 @@ class OneLineEditor extends PureComponent { } _mayContainNunjucks (text) { - return !!text.match(NUNJUCKS_REGEX); + return !!(text && text.match(NUNJUCKS_REGEX)); } render () { diff --git a/app/ui/components/editors/auth/o-auth-2.js b/app/ui/components/editors/auth/o-auth-2.js index b271cc2931..e664361b0a 100644 --- a/app/ui/components/editors/auth/o-auth-2.js +++ b/app/ui/components/editors/auth/o-auth-2.js @@ -1,4 +1,5 @@ import React, {PropTypes, PureComponent} from 'react'; +import moment from 'moment'; import autobind from 'autobind-decorator'; import OneLineEditor from '../../codemirror/one-line-editor'; import * as misc from '../../../../common/misc'; @@ -288,11 +289,13 @@ class OAuth2 extends PureComponent { return null; } - if (!token.expireAt) { + if (!token.expiresAt) { return '(never expires)'; } - return `(expires ${new Date(token.expireAt)})`; + const expiresAt = new Date(token.expiresAt); + const str = moment(expiresAt).fromNow(); + return (expires {str}); } render () { @@ -345,7 +348,6 @@ class OAuth2 extends PureComponent {