Преглед изворни кода

Resolve swagger problems by adding responses to definitions-apiv3

arvid-e пре 8 месеци
родитељ
комит
d42d4b1d4d

+ 160 - 12
apps/app/bin/openapi/definition-apiv3.js

@@ -49,6 +49,166 @@ module.exports = {
         in: 'header',
         name: 'x-growi-transfer-key',
       },
+      adminRequired: {
+        type: 'http',
+        scheme: 'bearer',
+        bearerFormat: 'AdminAccess',
+        description: 'Requires an authenticated user with admin privileges',
+      },
+    },
+    responses: {
+      400: {
+        description: 'Bad request.',
+        content: {
+          'application/json': {
+            schema: {
+              $ref: '#/components/schemas/ErrorResponse',
+            },
+          },
+        },
+      },
+      401: {
+        description: 'Unauthorized.',
+        content: {
+          'application/json': {
+            schema: {
+              $ref: '#/components/schemas/ErrorResponse',
+            },
+          },
+        },
+      },
+      403: {
+        description: 'Forbidden.',
+        content: {
+          'application/json': {
+            schema: {
+              $ref: '#/components/schemas/ErrorResponse',
+            },
+          },
+        },
+      },
+      404: {
+        description: 'Not found.',
+        content: {
+          'application/json': {
+            schema: {
+              $ref: '#/components/schemas/ErrorResponse',
+            },
+          },
+        },
+      },
+      500: {
+        description: 'Internal server error.',
+        content: {
+          'application/json': {
+            schema: {
+              $ref: '#/components/schemas/ErrorResponse',
+            },
+          },
+        },
+      },
+    },
+    schemas: {
+      ErrorResponse: {
+        type: 'object',
+        description: 'Standard error response format for API failures.',
+        properties: {
+          message: {
+            type: 'string',
+            description: 'A human-readable message providing details about the error.',
+          },
+          status: {
+            type: 'number',
+            description: 'The HTTP status code associated with the error (e.g., 400, 401, 500).',
+          },
+        },
+      },
+      MarkdownParams: {
+        type: 'object',
+        description: 'All current Markdown rendering settings.',
+        properties: {
+          isEnabledLinebreaks: { type: 'boolean', description: 'Controls if line breaks are enabled in Markdown.' },
+          isEnabledLinebreaksInComments: { type: 'boolean', description: 'Controls if line breaks are enabled in Markdown comments.' },
+          adminPreferredIndentSize: { type: 'number', enum: [2, 4], description: 'Preferred indent size for Markdown, either 2 or 4 spaces.' },
+          isIndentSizeForced: { type: 'boolean', description: 'If true, forces the preferred indent size across all users.' },
+          isEnabledXss: { type: 'boolean', description: 'Controls if XSS prevention is enabled.' },
+          xssOption: { type: 'string', description: 'The XSS prevention option.' },
+          tagWhitelist: { type: 'array', items: { type: 'string' }, description: 'List of HTML tags allowed if XSS prevention is enabled.' },
+          attrWhitelist: { type: 'string', description: 'Stringified JSON object of allowed attributes for whitelisted tags.' },
+        },
+      },
+      LineBreakParams: {
+        type: 'object',
+        description: 'Parameters for Markdown line break settings.',
+        properties: {
+          isEnabledLinebreaks: { type: 'boolean', description: 'Enable or disable line breaks.' },
+          isEnabledLinebreaksInComments: { type: 'boolean', description: 'Enable or disable line breaks in comments.' },
+        },
+      },
+      IndentParams: {
+        type: 'object',
+        description: 'Parameters for Markdown indent settings.',
+        properties: {
+          adminPreferredIndentSize: { type: 'number', enum: [2, 4], description: 'The preferred indent size (2 or 4).' },
+          isIndentSizeForced: { type: 'boolean', description: 'Force preferred indent size for all users.' },
+        },
+      },
+      XssParams: {
+        type: 'object',
+        description: 'Parameters for Markdown XSS prevention settings.',
+        properties: {
+          isEnabledXss: { type: 'boolean', description: 'Enable or disable XSS prevention.' },
+          xssOption: { type: 'string', description: 'XSS prevention option (e.g., "permissive", "strict").' }, // Adjust enum if known values exist
+          tagWhitelist: { type: 'array', items: { type: 'string' }, description: 'Array of whitelisted HTML tags.' },
+          attrWhitelist: { type: 'string', description: 'Stringified JSON of whitelisted HTML attributes.' },
+        },
+      },
+    },
+    parameters: {
+      MimeTypePathParam: {
+        name: 'mimeType',
+        in: 'path',
+        required: true,
+        description: 'Configurable MIME type (e.g., image/png, application/pdf)',
+        schema: {
+          type: 'string',
+          enum: [
+            'image/jpeg',
+            'image/png',
+            'image/gif',
+            'image/webp',
+            'image/bmp',
+            'image/tiff',
+            'image/x-icon',
+            'application/pdf',
+            'text/plain',
+            'video/mp4',
+            'video/webm',
+            'video/ogg',
+            'audio/mpeg',
+            'audio/ogg',
+            'audio/wav',
+            'text/html',
+            'text/javascript',
+            'application/javascript',
+            'image/svg+xml',
+            'application/xml',
+            'application/json',
+            'application/x-sh',
+            'application/x-msdownload',
+            'application/octet-stream',
+            'application/msword',
+            'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
+            'application/vnd.ms-excel',
+            'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
+            'application/vnd.ms-powerpoint',
+            'application/vnd.openxmlformats-officedocument.presentationml.presentation',
+            'application/zip',
+            'application/x-rar-compressed',
+            'text/csv',
+          ],
+        },
+      },
     },
   },
   'x-tagGroups': [
@@ -65,7 +225,6 @@ module.exports = {
         'ShareLinks',
         'Users',
         'UserUISettings',
-        '',
       ],
     },
     {
@@ -74,11 +233,6 @@ module.exports = {
         'GeneralSetting',
         'EditorSetting',
         'InAppNotificationSettings',
-        '',
-        '',
-        '',
-        '',
-        '',
       ],
     },
     {
@@ -120,12 +274,6 @@ module.exports = {
       tags: [
         'Healthcheck',
         'Statistics',
-        '',
-        '',
-        '',
-        '',
-        '',
-        '',
       ],
     },
   ],

+ 167 - 167
apps/app/src/server/routes/apiv3/content-disposition-settings.js

@@ -33,82 +33,82 @@ const validator = {
 };
 
 /*
-  * @swagger
-  *
-  * components:
-  *    securitySchemes:
-  *      adminRequired:
-  *        type: http
-  *        scheme: bearer
-  *        bearerFormat: AdminAccess
-  *        description: Requires an authenticated user with admin privileges
-  *    responses:
-  *      400:
-  *        description: Bad Request
-  *        content:
-  *          application/json:
-  *            schema:
-  *              $ref: '#/components/schemas/ErrorResponse'
-  *      401:
-  *        description: Unauthorized
-  *        content:
-  *          application/json:
-  *            schema:
-  *              $ref: '#/components/schemas/ErrorResponse'
-  *      403:
-  *        description: Forbidden
-  *        content:
-  *          application/json:
-  *            schema:
-  *              $ref: '#/components/schemas/ErrorResponse'
-  *      404:
-  *        description: Not Found
-  *        content:
-  *          application/json:
-  *            schema:
-  *              $ref: '#/components/schemas/ErrorResponse'
-  *      500:
-  *        description: Internal Server Error
-  *        content:
-  *          application/json:
-  *            schema:
-  *              $ref: '#/components/schemas/ErrorResponse'
-  *    schemas:
-  *      ErrorResponse:
-  *        type: object
-  *        properties:
-  *          message:
-  *            type: string
-  *            description: Error message
-  *          status:
-  *            type: number
-  *            description: HTTP status code
-  *    parameters:
-  *      MimeTypePathParam:
-  *        name: mimeType
-  *        in: path
-  *        required: true
-  *        description: Configurable MIME type (e g , image/png, application/pdf)
-  *        schema:
-  *          type: string
-  *          enum:
-  *            - application/pdf
-  *            - image/png
-  *            - image/jpeg
-  *            - image/gif
-  *            - text/plain
-  *            - text/html
-  *            - application/vnd openxmlformats-officedocument spreadsheetml sheet
-  *            - application/vnd openxmlformats-officedocument wordprocessingml document
-  *            - application/vnd openxmlformats-officedocument presentationml presentation
-  *            - application/msword
-  *            - application/vnd ms-excel
-  *            - application/vnd ms-powerpoint
-  *            - application/zip
-  *            - application/x-rar-compressed
-  *            - audio/mpeg
-  *            - video/mp4
-  *            - application/octet-stream
+ * @swagger
+ *
+ *  components:
+ *    securitySchemes:
+ *      adminRequired:
+ *        type: http
+ *        scheme: bearer
+ *        bearerFormat: AdminAccess
+ *        description: Requires an authenticated user with admin privileges
+ *    responses:
+ *      400:
+ *        description: Bad Request
+ *        content:
+ *          application/json:
+ *            schema:
+ *              $ref: '#/components/schemas/ErrorResponse'
+ *      401:
+ *        description: Unauthorized
+ *        content:
+ *          application/json:
+ *            schema:
+ *              $ref: '#/components/schemas/ErrorResponse'
+ *      403:
+ *        description: Forbidden
+ *        content:
+ *          application/json:
+ *            schema:
+ *              $ref: '#/components/schemas/ErrorResponse'
+ *      404:
+ *        description: Not Found
+ *        content:
+ *          application/json:
+ *            schema:
+ *              $ref: '#/components/schemas/ErrorResponse'
+ *      500:
+ *        description: Internal Server Error
+ *        content:
+ *          application/json:
+ *            schema:
+ *              $ref: '#/components/schemas/ErrorResponse'
+ *    schemas:
+ *      ErrorResponse:
+ *        type: object
+ *        properties:
+ *          message:
+ *            type: string
+ *            description: Error message
+ *          status:
+ *            type: number
+ *            description: HTTP status code
+ *    parameters:
+ *      MimeTypePathParam:
+ *        name: mimeType
+ *        in: path
+ *        required: true
+ *        description: Configurable MIME type (e g , image/png, application/pdf)
+ *        schema:
+ *          type: string
+ *          enum:
+ *            - application/pdf
+ *            - image/png
+ *            - image/jpeg
+ *            - image/gif
+ *            - text/plain
+ *            - text/html
+ *            - application/vnd openxmlformats-officedocument spreadsheetml sheet
+ *            - application/vnd openxmlformats-officedocument wordprocessingml document
+ *            - application/vnd openxmlformats-officedocument presentationml presentation
+ *            - application/msword
+ *            - application/vnd ms-excel
+ *            - application/vnd ms-powerpoint
+ *            - application/zip
+ *            - application/x-rar-compressed
+ *            - audio/mpeg
+ *            - video/mp4
+ *            - application/octet-stream
   */
 module.exports = (crowi) => {
   const loginRequiredStrictly = require('~/server/middlewares/login-required')(crowi);
@@ -117,42 +117,42 @@ module.exports = (crowi) => {
   const activityEvent = crowi.event('activity');
 
   /**
-	 * @swagger
-	 *
-	 * /content-disposition-settings:
-	 *   get:
-	 *     tags: [Content-Disposition Settings]
-	 *     summary: Get content disposition settings for configurable MIME types
-	 *     description: Retrieve the current `inline` or `attachment` disposition setting for each configurable MIME type.
-	 *     security:
-	 *       - cookieAuth: []
-	 *       - adminRequired: []
-	 *     responses:
-	 *       200:
-	 *         description: Successfully retrieved content disposition settings.
-	 *         content:
-	 *           application/json:
-	 *             schema:
-	 *               type: object
-	 *               properties:
-	 *                 contentDispositionSettings:
-	 *                   type: object
-	 *                   description: An object mapping configurable MIME types to their current inline disposition status.
-	 *                   additionalProperties:
-	 *                     type: boolean
-	 *                     description: true if inline, false if attachment.
-	 *                     example:
-	 *                       image/png: true
-	 *                       application/pdf: false
-	 *                       text/plain: true
-	 *       401:
-	 *         $ref: '#/components/responses/401'
-	 *       403:
-	 *         $ref: '#/components/responses/403'
-	 *       500:
-	 *         $ref: '#/components/responses/500'
-	 *
-	 */
+ * @swagger
+ *
+ * /content-disposition-settings:
+ *   get:
+ *     tags: [Content-Disposition Settings]
+ *     summary: Get content disposition settings for configurable MIME types
+ *     description: Retrieve the current `inline` or `attachment` disposition setting for each configurable MIME type.
+ *     security:
+ *       - cookieAuth: []
+ *       - adminRequired: []
+ *     responses:
+ *       200:
+ *         description: Successfully retrieved content disposition settings.
+ *         content:
+ *           application/json:
+ *             schema:
+ *               type: object
+ *               properties:
+ *                 contentDispositionSettings:
+ *                   type: object
+ *                   description: An object mapping configurable MIME types to their current inline disposition status.
+ *                   additionalProperties:
+ *                     type: boolean
+ *                     description: true if inline, false if attachment.
+ *                     example:
+ *                       image/png: true
+ *                       application/pdf: false
+ *                       text/plain: true
+ *       401:
+ *         $ref: '#/components/responses/401'
+ *       403:
+ *         $ref: '#/components/responses/403'
+ *       500:
+ *         $ref: '#/components/responses/500'
+ *
+ */
   router.get('/', loginRequiredStrictly, adminRequired, async(req, res) => {
     const promises = CONFIGURABLE_MIME_TYPES_FOR_DISPOSITION.map(
       async(mimeType) => {
@@ -181,61 +181,61 @@ module.exports = (crowi) => {
   });
 
   /**
-	 * @swagger
-	 *
-	 * paths:
-	 *    /content-disposition-settings/{mimeType}:
-	 *      put:
-	 *        tags: [Content Disposition Settings]
-	 *        summary: Update content disposition setting for a specific MIME type
-	 *        description: Set the `inline` or `attachment` disposition for a given configurable MIME type
-	 *        security:
-	 *          - cookieAuth: []
-	 *          - adminRequired: []
-	 *        parameters:
-	 *          - $ref: '#/components/parameters/MimeTypePathParam'
-	 *        requestBody:
-	 *          required: true
-	 *          content:
-	 *            application/json:
-	 *              schema:
-	 *                type: object
-	 *                required:
-	 *                  - isInline
-	 *                properties:
-	 *                  isInline:
-	 *                     type: boolean
-	 *                     description: 'Set to `true` for inline disposition, `false` for attachment disposition (e g , prompts download) '
-	 *                     example: true
-	 *      operationId: putContentDispositionSettingsByMimeType
-	 *      responses:
-	 *        200:
-	 *          description: Successfully updated content disposition setting
-	 *          content:
-	 *            application/json:
-	 *              schema:
-	 *                type: object
-	 *                properties:
-	 *                  setting:
-	 *                     type: object
-	 *                     properties:
-	 *                       mimeType:
-	 *                         type: string
-	 *                         example: 'application/pdf'
-	 *                       isInline:
-	 *                         type: boolean
-	 *                         example: true
-	 *        400:
-	 *          $ref: '#/components/responses/400'
-	 *        401:
-	 *          $ref: '#/components/responses/401'
-	 *        403:
-	 *          $ref: '#/components/responses/403'
-	 *        404:
-	 *          $ref: '#/components/responses/404'
-	 *        500:
-	 *          $ref: '#/components/responses/500'
-	 */
+ * @swagger
+ *
+ * paths:
+ *    /content-disposition-settings/{mimeType}:
+ *      put:
+ *        tags: [Content Disposition Settings]
+ *        summary: Update content disposition setting for a specific MIME type
+ *        description: Set the `inline` or `attachment` disposition for a given configurable MIME type
+ *        security:
+ *          - cookieAuth: []
+ *          - adminRequired: []
+ *        parameters:
+ *          - $ref: '#/components/parameters/MimeTypePathParam'
+ *        requestBody:
+ *          required: true
+ *          content:
+ *            application/json:
+ *              schema:
+ *                type: object
+ *                required:
+ *                  - isInline
+ *                properties:
+ *                  isInline:
+ *                     type: boolean
+ *                     description: 'Set to `true` for inline disposition, `false` for attachment disposition (e g , prompts download) '
+ *                     example: true
+ *        operationId: putContentDispositionSettingsByMimeType
+ *        responses:
+ *          200:
+ *            description: Successfully updated content disposition setting
+ *            content:
+ *              application/json:
+ *                schema:
+ *                  type: object
+ *                  properties:
+ *                    setting:
+ *                       type: object
+ *                       properties:
+ *                         mimeType:
+ *                           type: string
+ *                           example: 'application/pdf'
+ *                         isInline:
+ *                           type: boolean
+ *                           example: true
+ *        400:
+ *          $ref: '#/components/responses/400'
+ *        401:
+ *          $ref: '#/components/responses/401'
+ *        403:
+ *          $ref: '#/components/responses/403'
+ *        404:
+ *          $ref: '#/components/responses/404'
+ *        500:
+ *          $ref: '#/components/responses/500'
+ */
   router.put(
     '/:mimeType(*)',
     loginRequiredStrictly,

+ 79 - 90
apps/app/src/server/routes/apiv3/markdown-setting.js

@@ -1,4 +1,5 @@
 import { ErrorV3 } from '@growi/core/dist/models';
+import express from 'express';
 
 import { SupportedAction } from '~/interfaces/activity';
 import { configManager } from '~/server/service/config-manager';
@@ -10,8 +11,6 @@ import { apiV3FormValidator } from '../../middlewares/apiv3-form-validator';
 
 const logger = loggerFactory('growi:routes:apiv3:markdown-setting');
 
-const express = require('express');
-
 const router = express.Router();
 
 const { body } = require('express-validator');
@@ -33,94 +32,84 @@ const validator = {
 };
 
 
-/**
- * @swagger
- *
- *  components:
- *    schemas:
- *      MarkdownParams:
- *        description: MarkdownParams
- *        type: object
- *        properties:
- *          isEnabledLinebreaks:
- *            type: boolean
- *            description: enable lineBreak
- *          isEnabledLinebreaksInComments:
- *            type: boolean
- *            description: enable lineBreak in comment
- *          adminPreferredIndentSize:
- *            type: number
- *            description: preferred indent size
- *          isIndentSizeForced:
- *            type: boolean
- *            description: force indent size
- *          isEnabledXss:
- *            type: boolean
- *            description: enable xss
- *          xssOption:
- *            type: number
- *            description: number of xss option
- *          tagWhitelist:
- *            type: array
- *            description: array of tag whitelist
- *            items:
- *              type: string
- *              description: tag whitelist
- *          attrWhitelist:
- *            type: string
- *            description: attr whitelist
- *      LineBreakParams:
- *        description: LineBreakParams
- *        type: object
- *        properties:
- *          isEnabledLinebreaks:
- *            type: boolean
- *            description: enable lineBreak
- *          isEnabledLinebreaksInComments:
- *            type: boolean
- *            description: enable lineBreak in comment
- *      PresentationParams:
- *        description: PresentationParams
- *        type: object
- *        properties:
- *          pageBreakSeparator:
- *            type: number
- *            description: number of pageBreakSeparator
- *          pageBreakCustomSeparator:
- *            type: string
- *            description: string of pageBreakCustomSeparator
- *      XssParams:
- *        description: XssParams
- *        type: object
- *        properties:
- *          isEnabledXss:
- *            type: boolean
- *            description: enable xss
- *          xssOption:
- *            type: number
- *            description: number of xss option
- *          tagWhitelist:
- *            type: array
- *            description: array of tag whitelist
- *            items:
- *              type: string
- *              description: tag whitelist
- *          attrWhitelist:
- *            type: string
- *            description: attr whitelist
- *      IndentParams:
- *        description: IndentParams
- *        type: object
- *        properties:
- *          adminPreferredIndentSize:
- *            type: number
- *            description: preferred indent size
- *          isIndentSizeForced:
- *            type: boolean
- *            description: force indent size
- */
-
-/** @param {import('~/server/crowi').default} crowi Crowi instance */
+/*
+  * @swagger
+  *
+  * components:
+  *    securitySchemes:
+  *      adminRequired:
+  *        type: http
+  *        scheme: bearer
+  *        bearerFormat: AdminAccess
+  *        description: Requires an authenticated user with admin privileges
+  *    responses:
+  *      400:
+  *        description: Bad Request
+  *        content:
+  *          application/json:
+  *            schema:
+  *              $ref: '#/components/schemas/ErrorResponse'
+  *      401:
+  *        description: Unauthorized
+  *        content:
+  *          application/json:
+  *            schema:
+  *              $ref: '#/components/schemas/ErrorResponse'
+  *      403:
+  *        description: Forbidden
+  *        content:
+  *          application/json:
+  *            schema:
+  *              $ref: '#/components/schemas/ErrorResponse'
+  *      404:
+  *        description: Not Found
+  *        content:
+  *          application/json:
+  *            schema:
+  *              $ref: '#/components/schemas/ErrorResponse'
+  *      500:
+  *        description: Internal Server Error
+  *        content:
+  *          application/json:
+  *            schema:
+  *              $ref: '#/components/schemas/ErrorResponse'
+  *    schemas:
+  *      ErrorResponse:
+  *        type: object
+  *        properties:
+  *          message:
+  *            type: string
+  *            description: Error message
+  *          status:
+  *            type: number
+  *            description: HTTP status code
+  *    parameters:
+  *      MimeTypePathParam:
+  *        name: mimeType
+  *        in: path
+  *        required: true
+  *        description: Configurable MIME type (e.g., image/png, application/pdf)
+  *        schema:
+  *          type: string
+  *          enum:
+  *            - application/pdf
+  *            - image/png
+  *            - image/jpeg
+  *            - - image/gif
+  *            - text/plain
+  *            - text/html
+  *            - application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
+  *            - application/vnd.openxmlformats-officedocument.wordprocessingml.document
+  *            - application/vnd.openxmlformats-officedocument.presentationml.presentation
+  *            - application/msword
+  *            - application/vnd.ms-excel
+  *            - application/vnd.ms-powerpoint
+  *            - application/zip
+  *            - application/x-rar-compressed
+  *            - audio/mpeg
+  *            - video/mp4
+  *            - application/octet-stream
+  */
 module.exports = (crowi) => {
   const loginRequiredStrictly = require('../../middlewares/login-required')(crowi);
   const adminRequired = require('../../middlewares/admin-required')(crowi);