mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-01 19:46:01 +01:00
closes #1306
This commit is contained in:
@@ -9,7 +9,7 @@
|
|||||||
"maximumPostLength": 32767,
|
"maximumPostLength": 32767,
|
||||||
"allowGuestSearching": 0,
|
"allowGuestSearching": 0,
|
||||||
"allowTopicsThumbnail": 0,
|
"allowTopicsThumbnail": 0,
|
||||||
"allowRegistration": 1,
|
"registrationType": "normal",
|
||||||
"allowLocalLogin": 1,
|
"allowLocalLogin": 1,
|
||||||
"allowAccountDelete": 1,
|
"allowAccountDelete": 1,
|
||||||
"allowFileUploads": 0,
|
"allowFileUploads": 0,
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
"welcome.text1": "Thank you for registering with %1!",
|
"welcome.text1": "Thank you for registering with %1!",
|
||||||
"welcome.text2": "To fully activate your account, we need to verify that you own the email address you registered with.",
|
"welcome.text2": "To fully activate your account, we need to verify that you own the email address you registered with.",
|
||||||
|
"welcome.text3": "An administrator has accepted your registration application. You can login with your username/password now.",
|
||||||
"welcome.cta": "Click here to confirm your email address",
|
"welcome.cta": "Click here to confirm your email address",
|
||||||
|
|
||||||
"reset.text1": "We received a request to reset your password, possibly because you have forgotten it. If this is not the case, please ignore this email.",
|
"reset.text1": "We received a request to reset your password, possibly because you have forgotten it. If this is not the case, please ignore this email.",
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
"user_posted_topic": "<strong>%1</strong> has posted a new topic: <strong>%2</strong>",
|
"user_posted_topic": "<strong>%1</strong> has posted a new topic: <strong>%2</strong>",
|
||||||
"user_mentioned_you_in": "<strong>%1</strong> mentioned you in <strong>%2</strong>",
|
"user_mentioned_you_in": "<strong>%1</strong> mentioned you in <strong>%2</strong>",
|
||||||
"user_started_following_you": "<strong>%1</strong> started following you.",
|
"user_started_following_you": "<strong>%1</strong> started following you.",
|
||||||
|
"new_register": "<strong>%1</strong> sent a registration request.",
|
||||||
|
|
||||||
"email-confirmed": "Email Confirmed",
|
"email-confirmed": "Email Confirmed",
|
||||||
"email-confirmed-message": "Thank you for validating your email. Your account is now fully activated.",
|
"email-confirmed-message": "Thank you for validating your email. Your account is now fully activated.",
|
||||||
|
|||||||
@@ -14,5 +14,6 @@
|
|||||||
"register_now_button": "Register Now",
|
"register_now_button": "Register Now",
|
||||||
"alternative_registration": "Alternative Registration",
|
"alternative_registration": "Alternative Registration",
|
||||||
"terms_of_use": "Terms of Use",
|
"terms_of_use": "Terms of Use",
|
||||||
"agree_to_terms_of_use": "I agree to the Terms of Use"
|
"agree_to_terms_of_use": "I agree to the Terms of Use",
|
||||||
|
"registration-added-to-queue": "Your registration has been added to the approval queue. You will receive an email when it is accepted by an administrator."
|
||||||
}
|
}
|
||||||
28
public/src/admin/manage/registration.js
Normal file
28
public/src/admin/manage/registration.js
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
/* global config, socket, define, templates, bootbox, app, ajaxify, */
|
||||||
|
|
||||||
|
define('admin/manage/registration', function() {
|
||||||
|
var Registration = {};
|
||||||
|
|
||||||
|
Registration.init = function() {
|
||||||
|
|
||||||
|
$('.users-list').on('click', '[data-action]', function(ev) {
|
||||||
|
var $this = this;
|
||||||
|
var parent = $(this).parents('[data-username]');
|
||||||
|
var action = $(this).attr('data-action');
|
||||||
|
var username = parent.attr('data-username');
|
||||||
|
var method = action === 'accept' ? 'admin.user.acceptRegistration' : 'admin.user.rejectRegistration';
|
||||||
|
|
||||||
|
socket.emit(method, {username: username}, function(err) {
|
||||||
|
if (err) {
|
||||||
|
return app.alertError(err.message);
|
||||||
|
}
|
||||||
|
parent.remove();
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return Registration;
|
||||||
|
});
|
||||||
@@ -69,7 +69,15 @@ define('forum/register', ['csrf', 'translator'], function(csrf, translator) {
|
|||||||
'x-csrf-token': csrf.get()
|
'x-csrf-token': csrf.get()
|
||||||
},
|
},
|
||||||
success: function(data, status) {
|
success: function(data, status) {
|
||||||
window.location.href = data;
|
registerBtn.removeClass('disabled');
|
||||||
|
if (!data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (data.referrer) {
|
||||||
|
window.location.href = data.referrer;
|
||||||
|
} else if (data.message) {
|
||||||
|
app.alert({message: data.message, timeout: 20000});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
error: function(data, status) {
|
error: function(data, status) {
|
||||||
var errorEl = $('#register-error-notify');
|
var errorEl = $('#register-error-notify');
|
||||||
@@ -84,7 +92,7 @@ define('forum/register', ['csrf', 'translator'], function(csrf, translator) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
if(agreeTerms.length) {
|
if (agreeTerms.length) {
|
||||||
agreeTerms.on('click', function() {
|
agreeTerms.on('click', function() {
|
||||||
if ($(this).prop('checked')) {
|
if ($(this).prop('checked')) {
|
||||||
register.removeAttr('disabled');
|
register.removeAttr('disabled');
|
||||||
|
|||||||
@@ -30,6 +30,15 @@ usersController.banned = function(req, res, next) {
|
|||||||
getUsers('users:banned', req, res, next);
|
getUsers('users:banned', req, res, next);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
usersController.registrationQueue = function(req, res, next) {
|
||||||
|
user.getRegistrationQueue(0, -1, function(err, data) {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
res.render('admin/manage/registration', {users: data});
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
function getUsers(set, req, res, next) {
|
function getUsers(set, req, res, next) {
|
||||||
user.getUsersFromSet(set, req.uid, 0, 49, function(err, users) {
|
user.getUsersFromSet(set, req.uid, 0, 49, function(err, users) {
|
||||||
if (err) {
|
if (err) {
|
||||||
|
|||||||
@@ -16,7 +16,9 @@ var async = require('async'),
|
|||||||
authenticationController = {};
|
authenticationController = {};
|
||||||
|
|
||||||
authenticationController.register = function(req, res, next) {
|
authenticationController.register = function(req, res, next) {
|
||||||
if (parseInt(meta.config.allowRegistration, 10) === 0) {
|
var registrationType = meta.config.registrationType || 'normal';
|
||||||
|
|
||||||
|
if (registrationType === 'disabled') {
|
||||||
return res.sendStatus(403);
|
return res.sendStatus(403);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,7 +55,26 @@ authenticationController.register = function(req, res, next) {
|
|||||||
plugins.fireHook('filter:register.check', {req: req, res: res, userData: userData}, next);
|
plugins.fireHook('filter:register.check', {req: req, res: res, userData: userData}, next);
|
||||||
},
|
},
|
||||||
function(data, next) {
|
function(data, next) {
|
||||||
user.create(data.userData, next);
|
if (registrationType === 'normal') {
|
||||||
|
registerAndLoginUser(req, res, userData, next);
|
||||||
|
} else if (registrationType === 'admin-approval') {
|
||||||
|
addToApprovalQueue(req, res, userData, next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
], function(err, data) {
|
||||||
|
if (err) {
|
||||||
|
return res.status(400).send(err.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
res.json(data);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
function registerAndLoginUser(req, res, userData, callback) {
|
||||||
|
var uid;
|
||||||
|
async.waterfall([
|
||||||
|
function(next) {
|
||||||
|
user.create(userData, next);
|
||||||
},
|
},
|
||||||
function(_uid, next) {
|
function(_uid, next) {
|
||||||
uid = _uid;
|
uid = _uid;
|
||||||
@@ -64,16 +85,22 @@ authenticationController.register = function(req, res, next) {
|
|||||||
|
|
||||||
user.notifications.sendWelcomeNotification(uid);
|
user.notifications.sendWelcomeNotification(uid);
|
||||||
|
|
||||||
plugins.fireHook('filter:register.complete', {uid: uid, referrer: req.body.referrer}, next);
|
plugins.fireHook('filter:register.complete', {uid: uid, referrer: req.body.referrer || nconf.get('relative_path') + '/'}, next);
|
||||||
}
|
|
||||||
], function(err, data) {
|
|
||||||
if (err) {
|
|
||||||
return res.status(400).send(err.message);
|
|
||||||
}
|
}
|
||||||
|
], callback);
|
||||||
|
}
|
||||||
|
|
||||||
res.status(200).send(data.referrer ? data.referrer : nconf.get('relative_path') + '/');
|
function addToApprovalQueue(req, res, userData, callback) {
|
||||||
});
|
async.waterfall([
|
||||||
};
|
function(next) {
|
||||||
|
userData.ip = req.ip;
|
||||||
|
user.addToApprovalQueue(userData, next);
|
||||||
|
},
|
||||||
|
function(next) {
|
||||||
|
next(null, {message: '[[register:registration-added-to-queue]]'});
|
||||||
|
}
|
||||||
|
], callback);
|
||||||
|
}
|
||||||
|
|
||||||
authenticationController.login = function(req, res, next) {
|
authenticationController.login = function(req, res, next) {
|
||||||
// Handle returnTo data
|
// Handle returnTo data
|
||||||
|
|||||||
@@ -77,11 +77,13 @@ Controllers.login = function(req, res, next) {
|
|||||||
loginStrategies = require('../routes/authentication').getLoginStrategies(),
|
loginStrategies = require('../routes/authentication').getLoginStrategies(),
|
||||||
emailersPresent = plugins.hasListeners('action:email.send');
|
emailersPresent = plugins.hasListeners('action:email.send');
|
||||||
|
|
||||||
|
var registrationType = meta.config.registrationType || 'normal';
|
||||||
|
|
||||||
data.alternate_logins = loginStrategies.length > 0;
|
data.alternate_logins = loginStrategies.length > 0;
|
||||||
data.authentication = loginStrategies;
|
data.authentication = loginStrategies;
|
||||||
data.showResetLink = emailersPresent;
|
data.showResetLink = emailersPresent;
|
||||||
data.allowLocalLogin = parseInt(meta.config.allowLocalLogin, 10) === 1 || parseInt(req.query.local, 10) === 1;
|
data.allowLocalLogin = parseInt(meta.config.allowLocalLogin, 10) === 1 || parseInt(req.query.local, 10) === 1;
|
||||||
data.allowRegistration = parseInt(meta.config.allowRegistration, 10) === 1;
|
data.allowRegistration = registrationType === 'normal' || registrationType === 'admin-approval';
|
||||||
data.allowLoginWith = '[[login:' + (meta.config.allowLoginWith || 'username-email') + ']]';
|
data.allowLoginWith = '[[login:' + (meta.config.allowLoginWith || 'username-email') + ']]';
|
||||||
data.breadcrumbs = helpers.buildBreadcrumbs([{text: '[[global:login]]'}]);
|
data.breadcrumbs = helpers.buildBreadcrumbs([{text: '[[global:login]]'}]);
|
||||||
data.error = req.flash('error')[0];
|
data.error = req.flash('error')[0];
|
||||||
@@ -90,7 +92,9 @@ Controllers.login = function(req, res, next) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Controllers.register = function(req, res, next) {
|
Controllers.register = function(req, res, next) {
|
||||||
if (parseInt(meta.config.allowRegistration, 10) === 0) {
|
var registrationType = meta.config.registrationType || 'normal';
|
||||||
|
|
||||||
|
if (registrationType === 'disabled') {
|
||||||
return helpers.notFound(req, res);
|
return helpers.notFound(req, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ middleware.redirectToLoginIfGuest = function(req, res, next) {
|
|||||||
if (!req.user || parseInt(req.user.uid, 10) === 0) {
|
if (!req.user || parseInt(req.user.uid, 10) === 0) {
|
||||||
return redirectToLogin(req, res);
|
return redirectToLogin(req, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
next();
|
next();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -191,16 +191,17 @@ middleware.buildHeader = function(req, res, next) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
middleware.renderHeader = function(req, res, callback) {
|
middleware.renderHeader = function(req, res, callback) {
|
||||||
|
var registrationType = meta.config.registrationType || 'normal'
|
||||||
var templateValues = {
|
var templateValues = {
|
||||||
bootswatchCSS: meta.config['theme:src'],
|
bootswatchCSS: meta.config['theme:src'],
|
||||||
title: meta.config.title || '',
|
title: meta.config.title || '',
|
||||||
description: meta.config.description || '',
|
description: meta.config.description || '',
|
||||||
'cache-buster': meta.config['cache-buster'] ? 'v=' + meta.config['cache-buster'] : '',
|
'cache-buster': meta.config['cache-buster'] ? 'v=' + meta.config['cache-buster'] : '',
|
||||||
'brand:logo': meta.config['brand:logo'] || '',
|
'brand:logo': meta.config['brand:logo'] || '',
|
||||||
'brand:logo:display': meta.config['brand:logo']?'':'hide',
|
'brand:logo:display': meta.config['brand:logo']?'':'hide',
|
||||||
allowRegistration: meta.config.allowRegistration === undefined || parseInt(meta.config.allowRegistration, 10) === 1,
|
allowRegistration: registrationType === 'normal' || registrationType === 'admin-approval',
|
||||||
searchEnabled: plugins.hasListeners('filter:search.query')
|
searchEnabled: plugins.hasListeners('filter:search.query')
|
||||||
};
|
};
|
||||||
|
|
||||||
for (var key in res.locals.config) {
|
for (var key in res.locals.config) {
|
||||||
if (res.locals.config.hasOwnProperty(key)) {
|
if (res.locals.config.hasOwnProperty(key)) {
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ function addRoutes(router, middleware, controllers) {
|
|||||||
router.get('/manage/users/sort-posts', controllers.admin.users.sortByPosts);
|
router.get('/manage/users/sort-posts', controllers.admin.users.sortByPosts);
|
||||||
router.get('/manage/users/sort-reputation', controllers.admin.users.sortByReputation);
|
router.get('/manage/users/sort-reputation', controllers.admin.users.sortByReputation);
|
||||||
router.get('/manage/users/banned', controllers.admin.users.banned);
|
router.get('/manage/users/banned', controllers.admin.users.banned);
|
||||||
|
router.get('/manage/users/registration', controllers.admin.users.registrationQueue);
|
||||||
|
|
||||||
router.get('/manage/groups', controllers.admin.groups.list);
|
router.get('/manage/groups', controllers.admin.groups.list);
|
||||||
router.get('/manage/groups/:name', controllers.admin.groups.get);
|
router.get('/manage/groups/:name', controllers.admin.groups.get);
|
||||||
|
|||||||
@@ -241,4 +241,13 @@ User.search = function(socket, data, callback) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
User.acceptRegistration = function(socket, data, callback) {
|
||||||
|
user.acceptRegistration(data.username, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
User.rejectRegistration = function(socket, data, callback) {
|
||||||
|
user.rejectRegistration(data.username, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
module.exports = User;
|
module.exports = User;
|
||||||
@@ -30,6 +30,7 @@ var async = require('async'),
|
|||||||
require('./user/search')(User);
|
require('./user/search')(User);
|
||||||
require('./user/jobs')(User);
|
require('./user/jobs')(User);
|
||||||
require('./user/picture')(User);
|
require('./user/picture')(User);
|
||||||
|
require('./user/approval')(User);
|
||||||
|
|
||||||
User.getUserField = function(uid, field, callback) {
|
User.getUserField = function(uid, field, callback) {
|
||||||
User.getUserFields(uid, [field], function(err, user) {
|
User.getUserFields(uid, [field], function(err, user) {
|
||||||
|
|||||||
139
src/user/approval.js
Normal file
139
src/user/approval.js
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var async = require('async'),
|
||||||
|
nconf = require('nconf'),
|
||||||
|
db = require('./../database'),
|
||||||
|
meta = require('../meta'),
|
||||||
|
emailer = require('../emailer'),
|
||||||
|
notifications = require('../notifications'),
|
||||||
|
translator = require('../../public/src/modules/translator'),
|
||||||
|
utils = require('../../public/src/utils');
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = function(User) {
|
||||||
|
|
||||||
|
User.addToApprovalQueue = function(userData, callback) {
|
||||||
|
userData.userslug = utils.slugify(userData.username);
|
||||||
|
async.waterfall([
|
||||||
|
function(next) {
|
||||||
|
User.isDataValid(userData, next);
|
||||||
|
},
|
||||||
|
function(next) {
|
||||||
|
User.hashPassword(userData.password, next);
|
||||||
|
},
|
||||||
|
function(hashedPassword, next) {
|
||||||
|
var data = {
|
||||||
|
username: userData.username,
|
||||||
|
email: userData.email,
|
||||||
|
ip: userData.ip,
|
||||||
|
hashedPassword: hashedPassword
|
||||||
|
};
|
||||||
|
|
||||||
|
db.setObject('registration:queue:name:' + userData.username, data, next);
|
||||||
|
},
|
||||||
|
function(next) {
|
||||||
|
db.sortedSetAdd('registration:queue', Date.now(), userData.username, next);
|
||||||
|
},
|
||||||
|
function(next) {
|
||||||
|
sendNotificationToAdmins(userData.username, next);
|
||||||
|
}
|
||||||
|
], callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
function sendNotificationToAdmins(username, callback) {
|
||||||
|
notifications.create({
|
||||||
|
bodyShort: '[[notifications:new_register, ' + username + ']]',
|
||||||
|
nid: 'new_register' + username,
|
||||||
|
path: '/admin/manage/users/registration'
|
||||||
|
}, function(err, notification) {
|
||||||
|
if (err) {
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
if (notification) {
|
||||||
|
notifications.pushGroup(notification, 'administrators', callback);
|
||||||
|
} else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
User.acceptRegistration = function(username, callback) {
|
||||||
|
var uid;
|
||||||
|
var userData;
|
||||||
|
async.waterfall([
|
||||||
|
function(next) {
|
||||||
|
db.getObject('registration:queue:name:' + username, next);
|
||||||
|
},
|
||||||
|
function(_userData, next) {
|
||||||
|
if (!_userData) {
|
||||||
|
return callback(new Error('[[error:invalid-data]]'));
|
||||||
|
}
|
||||||
|
userData = _userData;
|
||||||
|
User.create(userData, next);
|
||||||
|
},
|
||||||
|
function(_uid, next) {
|
||||||
|
uid = _uid;
|
||||||
|
User.setUserField(uid, 'password', userData.hashedPassword, next);
|
||||||
|
},
|
||||||
|
function(next) {
|
||||||
|
var title = meta.config.title || meta.config.browserTitle || 'NodeBB';
|
||||||
|
translator.translate('[[email:welcome-to, ' + title + ']]', meta.config.defaultLang, function(subject) {
|
||||||
|
var data = {
|
||||||
|
site_title: title,
|
||||||
|
username: username,
|
||||||
|
subject: subject,
|
||||||
|
template: 'registration_accepted',
|
||||||
|
uid: uid
|
||||||
|
};
|
||||||
|
|
||||||
|
emailer.send('registration_accepted', uid, data, next);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
function(next) {
|
||||||
|
User.notifications.sendWelcomeNotification(uid, next);
|
||||||
|
},
|
||||||
|
function(next) {
|
||||||
|
removeFromQueue(username, next);
|
||||||
|
}
|
||||||
|
], callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
User.rejectRegistration = function(username, callback) {
|
||||||
|
removeFromQueue(username, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
function removeFromQueue(username, callback) {
|
||||||
|
async.parallel([
|
||||||
|
async.apply(db.sortedSetRemove, 'registration:queue', username),
|
||||||
|
async.apply(db.delete, 'registration:queue:name:' + username)
|
||||||
|
], callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
User.getRegistrationQueue = function(start, stop, callback) {
|
||||||
|
var data;
|
||||||
|
async.waterfall([
|
||||||
|
function(next) {
|
||||||
|
db.getSortedSetRevRangeWithScores('registration:queue', start, stop, next);
|
||||||
|
},
|
||||||
|
function(_data, next) {
|
||||||
|
data = _data;
|
||||||
|
var keys = data.filter(Boolean).map(function(user) {
|
||||||
|
return 'registration:queue:name:' + user.value;
|
||||||
|
});
|
||||||
|
db.getObjects(keys, next);
|
||||||
|
},
|
||||||
|
function(users, next) {
|
||||||
|
users.forEach(function(user, index) {
|
||||||
|
if (user) {
|
||||||
|
user.timestamp = utils.toISOString(data[index].score);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
next(null, users);
|
||||||
|
}
|
||||||
|
], callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
@@ -20,7 +20,7 @@ module.exports = function(User) {
|
|||||||
data.email = validator.escape(data.email.trim());
|
data.email = validator.escape(data.email.trim());
|
||||||
}
|
}
|
||||||
|
|
||||||
isDataValid(data, function(err) {
|
User.isDataValid(data, function(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
@@ -155,7 +155,7 @@ module.exports = function(User) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
function isDataValid(userData, callback) {
|
User.isDataValid = function(userData, callback) {
|
||||||
async.parallel({
|
async.parallel({
|
||||||
emailValid: function(next) {
|
emailValid: function(next) {
|
||||||
if (userData.email) {
|
if (userData.email) {
|
||||||
@@ -186,8 +186,10 @@ module.exports = function(User) {
|
|||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, callback);
|
}, function(err, results) {
|
||||||
}
|
callback(err);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
function renameUsername(userData, callback) {
|
function renameUsername(userData, callback) {
|
||||||
meta.userOrGroupExists(userData.userslug, function(err, exists) {
|
meta.userOrGroupExists(userData.userslug, function(err, exists) {
|
||||||
|
|||||||
@@ -289,9 +289,10 @@ var async = require('async'),
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
UserNotifications.sendWelcomeNotification = function(uid) {
|
UserNotifications.sendWelcomeNotification = function(uid, callback) {
|
||||||
|
callback = callback || function() {};
|
||||||
if (!meta.config.welcomeNotification) {
|
if (!meta.config.welcomeNotification) {
|
||||||
return;
|
return callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
var path = meta.config.welcomeLink ? meta.config.welcomeLink : '#';
|
var path = meta.config.welcomeLink ? meta.config.welcomeLink : '#';
|
||||||
@@ -301,8 +302,13 @@ var async = require('async'),
|
|||||||
path: path,
|
path: path,
|
||||||
nid: 'welcome_' + uid
|
nid: 'welcome_' + uid
|
||||||
}, function(err, notification) {
|
}, function(err, notification) {
|
||||||
if (!err && notification) {
|
if (err) {
|
||||||
notifications.push(notification, [uid]);
|
return callback(err);
|
||||||
|
}
|
||||||
|
if (notification) {
|
||||||
|
notifications.push(notification, [uid], callback);
|
||||||
|
} else {
|
||||||
|
callback();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
40
src/views/admin/manage/registration.tpl
Normal file
40
src/views/admin/manage/registration.tpl
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<div class="registration">
|
||||||
|
<div class="col-lg-9">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading"><i class="fa fa-group"></i> Registration Queue</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<table class="table table-striped users-list">
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Email</th>
|
||||||
|
<th>IP</th>
|
||||||
|
<th>Time</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
<!-- BEGIN users -->
|
||||||
|
<tr data-username="{users.username}">
|
||||||
|
<td>
|
||||||
|
{users.username}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{users.email}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{users.ip}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span class="timeago" title="{users.timestamp}"></span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div class="btn-group pull-right">
|
||||||
|
<button class="btn btn-success btn-xs" data-action="accept"><i class="fa fa-check"></i></button>
|
||||||
|
<button class="btn btn-danger btn-xs" data-action="delete"><i class="fa fa-times"></i></button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<!-- END users -->
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -8,6 +8,7 @@
|
|||||||
<li class=''><a href='{config.relative_path}/admin/manage/users/sort-posts'>Top Posters</a></li>
|
<li class=''><a href='{config.relative_path}/admin/manage/users/sort-posts'>Top Posters</a></li>
|
||||||
<li class=''><a href='{config.relative_path}/admin/manage/users/sort-reputation'>Most Reputation</a></li>
|
<li class=''><a href='{config.relative_path}/admin/manage/users/sort-reputation'>Most Reputation</a></li>
|
||||||
<li class=''><a href='{config.relative_path}/admin/manage/users/banned'>Banned</a></li>
|
<li class=''><a href='{config.relative_path}/admin/manage/users/banned'>Banned</a></li>
|
||||||
|
<li class=''><a href='{config.relative_path}/admin/manage/users/registration'>Registration Queue</a></li>
|
||||||
<li class=''><a href='{config.relative_path}/admin/manage/users/search'>User Search</a></li>
|
<li class=''><a href='{config.relative_path}/admin/manage/users/search'>User Search</a></li>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -4,11 +4,6 @@
|
|||||||
<div class="panel-heading">User List</div>
|
<div class="panel-heading">User List</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<form role="form">
|
<form role="form">
|
||||||
<div class="checkbox">
|
|
||||||
<label>
|
|
||||||
<input type="checkbox" data-field="allowRegistration" checked> <strong>Allow local registration</strong>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="checkbox">
|
<div class="checkbox">
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" data-field="allowLocalLogin" checked> <strong>Allow local login</strong>
|
<input type="checkbox" data-field="allowLocalLogin" checked> <strong>Allow local login</strong>
|
||||||
@@ -38,6 +33,15 @@
|
|||||||
<option value="email">Email Only</option>
|
<option value="email">Email Only</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Registration Type</label>
|
||||||
|
<select class="form-control" data-field="registrationType">
|
||||||
|
<option value="normal">Normal</option>
|
||||||
|
<option value="admin-approval">Admin Approval</option>
|
||||||
|
<option value="disabled">No registration</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
12
src/views/emails/registration_accepted.tpl
Normal file
12
src/views/emails/registration_accepted.tpl
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<p>[[email:greeting_with_name, {username}]],</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>[[email:welcome.text1, {site_title}]]</strong>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>[[email:welcome.text3]]</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
[[email:closing]]<br />
|
||||||
|
<strong>{site_title}</strong>
|
||||||
|
</p>
|
||||||
9
src/views/emails/registration_accepted_plaintext.tpl
Normal file
9
src/views/emails/registration_accepted_plaintext.tpl
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
[[email:greeting_with_name, {username}]],
|
||||||
|
|
||||||
|
[[email:welcome.text1, {site_title}]]
|
||||||
|
|
||||||
|
[[email:welcome.text3]]
|
||||||
|
|
||||||
|
|
||||||
|
[[email:closing]]
|
||||||
|
{site_title}
|
||||||
Reference in New Issue
Block a user