diff --git a/app/extensions/brave/locales/en-US/preferences.properties b/app/extensions/brave/locales/en-US/preferences.properties
index 0b26dcad5ea..f7138e0e8fe 100644
--- a/app/extensions/brave/locales/en-US/preferences.properties
+++ b/app/extensions/brave/locales/en-US/preferences.properties
@@ -192,7 +192,8 @@ protocolRegistrationPermission=Protocol registration
shieldsUp=All Brave Shields
ledgerPaymentsShown=Brave Payments
flash=Run Adobe Flash Player
-flashAllowOnce=Allow once
+allowOnce=Allow once
+allowUntilRestart=Allow until restart
flashAllowAlways=Allow until {{time}}
alwaysAllow=Always allow
alwaysDeny=Always deny
diff --git a/app/sessionStore.js b/app/sessionStore.js
index 8d14d406914..e7e3b206625 100644
--- a/app/sessionStore.js
+++ b/app/sessionStore.js
@@ -248,15 +248,23 @@ module.exports.cleanAppData = (data, isShutdown) => {
data.perWindowState.forEach((perWindowState) =>
module.exports.cleanPerWindowData(perWindowState, isShutdown))
}
- // Delete expired Flash approvals
+ // Delete expired Flash and NoScript allow-once approvals
let now = Date.now()
for (var host in data.siteSettings) {
let expireTime = data.siteSettings[host].flash
if (typeof expireTime === 'number' && expireTime < now) {
delete data.siteSettings[host].flash
}
+ let noScript = data.siteSettings[host].noScript
+ if (typeof noScript === 'number') {
+ delete data.siteSettings[host].noScript
+ }
// Don't write runInsecureContent to session
delete data.siteSettings[host].runInsecureContent
+ // If the site setting is empty, delete it for privacy
+ if (Object.keys(data.siteSettings[host]).length === 0) {
+ delete data.siteSettings[host]
+ }
}
if (data.sites) {
const clearHistory = isShutdown && getSetting(settings.SHUTDOWN_CLEAR_HISTORY) === true
diff --git a/docs/state.md b/docs/state.md
index 1bdca0b1dfd..db6cc0208bb 100644
--- a/docs/state.md
+++ b/docs/state.md
@@ -68,7 +68,7 @@ AppStore
adControl: string, // (showBraveAds | blockAds | allowAdsAndTracking)
cookieControl: string, // (block3rdPartyCookie | allowAllCookies)
safeBrowsing: boolean,
- noScript: boolean,
+ noScript: (number|boolean), // true = block scripts, false = allow, 0 = allow once, 1 = allow until restart
httpsEverywhere: boolean,
fingerprintingProtection: boolean,
flash: (number|boolean), // approval expiration time if allowed, false if never allow
@@ -79,6 +79,7 @@ AppStore
},
temporarySiteSettings: {
// Same as above but never gets written to disk
+ // XXX: This was intended for Private Browsing but is currently unused.
},
visits: [{
location: string,
diff --git a/js/about/preferences.js b/js/about/preferences.js
index 9cd22297284..4978e8aa1a9 100644
--- a/js/about/preferences.js
+++ b/js/about/preferences.js
@@ -68,7 +68,7 @@ const braveryPermissionNames = {
'safeBrowsing': ['boolean'],
'httpsEverywhere': ['boolean'],
'fingerprintingProtection': ['boolean'],
- 'noScript': ['boolean']
+ 'noScript': ['boolean', 'number']
}
const changeSetting = (cb, key, e) => {
@@ -1049,7 +1049,7 @@ class SitePermissionsPage extends React.Component {
if (name === 'flash') {
if (granted === 1) {
// Flash is allowed just one time
- statusText = 'flashAllowOnce'
+ statusText = 'allowOnce'
} else if (granted === false) {
// Flash installer is never intercepted
statusText = 'alwaysDeny'
@@ -1060,6 +1060,12 @@ class SitePermissionsPage extends React.Component {
time: new Date(granted).toLocaleString()
}
}
+ } else if (name === 'noScript' && typeof granted === 'number') {
+ if (granted === 1) {
+ statusText = 'allowUntilRestart'
+ } else if (granted === 0) {
+ statusText = 'allowOnce'
+ }
} else if (typeof granted === 'string') {
statusText = granted
} else if (!this.props.defaults) {
diff --git a/js/components/frame.js b/js/components/frame.js
index b8af2b080cf..c9e5fb63d06 100644
--- a/js/components/frame.js
+++ b/js/components/frame.js
@@ -200,21 +200,26 @@ class Frame extends ImmutableComponent {
return false
}
- expireFlash (origin) {
+ expireContentSettings (origin) {
// Expired Flash settings should be deleted when the webview is
- // navigated or closed.
+ // navigated or closed. Same for NoScript's allow-once option.
const activeSiteSettings = getSiteSettingsForHostPattern(this.props.allSiteSettings,
origin)
- if (activeSiteSettings && typeof activeSiteSettings.get('flash') === 'number') {
+ if (!activeSiteSettings) {
+ return
+ }
+ if (typeof activeSiteSettings.get('flash') === 'number') {
if (activeSiteSettings.get('flash') < Date.now()) {
- // Expired entry. Remove it.
appActions.removeSiteSetting(origin, 'flash')
}
}
+ if (activeSiteSettings.get('noScript') === 0) {
+ appActions.removeSiteSetting(origin, 'noScript')
+ }
}
componentWillUnmount () {
- this.expireFlash(this.origin)
+ this.expireContentSettings(this.origin)
}
updateWebview (cb, newSrc) {
@@ -381,10 +386,10 @@ class Frame extends ImmutableComponent {
this.updateAboutDetails()
}
- // For cross-origin navigation, clear temp Flash approvals
+ // For cross-origin navigation, clear temp approvals
const prevOrigin = siteUtil.getOrigin(prevProps.location)
if (this.origin !== prevOrigin) {
- this.expireFlash(prevOrigin)
+ this.expireContentSettings(prevOrigin)
}
if (this.props.src !== prevProps.src) {
diff --git a/js/components/main.js b/js/components/main.js
index fff3934643f..c6571783102 100644
--- a/js/components/main.js
+++ b/js/components/main.js
@@ -620,7 +620,7 @@ class Main extends ImmutableComponent {
}
enableNoScript (settings) {
- return siteSettings.activeSettings(settings, this.props.appState, appConfig).noScript
+ return siteSettings.activeSettings(settings, this.props.appState, appConfig).noScript === true
}
onCloseFrame (activeFrameProps) {
@@ -1008,6 +1008,7 @@ class Main extends ImmutableComponent {
{
noScriptIsVisible
?