diff --git a/install/web.js b/install/web.js index 7630db15eb..f624acd573 100644 --- a/install/web.js +++ b/install/web.js @@ -46,8 +46,8 @@ var web = module.exports; var scripts = [ 'node_modules/jquery/dist/jquery.js', - 'public/vendor/xregexp/xregexp.js', - 'public/vendor/xregexp/unicode/unicode-base.js', + 'node_modules/xregexp/xregexp-all.js', + 'public/src/modules/slugify.js', 'public/src/utils.js', 'public/src/installer/install.js', 'node_modules/zxcvbn/dist/zxcvbn.js', diff --git a/public/src/admin/manage/users.js b/public/src/admin/manage/users.js index 2bbeeabef8..7b71139304 100644 --- a/public/src/admin/manage/users.js +++ b/public/src/admin/manage/users.js @@ -1,8 +1,8 @@ 'use strict'; define('admin/manage/users', [ - 'translator', 'benchpress', 'autocomplete', 'api', -], function (translator, Benchpress, autocomplete, api) { + 'translator', 'benchpress', 'autocomplete', 'api', 'slugify', +], function (translator, Benchpress, autocomplete, api, slugify) { var Users = {}; Users.init = function () { @@ -110,7 +110,7 @@ define('admin/manage/users', [ var groupCard = $(this).parents('[data-group-name]'); var groupName = groupCard.attr('data-group-name'); 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(); }, 'default'); return false; diff --git a/public/src/client/account/edit/username.js b/public/src/client/account/edit/username.js index c6076ebc52..a40d5d0598 100644 --- a/public/src/client/account/edit/username.js +++ b/public/src/client/account/edit/username.js @@ -1,6 +1,8 @@ '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 = {}; AccountEditUsername.init = function () { @@ -26,7 +28,7 @@ define('forum/account/edit/username', ['forum/account/header', 'api'], function api.put('/users/' + userData.uid, userData, (res) => { 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)) { $('[component="header/profilelink"]').attr('href', config.relative_path + '/user/' + userslug); $('[component="header/profilelink/edit"]').attr('href', config.relative_path + '/user/' + userslug + '/edit'); diff --git a/public/src/client/groups/details.js b/public/src/client/groups/details.js index 5d772181ee..1253b5dfc7 100644 --- a/public/src/client/groups/details.js +++ b/public/src/client/groups/details.js @@ -8,7 +8,8 @@ define('forum/groups/details', [ 'pictureCropper', 'translator', 'api', -], function (memberList, iconSelect, components, coverPhoto, pictureCropper, translator, api) { + 'slugify', +], function (memberList, iconSelect, components, coverPhoto, pictureCropper, translator, api, slugify) { var Details = {}; var groupName; @@ -208,7 +209,7 @@ define('forum/groups/details', [ if (settings.name) { var pathname = window.location.pathname; pathname = pathname.substr(1, pathname.lastIndexOf('/')); - ajaxify.go(pathname + utils.slugify(settings.name)); + ajaxify.go(pathname + slugify(settings.name)); } else { ajaxify.refresh(); } diff --git a/public/src/client/register.js b/public/src/client/register.js index ca286afb4b..d2fca2b7f5 100644 --- a/public/src/client/register.js +++ b/public/src/client/register.js @@ -1,7 +1,9 @@ '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 validationError = false; var successIcon = ''; @@ -32,7 +34,7 @@ define('forum/register', ['translator', 'zxcvbn', 'jquery-form'], function (tran // Update the "others can mention you via" text 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 () { @@ -154,7 +156,7 @@ define('forum/register', ['translator', 'zxcvbn', 'jquery-form'], function (tran showError(username_notify, '[[error:username-too-short]]'); } else if (username.length > ajaxify.data.maximumUsernameLength) { 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]]'); } else { socket.emit('user.exists', { diff --git a/public/src/client/topic/postTools.js b/public/src/client/topic/postTools.js index 66fe870cbf..4d65574840 100644 --- a/public/src/client/topic/postTools.js +++ b/public/src/client/topic/postTools.js @@ -355,7 +355,14 @@ define('forum/topic/postTools', [ } 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') { slug = '@' + slug; diff --git a/public/src/installer/install.js b/public/src/installer/install.js index f1d0765d92..a4ac88a763 100644 --- a/public/src/installer/install.js +++ b/public/src/installer/install.js @@ -1,6 +1,6 @@ 'use strict'; -/* global zxcvbn */ +/* global zxcvbn, slugify */ $('document').ready(function () { setupInputs(); @@ -61,7 +61,7 @@ $('document').ready(function () { var help = parent.children('.help-text'); function validateUsername(field) { - if (!utils.isUserNameValid(field) || !utils.slugify(field)) { + if (!utils.isUserNameValid(field) || !slugify(field)) { parent.addClass('error'); help.html('Invalid Username.'); } else { diff --git a/public/src/modules/slugify.js b/public/src/modules/slugify.js index 09ac707152..56b72bbe4a 100644 --- a/public/src/modules/slugify.js +++ b/public/src/modules/slugify.js @@ -1,10 +1,13 @@ 'use strict'; +/* global XRegExp */ (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')); } else { - define('slugify', ['xregexp'], factory); + window.slugify = factory(XRegExp); } }(function (XRegExp) { var invalidUnicodeChars = XRegExp('[^\\p{L}\\s\\d\\-_]', 'g'); diff --git a/src/categories/create.js b/src/categories/create.js index 81edf33765..56f7a694f2 100644 --- a/src/categories/create.js +++ b/src/categories/create.js @@ -7,6 +7,7 @@ const db = require('../database'); const plugins = require('../plugins'); const privileges = require('../privileges'); const utils = require('../utils'); +const slugify = require('../slugify'); const cache = require('../cache'); module.exports = function (Categories) { @@ -15,7 +16,7 @@ module.exports = function (Categories) { const cid = await db.incrObjectField('global', 'nextCid'); 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 colours = Categories.assignColours(); diff --git a/src/categories/update.js b/src/categories/update.js index 6f89f5eb32..3086b1bf8c 100644 --- a/src/categories/update.js +++ b/src/categories/update.js @@ -5,6 +5,7 @@ const async = require('async'); const db = require('../database'); const meta = require('../meta'); const utils = require('../utils'); +const slugify = require('../slugify'); const translator = require('../translator'); const plugins = require('../plugins'); const cache = require('../cache'); @@ -24,7 +25,7 @@ module.exports = function (Categories) { if (modifiedFields.hasOwnProperty('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 }); diff --git a/src/controllers/authentication.js b/src/controllers/authentication.js index c54ebc52c5..a14faf2758 100644 --- a/src/controllers/authentication.js +++ b/src/controllers/authentication.js @@ -13,6 +13,7 @@ const meta = require('../meta'); const user = require('../user'); const plugins = require('../plugins'); const utils = require('../utils'); +const slugify = require('../slugify'); const translator = require('../translator'); const helpers = require('./helpers'); const privileges = require('../privileges'); @@ -81,7 +82,7 @@ authenticationController.register = async function (req, res) { 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]]'); } @@ -356,7 +357,7 @@ authenticationController.localLogin = async function (req, username, password, n return next(new Error('[[error:password-too-long]]')); } - const userslug = utils.slugify(username); + const userslug = slugify(username); const uid = await user.getUidByUserslug(userslug); try { const [userData, isAdminOrGlobalMod, banned, hasLoginPrivilege] = await Promise.all([ diff --git a/src/controllers/write/groups.js b/src/controllers/write/groups.js index db48853bd6..9f95f5361a 100644 --- a/src/controllers/write/groups.js +++ b/src/controllers/write/groups.js @@ -6,7 +6,7 @@ const user = require('../../user'); const groups = require('../../groups'); const events = require('../../events'); const meta = require('../../meta'); -const utils = require('../../utils'); +const slugify = require('../../slugify'); const notifications = require('../../notifications'); const helpers = require('../helpers'); @@ -114,7 +114,7 @@ Groups.leave = async (req, res) => { type: 'group-leave', bodyShort: '[[groups:membership.leave.notification-title, ' + username + ', ' + group.name + ']]', 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); await notifications.push(notification, uids); diff --git a/src/file.js b/src/file.js index a4b8277f0c..6876ad75b5 100644 --- a/src/file.js +++ b/src/file.js @@ -8,7 +8,7 @@ const mkdirp = require('mkdirp'); const mime = require('mime'); const graceful = require('graceful-fs'); -const utils = require('./utils'); +const slugify = require('./slugify'); 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. */ - 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); if (!uploadPath.startsWith(nconf.get('upload_path'))) { diff --git a/src/groups/create.js b/src/groups/create.js index 1bc7ba139a..20fe4ae465 100644 --- a/src/groups/create.js +++ b/src/groups/create.js @@ -2,7 +2,7 @@ const meta = require('../meta'); const plugins = require('../plugins'); -const utils = require('../utils'); +const slugify = require('../slugify'); const db = require('../database'); 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; let groupData = { name: data.name, - slug: utils.slugify(data.name), + slug: slugify(data.name), createtime: timestamp, userTitle: data.userTitle || data.name, userTitleEnabled: parseInt(data.userTitleEnabled, 10) === 1 ? 1 : 0, @@ -88,7 +88,7 @@ module.exports = function (Groups) { 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]]'); } }; diff --git a/src/groups/delete.js b/src/groups/delete.js index ecdb50469c..1bf3068f5a 100644 --- a/src/groups/delete.js +++ b/src/groups/delete.js @@ -1,7 +1,7 @@ 'use strict'; const plugins = require('../plugins'); -const utils = require('../utils'); +const slugify = require('../slugify'); const db = require('../database'); const batch = require('../batch'); @@ -27,7 +27,7 @@ module.exports = function (Groups) { ); }); 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([ db.deleteAll(keys), diff --git a/src/groups/index.js b/src/groups/index.js index d2b2450ccd..bbcb0cde57 100644 --- a/src/groups/index.js +++ b/src/groups/index.js @@ -3,7 +3,7 @@ const user = require('../user'); const db = require('../database'); const plugins = require('../plugins'); -const utils = require('../utils'); +const slugify = require('../slugify'); const Groups = module.exports; @@ -28,7 +28,7 @@ Groups.ephemeralGroups = ['guests', 'spiders']; Groups.getEphemeralGroup = function (groupName) { return { name: groupName, - slug: utils.slugify(groupName), + slug: slugify(groupName), description: '', deleted: '0', hidden: '0', @@ -217,12 +217,12 @@ async function isFieldOn(groupName, field) { Groups.exists = async function (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 isMembersOfEphemeralGroups = slugs.map(slug => Groups.ephemeralGroups.includes(slug)); 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 isMemberOfEphemeralGroups = Groups.ephemeralGroups.includes(slug); return isMemberOfRealGroups || isMemberOfEphemeralGroups; diff --git a/src/groups/invite.js b/src/groups/invite.js index df1263441d..b96869d856 100644 --- a/src/groups/invite.js +++ b/src/groups/invite.js @@ -4,7 +4,7 @@ const _ = require('lodash'); const db = require('../database'); const user = require('../user'); -const utils = require('../utils'); +const slugify = require('../slugify'); const plugins = require('../plugins'); const notifications = require('../notifications'); @@ -18,7 +18,7 @@ module.exports = function (Groups) { bodyShort: '[[groups:request.notification_title, ' + username + ']]', bodyLong: '[[groups:request.notification_text, ' + username + ', ' + groupName + ']]', nid: 'group:' + groupName + ':uid:' + uid + ':request', - path: '/groups/' + utils.slugify(groupName), + path: '/groups/' + slugify(groupName), from: uid, }), Groups.getOwners(groupName), @@ -35,7 +35,7 @@ module.exports = function (Groups) { type: 'group-invite', bodyShort: '[[groups:membership.accept.notification_title, ' + groupName + ']]', nid: 'group:' + groupName + ':uid:' + uid + ':invite-accepted', - path: '/groups/' + utils.slugify(groupName), + path: '/groups/' + slugify(groupName), }); await notifications.push(notification, [uid]); }; @@ -58,7 +58,7 @@ module.exports = function (Groups) { bodyShort: '[[groups:invited.notification_title, ' + groupName + ']]', bodyLong: '', 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))); diff --git a/src/groups/update.js b/src/groups/update.js index 4566442c9e..be2a04fcd1 100644 --- a/src/groups/update.js +++ b/src/groups/update.js @@ -3,7 +3,7 @@ const winston = require('winston'); const plugins = require('../plugins'); -const utils = require('../utils'); +const slugify = require('../slugify'); const db = require('../database'); const user = require('../user'); const batch = require('../batch'); @@ -132,8 +132,8 @@ module.exports = function (Groups) { if (Groups.isPrivilegeGroup(newName)) { throw new Error('[[error:invalid-group-name]]'); } - const currentSlug = utils.slugify(currentName); - const newSlug = utils.slugify(newName); + const currentSlug = slugify(currentName); + const newSlug = slugify(newName); if (currentName === newName || currentSlug === newSlug) { return; } @@ -174,9 +174,9 @@ module.exports = function (Groups) { await updateNavigationItems(oldName, newName); await updateWidgets(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.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 keys = allGroups.map(group => 'group:' + group + ':members'); diff --git a/src/meta/index.js b/src/meta/index.js index 030db6f3ad..326cfb8bf7 100644 --- a/src/meta/index.js +++ b/src/meta/index.js @@ -5,7 +5,7 @@ const os = require('os'); const nconf = require('nconf'); const pubsub = require('../pubsub'); -const utils = require('../utils'); +const slugify = require('../slugify'); const Meta = module.exports; @@ -29,7 +29,7 @@ Meta.languages = require('./languages'); Meta.userOrGroupExists = async function (slug) { const user = require('../user'); const groups = require('../groups'); - slug = utils.slugify(slug); + slug = slugify(slug); const [userExists, groupExists] = await Promise.all([ user.existsBySlug(slug), groups.existsBySlug(slug), diff --git a/src/meta/js.js b/src/meta/js.js index 915a8250e0..28be889c4c 100644 --- a/src/meta/js.js +++ b/src/meta/js.js @@ -37,8 +37,10 @@ JS.scripts = { 'node_modules/jquery-serializeobject/jquery.serializeObject.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/unicode/unicode-base.js', + 'public/src/utils.js', 'public/src/sockets.js', 'public/src/app.js', diff --git a/src/middleware/render.js b/src/middleware/render.js index a82bac03b5..5edc087262 100644 --- a/src/middleware/render.js +++ b/src/middleware/render.js @@ -10,6 +10,7 @@ const meta = require('../meta'); const translator = require('../translator'); const widgets = require('../widgets'); const utils = require('../utils'); +const slugify = require('../slugify'); module.exports = function (middleware) { middleware.processRender = function processRender(req, res, next) { @@ -111,7 +112,7 @@ module.exports = function (middleware) { const parts = clean.split('/').slice(0, 3); parts.forEach(function (p, index) { try { - p = utils.slugify(decodeURIComponent(p)); + p = slugify(decodeURIComponent(p)); } catch (err) { winston.error(err.stack); p = ''; @@ -122,7 +123,7 @@ module.exports = function (middleware) { if (templateData.template.topic) { 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) { templateData.breadcrumbs.forEach(function (crumb) { diff --git a/src/posts/edit.js b/src/posts/edit.js index 1ad2befa9d..9c15c5ee1b 100644 --- a/src/posts/edit.js +++ b/src/posts/edit.js @@ -11,6 +11,7 @@ const privileges = require('../privileges'); const plugins = require('../plugins'); const pubsub = require('../pubsub'); const utils = require('../utils'); +const slugify = require('../slugify'); const translator = require('../translator'); module.exports = function (Posts) { @@ -114,7 +115,7 @@ module.exports = function (Posts) { }; if (title) { newTopicData.title = title; - newTopicData.slug = tid + '/' + (utils.slugify(title) || 'topic'); + newTopicData.slug = tid + '/' + (slugify(title) || 'topic'); } newTopicData.thumb = data.thumb || ''; diff --git a/src/socket.io/groups.js b/src/socket.io/groups.js index ab1ad80ca1..e46983e183 100644 --- a/src/socket.io/groups.js +++ b/src/socket.io/groups.js @@ -5,6 +5,7 @@ const groups = require('../groups'); const meta = require('../meta'); const user = require('../user'); const utils = require('../utils'); +const slugify = require('../slugify'); const events = require('../events'); const privileges = require('../privileges'); const notifications = require('../notifications'); @@ -94,7 +95,7 @@ SocketGroups.leave = async (socket, data) => { type: 'group-leave', bodyShort: '[[groups:membership.leave.notification_title, ' + username + ', ' + data.groupName + ']]', 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); await notifications.push(notification, uids); diff --git a/src/topics/create.js b/src/topics/create.js index 7471b3bde9..2aed3268cb 100644 --- a/src/topics/create.js +++ b/src/topics/create.js @@ -6,6 +6,7 @@ const validator = require('validator'); const db = require('../database'); const utils = require('../utils'); +const slugify = require('../slugify'); const plugins = require('../plugins'); const analytics = require('../analytics'); const user = require('../user'); @@ -29,7 +30,7 @@ module.exports = function (Topics) { cid: data.cid, mainPid: 0, title: data.title, - slug: tid + '/' + (utils.slugify(data.title) || 'topic'), + slug: tid + '/' + (slugify(data.title) || 'topic'), timestamp: timestamp, lastposttime: 0, postcount: 0, @@ -261,7 +262,7 @@ module.exports = function (Topics) { if (data.handle.length > meta.config.maximumUsernameLength) { 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) { throw new Error('[[error:username-taken]]'); } diff --git a/src/user/approval.js b/src/user/approval.js index dec0bb7e2d..ba3ac2d07d 100644 --- a/src/user/approval.js +++ b/src/user/approval.js @@ -9,12 +9,13 @@ const emailer = require('../emailer'); const notifications = require('../notifications'); const groups = require('../groups'); const utils = require('../utils'); +const slugify = require('../slugify'); const plugins = require('../plugins'); module.exports = function (User) { User.addToApprovalQueue = async function (userData) { userData.username = userData.username.trim(); - userData.userslug = utils.slugify(userData.username); + userData.userslug = slugify(userData.username); await canQueue(userData); const hashedPassword = await User.hashPassword(userData.password); const data = { diff --git a/src/user/create.js b/src/user/create.js index 45d93b8e29..e0cf8f18ca 100644 --- a/src/user/create.js +++ b/src/user/create.js @@ -3,6 +3,7 @@ const zxcvbn = require('zxcvbn'); const db = require('../database'); const utils = require('../utils'); +const slugify = require('../slugify'); const plugins = require('../plugins'); const groups = require('../groups'); const meta = require('../meta'); @@ -10,7 +11,7 @@ const meta = require('../meta'); module.exports = function (User) { User.create = async function (data) { data.username = data.username.trim(); - data.userslug = utils.slugify(data.username); + data.userslug = slugify(data.username); if (data.email !== undefined) { data.email = String(data.email).trim(); } @@ -63,7 +64,7 @@ module.exports = function (User) { const userNameChanged = !!renamedUsername; if (userNameChanged) { userData.username = renamedUsername; - userData.userslug = utils.slugify(renamedUsername); + userData.userslug = slugify(renamedUsername); } const results = await plugins.fireHook('filter:user.create', { user: userData, data: data }); diff --git a/src/user/profile.js b/src/user/profile.js index d775824d06..229c5243bd 100644 --- a/src/user/profile.js +++ b/src/user/profile.js @@ -5,6 +5,7 @@ const async = require('async'); const validator = require('validator'); const utils = require('../utils'); +const slugify = require('../slugify'); const meta = require('../meta'); const db = require('../database'); const groups = require('../groups'); @@ -113,7 +114,7 @@ module.exports = function (User) { throw new Error('[[error:username-too-long]]'); } - const userslug = utils.slugify(data.username); + const userslug = slugify(data.username); if (!utils.isUserNameValid(data.username) || !userslug) { throw new Error('[[error:invalid-username]]'); } @@ -256,7 +257,7 @@ module.exports = function (User) { if (userData.username === newUsername) { return; } - const newUserslug = utils.slugify(newUsername); + const newUserslug = slugify(newUsername); const now = Date.now(); await Promise.all([ updateUidMapping('username', uid, newUsername, userData.username), diff --git a/test/utils.js b/test/utils.js index 09c608aba9..38283ac4bf 100644 --- a/test/utils.js +++ b/test/utils.js @@ -4,6 +4,7 @@ var assert = require('assert'); var JSDOM = require('jsdom').JSDOM; var utils = require('../public/src/utils.js'); +var slugify = require('../src/slugify'); const db = require('./mocks/databasemock'); describe('Utility Methods', function () { @@ -41,14 +42,14 @@ describe('Utility Methods', function () { }); it('should preserve case if requested', function (done) { - var slug = utils.slugify('UPPER CASE', true); - assert.equal(slug, 'UPPER-CASE'); + assert.strictEqual(utils.slugify('UPPER CASE', true), 'UPPER-CASE'); + assert.strictEqual(slugify('UPPER CASE', true), 'UPPER-CASE'); done(); }); it('should work if a number is passed in', function (done) { - var slug = utils.slugify(12345); - assert.strictEqual(slug, '12345'); + assert.strictEqual(utils.slugify(12345), '12345'); + assert.strictEqual(slugify(12345), '12345'); done(); });