@@ -4,10 +4,6 @@ const BotAtlasClient = require('./atlas_client');
4
4
const cache = require ( './cache' ) ;
5
5
const relay = require ( 'librelay' ) ;
6
6
const uuid4 = require ( "uuid/v4" ) ;
7
- const moment = require ( "moment" ) ;
8
- const words = require ( "./authwords" ) ;
9
-
10
- const AUTH_FAIL_THRESHOLD = 10 ;
11
7
12
8
class ForstaBot {
13
9
@@ -53,10 +49,6 @@ class ForstaBot {
53
49
console . error ( 'Message Error' , e , e . stack ) ;
54
50
}
55
51
56
- fqTag ( user ) { return `@${ user . tag . slug } :${ user . org . slug } ` ; }
57
- fqName ( user ) { return [ user . first_name , user . middle_name , user . last_name ] . map ( s => ( s || '' ) . trim ( ) ) . filter ( s => ! ! s ) . join ( ' ' ) ; }
58
- fqLabel ( user ) { return `${ this . fqTag ( user ) } (${ this . fqName ( user ) } )` ; }
59
-
60
52
async onMessage ( ev ) {
61
53
const message = ev . data . message ;
62
54
const msgEnvelope = JSON . parse ( message . body ) ;
@@ -71,6 +63,10 @@ class ForstaBot {
71
63
console . error ( "Received unsupported message:" , msgEnvelope ) ;
72
64
return ;
73
65
}
66
+ // ignore control messages, they are for the messenger
67
+ if ( msg . data . control ) {
68
+ return ;
69
+ }
74
70
75
71
console . log ( 'ev: ' ) ;
76
72
console . log ( ev ) ;
@@ -90,34 +86,9 @@ class ForstaBot {
90
86
} ) ;
91
87
}
92
88
93
- forgetStaleNotificationThreads ( ) {
94
- let tooOld = new Date ( ) ;
95
- tooOld . setDate ( tooOld . getDate ( ) - 7 ) ;
96
-
97
- Object . keys ( this . notificationThread ) . forEach ( n => {
98
- if ( this . notificationThread [ n ] . flaggedEntry . received < tooOld ) {
99
- delete this . notificationThread [ n ] ;
100
- }
101
- } ) ;
102
- console . log ( 'stale notification threads removed. currently tracking:' , Object . assign ( { } , this . notificationThread ) ) ;
103
- }
104
-
105
- async incrementAuthFailCount ( ) {
106
- let fails = await relay . storage . get ( 'authentication' , 'fails' , { count : 0 , since : new Date ( ) } ) ;
107
- fails . count ++ ;
108
-
109
- if ( fails . count >= AUTH_FAIL_THRESHOLD ) {
110
- await this . broadcastNotice ( {
111
- note : `SECURITY ALERT!\n\n${ fails . count } failed login attempts (last successful login was ${ moment ( fails . since ) . fromNow ( ) } )`
112
- } ) ;
113
- }
114
-
115
- await relay . storage . set ( 'authentication' , 'fails' , fails ) ;
116
- }
117
-
118
- async resetAuthFailCount ( ) {
119
- await relay . storage . set ( 'authentication' , 'fails' , { count : 0 , since : new Date ( ) } ) ;
120
- }
89
+ fqTag ( user ) { return `@${ user . tag . slug } :${ user . org . slug } ` ; }
90
+ fqName ( user ) { return [ user . first_name , user . middle_name , user . last_name ] . map ( s => ( s || '' ) . trim ( ) ) . filter ( s => ! ! s ) . join ( ' ' ) ; }
91
+ fqLabel ( user ) { return `${ this . fqTag ( user ) } (${ this . fqName ( user ) } )` ; }
121
92
122
93
async getSoloAuthThreadId ( ) {
123
94
let id = await relay . storage . get ( 'authentication' , 'soloThreadId' ) ;
@@ -139,76 +110,6 @@ class ForstaBot {
139
110
return id ;
140
111
}
141
112
142
- genAuthCode ( expirationMinutes ) {
143
- const code = `${ words . adjective ( ) } ${ words . noun ( ) } ` ;
144
- const expires = new Date ( ) ;
145
- expires . setMinutes ( expires . getMinutes ( ) + expirationMinutes ) ;
146
- return { code, expires } ;
147
- }
148
-
149
- removeExpiredAuthCodes ( pending ) {
150
- const now = new Date ( ) ;
151
-
152
- Object . keys ( pending ) . forEach ( uid => {
153
- pending [ uid ] . expires = new Date ( pending [ uid ] . expires ) ;
154
- if ( pending [ uid ] . expires < now ) {
155
- delete pending [ uid ] ;
156
- }
157
- } ) ;
158
-
159
- return pending ;
160
- }
161
-
162
- async sendAuthCode ( tag ) {
163
- tag = ( tag && tag [ 0 ] === '@' ) ? tag : '@' + tag ;
164
- const resolved = await this . resolveTags ( tag ) ;
165
- if ( resolved . userids . length === 1 && resolved . warnings . length === 0 ) {
166
- const uid = resolved . userids [ 0 ] ;
167
- const adminIds = await relay . storage . get ( 'authentication' , 'adminIds' ) ;
168
- if ( ! adminIds . includes ( uid ) ) {
169
- throw { statusCode : 403 , info : { tag : [ 'not an authorized user' ] } } ;
170
- }
171
-
172
- const auth = this . genAuthCode ( 1 ) ;
173
- console . log ( auth , resolved ) ;
174
- this . msgSender . send ( {
175
- distribution : resolved ,
176
- threadTitle : 'Message Bot Login' ,
177
- threadId : await this . getGroupAuthThreadId ( ) ,
178
- text : `codewords: ${ auth . code } \n(valid for one minute)`
179
- } ) ;
180
- const pending = await relay . storage . get ( 'authentication' , 'pending' , { } ) ;
181
- pending [ uid ] = auth ;
182
- await relay . storage . set ( 'authentication' , 'pending' , pending ) ;
183
-
184
- return resolved . userids [ 0 ] ;
185
- } else {
186
- throw { statusCode : 400 , info : { tag : [ 'not a recognized tag, please try again' ] } } ;
187
- }
188
- }
189
-
190
- async validateAuthCode ( userId , code ) {
191
- console . log ( userId , code ) ;
192
- let pending = await relay . storage . get ( 'authentication' , 'pending' , { } ) ;
193
- pending = this . removeExpiredAuthCodes ( pending ) ;
194
- const auth = pending [ userId ] ;
195
- if ( ! auth ) {
196
- throw { statusCode : 403 , info : { code : [ 'no authentication pending, please start over' ] } } ;
197
- }
198
- if ( auth . code != code ) {
199
- this . incrementAuthFailCount ( ) ;
200
- await relay . util . sleep ( .5 ) ; // throttle guessers
201
- throw { statusCode : 403 , info : { code : [ 'incorrect codewords, please try again' ] } } ;
202
- }
203
-
204
- delete pending [ userId ] ;
205
- relay . storage . set ( 'authentication' , 'pending' , pending ) ;
206
-
207
- await this . broadcastNotice ( { note : 'LOGIN' , actorUserId : userId , listAll : false } ) ;
208
- await this . resetAuthFailCount ( ) ;
209
- return true ;
210
- }
211
-
212
113
async getAdministrators ( ) {
213
114
const adminIds = await relay . storage . get ( 'authentication' , 'adminIds' , [ ] ) ;
214
115
const adminUsers = await this . getUsers ( adminIds ) ;
0 commit comments