Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions settings/Controller/AuthSettingsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ public function index() {
$data = $token->jsonSerialize();
if ($sessionToken->getId() === $token->getId()) {
$data['canDelete'] = false;
$data['current'] = true;
} else {
$data['canDelete'] = true;
}
Expand Down
130 changes: 96 additions & 34 deletions settings/js/authtoken_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@
*
*/

(function(OC, _, $, Handlebars, moment) {
(function (OC, _, $, Handlebars, moment) {
'use strict';

OC.Settings = OC.Settings || {};

var TEMPLATE_TOKEN =
'<tr data-id="{{id}}">'
+ '<td class="has-tooltip" title="{{name}}"><span class="token-name">{{name}}</span></td>'
+ '<td class="has-tooltip" title="{{title}}"><span class="token-name">{{name}}</span></td>'
+ '<td><span class="last-activity has-tooltip" title="{{lastActivityTime}}">{{lastActivity}}</span></td>'
+ '{{#if canDelete}}'
+ '<td><a class="icon-delete has-tooltip" title="' + t('core', 'Disconnect') + '"></a></td>'
Expand All @@ -50,51 +50,113 @@

_template: undefined,

template: function(data) {
template: function (data) {
if (_.isUndefined(this._template)) {
this._template = Handlebars.compile(TEMPLATE_TOKEN);
}

return this._template(data);
},

initialize: function(options) {
initialize: function (options) {
this.type = options.type;
this.collection = options.collection;

this.on(this.collection, 'change', this.render);
},

render: function() {
render: function () {
var _this = this;

var list = this.$('.token-list');
var tokens = this.collection.filter(function(token) {
var tokens = this.collection.filter(function (token) {
return parseInt(token.get('type'), 10) === _this.type;
});
list.html('');

// Show header only if there are tokens to show
this._toggleHeader(tokens.length > 0);

tokens.forEach(function(token) {
var viewData = token.toJSON();
var ts = viewData.lastActivity * 1000;
viewData.lastActivity = OC.Util.relativeModifiedDate(ts);
viewData.lastActivityTime = OC.Util.formatDate(ts, 'LLL');
tokens.forEach(function (token) {
var viewData = this._formatViewData(token.toJSON());
var html = _this.template(viewData);
var $html = $(html);
$html.find('.has-tooltip').tooltip({container: 'body'});
list.append($html);
});
}.bind(this));
},

toggleLoading: function(state) {
toggleLoading: function (state) {
this.$('.token-list').toggleClass('icon-loading', state);
},

_toggleHeader: function(show) {
_toggleHeader: function (show) {
this.$('.hidden-when-empty').toggleClass('hidden', !show);
},

_formatViewData: function (viewData) {
var ts = viewData.lastActivity * 1000;
viewData.lastActivity = OC.Util.relativeModifiedDate(ts);
viewData.lastActivityTime = OC.Util.formatDate(ts, 'LLL');

// preserve title for cases where we format it further
viewData.title = viewData.name;

// pretty format sync client user agent
var matches = viewData.name.match(/Mozilla\/5\.0 \((\w+)\) (?:mirall|csyncoC)\/(\d+\.\d+\.\d+)/);

var userAgentMap = {
ie: /(?:MSIE|Trident) (\d+)/,
// Microsoft Edge User Agent from https://msdn.microsoft.com/en-us/library/hh869301(v=vs.85).aspx
edge: /^Mozilla\/5\.0 \([^)]+\) AppleWebKit\/[0-9.]+ \(KHTML, like Gecko\) Chrome\/[0-9.]+ (?:Mobile Safari|Safari)\/[0-9.]+ Edge\/[0-9.]+$/,
// Firefox User Agent from https://developer.mozilla.org/en-US/docs/Web/HTTP/Gecko_user_agent_string_reference
firefox: /^Mozilla\/5\.0 \([^)]*(Windows|OS X|Linux)[^)]+\) Gecko\/[0-9.]+ Firefox\/(\d+)(?:\.\d)?$/,
// Chrome User Agent from https://developer.chrome.com/multidevice/user-agent
chrome: /^Mozilla\/5\.0 \([^)]*(Windows|OS X|Linux)[^)]+\) AppleWebKit\/[0-9.]+ \(KHTML, like Gecko\) Chrome\/(\d+)[0-9.]+ (?:Mobile Safari|Safari)\/[0-9.]+$/,
// Safari User Agent from http://www.useragentstring.com/pages/Safari/
safari: /^Mozilla\/5\.0 \([^)]+\) AppleWebKit\/[0-9.]+ \(KHTML, like Gecko\) Version\/([0-9]+)[0-9.]+ Safari\/[0-9.A-Z]+$/,
// Android Chrome user agent: https://developers.google.com/chrome/mobile/docs/user-agent
androidChrome: /Android.*(?:; (.*) Build\/).*Chrome\/(\d+)[0-9.]+/,
iphone: / *CPU +iPhone +OS +(\d+)_\d+ +like +Mac +OS +X */,
iosClient: /^Mozilla\/5\.0 \(iOS\) ownCloud\-iOS.*$/,
androidClient:/^Mozilla\/5\.0 \(Android\) ownCloud\-android.*$/,
// DAVdroid/1.2 (2016/07/03; dav4android; okhttp3) Android/6.0.1
davDroid: /DAVdroid\/([0-9.]+)/
};
var nameMap = {
ie: t('setting', 'Internet Explorer'),
edge: t('setting', 'Edge'),
firefox: t('setting', 'Firefox'),
chrome: t('setting', 'Google Chrome'),
safari: t('setting', 'Safari'),
androidChrome: t('setting', 'Google Chrome for Android'),
iphone: t('setting', 'iPhone'),
iosClient: t('setting', 'iOS Client'),
androidClient: t('setting', 'Android Client'),
davDroid: 'DAVdroid'
};

if (matches) {
viewData.name = t('settings', 'Sync client - {os}', {
os: matches[1],
version: matches[2]
});
}
for (var client in userAgentMap) {
if (matches = viewData.title.match(userAgentMap[client])) {
if (matches[2] && matches[1]) { // version number and os
viewData.name = nameMap[client] + ' ' + matches[2] + ' - ' + matches[1];
}else if (matches[1]) { // only version number
viewData.name = nameMap[client] + ' ' + matches[1];
} else {
viewData.name = nameMap[client];
}
}
}
if (viewData.current) {
viewData.name = t('settings', 'This session');
}
return viewData;
}
});

Expand All @@ -119,12 +181,12 @@

_addingToken: false,

initialize: function(options) {
initialize: function (options) {
this.collection = options.collection;

var tokenTypes = [0, 1];
var _this = this;
_.each(tokenTypes, function(type) {
_.each(tokenTypes, function (type) {
var el = type === 0 ? '#sessions' : '#apppasswords';
_this._views.push(new SubView({
el: el,
Expand All @@ -150,31 +212,31 @@
this._hideAppPasswordBtn.click(_.bind(this._hideToken, this));
},

render: function() {
_.each(this._views, function(view) {
render: function () {
_.each(this._views, function (view) {
view.render();
view.toggleLoading(false);
});
},

reload: function() {
reload: function () {
var _this = this;

_.each(this._views, function(view) {
_.each(this._views, function (view) {
view.toggleLoading(true);
});

var loadingTokens = this.collection.fetch();

$.when(loadingTokens).done(function() {
$.when(loadingTokens).done(function () {
_this.render();
});
$.when(loadingTokens).fail(function() {
$.when(loadingTokens).fail(function () {
OC.Notification.showTemporary(t('core', 'Error while loading browser sessions and device tokens'));
});
},

_addAppPassword: function() {
_addAppPassword: function () {
var _this = this;
this._toggleAddingToken(true);

Expand All @@ -186,7 +248,7 @@
}
});

$.when(creatingToken).done(function(resp) {
$.when(creatingToken).done(function (resp) {
_this.collection.add(resp.deviceToken);
_this.render();
_this._newAppLoginName.val(resp.loginName);
Expand All @@ -195,32 +257,32 @@
_this._newAppPassword.select();
_this._tokenName.val('');
});
$.when(creatingToken).fail(function() {
$.when(creatingToken).fail(function () {
OC.Notification.showTemporary(t('core', 'Error while creating device token'));
});
$.when(creatingToken).always(function() {
$.when(creatingToken).always(function () {
_this._toggleAddingToken(false);
});
},

_onNewTokenLoginNameFocus: function() {
_onNewTokenLoginNameFocus: function () {
this._newAppLoginName.select();
},

_onNewTokenFocus: function() {
_onNewTokenFocus: function () {
this._newAppPassword.select();
},

_hideToken: function() {
_hideToken: function () {
this._toggleFormResult(true);
},

_toggleAddingToken: function(state) {
_toggleAddingToken: function (state) {
this._addingToken = state;
this._addAppPasswordBtn.toggleClass('icon-loading-small', state);
},

_onDeleteToken: function(event) {
_onDeleteToken: function (event) {
var $target = $(event.target);
var $row = $target.closest('tr');
var id = $row.data('id');
Expand All @@ -236,15 +298,15 @@
$row.find('.icon-delete').tooltip('hide');

var _this = this;
$.when(destroyingToken).fail(function() {
$.when(destroyingToken).fail(function () {
OC.Notification.showTemporary(t('core', 'Error while deleting the token'));
});
$.when(destroyingToken).always(function() {
$.when(destroyingToken).always(function () {
_this.render();
});
},

_toggleFormResult: function(showForm) {
_toggleFormResult: function (showForm) {
this._form.toggleClass('hidden', !showForm);
this._result.toggleClass('hidden', showForm);
}
Expand Down