jam411 3 лет назад
Родитель
Сommit
e740d4cbf8

+ 1 - 1
packages/app/config/rate-limiter.ts

@@ -33,7 +33,7 @@ export const defaultConfig: IApiRateLimitEndpointMap = {
     maxRequests: MAX_REQUESTS_TIER_1,
     usersPerIpProspection: 100,
   },
-  '/invited/activateInvited': {
+  '/invited': {
     method: 'POST',
     maxRequests: MAX_REQUESTS_TIER_2,
   },

+ 1 - 1
packages/app/src/components/InvitedForm.tsx

@@ -39,7 +39,7 @@ export const InvitedForm = (props: InvitedFormProps): JSX.Element => {
     };
 
     try {
-      await apiv3Post('/invited/activateInvited', { invitedForm });
+      await apiv3Post('/invited', { invitedForm });
       router.push('/');
     }
     catch (err) {

+ 0 - 45
packages/app/src/server/middlewares/invited-form-validator.ts

@@ -1,45 +0,0 @@
-import { body, validationResult } from 'express-validator';
-
-// form rules
-export const invitedRules = () => {
-  return [
-    body('invitedForm.username')
-      .matches(/^[\da-zA-Z\-_.]+$/)
-      .withMessage('message.Username has invalid characters')
-      .not()
-      .isEmpty()
-      .withMessage('message.Username field is required'),
-    body('invitedForm.name').not().isEmpty().withMessage('message.Name field is required'),
-    body('invitedForm.password')
-      .matches(/^[\x20-\x7F]*$/)
-      .withMessage('message.Password has invalid character')
-      .isLength({ min: 6 })
-      .withMessage('message.Password minimum character should be more than 6 characters')
-      .not()
-      .isEmpty()
-      .withMessage('message.Password field is required'),
-  ];
-};
-
-// validation action
-export const invitedValidation = (req, res, next) => {
-  const form = req.body;
-
-  const errors = validationResult(req);
-  if (errors.isEmpty()) {
-    Object.assign(form, { isValid: true });
-    req.form = form;
-    return next();
-  }
-
-  const extractedErrors: string[] = [];
-  errors.array().map(err => extractedErrors.push(err.msg));
-
-  Object.assign(form, {
-    isValid: false,
-    errors: extractedErrors,
-  });
-  req.form = form;
-
-  return next();
-};

+ 1 - 4
packages/app/src/server/routes/apiv3/index.js

@@ -2,7 +2,6 @@ import loggerFactory from '~/utils/logger';
 
 import { generateAddActivityMiddleware } from '../../middlewares/add-activity';
 import injectUserRegistrationOrderByTokenMiddleware from '../../middlewares/inject-user-registration-order-by-token-middleware';
-import * as invitedFormValidator from '../../middlewares/invited-form-validator';
 import * as loginFormValidator from '../../middlewares/login-form-validator';
 import * as registerFormValidator from '../../middlewares/register-form-validator';
 
@@ -51,13 +50,11 @@ module.exports = (crowi, app, isInstalled) => {
     addActivity, loginPassport.loginWithLocal, loginPassport.loginWithLdap, loginPassport.cannotLoginErrorHadnler, loginPassport.loginFailure);
 
   routerForAuth.use('/logout', require('./logout')(crowi));
+  routerForAuth.use('/invited', require('./invited')(crowi, app));
 
   routerForAuth.post('/register',
     applicationInstalled, registerFormValidator.registerRules(), registerFormValidator.registerValidation, addActivity, login.register);
 
-  routerForAuth.post('/invited/activateInvited',
-    applicationInstalled, invitedFormValidator.invitedRules(), invitedFormValidator.invitedValidation, login.invited);
-
   // installer
   if (!isInstalled) {
     routerForAdmin.use('/installer', require('./installer')(crowi));

+ 97 - 0
packages/app/src/server/routes/apiv3/invited.ts

@@ -0,0 +1,97 @@
+import express, { Request, Router } from 'express';
+import { body, validationResult } from 'express-validator';
+
+import Crowi from '../../crowi';
+import { ApiV3Response } from './interfaces/apiv3-response';
+
+module.exports = (crowi: Crowi, app: any): Router => {
+  const applicationInstalled = require('../middlewares/application-installed')(crowi);
+  const debug = require('debug')('growi:routes:login');
+  const User = crowi.model('User');
+  const router = express.Router();
+
+  const invitedRules = () => {
+    return [
+      body('invitedForm.username')
+        .matches(/^[\da-zA-Z\-_.]+$/)
+        .withMessage('message.Username has invalid characters')
+        .not()
+        .isEmpty()
+        .withMessage('message.Username field is required'),
+      body('invitedForm.name').not().isEmpty().withMessage('message.Name field is required'),
+      body('invitedForm.password')
+        .matches(/^[\x20-\x7F]*$/)
+        .withMessage('message.Password has invalid character')
+        .isLength({ min: 6 })
+        .withMessage('message.Password minimum character should be more than 6 characters')
+        .not()
+        .isEmpty()
+        .withMessage('message.Password field is required'),
+    ];
+  };
+
+  const invitedValidation = (req, res, next) => {
+    const form = req.body;
+
+    const errors = validationResult(req);
+    if (errors.isEmpty()) {
+      Object.assign(form, { isValid: true });
+      req.form = form;
+      return next();
+    }
+
+    const extractedErrors: string[] = [];
+    errors.array().map(err => extractedErrors.push(err.msg));
+
+    Object.assign(form, {
+      isValid: false,
+      errors: extractedErrors,
+    });
+    req.form = form;
+
+    return next();
+  };
+
+  router.post('/invited', applicationInstalled, invitedRules(), invitedValidation, async(req: any, res: ApiV3Response) => {
+    if (!req.user) {
+      return res.redirect('/login');
+    }
+
+    if (req.method === 'POST' && req.form.isValid) {
+      const user = req.user;
+      const invitedForm = req.form.invitedForm || {};
+      const username = invitedForm.username;
+      const name = invitedForm.name;
+      const password = invitedForm.password;
+
+      // check user upper limit
+      const isUserCountExceedsUpperLimit = await User.isUserCountExceedsUpperLimit();
+      if (isUserCountExceedsUpperLimit) {
+        req.flash('warningMessage', req.t('message.can_not_activate_maximum_number_of_users'));
+        return res.redirect('/invited');
+      }
+
+      const creatable = await User.isRegisterableUsername(username);
+      if (creatable) {
+        try {
+          await user.activateInvitedUser(username, name, password);
+          return res.redirect('/');
+        }
+        catch (err) {
+          req.flash('warningMessage', req.t('message.failed_to_activate'));
+          return res.render('invited');
+        }
+      }
+      else {
+        req.flash('warningMessage', req.t('message.unable_to_use_this_user'));
+        debug('username', username);
+        return res.render('invited');
+      }
+    }
+    else {
+      return res.render('invited');
+    }
+  });
+
+  return router;
+};