mirror of
				https://github.com/NodeBB/NodeBB.git
				synced 2025-10-31 11:05:54 +01:00 
			
		
		
		
	refactor: switch to using slugify module
This commit is contained in:
		| @@ -46,8 +46,8 @@ var web = module.exports; | |||||||
|  |  | ||||||
| var scripts = [ | var scripts = [ | ||||||
| 	'node_modules/jquery/dist/jquery.js', | 	'node_modules/jquery/dist/jquery.js', | ||||||
| 	'public/vendor/xregexp/xregexp.js', | 	'node_modules/xregexp/xregexp-all.js', | ||||||
| 	'public/vendor/xregexp/unicode/unicode-base.js', | 	'public/src/modules/slugify.js', | ||||||
| 	'public/src/utils.js', | 	'public/src/utils.js', | ||||||
| 	'public/src/installer/install.js', | 	'public/src/installer/install.js', | ||||||
| 	'node_modules/zxcvbn/dist/zxcvbn.js', | 	'node_modules/zxcvbn/dist/zxcvbn.js', | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
|  |  | ||||||
| define('admin/manage/users', [ | define('admin/manage/users', [ | ||||||
| 	'translator', 'benchpress', 'autocomplete', 'api', | 	'translator', 'benchpress', 'autocomplete', 'api', 'slugify', | ||||||
| ], function (translator, Benchpress, autocomplete, api) { | ], function (translator, Benchpress, autocomplete, api, slugify) { | ||||||
| 	var Users = {}; | 	var Users = {}; | ||||||
|  |  | ||||||
| 	Users.init = function () { | 	Users.init = function () { | ||||||
| @@ -110,7 +110,7 @@ define('admin/manage/users', [ | |||||||
| 						var groupCard = $(this).parents('[data-group-name]'); | 						var groupCard = $(this).parents('[data-group-name]'); | ||||||
| 						var groupName = groupCard.attr('data-group-name'); | 						var groupName = groupCard.attr('data-group-name'); | ||||||
| 						var uid = $(this).parents('[data-uid]').attr('data-uid'); | 						var uid = $(this).parents('[data-uid]').attr('data-uid'); | ||||||
| 						api.del('/groups/' + utils.slugify(groupName) + '/membership/' + uid, undefined, () => { | 						api.del('/groups/' + slugify(groupName) + '/membership/' + uid, undefined, () => { | ||||||
| 							groupCard.remove(); | 							groupCard.remove(); | ||||||
| 						}, 'default'); | 						}, 'default'); | ||||||
| 						return false; | 						return false; | ||||||
|   | |||||||
| @@ -1,6 +1,8 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
|  |  | ||||||
| define('forum/account/edit/username', ['forum/account/header', 'api'], function (header, api) { | define('forum/account/edit/username', [ | ||||||
|  | 	'forum/account/header', 'api', 'slugify', | ||||||
|  | ], function (header, api, slugify) { | ||||||
| 	var AccountEditUsername = {}; | 	var AccountEditUsername = {}; | ||||||
|  |  | ||||||
| 	AccountEditUsername.init = function () { | 	AccountEditUsername.init = function () { | ||||||
| @@ -26,7 +28,7 @@ define('forum/account/edit/username', ['forum/account/header', 'api'], function | |||||||
|  |  | ||||||
| 			api.put('/users/' + userData.uid, userData, (res) => { | 			api.put('/users/' + userData.uid, userData, (res) => { | ||||||
| 				btn.removeClass('disabled').find('i').addClass('hide'); | 				btn.removeClass('disabled').find('i').addClass('hide'); | ||||||
| 				var userslug = utils.slugify(userData.username); | 				var userslug = slugify(userData.username); | ||||||
| 				if (userData.username && userslug && parseInt(userData.uid, 10) === parseInt(app.user.uid, 10)) { | 				if (userData.username && userslug && parseInt(userData.uid, 10) === parseInt(app.user.uid, 10)) { | ||||||
| 					$('[component="header/profilelink"]').attr('href', config.relative_path + '/user/' + userslug); | 					$('[component="header/profilelink"]').attr('href', config.relative_path + '/user/' + userslug); | ||||||
| 					$('[component="header/profilelink/edit"]').attr('href', config.relative_path + '/user/' + userslug + '/edit'); | 					$('[component="header/profilelink/edit"]').attr('href', config.relative_path + '/user/' + userslug + '/edit'); | ||||||
|   | |||||||
| @@ -8,7 +8,8 @@ define('forum/groups/details', [ | |||||||
| 	'pictureCropper', | 	'pictureCropper', | ||||||
| 	'translator', | 	'translator', | ||||||
| 	'api', | 	'api', | ||||||
| ], function (memberList, iconSelect, components, coverPhoto, pictureCropper, translator, api) { | 	'slugify', | ||||||
|  | ], function (memberList, iconSelect, components, coverPhoto, pictureCropper, translator, api, slugify) { | ||||||
| 	var Details = {}; | 	var Details = {}; | ||||||
| 	var groupName; | 	var groupName; | ||||||
|  |  | ||||||
| @@ -208,7 +209,7 @@ define('forum/groups/details', [ | |||||||
| 				if (settings.name) { | 				if (settings.name) { | ||||||
| 					var pathname = window.location.pathname; | 					var pathname = window.location.pathname; | ||||||
| 					pathname = pathname.substr(1, pathname.lastIndexOf('/')); | 					pathname = pathname.substr(1, pathname.lastIndexOf('/')); | ||||||
| 					ajaxify.go(pathname + utils.slugify(settings.name)); | 					ajaxify.go(pathname + slugify(settings.name)); | ||||||
| 				} else { | 				} else { | ||||||
| 					ajaxify.refresh(); | 					ajaxify.refresh(); | ||||||
| 				} | 				} | ||||||
|   | |||||||
| @@ -1,7 +1,9 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
|  |  | ||||||
|  |  | ||||||
| define('forum/register', ['translator', 'zxcvbn', 'jquery-form'], function (translator, zxcvbn) { | define('forum/register', [ | ||||||
|  | 	'translator', 'zxcvbn', 'slugify', 'jquery-form', | ||||||
|  | ], function (translator, zxcvbn, slugify) { | ||||||
| 	var Register = {}; | 	var Register = {}; | ||||||
| 	var validationError = false; | 	var validationError = false; | ||||||
| 	var successIcon = ''; | 	var successIcon = ''; | ||||||
| @@ -32,7 +34,7 @@ define('forum/register', ['translator', 'zxcvbn', 'jquery-form'], function (tran | |||||||
|  |  | ||||||
| 		// Update the "others can mention you via" text | 		// Update the "others can mention you via" text | ||||||
| 		username.on('keyup', function () { | 		username.on('keyup', function () { | ||||||
| 			$('#yourUsername').text(this.value.length > 0 ? utils.slugify(this.value) : 'username'); | 			$('#yourUsername').text(this.value.length > 0 ? slugify(this.value) : 'username'); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		username.on('blur', function () { | 		username.on('blur', function () { | ||||||
| @@ -154,7 +156,7 @@ define('forum/register', ['translator', 'zxcvbn', 'jquery-form'], function (tran | |||||||
| 			showError(username_notify, '[[error:username-too-short]]'); | 			showError(username_notify, '[[error:username-too-short]]'); | ||||||
| 		} else if (username.length > ajaxify.data.maximumUsernameLength) { | 		} else if (username.length > ajaxify.data.maximumUsernameLength) { | ||||||
| 			showError(username_notify, '[[error:username-too-long]]'); | 			showError(username_notify, '[[error:username-too-long]]'); | ||||||
| 		} else if (!utils.isUserNameValid(username) || !utils.slugify(username)) { | 		} else if (!utils.isUserNameValid(username) || !slugify(username)) { | ||||||
| 			showError(username_notify, '[[error:invalid-username]]'); | 			showError(username_notify, '[[error:invalid-username]]'); | ||||||
| 		} else { | 		} else { | ||||||
| 			socket.emit('user.exists', { | 			socket.emit('user.exists', { | ||||||
|   | |||||||
| @@ -355,7 +355,14 @@ define('forum/topic/postTools', [ | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if (post.length) { | 		if (post.length) { | ||||||
| 			slug = utils.slugify(post.attr('data-username'), true); | 			slug = post.attr('data-userslug'); | ||||||
|  | 			if (!slug) { | ||||||
|  | 				if (post.attr('data-uid') !== '0') { | ||||||
|  | 					slug = '[[global:former_user]]'; | ||||||
|  | 				} else { | ||||||
|  | 					slug = '[[global:guest]]'; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 		if (post.length && post.attr('data-uid') !== '0') { | 		if (post.length && post.attr('data-uid') !== '0') { | ||||||
| 			slug = '@' + slug; | 			slug = '@' + slug; | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
|  |  | ||||||
| /* global zxcvbn */ | /* global zxcvbn, slugify */ | ||||||
|  |  | ||||||
| $('document').ready(function () { | $('document').ready(function () { | ||||||
| 	setupInputs(); | 	setupInputs(); | ||||||
| @@ -61,7 +61,7 @@ $('document').ready(function () { | |||||||
| 		var help = parent.children('.help-text'); | 		var help = parent.children('.help-text'); | ||||||
|  |  | ||||||
| 		function validateUsername(field) { | 		function validateUsername(field) { | ||||||
| 			if (!utils.isUserNameValid(field) || !utils.slugify(field)) { | 			if (!utils.isUserNameValid(field) || !slugify(field)) { | ||||||
| 				parent.addClass('error'); | 				parent.addClass('error'); | ||||||
| 				help.html('Invalid Username.'); | 				help.html('Invalid Username.'); | ||||||
| 			} else { | 			} else { | ||||||
|   | |||||||
| @@ -1,10 +1,13 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
|  |  | ||||||
|  | /* global XRegExp */ | ||||||
| (function (factory) { | (function (factory) { | ||||||
| 	if (typeof module === 'object' && module.exports) { | 	if (typeof define === 'function' && define.amd) { | ||||||
|  | 		define('slugify', ['xregexp'], factory); | ||||||
|  | 	} else if (typeof exports === 'object') { | ||||||
| 		module.exports = factory(require('xregexp')); | 		module.exports = factory(require('xregexp')); | ||||||
| 	} else { | 	} else { | ||||||
| 		define('slugify', ['xregexp'], factory); | 		window.slugify = factory(XRegExp); | ||||||
| 	} | 	} | ||||||
| }(function (XRegExp) { | }(function (XRegExp) { | ||||||
| 	var invalidUnicodeChars = XRegExp('[^\\p{L}\\s\\d\\-_]', 'g'); | 	var invalidUnicodeChars = XRegExp('[^\\p{L}\\s\\d\\-_]', 'g'); | ||||||
|   | |||||||
| @@ -7,6 +7,7 @@ const db = require('../database'); | |||||||
| const plugins = require('../plugins'); | const plugins = require('../plugins'); | ||||||
| const privileges = require('../privileges'); | const privileges = require('../privileges'); | ||||||
| const utils = require('../utils'); | const utils = require('../utils'); | ||||||
|  | const slugify = require('../slugify'); | ||||||
| const cache = require('../cache'); | const cache = require('../cache'); | ||||||
|  |  | ||||||
| module.exports = function (Categories) { | module.exports = function (Categories) { | ||||||
| @@ -15,7 +16,7 @@ module.exports = function (Categories) { | |||||||
| 		const cid = await db.incrObjectField('global', 'nextCid'); | 		const cid = await db.incrObjectField('global', 'nextCid'); | ||||||
|  |  | ||||||
| 		data.name = data.name || 'Category ' + cid; | 		data.name = data.name || 'Category ' + cid; | ||||||
| 		const slug = cid + '/' + utils.slugify(data.name); | 		const slug = cid + '/' + slugify(data.name); | ||||||
| 		const order = data.order || cid;	// If no order provided, place it at the end | 		const order = data.order || cid;	// If no order provided, place it at the end | ||||||
| 		const colours = Categories.assignColours(); | 		const colours = Categories.assignColours(); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ const async = require('async'); | |||||||
| const db = require('../database'); | const db = require('../database'); | ||||||
| const meta = require('../meta'); | const meta = require('../meta'); | ||||||
| const utils = require('../utils'); | const utils = require('../utils'); | ||||||
|  | const slugify = require('../slugify'); | ||||||
| const translator = require('../translator'); | const translator = require('../translator'); | ||||||
| const plugins = require('../plugins'); | const plugins = require('../plugins'); | ||||||
| const cache = require('../cache'); | const cache = require('../cache'); | ||||||
| @@ -24,7 +25,7 @@ module.exports = function (Categories) { | |||||||
|  |  | ||||||
| 		if (modifiedFields.hasOwnProperty('name')) { | 		if (modifiedFields.hasOwnProperty('name')) { | ||||||
| 			const translated = await translator.translate(modifiedFields.name); | 			const translated = await translator.translate(modifiedFields.name); | ||||||
| 			modifiedFields.slug = cid + '/' + utils.slugify(translated); | 			modifiedFields.slug = cid + '/' + slugify(translated); | ||||||
| 		} | 		} | ||||||
| 		const result = await plugins.fireHook('filter:category.update', { cid: cid, category: modifiedFields }); | 		const result = await plugins.fireHook('filter:category.update', { cid: cid, category: modifiedFields }); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -13,6 +13,7 @@ const meta = require('../meta'); | |||||||
| const user = require('../user'); | const user = require('../user'); | ||||||
| const plugins = require('../plugins'); | const plugins = require('../plugins'); | ||||||
| const utils = require('../utils'); | const utils = require('../utils'); | ||||||
|  | const slugify = require('../slugify'); | ||||||
| const translator = require('../translator'); | const translator = require('../translator'); | ||||||
| const helpers = require('./helpers'); | const helpers = require('./helpers'); | ||||||
| const privileges = require('../privileges'); | const privileges = require('../privileges'); | ||||||
| @@ -81,7 +82,7 @@ authenticationController.register = async function (req, res) { | |||||||
| 			throw new Error('[[error:invalid-email]]'); | 			throw new Error('[[error:invalid-email]]'); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if (!userData.username || userData.username.length < meta.config.minimumUsernameLength || utils.slugify(userData.username).length < meta.config.minimumUsernameLength) { | 		if (!userData.username || userData.username.length < meta.config.minimumUsernameLength || slugify(userData.username).length < meta.config.minimumUsernameLength) { | ||||||
| 			throw new Error('[[error:username-too-short]]'); | 			throw new Error('[[error:username-too-short]]'); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @@ -356,7 +357,7 @@ authenticationController.localLogin = async function (req, username, password, n | |||||||
| 		return next(new Error('[[error:password-too-long]]')); | 		return next(new Error('[[error:password-too-long]]')); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	const userslug = utils.slugify(username); | 	const userslug = slugify(username); | ||||||
| 	const uid = await user.getUidByUserslug(userslug); | 	const uid = await user.getUidByUserslug(userslug); | ||||||
| 	try { | 	try { | ||||||
| 		const [userData, isAdminOrGlobalMod, banned, hasLoginPrivilege] = await Promise.all([ | 		const [userData, isAdminOrGlobalMod, banned, hasLoginPrivilege] = await Promise.all([ | ||||||
|   | |||||||
| @@ -6,7 +6,7 @@ const user = require('../../user'); | |||||||
| const groups = require('../../groups'); | const groups = require('../../groups'); | ||||||
| const events = require('../../events'); | const events = require('../../events'); | ||||||
| const meta = require('../../meta'); | const meta = require('../../meta'); | ||||||
| const utils = require('../../utils'); | const slugify = require('../../slugify'); | ||||||
| const notifications = require('../../notifications'); | const notifications = require('../../notifications'); | ||||||
|  |  | ||||||
| const helpers = require('../helpers'); | const helpers = require('../helpers'); | ||||||
| @@ -114,7 +114,7 @@ Groups.leave = async (req, res) => { | |||||||
| 		type: 'group-leave', | 		type: 'group-leave', | ||||||
| 		bodyShort: '[[groups:membership.leave.notification-title, ' + username + ', ' + group.name + ']]', | 		bodyShort: '[[groups:membership.leave.notification-title, ' + username + ', ' + group.name + ']]', | ||||||
| 		nid: 'group:' + validator.escape(group.name) + ':uid:' + req.params.uid + ':group-leave', | 		nid: 'group:' + validator.escape(group.name) + ':uid:' + req.params.uid + ':group-leave', | ||||||
| 		path: '/groups/' + utils.slugify(group.name), | 		path: '/groups/' + slugify(group.name), | ||||||
| 	}); | 	}); | ||||||
| 	const uids = await groups.getOwners(group.name); | 	const uids = await groups.getOwners(group.name); | ||||||
| 	await notifications.push(notification, uids); | 	await notifications.push(notification, uids); | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ const mkdirp = require('mkdirp'); | |||||||
| const mime = require('mime'); | const mime = require('mime'); | ||||||
| const graceful = require('graceful-fs'); | const graceful = require('graceful-fs'); | ||||||
|  |  | ||||||
| const utils = require('./utils'); | const slugify = require('./slugify'); | ||||||
|  |  | ||||||
| graceful.gracefulify(fs); | graceful.gracefulify(fs); | ||||||
|  |  | ||||||
| @@ -18,7 +18,7 @@ file.saveFileToLocal = async function (filename, folder, tempPath) { | |||||||
| 	/* | 	/* | ||||||
| 	 * remarkable doesn't allow spaces in hyperlinks, once that's fixed, remove this. | 	 * remarkable doesn't allow spaces in hyperlinks, once that's fixed, remove this. | ||||||
| 	 */ | 	 */ | ||||||
| 	filename = filename.split('.').map(name => utils.slugify(name)).join('.'); | 	filename = filename.split('.').map(name => slugify(name)).join('.'); | ||||||
|  |  | ||||||
| 	const uploadPath = path.join(nconf.get('upload_path'), folder, filename); | 	const uploadPath = path.join(nconf.get('upload_path'), folder, filename); | ||||||
| 	if (!uploadPath.startsWith(nconf.get('upload_path'))) { | 	if (!uploadPath.startsWith(nconf.get('upload_path'))) { | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ | |||||||
|  |  | ||||||
| const meta = require('../meta'); | const meta = require('../meta'); | ||||||
| const plugins = require('../plugins'); | const plugins = require('../plugins'); | ||||||
| const utils = require('../utils'); | const slugify = require('../slugify'); | ||||||
| const db = require('../database'); | const db = require('../database'); | ||||||
|  |  | ||||||
| module.exports = function (Groups) { | module.exports = function (Groups) { | ||||||
| @@ -27,7 +27,7 @@ module.exports = function (Groups) { | |||||||
| 		const isPrivate = data.hasOwnProperty('private') && data.private !== undefined ? parseInt(data.private, 10) === 1 : true; | 		const isPrivate = data.hasOwnProperty('private') && data.private !== undefined ? parseInt(data.private, 10) === 1 : true; | ||||||
| 		let groupData = { | 		let groupData = { | ||||||
| 			name: data.name, | 			name: data.name, | ||||||
| 			slug: utils.slugify(data.name), | 			slug: slugify(data.name), | ||||||
| 			createtime: timestamp, | 			createtime: timestamp, | ||||||
| 			userTitle: data.userTitle || data.name, | 			userTitle: data.userTitle || data.name, | ||||||
| 			userTitleEnabled: parseInt(data.userTitleEnabled, 10) === 1 ? 1 : 0, | 			userTitleEnabled: parseInt(data.userTitleEnabled, 10) === 1 ? 1 : 0, | ||||||
| @@ -88,7 +88,7 @@ module.exports = function (Groups) { | |||||||
| 			throw new Error('[[error:invalid-group-name]]'); | 			throw new Error('[[error:invalid-group-name]]'); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if (name.includes('/') || !utils.slugify(name)) { | 		if (name.includes('/') || !slugify(name)) { | ||||||
| 			throw new Error('[[error:invalid-group-name]]'); | 			throw new Error('[[error:invalid-group-name]]'); | ||||||
| 		} | 		} | ||||||
| 	}; | 	}; | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
|  |  | ||||||
| const plugins = require('../plugins'); | const plugins = require('../plugins'); | ||||||
| const utils = require('../utils'); | const slugify = require('../slugify'); | ||||||
| const db = require('../database'); | const db = require('../database'); | ||||||
| const batch = require('../batch'); | const batch = require('../batch'); | ||||||
|  |  | ||||||
| @@ -27,7 +27,7 @@ module.exports = function (Groups) { | |||||||
| 			); | 			); | ||||||
| 		}); | 		}); | ||||||
| 		const sets = groupNames.map(groupName => groupName.toLowerCase() + ':' + groupName); | 		const sets = groupNames.map(groupName => groupName.toLowerCase() + ':' + groupName); | ||||||
| 		const fields = groupNames.map(groupName => utils.slugify(groupName)); | 		const fields = groupNames.map(groupName => slugify(groupName)); | ||||||
|  |  | ||||||
| 		await Promise.all([ | 		await Promise.all([ | ||||||
| 			db.deleteAll(keys), | 			db.deleteAll(keys), | ||||||
|   | |||||||
| @@ -3,7 +3,7 @@ | |||||||
| const user = require('../user'); | const user = require('../user'); | ||||||
| const db = require('../database'); | const db = require('../database'); | ||||||
| const plugins = require('../plugins'); | const plugins = require('../plugins'); | ||||||
| const utils = require('../utils'); | const slugify = require('../slugify'); | ||||||
|  |  | ||||||
| const Groups = module.exports; | const Groups = module.exports; | ||||||
|  |  | ||||||
| @@ -28,7 +28,7 @@ Groups.ephemeralGroups = ['guests', 'spiders']; | |||||||
| Groups.getEphemeralGroup = function (groupName) { | Groups.getEphemeralGroup = function (groupName) { | ||||||
| 	return { | 	return { | ||||||
| 		name: groupName, | 		name: groupName, | ||||||
| 		slug: utils.slugify(groupName), | 		slug: slugify(groupName), | ||||||
| 		description: '', | 		description: '', | ||||||
| 		deleted: '0', | 		deleted: '0', | ||||||
| 		hidden: '0', | 		hidden: '0', | ||||||
| @@ -217,12 +217,12 @@ async function isFieldOn(groupName, field) { | |||||||
|  |  | ||||||
| Groups.exists = async function (name) { | Groups.exists = async function (name) { | ||||||
| 	if (Array.isArray(name)) { | 	if (Array.isArray(name)) { | ||||||
| 		const slugs = name.map(groupName => utils.slugify(groupName)); | 		const slugs = name.map(groupName => slugify(groupName)); | ||||||
| 		const isMembersOfRealGroups = await db.isSortedSetMembers('groups:createtime', name); | 		const isMembersOfRealGroups = await db.isSortedSetMembers('groups:createtime', name); | ||||||
| 		const isMembersOfEphemeralGroups = slugs.map(slug => Groups.ephemeralGroups.includes(slug)); | 		const isMembersOfEphemeralGroups = slugs.map(slug => Groups.ephemeralGroups.includes(slug)); | ||||||
| 		return name.map((n, index) => isMembersOfRealGroups[index] || isMembersOfEphemeralGroups[index]); | 		return name.map((n, index) => isMembersOfRealGroups[index] || isMembersOfEphemeralGroups[index]); | ||||||
| 	} | 	} | ||||||
| 	const slug = utils.slugify(name); | 	const slug = slugify(name); | ||||||
| 	const isMemberOfRealGroups = await db.isSortedSetMember('groups:createtime', name); | 	const isMemberOfRealGroups = await db.isSortedSetMember('groups:createtime', name); | ||||||
| 	const isMemberOfEphemeralGroups = Groups.ephemeralGroups.includes(slug); | 	const isMemberOfEphemeralGroups = Groups.ephemeralGroups.includes(slug); | ||||||
| 	return isMemberOfRealGroups || isMemberOfEphemeralGroups; | 	return isMemberOfRealGroups || isMemberOfEphemeralGroups; | ||||||
|   | |||||||
| @@ -4,7 +4,7 @@ const _ = require('lodash'); | |||||||
|  |  | ||||||
| const db = require('../database'); | const db = require('../database'); | ||||||
| const user = require('../user'); | const user = require('../user'); | ||||||
| const utils = require('../utils'); | const slugify = require('../slugify'); | ||||||
| const plugins = require('../plugins'); | const plugins = require('../plugins'); | ||||||
| const notifications = require('../notifications'); | const notifications = require('../notifications'); | ||||||
|  |  | ||||||
| @@ -18,7 +18,7 @@ module.exports = function (Groups) { | |||||||
| 				bodyShort: '[[groups:request.notification_title, ' + username + ']]', | 				bodyShort: '[[groups:request.notification_title, ' + username + ']]', | ||||||
| 				bodyLong: '[[groups:request.notification_text, ' + username + ', ' + groupName + ']]', | 				bodyLong: '[[groups:request.notification_text, ' + username + ', ' + groupName + ']]', | ||||||
| 				nid: 'group:' + groupName + ':uid:' + uid + ':request', | 				nid: 'group:' + groupName + ':uid:' + uid + ':request', | ||||||
| 				path: '/groups/' + utils.slugify(groupName), | 				path: '/groups/' + slugify(groupName), | ||||||
| 				from: uid, | 				from: uid, | ||||||
| 			}), | 			}), | ||||||
| 			Groups.getOwners(groupName), | 			Groups.getOwners(groupName), | ||||||
| @@ -35,7 +35,7 @@ module.exports = function (Groups) { | |||||||
| 			type: 'group-invite', | 			type: 'group-invite', | ||||||
| 			bodyShort: '[[groups:membership.accept.notification_title, ' + groupName + ']]', | 			bodyShort: '[[groups:membership.accept.notification_title, ' + groupName + ']]', | ||||||
| 			nid: 'group:' + groupName + ':uid:' + uid + ':invite-accepted', | 			nid: 'group:' + groupName + ':uid:' + uid + ':invite-accepted', | ||||||
| 			path: '/groups/' + utils.slugify(groupName), | 			path: '/groups/' + slugify(groupName), | ||||||
| 		}); | 		}); | ||||||
| 		await notifications.push(notification, [uid]); | 		await notifications.push(notification, [uid]); | ||||||
| 	}; | 	}; | ||||||
| @@ -58,7 +58,7 @@ module.exports = function (Groups) { | |||||||
| 			bodyShort: '[[groups:invited.notification_title, ' + groupName + ']]', | 			bodyShort: '[[groups:invited.notification_title, ' + groupName + ']]', | ||||||
| 			bodyLong: '', | 			bodyLong: '', | ||||||
| 			nid: 'group:' + groupName + ':uid:' + uid + ':invite', | 			nid: 'group:' + groupName + ':uid:' + uid + ':invite', | ||||||
| 			path: '/groups/' + utils.slugify(groupName), | 			path: '/groups/' + slugify(groupName), | ||||||
| 		}))); | 		}))); | ||||||
|  |  | ||||||
| 		await Promise.all(uids.map((uid, index) => notifications.push(notificationData[index], uid))); | 		await Promise.all(uids.map((uid, index) => notifications.push(notificationData[index], uid))); | ||||||
|   | |||||||
| @@ -3,7 +3,7 @@ | |||||||
| const winston = require('winston'); | const winston = require('winston'); | ||||||
|  |  | ||||||
| const plugins = require('../plugins'); | const plugins = require('../plugins'); | ||||||
| const utils = require('../utils'); | const slugify = require('../slugify'); | ||||||
| const db = require('../database'); | const db = require('../database'); | ||||||
| const user = require('../user'); | const user = require('../user'); | ||||||
| const batch = require('../batch'); | const batch = require('../batch'); | ||||||
| @@ -132,8 +132,8 @@ module.exports = function (Groups) { | |||||||
| 		if (Groups.isPrivilegeGroup(newName)) { | 		if (Groups.isPrivilegeGroup(newName)) { | ||||||
| 			throw new Error('[[error:invalid-group-name]]'); | 			throw new Error('[[error:invalid-group-name]]'); | ||||||
| 		} | 		} | ||||||
| 		const currentSlug = utils.slugify(currentName); | 		const currentSlug = slugify(currentName); | ||||||
| 		const newSlug = utils.slugify(newName); | 		const newSlug = slugify(newName); | ||||||
| 		if (currentName === newName || currentSlug === newSlug) { | 		if (currentName === newName || currentSlug === newSlug) { | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
| @@ -174,9 +174,9 @@ module.exports = function (Groups) { | |||||||
| 		await updateNavigationItems(oldName, newName); | 		await updateNavigationItems(oldName, newName); | ||||||
| 		await updateWidgets(oldName, newName); | 		await updateWidgets(oldName, newName); | ||||||
| 		await updateConfig(oldName, newName); | 		await updateConfig(oldName, newName); | ||||||
| 		await db.setObject('group:' + oldName, { name: newName, slug: utils.slugify(newName) }); | 		await db.setObject('group:' + oldName, { name: newName, slug: slugify(newName) }); | ||||||
| 		await db.deleteObjectField('groupslug:groupname', group.slug); | 		await db.deleteObjectField('groupslug:groupname', group.slug); | ||||||
| 		await db.setObjectField('groupslug:groupname', utils.slugify(newName), newName); | 		await db.setObjectField('groupslug:groupname', slugify(newName), newName); | ||||||
|  |  | ||||||
| 		const allGroups = await db.getSortedSetRange('groups:createtime', 0, -1); | 		const allGroups = await db.getSortedSetRange('groups:createtime', 0, -1); | ||||||
| 		const keys = allGroups.map(group => 'group:' + group + ':members'); | 		const keys = allGroups.map(group => 'group:' + group + ':members'); | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ const os = require('os'); | |||||||
| const nconf = require('nconf'); | const nconf = require('nconf'); | ||||||
|  |  | ||||||
| const pubsub = require('../pubsub'); | const pubsub = require('../pubsub'); | ||||||
| const utils = require('../utils'); | const slugify = require('../slugify'); | ||||||
|  |  | ||||||
| const Meta = module.exports; | const Meta = module.exports; | ||||||
|  |  | ||||||
| @@ -29,7 +29,7 @@ Meta.languages = require('./languages'); | |||||||
| Meta.userOrGroupExists = async function (slug) { | Meta.userOrGroupExists = async function (slug) { | ||||||
| 	const user = require('../user'); | 	const user = require('../user'); | ||||||
| 	const groups = require('../groups'); | 	const groups = require('../groups'); | ||||||
| 	slug = utils.slugify(slug); | 	slug = slugify(slug); | ||||||
| 	const [userExists, groupExists] = await Promise.all([ | 	const [userExists, groupExists] = await Promise.all([ | ||||||
| 		user.existsBySlug(slug), | 		user.existsBySlug(slug), | ||||||
| 		groups.existsBySlug(slug), | 		groups.existsBySlug(slug), | ||||||
|   | |||||||
| @@ -37,8 +37,10 @@ JS.scripts = { | |||||||
| 		'node_modules/jquery-serializeobject/jquery.serializeObject.js', | 		'node_modules/jquery-serializeobject/jquery.serializeObject.js', | ||||||
|  |  | ||||||
| 		'public/vendor/bootbox/wrapper.js', | 		'public/vendor/bootbox/wrapper.js', | ||||||
|  | 		// TODO: remove xregexp on 1.16.0, it is loaded via require | ||||||
| 		'public/vendor/xregexp/xregexp.js', | 		'public/vendor/xregexp/xregexp.js', | ||||||
| 		'public/vendor/xregexp/unicode/unicode-base.js', | 		'public/vendor/xregexp/unicode/unicode-base.js', | ||||||
|  |  | ||||||
| 		'public/src/utils.js', | 		'public/src/utils.js', | ||||||
| 		'public/src/sockets.js', | 		'public/src/sockets.js', | ||||||
| 		'public/src/app.js', | 		'public/src/app.js', | ||||||
|   | |||||||
| @@ -10,6 +10,7 @@ const meta = require('../meta'); | |||||||
| const translator = require('../translator'); | const translator = require('../translator'); | ||||||
| const widgets = require('../widgets'); | const widgets = require('../widgets'); | ||||||
| const utils = require('../utils'); | const utils = require('../utils'); | ||||||
|  | const slugify = require('../slugify'); | ||||||
|  |  | ||||||
| module.exports = function (middleware) { | module.exports = function (middleware) { | ||||||
| 	middleware.processRender = function processRender(req, res, next) { | 	middleware.processRender = function processRender(req, res, next) { | ||||||
| @@ -111,7 +112,7 @@ module.exports = function (middleware) { | |||||||
| 		const parts = clean.split('/').slice(0, 3); | 		const parts = clean.split('/').slice(0, 3); | ||||||
| 		parts.forEach(function (p, index) { | 		parts.forEach(function (p, index) { | ||||||
| 			try { | 			try { | ||||||
| 				p = utils.slugify(decodeURIComponent(p)); | 				p = slugify(decodeURIComponent(p)); | ||||||
| 			} catch (err) { | 			} catch (err) { | ||||||
| 				winston.error(err.stack); | 				winston.error(err.stack); | ||||||
| 				p = ''; | 				p = ''; | ||||||
| @@ -122,7 +123,7 @@ module.exports = function (middleware) { | |||||||
|  |  | ||||||
| 		if (templateData.template.topic) { | 		if (templateData.template.topic) { | ||||||
| 			parts.push('page-topic-category-' + templateData.category.cid); | 			parts.push('page-topic-category-' + templateData.category.cid); | ||||||
| 			parts.push('page-topic-category-' + utils.slugify(templateData.category.name)); | 			parts.push('page-topic-category-' + slugify(templateData.category.name)); | ||||||
| 		} | 		} | ||||||
| 		if (templateData.breadcrumbs) { | 		if (templateData.breadcrumbs) { | ||||||
| 			templateData.breadcrumbs.forEach(function (crumb) { | 			templateData.breadcrumbs.forEach(function (crumb) { | ||||||
|   | |||||||
| @@ -11,6 +11,7 @@ const privileges = require('../privileges'); | |||||||
| const plugins = require('../plugins'); | const plugins = require('../plugins'); | ||||||
| const pubsub = require('../pubsub'); | const pubsub = require('../pubsub'); | ||||||
| const utils = require('../utils'); | const utils = require('../utils'); | ||||||
|  | const slugify = require('../slugify'); | ||||||
| const translator = require('../translator'); | const translator = require('../translator'); | ||||||
|  |  | ||||||
| module.exports = function (Posts) { | module.exports = function (Posts) { | ||||||
| @@ -114,7 +115,7 @@ module.exports = function (Posts) { | |||||||
| 		}; | 		}; | ||||||
| 		if (title) { | 		if (title) { | ||||||
| 			newTopicData.title = title; | 			newTopicData.title = title; | ||||||
| 			newTopicData.slug = tid + '/' + (utils.slugify(title) || 'topic'); | 			newTopicData.slug = tid + '/' + (slugify(title) || 'topic'); | ||||||
| 		} | 		} | ||||||
| 		newTopicData.thumb = data.thumb || ''; | 		newTopicData.thumb = data.thumb || ''; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ const groups = require('../groups'); | |||||||
| const meta = require('../meta'); | const meta = require('../meta'); | ||||||
| const user = require('../user'); | const user = require('../user'); | ||||||
| const utils = require('../utils'); | const utils = require('../utils'); | ||||||
|  | const slugify = require('../slugify'); | ||||||
| const events = require('../events'); | const events = require('../events'); | ||||||
| const privileges = require('../privileges'); | const privileges = require('../privileges'); | ||||||
| const notifications = require('../notifications'); | const notifications = require('../notifications'); | ||||||
| @@ -94,7 +95,7 @@ SocketGroups.leave = async (socket, data) => { | |||||||
| 		type: 'group-leave', | 		type: 'group-leave', | ||||||
| 		bodyShort: '[[groups:membership.leave.notification_title, ' + username + ', ' + data.groupName + ']]', | 		bodyShort: '[[groups:membership.leave.notification_title, ' + username + ', ' + data.groupName + ']]', | ||||||
| 		nid: 'group:' + validator.escape(data.groupName) + ':uid:' + socket.uid + ':group-leave', | 		nid: 'group:' + validator.escape(data.groupName) + ':uid:' + socket.uid + ':group-leave', | ||||||
| 		path: '/groups/' + utils.slugify(data.groupName), | 		path: '/groups/' + slugify(data.groupName), | ||||||
| 	}); | 	}); | ||||||
| 	const uids = await groups.getOwners(data.groupName); | 	const uids = await groups.getOwners(data.groupName); | ||||||
| 	await notifications.push(notification, uids); | 	await notifications.push(notification, uids); | ||||||
|   | |||||||
| @@ -6,6 +6,7 @@ const validator = require('validator'); | |||||||
|  |  | ||||||
| const db = require('../database'); | const db = require('../database'); | ||||||
| const utils = require('../utils'); | const utils = require('../utils'); | ||||||
|  | const slugify = require('../slugify'); | ||||||
| const plugins = require('../plugins'); | const plugins = require('../plugins'); | ||||||
| const analytics = require('../analytics'); | const analytics = require('../analytics'); | ||||||
| const user = require('../user'); | const user = require('../user'); | ||||||
| @@ -29,7 +30,7 @@ module.exports = function (Topics) { | |||||||
| 			cid: data.cid, | 			cid: data.cid, | ||||||
| 			mainPid: 0, | 			mainPid: 0, | ||||||
| 			title: data.title, | 			title: data.title, | ||||||
| 			slug: tid + '/' + (utils.slugify(data.title) || 'topic'), | 			slug: tid + '/' + (slugify(data.title) || 'topic'), | ||||||
| 			timestamp: timestamp, | 			timestamp: timestamp, | ||||||
| 			lastposttime: 0, | 			lastposttime: 0, | ||||||
| 			postcount: 0, | 			postcount: 0, | ||||||
| @@ -261,7 +262,7 @@ module.exports = function (Topics) { | |||||||
| 			if (data.handle.length > meta.config.maximumUsernameLength) { | 			if (data.handle.length > meta.config.maximumUsernameLength) { | ||||||
| 				throw new Error('[[error:guest-handle-invalid]]'); | 				throw new Error('[[error:guest-handle-invalid]]'); | ||||||
| 			} | 			} | ||||||
| 			const exists = await user.existsBySlug(utils.slugify(data.handle)); | 			const exists = await user.existsBySlug(slugify(data.handle)); | ||||||
| 			if (exists) { | 			if (exists) { | ||||||
| 				throw new Error('[[error:username-taken]]'); | 				throw new Error('[[error:username-taken]]'); | ||||||
| 			} | 			} | ||||||
|   | |||||||
| @@ -9,12 +9,13 @@ const emailer = require('../emailer'); | |||||||
| const notifications = require('../notifications'); | const notifications = require('../notifications'); | ||||||
| const groups = require('../groups'); | const groups = require('../groups'); | ||||||
| const utils = require('../utils'); | const utils = require('../utils'); | ||||||
|  | const slugify = require('../slugify'); | ||||||
| const plugins = require('../plugins'); | const plugins = require('../plugins'); | ||||||
|  |  | ||||||
| module.exports = function (User) { | module.exports = function (User) { | ||||||
| 	User.addToApprovalQueue = async function (userData) { | 	User.addToApprovalQueue = async function (userData) { | ||||||
| 		userData.username = userData.username.trim(); | 		userData.username = userData.username.trim(); | ||||||
| 		userData.userslug = utils.slugify(userData.username); | 		userData.userslug = slugify(userData.username); | ||||||
| 		await canQueue(userData); | 		await canQueue(userData); | ||||||
| 		const hashedPassword = await User.hashPassword(userData.password); | 		const hashedPassword = await User.hashPassword(userData.password); | ||||||
| 		const data = { | 		const data = { | ||||||
|   | |||||||
| @@ -3,6 +3,7 @@ | |||||||
| const zxcvbn = require('zxcvbn'); | const zxcvbn = require('zxcvbn'); | ||||||
| const db = require('../database'); | const db = require('../database'); | ||||||
| const utils = require('../utils'); | const utils = require('../utils'); | ||||||
|  | const slugify = require('../slugify'); | ||||||
| const plugins = require('../plugins'); | const plugins = require('../plugins'); | ||||||
| const groups = require('../groups'); | const groups = require('../groups'); | ||||||
| const meta = require('../meta'); | const meta = require('../meta'); | ||||||
| @@ -10,7 +11,7 @@ const meta = require('../meta'); | |||||||
| module.exports = function (User) { | module.exports = function (User) { | ||||||
| 	User.create = async function (data) { | 	User.create = async function (data) { | ||||||
| 		data.username = data.username.trim(); | 		data.username = data.username.trim(); | ||||||
| 		data.userslug = utils.slugify(data.username); | 		data.userslug = slugify(data.username); | ||||||
| 		if (data.email !== undefined) { | 		if (data.email !== undefined) { | ||||||
| 			data.email = String(data.email).trim(); | 			data.email = String(data.email).trim(); | ||||||
| 		} | 		} | ||||||
| @@ -63,7 +64,7 @@ module.exports = function (User) { | |||||||
| 		const userNameChanged = !!renamedUsername; | 		const userNameChanged = !!renamedUsername; | ||||||
| 		if (userNameChanged) { | 		if (userNameChanged) { | ||||||
| 			userData.username = renamedUsername; | 			userData.username = renamedUsername; | ||||||
| 			userData.userslug = utils.slugify(renamedUsername); | 			userData.userslug = slugify(renamedUsername); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		const results = await plugins.fireHook('filter:user.create', { user: userData, data: data }); | 		const results = await plugins.fireHook('filter:user.create', { user: userData, data: data }); | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ const async = require('async'); | |||||||
| const validator = require('validator'); | const validator = require('validator'); | ||||||
|  |  | ||||||
| const utils = require('../utils'); | const utils = require('../utils'); | ||||||
|  | const slugify = require('../slugify'); | ||||||
| const meta = require('../meta'); | const meta = require('../meta'); | ||||||
| const db = require('../database'); | const db = require('../database'); | ||||||
| const groups = require('../groups'); | const groups = require('../groups'); | ||||||
| @@ -113,7 +114,7 @@ module.exports = function (User) { | |||||||
| 			throw new Error('[[error:username-too-long]]'); | 			throw new Error('[[error:username-too-long]]'); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		const userslug = utils.slugify(data.username); | 		const userslug = slugify(data.username); | ||||||
| 		if (!utils.isUserNameValid(data.username) || !userslug) { | 		if (!utils.isUserNameValid(data.username) || !userslug) { | ||||||
| 			throw new Error('[[error:invalid-username]]'); | 			throw new Error('[[error:invalid-username]]'); | ||||||
| 		} | 		} | ||||||
| @@ -256,7 +257,7 @@ module.exports = function (User) { | |||||||
| 		if (userData.username === newUsername) { | 		if (userData.username === newUsername) { | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
| 		const newUserslug = utils.slugify(newUsername); | 		const newUserslug = slugify(newUsername); | ||||||
| 		const now = Date.now(); | 		const now = Date.now(); | ||||||
| 		await Promise.all([ | 		await Promise.all([ | ||||||
| 			updateUidMapping('username', uid, newUsername, userData.username), | 			updateUidMapping('username', uid, newUsername, userData.username), | ||||||
|   | |||||||
| @@ -4,6 +4,7 @@ | |||||||
| var assert = require('assert'); | var assert = require('assert'); | ||||||
| var JSDOM = require('jsdom').JSDOM; | var JSDOM = require('jsdom').JSDOM; | ||||||
| var utils = require('../public/src/utils.js'); | var utils = require('../public/src/utils.js'); | ||||||
|  | var slugify = require('../src/slugify'); | ||||||
| const db = require('./mocks/databasemock'); | const db = require('./mocks/databasemock'); | ||||||
|  |  | ||||||
| describe('Utility Methods', function () { | describe('Utility Methods', function () { | ||||||
| @@ -41,14 +42,14 @@ describe('Utility Methods', function () { | |||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	it('should preserve case if requested', function (done) { | 	it('should preserve case if requested', function (done) { | ||||||
| 		var slug = utils.slugify('UPPER CASE', true); | 		assert.strictEqual(utils.slugify('UPPER CASE', true), 'UPPER-CASE'); | ||||||
| 		assert.equal(slug, 'UPPER-CASE'); | 		assert.strictEqual(slugify('UPPER CASE', true), 'UPPER-CASE'); | ||||||
| 		done(); | 		done(); | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	it('should work if a number is passed in', function (done) { | 	it('should work if a number is passed in', function (done) { | ||||||
| 		var slug = utils.slugify(12345); | 		assert.strictEqual(utils.slugify(12345), '12345'); | ||||||
| 		assert.strictEqual(slug, '12345'); | 		assert.strictEqual(slugify(12345), '12345'); | ||||||
| 		done(); | 		done(); | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user