app-settings.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689
  1. const loggerFactory = require('@alias/logger');
  2. const logger = loggerFactory('growi:routes:apiv3:app-settings');
  3. const debug = require('debug')('growi:routes:admin');
  4. const express = require('express');
  5. const { pathUtils } = require('growi-commons');
  6. const { listLocaleIds } = require('@commons/util/locale-utils');
  7. const router = express.Router();
  8. const { body } = require('express-validator');
  9. const ErrorV3 = require('../../models/vo/error-apiv3');
  10. /**
  11. * @swagger
  12. * tags:
  13. * name: AppSettings
  14. */
  15. /**
  16. * @swagger
  17. *
  18. * components:
  19. * schemas:
  20. * AppSettingParams:
  21. * description: AppSettingParams
  22. * type: object
  23. * properties:
  24. * title:
  25. * type: string
  26. * description: site name show on page header and tilte of HTML
  27. * confidential:
  28. * type: string
  29. * description: confidential show on page header
  30. * globalLang:
  31. * type: string
  32. * description: language set when create user
  33. * fileUpload:
  34. * type: boolean
  35. * description: enable upload file except image file
  36. * SiteUrlSettingParams:
  37. * description: SiteUrlSettingParams
  38. * type: object
  39. * properties:
  40. * siteUrl:
  41. * type: string
  42. * description: Site URL. e.g. https://example.com, https://example.com:8080
  43. * envSiteUrl:
  44. * type: string
  45. * description: environment variable 'APP_SITE_URL'
  46. * MailSetting:
  47. * description: MailSettingParams
  48. * type: object
  49. * properties:
  50. * fromAddress:
  51. * type: string
  52. * description: e-mail address used as from address of mail which sent from GROWI app
  53. * transmissionMethod:
  54. * type: string
  55. * description: transmission method
  56. * SmtpSettingParams:
  57. * description: SmtpSettingParams
  58. * type: object
  59. * properties:
  60. * smtpHost:
  61. * type: string
  62. * description: host name of client's smtp server
  63. * smtpPort:
  64. * type: string
  65. * description: port of client's smtp server
  66. * smtpUser:
  67. * type: string
  68. * description: user name of client's smtp server
  69. * smtpPassword:
  70. * type: string
  71. * description: password of client's smtp server
  72. * SesSettingParams:
  73. * description: SesSettingParams
  74. * type: object
  75. * properties:
  76. * accessKeyId:
  77. * type: string
  78. * description: accesskey id for authentification of AWS
  79. * secretAccessKey:
  80. * type: string
  81. * description: secret key for authentification of AWS
  82. * FileUploadSettingParams:
  83. * description: FileUploadTypeParams
  84. * type: object
  85. * properties:
  86. * fileUploadType:
  87. * type: string
  88. * description: fileUploadType
  89. * s3Region:
  90. * type: string
  91. * description: region of AWS S3
  92. * s3CustomEndpoint:
  93. * type: string
  94. * description: custom endpoint of AWS S3
  95. * s3Bucket:
  96. * type: string
  97. * description: AWS S3 bucket name
  98. * s3AccessKeyId:
  99. * type: string
  100. * description: accesskey id for authentification of AWS
  101. * s3SecretAccessKey:
  102. * type: string
  103. * description: secret key for authentification of AWS
  104. * s3ReferenceFileWithRelayMode:
  105. * type: boolean
  106. * description: is enable internal stream system for s3 file request
  107. * gcsApiKeyJsonPath:
  108. * type: string
  109. * description: apiKeyJsonPath of gcp
  110. * gcsBucket:
  111. * type: string
  112. * description: bucket name of gcs
  113. * gcsUploadNamespace:
  114. * type: string
  115. * description: name space of gcs
  116. * gcsReferenceFileWithRelayMode:
  117. * type: boolean
  118. * description: is enable internal stream system for gcs file request
  119. * envGcsApiKeyJsonPath:
  120. * type: string
  121. * description: Path of the JSON file that contains service account key to authenticate to GCP API
  122. * envGcsBucket:
  123. * type: string
  124. * description: Name of the GCS bucket
  125. * envGcsUploadNamespace:
  126. * type: string
  127. * description: Directory name to create in the bucket
  128. * PluginSettingParams:
  129. * description: PluginSettingParams
  130. * type: object
  131. * properties:
  132. * isEnabledPlugins:
  133. * type: string
  134. * description: enable use plugins
  135. */
  136. module.exports = (crowi) => {
  137. const accessTokenParser = require('../../middlewares/access-token-parser')(crowi);
  138. const loginRequiredStrictly = require('../../middlewares/login-required')(crowi);
  139. const adminRequired = require('../../middlewares/admin-required')(crowi);
  140. const csrf = require('../../middlewares/csrf')(crowi);
  141. const apiV3FormValidator = require('../../middlewares/apiv3-form-validator')(crowi);
  142. const validator = {
  143. appSetting: [
  144. body('title').trim(),
  145. body('confidential'),
  146. body('globalLang').isIn(listLocaleIds()),
  147. body('fileUpload').isBoolean(),
  148. ],
  149. siteUrlSetting: [
  150. // https://regex101.com/r/5Xef8V/1
  151. body('siteUrl').trim().matches(/^(https?:\/\/)/).isURL({ require_tld: false }),
  152. ],
  153. mailSetting: [
  154. body('fromAddress').trim().if(value => value !== '').isEmail(),
  155. body('transmissionMethod').isIn(['smtp', 'ses']),
  156. ],
  157. smtpSetting: [
  158. body('smtpHost').trim(),
  159. body('smtpPort').trim().if(value => value !== '').isPort(),
  160. body('smtpUser').trim(),
  161. body('smtpPassword').trim(),
  162. ],
  163. sesSetting: [
  164. body('sesAccessKeyId').trim().if(value => value !== '').matches(/^[\da-zA-Z]+$/),
  165. body('sesSecretAccessKey').trim(),
  166. ],
  167. fileUploadSetting: [
  168. body('fileUploadType').isIn(['aws', 'gcs', 'local', 'gridfs']),
  169. body('gcsApiKeyJsonPath').trim(),
  170. body('gcsBucket').trim(),
  171. body('gcsUploadNamespace').trim(),
  172. body('gcsReferenceFileWithRelayMode').if(value => value != null).isBoolean(),
  173. body('s3Region').trim().if(value => value !== '').matches(/^[a-z]+-[a-z]+-\d+$/)
  174. .withMessage((value, { req }) => req.t('validation.aws_region')),
  175. body('s3CustomEndpoint').trim().if(value => value !== '').matches(/^(https?:\/\/[^/]+|)$/)
  176. .withMessage((value, { req }) => req.t('validation.aws_custom_endpoint')),
  177. body('s3Bucket').trim(),
  178. body('s3AccessKeyId').trim().if(value => value !== '').matches(/^[\da-zA-Z]+$/),
  179. body('s3SecretAccessKey').trim(),
  180. body('s3ReferenceFileWithRelayMode').if(value => value != null).isBoolean(),
  181. ],
  182. pluginSetting: [
  183. body('isEnabledPlugins').isBoolean(),
  184. ],
  185. };
  186. /**
  187. * @swagger
  188. *
  189. * /app-settings:
  190. * get:
  191. * tags: [AppSettings]
  192. * operationId: getAppSettings
  193. * summary: /app-settings
  194. * description: get app setting params
  195. * responses:
  196. * 200:
  197. * description: Resources are available
  198. * content:
  199. * application/json:
  200. * schema:
  201. * properties:
  202. * appSettingsParams:
  203. * type: object
  204. * description: app settings params
  205. */
  206. router.get('/', accessTokenParser, loginRequiredStrictly, adminRequired, async(req, res) => {
  207. const appSettingsParams = {
  208. title: crowi.configManager.getConfig('crowi', 'app:title'),
  209. confidential: crowi.configManager.getConfig('crowi', 'app:confidential'),
  210. globalLang: crowi.configManager.getConfig('crowi', 'app:globalLang'),
  211. fileUpload: crowi.configManager.getConfig('crowi', 'app:fileUpload'),
  212. siteUrl: crowi.configManager.getConfig('crowi', 'app:siteUrl'),
  213. envSiteUrl: crowi.configManager.getConfigFromEnvVars('crowi', 'app:siteUrl'),
  214. isMailerSetup: crowi.mailService.isMailerSetup,
  215. fromAddress: crowi.configManager.getConfig('crowi', 'mail:from'),
  216. transmissionMethod: crowi.configManager.getConfig('crowi', 'mail:transmissionMethod'),
  217. smtpHost: crowi.configManager.getConfig('crowi', 'mail:smtpHost'),
  218. smtpPort: crowi.configManager.getConfig('crowi', 'mail:smtpPort'),
  219. smtpUser: crowi.configManager.getConfig('crowi', 'mail:smtpUser'),
  220. smtpPassword: crowi.configManager.getConfig('crowi', 'mail:smtpPassword'),
  221. sesAccessKeyId: crowi.configManager.getConfig('crowi', 'mail:sesAccessKeyId'),
  222. sesSecretAccessKey: crowi.configManager.getConfig('crowi', 'mail:sesSecretAccessKey'),
  223. fileUploadType: crowi.configManager.getConfig('crowi', 'app:fileUploadType'),
  224. envFileUploadType: crowi.configManager.getConfigFromEnvVars('crowi', 'app:fileUploadType'),
  225. useOnlyEnvVarForFileUploadType: crowi.configManager.getConfig('crowi', 'app:useOnlyEnvVarForFileUploadType'),
  226. s3Region: crowi.configManager.getConfig('crowi', 'aws:s3Region'),
  227. s3CustomEndpoint: crowi.configManager.getConfig('crowi', 'aws:s3CustomEndpoint'),
  228. s3Bucket: crowi.configManager.getConfig('crowi', 'aws:s3Bucket'),
  229. s3AccessKeyId: crowi.configManager.getConfig('crowi', 'aws:s3AccessKeyId'),
  230. s3SecretAccessKey: crowi.configManager.getConfig('crowi', 'aws:s3SecretAccessKey'),
  231. s3ReferenceFileWithRelayMode: crowi.configManager.getConfig('crowi', 'aws:referenceFileWithRelayMode'),
  232. gcsUseOnlyEnvVars: crowi.configManager.getConfig('crowi', 'gcs:useOnlyEnvVarsForSomeOptions'),
  233. gcsApiKeyJsonPath: crowi.configManager.getConfig('crowi', 'gcs:apiKeyJsonPath'),
  234. gcsBucket: crowi.configManager.getConfig('crowi', 'gcs:bucket'),
  235. gcsUploadNamespace: crowi.configManager.getConfig('crowi', 'gcs:uploadNamespace'),
  236. gcsReferenceFileWithRelayMode: crowi.configManager.getConfig('crowi', 'gcs:referenceFileWithRelayMode'),
  237. envGcsApiKeyJsonPath: crowi.configManager.getConfigFromEnvVars('crowi', 'gcs:apiKeyJsonPath'),
  238. envGcsBucket: crowi.configManager.getConfigFromEnvVars('crowi', 'gcs:bucket'),
  239. envGcsUploadNamespace: crowi.configManager.getConfigFromEnvVars('crowi', 'gcs:uploadNamespace'),
  240. isEnabledPlugins: crowi.configManager.getConfig('crowi', 'plugin:isEnabledPlugins'),
  241. };
  242. return res.apiv3({ appSettingsParams });
  243. });
  244. /**
  245. * @swagger
  246. *
  247. * /app-settings/app-setting:
  248. * put:
  249. * tags: [AppSettings]
  250. * summary: /app-settings/app-setting
  251. * operationId: updateAppSettings
  252. * description: Update app setting
  253. * requestBody:
  254. * required: true
  255. * content:
  256. * application/json:
  257. * schema:
  258. * $ref: '#/components/schemas/AppSettingParams'
  259. * responses:
  260. * 200:
  261. * description: Succeeded to update app setting
  262. * content:
  263. * application/json:
  264. * schema:
  265. * $ref: '#/components/schemas/AppSettingParams'
  266. */
  267. router.put('/app-setting', loginRequiredStrictly, adminRequired, csrf, validator.appSetting, apiV3FormValidator, async(req, res) => {
  268. const requestAppSettingParams = {
  269. 'app:title': req.body.title,
  270. 'app:confidential': req.body.confidential,
  271. 'app:globalLang': req.body.globalLang,
  272. 'app:fileUpload': req.body.fileUpload,
  273. };
  274. try {
  275. await crowi.configManager.updateConfigsInTheSameNamespace('crowi', requestAppSettingParams);
  276. const appSettingParams = {
  277. title: crowi.configManager.getConfig('crowi', 'app:title'),
  278. confidential: crowi.configManager.getConfig('crowi', 'app:confidential'),
  279. globalLang: crowi.configManager.getConfig('crowi', 'app:globalLang'),
  280. fileUpload: crowi.configManager.getConfig('crowi', 'app:fileUpload'),
  281. };
  282. return res.apiv3({ appSettingParams });
  283. }
  284. catch (err) {
  285. const msg = 'Error occurred in updating app setting';
  286. logger.error('Error', err);
  287. return res.apiv3Err(new ErrorV3(msg, 'update-appSetting-failed'));
  288. }
  289. });
  290. /**
  291. * @swagger
  292. *
  293. * /app-settings/site-url-setting:
  294. * put:
  295. * tags: [AppSettings]
  296. * operationId: updateAppSettingSiteUrlSetting
  297. * summary: /app-settings/site-url-setting
  298. * description: Update site url setting
  299. * requestBody:
  300. * required: true
  301. * content:
  302. * application/json:
  303. * schema:
  304. * $ref: '#/components/schemas/SiteUrlSettingParams'
  305. * responses:
  306. * 200:
  307. * description: Succeeded to update site url setting
  308. * content:
  309. * application/json:
  310. * schema:
  311. * $ref: '#/components/schemas/SiteUrlSettingParams'
  312. */
  313. router.put('/site-url-setting', loginRequiredStrictly, adminRequired, csrf, validator.siteUrlSetting, apiV3FormValidator, async(req, res) => {
  314. const requestSiteUrlSettingParams = {
  315. 'app:siteUrl': pathUtils.removeTrailingSlash(req.body.siteUrl),
  316. };
  317. try {
  318. await crowi.configManager.updateConfigsInTheSameNamespace('crowi', requestSiteUrlSettingParams);
  319. const siteUrlSettingParams = {
  320. siteUrl: crowi.configManager.getConfig('crowi', 'app:siteUrl'),
  321. };
  322. return res.apiv3({ siteUrlSettingParams });
  323. }
  324. catch (err) {
  325. const msg = 'Error occurred in updating site url setting';
  326. logger.error('Error', err);
  327. return res.apiv3Err(new ErrorV3(msg, 'update-siteUrlSetting-failed'));
  328. }
  329. });
  330. /**
  331. * send mail (Promise wrapper)
  332. */
  333. async function sendMailPromiseWrapper(smtpClient, options) {
  334. return new Promise((resolve, reject) => {
  335. smtpClient.sendMail(options, (err, res) => {
  336. if (err) {
  337. reject(err);
  338. }
  339. else {
  340. resolve(res);
  341. }
  342. });
  343. });
  344. }
  345. /**
  346. * validate mail setting send test mail
  347. */
  348. async function sendTestEmail(destinationAddress) {
  349. const { configManager, mailService } = crowi;
  350. if (!mailService.isMailerSetup) {
  351. throw Error('mailService is not setup');
  352. }
  353. const fromAddress = configManager.getConfig('crowi', 'mail:from');
  354. if (fromAddress == null) {
  355. throw Error('fromAddress is not setup');
  356. }
  357. const smtpHost = configManager.getConfig('crowi', 'mail:smtpHost');
  358. const smtpPort = configManager.getConfig('crowi', 'mail:smtpPort');
  359. const smtpUser = configManager.getConfig('crowi', 'mail:smtpUser');
  360. const smtpPassword = configManager.getConfig('crowi', 'mail:smtpPassword');
  361. const option = {
  362. host: smtpHost,
  363. port: smtpPort,
  364. };
  365. if (smtpUser && smtpPassword) {
  366. option.auth = {
  367. user: smtpUser,
  368. pass: smtpPassword,
  369. };
  370. }
  371. if (option.port === 465) {
  372. option.secure = true;
  373. }
  374. const smtpClient = mailService.createSMTPClient(option);
  375. debug('mailer setup for validate SMTP setting', smtpClient);
  376. const mailOptions = {
  377. from: fromAddress,
  378. to: destinationAddress,
  379. subject: 'Wiki管理設定のアップデートによるメール通知',
  380. text: 'このメールは、WikiのSMTP設定のアップデートにより送信されています。',
  381. };
  382. await sendMailPromiseWrapper(smtpClient, mailOptions);
  383. }
  384. const updateMailSettinConfig = async function(requestMailSettingParams) {
  385. const {
  386. configManager,
  387. mailService,
  388. } = crowi;
  389. // update config without publishing S2sMessage
  390. await configManager.updateConfigsInTheSameNamespace('crowi', requestMailSettingParams, true);
  391. await mailService.initialize();
  392. mailService.publishUpdatedMessage();
  393. return {
  394. isMailerSetup: mailService.isMailerSetup,
  395. fromAddress: configManager.getConfig('crowi', 'mail:from'),
  396. smtpHost: configManager.getConfig('crowi', 'mail:smtpHost'),
  397. smtpPort: configManager.getConfig('crowi', 'mail:smtpPort'),
  398. smtpUser: configManager.getConfig('crowi', 'mail:smtpUser'),
  399. smtpPassword: configManager.getConfig('crowi', 'mail:smtpPassword'),
  400. sesAccessKeyId: configManager.getConfig('crowi', 'mail:sesAccessKeyId'),
  401. sesSecretAccessKey: configManager.getConfig('crowi', 'mail:sesSecretAccessKey'),
  402. };
  403. };
  404. /**
  405. * @swagger
  406. *
  407. * /app-settings/smtp-setting:
  408. * put:
  409. * tags: [AppSettings]
  410. * operationId: updateAppSettingSmtpSetting
  411. * summary: /app-settings/smtp-setting
  412. * description: Update smtp setting
  413. * requestBody:
  414. * required: true
  415. * content:
  416. * application/json:
  417. * schema:
  418. * $ref: '#/components/schemas/SmtpSettingParams'
  419. * responses:
  420. * 200:
  421. * description: Succeeded to update smtp setting
  422. * content:
  423. * application/json:
  424. * schema:
  425. * $ref: '#/components/schemas/SmtpSettingParams'
  426. */
  427. router.put('/smtp-setting', loginRequiredStrictly, adminRequired, csrf, validator.smtpSetting, apiV3FormValidator, async(req, res) => {
  428. const requestMailSettingParams = {
  429. 'mail:from': req.body.fromAddress,
  430. 'mail:transmissionMethod': req.body.transmissionMethod,
  431. 'mail:smtpHost': req.body.smtpHost,
  432. 'mail:smtpPort': req.body.smtpPort,
  433. 'mail:smtpUser': req.body.smtpUser,
  434. 'mail:smtpPassword': req.body.smtpPassword,
  435. };
  436. try {
  437. const mailSettingParams = await updateMailSettinConfig(requestMailSettingParams);
  438. return res.apiv3({ mailSettingParams });
  439. }
  440. catch (err) {
  441. const msg = 'Error occurred in updating smtp setting';
  442. logger.error('Error', err);
  443. return res.apiv3Err(new ErrorV3(msg, 'update-smtpSetting-failed'));
  444. }
  445. });
  446. /**
  447. * @swagger
  448. *
  449. * /app-settings/smtp-test:
  450. * post:
  451. * tags: [AppSettings]
  452. * operationId: postSmtpTest
  453. * summary: /app-settings/smtp-setting
  454. * description: Send test mail for smtp
  455. * responses:
  456. * 200:
  457. * description: Succeeded to send test mail for smtp
  458. */
  459. router.post('/smtp-test', loginRequiredStrictly, adminRequired, async(req, res) => {
  460. try {
  461. await sendTestEmail(req.user.email);
  462. return res.apiv3({});
  463. }
  464. catch (err) {
  465. const msg = req.t('validation.failed_to_send_a_test_email');
  466. logger.error('Error', err);
  467. debug('Error validate mail setting: ', err);
  468. return res.apiv3Err(new ErrorV3(msg, 'send-email-with-smtp-failed'));
  469. }
  470. });
  471. /**
  472. * @swagger
  473. *
  474. * /app-settings/ses-setting:
  475. * put:
  476. * tags: [AppSettings]
  477. * operationId: updateAppSettingSesSetting
  478. * summary: /app-settings/ses-setting
  479. * description: Update ses setting
  480. * requestBody:
  481. * required: true
  482. * content:
  483. * application/json:
  484. * schema:
  485. * $ref: '#/components/schemas/SesSettingParams'
  486. * responses:
  487. * 200:
  488. * description: Succeeded to update ses setting
  489. * content:
  490. * application/json:
  491. * schema:
  492. * $ref: '#/components/schemas/SesSettingParams'
  493. */
  494. router.put('/ses-setting', loginRequiredStrictly, adminRequired, csrf, validator.sesSetting, apiV3FormValidator, async(req, res) => {
  495. const { mailService } = crowi;
  496. const requestSesSettingParams = {
  497. 'mail:from': req.body.fromAddress,
  498. 'mail:transmissionMethod': req.body.transmissionMethod,
  499. 'mail:sesAccessKeyId': req.body.sesAccessKeyId,
  500. 'mail:sesSecretAccessKey': req.body.sesSecretAccessKey,
  501. };
  502. let mailSettingParams;
  503. try {
  504. mailSettingParams = await updateMailSettinConfig(requestSesSettingParams);
  505. }
  506. catch (err) {
  507. const msg = 'Error occurred in updating ses setting';
  508. logger.error('Error', err);
  509. return res.apiv3Err(new ErrorV3(msg, 'update-ses-setting-failed'));
  510. }
  511. await mailService.initialize();
  512. mailService.publishUpdatedMessage();
  513. return res.apiv3({ mailSettingParams });
  514. });
  515. /**
  516. * @swagger
  517. *
  518. * /app-settings/file-upload-settings:
  519. * put:
  520. * tags: [AppSettings]
  521. * operationId: updateAppSettingFileUploadSetting
  522. * summary: /app-settings/file-upload-setting
  523. * description: Update fileUploadSetting
  524. * requestBody:
  525. * required: true
  526. * content:
  527. * application/json:
  528. * schema:
  529. * $ref: '#/components/schemas/FileUploadSettingParams'
  530. * responses:
  531. * 200:
  532. * description: Succeeded to update fileUploadSetting
  533. * content:
  534. * application/json:
  535. * schema:
  536. * $ref: '#/components/schemas/FileUploadSettingParams'
  537. */
  538. router.put('/file-upload-setting', loginRequiredStrictly, adminRequired, csrf, validator.fileUploadSetting, apiV3FormValidator, async(req, res) => {
  539. const { fileUploadType } = req.body;
  540. const requestParams = {
  541. 'app:fileUploadType': fileUploadType,
  542. };
  543. if (fileUploadType === 'gcs') {
  544. requestParams['gcs:apiKeyJsonPath'] = req.body.gcsApiKeyJsonPath;
  545. requestParams['gcs:bucket'] = req.body.gcsBucket;
  546. requestParams['gcs:uploadNamespace'] = req.body.gcsUploadNamespace;
  547. requestParams['gcs:referenceFileWithRelayMode'] = req.body.gcsReferenceFileWithRelayMode;
  548. }
  549. if (fileUploadType === 'aws') {
  550. requestParams['aws:s3Region'] = req.body.s3Region;
  551. requestParams['aws:s3CustomEndpoint'] = req.body.s3CustomEndpoint;
  552. requestParams['aws:s3Bucket'] = req.body.s3Bucket;
  553. requestParams['aws:s3AccessKeyId'] = req.body.s3AccessKeyId;
  554. requestParams['aws:s3SecretAccessKey'] = req.body.s3SecretAccessKey;
  555. requestParams['aws:referenceFileWithRelayMode'] = req.body.s3ReferenceFileWithRelayMode;
  556. }
  557. try {
  558. await crowi.configManager.updateConfigsInTheSameNamespace('crowi', requestParams, true);
  559. await crowi.setUpFileUpload(true);
  560. crowi.fileUploaderSwitchService.publishUpdatedMessage();
  561. const responseParams = {
  562. fileUploadType: crowi.configManager.getConfig('crowi', 'app:fileUploadType'),
  563. };
  564. if (fileUploadType === 'gcs') {
  565. responseParams.gcsApiKeyJsonPath = crowi.configManager.getConfig('crowi', 'gcs:apiKeyJsonPath');
  566. responseParams.gcsBucket = crowi.configManager.getConfig('crowi', 'gcs:bucket');
  567. responseParams.gcsUploadNamespace = crowi.configManager.getConfig('crowi', 'gcs:uploadNamespace');
  568. responseParams.gcsReferenceFileWithRelayMode = crowi.configManager.getConfig('crowi', 'gcs:referenceFileWithRelayMode ');
  569. }
  570. if (fileUploadType === 'aws') {
  571. responseParams.s3Region = crowi.configManager.getConfig('crowi', 'aws:s3Region');
  572. responseParams.s3CustomEndpoint = crowi.configManager.getConfig('crowi', 'aws:s3CustomEndpoint');
  573. responseParams.s3Bucket = crowi.configManager.getConfig('crowi', 'aws:s3Bucket');
  574. responseParams.s3AccessKeyId = crowi.configManager.getConfig('crowi', 'aws:s3AccessKeyId');
  575. responseParams.s3SecretAccessKey = crowi.configManager.getConfig('crowi', 'aws:s3SecretAccessKey');
  576. responseParams.s3ReferenceFileWithRelayMode = crowi.configManager.getConfig('crowi', 'aws:referenceFileWithRelayMode');
  577. }
  578. return res.apiv3({ responseParams });
  579. }
  580. catch (err) {
  581. const msg = 'Error occurred in updating fileUploadType';
  582. logger.error('Error', err);
  583. return res.apiv3Err(new ErrorV3(msg, 'update-fileUploadType-failed'));
  584. }
  585. });
  586. /**
  587. * @swagger
  588. *
  589. * /app-settings/plugin-setting:
  590. * put:
  591. * tags: [AppSettings]
  592. * operationId: updateAppSettingPluginSetting
  593. * summary: /app-settings/plugin-setting
  594. * description: Update plugin setting
  595. * requestBody:
  596. * required: true
  597. * content:
  598. * application/json:
  599. * schema:
  600. * $ref: '#/components/schemas/PluginSettingParams'
  601. * responses:
  602. * 200:
  603. * description: Succeeded to update plugin setting
  604. * content:
  605. * application/json:
  606. * schema:
  607. * $ref: '#/components/schemas/PluginSettingParams'
  608. */
  609. router.put('/plugin-setting', loginRequiredStrictly, adminRequired, csrf, validator.pluginSetting, apiV3FormValidator, async(req, res) => {
  610. const requestPluginSettingParams = {
  611. 'plugin:isEnabledPlugins': req.body.isEnabledPlugins,
  612. };
  613. try {
  614. await crowi.configManager.updateConfigsInTheSameNamespace('crowi', requestPluginSettingParams);
  615. const pluginSettingParams = {
  616. isEnabledPlugins: crowi.configManager.getConfig('crowi', 'plugin:isEnabledPlugins'),
  617. };
  618. return res.apiv3({ pluginSettingParams });
  619. }
  620. catch (err) {
  621. const msg = 'Error occurred in updating plugin setting';
  622. logger.error('Error', err);
  623. return res.apiv3Err(new ErrorV3(msg, 'update-pluginSetting-failed'));
  624. }
  625. });
  626. return router;
  627. };