Browse Source

feat: SRI security toggle

pull/1098/head
NGPixel 5 years ago
parent
commit
acb57879dd
10 changed files with 452 additions and 322 deletions
  1. 12
      client/components/admin/admin-general.vue
  2. 23
      client/components/common/page-selector.vue
  3. 1
      client/graph/admin/site/site-query-config.gql
  4. 19
      dev/templates/legacy.pug
  5. 6
      dev/templates/master.pug
  6. 70
      package.json
  7. 1
      server/app/data.yml
  8. 1
      server/graph/resolvers/site.js
  9. 2
      server/graph/schemas/site.graphql
  10. 639
      yarn.lock

12
client/components/admin/admin-general.vue

@ -184,6 +184,16 @@
hint='Should be enabled when using a reverse-proxy like nginx, apache, CloudFlare, etc in front of Wiki.js. Turn off otherwise.'
)
v-divider.mt-3
v-switch(
inset
label='Subresource Integrity'
color='red darken-2'
v-model='config.securitySRI'
persistent-hint
hint='This ensure that resources such as CSS and JS files are not altered during delivery.'
)
v-divider.mt-3
v-switch(
inset
@ -262,6 +272,7 @@ export default {
securityIframe: true,
securityReferrerPolicy: true,
securityTrustProxy: true,
securitySRI: true,
securityHSTS: false,
securityHSTSDuration: 0,
securityCSP: false,
@ -309,6 +320,7 @@ export default {
securityIframe: _.get(this.config, 'securityIframe', false),
securityReferrerPolicy: _.get(this.config, 'securityReferrerPolicy', false),
securityTrustProxy: _.get(this.config, 'securityTrustProxy', false),
securitySRI: _.get(this.config, 'securitySRI', false),
securityHSTS: _.get(this.config, 'securityHSTS', false),
securityHSTSDuration: _.get(this.config, 'securityHSTSDuration', 0),
securityCSP: _.get(this.config, 'securityCSP', false),

23
client/components/common/page-selector.vue

@ -17,7 +17,7 @@
v-toolbar(color='grey darken-3', dark, dense, flat)
.body-2 Virtual Folders
v-spacer
v-btn(icon, tile)
v-btn(icon, tile, href='https://docs.requarks.io/', target='_blank')
v-icon mdi-help-box
v-treeview(
:active.sync='currentNode'
@ -37,8 +37,8 @@
v-toolbar(color='blue darken-2', dark, dense, flat)
.body-2 Pages
v-spacer
v-btn(icon, tile): v-icon mdi-content-save-move-outline
v-btn(icon, tile): v-icon mdi-trash-can-outline
v-btn(icon, tile, disabled): v-icon mdi-content-save-move-outline
v-btn(icon, tile, disabled): v-icon mdi-trash-can-outline
v-list.py-0(dense, v-if='currentPages.length > 0')
v-list-item-group(
v-model='currentPage'
@ -131,6 +131,7 @@ export default {
children: []
}],
pages: [],
all: [],
namespaces: siteLangs.length ? siteLangs.map(ns => ns.code) : [siteConfig.lang]
}
},
@ -162,6 +163,20 @@ export default {
this.$nextTick(() => {
this.currentNode = oldValue
})
} else {
if (this.openNodes.indexOf(newValue[0]) < 0) { // auto open and load children
const current = _.find(this.all, ['id', newValue[0]])
if (current) {
if (this.openNodes.indexOf(current.parent) < 0) {
this.$nextTick(() => {
this.openNodes.push(current.parent)
})
}
}
this.$nextTick(() => {
this.openNodes.push(newValue[0])
})
}
}
},
currentPage (newValue, oldValue) {
@ -204,6 +219,8 @@ export default {
}
this.pages.push(...itemPages)
this.all.push(...items)
this.searchLoading = false
}
}

1
client/graph/admin/site/site-query-config.gql

@ -16,6 +16,7 @@
securityIframe
securityReferrerPolicy
securityTrustProxy
securitySRI
securityHSTS
securityHSTSDuration
securityCSP

19
dev/templates/legacy.pug

@ -43,21 +43,11 @@ html
//- CSS
<% for (var index in htmlWebpackPlugin.files.css) { %>
<% if (htmlWebpackPlugin.files.cssIntegrity) { %>
link(
type='text/css'
rel='stylesheet'
href='<%= htmlWebpackPlugin.files.css[index] %>'
integrity='<%= htmlWebpackPlugin.files.cssIntegrity[index] %>'
crossorigin='<%= webpackConfig.output.crossOriginLoading %>'
)
<% } else { %>
link(
type='text/css'
rel='stylesheet'
href='<%= htmlWebpackPlugin.files.css[index] %>'
)
<% } %>
<% } %>
script(
@ -67,19 +57,10 @@ html
//- JS
<% for (var index in htmlWebpackPlugin.files.js) { %>
<% if (htmlWebpackPlugin.files.cssIntegrity) { %>
script(
type='text/javascript'
src='<%= htmlWebpackPlugin.files.js[index] %>'
integrity='<%= htmlWebpackPlugin.files.jsIntegrity[index] %>'
crossorigin='<%= webpackConfig.output.crossOriginLoading %>'
)
<% } else { %>
script(
type='text/javascript'
src='<%= htmlWebpackPlugin.files.js[index] %>'
)
<% } %>
<% } %>
!= analyticsCode.head

6
dev/templates/master.pug

@ -52,7 +52,7 @@ html(lang=siteConfig.lang)
type='text/css'
rel='stylesheet'
href='<%= htmlWebpackPlugin.files.css[index] %>'
integrity='<%= htmlWebpackPlugin.files.cssIntegrity[index] %>'
integrity=config.security.securitySRI ? '<%= htmlWebpackPlugin.files.cssIntegrity[index] %>' : false
crossorigin='<%= webpackConfig.output.crossOriginLoading %>'
)
<% } else { %>
@ -66,11 +66,11 @@ html(lang=siteConfig.lang)
//- JS
<% for (var index in htmlWebpackPlugin.files.js) { %>
<% if (htmlWebpackPlugin.files.cssIntegrity) { %>
<% if (htmlWebpackPlugin.files.jsIntegrity) { %>
script(
type='text/javascript'
src='<%= htmlWebpackPlugin.files.js[index] %>'
integrity='<%= htmlWebpackPlugin.files.jsIntegrity[index] %>'
integrity=config.security.securitySRI ? '<%= htmlWebpackPlugin.files.jsIntegrity[index] %>' : false
crossorigin='<%= webpackConfig.output.crossOriginLoading %>'
)
<% } else { %>

70
package.json

@ -35,22 +35,22 @@
},
"dependencies": {
"@aoberoi/passport-slack": "1.0.5",
"@bugsnag/js": "6.4.1",
"@bugsnag/js": "6.4.2",
"@exlinc/keycloak-passport": "1.0.2",
"algoliasearch": "3.35.0",
"algoliasearch": "3.35.1",
"apollo-fetch": "0.7.0",
"apollo-server": "2.9.4",
"apollo-server-express": "2.9.4",
"apollo-server": "2.9.6",
"apollo-server-express": "2.9.6",
"auto-load": "3.0.4",
"aws-sdk": "2.538.0",
"aws-sdk": "2.548.0",
"azure-search-client": "3.1.5",
"bcryptjs-then": "1.0.1",
"bluebird": "3.5.5",
"bluebird": "3.7.0",
"body-parser": "1.19.0",
"brute-knex": "4.0.0",
"chalk": "2.4.2",
"cheerio": "1.0.0-rc.3",
"chokidar": "3.1.1",
"chokidar": "3.2.1",
"clean-css": "4.2.1",
"compression": "1.7.4",
"connect-session-knex": "1.4.0",
@ -59,35 +59,35 @@
"custom-error-instance": "2.1.1",
"dependency-graph": "0.8.0",
"diff": "4.0.1",
"diff2html": "2.11.3",
"diff2html": "2.12.1",
"dotize": "0.3.0",
"elasticsearch6": "npm:@elastic/elasticsearch@6",
"elasticsearch7": "npm:@elastic/elasticsearch@7",
"emoji-regex": "8.0.0",
"express": "4.17.1",
"express-brute": "1.0.1",
"express-session": "1.16.2",
"express-session": "1.17.0",
"file-type": "12.3.0",
"filesize": "4.2.1",
"filesize": "5.0.3",
"fs-extra": "8.1.0",
"getos": "3.1.1",
"graphql": "14.5.8",
"graphql-list-fields": "2.0.2",
"graphql-rate-limit-directive": "1.1.0",
"graphql-rate-limit-directive": "1.2.0",
"graphql-subscriptions": "1.1.0",
"graphql-tools": "4.0.5",
"he": "1.2.0",
"highlight.js": "9.15.10",
"i18next": "17.0.16",
"i18next": "17.2.0",
"i18next-express-middleware": "1.8.2",
"i18next-node-fs-backend": "2.1.3",
"image-size": "0.8.2",
"image-size": "0.8.3",
"js-base64": "2.5.1",
"js-binary": "1.2.0",
"js-yaml": "3.13.1",
"jsonwebtoken": "8.5.1",
"klaw": "3.0.0",
"knex": "0.19.4",
"knex": "0.19.5",
"lodash": "4.17.15",
"markdown-it": "10.0.0",
"markdown-it-abbr": "1.0.4",
@ -111,10 +111,10 @@
"mssql": "5.1.0",
"multer": "1.4.2",
"mysql2": "1.7.0",
"nanoid": "2.1.1",
"nanoid": "2.1.3",
"node-2fa": "1.1.2",
"node-cache": "4.2.1",
"nodemailer": "6.3.0",
"nodemailer": "6.3.1",
"objection": "1.6.11",
"passport": "0.4.0",
"passport-auth0": "1.2.1",
@ -148,7 +148,7 @@
"request-promise": "4.2.4",
"safe-regex": "2.0.2",
"sanitize-filename": "1.6.3",
"scim-query-filter-parser": "2.0.0",
"scim-query-filter-parser": "2.0.1",
"semver": "6.3.0",
"serve-favicon": "2.5.0",
"simple-git": "1.126.0",
@ -162,11 +162,11 @@
"uuid": "3.3.3",
"validate.js": "0.13.1",
"winston": "3.2.1",
"yargs": "14.0.0"
"yargs": "14.2.0"
},
"devDependencies": {
"@babel/cli": "^7.6.2",
"@babel/core": "^7.6.2",
"@babel/cli": "^7.6.4",
"@babel/core": "^7.6.4",
"@babel/plugin-proposal-class-properties": "^7.5.0",
"@babel/plugin-proposal-decorators": "^7.6.0",
"@babel/plugin-proposal-export-namespace-from": "^7.5.2",
@ -177,11 +177,11 @@
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
"@babel/plugin-syntax-import-meta": "^7.2.0",
"@babel/polyfill": "^7.6.0",
"@babel/preset-env": "^7.6.2",
"@mdi/font": "4.4.95",
"@babel/preset-env": "^7.6.3",
"@mdi/font": "4.5.95",
"@panter/vue-i18next": "0.15.1",
"@requarks/ckeditor5": "12.4.0-wiki.14",
"@vue/babel-preset-app": "3.11.0",
"@vue/babel-preset-app": "3.12.0",
"animate-sass": "0.8.2",
"animated-number-vue": "1.0.0",
"apollo-cache-inmemory": "1.6.3",
@ -193,7 +193,7 @@
"apollo-link-persisted-queries": "0.2.2",
"apollo-link-ws": "1.0.19",
"apollo-utilities": "1.3.2",
"autoprefixer": "9.6.1",
"autoprefixer": "9.6.4",
"babel-eslint": "10.0.3",
"babel-jest": "24.9.0",
"babel-loader": "^8.0.6",
@ -211,7 +211,7 @@
"cssnano": "4.1.10",
"duplicate-package-checker-webpack-plugin": "3.0.0",
"epic-spinners": "1.1.0",
"eslint": "6.4.0",
"eslint": "6.5.1",
"eslint-config-requarks": "1.0.7",
"eslint-config-standard": "14.1.0",
"eslint-plugin-import": "2.18.2",
@ -223,7 +223,7 @@
"file-loader": "4.2.0",
"filepond": "4.7.2",
"filepond-plugin-file-validate-type": "1.2.4",
"filesize.js": "1.0.2",
"filesize.js": "2.0.0",
"graphiql": "0.14.2",
"graphql-persisted-document-loader": "1.0.1",
"graphql-tag": "^2.10.1",
@ -253,19 +253,19 @@
"pug-plain-loader": "1.0.0",
"raw-loader": "3.1.0",
"resolve-url-loader": "3.1.0",
"sass": "1.22.12",
"sass": "1.23.0",
"sass-loader": "8.0.0",
"sass-resources-loader": "2.0.1",
"script-ext-html-webpack-plugin": "2.1.4",
"simple-progress-webpack-plugin": "1.1.2",
"style-loader": "1.0.0",
"terser": "4.3.3",
"terser": "4.3.8",
"twemoji-awesome": "1.0.6",
"url-loader": "2.1.0",
"url-loader": "2.2.0",
"velocity-animate": "1.5.2",
"viz.js": "2.1.2",
"vue": "2.6.10",
"vue-apollo": "3.0.0-rc.6",
"vue-apollo": "3.0.0-rc.7",
"vue-chartjs": "3.4.2",
"vue-clipboards": "1.3.0",
"vue-filepond": "5.1.3",
@ -278,22 +278,22 @@
"vue2-animate": "2.1.2",
"vuedraggable": "2.23.2",
"vuescroll": "4.14.4",
"vuetify": "2.0.19",
"vuetify": "2.1.3",
"vuetify-loader": "1.3.0",
"vuex": "3.1.1",
"vuex-pathify": "1.4.0",
"vuex-persistedstate": "2.5.4",
"webpack": "4.41.0",
"webpack": "4.41.1",
"webpack-bundle-analyzer": "3.5.2",
"webpack-cli": "3.3.9",
"webpack-dev-middleware": "3.7.1",
"webpack-dev-middleware": "3.7.2",
"webpack-hot-middleware": "2.25.0",
"webpack-merge": "4.2.2",
"webpack-subresource-integrity": "1.3.3",
"webpack-subresource-integrity": "1.3.4",
"webpackbar": "4.0.0",
"whatwg-fetch": "3.0.0",
"write-file-webpack-plugin": "4.5.1",
"xterm": "4.0.2",
"xterm": "4.1.0",
"zxcvbn": "4.4.2"
},
"browserslist": [

1
server/app/data.yml

@ -46,6 +46,7 @@ defaults:
securityIframe: true
securityReferrerPolicy: true
securityTrustProxy: true
securitySRI: true
securityHSTS: false
securityHSTSDuration: 300
securityCSP: false

1
server/graph/resolvers/site.js

@ -47,6 +47,7 @@ module.exports = {
securityIframe: args.securityIframe,
securityReferrerPolicy: args.securityReferrerPolicy,
securityTrustProxy: args.securityTrustProxy,
securitySRI: args.securitySRI,
securityHSTS: args.securityHSTS,
securityHSTSDuration: args.securityHSTSDuration,
securityCSP: args.securityCSP,

2
server/graph/schemas/site.graphql

@ -39,6 +39,7 @@ type SiteMutation {
securityIframe: Boolean!
securityReferrerPolicy: Boolean!
securityTrustProxy: Boolean!
securitySRI: Boolean!
securityHSTS: Boolean!
securityHSTSDuration: Int!
securityCSP: Boolean!
@ -66,6 +67,7 @@ type SiteConfig {
securityIframe: Boolean!
securityReferrerPolicy: Boolean!
securityTrustProxy: Boolean!
securitySRI: Boolean!
securityHSTS: Boolean!
securityHSTSDuration: Int!
securityCSP: Boolean!

639
yarn.lock
File diff suppressed because it is too large
View File

Loading…
Cancel
Save