|
|
@@ -1,4 +1,5 @@
|
|
|
import express from 'express';
|
|
|
+import csrf from 'csurf';
|
|
|
|
|
|
import apiV1FormValidator from '../middlewares/apiv1-form-validator';
|
|
|
import injectResetOrderByTokenMiddleware from '../middlewares/inject-reset-order-by-token-middleware';
|
|
|
@@ -20,6 +21,8 @@ const rateLimit = require('express-rate-limit');
|
|
|
const multer = require('multer');
|
|
|
const autoReap = require('multer-autoreap');
|
|
|
|
|
|
+const csrfProtection = csrf({ cookie: false });
|
|
|
+
|
|
|
const apiLimiter = rateLimit({
|
|
|
windowMs: 15 * 60 * 1000, // 15 minutes
|
|
|
max: 10, // limit each IP to 10 requests per windowMs
|
|
|
@@ -38,7 +41,6 @@ module.exports = function(crowi, app) {
|
|
|
const loginRequired = require('../middlewares/login-required')(crowi, true);
|
|
|
const adminRequired = require('../middlewares/admin-required')(crowi);
|
|
|
const certifySharedFile = require('../middlewares/certify-shared-file')(crowi);
|
|
|
- const csrf = require('../middlewares/csrf')(crowi);
|
|
|
const injectUserUISettings = require('../middlewares/inject-user-ui-settings-to-localvars')();
|
|
|
|
|
|
const uploads = multer({ dest: `${crowi.tmpDir}uploads` });
|
|
|
@@ -81,10 +83,10 @@ module.exports = function(crowi, app) {
|
|
|
app.get('/login/error/:reason' , applicationInstalled, login.error);
|
|
|
app.get('/login' , applicationInstalled, login.preLogin, login.login);
|
|
|
app.get('/login/invited' , applicationInstalled, login.invited);
|
|
|
- app.post('/login/activateInvited' , apiLimiter , applicationInstalled, loginFormValidator.inviteRules(), loginFormValidator.inviteValidation, csrf, login.invited);
|
|
|
- app.post('/login' , apiLimiter , applicationInstalled, loginFormValidator.loginRules(), loginFormValidator.loginValidation, csrf, loginPassport.loginWithLocal, loginPassport.loginWithLdap, loginPassport.loginFailure);
|
|
|
+ app.post('/login/activateInvited' , apiLimiter , applicationInstalled, loginFormValidator.inviteRules(), loginFormValidator.inviteValidation, csrfProtection, login.invited);
|
|
|
+ app.post('/login' , apiLimiter , applicationInstalled, loginFormValidator.loginRules(), loginFormValidator.loginValidation, csrfProtection, loginPassport.loginWithLocal, loginPassport.loginWithLdap, loginPassport.loginFailure);
|
|
|
|
|
|
- app.post('/register' , apiLimiter , applicationInstalled, registerFormValidator.registerRules(), registerFormValidator.registerValidation, csrf, login.register);
|
|
|
+ app.post('/register' , apiLimiter , applicationInstalled, registerFormValidator.registerRules(), registerFormValidator.registerValidation, csrfProtection, login.register);
|
|
|
app.get('/register' , applicationInstalled, login.preLogin, login.register);
|
|
|
|
|
|
app.get('/admin' , applicationInstalled, loginRequiredStrictly , adminRequired , admin.index);
|
|
|
@@ -94,7 +96,7 @@ module.exports = function(crowi, app) {
|
|
|
if (!isInstalled) {
|
|
|
const installer = require('./installer')(crowi);
|
|
|
app.get('/installer' , applicationNotInstalled , installer.index);
|
|
|
- app.post('/installer' , apiLimiter , applicationNotInstalled , registerFormValidator.registerRules(), registerFormValidator.registerValidation, csrf, installer.install);
|
|
|
+ app.post('/installer' , apiLimiter , applicationNotInstalled , registerFormValidator.registerRules(), registerFormValidator.registerValidation, csrfProtection, installer.install);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
@@ -144,12 +146,12 @@ module.exports = function(crowi, app) {
|
|
|
|
|
|
// importer management for admin
|
|
|
app.get('/admin/importer' , loginRequiredStrictly , adminRequired , admin.importer.index);
|
|
|
- app.post('/_api/admin/settings/importerEsa' , loginRequiredStrictly , adminRequired , csrf, admin.importer.api.validators.importer.esa(),admin.api.importerSettingEsa);
|
|
|
- app.post('/_api/admin/settings/importerQiita' , loginRequiredStrictly , adminRequired , csrf , admin.importer.api.validators.importer.qiita(), admin.api.importerSettingQiita);
|
|
|
- app.post('/_api/admin/import/esa' , loginRequiredStrictly , adminRequired , admin.api.importDataFromEsa);
|
|
|
- app.post('/_api/admin/import/testEsaAPI' , loginRequiredStrictly , adminRequired , csrf, admin.api.testEsaAPI);
|
|
|
- app.post('/_api/admin/import/qiita' , loginRequiredStrictly , adminRequired , admin.api.importDataFromQiita);
|
|
|
- app.post('/_api/admin/import/testQiitaAPI' , loginRequiredStrictly , adminRequired , csrf, admin.api.testQiitaAPI);
|
|
|
+ app.post('/_api/admin/settings/importerEsa' , loginRequiredStrictly , adminRequired , csrfProtection, admin.importer.api.validators.importer.esa(),admin.api.importerSettingEsa);
|
|
|
+ app.post('/_api/admin/settings/importerQiita' , loginRequiredStrictly , adminRequired , csrfProtection, admin.importer.api.validators.importer.qiita(), admin.api.importerSettingQiita);
|
|
|
+ app.post('/_api/admin/import/esa' , loginRequiredStrictly , adminRequired , csrfProtection, admin.api.importDataFromEsa);
|
|
|
+ app.post('/_api/admin/import/testEsaAPI' , loginRequiredStrictly , adminRequired , csrfProtection, admin.api.testEsaAPI);
|
|
|
+ app.post('/_api/admin/import/qiita' , loginRequiredStrictly , adminRequired , csrfProtection, admin.api.importDataFromQiita);
|
|
|
+ app.post('/_api/admin/import/testQiitaAPI' , loginRequiredStrictly , adminRequired , csrfProtection, admin.api.testQiitaAPI);
|
|
|
|
|
|
// export management for admin
|
|
|
app.get('/admin/export' , loginRequiredStrictly , adminRequired ,admin.export.index);
|
|
|
@@ -173,26 +175,26 @@ module.exports = function(crowi, app) {
|
|
|
|
|
|
// HTTP RPC Styled API (に徐々に移行していいこうと思う)
|
|
|
apiV1Router.get('/pages.list' , accessTokenParser , loginRequired , page.api.list);
|
|
|
- apiV1Router.post('/pages.update' , accessTokenParser , loginRequiredStrictly , csrf, page.api.update);
|
|
|
+ apiV1Router.post('/pages.update' , accessTokenParser , loginRequiredStrictly , page.api.update);
|
|
|
apiV1Router.get('/pages.exist' , accessTokenParser , loginRequired , page.api.exist);
|
|
|
apiV1Router.get('/pages.updatePost' , accessTokenParser, loginRequired, page.api.getUpdatePost);
|
|
|
apiV1Router.get('/pages.getPageTag' , accessTokenParser , loginRequired , page.api.getPageTag);
|
|
|
// allow posting to guests because the client doesn't know whether the user logged in
|
|
|
- apiV1Router.post('/pages.remove' , loginRequiredStrictly , csrf, page.validator.remove, apiV1FormValidator, page.api.remove); // (Avoid from API Token)
|
|
|
- apiV1Router.post('/pages.revertRemove' , loginRequiredStrictly , csrf, page.validator.revertRemove, apiV1FormValidator, page.api.revertRemove); // (Avoid from API Token)
|
|
|
- apiV1Router.post('/pages.unlink' , loginRequiredStrictly , csrf, page.api.unlink); // (Avoid from API Token)
|
|
|
- apiV1Router.post('/pages.duplicate' , accessTokenParser, loginRequiredStrictly, csrf, page.api.duplicate);
|
|
|
+ apiV1Router.post('/pages.remove' , loginRequiredStrictly , page.validator.remove, apiV1FormValidator, page.api.remove); // (Avoid from API Token)
|
|
|
+ apiV1Router.post('/pages.revertRemove' , loginRequiredStrictly , page.validator.revertRemove, apiV1FormValidator, page.api.revertRemove); // (Avoid from API Token)
|
|
|
+ apiV1Router.post('/pages.unlink' , loginRequiredStrictly , page.api.unlink); // (Avoid from API Token)
|
|
|
+ apiV1Router.post('/pages.duplicate' , accessTokenParser, loginRequiredStrictly, page.api.duplicate);
|
|
|
apiV1Router.get('/tags.list' , accessTokenParser, loginRequired, tag.api.list);
|
|
|
apiV1Router.get('/tags.search' , accessTokenParser, loginRequired, tag.api.search);
|
|
|
apiV1Router.post('/tags.update' , accessTokenParser, loginRequiredStrictly, tag.api.update);
|
|
|
apiV1Router.get('/comments.get' , accessTokenParser , loginRequired , comment.api.get);
|
|
|
- apiV1Router.post('/comments.add' , comment.api.validators.add(), accessTokenParser , loginRequiredStrictly , csrf, comment.api.add);
|
|
|
- apiV1Router.post('/comments.update' , comment.api.validators.add(), accessTokenParser , loginRequiredStrictly , csrf, comment.api.update);
|
|
|
+ apiV1Router.post('/comments.add' , comment.api.validators.add(), accessTokenParser , loginRequiredStrictly , comment.api.add);
|
|
|
+ apiV1Router.post('/comments.update' , comment.api.validators.add(), accessTokenParser , loginRequiredStrictly , comment.api.update);
|
|
|
apiV1Router.post('/comments.remove' , accessTokenParser , loginRequiredStrictly , csrf, comment.api.remove);
|
|
|
- apiV1Router.post('/attachments.add' , uploads.single('file'), autoReap, accessTokenParser, loginRequiredStrictly ,csrf, attachment.api.add);
|
|
|
- apiV1Router.post('/attachments.uploadProfileImage' , uploads.single('file'), autoReap, accessTokenParser, loginRequiredStrictly ,csrf, attachment.api.uploadProfileImage);
|
|
|
- apiV1Router.post('/attachments.remove' , accessTokenParser , loginRequiredStrictly , csrf, attachment.api.remove);
|
|
|
- apiV1Router.post('/attachments.removeProfileImage' , accessTokenParser , loginRequiredStrictly , csrf, attachment.api.removeProfileImage);
|
|
|
+ apiV1Router.post('/attachments.add' , uploads.single('file'), autoReap, accessTokenParser, loginRequiredStrictly, attachment.api.add);
|
|
|
+ apiV1Router.post('/attachments.uploadProfileImage' , uploads.single('file'), autoReap, accessTokenParser, loginRequiredStrictly, attachment.api.uploadProfileImage);
|
|
|
+ apiV1Router.post('/attachments.remove' , accessTokenParser , loginRequiredStrictly , attachment.api.remove);
|
|
|
+ apiV1Router.post('/attachments.removeProfileImage' , accessTokenParser , loginRequiredStrictly , attachment.api.removeProfileImage);
|
|
|
apiV1Router.get('/attachments.limit' , accessTokenParser , loginRequiredStrictly, attachment.api.limit);
|
|
|
|
|
|
// API v1
|
|
|
@@ -223,9 +225,9 @@ module.exports = function(crowi, app) {
|
|
|
|
|
|
app.get('/_hackmd/load-agent' , hackmd.loadAgent);
|
|
|
app.get('/_hackmd/load-styles' , hackmd.loadStyles);
|
|
|
- app.post('/_api/hackmd.integrate' , accessTokenParser , loginRequiredStrictly , csrf, hackmd.validateForApi, hackmd.integrate);
|
|
|
- app.post('/_api/hackmd.discard' , accessTokenParser , loginRequiredStrictly , csrf, hackmd.validateForApi, hackmd.discard);
|
|
|
- app.post('/_api/hackmd.saveOnHackmd' , accessTokenParser , loginRequiredStrictly , csrf, hackmd.validateForApi, hackmd.saveOnHackmd);
|
|
|
+ app.post('/_api/hackmd.integrate' , accessTokenParser , loginRequiredStrictly , hackmd.validateForApi, hackmd.integrate);
|
|
|
+ app.post('/_api/hackmd.discard' , accessTokenParser , loginRequiredStrictly , hackmd.validateForApi, hackmd.discard);
|
|
|
+ app.post('/_api/hackmd.saveOnHackmd' , accessTokenParser , loginRequiredStrictly , hackmd.validateForApi, hackmd.saveOnHackmd);
|
|
|
|
|
|
app.use('/forgot-password', express.Router()
|
|
|
.use(forgotPassword.checkForgotPasswordEnabledMiddlewareFactory(crowi))
|
|
|
@@ -238,7 +240,7 @@ module.exports = function(crowi, app) {
|
|
|
app.use('/user-activation', express.Router()
|
|
|
.get('/:token', apiLimiter, applicationInstalled, injectUserRegistrationOrderByTokenMiddleware, userActivation.form)
|
|
|
.use(userActivation.tokenErrorHandlerMiddeware));
|
|
|
- app.post('/user-activation/register', apiLimiter, applicationInstalled, csrf, userActivation.registerRules(), userActivation.validateRegisterForm, userActivation.registerAction(crowi));
|
|
|
+ app.post('/user-activation/register', apiLimiter, applicationInstalled, csrfProtection, userActivation.registerRules(), userActivation.validateRegisterForm, userActivation.registerAction(crowi));
|
|
|
|
|
|
app.get('/share/:linkId', page.showSharedPage);
|
|
|
|