diff --git a/package.json b/package.json
index 25348c8e8b..11e0acd1d7 100644
--- a/package.json
+++ b/package.json
@@ -30,6 +30,7 @@
"daemon": "~1.1.0",
"express": "^4.9.5",
"express-session": "^1.8.2",
+ "express-useragent": "0.2.4",
"heapdump": "^0.3.0",
"html-to-text": "1.5.0",
"jimp": "0.2.20",
diff --git a/public/language/en_GB/error.json b/public/language/en_GB/error.json
index 1625aef3a5..7644960602 100644
--- a/public/language/en_GB/error.json
+++ b/public/language/en_GB/error.json
@@ -118,5 +118,7 @@
"wrong-login-type-email": "Please use your email to login",
"wrong-login-type-username": "Please use your username to login",
- "invite-maximum-met": "You have invited the maximum amount of people (%1 out of %2)."
+ "invite-maximum-met": "You have invited the maximum amount of people (%1 out of %2).",
+
+ "no-session-found": "No login session found!"
}
diff --git a/public/language/en_GB/global.json b/public/language/en_GB/global.json
index 8ef1ff7496..e6f4a35ee6 100644
--- a/public/language/en_GB/global.json
+++ b/public/language/en_GB/global.json
@@ -107,5 +107,7 @@
"follow": "Follow",
"unfollow": "Unfollow",
"delete_all": "Delete All",
- "map": "Map"
+ "map": "Map",
+ "sessions": "Login Sessions",
+ "ip_address": "IP Address"
}
diff --git a/public/src/client/account/settings.js b/public/src/client/account/settings.js
index 840f498259..04312f2823 100644
--- a/public/src/client/account/settings.js
+++ b/public/src/client/account/settings.js
@@ -2,7 +2,7 @@
/*global define, socket, app, ajaxify, config*/
-define('forum/account/settings', ['forum/account/header'], function(header) {
+define('forum/account/settings', ['forum/account/header', 'components', 'csrf'], function(header, components, csrf) {
var AccountSettings = {};
AccountSettings.init = function() {
@@ -72,6 +72,9 @@ define('forum/account/settings', ['forum/account/header'], function(header) {
$('[data-property="homePageRoute"]').on('change', toggleCustomRoute);
toggleCustomRoute();
+
+ components.get('user/sessions').find('.timeago').timeago();
+ prepareSessionRevoking();
};
function toggleCustomRoute() {
@@ -83,5 +86,28 @@ define('forum/account/settings', ['forum/account/header'], function(header) {
}
}
+ function prepareSessionRevoking() {
+ components.get('user/sessions').on('click', '[data-action]', function() {
+ var parentEl = $(this).parents('[data-uuid]'),
+ uuid = parentEl.attr('data-uuid');
+
+ if (uuid) {
+ // This is done via DELETE because a user shouldn't be able to
+ // revoke his own session! This is what logout is for
+ $.ajax({
+ url: config.relative_path + '/user/' + ajaxify.data.userslug + '/session/' + uuid,
+ method: 'delete',
+ headers: {
+ 'x-csrf-token': csrf.get()
+ }
+ }).done(function() {
+ parentEl.remove();
+ }).fail(function(err) {
+ app.alertError(err.responseText);
+ })
+ }
+ });
+ }
+
return AccountSettings;
});
diff --git a/public/src/modules/helpers.js b/public/src/modules/helpers.js
index ed27369c27..ee1a6aed17 100644
--- a/public/src/modules/helpers.js
+++ b/public/src/modules/helpers.js
@@ -191,6 +191,58 @@
}
};
+ helpers.userAgentIcons = function(data) {
+ var icons = '';
+
+ switch(data.platform) {
+ case 'Linux':
+ icons += '';
+ break;
+ case 'Microsoft Windows':
+ icons += '';
+ break;
+ case 'Mac':
+ icons += '';
+ break;
+ case 'Android':
+ icons += '';
+ break;
+ case 'iPad':
+ icons += '';
+ break;
+ case 'iPod': // intentional fall-through
+ case 'iPhone':
+ icons += '';
+ break;
+ default:
+ icons += '';
+ break;
+ }
+
+ switch(data.browser) {
+ case 'Chrome':
+ icons += '';
+ break;
+ case 'Firefox':
+ icons += '';
+ break;
+ case 'Safari':
+ icons += '';
+ break;
+ case 'IE':
+ icons += '';
+ break;
+ case 'Edge':
+ icons += '';
+ break;
+ default:
+ icons += '';
+ break;
+ }
+
+ return icons;
+ }
+
exports.register = function() {
var templates;
diff --git a/public/vendor/fontawesome/fonts/FontAwesome.otf b/public/vendor/fontawesome/fonts/FontAwesome.otf
index 681bdd4d4c..3ed7f8b48a 100644
Binary files a/public/vendor/fontawesome/fonts/FontAwesome.otf and b/public/vendor/fontawesome/fonts/FontAwesome.otf differ
diff --git a/public/vendor/fontawesome/fonts/fontawesome-webfont.eot b/public/vendor/fontawesome/fonts/fontawesome-webfont.eot
index a30335d748..9b6afaedc0 100644
Binary files a/public/vendor/fontawesome/fonts/fontawesome-webfont.eot and b/public/vendor/fontawesome/fonts/fontawesome-webfont.eot differ
diff --git a/public/vendor/fontawesome/fonts/fontawesome-webfont.svg b/public/vendor/fontawesome/fonts/fontawesome-webfont.svg
index 6fd19abcb9..d05688e9e2 100644
--- a/public/vendor/fontawesome/fonts/fontawesome-webfont.svg
+++ b/public/vendor/fontawesome/fonts/fontawesome-webfont.svg
@@ -1,6 +1,6 @@
-