]> git.example.dev Git - binbsis50.git/commitdiff
changed username policy to allow only unreserved URI characters
authorLuigi Pinca <luigipinca@gmail.com>
Fri, 22 Feb 2013 18:28:02 +0000 (19:28 +0100)
committerLuigi Pinca <luigipinca@gmail.com>
Fri, 22 Feb 2013 18:28:02 +0000 (19:28 +0100)
12 files changed:
app.js
lib/room.js
lib/utils.js
package.json
public/js/app.js
public/js/leaderboards.js
routes/user.js
views/changepasswd.jade
views/home.jade
views/leaderboards.jade
views/room.jade
views/user.jade

diff --git a/app.js b/app.js
index f950a07470351a3d88ddfe53240f3289ebfa0861..9c3cc6c3a5b0f2aa31e1c1623cf5956714754f85 100644 (file)
--- a/app.js
+++ b/app.js
@@ -127,8 +127,7 @@ io.sockets.on('connection', function(socket) {
         }
     });
     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);
         }
     });
index 3163df203fd608e6c591d5ea360145ff220675ef..75d26b2bf9bdd4730ab750be424bc3edce8c887f 100644 (file)
@@ -8,6 +8,7 @@ var amatch = require('./match')
     , config = require('../config')
     , fifolength = config.songsinarun * config.gameswithnorepeats
     , io
+    , isUsername = require('./utils').isUsername
     , sockets
     , songsdb = clients.songs
     , usersdb = clients.users;
@@ -405,12 +406,13 @@ function Room(roomname) {
     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>';
         }
index b5118ec2e9a59e417728eb0a2f2493f54d5fb991..d5b81cab11a6bcc38f4ac66db192161a0ddfceab 100644 (file)
@@ -22,7 +22,7 @@ exports.buildLeaderboards = function(pointsresults, timesresults) {
 };
 
 /**
- * Check if the provided string is a valid email address.
+ * Check whether a given string is a valid email address.
  */
 
 exports.isEmail = function(str) {
@@ -31,6 +31,15 @@ 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.
  */
index 40758d34bb5a10da389d1c23d643c7b1d6644ffb..3aa5d9ee405990bf1ceb20d41ee8b061ffe86360 100644 (file)
@@ -21,5 +21,5 @@
     "start": "app.js"
   },
   "subdomain": "binb",
-  "version": "0.3.5-6"
+  "version": "0.3.5-7"
 }
index ebb4bf04f35f5433470ba4b6345eb56a8468a1b1..e899f8315223959233e9e8e98cde47ff8364cc83 100644 (file)
 
         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;
                 }
index d009716f3e51d62b2e24c6ea1513a3d6ccddb614..81d84b67275c9f46ce297422f66e3ea54469c627 100644 (file)
@@ -1,7 +1,7 @@
 (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')
index 43b66295e51e28b2529a50a2002243f986de0b6f..c30ec04b71f5f1d34b793e508c369b93615515eb 100644 (file)
@@ -65,13 +65,12 @@ exports.validateChangePasswd = function(req, res, next) {
     }
     
     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";
@@ -123,13 +122,11 @@ exports.validateLogin = function(req, res, next) {
     }
 
     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";
     }
     
@@ -194,23 +191,18 @@ exports.validateSignUp = function(req, res, next) {
     }
 
     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';
@@ -353,8 +345,8 @@ exports.resetPasswd = function(req, res) {
     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) {
index 031e04a68a325b359a6a8021a46f5762b5bed9a9..01c714c7ac95853e7d26504425d2d5514199c00c 100644 (file)
@@ -9,11 +9,11 @@ block nav
             a(href="/") Home
         li.dropdown
             a.dropdown-toggle(data-toggle="dropdown", href="#")
-                | Logged in as #{loggedin.replace(/&/g, '&amp;')
+                | 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
 
index 1a061fdb8e39fd39da344e12995f4084d52ab4b7..cbbf765950a6b9d8c504d7668005dda00e77de31 100644 (file)
@@ -14,11 +14,11 @@ block nav
         - if (locals.loggedin)
             li.dropdown
                 a.dropdown-toggle(data-toggle="dropdown", href="#")
-                    | Logged in as #{loggedin.replace(/&/g, '&amp;')
+                    | 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
index 2dfef063efebfa85855ec80bcf3173a77294e922..d8e24d83b461269c76d446f3d51fce0463a3eaaa 100644 (file)
@@ -24,8 +24,7 @@ block sections
                                 tr
                                     td #{i+1}
                                     td
-                                        a(href="/user/#{encodeURIComponent(user.username)}")
-                                            | #{user.username.replace(/&/g, '&amp;')}
+                                        a(href="/user/#{user.username}") #{user.username}
                                     td #{user.totpoints}
                     .loading
                         .loading-block
@@ -40,8 +39,7 @@ block sections
                                 tr
                                     td #{i+1}
                                     td
-                                        a(href="/user/#{encodeURIComponent(user.username)}")
-                                            | #{user.username.replace(/&/g, '&amp;')}
+                                        a(href="/user/#{user.username}") #{user.username}
                                     td 
                                         i.icon-time
                                         |  #{user.bestguesstime} sec
index 14605d7c18b33d0b47358dbbd7442f78b1b49986..7a558d6eb113544b7ee572b0c74f8f8741a9175d 100644 (file)
@@ -27,11 +27,11 @@ block nav
         - if (locals.loggedin)
             li.dropdown
                 a.dropdown-toggle(data-toggle="dropdown", href="#")
-                    | Logged in as #{loggedin.replace(/&/g, '&amp;')
+                    | 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
index 38b2b6df08bf47f446a24c438e17123962bc3b92..01cb36ff73f378c536eb7fd6de3470ded1a983c5 100644 (file)
@@ -1,7 +1,7 @@
 extends layout
 
 block title
-    title binb :: #{username.replace(/&/g, '&amp;')} info
+    title binb :: #{username} info
     
 block brand
     a.brand(href="#")
@@ -11,7 +11,7 @@ block sections
     section
         .row
             .span7.offset1
-                .profile #{username.replace(/&/g, '&amp;')}
+                .profile #{username}
                     .icons.img
                 div member since #{joindate}
     section