fix: address all 11 review items for group-based access control
Bugs fixed: - knowledgeBase.js: logAudit calls converted from positional args to object signature - archerTickets.js: targetType/targetId renamed to entityType/entityId - server.js: single CVE delete now has cascade/compliance check for Standard_User Unprotected endpoints secured: - ivantiTodoQueue.js: POST/PUT/DELETE now require Admin or Standard_User - ivantiFindings.js: PUT note and POST sync now require Admin or Standard_User - compliance.js: POST notes now requires Admin or Standard_User - ivantiWorkflows.js: POST sync now requires Admin or Standard_User - auth.js: cleanup-sessions now requires Admin via requireAuth + requireGroup Additional fixes: - ExportsPage.js: canExport() guard blocks Read_Only users - knowledgeBase.js: Standard_User delete checks created_by ownership - Migration: added INSERT/UPDATE triggers to enforce valid user_group values
This commit is contained in:
@@ -39,7 +39,19 @@ function createKnowledgeBaseRouter(db, upload) {
|
||||
return ALLOWED_EXTENSIONS.has(ext);
|
||||
}
|
||||
|
||||
// POST /api/knowledge-base/upload - Upload new document
|
||||
/**
|
||||
* POST /api/knowledge-base/upload
|
||||
* Upload a new knowledge base document.
|
||||
*
|
||||
* @body {string} title - Article title (required)
|
||||
* @body {string} [description] - Article description
|
||||
* @body {string} [category] - Article category (defaults to 'General')
|
||||
* @body {File} file - The document file to upload (multipart/form-data)
|
||||
*
|
||||
* @response 200 - { success: true, id: number, title: string, slug: string, category: string }
|
||||
* @response 400 - { error: string } - Missing title, no file, or invalid file type
|
||||
* @response 500 - { error: string } - Database or filesystem error
|
||||
*/
|
||||
router.post('/upload', requireAuth(db), requireGroup('Admin', 'Standard_User'), (req, res, next) => {
|
||||
upload.single('file')(req, res, (err) => {
|
||||
if (err) {
|
||||
@@ -160,7 +172,13 @@ function createKnowledgeBaseRouter(db, upload) {
|
||||
}
|
||||
});
|
||||
|
||||
// GET /api/knowledge-base - List all articles
|
||||
/**
|
||||
* GET /api/knowledge-base
|
||||
* List all knowledge base articles.
|
||||
*
|
||||
* @response 200 - Array of article objects: [{ id, title, slug, description, category, file_name, file_type, file_size, created_at, updated_at, created_by_username }]
|
||||
* @response 500 - { error: string }
|
||||
*/
|
||||
router.get('/', requireAuth(db), (req, res) => {
|
||||
const sql = `
|
||||
SELECT
|
||||
@@ -182,7 +200,16 @@ function createKnowledgeBaseRouter(db, upload) {
|
||||
});
|
||||
});
|
||||
|
||||
// GET /api/knowledge-base/:id - Get single article details
|
||||
/**
|
||||
* GET /api/knowledge-base/:id
|
||||
* Get a single article's details by ID.
|
||||
*
|
||||
* @param {string} id - Article ID (route parameter)
|
||||
*
|
||||
* @response 200 - { id, title, slug, description, category, file_name, file_type, file_size, created_at, updated_at, created_by_username }
|
||||
* @response 404 - { error: 'Article not found' }
|
||||
* @response 500 - { error: string }
|
||||
*/
|
||||
router.get('/:id', requireAuth(db), (req, res) => {
|
||||
const { id } = req.params;
|
||||
|
||||
@@ -210,7 +237,17 @@ function createKnowledgeBaseRouter(db, upload) {
|
||||
});
|
||||
});
|
||||
|
||||
// GET /api/knowledge-base/:id/content - Get document content for display
|
||||
/**
|
||||
* GET /api/knowledge-base/:id/content
|
||||
* Get document content for inline display. Returns the raw file with appropriate
|
||||
* Content-Type headers. Markdown and text files are served as text/plain.
|
||||
*
|
||||
* @param {string} id - Article ID (route parameter)
|
||||
*
|
||||
* @response 200 - Raw file content with Content-Type and Content-Disposition headers
|
||||
* @response 404 - { error: string } - Article or file not found
|
||||
* @response 500 - { error: string }
|
||||
*/
|
||||
router.get('/:id/content', requireAuth(db), (req, res) => {
|
||||
const { id } = req.params;
|
||||
|
||||
@@ -261,7 +298,16 @@ function createKnowledgeBaseRouter(db, upload) {
|
||||
});
|
||||
});
|
||||
|
||||
// GET /api/knowledge-base/:id/download - Download document
|
||||
/**
|
||||
* GET /api/knowledge-base/:id/download
|
||||
* Download a knowledge base document as an attachment.
|
||||
*
|
||||
* @param {string} id - Article ID (route parameter)
|
||||
*
|
||||
* @response 200 - File download with Content-Disposition: attachment header
|
||||
* @response 404 - { error: string } - Article or file not found
|
||||
* @response 500 - { error: string }
|
||||
*/
|
||||
router.get('/:id/download', requireAuth(db), (req, res) => {
|
||||
const { id } = req.params;
|
||||
|
||||
@@ -298,7 +344,18 @@ function createKnowledgeBaseRouter(db, upload) {
|
||||
});
|
||||
});
|
||||
|
||||
// DELETE /api/knowledge-base/:id - Delete article
|
||||
/**
|
||||
* DELETE /api/knowledge-base/:id
|
||||
* Delete a knowledge base article and its associated file.
|
||||
* Standard_User can only delete articles they created. Admin can delete any article.
|
||||
*
|
||||
* @param {string} id - Article ID (route parameter)
|
||||
*
|
||||
* @response 200 - { success: true }
|
||||
* @response 403 - { error: string } - Ownership check failed for Standard_User
|
||||
* @response 404 - { error: 'Article not found' }
|
||||
* @response 500 - { error: string }
|
||||
*/
|
||||
router.delete('/:id', requireAuth(db), requireGroup('Admin', 'Standard_User'), (req, res) => {
|
||||
const { id } = req.params;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user