Taichi Masuyama 3 лет назад
Родитель
Сommit
16e505b146

+ 4 - 2
packages/app/src/components/InstallerForm.tsx

@@ -24,7 +24,9 @@ const InstallerForm = memo((): JSX.Element => {
   }, []);
   }, []);
 
 
   // TODO: XHRize https://redmine.weseek.co.jp/issues/105252
   // TODO: XHRize https://redmine.weseek.co.jp/issues/105252
-  const submitHandler = useCallback(() => {
+  const submitHandler = useCallback((e) => {
+    e.preventDefault();
+
     if (isSubmittingDisabled) {
     if (isSubmittingDisabled) {
       return;
       return;
     }
     }
@@ -51,7 +53,7 @@ const InstallerForm = memo((): JSX.Element => {
         </div>
         </div>
       </div>
       </div>
       <div className="row">
       <div className="row">
-        <form role="form" action="/installer" method="post" id="register-form" className="col-md-12" onSubmit={submitHandler}>
+        <form role="form" action="/_api/v3/installer" method="post" id="register-form" className="col-md-12" onSubmit={submitHandler}>
           <div className="dropdown mb-3">
           <div className="dropdown mb-3">
             <div className="d-flex dropdown-with-icon">
             <div className="d-flex dropdown-with-icon">
               <i className="icon-bubbles border-0 rounded-0" />
               <i className="icon-bubbles border-0 rounded-0" />

+ 6 - 0
packages/app/src/server/routes/apiv3/index.js

@@ -40,6 +40,12 @@ module.exports = (crowi) => {
   // auth
   // auth
   routerForAuth.use('/logout', require('./logout')(crowi));
   routerForAuth.use('/logout', require('./logout')(crowi));
 
 
+  // installer
+  const isInstalled = crowi.configManager.getConfig('crowi', 'app:installed');
+  if (!isInstalled) {
+    router.use('/installer', require('./installer')(crowi));
+  }
+
 
 
   router.use('/in-app-notification', require('./in-app-notification')(crowi));
   router.use('/in-app-notification', require('./in-app-notification')(crowi));
 
 

+ 28 - 16
packages/app/src/server/routes/installer.js → packages/app/src/server/routes/apiv3/installer.ts

@@ -1,26 +1,39 @@
+import express, { Request, Router } from 'express';
+
 import { SupportedAction } from '~/interfaces/activity';
 import { SupportedAction } from '~/interfaces/activity';
+import ErrorV3 from '~/server/models/vo/error-apiv3';
 import loggerFactory from '~/utils/logger';
 import loggerFactory from '~/utils/logger';
 
 
-import { InstallerService, FailedToCreateAdminUserError } from '../service/installer';
+import Crowi from '../../crowi';
+import { apiV3FormValidator } from '../../middlewares/apiv3-form-validator';
+import { registerValidation, registerRules } from '../../middlewares/register-form-validator';
+import { InstallerService, FailedToCreateAdminUserError } from '../../service/installer';
 
 
-const logger = loggerFactory('growi:routes:installer');
+import { ApiV3Response } from './interfaces/apiv3-response';
 
 
-module.exports = function(crowi) {
 
 
-  const actions = {};
+const logger = loggerFactory('growi:routes:apiv3:installer');
 
 
-  const activityEvent = crowi.event('activity');
 
 
-  actions.index = function(req, res) {
-    return res.render('installer');
-  };
+type FormRequest = Request & { form: any };
 
 
-  actions.install = async function(req, res, next) {
-    const registerForm = req.body.registerForm || {};
+module.exports = (crowi: Crowi): Router => {
+  const adminRequired = require('../../middlewares/admin-required')(crowi);
+  const accessTokenParser = require('../../middlewares/access-token-parser')(crowi);
+  const loginRequiredStrictly = require('../../middlewares/login-required')(crowi);
+  const applicationNotInstalled = require('../../middlewares/application-not-installed')(crowi);
 
 
-    if (!req.form.isValid) {
-      return res.render('installer');
+  const activityEvent = crowi.event('activity');
+
+  const router = express.Router();
+
+  // eslint-disable-next-line max-len
+  router.post('/', applicationNotInstalled, accessTokenParser, loginRequiredStrictly, adminRequired, registerRules, registerValidation, apiV3FormValidator, async(req: FormRequest, res: ApiV3Response) => {
+    const appService = crowi.appService;
+    if (appService == null) {
+      return res.apiv3Err(new ErrorV3('GROWI cannot be installed due to an internal error', 'app_service_not_setup'), 500);
     }
     }
+    const registerForm = req.body.registerForm || {};
 
 
     const name = registerForm.name;
     const name = registerForm.name;
     const username = registerForm.username;
     const username = registerForm.username;
@@ -46,8 +59,7 @@ module.exports = function(crowi) {
       return res.render('installer');
       return res.render('installer');
     }
     }
 
 
-    const appService = crowi.appService;
-    appService.setupAfterInstall();
+    await appService.setupAfterInstall();
 
 
     // login with passport
     // login with passport
     req.logIn(adminUser, (err) => {
     req.logIn(adminUser, (err) => {
@@ -64,7 +76,7 @@ module.exports = function(crowi) {
 
 
       return res.redirect('/');
       return res.redirect('/');
     });
     });
-  };
+  });
 
 
-  return actions;
+  return router;
 };
 };

+ 1 - 1
packages/app/src/server/service/installer.ts

@@ -109,7 +109,7 @@ export class InstallerService {
     return configManager.updateConfigsInTheSameNamespace('crowi', initialConfig, true);
     return configManager.updateConfigsInTheSameNamespace('crowi', initialConfig, true);
   }
   }
 
 
-  async install(firstAdminUserToSave: IUser, globalLang: Lang, options?: AutoInstallOptions): Promise<IUser> {
+  async install(firstAdminUserToSave: Pick<IUser, 'name' | 'username' | 'email' | 'password'>, globalLang: Lang, options?: AutoInstallOptions): Promise<IUser> {
     await this.initDB(globalLang, options);
     await this.initDB(globalLang, options);
 
 
     // TODO typescriptize models/user.js and remove eslint-disable-next-line
     // TODO typescriptize models/user.js and remove eslint-disable-next-line