Skip to content

Commit 21e0591

Browse files
authored
Merge pull request #8128 from nightscout/dev
Dev branch for next release, 15.0.2
2 parents f46f869 + 44f70db commit 21e0591

File tree

7 files changed

+106
-31
lines changed

7 files changed

+106
-31
lines changed

lib/api3/alarmSocket.js

+65-19
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,11 @@ function AlarmSocket (app, env, ctx) {
4646
socket.on('subscribe', function onSubscribe (message, returnCallback) {
4747
self.subscribe(socket, message, returnCallback);
4848
});
49-
49+
5050
});
5151

52+
// Turns all notifications on the event bus back into events to be
53+
// broadcast to clients.
5254
ctx.bus.on('notification', self.emitNotification);
5355
};
5456

@@ -65,7 +67,7 @@ function AlarmSocket (app, env, ctx) {
6567
self.subscribe = function subscribe (socket, message, returnCallback) {
6668
const shouldCallBack = typeof(returnCallback) === 'function';
6769

68-
// Native client
70+
// Native client
6971
if (message && message.accessToken) {
7072
return ctx.authorization.resolveAccessToken(message.accessToken, function resolveFinishForToken (err, auth) {
7173
if (err) {
@@ -76,24 +78,47 @@ function AlarmSocket (app, env, ctx) {
7678
}
7779
return err;
7880
} else {
79-
// Subscribe for acking alarms
80-
socket.on('ack', function onAck (level, group, silenceTime) {
81-
ctx.notifications.ack(level, group, silenceTime, true);
82-
console.info(LOG + 'ack received ' + level + ' ' + group + ' ' + silenceTime);
83-
});
84-
85-
var okResponse = { success: true, message: 'Subscribed for alarms' }
81+
// Subscribe for acking alarms
82+
// Client sends ack, which sends a notificaiton through our internal bus
83+
socket.on('ack', function onAck (level, group, silenceTime) {
84+
ctx.notifications.ack(level, group, silenceTime, true);
85+
console.info(LOG + 'ack received ' + level + ' ' + group + ' ' + silenceTime);
86+
});
87+
88+
var okResponse = { success: true, message: 'Subscribed for alarms' }
8689
if (shouldCallBack) {
8790
returnCallback(okResponse);
8891
}
8992
return okResponse;
9093
}
9194
});
9295
}
93-
94-
// Web client (jwt access token or api_hash)
95-
if (message && (message.jwtToken || message.secret)) {
96+
97+
if (!message) { message = {}; }
98+
// Web client (jwt access token or api_hash)
99+
/*
100+
* On the web: a client may have saved a secret or using a jwtToken, or may have none.
101+
* Some pages will automatically prompt for authorization, when needed.
102+
* To make the main homepage require authorization as well, set
103+
* AUTHENTICATION_PROMPT_ON_LOAD=true.
104+
*
105+
* If there is missing authorization when authorization is required,
106+
* rejecting the attempt in order to trigger a prompt on the client.
107+
* If there is no authorization required, or there are available
108+
* credentials, attempt to resolve the available permissions.
109+
* When processing ACK messages that dismiss alarms, Authorization should be
110+
* required.
111+
*/
112+
var shouldTry = true;
113+
if (env.settings.authenticationPromptOnLoad) {
114+
if (!message.jwtToken && !message.secret) {
115+
shouldTry = false;
116+
}
117+
}
118+
119+
if (message && shouldTry) {
96120
return ctx.authorization.resolve({ api_secret: message.secret, token: message.jwtToken, ip: getRemoteIP(socket.request) }, function resolveFinish (err, auth) {
121+
97122
if (err) {
98123
console.log(`${LOG_ERROR} Authorization failed for jwtToken:`, message.jwtToken);
99124

@@ -102,13 +127,34 @@ function AlarmSocket (app, env, ctx) {
102127
}
103128
return err;
104129
} else {
105-
// Subscribe for acking alarms
106-
socket.on('ack', function onAck (level, group, silenceTime) {
107-
ctx.notifications.ack(level, group, silenceTime, true);
108-
console.info(LOG + 'ack received ' + level + ' ' + group + ' ' + silenceTime);
109-
});
110-
111-
var okResponse = { success: true, message: 'Subscribed for alarms' }
130+
var perms = {
131+
read: ctx.authorization.checkMultiple('api:*:read', auth.shiros)
132+
, ack: ctx.authorization.checkMultiple('notifications:*:ack', auth.shiros)
133+
};
134+
// Subscribe for acking alarms
135+
// TODO: does this produce double ACK after the authorizing? Only if reconnecting?
136+
// TODO: how will perms get updated after authorizing?
137+
socket.on('ack', function onAck (level, group, silenceTime) {
138+
if (perms.ack) {
139+
// This goes through the server-wide event bus.
140+
ctx.notifications.ack(level, group, silenceTime, true);
141+
console.info(LOG + 'ack received ' + level + ' ' + group + ' ' + silenceTime);
142+
} else {
143+
// TODO: send a message to client to silence locally, but not
144+
// globally, and request authorization.
145+
// This won't go through th event bus.
146+
// var acked = { silenceTime, group, level };
147+
// socket.emit('authorization_needed', acked);
148+
}
149+
});
150+
/* TODO: need to know when to update the permissions.
151+
// Can we use
152+
socket.on('resubscribe', function update_permissions ( ) {
153+
// perms = { ... };
154+
});
155+
*/
156+
157+
var okResponse = { success: true, message: 'Subscribed for alarms', ...perms };
112158
if (shouldCallBack) {
113159
returnCallback(okResponse);
114160
}

lib/client/index.js

+29-9
Original file line numberDiff line numberDiff line change
@@ -1146,15 +1146,13 @@ client.load = function load (serverSettings, callback) {
11461146
}
11471147

11481148
console.log('Subscribed for alarms', data);
1149-
if (client.settings.authenticationPromptOnLoad && !data.success) {
1150-
client.hashauth.requestAuthentication(function afterRequest () {
1151-
client.hashauth.updateSocketAuth();
1152-
if (callback) {
1153-
callback();
1154-
}
1155-
});
1156-
} else if (callback) {
1157-
callback();
1149+
var shouldAuthenticationPromptOnLoad = client.settings.authenticationPromptOnLoad ;
1150+
if (!data.success) {
1151+
if (!data.read || !hasRequiredPermission() || shouldAuthenticationPromptOnLoad) {
1152+
return client.hashauth.requestAuthentication(function afterRequest () {
1153+
return client.hashauth.updateSocketAuth();
1154+
});
1155+
}
11581156
}
11591157
}
11601158
);
@@ -1235,6 +1233,28 @@ client.load = function load (serverSettings, callback) {
12351233
stopAlarm(false, null, notify);
12361234
}
12371235
});
1236+
/*
1237+
*
1238+
// TODO: When an unauthorized client attempts to silence an alarm, we should
1239+
// allow silencing locally, request for authorization, and if the
1240+
// authorization succeeds even republish the ACK notification. something like...
1241+
alarmSocket.on('authorization_needed', function(details) {
1242+
if (alarmInProgress) {
1243+
console.log('clearing alarm');
1244+
stopAlarm(true, details.silenceTime, currentNotify);
1245+
}
1246+
client.hashauth.requestAuthentication(function afterRequest () {
1247+
console.log("SUCCESSFULLY AUTHORIZED, REPUBLISHED ACK?");
1248+
// easiest way to update permission set on server side is to send another message.
1249+
alarmSocket.emit('resubscribe', currentNotify, details);
1250+
1251+
if (isClient && currentNotify) {
1252+
alarmSocket.emit('ack', currentNotify.level, currentNotify.group, details.silenceTime);
1253+
}
1254+
});
1255+
});
1256+
1257+
*/
12381258

12391259
$('#testAlarms').click(function(event) {
12401260

lib/notifications.js

+6
Original file line numberDiff line numberDiff line change
@@ -185,13 +185,19 @@ function init (env, ctx) {
185185
notifications.ack(1, group, time);
186186
}
187187

188+
/*
189+
* TODO: modify with a local clear, this will clear all connected clients,
190+
* globally
191+
*/
188192
if (sendClear) {
189193
var notify = {
190194
clear: true
191195
, title: 'All Clear'
192196
, message: group + ' - ' + ctx.levels.toDisplay(level) + ' was ack\'d'
193197
, group: group
194198
};
199+
// When web client sends ack, this translates the websocket message into
200+
// an event on our internal bus.
195201
ctx.bus.emit('notification', notify);
196202
logEmitEvent(notify);
197203
}

lib/profile/profileeditor.js

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ var init = function init () {
1818

1919
client.init(function loaded () {
2020

21+
console.log("LOADING CLIENT INIT");
2122
if (c_profile !== null) {
2223
return; // already loaded so don't load again
2324
}

lib/server/websocket.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,9 @@ function init (env, ctx, server) {
7575
'log level': 0
7676
}).listen(server, {
7777
//these only effect the socket.io.js file that is sent to the client, but better than nothing
78-
'browser client minification': true
78+
// compat with v2 client
79+
allowEIO3: true
80+
, 'browser client minification': true
7981
, 'browser client etag': true
8082
, 'browser client gzip': false
8183
, 'perMessageDeflate': {

package-lock.json

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "nightscout",
3-
"version": "15.0.1",
3+
"version": "15.0.2",
44
"description": "Nightscout acts as a web-based CGM (Continuous Glucose Montinor) to allow multiple caregivers to remotely view a patients glucose data in realtime.",
55
"license": "AGPL-3.0",
66
"author": "Nightscout Team",

0 commit comments

Comments
 (0)