Просмотр исходного кода

Merge remote-tracking branch 'origin/imprv/add-option-preventXSS-combine' into imprv/add-option-preventXSS-combine

sou 7 лет назад
Родитель
Сommit
4b384e8e17

+ 18 - 6
CHANGES.md

@@ -1,8 +1,22 @@
 CHANGES
 ========
 
-## 3.1.10-RC
+## 3.1.12-RC
 
+* Fix: Omit unnecessary css link
+    * Introduced by 3.1.10
+
+## 3.1.11
+
+* Fix: OAuth doesn't work in production because callback URL field cannot be specified
+    * Introduced by 3.1.9
+
+## 3.1.10
+
+* Fix: Enter key on react-bootstrap-typeahead doesn't submit
+    * Introduced by 3.1.9
+* Fix: CodeMirror of `/admin/customize` is broken
+    * Introduced by 3.1.9
 
 ## 3.1.9
 
@@ -10,7 +24,7 @@ CHANGES
 * Feature: Login with GitHub Account
 * Feature: Attach files in Comment
 * Improvement: Write comment with CodeMirror Editor
-* Improvement: Post comment with Ctrl-Enter
+* Improvement: Post comment with `Ctrl-Enter`
 * Improvement: Place the commented page at the beginning of the list
 * Improvement: Resolve errors on IE11 (Experimental)
 * Support: Migrate to webpack 4 
@@ -20,13 +34,11 @@ CHANGES
     * react-codemirror2
     * webpack
 
-
 ## 3.1.8 (Missing number)
 
-
 ## 3.1.7
 
-* Fix: Update hidden input 'pageForm[grant]' when save with Ctrl-S
+* Fix: Update hidden input 'pageForm[grant]' when save with `Ctrl-S`
 * Fix: Show alert message when conflict
 * Fix: `BLOCKDIAG_URI` environment variable doesn't work
 * Fix: Paste in markdown list doesn't work correctly
@@ -129,7 +141,7 @@ CHANGES
 * Fix: Sidebar breaks editor layouts
 * Support: Switch the logger from 'pino' to 'bunyan'
 * Support: Set the alias for 'debug' to the debug function of 'bunyan'
-* Support: Translate /admin/security
+* Support: Translate `/admin/security`
 * Support: Optimize bundles
     * upgrade 'markdown-it-toc-and-anchor-with-slugid' and omit 'uslug'
 * Support: Optimize .eslintrc.js

+ 2 - 0
README.md

@@ -168,8 +168,10 @@ Environment Variables
 * **Option (Overwritable in admin page)**
     * OAUTH_GOOGLE_CLIENT_ID: Google API client id for OAuth login
     * OAUTH_GOOGLE_CLIENT_SECRET: Google API client secret for OAuth login
+    * OAUTH_GOOGLE_CALLBACK_URI: Google API callback URI for OAuth login (Set `https://${growi.host}/passport/google/callback`)
     * OAUTH_GITHUB_CLIENT_ID: GitHub API client id for OAuth login
     * OAUTH_GITHUB_CLIENT_SECRET: GitHub API client secret for OAuth login
+    * OAUTH_GITHUB_CALLBACK_URI: GitHub API callback URI for OAuth login (Set `https://${growi.host}/passport/github/callback`)
 
 
 Documentation

+ 14 - 13
config/webpack.prod.js

@@ -8,7 +8,7 @@ const helpers = require('./helpers');
  * Webpack Plugins
  */
 const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
-const MiniCssExtractPlugin = require('mini-css-extract-plugin');
+const ExtractTextPlugin = require('extract-text-webpack-plugin');
 const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
 const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
 
@@ -28,24 +28,25 @@ module.exports = require('./webpack.common')({
     rules: [
       {
         test: /\.scss$/,
-        use: [
-          MiniCssExtractPlugin.loader,
-          'css-loader',
-          { loader: 'postcss-loader', options: {
-            sourceMap: false,
-            plugins: (loader) => [
-              require('autoprefixer')()
-            ]
-          } },
-          'sass-loader'
-        ],
+        use: ExtractTextPlugin.extract({
+          use: [
+            'css-loader',
+            { loader: 'postcss-loader', options: {
+              sourceMap: false,
+              plugins: (loader) => [
+                require('autoprefixer')()
+              ]
+            } },
+            'sass-loader'
+          ]
+        }),
         include: [helpers.root('resource/styles/scss')]
       }
     ]
   },
   plugins: [
 
-    new MiniCssExtractPlugin({
+    new ExtractTextPlugin({
       filename: '[name].[hash].css',
     }),
 

+ 2 - 1
lib/form/admin/securityPassportGitHub.js

@@ -8,5 +8,6 @@ module.exports = form(
   field('settingForm[security:passport-github:isEnabled]').trim().toBooleanStrict().required(),
   field('settingForm[security:passport-github:clientId]').trim(),
   field('settingForm[security:passport-github:clientSecret]').trim(),
-  field('settingForm[security:passport-github:isSameUsernameTreatedAsIdenticalUser]').trim().toBooleanStrict()
+  field('settingForm[security:passport-github:callbackUrl]').trim(),
+  field('settingForm[security:passport-github:isSameUsernameTreatedAsIdenticalUser]').trim().toBooleanStrict(),
 );

+ 2 - 1
lib/form/admin/securityPassportGoogle.js

@@ -8,5 +8,6 @@ module.exports = form(
   field('settingForm[security:passport-google:isEnabled]').trim().toBooleanStrict().required(),
   field('settingForm[security:passport-google:clientId]').trim(),
   field('settingForm[security:passport-google:clientSecret]').trim(),
-  field('settingForm[security:passport-google:isSameUsernameTreatedAsIdenticalUser]').trim().toBooleanStrict()
+  field('settingForm[security:passport-google:callbackUrl]').trim(),
+  field('settingForm[security:passport-google:isSameUsernameTreatedAsIdenticalUser]').trim().toBooleanStrict(),
 );

+ 1 - 0
lib/locales/en-US/translation.json

@@ -329,6 +329,7 @@
     "client_secret": "Client Secret",
     "xss_prevent_setting":"Prevent XSS(Cross Site Scripting)",
     "xss_prevent_setting_link":"Go to Markdown settings",
+    "callback_URL": "Callback URL",
     "guest_mode": {
       "deny": "Deny Unregistered Users",
       "readonly": "View Only"

+ 1 - 0
lib/locales/ja/translation.json

@@ -346,6 +346,7 @@
     "client_secret": "クライアントシークレット",
     "xss_prevent_setting":"XSS(Cross Site Scripting)対策設定",
     "xss_prevent_setting_link":"マークダウン設定ページに移動",
+    "callback_URL": "コールバックURL",
     "guest_mode": {
       "deny": "アカウントを持たないユーザーはアクセス不可",
       "readonly": "閲覧のみ許可"

+ 3 - 10
lib/routes/admin.js

@@ -452,7 +452,7 @@ module.exports = function(crowi, app) {
   };
 
   actions.user.remove = function(req, res) {
-    var id = req.params.id;
+    const id = req.params.id;
     let username = '';
 
     return new Promise((resolve, reject) => {
@@ -473,17 +473,10 @@ module.exports = function(crowi, app) {
     })
     .then((userData) => {
       // remove all External Accounts
-      ExternalAccount.remove({user: userData})
-      .then((err) => {
-        if (err) {
-          throw new Error(err.message);
-        }
-        return userData;
-      });
+      return ExternalAccount.remove({user: userData}).then(() => userData);
     })
     .then((userData) => {
-      return Page.removePageByPath(`/user/${username}`)
-        .then(() => userData);
+      return Page.removePageByPath(`/user/${username}`).then(() => userData);
     })
     .then((userData) => {
       req.flash('successMessage', `${username} さんのアカウントを削除しました`);

+ 9 - 4
lib/service/passport.js

@@ -220,7 +220,12 @@ class PassportService {
         bindDN.replace(/{{username}}/, loginForm.username):
         bindDN;
       const fixedBindCredentials = (isUserBind) ? loginForm.password : bindCredentials;
-      let serverOpt = { url, bindDN: fixedBindDN, bindCredentials: fixedBindCredentials, searchBase, searchFilter };
+      let serverOpt = {
+        url, bindDN: fixedBindDN, bindCredentials: fixedBindCredentials,
+        searchBase, searchFilter,
+        attrMapUsername: this.getLdapAttrNameMappedToUsername(),
+        attrMapName: this.getLdapAttrNameMappedToName(),
+      };
 
       if (groupSearchBase && groupSearchFilter) {
         serverOpt = Object.assign(serverOpt, { groupSearchBase, groupSearchFilter, groupDnProperty });
@@ -265,9 +270,9 @@ class PassportService {
 
     debug('GoogleStrategy: setting up..');
     passport.use(new GoogleStrategy({
-      clientId: config.crowi['security:passport-google:clientId'] || process.env.OAUTH_GOOGLE_CLIENT_SECRET,
+      clientId: config.crowi['security:passport-google:clientId'] || process.env.OAUTH_GOOGLE_CLIENT_ID,
       clientSecret: config.crowi['security:passport-google:clientSecret'] || process.env.OAUTH_GOOGLE_CLIENT_SECRET,
-      callbackURL: 'http://localhost:3000/passport/google/callback',  //change this
+      callbackURL: config.crowi['security:passport-google:callbackUrl'] || process.env.OAUTH_GOOGLE_CALLBACK_URI,
       skipUserProfile: false,
     }, function(accessToken, refreshToken, profile, done) {
       if (profile) {
@@ -313,7 +318,7 @@ class PassportService {
     passport.use(new GitHubStrategy({
       clientID: config.crowi['security:passport-github:clientId'] || process.env.OAUTH_GITHUB_CLIENT_ID,
       clientSecret: config.crowi['security:passport-github:clientSecret'] || process.env.OAUTH_GITHUB_CLIENT_SECRET,
-      callbackURL: 'http://localhost:3000/passport/github/callback',  //change this
+      callbackURL: config.crowi['security:passport-github:callbackUrl'] || process.env.OAUTH_GITHUB_CALLBACK_URI,
       skipUserProfile: false,
     }, function(accessToken, refreshToken, profile, done) {
       if (profile) {

+ 15 - 0
lib/views/admin/widget/passport/github.html

@@ -45,6 +45,21 @@
         </p>
       </div>
     </div>
+
+    <div class="form-group">
+      <label for="settingForm[security:passport-github:callbackUrl]" class="col-xs-3 control-label">{{ t("security_setting.callback_URL") }}</label>
+      <div class="col-xs-6">
+        <input class="form-control" type="text" name="settingForm[security:passport-github:callbackUrl]" value="{{ settingForm['security:passport-github:callbackUrl'] || '' }}"
+            placeholder="http(s)://${growi.host}/passport/github/callback">
+        <p class="help-block">
+          Input <code>http(s)://${growi.host}/passport/github/callback</code><br>
+          <small>
+            {{ t("security_setting.Use env var if empty", "OAUTH_GITHUB_CALLBACK_URI") }}
+          </small>
+        </p>
+      </div>
+    </div>
+
     <div class="form-group">
       <div class="col-xs-6 col-xs-offset-3">
         <div class="checkbox checkbox-info">

+ 15 - 0
lib/views/admin/widget/passport/google-oauth.html

@@ -45,6 +45,21 @@
         </p>
       </div>
     </div>
+
+    <div class="form-group">
+      <label for="settingForm[security:passport-google:callbackUrl]" class="col-xs-3 control-label">{{ t("security_setting.callback_URL") }}</label>
+      <div class="col-xs-6">
+        <input class="form-control" type="text" name="settingForm[security:passport-google:callbackUrl]" value="{{ settingForm['security:passport-google:callbackUrl'] || '' }}"
+            placeholder="http(s)://${growi.host}/passport/google/callback">
+        <p class="help-block">
+          Input <code>http(s)://${growi.host}/passport/google/callback</code><br>
+          <small>
+            {{ t("security_setting.Use env var if empty", "OAUTH_GOOGLE_CALLBACK_URI") }}
+          </small>
+        </p>
+      </div>
+    </div>
+
     <div class="form-group">
       <div class="col-xs-6 col-xs-offset-3">
         <div class="checkbox checkbox-info">

+ 0 - 1
lib/views/layout/layout.html

@@ -88,7 +88,6 @@ gh/highlightjs/cdn-release@9.12.0/build/languages/yaml.min.js
       <script src="{{ webpack_asset('styles/style.js') }}"></script>
       <script src="{{ webpack_asset('styles/theme-' + theme() + '.js') }}"></script>
     {% else %}
-      <link rel="stylesheet" href="{{ webpack_asset('js/vendors.css') }}">
       <link rel="stylesheet" href="{{ webpack_asset('styles/style.css') }}">
       <link rel="stylesheet" href="{{ webpack_asset('styles/theme-' + theme() + '.css') }}">
     {% endif %}

+ 3 - 3
package.json

@@ -1,6 +1,6 @@
 {
   "name": "growi",
-  "version": "3.1.10-RC",
+  "version": "3.1.12-RC",
   "description": "Team collaboration software using markdown",
   "tags": [
     "wiki",
@@ -137,6 +137,7 @@
     "eazy-logger": "^3.0.2",
     "eslint": "^5.0.0",
     "eslint-plugin-react": "^7.7.0",
+    "extract-text-webpack-plugin": "^4.0.0-beta.0",
     "file-loader": "^1.1.0",
     "i18next-browser-languagedetector": "^2.2.0",
     "jquery-slimscroll": "^1.3.8",
@@ -155,7 +156,6 @@
     "markdown-it-toc-and-anchor-with-slugid": "^1.1.4",
     "markdown-table": "^1.1.1",
     "metismenu": "^2.7.4",
-    "mini-css-extract-plugin": "^0.4.0",
     "mocha": "^5.0.0",
     "morgan": "^1.9.0",
     "node-dev": "^3.1.3",
@@ -169,7 +169,7 @@
     "postcss-loader": "^2.1.3",
     "react": "^16.2.0",
     "react-bootstrap": "^0.32.1",
-    "react-bootstrap-typeahead": "^3.1.4",
+    "react-bootstrap-typeahead": "=3.0.4",
     "react-clipboard.js": "^2.0.0",
     "react-codemirror2": "^5.0.4",
     "react-dom": "^16.2.0",

+ 24 - 16
yarn.lock

@@ -553,6 +553,12 @@ async@^2.3.0:
   dependencies:
     lodash "^4.14.0"
 
+async@^2.4.1:
+  version "2.6.1"
+  resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610"
+  dependencies:
+    lodash "^4.17.10"
+
 async@~0.2.6:
   version "0.2.10"
   resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1"
@@ -1942,8 +1948,8 @@ code-point-at@^1.0.0:
   resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
 
 codemirror@^5.37.0:
-  version "5.37.0"
-  resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.37.0.tgz#c349b584e158f590277f26d37c2469a6bc538036"
+  version "5.39.0"
+  resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.39.0.tgz#4654f7d2f7e525e04a62e72d9482348ccb37dce5"
 
 collection-visit@^1.0.0:
   version "1.0.0"
@@ -3160,6 +3166,15 @@ extglob@^2.0.4:
     snapdragon "^0.8.1"
     to-regex "^3.0.1"
 
+extract-text-webpack-plugin@^4.0.0-beta.0:
+  version "4.0.0-beta.0"
+  resolved "https://registry.yarnpkg.com/extract-text-webpack-plugin/-/extract-text-webpack-plugin-4.0.0-beta.0.tgz#f7361d7ff430b42961f8d1321ba8c1757b5d4c42"
+  dependencies:
+    async "^2.4.1"
+    loader-utils "^1.1.0"
+    schema-utils "^0.4.5"
+    webpack-sources "^1.1.0"
+
 extsprintf@1.2.0:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.2.0.tgz#5ad946c22f5b32ba7f8cd7426711c6e8a3fc2529"
@@ -5212,13 +5227,6 @@ mimic-fn@^1.0.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18"
 
-mini-css-extract-plugin@^0.4.0:
-  version "0.4.0"
-  resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.4.0.tgz#ff3bf08bee96e618e177c16ca6131bfecef707f9"
-  dependencies:
-    loader-utils "^1.1.0"
-    webpack-sources "^1.1.0"
-
 minimalistic-assert@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz#702be2dda6b37f4836bcb3f5db56641b64a1d3d3"
@@ -6741,9 +6749,9 @@ rc@^1.1.7:
     minimist "^1.2.0"
     strip-json-comments "~2.0.1"
 
-react-bootstrap-typeahead@^3.1.4:
-  version "3.1.4"
-  resolved "https://registry.yarnpkg.com/react-bootstrap-typeahead/-/react-bootstrap-typeahead-3.1.4.tgz#970106959e0491f29fdeeb5dd7f51ca87b83c2e2"
+react-bootstrap-typeahead@=3.0.4:
+  version "3.0.4"
+  resolved "https://registry.yarnpkg.com/react-bootstrap-typeahead/-/react-bootstrap-typeahead-3.0.4.tgz#1ebfb259f986c86ff03beef1091cab4614d6ea1d"
   dependencies:
     classnames "^2.2.0"
     escape-string-regexp "^1.0.5"
@@ -6753,7 +6761,7 @@ react-bootstrap-typeahead@^3.1.4:
     prop-types-extra "^1.0.1"
     react-onclickoutside "^6.1.1"
     react-overlays "^0.8.1"
-    react-popper "^0.10.4"
+    react-popper "^0.9.0"
     warning "^3.0.0"
 
 react-bootstrap@^0.32.1:
@@ -6823,9 +6831,9 @@ react-overlays@^0.8.0, react-overlays@^0.8.1:
     react-transition-group "^2.2.0"
     warning "^3.0.0"
 
-react-popper@^0.10.4:
-  version "0.10.4"
-  resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-0.10.4.tgz#af2a415ea22291edd504678d7afda8a6ee3295aa"
+react-popper@^0.9.0:
+  version "0.9.5"
+  resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-0.9.5.tgz#02a24ef3eec33af9e54e8358ab70eb0e331edd05"
   dependencies:
     popper.js "^1.14.1"
     prop-types "^15.6.1"