Deduplicate validateTagName function.

This commit is contained in:
antanst 2025-08-06 18:09:27 +03:00 committed by Antonis Anastasiadis
parent 1d4dcef1d1
commit ade694da4c
5 changed files with 38 additions and 128 deletions

View file

@ -2,40 +2,9 @@ const express = require('express');
const { Note, Tag, Project, sequelize } = require('../models');
const { Op } = require('sequelize');
const { extractUidFromSlug } = require('../utils/slug-utils');
const { validateTagName } = require('../utils/validation');
const router = express.Router();
// Helper function to validate tag name (same as in tags.js)
function validateTagName(name) {
if (!name || !name.trim()) {
return { valid: false, error: 'Tag name is required' };
}
const trimmedName = name.trim();
// Check for invalid characters that can break URLs or cause issues
const invalidChars = /[#%&{}\\<>*?/$!'":@+`|=]/;
if (invalidChars.test(trimmedName)) {
return {
valid: false,
error: 'Tag name contains invalid characters. Please avoid: # % & { } \\ < > * ? / $ ! \' " : @ + ` | =',
};
}
// Check length limits
if (trimmedName.length > 50) {
return {
valid: false,
error: 'Tag name must be 50 characters or less',
};
}
if (trimmedName.length < 1) {
return { valid: false, error: 'Tag name cannot be empty' };
}
return { valid: true, name: trimmedName };
}
// Helper function to update note tags
async function updateNoteTags(note, tagsArray, userId) {
if (!tagsArray || tagsArray.length === 0) {

View file

@ -7,40 +7,9 @@ const fs = require('fs');
const { Project, Task, Tag, Area, Note, sequelize } = require('../models');
const { Op } = require('sequelize');
const { extractUidFromSlug } = require('../utils/slug-utils');
const { validateTagName } = require('../utils/validation');
const router = express.Router();
// Helper function to validate tag name (same as in tags.js)
function validateTagName(name) {
if (!name || !name.trim()) {
return { valid: false, error: 'Tag name is required' };
}
const trimmedName = name.trim();
// Check for invalid characters that can break URLs or cause issues
const invalidChars = /[#%&{}\\<>*?/$!'":@+`|=]/;
if (invalidChars.test(trimmedName)) {
return {
valid: false,
error: 'Tag name contains invalid characters. Please avoid: # % & { } \\ < > * ? / $ ! \' " : @ + ` | =',
};
}
// Check length limits
if (trimmedName.length > 50) {
return {
valid: false,
error: 'Tag name must be 50 characters or less',
};
}
if (trimmedName.length < 1) {
return { valid: false, error: 'Tag name cannot be empty' };
}
return { valid: true, name: trimmedName };
}
// Helper function to safely format dates
const formatDate = (date) => {
if (!date) return null;

View file

@ -1,41 +1,10 @@
const express = require('express');
const { Tag, Task, Note, Project, sequelize } = require('../models');
const { extractUidFromSlug } = require('../utils/slug-utils');
const { validateTagName } = require('../utils/validation');
const router = express.Router();
const _ = require('lodash');
// Helper function to validate tag name
function validateTagName(name) {
if (!name || !name.trim()) {
return { valid: false, error: 'Tag name is required' };
}
const trimmedName = name.trim();
// Check for invalid characters that can break URLs or cause issues
const invalidChars = /[#%&{}\\<>*?/$!'":@+`|=]/;
if (invalidChars.test(trimmedName)) {
return {
valid: false,
error: 'Tag name contains invalid characters. Please avoid: # % & { } \\ < > * ? / $ ! \' " : @ + ` | =',
};
}
// Check length limits
if (trimmedName.length > 50) {
return {
valid: false,
error: 'Tag name must be 50 characters or less',
};
}
if (trimmedName.length < 1) {
return { valid: false, error: 'Tag name cannot be empty' };
}
return { valid: true, name: trimmedName };
}
// GET /api/tags
router.get('/tags', async (req, res) => {
try {

View file

@ -3,42 +3,11 @@ const { Task, Tag, Project, TaskEvent, sequelize } = require('../models');
const { Op } = require('sequelize');
const RecurringTaskService = require('../services/recurringTaskService');
const TaskEventService = require('../services/taskEventService');
const { validateTagName } = require('../utils/validation');
const moment = require('moment-timezone');
const _ = require('lodash');
const router = express.Router();
// Helper function to validate tag name (same as in tags.js)
function validateTagName(name) {
if (!name || !name.trim()) {
return { valid: false, error: 'Tag name is required' };
}
const trimmedName = name.trim();
// Check for invalid characters that can break URLs or cause issues
const invalidChars = /[#%&{}\\<>*?/$!'":@+`|=]/;
if (invalidChars.test(trimmedName)) {
return {
valid: false,
error: 'Tag name contains invalid characters. Please avoid: # % & { } \\ < > * ? / $ ! \' " : @ + ` | =',
};
}
// Check length limits
if (trimmedName.length > 50) {
return {
valid: false,
error: 'Tag name must be 50 characters or less',
};
}
if (trimmedName.length < 1) {
return { valid: false, error: 'Tag name cannot be empty' };
}
return { valid: true, name: trimmedName };
}
// Helper function to serialize task with today move count
async function serializeTask(task) {
const taskJson = task.toJSON();

View file

@ -0,0 +1,34 @@
function validateTagName(name) {
if (!name || !name.trim()) {
return { valid: false, error: 'Tag name is required' };
}
const trimmedName = name.trim();
// Check for invalid characters that can break URLs or cause issues
const invalidChars = /[#%&{}\\<>*?/$!'":@+`|=]/;
if (invalidChars.test(trimmedName)) {
return {
valid: false,
error: 'Tag name contains invalid characters. Please avoid: # % & { } \\ < > * ? / $ ! \' " : @ + ` | =',
};
}
// Check length limits
if (trimmedName.length > 50) {
return {
valid: false,
error: 'Tag name must be 50 characters or less',
};
}
if (trimmedName.length < 1) {
return { valid: false, error: 'Tag name cannot be empty' };
}
return { valid: true, name: trimmedName };
}
module.exports = {
validateTagName,
};