customize-setting.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. /* eslint-disable no-unused-vars */
  2. const loggerFactory = require('@alias/logger');
  3. const logger = loggerFactory('growi:routes:apiv3:customize-setting');
  4. const express = require('express');
  5. const router = express.Router();
  6. const { body } = require('express-validator/check');
  7. const ErrorV3 = require('../../models/vo/error-apiv3');
  8. /**
  9. * @swagger
  10. * tags:
  11. * name: CustomizeSetting
  12. */
  13. /**
  14. * @swagger
  15. *
  16. * components:
  17. * schemas:
  18. * CustomizeLayoutTheme:
  19. * type: object
  20. * properties:
  21. * layoutType:
  22. * type: string
  23. * themeType:
  24. * type: string
  25. * CustomizeBehavior:
  26. * type: object
  27. * properties:
  28. * behaviorType:
  29. * type: string
  30. * CustomizeFunction:
  31. * type: object
  32. * properties:
  33. * isEnabledTimeline:
  34. * type: boolean
  35. * isSavedStatesOfTabChanges:
  36. * type: boolean
  37. * isEnabledAttachTitleHeader:
  38. * type: boolean
  39. * recentCreatedLimit:
  40. * type: number
  41. * CustomizeHighlight:
  42. * type: object
  43. * properties:
  44. * styleName:
  45. * type: string
  46. * styleBorder:
  47. * type: boolean
  48. * CustomizeTitle:
  49. * type: object
  50. * properties:
  51. * customizeTitle:
  52. * type: string
  53. * CustomizeHeader:
  54. * type: object
  55. * properties:
  56. * customizeHeader:
  57. * type: string
  58. * CustomizeCss:
  59. * type: object
  60. * properties:
  61. * customizeCss:
  62. * type: string
  63. * CustomizeScript:
  64. * type: object
  65. * properties:
  66. * customizeScript:
  67. * type: string
  68. */
  69. module.exports = (crowi) => {
  70. const loginRequiredStrictly = require('../../middleware/login-required')(crowi);
  71. const adminRequired = require('../../middleware/admin-required')(crowi);
  72. const csrf = require('../../middleware/csrf')(crowi);
  73. const { customizeService } = crowi;
  74. const { ApiV3FormValidator } = crowi.middlewares;
  75. const validator = {
  76. layoutTheme: [
  77. body('layoutType').isString().isIn(['growi', 'kibela', 'crowi']),
  78. body('themeType').isString().isIn([
  79. 'default', 'nature', 'mono-blue', 'wood', 'island', 'christmas', 'antarctic', 'default-dark', 'future', 'blue-night', 'halloween',
  80. ]),
  81. ],
  82. behavior: [
  83. body('behaviorType').isString().isIn(['growi', 'crowi-plus']),
  84. ],
  85. function: [
  86. body('isEnabledTimeline').isBoolean(),
  87. body('isSavedStatesOfTabChanges').isBoolean(),
  88. body('isEnabledAttachTitleHeader').isBoolean(),
  89. body('recentCreatedLimit').isInt().isInt({ min: 1, max: 1000 }),
  90. ],
  91. customizeTitle: [
  92. body('customizeTitle').isString(),
  93. ],
  94. customizeHeader: [
  95. body('customizeHeader').isString(),
  96. ],
  97. highlight: [
  98. body('highlightJsStyle').isString().isIn([
  99. 'github', 'github-gist', 'atom-one-light', 'xcode', 'vs', 'atom-one-dark', 'hybrid', 'monokai', 'tororrow-night', 'vs2015',
  100. ]),
  101. body('highlightJsStyleBorder').isBoolean(),
  102. ],
  103. customizeCss: [
  104. body('customizeCss').isString(),
  105. ],
  106. customizeScript: [
  107. body('customizeScript').isString(),
  108. ],
  109. };
  110. /**
  111. * @swagger
  112. *
  113. * /customize-setting/:
  114. * get:
  115. * tags: [CustomizeSetting]
  116. * description: Get customize paramators
  117. * responses:
  118. * 200:
  119. * description: params of customize
  120. * content:
  121. * application/json:
  122. * schema:
  123. * properties:
  124. * customizeParams:
  125. * type: object
  126. * description: customize params
  127. */
  128. router.get('/', loginRequiredStrictly, adminRequired, async(req, res) => {
  129. const customizeParams = {
  130. layoutType: await crowi.configManager.getConfig('crowi', 'customize:layout'),
  131. themeType: await crowi.configManager.getConfig('crowi', 'customize:theme'),
  132. behaviorType: await crowi.configManager.getConfig('crowi', 'customize:behavior'),
  133. isEnabledTimeline: await crowi.configManager.getConfig('crowi', 'customize:isEnabledTimeline'),
  134. isSavedStatesOfTabChanges: await crowi.configManager.getConfig('crowi', 'customize:isSavedStatesOfTabChanges'),
  135. isEnabledAttachTitleHeader: await crowi.configManager.getConfig('crowi', 'customize:isEnabledAttachTitleHeader'),
  136. recentCreatedLimit: await crowi.configManager.getConfig('crowi', 'customize:showRecentCreatedNumber'),
  137. styleName: await crowi.configManager.getConfig('crowi', 'customize:highlightJsStyle'),
  138. styleBorder: await crowi.configManager.getConfig('crowi', 'customize:highlightJsStyleBorder'),
  139. customizeTitle: await crowi.configManager.getConfig('crowi', 'customize:title'),
  140. customizeHeader: await crowi.configManager.getConfig('crowi', 'customize:header'),
  141. customizeCss: await crowi.configManager.getConfig('crowi', 'customize:header'),
  142. customizeScript: await crowi.configManager.getConfig('crowi', 'customize:script'),
  143. };
  144. return res.apiv3({ customizeParams });
  145. });
  146. /**
  147. * @swagger
  148. *
  149. * /customize-setting/layoutTheme:
  150. * put:
  151. * tags: [CustomizeSetting]
  152. * description: Update layout and theme
  153. * requestBody:
  154. * required: true
  155. * content:
  156. * application/json:
  157. * schama:
  158. * $ref: '#/components/schemas/CustomizeLayoutTheme'
  159. * responses:
  160. * 200:
  161. * description: Succeeded to update layout and theme
  162. * content:
  163. * application/json:
  164. * schema:
  165. * $ref: '#/components/schemas/CustomizeLayoutTheme'
  166. */
  167. router.put('/layoutTheme', loginRequiredStrictly, adminRequired, csrf, validator.layoutTheme, ApiV3FormValidator, async(req, res) => {
  168. const requestParams = {
  169. 'customize:layout': req.body.layoutType,
  170. 'customize:theme': req.body.themeType,
  171. };
  172. try {
  173. await crowi.configManager.updateConfigsInTheSameNamespace('crowi', requestParams);
  174. const customizedParams = {
  175. layoutType: await crowi.configManager.getConfig('crowi', 'customize:layout'),
  176. themeType: await crowi.configManager.getConfig('crowi', 'customize:theme'),
  177. };
  178. return res.apiv3({ customizedParams });
  179. }
  180. catch (err) {
  181. const msg = 'Error occurred in updating layout and theme';
  182. logger.error('Error', err);
  183. return res.apiv3Err(new ErrorV3(msg, 'update-layoutTheme-failed'));
  184. }
  185. });
  186. /**
  187. * @swagger
  188. *
  189. * /customize-setting/behavior:
  190. * put:
  191. * tags: [CustomizeSetting]
  192. * description: Update behavior
  193. * requestBody:
  194. * required: true
  195. * content:
  196. * application/json:
  197. * schama:
  198. * $ref: '#/components/schemas/CustomizeBehavior'
  199. * responses:
  200. * 200:
  201. * description: Succeeded to update behavior
  202. * content:
  203. * application/json:
  204. * schema:
  205. * $ref: '#/components/schemas/CustomizeBehavior'
  206. */
  207. router.put('/behavior', loginRequiredStrictly, adminRequired, csrf, validator.behavior, ApiV3FormValidator, async(req, res) => {
  208. const requestParams = {
  209. 'customize:behavior': req.body.behaviorType,
  210. };
  211. try {
  212. await crowi.configManager.updateConfigsInTheSameNamespace('crowi', requestParams);
  213. const customizedParams = {
  214. behaviorType: await crowi.configManager.getConfig('crowi', 'customize:behavior'),
  215. };
  216. return res.apiv3({ customizedParams });
  217. }
  218. catch (err) {
  219. const msg = 'Error occurred in updating behavior';
  220. logger.error('Error', err);
  221. return res.apiv3Err(new ErrorV3(msg, 'update-behavior-failed'));
  222. }
  223. });
  224. /**
  225. * @swagger
  226. *
  227. * /customize-setting/function:
  228. * put:
  229. * tags: [CustomizeSetting]
  230. * description: Update function
  231. * requestBody:
  232. * required: true
  233. * content:
  234. * application/json:
  235. * schama:
  236. * $ref: '#/components/schemas/CustomizeFunction'
  237. * responses:
  238. * 200:
  239. * description: Succeeded to update function
  240. * content:
  241. * application/json:
  242. * schema:
  243. * $ref: '#/components/schemas/CustomizeFunction'
  244. */
  245. router.put('/function', loginRequiredStrictly, adminRequired, csrf, validator.function, ApiV3FormValidator, async(req, res) => {
  246. const requestParams = {
  247. 'customize:isEnabledTimeline': req.body.isEnabledTimeline,
  248. 'customize:isSavedStatesOfTabChanges': req.body.isSavedStatesOfTabChanges,
  249. 'customize:isEnabledAttachTitleHeader': req.body.isEnabledAttachTitleHeader,
  250. 'customize:showRecentCreatedNumber': req.body.recentCreatedLimit,
  251. };
  252. try {
  253. await crowi.configManager.updateConfigsInTheSameNamespace('crowi', requestParams);
  254. const customizedParams = {
  255. isEnabledTimeline: await crowi.configManager.getConfig('crowi', 'customize:isEnabledTimeline'),
  256. isSavedStatesOfTabChanges: await crowi.configManager.getConfig('crowi', 'customize:isSavedStatesOfTabChanges'),
  257. isEnabledAttachTitleHeader: await crowi.configManager.getConfig('crowi', 'customize:isEnabledAttachTitleHeader'),
  258. recentCreatedLimit: await crowi.configManager.getConfig('crowi', 'customize:showRecentCreatedNumber'),
  259. };
  260. return res.apiv3({ customizedParams });
  261. }
  262. catch (err) {
  263. const msg = 'Error occurred in updating function';
  264. logger.error('Error', err);
  265. return res.apiv3Err(new ErrorV3(msg, 'update-function-failed'));
  266. }
  267. });
  268. /**
  269. * @swagger
  270. *
  271. * /customize-setting/highlight:
  272. * put:
  273. * tags: [CustomizeSetting]
  274. * description: Update highlight
  275. * requestBody:
  276. * required: true
  277. * content:
  278. * application/json:
  279. * schama:
  280. * $ref: '#/components/schemas/CustomizeHighlight'
  281. * responses:
  282. * 200:
  283. * description: Succeeded to update highlight
  284. * content:
  285. * application/json:
  286. * schema:
  287. * $ref: '#/components/schemas/CustomizeHighlight'
  288. */
  289. router.put('/highlight', loginRequiredStrictly, adminRequired, csrf, validator.highlight, ApiV3FormValidator, async(req, res) => {
  290. const requestParams = {
  291. 'customize:highlightJsStyle': req.body.highlightJsStyle,
  292. 'customize:highlightJsStyleBorder': req.body.highlightJsStyleBorder,
  293. };
  294. try {
  295. await crowi.configManager.updateConfigsInTheSameNamespace('crowi', requestParams);
  296. const customizedParams = {
  297. styleName: await crowi.configManager.getConfig('crowi', 'customize:highlightJsStyle'),
  298. styleBorder: await crowi.configManager.getConfig('crowi', 'customize:highlightJsStyleBorder'),
  299. };
  300. return res.apiv3({ customizedParams });
  301. }
  302. catch (err) {
  303. const msg = 'Error occurred in updating highlight';
  304. logger.error('Error', err);
  305. return res.apiv3Err(new ErrorV3(msg, 'update-highlight-failed'));
  306. }
  307. });
  308. /**
  309. * @swagger
  310. *
  311. * /customize-setting/customizeTitle:
  312. * put:
  313. * tags: [CustomizeSetting]
  314. * description: Update customizeTitle
  315. * requestBody:
  316. * required: true
  317. * content:
  318. * application/json:
  319. * schema:
  320. * $ref: '#/components/schemas/CustomizeTitle'
  321. * responses:
  322. * 200:
  323. * description: Succeeded to update customizeTitle
  324. * content:
  325. * application/json:
  326. * schema:
  327. * $ref: '#/components/schemas/CustomizeTitle'
  328. */
  329. router.put('/customize-title', loginRequiredStrictly, adminRequired, csrf, validator.customizeTitle, ApiV3FormValidator, async(req, res) => {
  330. const requestParams = {
  331. 'customize:title': req.body.customizeTitle,
  332. };
  333. try {
  334. await crowi.configManager.updateConfigsInTheSameNamespace('crowi', requestParams);
  335. const customizedParams = {
  336. customizeTitle: await crowi.configManager.getConfig('crowi', 'customize:title'),
  337. };
  338. customizeService.initCustomTitle();
  339. return res.apiv3({ customizedParams });
  340. }
  341. catch (err) {
  342. const msg = 'Error occurred in updating customizeTitle';
  343. logger.error('Error', err);
  344. return res.apiv3Err(new ErrorV3(msg, 'update-customizeTitle-failed'));
  345. }
  346. });
  347. /**
  348. * @swagger
  349. *
  350. * /customize-setting/customizeHeader:
  351. * put:
  352. * tags: [CustomizeSetting]
  353. * description: Update customizeHeader
  354. * requestBody:
  355. * required: true
  356. * content:
  357. * application/json:
  358. * schama:
  359. * $ref: '#/components/schemas/CustomizeHeader'
  360. * responses:
  361. * 200:
  362. * description: Succeeded to update customize header
  363. * content:
  364. * application/json:
  365. * schema:
  366. * $ref: '#/components/schemas/CustomizeHeader'
  367. */
  368. router.put('/customize-header', loginRequiredStrictly, adminRequired, csrf, validator.customizeHeader, ApiV3FormValidator, async(req, res) => {
  369. const requestParams = {
  370. 'customize:header': req.body.customizeHeader,
  371. };
  372. try {
  373. await crowi.configManager.updateConfigsInTheSameNamespace('crowi', requestParams);
  374. const customizedParams = {
  375. customizeHeader: await crowi.configManager.getConfig('crowi', 'customize:header'),
  376. };
  377. return res.apiv3({ customizedParams });
  378. }
  379. catch (err) {
  380. const msg = 'Error occurred in updating customizeHeader';
  381. logger.error('Error', err);
  382. return res.apiv3Err(new ErrorV3(msg, 'update-customizeHeader-failed'));
  383. }
  384. });
  385. /**
  386. * @swagger
  387. *
  388. * /customize-setting/customizeCss:
  389. * put:
  390. * tags: [CustomizeSetting]
  391. * description: Update customizeCss
  392. * requestBody:
  393. * required: true
  394. * content:
  395. * application/json:
  396. * schama:
  397. * $ref: '#/components/schemas/CustomizeCss'
  398. * responses:
  399. * 200:
  400. * description: Succeeded to update customize css
  401. * content:
  402. * application/json:
  403. * schema:
  404. * $ref: '#/components/schemas/CustomizeCss'
  405. */
  406. router.put('/customize-css', loginRequiredStrictly, adminRequired, csrf, validator.customizeCss, ApiV3FormValidator, async(req, res) => {
  407. const requestParams = {
  408. 'customize:css': req.body.customizeCss,
  409. };
  410. try {
  411. await crowi.configManager.updateConfigsInTheSameNamespace('crowi', requestParams);
  412. const customizedParams = {
  413. customizeCss: await crowi.configManager.getConfig('crowi', 'customize:css'),
  414. };
  415. customizeService.initCustomCss();
  416. return res.apiv3({ customizedParams });
  417. }
  418. catch (err) {
  419. const msg = 'Error occurred in updating customizeCss';
  420. logger.error('Error', err);
  421. return res.apiv3Err(new ErrorV3(msg, 'update-customizeCss-failed'));
  422. }
  423. });
  424. /**
  425. * @swagger
  426. *
  427. * /customize-setting/customizeScript:
  428. * put:
  429. * tags: [CustomizeSetting]
  430. * description: Update customizeScript
  431. * requestBody:
  432. * required: true
  433. * content:
  434. * application/json:
  435. * schama:
  436. * $ref: '#/components/schemas/CustomizeScript'
  437. * responses:
  438. * 200:
  439. * description: Succeeded to update customize script
  440. * content:
  441. * application/json:
  442. * schema:
  443. * $ref: '#/components/schemas/CustomizeScript'
  444. */
  445. router.put('/customize-script', loginRequiredStrictly, adminRequired, csrf, validator.customizeScript, ApiV3FormValidator, async(req, res) => {
  446. const requestParams = {
  447. 'customize:script': req.body.customizeScript,
  448. };
  449. try {
  450. await crowi.configManager.updateConfigsInTheSameNamespace('crowi', requestParams);
  451. const customizedParams = {
  452. customizeScript: await crowi.configManager.getConfig('crowi', 'customize:script'),
  453. };
  454. return res.apiv3({ customizedParams });
  455. }
  456. catch (err) {
  457. const msg = 'Error occurred in updating customizeScript';
  458. logger.error('Error', err);
  459. return res.apiv3Err(new ErrorV3(msg, 'update-customizeScript-failed'));
  460. }
  461. });
  462. return router;
  463. };