Add setting to enable response filtering (for backwards-compatibility)

This commit is contained in:
Gregory Schier 2020-02-11 13:45:47 -05:00
parent b7250519ec
commit 1e50cd4a53
5 changed files with 49 additions and 63 deletions

View File

@ -53,7 +53,6 @@ export type Response = BaseModel & BaseResponse;
export function init(): BaseResponse {
return {
environmentId: '__LEGACY__',
statusCode: 0,
statusMessage: '',
httpVersion: '',
@ -72,6 +71,10 @@ export function init(): BaseResponse {
// Things from the request
settingStoreCookies: null,
settingSendCookies: null,
// Responses sent before environment filtering will have a special value
// so they don't show up at all when filtering is on.
environmentId: '__LEGACY__',
};
}
@ -86,9 +89,6 @@ export function hookDatabaseInit() {
console.log('Init responses DB');
process.nextTick(async () => {
await models.response.cleanDeletedResponses();
// Can remove this after March 2020
await addLegacyEnvironmentId();
});
}
@ -110,20 +110,21 @@ export async function all(): Promise<Array<Response>> {
}
export async function removeForRequest(parentId: string, environmentId?: string | null) {
const q: Object = {
const settings = await models.settings.getOrCreate();
const query: Object = {
parentId,
};
// Only add if not undefined. null is not the same as undefined
// null: find responses sent from base environment
// undefined: find all responses
if (environmentId !== undefined) {
q.environmentId = environmentId;
if (environmentId !== undefined && settings.filterResponsesByEnv) {
query.environmentId = environmentId;
}
// Also delete legacy responses here or else the user will be confused as to
// why some responses are still showing in the UI.
await db.removeWhere(type, { $or: [q, { parentId, environmentId: '__LEGACY__' }] });
await db.removeWhere(type, query);
}
export function remove(response: Response) {
@ -135,24 +136,16 @@ async function _findRecentForRequest(
environmentId: string | null,
limit: number,
): Promise<Array<Response>> {
const q = {
const query = {
parentId: requestId,
environmentId: environmentId,
};
return db.findMostRecentlyModified(
type,
{
$or: [
q,
{
parentId: requestId,
environmentId: '__LEGACY__',
},
],
},
limit,
);
// Filter responses by environment if setting is enabled
if ((await models.settings.getOrCreate()).filterResponsesByEnv) {
query.environmentId = environmentId;
}
return db.findMostRecentlyModified(type, query, limit);
}
export async function getLatestForRequest(
@ -176,14 +169,21 @@ export async function create(patch: Object = {}, maxResponses: number = 20) {
const requestVersion = request ? await models.requestVersion.create(request) : null;
patch.requestVersionId = requestVersion ? requestVersion._id : null;
// Filter responses by environment if setting is enabled
const query = { parentId };
if (
(await models.settings.getOrCreate()).filterResponsesByEnv &&
patch.hasOwnProperty('environmentId')
) {
query.environmentId = patch.environmentId;
}
// Delete all other responses before creating the new one
const allResponses = await db.findMostRecentlyModified(
type,
{ parentId },
Math.max(1, maxResponses),
);
const allResponses = await db.findMostRecentlyModified(type, query, Math.max(1, maxResponses));
const recentIds = allResponses.map(r => r._id);
await db.removeWhere(type, { parentId, _id: { $nin: recentIds } });
// Remove all that were in the last query, except the first `maxResponses` IDs
await db.removeWhere(type, { ...query, _id: { $nin: recentIds } });
// Actually create the new response
return db.docCreate(type, patch);
@ -322,33 +322,6 @@ async function migrateTimelineToFileSystem(doc: Object) {
}
}
async function addLegacyEnvironmentId() {
const all = await db.all(type);
// Bail early if none yet. This is mostly here so tests don't
// get impacted
if (all.length === 0) {
return;
}
// We need to query on the __LEGACY__ value so we need
// to migrate it into the DB to make that possible. If we
// don't do that, it will exist on queried document by default
// but won't actually be in the DB.
const promises = [];
const flushId = await db.bufferChanges();
for (const doc of all) {
if (doc.environmentId !== '__LEGACY__') {
continue;
}
promises.push(db.docUpdate(doc));
}
await Promise.all(promises);
await db.flushChanges(flushId);
}
export async function cleanDeletedResponses() {
const responsesDir = path.join(getDataDirectory(), 'responses');
mkdirp.sync(responsesDir);

View File

@ -42,6 +42,7 @@ type BaseSettings = {
nunjucksPowerUserMode: boolean,
pluginPath: string,
proxyEnabled: boolean,
filterResponsesByEnv: boolean,
showPasswords: boolean,
theme: string,
timeout: number,
@ -94,6 +95,7 @@ export function init(): BaseSettings {
nunjucksPowerUserMode: false,
pluginPath: '',
proxyEnabled: false,
filterResponsesByEnv: false,
showPasswords: false,
theme: packageJson.app.theme,
timeout: 0,

View File

@ -307,6 +307,13 @@ class General extends React.PureComponent<Props, State> {
<div>
{this.renderBooleanSetting('Validate certificates', 'validateSSL', '')}
{this.renderBooleanSetting('Follow redirects', 'followRedirects', '')}
{this.renderBooleanSetting(
'Filter responses by environment',
'filterResponsesByEnv',
'Only show responses that were sent under the currently-active environment. This ' +
'adds additional separation when working with Development, Staging, Production ' +
'environments, for example.',
)}
</div>
<div>
{this.renderBooleanSetting('Disable JS in HTML preview', 'disableHtmlPreviewJs', '')}

View File

@ -272,16 +272,20 @@ export const selectActiveRequestResponses = createSelector(
selectActiveWorkspaceMeta,
(activeRequest, entities, meta) => {
const requestId = activeRequest ? activeRequest._id : 'n/a';
const settings = entities.settings[0];
// Filter responses down if the setting is enabled
return entities.responses
.filter(response => {
const requestMatches = requestId === response.parentId;
const activeEnvironmentId = meta ? meta.activeEnvironmentId : 'n/a';
const environmentMatches = response.environmentId === activeEnvironmentId;
// Legacy responses were sent before environment scoping existed
const isLegacy = response.environmentId === '__LEGACY__';
return requestMatches && (environmentMatches || isLegacy);
if (settings.filterResponsesByEnv) {
const activeEnvironmentId = meta ? meta.activeEnvironmentId : 'n/a';
const environmentMatches = response.environmentId === activeEnvironmentId;
return requestMatches && environmentMatches;
} else {
return requestMatches;
}
})
.sort((a, b) => (a.created > b.created ? -1 : 1));
},

View File

@ -578,7 +578,7 @@ function _genTestContext(requests, responses, extraInfoRoot) {
},
},
response: {
getLatestForRequestId(requestId) {
getLatestForRequestId(requestId, environmentId) {
return responses.find(r => r.parentId === requestId) || null;
},
getBodyBuffer(response) {