| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100 |
- /* eslint-disable no-unused-vars */
- import { GrowiPluginType } from '@growi/core';
- import { ErrorV3 } from '@growi/core/dist/models';
- import express from 'express';
- import { body } from 'express-validator';
- import multer from 'multer';
- import { GrowiPlugin } from '~/features/growi-plugin/server/models';
- import { SupportedAction } from '~/interfaces/activity';
- import { AttachmentType } from '~/server/interfaces/attachment';
- import { Attachment } from '~/server/models/attachment';
- import { configManager } from '~/server/service/config-manager';
- import loggerFactory from '~/utils/logger';
- import { generateAddActivityMiddleware } from '../../middlewares/add-activity';
- import { apiV3FormValidator } from '../../middlewares/apiv3-form-validator';
- const logger = loggerFactory('growi:routes:apiv3:customize-setting');
- const router = express.Router();
- /**
- * @swagger
- *
- * components:
- * schemas:
- * CustomizeLayout:
- * description: CustomizeLayout
- * type: object
- * properties:
- * isContainerFluid:
- * type: boolean
- * CustomizeTheme:
- * description: CustomizeTheme
- * type: object
- * properties:
- * theme:
- * type: string
- * CustomizeFunction:
- * description: CustomizeFunction
- * type: object
- * properties:
- * isEnabledTimeline:
- * type: boolean
- * isEnabledAttachTitleHeader:
- * type: boolean
- * pageLimitationS:
- * type: number
- * pageLimitationM:
- * type: number
- * isEnabledStaleNotification:
- * type: boolean
- * isAllReplyShown:
- * type: boolean
- * isSearchScopeChildrenAsDefault:
- * type: boolean
- * CustomizeHighlight:
- * description: CustomizeHighlight
- * type: object
- * properties:
- * highlightJsStyle:
- * type: string
- * highlightJsStyleBorder:
- * type: boolean
- * CustomizeHighlightResponse:
- * description: CustomizeHighlight Response
- * type: object
- * properties:
- * styleName:
- * type: string
- * styleBorder:
- * type: boolean
- * CustomizeTitle:
- * description: CustomizeTitle
- * type: object
- * properties:
- * customizeTitle:
- * type: string
- * CustomizeNoscript:
- * description: CustomizeNoscript
- * type: object
- * properties:
- * customizeNoscript:
- * type: string
- * CustomizeCss:
- * description: CustomizeCss
- * type: object
- * properties:
- * customizeCss:
- * type: string
- * CustomizeScript:
- * description: CustomizeScript
- * type: object
- * properties:
- * customizeScript:
- * type: string
- * CustomizeSetting:
- * description: Customize Setting
- * type: object
- * properties:
- * isEnabledTimeline:
- * type: boolean
- * isEnabledAttachTitleHeader:
- * type: boolean
- * pageLimitationS:
- * type: number
- * pageLimitationM:
- * type: number
- * pageLimitationL:
- * type: number
- * pageLimitationXL:
- * type: number
- * isEnabledStaleNotification:
- * type: boolean
- * isAllReplyShown:
- * type: boolean
- * isSearchScopeChildrenAsDefault:
- * type: boolean
- * isEnabledMarp:
- * type: boolean
- * styleName:
- * type: string
- * styleBorder:
- * type: string
- * customizeTitle:
- * type: string
- * customizeScript:
- * type: string
- * customizeCss:
- * type: string
- * customizeNoscript:
- * type: string
- * ThemesMetadata:
- * type: object
- * properties:
- * name:
- * type: string
- * description: The name of the plugin theme.
- * manifestKey:
- * type: string
- * description: Path to the theme manifest file.
- * schemeType:
- * type: string
- * description: The color scheme type (e.g., light or dark).
- * lightBg:
- * type: string
- * description: Light mode background color (hex).
- * darkBg:
- * type: string
- * description: Dark mode background color (hex).
- * lightSidebar:
- * type: string
- * description: Light mode sidebar color (hex).
- * darkSidebar:
- * type: string
- * description: Dark mode sidebar color (hex).
- * lightIcon:
- * type: string
- * description: Light mode icon color (hex).
- * darkIcon:
- * type: string
- * description: Dark mode icon color (hex).
- * createBtn:
- * type: string
- * description: Color of the create button (hex).
- * CustomizeSidebar:
- * description: Customize Sidebar
- * type: object
- * properties:
- * isSidebarCollapsedMode:
- * type: boolean
- * description: The flag whether sidebar is collapsed mode or not.
- * isSidebarClosedAtDockMode:
- * type: boolean
- * description: The flag whether sidebar is closed at dock mode or not.
- * CustomizePresentation:
- * description: Customize Presentation
- * type: object
- * properties:
- * isEnabledMarp:
- * type: boolean
- * description: The flag whether Marp is enabled or not.
- * CustomizeLogo:
- * description: Customize Logo
- * type: object
- * properties:
- * isDefaultLogo:
- * type: boolean
- * description: The flag whether the logo is default or not.
- */
- /** @param {import('~/server/crowi').default} crowi Crowi instance */
- module.exports = (crowi) => {
- const loginRequiredStrictly = require('../../middlewares/login-required')(crowi);
- const adminRequired = require('../../middlewares/admin-required')(crowi);
- const addActivity = generateAddActivityMiddleware(crowi);
- const activityEvent = crowi.event('activity');
- const { customizeService, attachmentService } = crowi;
- const uploads = multer({ dest: `${crowi.tmpDir}uploads` });
- const validator = {
- layout: [
- body('isContainerFluid').isBoolean(),
- ],
- theme: [
- body('theme').isString(),
- ],
- sidebar: [
- body('isSidebarCollapsedMode').isBoolean(),
- body('isSidebarClosedAtDockMode').optional().isBoolean(),
- ],
- function: [
- body('isEnabledTimeline').isBoolean(),
- body('isEnabledAttachTitleHeader').isBoolean(),
- body('pageLimitationS').isInt().isInt({ min: 1, max: 1000 }),
- body('pageLimitationM').isInt().isInt({ min: 1, max: 1000 }),
- body('pageLimitationL').isInt().isInt({ min: 1, max: 1000 }),
- body('pageLimitationXL').isInt().isInt({ min: 1, max: 1000 }),
- body('isEnabledStaleNotification').isBoolean(),
- body('isAllReplyShown').isBoolean(),
- body('isSearchScopeChildrenAsDefault').isBoolean(),
- body('showPageSideAuthors').isBoolean(),
- ],
- CustomizePresentation: [
- body('isEnabledMarp').isBoolean(),
- ],
- customizeTitle: [
- body('customizeTitle').isString(),
- ],
- highlight: [
- body('highlightJsStyle').isString().isIn([
- 'github', 'github-gist', 'atom-one-light', 'xcode', 'vs', 'atom-one-dark', 'hybrid', 'monokai', 'tomorrow-night', 'vs2015',
- ]),
- body('highlightJsStyleBorder').isBoolean(),
- ],
- customizeScript: [
- body('customizeScript').isString(),
- ],
- customizeCss: [
- body('customizeCss').isString(),
- ],
- customizeNoscript: [
- body('customizeNoscript').isString(),
- ],
- logo: [
- body('isDefaultLogo').isBoolean().optional({ nullable: true }),
- body('customizedLogoSrc').isString().optional({ nullable: true }),
- ],
- };
- /**
- * @swagger
- *
- * /customize-setting:
- * get:
- * tags: [CustomizeSetting]
- * security:
- * - cookieAuth: []
- * operationId: getCustomizeSetting
- * summary: /customize-setting
- * description: Get customize parameters
- * responses:
- * 200:
- * description: params of customize
- * content:
- * application/json:
- * schema:
- * properties:
- * customizeParams:
- * type: object
- * description: customize params
- * $ref: '#/components/schemas/CustomizeSetting'
- */
- router.get('/', loginRequiredStrictly, adminRequired, async(req, res) => {
- const customizeParams = {
- isEnabledTimeline: await configManager.getConfig('customize:isEnabledTimeline'),
- isEnabledAttachTitleHeader: await configManager.getConfig('customize:isEnabledAttachTitleHeader'),
- pageLimitationS: await configManager.getConfig('customize:showPageLimitationS'),
- pageLimitationM: await configManager.getConfig('customize:showPageLimitationM'),
- pageLimitationL: await configManager.getConfig('customize:showPageLimitationL'),
- pageLimitationXL: await configManager.getConfig('customize:showPageLimitationXL'),
- isEnabledStaleNotification: await configManager.getConfig('customize:isEnabledStaleNotification'),
- isAllReplyShown: await configManager.getConfig('customize:isAllReplyShown'),
- showPageSideAuthors: await configManager.getConfig('customize:showPageSideAuthors'),
- isSearchScopeChildrenAsDefault: await configManager.getConfig('customize:isSearchScopeChildrenAsDefault'),
- isEnabledMarp: await configManager.getConfig('customize:isEnabledMarp'),
- styleName: await configManager.getConfig('customize:highlightJsStyle'),
- styleBorder: await configManager.getConfig('customize:highlightJsStyleBorder'),
- customizeTitle: await configManager.getConfig('customize:title'),
- customizeScript: await configManager.getConfig('customize:script'),
- customizeCss: await configManager.getConfig('customize:css'),
- customizeNoscript: await configManager.getConfig('customize:noscript'),
- };
- return res.apiv3({ customizeParams });
- });
- /**
- * @swagger
- *
- * /customize-setting/layout:
- * get:
- * tags: [CustomizeSetting]
- * security:
- * - cookieAuth: []
- * operationId: getLayoutCustomizeSetting
- * summary: /customize-setting/layout
- * description: Get layout
- * responses:
- * 200:
- * description: Succeeded to get layout
- * content:
- * application/json:
- * schema:
- * $ref: '#/components/schemas/CustomizeLayout'
- */
- router.get('/layout', loginRequiredStrictly, adminRequired, async(req, res) => {
- try {
- const isContainerFluid = await configManager.getConfig('customize:isContainerFluid');
- return res.apiv3({ isContainerFluid });
- }
- catch (err) {
- const msg = 'Error occurred in getting layout';
- logger.error('Error', err);
- return res.apiv3Err(new ErrorV3(msg, 'get-layout-failed'));
- }
- });
- /**
- * @swagger
- *
- * /customize-setting/layout:
- * put:
- * tags: [CustomizeSetting]
- * operationId: updateLayoutCustomizeSetting
- * summary: /customize-setting/layout
- * description: Update layout
- * requestBody:
- * required: true
- * content:
- * application/json:
- * schema:
- * $ref: '#/components/schemas/CustomizeLayout'
- * responses:
- * 200:
- * description: Succeeded to update layout
- * content:
- * application/json:
- * schema:
- * type: object
- * properties:
- * customizedParams:
- * type: object
- * description: customized params
- * $ref: '#/components/schemas/CustomizeLayout'
- */
- router.put('/layout', loginRequiredStrictly, adminRequired, addActivity, validator.layout, apiV3FormValidator, async(req, res) => {
- const requestParams = {
- 'customize:isContainerFluid': req.body.isContainerFluid,
- };
- try {
- await configManager.updateConfigs(requestParams);
- const customizedParams = {
- isContainerFluid: await configManager.getConfig('customize:isContainerFluid'),
- };
- const parameters = { action: SupportedAction.ACTION_ADMIN_LAYOUT_UPDATE };
- activityEvent.emit('update', res.locals.activity._id, parameters);
- return res.apiv3({ customizedParams });
- }
- catch (err) {
- const msg = 'Error occurred in updating layout';
- logger.error('Error', err);
- return res.apiv3Err(new ErrorV3(msg, 'update-layout-failed'));
- }
- });
- /**
- * @swagger
- *
- * /customize-setting/theme:
- * get:
- * tags: [CustomizeSetting]
- * security:
- * - cookieAuth: []
- * operationId: getThemeCustomizeSetting
- * summary: /customize-setting/theme
- * description: Get theme
- * responses:
- * 200:
- * description: Succeeded to get layout
- * content:
- * application/json:
- * schema:
- * type: object
- * properties:
- * currentTheme:
- * type: string
- * description: The current theme name.
- * pluginThemesMetadatas:
- * type: array
- * description: Metadata for available plugin themes.
- * items:
- * $ref: '#/components/schemas/ThemesMetadata'
- */
- router.get('/theme', loginRequiredStrictly, async(req, res) => {
- try {
- const currentTheme = await configManager.getConfig('customize:theme');
- // retrieve plugin manifests
- const themePlugins = await GrowiPlugin.findEnabledPluginsByType(GrowiPluginType.Theme);
- const pluginThemesMetadatas = themePlugins
- .map(themePlugin => themePlugin.meta.themes)
- .flat();
- return res.apiv3({ currentTheme, pluginThemesMetadatas });
- }
- catch (err) {
- const msg = 'Error occurred in getting theme';
- logger.error('Error', err);
- return res.apiv3Err(new ErrorV3(msg, 'get-theme-failed'));
- }
- });
- /**
- * @swagger
- *
- * /customize-setting/theme:
- * put:
- * tags: [CustomizeSetting]
- * security:
- * - cookieAuth: []
- * operationId: updateThemeCustomizeSetting
- * summary: /customize-setting/theme
- * description: Update theme
- * requestBody:
- * required: true
- * content:
- * application/json:
- * schema:
- * $ref: '#/components/schemas/CustomizeTheme'
- * responses:
- * 200:
- * description: Succeeded to update theme
- * content:
- * application/json:
- * schema:
- * type: object
- * properties:
- * customizedParams:
- * $ref: '#/components/schemas/CustomizeTheme'
- */
- router.put('/theme', loginRequiredStrictly, adminRequired, addActivity, validator.theme, apiV3FormValidator, async(req, res) => {
- const requestParams = {
- 'customize:theme': req.body.theme,
- };
- try {
- await configManager.updateConfigs(requestParams);
- const customizedParams = {
- theme: await configManager.getConfig('customize:theme'),
- };
- customizeService.initGrowiTheme();
- const parameters = { action: SupportedAction.ACTION_ADMIN_THEME_UPDATE };
- activityEvent.emit('update', res.locals.activity._id, parameters);
- return res.apiv3({ customizedParams });
- }
- catch (err) {
- const msg = 'Error occurred in updating theme';
- logger.error('Error', err);
- return res.apiv3Err(new ErrorV3(msg, 'update-theme-failed'));
- }
- });
- /**
- * @swagger
- *
- * /customize-setting/sidebar:
- * get:
- * tags: [CustomizeSetting]
- * security:
- * - cookieAuth: []
- * operationId: getCustomeSettingSidebar
- * summary: /customize-setting/sidebar
- * description: Get sidebar
- * responses:
- * 200:
- * description: Succeeded to get sidebar
- * content:
- * application/json:
- * schema:
- * $ref: '#/components/schemas/CustomizeSidebar'
- */
- router.get('/sidebar', loginRequiredStrictly, adminRequired, async(req, res) => {
- try {
- const isSidebarCollapsedMode = await configManager.getConfig('customize:isSidebarCollapsedMode');
- const isSidebarClosedAtDockMode = await configManager.getConfig('customize:isSidebarClosedAtDockMode');
- return res.apiv3({ isSidebarCollapsedMode, isSidebarClosedAtDockMode });
- }
- catch (err) {
- const msg = 'Error occurred in getting sidebar';
- logger.error('Error', err);
- return res.apiv3Err(new ErrorV3(msg, 'get-sidebar-failed'));
- }
- });
- /**
- * @swagger
- *
- * /customize-setting/sidebar:
- * put:
- * tags: [CustomizeSetting]
- * security:
- * - cookieAuth: []
- * operationId: updateCustomizeSettingSidebar
- * summary: /customize-setting/sidebar
- * description: Update sidebar
- * requestBody:
- * required: true
- * content:
- * application/json:
- * schema:
- * $ref: '#/components/schemas/CustomizeSidebar'
- * responses:
- * 200:
- * description: Succeeded to update sidebar
- * content:
- * application/json:
- * schema:
- * type: object
- * properties:
- * customizedParams:
- * $ref: '#/components/schemas/CustomizeSidebar'
- */
- router.put('/sidebar', loginRequiredStrictly, adminRequired, validator.sidebar, apiV3FormValidator, addActivity, async(req, res) => {
- const requestParams = {
- 'customize:isSidebarCollapsedMode': req.body.isSidebarCollapsedMode,
- 'customize:isSidebarClosedAtDockMode': req.body.isSidebarClosedAtDockMode,
- };
- try {
- await configManager.updateConfigs(requestParams);
- const customizedParams = {
- isSidebarCollapsedMode: await configManager.getConfig('customize:isSidebarCollapsedMode'),
- isSidebarClosedAtDockMode: await configManager.getConfig('customize:isSidebarClosedAtDockMode'),
- };
- activityEvent.emit('update', res.locals.activity._id, { action: SupportedAction.ACTION_ADMIN_SIDEBAR_UPDATE });
- return res.apiv3({ customizedParams });
- }
- catch (err) {
- const msg = 'Error occurred in updating sidebar';
- logger.error('Error', err);
- return res.apiv3Err(new ErrorV3(msg, 'update-sidebar-failed'));
- }
- });
- /**
- * @swagger
- *
- * /customize-setting/function:
- * put:
- * tags: [CustomizeSetting]
- * security:
- * - cookieAuth: []
- * operationId: updateFunctionCustomizeSetting
- * summary: /customize-setting/function
- * description: Update function
- * requestBody:
- * required: true
- * content:
- * application/json:
- * schema:
- * $ref: '#/components/schemas/CustomizeFunction'
- * responses:
- * 200:
- * description: Succeeded to update function
- * content:
- * application/json:
- * schema:
- * type: object
- * properties:
- * customizedParams:
- * $ref: '#/components/schemas/CustomizeFunction'
- */
- router.put('/function', loginRequiredStrictly, adminRequired, addActivity, validator.function, apiV3FormValidator, async(req, res) => {
- const requestParams = {
- 'customize:isEnabledTimeline': req.body.isEnabledTimeline,
- 'customize:isEnabledAttachTitleHeader': req.body.isEnabledAttachTitleHeader,
- 'customize:showPageLimitationS': req.body.pageLimitationS,
- 'customize:showPageLimitationM': req.body.pageLimitationM,
- 'customize:showPageLimitationL': req.body.pageLimitationL,
- 'customize:showPageLimitationXL': req.body.pageLimitationXL,
- 'customize:isEnabledStaleNotification': req.body.isEnabledStaleNotification,
- 'customize:isAllReplyShown': req.body.isAllReplyShown,
- 'customize:isSearchScopeChildrenAsDefault': req.body.isSearchScopeChildrenAsDefault,
- 'customize:showPageSideAuthors': req.body.showPageSideAuthors,
- };
- try {
- await configManager.updateConfigs(requestParams);
- const customizedParams = {
- isEnabledTimeline: await configManager.getConfig('customize:isEnabledTimeline'),
- isEnabledAttachTitleHeader: await configManager.getConfig('customize:isEnabledAttachTitleHeader'),
- pageLimitationS: await configManager.getConfig('customize:showPageLimitationS'),
- pageLimitationM: await configManager.getConfig('customize:showPageLimitationM'),
- pageLimitationL: await configManager.getConfig('customize:showPageLimitationL'),
- pageLimitationXL: await configManager.getConfig('customize:showPageLimitationXL'),
- isEnabledStaleNotification: await configManager.getConfig('customize:isEnabledStaleNotification'),
- isAllReplyShown: await configManager.getConfig('customize:isAllReplyShown'),
- isSearchScopeChildrenAsDefault: await configManager.getConfig('customize:isSearchScopeChildrenAsDefault'),
- showPageSideAuthors: await configManager.getConfig('customize:showPageSideAuthors'),
- };
- const parameters = { action: SupportedAction.ACTION_ADMIN_FUNCTION_UPDATE };
- activityEvent.emit('update', res.locals.activity._id, parameters);
- return res.apiv3({ customizedParams });
- }
- catch (err) {
- const msg = 'Error occurred in updating function';
- logger.error('Error', err);
- return res.apiv3Err(new ErrorV3(msg, 'update-function-failed'));
- }
- });
- /**
- * @swagger
- *
- * /customize-setting/presentation:
- * put:
- * tags: [CustomizeSetting]
- * security:
- * - cookieAuth: []
- * operationId: updatePresentationCustomizeSetting
- * summary: /customize-setting/presentation
- * description: Update presentation
- * requestBody:
- * required: true
- * content:
- * application/json:
- * schema:
- * $ref: '#/components/schemas/CustomizePresentation'
- * responses:
- * 200:
- * description: Succeeded to update presentation
- * content:
- * application/json:
- * schema:
- * type: object
- * properties:
- * customizedParams:
- * $ref: '#/components/schemas/CustomizePresentation'
- */
- router.put('/presentation', loginRequiredStrictly, adminRequired, addActivity, validator.CustomizePresentation, apiV3FormValidator, async(req, res) => {
- const requestParams = {
- 'customize:isEnabledMarp': req.body.isEnabledMarp,
- };
- try {
- await configManager.updateConfigs(requestParams);
- const customizedParams = {
- isEnabledMarp: await configManager.getConfig('customize:isEnabledMarp'),
- };
- const parameters = { action: SupportedAction.ACTION_ADMIN_FUNCTION_UPDATE };
- activityEvent.emit('update', res.locals.activity._id, parameters);
- return res.apiv3({ customizedParams });
- }
- catch (err) {
- const msg = 'Error occurred in updating presentaion';
- logger.error('Error', err);
- return res.apiv3Err(new ErrorV3(msg, 'update-presentation-failed'));
- }
- });
- /**
- * @swagger
- *
- * /customize-setting/highlight:
- * put:
- * tags: [CustomizeSetting]
- * security:
- * - cookieAuth: []
- * operationId: updateHighlightCustomizeSetting
- * summary: /customize-setting/highlight
- * description: Update highlight
- * requestBody:
- * required: true
- * content:
- * application/json:
- * schema:
- * $ref: '#/components/schemas/CustomizeHighlight'
- * responses:
- * 200:
- * description: Succeeded to update highlight
- * content:
- * application/json:
- * schema:
- * type: object
- * properties:
- * customizedParams:
- * $ref: '#/components/schemas/CustomizeHighlightResponse'
- */
- router.put('/highlight', loginRequiredStrictly, adminRequired, addActivity, validator.highlight, apiV3FormValidator, async(req, res) => {
- const requestParams = {
- 'customize:highlightJsStyle': req.body.highlightJsStyle,
- 'customize:highlightJsStyleBorder': req.body.highlightJsStyleBorder,
- };
- try {
- await configManager.updateConfigs(requestParams);
- const customizedParams = {
- styleName: await configManager.getConfig('customize:highlightJsStyle'),
- styleBorder: await configManager.getConfig('customize:highlightJsStyleBorder'),
- };
- const parameters = { action: SupportedAction.ACTION_ADMIN_CODE_HIGHLIGHT_UPDATE };
- activityEvent.emit('update', res.locals.activity._id, parameters);
- return res.apiv3({ customizedParams });
- }
- catch (err) {
- const msg = 'Error occurred in updating highlight';
- logger.error('Error', err);
- return res.apiv3Err(new ErrorV3(msg, 'update-highlight-failed'));
- }
- });
- /**
- * @swagger
- *
- * /customize-setting/customizeTitle:
- * put:
- * tags: [CustomizeSetting]
- * security:
- * - cookieAuth: []
- * operationId: updateCustomizeTitleCustomizeSetting
- * summary: /customize-setting/customizeTitle
- * description: Update title
- * requestBody:
- * required: true
- * content:
- * application/json:
- * schema:
- * $ref: '#/components/schemas/CustomizeTitle'
- * responses:
- * 200:
- * description: Succeeded to update customizeTitle
- * content:
- * application/json:
- * schema:
- * type: object
- * properties:
- * customizedParams:
- * $ref: '#/components/schemas/CustomizeTitle'
- */
- router.put('/customize-title', loginRequiredStrictly, adminRequired, addActivity, validator.customizeTitle, apiV3FormValidator, async(req, res) => {
- const requestParams = {
- 'customize:title': req.body.customizeTitle,
- };
- try {
- await configManager.updateConfigs(requestParams, { skipPubsub: true });
- crowi.customizeService.publishUpdatedMessage();
- const customizedParams = {
- customizeTitle: await configManager.getConfig('customize:title'),
- };
- customizeService.initCustomTitle();
- const parameters = { action: SupportedAction.ACTION_ADMIN_CUSTOM_TITLE_UPDATE };
- activityEvent.emit('update', res.locals.activity._id, parameters);
- return res.apiv3({ customizedParams });
- }
- catch (err) {
- const msg = 'Error occurred in updating customizeTitle';
- logger.error('Error', err);
- return res.apiv3Err(new ErrorV3(msg, 'update-customizeTitle-failed'));
- }
- });
- /**
- * @swagger
- *
- * /customize-setting/customize-noscript:
- * put:
- * tags: [CustomizeSetting]
- * security:
- * - cookieAuth: []
- * operationId: updateCustomizeNoscriptCustomizeSetting
- * summary: /customize-setting/customize-noscript
- * description: Update noscript
- * requestBody:
- * required: true
- * content:
- * application/json:
- * schema:
- * $ref: '#/components/schemas/CustomizeNoscript'
- * responses:
- * 200:
- * description: Succeeded to update customize header
- * content:
- * application/json:
- * schema:
- * type: object
- * properties:
- * customizedParams:
- * $ref: '#/components/schemas/CustomizeNoscript'
- */
- router.put('/customize-noscript', loginRequiredStrictly, adminRequired, addActivity, validator.customizeNoscript, apiV3FormValidator, async(req, res) => {
- const requestParams = {
- 'customize:noscript': req.body.customizeNoscript,
- };
- try {
- await configManager.updateConfigs(requestParams);
- const customizedParams = {
- customizeNoscript: await configManager.getConfig('customize:noscript'),
- };
- const parameters = { action: SupportedAction.ACTION_ADMIN_CUSTOM_NOSCRIPT_UPDATE };
- activityEvent.emit('update', res.locals.activity._id, parameters);
- return res.apiv3({ customizedParams });
- }
- catch (err) {
- const msg = 'Error occurred in updating customizeNoscript';
- logger.error('Error', err);
- return res.apiv3Err(new ErrorV3(msg, 'update-customizeNoscript-failed'));
- }
- });
- /**
- * @swagger
- *
- * /customize-setting/customize-css:
- * put:
- * tags: [CustomizeSetting]
- * security:
- * - cookieAuth: []
- * operationId: updateCustomizeCssCustomizeSetting
- * summary: /customize-setting/customize-css
- * description: Update customize css
- * requestBody:
- * required: true
- * content:
- * application/json:
- * schema:
- * $ref: '#/components/schemas/CustomizeCss'
- * responses:
- * 200:
- * description: Succeeded to update customize css
- * content:
- * application/json:
- * schema:
- * type: object
- * properties:
- * customizedParams:
- * $ref: '#/components/schemas/CustomizeCss'
- */
- router.put('/customize-css', loginRequiredStrictly, adminRequired, addActivity, validator.customizeCss, apiV3FormValidator, async(req, res) => {
- const requestParams = {
- 'customize:css': req.body.customizeCss,
- };
- try {
- await configManager.updateConfigs(requestParams, { skipPubsub: true });
- crowi.customizeService.publishUpdatedMessage();
- const customizedParams = {
- customizeCss: await configManager.getConfig('customize:css'),
- };
- customizeService.initCustomCss();
- const parameters = { action: SupportedAction.ACTION_ADMIN_CUSTOM_CSS_UPDATE };
- activityEvent.emit('update', res.locals.activity._id, parameters);
- return res.apiv3({ customizedParams });
- }
- catch (err) {
- const msg = 'Error occurred in updating customizeCss';
- logger.error('Error', err);
- return res.apiv3Err(new ErrorV3(msg, 'update-customizeCss-failed'));
- }
- });
- /**
- * @swagger
- *
- * /customize-setting/customize-script:
- * put:
- * tags: [CustomizeSetting]
- * security:
- * - cookieAuth: []
- * operationId: updateCustomizeScriptCustomizeSetting
- * summary: /customize-setting/customize-script
- * description: Update customize script
- * requestBody:
- * required: true
- * content:
- * application/json:
- * schema:
- * $ref: '#/components/schemas/CustomizeScript'
- * responses:
- * 200:
- * description: Succeeded to update customize script
- * content:
- * application/json:
- * schema:
- * type: object
- * properties:
- * customizedParams:
- * $ref: '#/components/schemas/CustomizeScript'
- */
- router.put('/customize-script', loginRequiredStrictly, adminRequired, addActivity, validator.customizeScript, apiV3FormValidator, async(req, res) => {
- const requestParams = {
- 'customize:script': req.body.customizeScript,
- };
- try {
- await configManager.updateConfigs(requestParams);
- const customizedParams = {
- customizeScript: await configManager.getConfig('customize:script'),
- };
- const parameters = { action: SupportedAction.ACTION_ADMIN_CUSTOM_SCRIPT_UPDATE };
- activityEvent.emit('update', res.locals.activity._id, parameters);
- return res.apiv3({ customizedParams });
- }
- catch (err) {
- const msg = 'Error occurred in updating customizeScript';
- logger.error('Error', err);
- return res.apiv3Err(new ErrorV3(msg, 'update-customizeScript-failed'));
- }
- });
- /**
- * @swagger
- *
- * /customize-setting/customize-logo:
- * put:
- * tags: [CustomizeSetting]
- * security:
- * - cookieAuth: []
- * operationId: updateCustomizeLogoCustomizeSetting
- * summary: /customize-setting/customize-logo
- * description: Update customize logo
- * requestBody:
- * required: true
- * content:
- * application/json:
- * schema:
- * $ref: '#/components/schemas/CustomizeLogo'
- * responses:
- * 200:
- * description: Succeeded to update customize logo
- * content:
- * application/json:
- * schema:
- * type: object
- * properties:
- * customizedParams:
- * $ref: '#/components/schemas/CustomizeLogo'
- */
- router.put('/customize-logo', loginRequiredStrictly, adminRequired, validator.logo, apiV3FormValidator, async(req, res) => {
- const {
- isDefaultLogo,
- } = req.body;
- const requestParams = {
- 'customize:isDefaultLogo': isDefaultLogo,
- };
- try {
- await configManager.updateConfigs(requestParams);
- const customizedParams = {
- isDefaultLogo: await configManager.getConfig('customize:isDefaultLogo'),
- };
- return res.apiv3({ customizedParams });
- }
- catch (err) {
- const msg = 'Error occurred in updating customizeLogo';
- logger.error('Error', err);
- return res.apiv3Err(new ErrorV3(msg, 'update-customizeLogo-failed'));
- }
- });
- /**
- * @swagger
- *
- * /customize-setting/upload-brand-logo:
- * put:
- * tags: [CustomizeSetting]
- * security:
- * - cookieAuth: []
- * operationId: uploadBrandLogoCustomizeSetting
- * summary: /customize-setting/upload-brand-logo
- * description: Upload brand logo
- * requestBody:
- * required: true
- * content:
- * multipart/form-data:
- * schema:
- * type: object
- * properties:
- * file:
- * format: binary
- * responses:
- * 200:
- * description: Succeeded to upload brand logo
- * content:
- * application/json:
- * schema:
- * type: object
- * properties:
- * attachment:
- * allOf:
- * - $ref: '#/components/schemas/Attachment'
- * - type: object
- * properties:
- * creator:
- * type: string
- * page: {}
- * temporaryUrlExpiredAt: {}
- * temporaryUrlCached: {}
- */
- router.post('/upload-brand-logo', loginRequiredStrictly, adminRequired,
- uploads.single('file'), validator.logo, apiV3FormValidator, async(req, res) => {
- if (req.file == null) {
- return res.apiv3Err(new ErrorV3('File error.', 'upload-brand-logo-failed'));
- }
- if (req.user == null) {
- return res.apiv3Err(new ErrorV3('param "user" must be set.', 'upload-brand-logo-failed'));
- }
- const file = req.file;
- // check type
- const acceptableFileType = /image\/.+/;
- if (!file.mimetype.match(acceptableFileType)) {
- const msg = 'File type error. Only image files is allowed to set as user picture.';
- return res.apiv3Err(new ErrorV3(msg, 'upload-brand-logo-failed'));
- }
- // Check if previous attachment exists and remove it
- const attachments = await Attachment.find({ attachmentType: AttachmentType.BRAND_LOGO });
- if (attachments != null) {
- await attachmentService.removeAllAttachments(attachments);
- }
- let attachment;
- try {
- attachment = await attachmentService.createAttachment(file, req.user, null, AttachmentType.BRAND_LOGO);
- }
- catch (err) {
- logger.error(err);
- return res.apiv3Err(new ErrorV3(err.message, 'upload-brand-logo-failed'));
- }
- attachment.toObject({ virtuals: true });
- return res.apiv3({ attachment });
- });
- /**
- * @swagger
- *
- * /customize-setting/delete-brand-logo:
- * delete:
- * tags: [CustomizeSetting]
- * security:
- * - cookieAuth: []
- * operationId: deleteBrandLogoCustomizeSetting
- * summary: /customize-setting/delete-brand-logo
- * description: Delete brand logo
- * responses:
- * 200:
- * description: Succeeded to delete brand logo
- * content:
- * application/json:
- * schema:
- * additionalProperties: false
- */
- router.delete('/delete-brand-logo', loginRequiredStrictly, adminRequired, async(req, res) => {
- const attachments = await Attachment.find({ attachmentType: AttachmentType.BRAND_LOGO });
- if (attachments == null) {
- return res.apiv3Err(new ErrorV3('attachment not found', 'delete-brand-logo-failed'));
- }
- try {
- await attachmentService.removeAllAttachments(attachments);
- }
- catch (err) {
- logger.error(err);
- return res.status(500).apiv3Err(new ErrorV3('Error while deleting logo', 'delete-brand-logo-failed'));
- }
- return res.apiv3({});
- });
- return router;
- };
|