customize-setting.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664
  1. /* eslint-disable no-unused-vars */
  2. import { SupportedAction } from '~/interfaces/activity';
  3. import loggerFactory from '~/utils/logger';
  4. import { generateAddActivityMiddleware } from '../../middlewares/add-activity';
  5. import { apiV3FormValidator } from '../../middlewares/apiv3-form-validator';
  6. const logger = loggerFactory('growi:routes:apiv3:customize-setting');
  7. const express = require('express');
  8. const router = express.Router();
  9. const { body, query } = require('express-validator');
  10. const ErrorV3 = require('../../models/vo/error-apiv3');
  11. /**
  12. * @swagger
  13. * tags:
  14. * name: CustomizeSetting
  15. */
  16. /**
  17. * @swagger
  18. *
  19. * components:
  20. * schemas:
  21. * CustomizeLayout:
  22. * description: CustomizeLayout
  23. * type: object
  24. * properties:
  25. * isContainerFluid:
  26. * type: boolean
  27. * CustomizeTheme:
  28. * description: CustomizeTheme
  29. * type: object
  30. * properties:
  31. * themeType:
  32. * type: string
  33. * CustomizeFunction:
  34. * description: CustomizeFunction
  35. * type: object
  36. * properties:
  37. * isEnabledTimeline:
  38. * type: boolean
  39. * isSavedStatesOfTabChanges:
  40. * type: boolean
  41. * isEnabledAttachTitleHeader:
  42. * type: boolean
  43. * pageLimitationS:
  44. * type: number
  45. * pageLimitationM:
  46. * type: number
  47. * isEnabledStaleNotification:
  48. * type: boolean
  49. * isAllReplyShown:
  50. * type: boolean
  51. * isSearchScopeChildrenAsDefault:
  52. * type: boolean
  53. * CustomizeHighlight:
  54. * description: CustomizeHighlight
  55. * type: object
  56. * properties:
  57. * styleName:
  58. * type: string
  59. * styleBorder:
  60. * type: boolean
  61. * CustomizeTitle:
  62. * description: CustomizeTitle
  63. * type: object
  64. * properties:
  65. * customizeTitle:
  66. * type: string
  67. * CustomizeHeader:
  68. * description: CustomizeHeader
  69. * type: object
  70. * properties:
  71. * customizeHeader:
  72. * type: string
  73. * CustomizeCss:
  74. * description: CustomizeCss
  75. * type: object
  76. * properties:
  77. * customizeCss:
  78. * type: string
  79. * CustomizeScript:
  80. * description: CustomizeScript
  81. * type: object
  82. * properties:
  83. * customizeScript:
  84. * type: string
  85. */
  86. module.exports = (crowi) => {
  87. const loginRequiredStrictly = require('../../middlewares/login-required')(crowi);
  88. const adminRequired = require('../../middlewares/admin-required')(crowi);
  89. const csrf = require('../../middlewares/csrf')(crowi);
  90. const addActivity = generateAddActivityMiddleware(crowi);
  91. const activityEvent = crowi.event('activity');
  92. const { customizeService } = crowi;
  93. const validator = {
  94. layout: [
  95. body('isContainerFluid').isBoolean(),
  96. ],
  97. themeAssetPath: [
  98. query('themeName').isString(),
  99. ],
  100. theme: [
  101. body('themeType').isString(),
  102. ],
  103. sidebar: [
  104. body('isSidebarDrawerMode').isBoolean(),
  105. body('isSidebarClosedAtDockMode').isBoolean(),
  106. ],
  107. function: [
  108. body('isEnabledTimeline').isBoolean(),
  109. body('isSavedStatesOfTabChanges').isBoolean(),
  110. body('isEnabledAttachTitleHeader').isBoolean(),
  111. body('pageLimitationS').isInt().isInt({ min: 1, max: 1000 }),
  112. body('pageLimitationM').isInt().isInt({ min: 1, max: 1000 }),
  113. body('pageLimitationL').isInt().isInt({ min: 1, max: 1000 }),
  114. body('pageLimitationXL').isInt().isInt({ min: 1, max: 1000 }),
  115. body('isEnabledStaleNotification').isBoolean(),
  116. body('isAllReplyShown').isBoolean(),
  117. body('isSearchScopeChildrenAsDefault').isBoolean(),
  118. ],
  119. customizeTitle: [
  120. body('customizeTitle').isString(),
  121. ],
  122. customizeHeader: [
  123. body('customizeHeader').isString(),
  124. ],
  125. highlight: [
  126. body('highlightJsStyle').isString().isIn([
  127. 'github', 'github-gist', 'atom-one-light', 'xcode', 'vs', 'atom-one-dark', 'hybrid', 'monokai', 'tomorrow-night', 'vs2015',
  128. ]),
  129. body('highlightJsStyleBorder').isBoolean(),
  130. ],
  131. customizeCss: [
  132. body('customizeCss').isString(),
  133. ],
  134. customizeScript: [
  135. body('customizeScript').isString(),
  136. ],
  137. };
  138. /**
  139. * @swagger
  140. *
  141. * /customize-setting:
  142. * get:
  143. * tags: [CustomizeSetting]
  144. * operationId: getCustomizeSetting
  145. * summary: /customize-setting
  146. * description: Get customize parameters
  147. * responses:
  148. * 200:
  149. * description: params of customize
  150. * content:
  151. * application/json:
  152. * schema:
  153. * properties:
  154. * customizeParams:
  155. * type: object
  156. * description: customize params
  157. */
  158. router.get('/', loginRequiredStrictly, adminRequired, async(req, res) => {
  159. const customizeParams = {
  160. themeType: await crowi.configManager.getConfig('crowi', 'customize:theme'),
  161. isEnabledTimeline: await crowi.configManager.getConfig('crowi', 'customize:isEnabledTimeline'),
  162. isSavedStatesOfTabChanges: await crowi.configManager.getConfig('crowi', 'customize:isSavedStatesOfTabChanges'),
  163. isEnabledAttachTitleHeader: await crowi.configManager.getConfig('crowi', 'customize:isEnabledAttachTitleHeader'),
  164. pageLimitationS: await crowi.configManager.getConfig('crowi', 'customize:showPageLimitationS'),
  165. pageLimitationM: await crowi.configManager.getConfig('crowi', 'customize:showPageLimitationM'),
  166. pageLimitationL: await crowi.configManager.getConfig('crowi', 'customize:showPageLimitationL'),
  167. pageLimitationXL: await crowi.configManager.getConfig('crowi', 'customize:showPageLimitationXL'),
  168. isEnabledStaleNotification: await crowi.configManager.getConfig('crowi', 'customize:isEnabledStaleNotification'),
  169. isAllReplyShown: await crowi.configManager.getConfig('crowi', 'customize:isAllReplyShown'),
  170. isSearchScopeChildrenAsDefault: await crowi.configManager.getConfig('crowi', 'customize:isSearchScopeChildrenAsDefault'),
  171. styleName: await crowi.configManager.getConfig('crowi', 'customize:highlightJsStyle'),
  172. styleBorder: await crowi.configManager.getConfig('crowi', 'customize:highlightJsStyleBorder'),
  173. customizeTitle: await crowi.configManager.getConfig('crowi', 'customize:title'),
  174. customizeHeader: await crowi.configManager.getConfig('crowi', 'customize:header'),
  175. customizeCss: await crowi.configManager.getConfig('crowi', 'customize:css'),
  176. customizeScript: await crowi.configManager.getConfig('crowi', 'customize:script'),
  177. };
  178. return res.apiv3({ customizeParams });
  179. });
  180. /**
  181. * @swagger
  182. *
  183. * /customize-setting/layout:
  184. * get:
  185. * tags: [CustomizeSetting]
  186. * operationId: getLayoutCustomizeSetting
  187. * summary: /customize-setting/layout
  188. * description: Get layout
  189. * responses:
  190. * 200:
  191. * description: Succeeded to get layout
  192. * content:
  193. * application/json:
  194. * schema:
  195. * $ref: '#/components/schemas/CustomizeLayout'
  196. */
  197. router.get('/layout', loginRequiredStrictly, adminRequired, async(req, res) => {
  198. try {
  199. const isContainerFluid = await crowi.configManager.getConfig('crowi', 'customize:isContainerFluid');
  200. return res.apiv3({ isContainerFluid });
  201. }
  202. catch (err) {
  203. const msg = 'Error occurred in getting layout';
  204. logger.error('Error', err);
  205. return res.apiv3Err(new ErrorV3(msg, 'get-layout-failed'));
  206. }
  207. });
  208. /**
  209. * @swagger
  210. *
  211. * /customize-setting/layout:
  212. * put:
  213. * tags: [CustomizeSetting]
  214. * operationId: updateLayoutCustomizeSetting
  215. * summary: /customize-setting/layout
  216. * description: Update layout
  217. * requestBody:
  218. * required: true
  219. * content:
  220. * application/json:
  221. * schema:
  222. * $ref: '#/components/schemas/CustomizeLayout'
  223. * responses:
  224. * 200:
  225. * description: Succeeded to update layout
  226. * content:
  227. * application/json:
  228. * schema:
  229. * $ref: '#/components/schemas/CustomizeLayout'
  230. */
  231. router.put('/layout', loginRequiredStrictly, adminRequired, csrf, addActivity, validator.layout, apiV3FormValidator, async(req, res) => {
  232. const requestParams = {
  233. 'customize:isContainerFluid': req.body.isContainerFluid,
  234. };
  235. try {
  236. await crowi.configManager.updateConfigsInTheSameNamespace('crowi', requestParams);
  237. const customizedParams = {
  238. isContainerFluid: await crowi.configManager.getConfig('crowi', 'customize:isContainerFluid'),
  239. };
  240. const parameters = { action: SupportedAction.ACTION_ADMIN_LAYOUT_UPDATE };
  241. activityEvent.emit('update', res.locals.activity._id, parameters);
  242. return res.apiv3({ customizedParams });
  243. }
  244. catch (err) {
  245. const msg = 'Error occurred in updating layout';
  246. logger.error('Error', err);
  247. return res.apiv3Err(new ErrorV3(msg, 'update-layout-failed'));
  248. }
  249. });
  250. /**
  251. * @swagger
  252. *
  253. * /customize-setting/theme/asset-path:
  254. * put:
  255. * tags: [CustomizeSetting]
  256. * operationId: getThemeAssetPath
  257. * summary: /customize-setting/theme/asset-path
  258. * description: Get theme asset path
  259. * parameters:
  260. * - name: themeName
  261. * in: query
  262. * required: true
  263. * schema:
  264. * type: string
  265. * responses:
  266. * 200:
  267. * description: Succeeded to get theme asset path
  268. * content:
  269. * application/json:
  270. * schema:
  271. * properties:
  272. * assetPath:
  273. * type: string
  274. */
  275. router.get('/theme/asset-path', loginRequiredStrictly, adminRequired, validator.themeAssetPath, apiV3FormValidator, async(req, res) => {
  276. const { themeName } = req.query;
  277. const webpackAssetKey = `styles/theme-${themeName}.css`;
  278. const assetPath = res.locals.webpack_asset(webpackAssetKey);
  279. if (assetPath == null) {
  280. return res.apiv3Err(new ErrorV3(`The asset for '${webpackAssetKey}' is undefined.`, 'invalid-asset'));
  281. }
  282. return res.apiv3({ assetPath });
  283. });
  284. /**
  285. * @swagger
  286. *
  287. * /customize-setting/theme:
  288. * put:
  289. * tags: [CustomizeSetting]
  290. * operationId: updateThemeCustomizeSetting
  291. * summary: /customize-setting/theme
  292. * description: Update theme
  293. * requestBody:
  294. * required: true
  295. * content:
  296. * application/json:
  297. * schema:
  298. * $ref: '#/components/schemas/CustomizeTheme'
  299. * responses:
  300. * 200:
  301. * description: Succeeded to update theme
  302. * content:
  303. * application/json:
  304. * schema:
  305. * $ref: '#/components/schemas/CustomizeTheme'
  306. */
  307. router.put('/theme', loginRequiredStrictly, adminRequired, csrf, validator.theme, apiV3FormValidator, async(req, res) => {
  308. const requestParams = {
  309. 'customize:theme': req.body.themeType,
  310. };
  311. try {
  312. await crowi.configManager.updateConfigsInTheSameNamespace('crowi', requestParams);
  313. const customizedParams = {
  314. themeType: await crowi.configManager.getConfig('crowi', 'customize:theme'),
  315. };
  316. return res.apiv3({ customizedParams });
  317. }
  318. catch (err) {
  319. const msg = 'Error occurred in updating theme';
  320. logger.error('Error', err);
  321. return res.apiv3Err(new ErrorV3(msg, 'update-theme-failed'));
  322. }
  323. });
  324. // sidebar
  325. router.get('/sidebar', loginRequiredStrictly, adminRequired, async(req, res) => {
  326. try {
  327. const isSidebarDrawerMode = await crowi.configManager.getConfig('crowi', 'customize:isSidebarDrawerMode');
  328. const isSidebarClosedAtDockMode = await crowi.configManager.getConfig('crowi', 'customize:isSidebarClosedAtDockMode');
  329. return res.apiv3({ isSidebarDrawerMode, isSidebarClosedAtDockMode });
  330. }
  331. catch (err) {
  332. const msg = 'Error occurred in getting sidebar';
  333. logger.error('Error', err);
  334. return res.apiv3Err(new ErrorV3(msg, 'get-sidebar-failed'));
  335. }
  336. });
  337. router.put('/sidebar', loginRequiredStrictly, adminRequired, csrf, validator.sidebar, apiV3FormValidator, async(req, res) => {
  338. const requestParams = {
  339. 'customize:isSidebarDrawerMode': req.body.isSidebarDrawerMode,
  340. 'customize:isSidebarClosedAtDockMode': req.body.isSidebarClosedAtDockMode,
  341. };
  342. try {
  343. await crowi.configManager.updateConfigsInTheSameNamespace('crowi', requestParams);
  344. const customizedParams = {
  345. isSidebarDrawerMode: await crowi.configManager.getConfig('crowi', 'customize:isSidebarDrawerMode'),
  346. isSidebarClosedAtDockMode: await crowi.configManager.getConfig('crowi', 'customize:isSidebarClosedAtDockMode'),
  347. };
  348. return res.apiv3({ customizedParams });
  349. }
  350. catch (err) {
  351. const msg = 'Error occurred in updating sidebar';
  352. logger.error('Error', err);
  353. return res.apiv3Err(new ErrorV3(msg, 'update-sidebar-failed'));
  354. }
  355. });
  356. /**
  357. * @swagger
  358. *
  359. * /customize-setting/function:
  360. * put:
  361. * tags: [CustomizeSetting]
  362. * operationId: updateFunctionCustomizeSetting
  363. * summary: /customize-setting/function
  364. * description: Update function
  365. * requestBody:
  366. * required: true
  367. * content:
  368. * application/json:
  369. * schema:
  370. * $ref: '#/components/schemas/CustomizeFunction'
  371. * responses:
  372. * 200:
  373. * description: Succeeded to update function
  374. * content:
  375. * application/json:
  376. * schema:
  377. * $ref: '#/components/schemas/CustomizeFunction'
  378. */
  379. router.put('/function', loginRequiredStrictly, adminRequired, csrf, validator.function, apiV3FormValidator, async(req, res) => {
  380. const requestParams = {
  381. 'customize:isEnabledTimeline': req.body.isEnabledTimeline,
  382. 'customize:isSavedStatesOfTabChanges': req.body.isSavedStatesOfTabChanges,
  383. 'customize:isEnabledAttachTitleHeader': req.body.isEnabledAttachTitleHeader,
  384. 'customize:showPageLimitationS': req.body.pageLimitationS,
  385. 'customize:showPageLimitationM': req.body.pageLimitationM,
  386. 'customize:showPageLimitationL': req.body.pageLimitationL,
  387. 'customize:showPageLimitationXL': req.body.pageLimitationXL,
  388. 'customize:isEnabledStaleNotification': req.body.isEnabledStaleNotification,
  389. 'customize:isAllReplyShown': req.body.isAllReplyShown,
  390. 'customize:isSearchScopeChildrenAsDefault': req.body.isSearchScopeChildrenAsDefault,
  391. };
  392. try {
  393. await crowi.configManager.updateConfigsInTheSameNamespace('crowi', requestParams);
  394. const customizedParams = {
  395. isEnabledTimeline: await crowi.configManager.getConfig('crowi', 'customize:isEnabledTimeline'),
  396. isSavedStatesOfTabChanges: await crowi.configManager.getConfig('crowi', 'customize:isSavedStatesOfTabChanges'),
  397. isEnabledAttachTitleHeader: await crowi.configManager.getConfig('crowi', 'customize:isEnabledAttachTitleHeader'),
  398. pageLimitationS: await crowi.configManager.getConfig('crowi', 'customize:showPageLimitationS'),
  399. pageLimitationM: await crowi.configManager.getConfig('crowi', 'customize:showPageLimitationM'),
  400. pageLimitationL: await crowi.configManager.getConfig('crowi', 'customize:showPageLimitationL'),
  401. pageLimitationXL: await crowi.configManager.getConfig('crowi', 'customize:showPageLimitationXL'),
  402. isEnabledStaleNotification: await crowi.configManager.getConfig('crowi', 'customize:isEnabledStaleNotification'),
  403. isAllReplyShown: await crowi.configManager.getConfig('crowi', 'customize:isAllReplyShown'),
  404. isSearchScopeChildrenAsDefault: await crowi.configManager.getConfig('crowi', 'customize:isSearchScopeChildrenAsDefault'),
  405. };
  406. return res.apiv3({ customizedParams });
  407. }
  408. catch (err) {
  409. const msg = 'Error occurred in updating function';
  410. logger.error('Error', err);
  411. return res.apiv3Err(new ErrorV3(msg, 'update-function-failed'));
  412. }
  413. });
  414. /**
  415. * @swagger
  416. *
  417. * /customize-setting/highlight:
  418. * put:
  419. * tags: [CustomizeSetting]
  420. * operationId: updateHighlightCustomizeSetting
  421. * summary: /customize-setting/highlight
  422. * description: Update highlight
  423. * requestBody:
  424. * required: true
  425. * content:
  426. * application/json:
  427. * schema:
  428. * $ref: '#/components/schemas/CustomizeHighlight'
  429. * responses:
  430. * 200:
  431. * description: Succeeded to update highlight
  432. * content:
  433. * application/json:
  434. * schema:
  435. * $ref: '#/components/schemas/CustomizeHighlight'
  436. */
  437. router.put('/highlight', loginRequiredStrictly, adminRequired, csrf, validator.highlight, apiV3FormValidator, async(req, res) => {
  438. const requestParams = {
  439. 'customize:highlightJsStyle': req.body.highlightJsStyle,
  440. 'customize:highlightJsStyleBorder': req.body.highlightJsStyleBorder,
  441. };
  442. try {
  443. await crowi.configManager.updateConfigsInTheSameNamespace('crowi', requestParams);
  444. const customizedParams = {
  445. styleName: await crowi.configManager.getConfig('crowi', 'customize:highlightJsStyle'),
  446. styleBorder: await crowi.configManager.getConfig('crowi', 'customize:highlightJsStyleBorder'),
  447. };
  448. return res.apiv3({ customizedParams });
  449. }
  450. catch (err) {
  451. const msg = 'Error occurred in updating highlight';
  452. logger.error('Error', err);
  453. return res.apiv3Err(new ErrorV3(msg, 'update-highlight-failed'));
  454. }
  455. });
  456. /**
  457. * @swagger
  458. *
  459. * /customize-setting/customizeTitle:
  460. * put:
  461. * tags: [CustomizeSetting]
  462. * operationId: updateCustomizeTitleCustomizeSetting
  463. * summary: /customize-setting/customizeTitle
  464. * description: Update customizeTitle
  465. * requestBody:
  466. * required: true
  467. * content:
  468. * application/json:
  469. * schema:
  470. * $ref: '#/components/schemas/CustomizeTitle'
  471. * responses:
  472. * 200:
  473. * description: Succeeded to update customizeTitle
  474. * content:
  475. * application/json:
  476. * schema:
  477. * $ref: '#/components/schemas/CustomizeTitle'
  478. */
  479. router.put('/customize-title', loginRequiredStrictly, adminRequired, csrf, validator.customizeTitle, apiV3FormValidator, async(req, res) => {
  480. const requestParams = {
  481. 'customize:title': req.body.customizeTitle,
  482. };
  483. try {
  484. await crowi.configManager.updateConfigsInTheSameNamespace('crowi', requestParams, true);
  485. crowi.customizeService.publishUpdatedMessage();
  486. const customizedParams = {
  487. customizeTitle: await crowi.configManager.getConfig('crowi', 'customize:title'),
  488. };
  489. customizeService.initCustomTitle();
  490. return res.apiv3({ customizedParams });
  491. }
  492. catch (err) {
  493. const msg = 'Error occurred in updating customizeTitle';
  494. logger.error('Error', err);
  495. return res.apiv3Err(new ErrorV3(msg, 'update-customizeTitle-failed'));
  496. }
  497. });
  498. /**
  499. * @swagger
  500. *
  501. * /customize-setting/customizeHeader:
  502. * put:
  503. * tags: [CustomizeSetting]
  504. * operationId: updateCustomizeHeaderCustomizeSetting
  505. * summary: /customize-setting/customizeHeader
  506. * description: Update customizeHeader
  507. * requestBody:
  508. * required: true
  509. * content:
  510. * application/json:
  511. * schema:
  512. * $ref: '#/components/schemas/CustomizeHeader'
  513. * responses:
  514. * 200:
  515. * description: Succeeded to update customize header
  516. * content:
  517. * application/json:
  518. * schema:
  519. * $ref: '#/components/schemas/CustomizeHeader'
  520. */
  521. router.put('/customize-header', loginRequiredStrictly, adminRequired, csrf, validator.customizeHeader, apiV3FormValidator, async(req, res) => {
  522. const requestParams = {
  523. 'customize:header': req.body.customizeHeader,
  524. };
  525. try {
  526. await crowi.configManager.updateConfigsInTheSameNamespace('crowi', requestParams);
  527. const customizedParams = {
  528. customizeHeader: await crowi.configManager.getConfig('crowi', 'customize:header'),
  529. };
  530. return res.apiv3({ customizedParams });
  531. }
  532. catch (err) {
  533. const msg = 'Error occurred in updating customizeHeader';
  534. logger.error('Error', err);
  535. return res.apiv3Err(new ErrorV3(msg, 'update-customizeHeader-failed'));
  536. }
  537. });
  538. /**
  539. * @swagger
  540. *
  541. * /customize-setting/customizeCss:
  542. * put:
  543. * tags: [CustomizeSetting]
  544. * operationId: updateCustomizeCssCustomizeSetting
  545. * summary: /customize-setting/customizeCss
  546. * description: Update customizeCss
  547. * requestBody:
  548. * required: true
  549. * content:
  550. * application/json:
  551. * schema:
  552. * $ref: '#/components/schemas/CustomizeCss'
  553. * responses:
  554. * 200:
  555. * description: Succeeded to update customize css
  556. * content:
  557. * application/json:
  558. * schema:
  559. * $ref: '#/components/schemas/CustomizeCss'
  560. */
  561. router.put('/customize-css', loginRequiredStrictly, adminRequired, csrf, validator.customizeCss, apiV3FormValidator, async(req, res) => {
  562. const requestParams = {
  563. 'customize:css': req.body.customizeCss,
  564. };
  565. try {
  566. await crowi.configManager.updateConfigsInTheSameNamespace('crowi', requestParams, true);
  567. crowi.customizeService.publishUpdatedMessage();
  568. const customizedParams = {
  569. customizeCss: await crowi.configManager.getConfig('crowi', 'customize:css'),
  570. };
  571. customizeService.initCustomCss();
  572. return res.apiv3({ customizedParams });
  573. }
  574. catch (err) {
  575. const msg = 'Error occurred in updating customizeCss';
  576. logger.error('Error', err);
  577. return res.apiv3Err(new ErrorV3(msg, 'update-customizeCss-failed'));
  578. }
  579. });
  580. /**
  581. * @swagger
  582. *
  583. * /customize-setting/customizeScript:
  584. * put:
  585. * tags: [CustomizeSetting]
  586. * operationId: updateCustomizeScriptCustomizeSetting
  587. * summary: /customize-setting/customizeScript
  588. * description: Update customizeScript
  589. * requestBody:
  590. * required: true
  591. * content:
  592. * application/json:
  593. * schema:
  594. * $ref: '#/components/schemas/CustomizeScript'
  595. * responses:
  596. * 200:
  597. * description: Succeeded to update customize script
  598. * content:
  599. * application/json:
  600. * schema:
  601. * $ref: '#/components/schemas/CustomizeScript'
  602. */
  603. router.put('/customize-script', loginRequiredStrictly, adminRequired, csrf, validator.customizeScript, apiV3FormValidator, async(req, res) => {
  604. const requestParams = {
  605. 'customize:script': req.body.customizeScript,
  606. };
  607. try {
  608. await crowi.configManager.updateConfigsInTheSameNamespace('crowi', requestParams);
  609. const customizedParams = {
  610. customizeScript: await crowi.configManager.getConfig('crowi', 'customize:script'),
  611. };
  612. return res.apiv3({ customizedParams });
  613. }
  614. catch (err) {
  615. const msg = 'Error occurred in updating customizeScript';
  616. logger.error('Error', err);
  617. return res.apiv3Err(new ErrorV3(msg, 'update-customizeScript-failed'));
  618. }
  619. });
  620. return router;
  621. };