Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GH 1960 Intro Hub Forgot Password #506

Closed
wants to merge 20 commits into from
Closed
Changes from 3 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
51c9195
update npm dependencies and nvm version
christophertino Jan 24, 2020
851235f
GH-1911 Remove edge legacy code (#492)
benstrumeyer Jan 30, 2020
be339da
update changelog
christophertino Jan 30, 2020
e1de727
Update browser-core to v7.43 (#490)
sammacbeth Jan 30, 2020
e3610ea
fix lint errors and clean up yarn.lock
christophertino Jan 30, 2020
4afff29
Fix 'trust site' on localhost (#491)
benstrumeyer Feb 3, 2020
a597881
change manifest applications property to browser_specific_settings
christophertino Feb 3, 2020
02d5bed
update dependencies
christophertino Feb 3, 2020
371fae8
GH-1791 / add locale-appropriate formatting to historical stats numbe…
wlycdgr Feb 13, 2020
cb14abf
GH-1936 & GH-1920 Remove email opt-in from account creation in panel …
benstrumeyer Feb 14, 2020
22c66d6
Disable Purplebox on Firefox Android (#494)
benstrumeyer Feb 14, 2020
eb278c4
update changelog
christophertino Feb 14, 2020
b9186bc
GH-1947 Plus checkout UTM params (#499)
benstrumeyer Feb 21, 2020
a726e87
update translations
christophertino Feb 21, 2020
8b8bb4f
bump browser core
christophertino Feb 25, 2020
79bf18f
GH-1477 Wildcard/Regex Whitelisting (#501)
benstrumeyer Mar 3, 2020
7b6c32e
Enable whitelisting of Unknown Trackers from Ad Block module (#503)
christophertino Mar 3, 2020
0f32e80
Add ForgotPasswordViewto hub. Move related code from panel to shared …
benstrumeyer Mar 5, 2020
7e61aee
Update snapshot
benstrumeyer Mar 5, 2020
aa44a15
Merge branch 'develop' into GH-1960/intro-hub-forgot-password
benstrumeyer Mar 5, 2020
File filter
Filter file types
Jump to
Jump to file
Failed to load files.

Always

Just for now

@@ -2,7 +2,8 @@

+ Migrate to the new Chromium-based Edge browser (#492)
+ Disable Purplebox on Firefox Android (#494)
+ Allow white-listing of regex and wildcard domains (#497)
+ Allow white-listing of wildcard domains (#501)
+ Allow site-specific white-listing of Unknown Trackers caught by Ad-Blocker (#503)
+ Fixes issue when adding localhost to Trusted Sites with port value (Fixes #470)
+ Add locale-appropriate formatting to historical stats numbers (#498)
+ Remove email opt-in from account creation in panel and hub (#495)
@@ -802,7 +802,7 @@
"message": "unblocked"
},
"white_black_list_error_invalid_url": {
"message": "Please enter a valid URL."
"message": "Please enter a valid URL or wildcard."
},
"whitelist_error_blacklist_url": {
"message": "This site has been removed from your Restricted Sites list and added to your Trusted Sites list."
@@ -1058,7 +1058,7 @@
"message": "Trusted Sites"
},
"settings_sites_placeholder": {
"message": "example.com"
"message": "example.com (wildcards supported)"
},
"settings_restricted_sites": {
"message": "Restricted Sites"
@@ -342,7 +342,7 @@ class Tracker extends React.Component {
this.clickTrackerRestrict,
this.clickTrackerStatus,
)}
{isUnknown && tracker.type === 'antiTracking' && renderUnknownTrackerButtons(
{isUnknown && renderUnknownTrackerButtons(
this.handleCliqzTrackerWhitelist,
tracker.whitelisted,
tracker.siteRestricted,
@@ -77,7 +77,7 @@ export const renderUnknownTrackerButtons = (
</span>

{/* USE INLINE SVG FOR ANTI-TRACKING SHIELD TO CHANGE COLORS WITH CSS */}
<span className="t-tooltip-up-left" data-g-tooltip={t('panel_tracker_scrub_tooltip')}>
<span className="t-tooltip-up-left" data-g-tooltip={type === 'antiTracking' ? t('panel_tracker_scrub_tooltip') : t('panel_tracker_restrict_tooltip')}>
<svg className="cliqz-tracker-scrub" onClick={handleCliqzTrackerWhitelist} width="20px" height="20px" viewBox="0 0 20 20">
<g transform="translate(1 1)" fill="none" fillRule="evenodd">
<path className="border" stroke="#00AEF0" d="M-.5-.5h18.3v18.217H-.5z" />
@@ -89,8 +89,6 @@ class TrustAndRestrict extends React.Component {
* if it has been alreday added to the opposite list. Displays appropriate warnings.
*/
addSite() {
// from node-validator
const isValidUrlRegex = /^(?!mailto:)(?:(?:https?|ftp):\/\/)?(?:\S+(?::\S*)?@)?(?:(?:(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))|localhost)(?::\d{2,5})?(?:\/[^\s]*)?$/i;
let pageHost;
let list;
let listType;
@@ -121,10 +119,12 @@ class TrustAndRestrict extends React.Component {
pageHost = pageHost.toLowerCase().replace(/^(http[s]?:\/\/)?(www\.)?/, '');

// Check for Validity
if (pageHost.length >= 2083 || !isValidUrlRegex.test(pageHost)) {
if (pageHost.length >= 2083
|| !this.isValidUrlorWildcard(pageHost)) {
this.showWarning(t('white_black_list_error_invalid_url'));
return;
}

// Check for Duplicates
if (list.includes(pageHost)) {
this.showWarning(duplicateWarning);
@@ -137,6 +137,35 @@ class TrustAndRestrict extends React.Component {
this.props.actions.updateSitePolicy({ type: otherListType, pageHost });
}
this.props.actions.updateSitePolicy({ type: listType, pageHost });
if (listType === 'whitelist') {
this.setState({ trustedValue: '' });
} else {
this.setState({ restrictedValue: '' });
}
}

isValidUrlorWildcard(pageHost) {
// Only allow valid host name characters, ':' for port numbers and '*' for wildcards
const isSafePageHost = /^[a-zA-Z0-9-.:*]*$/;
if (!isSafePageHost.test(pageHost)) { return false; }

// Check for valid URL from node-validator
const isValidUrlRegex = /^(?!mailto:)(?:(?:https?|ftp):\/\/)?(?:\S+(?::\S*)?@)?(?:(?:(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))|localhost)(?::\d{2,5})?(?:\/[^\s]*)?$/i;
if (isValidUrlRegex.test(pageHost)) return true;

// Check for valid wildcard
let isValidWildcard = false;
if (pageHost.includes('*')) {
const wildcardPattern = pageHost.replace(/\*/g, '.*');
try {
// eslint-disable-next-line
new RegExp(wildcardPattern);
isValidWildcard = true;
} catch {
return false;
}
}
return isValidWildcard;
}

/**
@@ -0,0 +1,153 @@
/**
* Rewards Test Component
*
* Ghostery Browser Extension
* https://www.ghostery.com/
*
* Copyright 2019 Ghostery, Inc. All rights reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0
*/

import React from 'react';
import renderer from 'react-test-renderer';
import { shallow } from 'enzyme';
import { when } from 'jest-when';
import TrustAndRestrict from '../TrustAndRestrict';

describe('app/panel/components/Settings/TrustAndRestrict', () => {
describe('Snapshot test with react-test-renderer', () => {
test('Testing TrustAndRestrict is rendering', () => {
const wrapper = renderer.create(
<TrustAndRestrict />
).toJSON();
expect(wrapper).toMatchSnapshot();
});
});
});

describe('app/panel/components/Settings/', () => {
test('isValidUrlorWildcard should return true with url entered', () => {
const wrapper = shallow(<TrustAndRestrict />);
let input = 'ghostery.com';

let fn = jest.spyOn(wrapper.instance(), 'isValidUrlorWildcard');
when(fn).calledWith(input);
let returnValue = wrapper.instance().isValidUrlorWildcard(input);
expect(returnValue).toBe(true);

input = 'localhost:3000';
fn = jest.spyOn(wrapper.instance(), 'isValidUrlorWildcard');
when(fn).calledWith(input);
returnValue = wrapper.instance().isValidUrlorWildcard(input);
expect(returnValue).toBe(true);
});

test('isValidUrlorWildcard should return true with wildcard URL entered', () => {
const wrapper = shallow(<TrustAndRestrict />);

let input = 'developer.*.org';
let fn = jest.spyOn(wrapper.instance(), 'isValidUrlorWildcard');
when(fn).calledWith(input);
let returnValue = wrapper.instance().isValidUrlorWildcard(input);
expect(returnValue).toBe(true);

input = '*.com';
fn = jest.spyOn(wrapper.instance(), 'isValidUrlorWildcard');
when(fn).calledWith(input);
returnValue = wrapper.instance().isValidUrlorWildcard(input);
expect(returnValue).toBe(true);

input = '*';
fn = jest.spyOn(wrapper.instance(), 'isValidUrlorWildcard');
when(fn).calledWith(input);
returnValue = wrapper.instance().isValidUrlorWildcard(input);
expect(returnValue).toBe(true);

input = 'developer.*';
fn = jest.spyOn(wrapper.instance(), 'isValidUrlorWildcard');
when(fn).calledWith(input);
returnValue = wrapper.instance().isValidUrlorWildcard(input);
expect(returnValue).toBe(true);

input = '****';
fn = jest.spyOn(wrapper.instance(), 'isValidUrlorWildcard');
when(fn).calledWith(input);
returnValue = wrapper.instance().isValidUrlorWildcard(input);
expect(returnValue).toBe(true);
});

test('isValidUrlorWildcard should return false with wildcard URL entered', () => {
const wrapper = shallow(<TrustAndRestrict />);

let input = '<script>*</script>';
let fn = jest.spyOn(wrapper.instance(), 'isValidUrlorWildcard');
when(fn).calledWith(input);
let returnValue = wrapper.instance().isValidUrlorWildcard(input);
expect(returnValue).toBe(false);

input = '+$@@#$*';
fn = jest.spyOn(wrapper.instance(), 'isValidUrlorWildcard');
when(fn).calledWith(input);
returnValue = wrapper.instance().isValidUrlorWildcard(input);
expect(returnValue).toBe(false);

input = 'αράδειγμα.δοκιμ.*';
fn = jest.spyOn(wrapper.instance(), 'isValidUrlorWildcard');
when(fn).calledWith(input);
returnValue = wrapper.instance().isValidUrlorWildcard(input);
expect(returnValue).toBe(false);

input = 'SELECT * FROM USERS';
fn = jest.spyOn(wrapper.instance(), 'isValidUrlorWildcard');
when(fn).calledWith(input);
returnValue = wrapper.instance().isValidUrlorWildcard(input);
expect(returnValue).toBe(false);
});

test('isValidUrlorWildcard should return false with regex entered', () => {
const wrapper = shallow(<TrustAndRestrict />);

let input = ')';
let fn = jest.spyOn(wrapper.instance(), 'isValidUrlorWildcard');
when(fn).calledWith(input);
let returnValue = wrapper.instance().isValidUrlorWildcard(input);
expect(returnValue).toBe(false);

input = '++';
fn = jest.spyOn(wrapper.instance(), 'isValidUrlorWildcard');
when(fn).calledWith(input);
returnValue = wrapper.instance().isValidUrlorWildcard(input);
expect(returnValue).toBe(false);

input = '/foo(?)/';
fn = jest.spyOn(wrapper.instance(), 'isValidUrlorWildcard');
when(fn).calledWith(input);
returnValue = wrapper.instance().isValidUrlorWildcard(input);
expect(returnValue).toBe(false);
});

test('isValidUrlorWildcard should return false with unsafe test entered', () => {
const wrapper = shallow(<TrustAndRestrict />);

let input = '/^(\w+\s?)*$/';
let fn = jest.spyOn(wrapper.instance(), 'isValidUrlorWildcard');
when(fn).calledWith(input);
let returnValue = wrapper.instance().isValidUrlorWildcard(input);
expect(returnValue).toBe(false);

input = '/^([0-9]+)*$/';
fn = jest.spyOn(wrapper.instance(), 'isValidUrlorWildcard');
when(fn).calledWith(input);
returnValue = wrapper.instance().isValidUrlorWildcard(input);
expect(returnValue).toBe(false);

input = '(x\w{1,10})+y';
fn = jest.spyOn(wrapper.instance(), 'isValidUrlorWildcard');
when(fn).calledWith(input);
returnValue = wrapper.instance().isValidUrlorWildcard(input);
expect(returnValue).toBe(false);
});
});
@@ -0,0 +1,119 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`app/panel/components/Settings/TrustAndRestrict Snapshot test with react-test-renderer Testing TrustAndRestrict is rendering 1`] = `
<div
className="s-trust-restrict-panel s-tabs-panel"
>
<div
className="row"
>
<div
className="columns"
>
<h3>
settings_trusted_restricted_sites
</h3>
</div>
</div>
<div
className="s-trust-restrict-menu"
>
<div
className="s-active-pane s-pane-title"
id="showTrustedSites"
onClick={[Function]}
>
<span>
settings_trusted_sites
</span>
</div>
<div
className="s-pane-title-next"
id="showRestrictedSites"
onClick={[Function]}
>
<span>
settings_restricted_sites
</span>
</div>
</div>
<div
className="s-sites-pane"
>
<div
className="row"
>
<div
className="columns"
>
<div
className="s-sites-input-box"
>
<input
onChange={[Function]}
onKeyDown={[Function]}
placeholder="settings_sites_placeholder"
type="text"
value=""
/>
<div
className="s-sites-input-icon"
onClick={[Function]}
/>
</div>
<div
className="s-site-description"
>
<span>
settings_trusted_sites_description
</span>
</div>
<div
className="s-invisible s-callout"
>

</div>
</div>
</div>
</div>
<div
className="s-hide s-sites-pane"
>
<div
className="row"
>
<div
className="columns"
>
<div
className="s-sites-input-box"
>
<input
onChange={[Function]}
onKeyDown={[Function]}
placeholder="settings_sites_placeholder"
type="text"
value=""
/>
<div
className="s-sites-input-icon"
onClick={[Function]}
/>
</div>
<div
className="s-site-description"
>
<span>
settings_restricted_sites_description
</span>
</div>
<div
className="s-invisible s-callout"
>

</div>
</div>
</div>
</div>
</div>
`;
ProTip! Use n and p to navigate between commits in a pull request.