customize-setting.js 16 KB

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