mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-27 00:56:13 +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