@@ -46,9 +46,11 @@ function AlarmSocket (app, env, ctx) {
46
46
socket . on ( 'subscribe' , function onSubscribe ( message , returnCallback ) {
47
47
self . subscribe ( socket , message , returnCallback ) ;
48
48
} ) ;
49
-
49
+
50
50
} ) ;
51
51
52
+ // Turns all notifications on the event bus back into events to be
53
+ // broadcast to clients.
52
54
ctx . bus . on ( 'notification' , self . emitNotification ) ;
53
55
} ;
54
56
@@ -65,7 +67,7 @@ function AlarmSocket (app, env, ctx) {
65
67
self . subscribe = function subscribe ( socket , message , returnCallback ) {
66
68
const shouldCallBack = typeof ( returnCallback ) === 'function' ;
67
69
68
- // Native client
70
+ // Native client
69
71
if ( message && message . accessToken ) {
70
72
return ctx . authorization . resolveAccessToken ( message . accessToken , function resolveFinishForToken ( err , auth ) {
71
73
if ( err ) {
@@ -76,24 +78,47 @@ function AlarmSocket (app, env, ctx) {
76
78
}
77
79
return err ;
78
80
} 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' }
86
89
if ( shouldCallBack ) {
87
90
returnCallback ( okResponse ) ;
88
91
}
89
92
return okResponse ;
90
93
}
91
94
} ) ;
92
95
}
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 ) {
96
120
return ctx . authorization . resolve ( { api_secret : message . secret , token : message . jwtToken , ip : getRemoteIP ( socket . request ) } , function resolveFinish ( err , auth ) {
121
+
97
122
if ( err ) {
98
123
console . log ( `${ LOG_ERROR } Authorization failed for jwtToken:` , message . jwtToken ) ;
99
124
@@ -102,13 +127,34 @@ function AlarmSocket (app, env, ctx) {
102
127
}
103
128
return err ;
104
129
} 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 } ;
112
158
if ( shouldCallBack ) {
113
159
returnCallback ( okResponse ) ;
114
160
}
0 commit comments