浏览代码

Add csp option

simov 7 年之前
父节点
当前提交
45719f8b83
共有 3 个文件被更改,包括 85 次插入24 次删除
  1. 43 21
      background/background.js
  2. 39 2
      content/options.js
  3. 3 1
      manifest.json

+ 43 - 21
background/background.js

@@ -15,6 +15,7 @@ var defaults = {
   },
   raw: false,
   header: true,
+  csp: false,
   match,
   origins: {
     'file://': match
@@ -26,6 +27,8 @@ Object.keys(md).forEach((compiler) => {
 
 var state
 
+var onwakeup = true
+
 function set (options) {
   chrome.storage.sync.set(options)
   Object.assign(state, options)
@@ -76,6 +79,10 @@ chrome.storage.sync.get((res) => {
   if (options.content.mathjax === undefined) {
     options.content.mathjax = false
   }
+  // v3.3 -> v3.4
+  if (options.csp === undefined) {
+    options.csp = false
+  }
 
   // reload extension bug
   chrome.permissions.getAll((permissions) => {
@@ -97,6 +104,11 @@ chrome.storage.sync.get((res) => {
 })
 
 function inject (id) {
+  if (onwakeup && state.csp) {
+    onwakeup = false
+    chrome.tabs.reload(id)
+  }
+
   chrome.tabs.executeScript(id, {
     code: `
       document.querySelector('pre').style.visibility = 'hidden'
@@ -245,6 +257,7 @@ chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
     sendResponse({
       origins: state.origins,
       header: state.header,
+      csp: state.csp,
       exclude: state.exclude,
     })
   }
@@ -252,6 +265,12 @@ chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
     set({header: req.header})
     sendResponse()
   }
+  else if (req.message === 'options.csp') {
+    chrome.webRequest.onHeadersReceived
+      [`${req.csp ? 'add' : 'remove'}Listener`](...onHeaderArgs)
+    set({csp: req.csp})
+    sendResponse()
+  }
 
   // options origins
   else if (req.message === 'origin.add') {
@@ -279,25 +298,28 @@ function notifyContent (req, res) {
   })
 }
 
+var onHeaderArgs = [
+  ({responseHeaders}) => ({
+    responseHeaders: responseHeaders
+      .filter(({name}) => name.toLowerCase() !== 'content-security-policy')
+      // ff: markdown `content-type` is not allowed
+      .map((header) => {
+        if (
+          /Firefox/.test(navigator.userAgent) &&
+          header.name.toLowerCase() === 'content-type' &&
+          /text\/(?:x-)?markdown/.test(header.value)
+        ) {
+          header.value = 'text/plain; charset=utf-8'
+        }
+        return header
+      })
+    }),
+    {
+      urls: ['<all_urls>'],
+      types: ['main_frame', 'sub_frame']
+    },
+    ['blocking', 'responseHeaders']
+]
+
 chrome.webRequest &&
-chrome.webRequest.onHeadersReceived.addListener(({responseHeaders}) => ({
-  responseHeaders: responseHeaders
-    .filter(({name}) => name.toLowerCase() !== 'content-security-policy')
-    // ff: markdown `content-type` is not allowed
-    .map((header) => {
-      if (
-        /Firefox/.test(navigator.userAgent) &&
-        header.name.toLowerCase() === 'content-type' &&
-        /text\/(?:x-)?markdown/.test(header.value)
-      ) {
-        header.value = 'text/plain; charset=utf-8'
-      }
-      return header
-    })
-  }),
-  {
-    urls: ['<all_urls>'],
-    types: ['main_frame', 'sub_frame']
-  },
-  ['blocking', 'responseHeaders']
-)
+chrome.webRequest.onHeadersReceived.addListener(...onHeaderArgs)

+ 39 - 2
content/options.js

@@ -3,6 +3,7 @@ var defaults = {
   // storage
   origins: {},
   header: false,
+  csp: false,
   // static
   protocols: ['https', 'http', '*'],
   // UI
@@ -26,6 +27,19 @@ var events = {
     })
   },
 
+  csp: (e) => {
+    var action = state.csp ? 'remove' : 'request'
+    state.csp = !state.csp
+    chrome.permissions[action]({
+      permissions: ['webRequest', 'webRequestBlocking']
+    }, () => {
+      chrome.runtime.sendMessage({
+        message: 'options.csp',
+        csp: state.csp,
+      })
+    })
+  },
+
   origin: {
     protocol: (e) => {
       state.protocol = state.protocols[e.target.selectedIndex]
@@ -104,10 +118,15 @@ var oncreate = {
 }
 
 var onupdate = {
-  switch: (vnode) => {
+  header: (vnode) => {
     if (vnode.dom.classList.contains('is-checked') !== state.header) {
       vnode.dom.classList.toggle('is-checked')
     }
+  },
+  csp: (vnode) => {
+    if (vnode.dom.classList.contains('is-checked') !== state.csp) {
+      vnode.dom.classList.toggle('is-checked')
+    }
   }
 }
 
@@ -168,7 +187,7 @@ m.mount(document.querySelector('main'), {
         // header detection - ff: disabled
         (!/Firefox/.test(navigator.userAgent) || null) &&
         m('label.mdc-switch m-switch', {
-          onupdate: onupdate.switch,
+          onupdate: onupdate.header,
           title: 'Toggle header detection'
           },
           m('input.mdc-switch__native-control', {
@@ -186,6 +205,24 @@ m.mount(document.querySelector('main'), {
           )
         ),
 
+        // csp - ff: disabled
+        (!/Firefox/.test(navigator.userAgent) || null) &&
+        m('label.mdc-switch m-switch', {
+          onupdate: onupdate.csp,
+          title: 'Disable Content Security Policy (CSP)'
+          },
+          m('input.mdc-switch__native-control', {
+            type: 'checkbox',
+            checked: state.csp,
+            onchange: events.csp
+          }),
+          m('.mdc-switch__background', m('.mdc-switch__knob')),
+          m('span.mdc-switch-label',
+            'Disable ',
+            m('code', 'Content Security Policy'),
+          )
+        ),
+
         m('ul.mdc-elevation--z2 m-list',
           Object.keys(state.origins).sort().map((origin) =>
             // ff: access to file:// URLs is not allowed

+ 3 - 1
manifest.json

@@ -72,6 +72,8 @@
   "optional_permissions": [
     "https://*/",
     "http://*/",
-    "*://*/"
+    "*://*/",
+    "webRequest",
+    "webRequestBlocking"
   ]
 }