Skip to content

Commit 618e587

Browse files
committed
Close RocketChat#144; HTTP Basic Authentication support
1 parent 8c51337 commit 618e587

File tree

7 files changed

+94
-13
lines changed

7 files changed

+94
-13
lines changed

.eslintrc.js

+3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ module.exports = {
66
'node': true,
77
'jquery': true
88
},
9+
'parserOptions': {
10+
'sourceType': 'module'
11+
},
912
'rules': {
1013
// 'no-alert': 0,
1114
// 'no-array-constructor': 0,

app/scripts/servers.js

+36-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
/* globals $ */
22

33
import { EventEmitter } from 'events';
4+
import { remote } from 'electron';
5+
const remoteServers = remote.require('./servers');
46

57
class Servers extends EventEmitter {
68
constructor() {
@@ -61,6 +63,7 @@ class Servers extends EventEmitter {
6163
}
6264

6365
this._hosts = hosts;
66+
remoteServers.loadServers(this._hosts);
6467
this.emit('loaded');
6568
}
6669

@@ -93,13 +96,21 @@ class Servers extends EventEmitter {
9396
resolved = true;
9497
console.log('HostUrl valid', hostUrl);
9598
resolve();
96-
},function(request) {
99+
}, function(request) {
100+
if (request.status === 401) {
101+
let authHeader = request.getResponseHeader('www-authenticate');
102+
if (authHeader && authHeader.toLowerCase().indexOf('basic ') === 0) {
103+
resolved = true;
104+
console.log('HostUrl needs basic auth', hostUrl);
105+
reject('basic-auth');
106+
}
107+
}
97108
if (resolved) {
98109
return;
99110
}
100111
resolved = true;
101112
console.log('HostUrl invalid', hostUrl);
102-
reject(request.status);
113+
reject('invalid');
103114
});
104115
if (timeout) {
105116
setTimeout(function() {
@@ -108,7 +119,7 @@ class Servers extends EventEmitter {
108119
}
109120
resolved = true;
110121
console.log('Validating hostUrl TIMEOUT', hostUrl);
111-
reject();
122+
reject('timeout');
112123
}, timeout);
113124
}
114125
});
@@ -123,26 +134,45 @@ class Servers extends EventEmitter {
123134
addHost(hostUrl) {
124135
var hosts = this.hosts;
125136

137+
let match = hostUrl.match(/^(https?:\/\/)([^:]+):([^@]+)@(.+)$/);
138+
let username;
139+
let password;
140+
let authUrl;
141+
if (match) {
142+
authUrl = hostUrl;
143+
hostUrl = match[1] + match[4];
144+
username = match[2];
145+
password = match[3];
146+
}
147+
126148
if (this.hostExists(hostUrl) === true) {
127149
return false;
128150
}
129151

130152
hosts[hostUrl] = {
131153
title: hostUrl,
132-
url: hostUrl
154+
url: hostUrl,
155+
authUrl: authUrl,
156+
username: username,
157+
password: password
133158
};
134159
this.hosts = hosts;
135160

161+
remoteServers.loadServers(this.hosts);
162+
136163
this.emit('host-added', hostUrl);
137164

138-
return true;
165+
return hostUrl;
139166
}
140167

141168
removeHost(hostUrl) {
142169
var hosts = this.hosts;
143170
if (hosts[hostUrl]) {
144171
delete hosts[hostUrl];
145172
this.hosts = hosts;
173+
174+
remoteServers.loadServers(this.hosts);
175+
146176
if (this.active === hostUrl) {
147177
this.clearActive();
148178
}
@@ -164,7 +194,7 @@ class Servers extends EventEmitter {
164194
}
165195

166196
restoreActive() {
167-
servers.setActive(servers.active);
197+
this.setActive(this.active);
168198
}
169199

170200
clearActive() {

app/scripts/sidebar.js

+10-1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ class SideBar extends EventEmitter {
4343
this.setLabel(hostUrl, title);
4444
});
4545

46+
webview.on('dom-ready', (hostUrl) => {
47+
this.setImage(hostUrl);
48+
});
49+
4650
if (this.isHidden()) {
4751
this.hide();
4852
} else {
@@ -71,7 +75,7 @@ class SideBar extends EventEmitter {
7175
img.style.display = 'initial';
7276
initials.style.display = 'none';
7377
};
74-
img.src = `${host.url}/assets/favicon.svg?v=${Math.round(Math.random()*10000)}`;
78+
// img.src = `${host.url}/assets/favicon.svg?v=${Math.round(Math.random()*10000)}`;
7579

7680
var hotkey = document.createElement('div');
7781
hotkey.classList.add('name');
@@ -119,6 +123,11 @@ class SideBar extends EventEmitter {
119123
Menu.setApplicationMenu(Menu.buildFromTemplate(menuTemplate));
120124
}
121125

126+
setImage(hostUrl) {
127+
const img = this.getByUrl(hostUrl).querySelector('img');
128+
img.src = `${hostUrl}/assets/favicon.svg?v=${Math.round(Math.random()*10000)}`;
129+
}
130+
122131
remove(hostUrl) {
123132
var el = this.getByUrl(hostUrl);
124133
if (el) {

app/scripts/start.js

+17-6
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,22 @@ export var start = function() {
6868
button.value = 'Connect';
6969
button.disabled = false;
7070
resolve();
71-
}, function() {
71+
}, function(status) {
7272
// If the url begins with HTTP, mark as invalid
73-
if (/^http:\/\/.+/.test(host)) {
73+
if (/^http:\/\/.+/.test(host) || status === 'basic-auth') {
7474
button.value = 'Invalid url';
7575
invalidUrl.style.display = 'block';
76+
switch (status) {
77+
case 'basic-auth':
78+
invalidUrl.innerHTML = 'Auth needed, try <b>username:password@host</b>';
79+
break;
80+
case 'invalid':
81+
invalidUrl.innerHTML = 'No valid server found at the URL';
82+
break;
83+
case 'timeout':
84+
invalidUrl.innerHTML = 'Timeout trying to connect';
85+
break;
86+
}
7687
hostField.classList.add('wrong');
7788
reject();
7889
return;
@@ -86,7 +97,7 @@ export var start = function() {
8697

8798
// If the url isn't localhost, don't have dots and don't have protocol
8899
// try as a .rocket.chat subdomain
89-
if (!/(^https?:\/\/)|(\.)|(^localhost(:\d+)?$)/.test(host)) {
100+
if (!/(^https?:\/\/)|(\.)|(^([^:]+:[^@]+@)?localhost(:\d+)?$)/.test(host)) {
90101
hostField.value = `https://${host}.rocket.chat`;
91102
return execValidation();
92103
}
@@ -115,12 +126,12 @@ export var start = function() {
115126
url = defaultInstance;
116127
}
117128

118-
if (servers.addHost(url) === true) {
129+
url = servers.addHost(url);
130+
if (url !== false) {
119131
sidebar.show();
132+
servers.setActive(url);
120133
}
121134

122-
servers.setActive(url);
123-
124135
input.value = '';
125136
}, function() {});
126137
};

app/scripts/webview.js

+4
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ class WebView extends EventEmitter {
6565
}
6666
});
6767

68+
webviewObj.addEventListener('dom-ready', () => {
69+
this.emit('dom-ready', host.url);
70+
});
71+
6872
this.webviewParentElement.appendChild(webviewObj);
6973

7074
webviewObj.src = host.lastPath || host.url;

app/servers.js

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { app } from 'electron';
2+
3+
let servers = {};
4+
5+
export default {
6+
loadServers(s) {
7+
servers = s;
8+
},
9+
10+
getServers() {
11+
return servers;
12+
}
13+
};
14+
15+
app.on('login', function(event, webContents, request, authInfo, callback) {
16+
for (let url in servers) {
17+
const server = servers[url];
18+
if (request.url.indexOf(url) === 0 && server.username) {
19+
callback(server.username, server.password);
20+
break;
21+
}
22+
}
23+
});

tasks/build/build.js

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ gulp.task('copy-watch', copyTask);
5454
var bundleApplication = function () {
5555
return Q.all([
5656
bundle(srcDir.path('background.js'), destDir.path('background.js')),
57+
bundle(srcDir.path('servers.js'), destDir.path('servers.js')),
5758
bundle(srcDir.path('app.js'), destDir.path('app.js')),
5859
]);
5960
};

0 commit comments

Comments
 (0)