Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

nodebb-plugin-restrict-usernames

Package Overview
Dependencies
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

nodebb-plugin-restrict-usernames - npm Package Compare versions

Comparing version 0.6.0 to 0.7.0

.github/workflows/release-please.yml

80

library.js
'use strict';
const { metaphone3 } = require('metaphone3');
const meta = require.main.require('./src/meta');
const batch = require.main.require('./src/batch');
const groups = require.main.require('./src/groups');
const user = require.main.require('./src/user');

@@ -26,9 +29,11 @@ const routeHelpers = require.main.require('./src/routes/helpers');

plugin.settings['similarity-value'] = 85;
plugin.settingsgroupsChecked = '[""]';
await meta.settings.set(plugin.id, plugin.settings, true);
}
routeHelpers.setupAdminPageRoute(router, '/admin/plugins/restrict-usernames', [], (req, res) => {
res.render('admin/plugins/restrict-usernames', { rules: plugin.userFilters });
routeHelpers.setupAdminPageRoute(router, '/admin/plugins/restrict-usernames', [], async (req, res) => {
res.render('admin/plugins/restrict-usernames', { rules: plugin.userFilters, groupsChecked: [{ name: '' }, ...(await groups.getGroupsBySort('count', 0, -1)).filter(group => group?.name)] });
});
};
plugin.userFilters = {

@@ -75,16 +80,60 @@ duplicate: {

// just precompute the bigrams for the current username to avoid redoing the work
const usernameBigrams = bigram(username);
await batch.processSortedSet('username:uid', (checkedUsernames) => {
if (!checkedUsernames.length) {
checkedUsernames = [checkedUsernames];
}
for (const checkedUsername of checkedUsernames) {
const similarity = diceCoefficient(usernameBigrams, checkedUsername);
if (similarity >= parseInt(plugin.settings['similarity-value'] ?? plugin.userFilters.similarity.placeholder, 10) / 100) {
throw new Error(`[[restrict-usernames:error.username-too-similar, ${checkedUsername}]]`);
const usernameBigrams = bigram(username.normalize('NFD'));
const checkedGroups = JSON.parse(plugin.settings.groupsChecked);
const checkedSets = checkedGroups.filter(group => group.length).map(group => `group:${group}:members`);
if (checkedSets.length === 0) {
checkedSets.push('username:uid');
}
const batchPromises = checkedSets.map(checkedSet => batch.processSortedSet(
checkedSet,
async (checkedUsernames) => {
if (checkedSet !== 'username:uid') {
checkedUsernames = await user.getUsernamesByUids(checkedUsernames);
}
}
}, {});
if (!checkedUsernames.length) {
checkedUsernames = [checkedUsernames];
}
for (const checkedUsername of checkedUsernames) {
const similarity = diceCoefficient(usernameBigrams, checkedUsername.normalize('NFD'));
if (similarity >= parseInt(plugin.settings['similarity-value'] ?? plugin.userFilters.similarity.placeholder, 10) / 100) {
throw new Error(`[[restrict-usernames:error.username-too-similar, ${checkedUsername}]]`);
}
}
},
{}
));
await Promise.all(batchPromises);
},
},
phonetic: {
type: 'boolean',
name: '[[restrict-usernames:filter.phonetic.name]]',
description: '[[restrict-usernames:filter.phonetic.description]]',
function: async (username) => {
const phonetic = new Set(metaphone3(username));
const checkedGroups = JSON.parse(plugin.settings.groupsChecked);
const checkedSets = checkedGroups.filter(group => group.length).map(group => `group:${group}:members`);
if (checkedSets.length === 0) {
checkedSets.push('username:uid');
}
const batchPromises = checkedSets.map(checkedSet => batch.processSortedSet(
checkedSet,
async (checkedUsernames) => {
if (checkedSet !== 'username:uid') {
checkedUsernames = await user.getUsernamesByUids(checkedUsernames);
}
if (!checkedUsernames.length) {
checkedUsernames = [checkedUsernames];
}
for (const checkedUsername of checkedUsernames) {
if (metaphone3(checkedUsername).filter(p => p && phonetic.has(p)).length) {
throw new Error(`[[restrict-usernames:error.username-too-similar-phonetic, ${checkedUsername}]]`);
}
}
},
{}
));
await Promise.all(batchPromises);
},
},
regex: {

@@ -111,3 +160,2 @@ type: 'rules',

plugin.settings = await meta.settings.get(plugin.id);
console.log(plugin.settings);
}

@@ -130,4 +178,4 @@ return data;

route: '/plugins/restrict-usernames',
icon: 'fa-tint',
name: 'restrict-usernames',
icon: 'fa-user-lock',
name: 'Restrict Usernames',
});

@@ -134,0 +182,0 @@

19

package.json
{
"name": "nodebb-plugin-restrict-usernames",
"version": "0.6.0",
"version": "0.7.0",
"description": "Set rules for what usernames are allowed on your forum",

@@ -37,14 +37,15 @@ "main": "library.js",

"devDependencies": {
"@commitlint/cli": "17.2.0",
"@commitlint/config-angular": "17.2.0",
"eslint": "8.27.0",
"eslint-config-nodebb": "0.1.1",
"eslint-plugin-import": "2.26.0",
"husky": "8.0.2",
"lint-staged": "13.0.3"
"@commitlint/cli": "19.2.1",
"@commitlint/config-angular": "19.1.0",
"eslint": "8.57.0",
"eslint-config-nodebb": "0.2.1",
"eslint-plugin-import": "2.29.1",
"husky": "9.0.11",
"lint-staged": "15.2.2"
},
"dependencies": {
"dice-coefficient": "^2.1.1",
"metaphone3": "^1.0.1",
"n-gram": "^2.0.2"
}
}
}
{
"add-item": "Add Item",
"rules": "Rules",
"enabled": "Enabled",
"error.username-too-similar": "The username is too similar to existing user %1",
"error.username-too-similar-phonetic": "The username sounds too similar to existing user %1",
"error.invalid-username": "The username is invalid",

@@ -19,5 +19,10 @@ "error.username-taken": "The username is already taken",

"filter.similarity.description": "If enabled, registering with a username that is too similar to an existing username will be rejected. This is calculated using Sørensen-Dice coefficient of these two usernames. The value is the maximum similarity allowed, so 85 means that usernames with coeffient of 0.85 or more will be rejected. Warning: setting this too low will cause a lot of false positives.",
"filter.phonetic.name": "Phonetic similarity to existing usernames",
"filter.phonetic.description": "If enabled, registering with a username that sounds very similar to an existing username will be rejected. This is calculated using Metaphone algorithm.",
"filter.regex.name": "Custom blacklist (words or regex)",
"filter.regex.description": "If enabled, registering with a username that matches any of the rules will be rejected. Rules are matched using JavaScript regex, but for basic usage just inputting the word will match it as is. Just be weary of special characters like parentheses or periods, which need to be escaped by prepending them with \\",
"insensitive": "(case insensitive)"
"groups-checked": "Checked Groups",
"groups-checked-description": "If any groups is selected here, similarity checks will only compare new usernames to their members",
"insensitive": "(case insensitive)",
"rules": "Rules"
}

@@ -10,3 +10,5 @@ {

"error.no-letters": "Nazwa użytkownika musi zawierać przy najmniej jedną literę",
"insensitive": "(ignoruje wielkość liter)"
"insensitive": "(ignoruje wielkość liter)",
"groups-checked": "Sprawdzane grupy",
"groups-checked-description": "Jeśli przynajmniej jedna z tych grup jest zaznaczona, zasady podobności będą stosowane tylko do nich"
}

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc