}
});
socket.on('joinanonymously', function(nickname, roomname) {
- if (!socket.nickname && typeof nickname === 'string' && nickname !== '' &&
- ~config.rooms.indexOf(roomname)) {
+ if (!socket.nickname && typeof nickname === 'string' && ~config.rooms.indexOf(roomname)) {
rooms[roomname].setNickName(socket, nickname);
}
});
, config = require('../config')
, fifolength = config.songsinarun * config.gameswithnorepeats
, io
+ , isUsername = require('./utils').isUsername
, sockets
, songsdb = clients.songs
, usersdb = clients.users;
this.setNickName = function(socket, nickname) {
var feedback = null;
- if (nickname.length > 15) {
- feedback = '<span class="label label-important">That name is too long.</span>';
- }
- else if (nickname === 'binb') {
+ if (nickname === 'binb') {
feedback = '<span class="label label-important">That name is reserved.</span>';
}
+ else if (!isUsername(nickname)) {
+ feedback = '<span class="label label-important">Name must contain only ';
+ feedback += 'alphanumeric characters.</span>';
+ }
else if (sockets[nickname]) {
feedback = '<span class="label label-important">Name already taken.</span>';
}
};
/**
- * Check if the provided string is a valid email address.
+ * Check whether a given string is a valid email address.
*/
exports.isEmail = function(str) {
return filter.test(str);
};
+/**
+ * Check whether a given string is a well formed username.
+ */
+
+exports.isUsername = function(str) {
+ var filter = /^[a-zA-Z0-9\-_]{1,15}$/;
+ return filter.test(str);
+};
+
/**
* Get a random slogan.
*/
"start": "app.js"
},
"subdomain": "binb",
- "version": "0.3.5-6"
+ "version": "0.3.5-7"
}
for(var i=0;i<3;i++) {
if (podium[i]) {
- var playername = podium[i].nickname.encodeEntities();
html += '<tr><td><div class="icons medals rank'+(i+1)+'"></div></td>';
- html += '<td class="name">'+playername+'</td>';
+ html += '<td class="name">'+podium[i].nickname+'</td>';
html += '<td>'+podium[i].points+'</td>';
html += '<td>'+podium[i].golds+'</td><td>'+podium[i].silvers+'</td>';
html += '<td>'+podium[i].bronzes+'</td><td>'+podium[i].guessed+'</td>';
// Prompt for name and send it
var joinAnonymously = function(msg) {
if (/nickname\s*\=/.test(document.cookie) && !msg) {
- var encodednickname = document.cookie.replace(/.*nickname\s*\=\s*([^;]*);?.*/, '$1');
- nickname = decodeURIComponent(encodednickname);
+ var nickname = document.cookie.replace(/.*nickname\s*\=\s*([^;]*);?.*/, '$1');
return socket.emit('joinanonymously', nickname, roomname);
}
html += '<h3>You are joining the '+roomname+' room</h3></div>';
html += '<div class="modal-body"><p>'+(msg || "What's your name?")+'</p></div>';
html += '<div class="modal-footer relative">';
- html += '<input id="login" class="" type="text" name="nickname" />';
+ html += '<input id="login" maxlength="15" type="text" name="nickname" />';
html += '<button id="join" class="btn btn-success">';
html += '<i class="icon-user icon-white"></i> Join the game</button>';
html += '<span class="divider"><span>or</span></span>';
var button = $('#join');
button.click(function() {
- var val = $.trim(login.val());
- if (val !== '') {
- nickname = val;
+ if ($.trim(login.val()) !== '') {
+ nickname = login.val();
socket.emit('joinanonymously', nickname, roomname);
}
else {
// Successfully joined the room
var ready = function(usersData, trackscount, loggedin) {
if (!loggedin && !/nickname\s*\=/.test(document.cookie)) {
- document.cookie = 'nickname='+encodeURIComponent(nickname)+';path=/;';
+ document.cookie = 'nickname='+nickname+';path=/;';
}
DOM.modal.modal('hide').empty();
li.append(pvt, username, points, roundrank, roundpointsel, guesstime);
if (user.registered) {
- var href = 'href="/user/'+encodeURIComponent(user.nickname)+'"';
+ var href = 'href="/user/'+user.nickname+'"';
pvt.after('<a class="icons registered" target="_blank" '+href+'></a>');
}
DOM.users.append(li);
// Convert any URLs in text into clickable links
var urlize = function(text) {
- if (text.match(urlregex)) {
+ if (urlregex.test(text)) {
var html = '';
var splits = text.split(urlregex);
for (var i=0; i<splits.length; i++) {
var escapedsplit = splits[i].encodeEntities();
- if (splits[i].match(urlregex)) {
+ if (urlregex.test(splits[i])) {
html += '<a target="_blank" href="'+escapedsplit+'">'+escapedsplit+'</a>';
continue;
}
(function() {
var appendResults = function(data, leaderboard, offset, type) {
for (var i=0; i<data.length; i+=2) {
- var link = $('<a href="/user/'+encodeURIComponent(data[i])+'"></a>').text(data[i])
+ var link = $('<a href="/user/'+data[i]+'"></a>').text(data[i])
, col1 = '<td>'+(++offset)+'</td>'
, col2 = $('<td></td>').append(link)
, col3 = (type === 'points')
}
var errors = {};
-
- req.body.oldpassword = req.body.oldpassword.trim();
- if (req.body.oldpassword === '') {
+
+ if (req.body.oldpassword.trim() === '') {
errors.oldpassword = "can't be empty";
}
- if (!/^[\x21-\x7E]{6,15}$/.test(req.body.newpassword)) {
- errors.newpassword = '6 to 15 characters required';
+ if (req.body.newpassword.length < 6) {
+ errors.newpassword = 'must be at least 6 characters long';
}
else if(req.body.newpassword === req.body.oldpassword) {
errors.newpassword = "can't be changed to the old one";
}
var errors = {};
-
- req.body.username = req.body.username.trim(); // Username sanitization
- req.body.password = req.body.password.trim(); // Password sanitization
- if (req.body.username === '') {
+
+ if (req.body.username.trim() === '') {
errors.username = "can't be empty";
}
- if (req.body.password === '') {
+ if (req.body.password.trim() === '') {
errors.password = "can't be empty";
}
}
var errors = {};
-
- req.body.username = req.body.username.trim(); // Username sanitization
+
if (req.body.username === 'binb') {
errors.username = 'is reserved';
}
- else if (/\.\.?/.test('/'+req.body.username+'/')) {
- // Username contains dot segments which will be removed by URL normalization
- errors.username = 'is not valid';
- }
- else if (!/^[^\x00-\x1F\x7F]{1,15}$/.test(req.body.username)) {
- errors.username = '1 to 15 characters required';
+ else if (!utils.isUsername(req.body.username)) {
+ errors.username = 'must contain only alphanumeric characters';
}
if (!utils.isEmail(req.body.email)) {
errors.email = 'is not an email address';
}
- if (!/^[\x21-\x7E]{6,15}$/.test(req.body.password)) {
- errors.password = '6 to 15 characters required';
+ if (req.body.password.length < 6) {
+ errors.password = 'must be at least 6 characters long';
}
if (req.body.captcha !== req.session.captchacode) {
errors.captcha = 'no match';
var errors = {};
// Validate new password
- if (!/^[\x21-\x7E]{6,15}$/.test(req.body.password)) {
- errors.password = '6 to 15 characters required';
+ if (req.body.password.length < 6) {
+ errors.password = 'must be at least 6 characters long';
}
// Check token availability
if (!req.query.token) {
a(href="/") Home
li.dropdown
a.dropdown-toggle(data-toggle="dropdown", href="#")
- | Logged in as #{loggedin.replace(/&/g, '&')}
+ | Logged in as #{loggedin}
span.caret
ul.dropdown-menu
li
- a(href="/user/#{encodeURIComponent(loggedin)}", target="_blank") Profile
+ a(href="/user/#{loggedin}", target="_blank") Profile
li
a(href="/logout") Logout
- if (locals.loggedin)
li.dropdown
a.dropdown-toggle(data-toggle="dropdown", href="#")
- | Logged in as #{loggedin.replace(/&/g, '&')}
+ | Logged in as #{loggedin}
span.caret
ul.dropdown-menu
li
- a(href="/user/#{encodeURIComponent(loggedin)}", target="_blank") Profile
+ a(href="/user/#{loggedin}", target="_blank") Profile
li
a(href="/changepasswd") Change password
li
tr
td #{i+1}
td
- a(href="/user/#{encodeURIComponent(user.username)}")
- | #{user.username.replace(/&/g, '&')}
+ a(href="/user/#{user.username}") #{user.username}
td #{user.totpoints}
.loading
.loading-block
tr
td #{i+1}
td
- a(href="/user/#{encodeURIComponent(user.username)}")
- | #{user.username.replace(/&/g, '&')}
+ a(href="/user/#{user.username}") #{user.username}
td
i.icon-time
| #{user.bestguesstime} sec
- if (locals.loggedin)
li.dropdown
a.dropdown-toggle(data-toggle="dropdown", href="#")
- | Logged in as #{loggedin.replace(/&/g, '&')}
+ | Logged in as #{loggedin}
span.caret
ul.dropdown-menu
li
- a(href="/user/#{encodeURIComponent(loggedin)}", target="_blank") Profile
+ a(href="/user/#{loggedin}", target="_blank") Profile
li
a(href="/changepasswd?followup=/#{roomname}") Change password
li
extends layout
block title
- title binb :: #{username.replace(/&/g, '&')} info
+ title binb :: #{username} info
block brand
a.brand(href="#")
section
.row
.span7.offset1
- .profile #{username.replace(/&/g, '&')}
+ .profile #{username}
.icons.img
div member since #{joindate}
section