// Admin · Pages — the block-based CMS page builder: drafts, protection, and // short-lived preview links. // // Mounted at /api/v1/admin/pages by admin/index.js, which already applied // `noindex, isLoggedIn, staffOnly`. No extra gate — editors build pages. Note // that protection is *not* a role gate: POST /:id/unprotect re-verifies the // caller's password server-side (see pages.controller.js). // // Unrelated to /admin/shard/pages, which is the in-game help-page (support) // queue and stays with the shard capability. // // Handlers live in pages.controller.js; this PR re-wires routes, not logic. const express = require('express') const { body, param } = require('express-validator') const pagesCtrl = require('./pages.controller') const validate = require('../../../middleware/validate') const pagesRouter = express.Router() pagesRouter.get( '/', // #swagger.tags = ['Admin · Pages'] // #swagger.summary = 'List all CMS pages (summaries)' // #swagger.security = [{ "cookieAuth": [] }, { "bearerAuth": [] }] /* #swagger.responses[200] = { description: 'Page summaries', content: { "application/json": { schema: { type: "array", items: { type: "object", additionalProperties: true } } } } } */ pagesCtrl.listPages, ) pagesRouter.post( '/', // #swagger.tags = ['Admin · Pages'] // #swagger.summary = 'Create a CMS page' // #swagger.security = [{ "cookieAuth": [] }, { "bearerAuth": [] }] /* #swagger.requestBody = { required: true, content: { "application/json": { schema: { type: "object", properties: { slug: { type: "string" }, title: { type: "string" }, status: { type: "string", enum: ["draft","published"] }, blocks: { type: "array", items: { type: "object" } }, metadata: { type: "object" }, settings: { type: "object" } } } } } } */ /* #swagger.responses[201] = { description: 'Created page', content: { "application/json": { schema: { type: "object", additionalProperties: true } } } } */ /* #swagger.responses[400] = { description: 'Invalid slug / title / blocks / metadata / settings', content: { "application/json": { schema: { $ref: "#/components/schemas/Error" } } } } */ /* #swagger.responses[409] = { description: 'Slug already exists', content: { "application/json": { schema: { $ref: "#/components/schemas/Error" } } } } */ body('slug').isString().trim().notEmpty(), body('title').isString().trim().notEmpty().isLength({ max: 200 }), validate, pagesCtrl.createPage, ) pagesRouter.get( '/:id', // #swagger.tags = ['Admin · Pages'] // #swagger.summary = 'Get a CMS page by id (full, incl. blocks)' // #swagger.security = [{ "cookieAuth": [] }, { "bearerAuth": [] }] // #swagger.parameters['id'] = { in: 'path', required: true, schema: { type: 'integer' }, description: 'Page id.' } /* #swagger.responses[200] = { description: 'The page', content: { "application/json": { schema: { type: "object", additionalProperties: true } } } } */ /* #swagger.responses[404] = { description: 'Not found', content: { "application/json": { schema: { $ref: "#/components/schemas/Error" } } } } */ param('id').isInt(), validate, pagesCtrl.getPage, ) pagesRouter.patch( '/:id', // #swagger.tags = ['Admin · Pages'] // #swagger.summary = 'Update a CMS page (title, status, blocks, metadata, settings)' // #swagger.description = 'slug is immutable; disabling protection is rejected here (use /unprotect).' // #swagger.security = [{ "cookieAuth": [] }, { "bearerAuth": [] }] // #swagger.parameters['id'] = { in: 'path', required: true, schema: { type: 'integer' }, description: 'Page id.' } /* #swagger.requestBody = { content: { "application/json": { schema: { type: "object", additionalProperties: true } } } } */ /* #swagger.responses[200] = { description: 'Updated page', content: { "application/json": { schema: { type: "object", additionalProperties: true } } } } */ /* #swagger.responses[400] = { description: 'Validation error (slug immutable, invalid blocks, etc.)', content: { "application/json": { schema: { $ref: "#/components/schemas/Error" } } } } */ /* #swagger.responses[403] = { description: 'Disabling protection requires /unprotect', content: { "application/json": { schema: { $ref: "#/components/schemas/Error" } } } } */ /* #swagger.responses[404] = { description: 'Not found', content: { "application/json": { schema: { $ref: "#/components/schemas/Error" } } } } */ param('id').isInt(), validate, pagesCtrl.updatePage, ) pagesRouter.delete( '/:id', // #swagger.tags = ['Admin · Pages'] // #swagger.summary = 'Delete a CMS page (blocked if protected)' // #swagger.security = [{ "cookieAuth": [] }, { "bearerAuth": [] }] // #swagger.parameters['id'] = { in: 'path', required: true, schema: { type: 'integer' }, description: 'Page id.' } /* #swagger.responses[200] = { description: 'Deleted (echoes the id)', content: { "application/json": { schema: { $ref: "#/components/schemas/DeletedId" } } } } */ /* #swagger.responses[403] = { description: 'Page is protected', content: { "application/json": { schema: { $ref: "#/components/schemas/Error" } } } } */ /* #swagger.responses[404] = { description: 'Not found', content: { "application/json": { schema: { $ref: "#/components/schemas/Error" } } } } */ param('id').isInt(), validate, pagesCtrl.deletePage, ) pagesRouter.post( '/:id/unprotect', // #swagger.tags = ['Admin · Pages'] // #swagger.summary = 'Disable page protection (password step-up re-auth)' // #swagger.description = 'Verifies the current admin password server-side, then flips protected → false.' // #swagger.security = [{ "cookieAuth": [] }, { "bearerAuth": [] }] // #swagger.parameters['id'] = { in: 'path', required: true, schema: { type: 'integer' }, description: 'Page id.' } /* #swagger.requestBody = { required: true, content: { "application/json": { schema: { type: "object", properties: { password: { type: "string" } }, required: ["password"] } } } } */ /* #swagger.responses[200] = { description: 'Updated page (protected=false)', content: { "application/json": { schema: { type: "object", additionalProperties: true } } } } */ /* #swagger.responses[401] = { description: 'Password incorrect', content: { "application/json": { schema: { $ref: "#/components/schemas/Error" } } } } */ /* #swagger.responses[404] = { description: 'Not found', content: { "application/json": { schema: { $ref: "#/components/schemas/Error" } } } } */ param('id').isInt(), body('password').isString().notEmpty(), validate, pagesCtrl.unprotectPage, ) pagesRouter.post( '/:id/preview', // #swagger.tags = ['Admin · Pages'] // #swagger.summary = 'Mint a 1h draft-preview link for a page' // #swagger.security = [{ "cookieAuth": [] }, { "bearerAuth": [] }] // #swagger.parameters['id'] = { in: 'path', required: true, schema: { type: 'integer' }, description: 'Page id.' } /* #swagger.responses[200] = { description: 'Preview token + path', content: { "application/json": { schema: { type: "object", properties: { token: { type: "string" }, expiresInSeconds: { type: "integer" }, path: { type: "string" } } } } } } */ /* #swagger.responses[404] = { description: 'Not found', content: { "application/json": { schema: { $ref: "#/components/schemas/Error" } } } } */ param('id').isInt(), validate, pagesCtrl.createPreview, ) module.exports = pagesRouter