-
Notifications
You must be signed in to change notification settings - Fork 0
/
mailServerMock.js
181 lines (138 loc) · 5.04 KB
/
mailServerMock.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
const msg = require('./lib/msg')
const sign = require('./lib/sign')
const crypt = require('./lib/crypt')
const EventEmitter = require('events');
const colors = require('colors/safe');
const colorsArray = ['magenta', 'yellow', 'cyan', 'green', 'red', 'blue']
let counter = 0
// ## 1. Use case
// ------------------------> t
// A .[===]..................
// B ................[===]...
// C ..[===================].
// - A broadcasts msg directed to B.
// - B doesn't get it because it expires before logging in.
// - C gets it and stores it. It should not be aware of any info not necessary to resend it.
// - B goes online,
// - and sends a signal to the network: "Hi, send my pending messages"
// - C is able to retrieve the message and broadcasts it to the network, which B will pick up
// Whisper mock
// ============
// Setup an eventEmitter that will mock whisper
// To use:
// myEmitter.on('event', (arg1) => {
// console.log('an event occurred!');
// });
// myEmitter.emit('event', arg);
const regularMsgTopic = '0x000001'
const imOnlineMsgTopic = '0x000002'
const topics = [regularMsgTopic, imOnlineMsgTopic]
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
// Logger:
topics.forEach(topic => {
const startTime = Date.now()
myEmitter.on(topic, payload => {
const t = String(Date.now() - startTime).padStart(6)
const msgHash = msg.regular.hash(payload)
console.log(colors.gray(`LOG: ${t} ms ${topic}, payload hash: ${msgHash}`))
});
})
// Setup listeners
// ===============
const timeToOnlineB = 1000
const userA = new User('A', sign.generateKey())
const userB = new User('B', sign.generateKey())
const mailServerC = new MailServer('C')
// Setup Emitters
// ==============
// A: Emitter
userB.ignore(true)
const chatPrivateKey = crypt.generateKey()
userA.join(chatPrivateKey)
userB.join(chatPrivateKey)
userA.message(userB.address, userA.chats()[0], 'Super cool message from A to B')
userA.message(userB.address, userA.chats()[0], 'Another super cool message from A to B')
// B: Receiver
setTimeout(() => {
userB.ignore(false)
userB.online()
setTimeout(() => {
userB.online()
userA.message(userB.address, userA.chats()[0], 'Last message from A to B')
}, 500)
}, timeToOnlineB)
// Define user classes
// ===================
function User(name, privateKey) {
const address = sign.getAddress(privateKey)
const chats = []
let ignore = false
const color = colorsArray[counter++]
const log = (txt) => console.log(colors[color](`--${name}: ${txt}`))
return {
ignore: (_ignore) => {
ignore = _ignore
},
online: () => {
log(`i'm online`)
const payload = msg.online.encode(chatPrivateKey, address, privateKey);
myEmitter.emit(imOnlineMsgTopic, payload);
},
join: (chatPrivateKey) => {
chats.push(chatPrivateKey)
myEmitter.on(regularMsgTopic, payload => {
if (ignore) return
// Ignore unauthorized messages
const hashOfInterest = msg.regular.getHash(chatPrivateKey, address)
const { hash, cipher } = msg.regular.decode(payload);
if (hash === hashOfInterest) {
const message = crypt.decrypt(cipher, chatPrivateKey)
log(`received a msg of interest: ${message}`)
}
});
},
message: (addressRecepient, chatPrivateKey, message) => {
log(`sent message: ${message}`)
const cipher = crypt.encrypt(message, chatPrivateKey);
const payload = msg.regular.encode(chatPrivateKey, addressRecepient, cipher);
myEmitter.emit(regularMsgTopic, payload);
},
chats: () => chats,
address
}
}
function MailServer(name) {
// C: Mailserver
const msgs = []
const rebroadcastedMsgs = {}
const color = colorsArray[counter++]
const log = (txt) => console.log(colors[color](`--${name}: ${txt}`))
myEmitter
.on(imOnlineMsgTopic, payload => {
// Ignore unauthorized messages
if (!msg.online.authorize(payload)) {
// Maybe punishable action could be taken against this user
return console.log(
"Unauthorized user attempted to access messages of hash: " + payload
);
}
const { hash } = msg.online.decode(payload);
// Search the database for matching msgs
if (msgs[hash]) {
log(`re-broadcasting message after imOnlineMsg`)
msgs[hash].forEach(msg => myEmitter.emit(regularMsgTopic, msg))
delete msgs[hash]
}
})
.on(regularMsgTopic, payload => {
// Prevent listening to the msgs you have broadcasted
const msgHash = msg.regular.hash(payload)
if (rebroadcastedMsgs[msgHash]) return
else rebroadcastedMsgs[msgHash] = true
const { hash } = msg.regular.decode(payload);
log(`stored msg`)
if (!msgs[hash]) msgs[hash] = []
msgs[hash].push(payload)
});
}