• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

u-wave / core / 12197793619

06 Dec 2024 11:12AM UTC coverage: 84.385% (+0.03%) from 84.36%
12197793619

Pull #682

github

goto-bus-stop
lint
Pull Request #682: Improve session handling

911 of 1089 branches covered (83.65%)

Branch coverage included in aggregate %.

85 of 122 new or added lines in 10 files covered. (69.67%)

50 existing lines in 2 files now uncovered.

9881 of 11700 relevant lines covered (84.45%)

92.82 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

78.57
/src/sockets/AuthedConnection.js
1
import EventEmitter from 'node:events';
1✔
2
import Ultron from 'ultron';
1✔
3
import WebSocket from 'ws';
1✔
4
import sjson from 'secure-json-parse';
1✔
5

1✔
6
class AuthedConnection extends EventEmitter {
22✔
7
  #logger;
22✔
8

22✔
9
  /**
22✔
10
   * @param {import('../Uwave.js').default} uw
22✔
11
   * @param {import('ws').WebSocket} socket
22✔
12
   * @param {import('../schema.js').User} user
22✔
13
   * @param {string} sessionID
22✔
14
   */
22✔
15
  constructor(uw, socket, user, sessionID) {
22✔
16
    super();
22✔
17
    this.uw = uw;
22✔
18
    this.socket = socket;
22✔
19
    this.events = new Ultron(this.socket);
22✔
20
    this.user = user;
22✔
21
    this.sessionID = sessionID;
22✔
22
    this.#logger = uw.logger.child({
22✔
23
      ns: 'uwave:sockets', connectionType: 'AuthedConnection', userId: this.user.id, sessionID,
22✔
24
    });
22✔
25

22✔
26
    this.events.on('close', () => {
22✔
27
      this.emit('close', { banned: this.banned });
22✔
28
    });
22✔
29
    this.events.on('message', this.onMessage.bind(this));
22✔
30

22✔
31
    this.lastMessage = Date.now();
22✔
32
    this.sendWaiting();
22✔
33
  }
22✔
34

22✔
35
  /**
22✔
36
   * @private
22✔
37
   */
22✔
38
  get key() {
22✔
39
    return `http-api:disconnected:${this.sessionID}`;
22✔
40
  }
22✔
41

22✔
42
  /**
22✔
43
   * @private
22✔
44
   */
22✔
45
  get messagesKey() {
22✔
NEW
46
    return `http-api:disconnected:${this.sessionID}:messages`;
×
47
  }
×
48

22✔
49
  /**
22✔
50
   * @private
22✔
51
   */
22✔
52
  async sendWaiting() {
22✔
53
    const wasDisconnected = await this.uw.redis.exists(this.key);
22✔
54
    if (!wasDisconnected) {
22✔
55
      return;
22✔
56
    }
22✔
57
    /** @type {string[]} */
×
58
    const messages = await this.uw.redis.lrange(this.messagesKey, 0, -1);
×
59
    this.#logger.info({ count: messages.length }, 'queued messages');
×
60
    messages.forEach((message) => {
×
61
      const { command, data } = sjson.parse(message);
×
62
      this.send(command, data);
×
63
    });
×
64
    await this.uw.redis.del(this.key, this.messagesKey);
×
65
  }
22✔
66

22✔
67
  /**
22✔
68
   * @param {string|Buffer} raw
22✔
69
   * @private
22✔
70
   */
22✔
71
  onMessage(raw) {
22✔
72
    const { command, data } = sjson.safeParse(raw) ?? {};
3!
73
    if (command) {
3✔
74
      this.emit('command', command, data);
3✔
75
    }
3✔
76
  }
3✔
77

22✔
78
  /**
22✔
79
   * @param {string} command
22✔
80
   * @param {import('type-fest').JsonValue} data
22✔
81
   */
22✔
82
  send(command, data) {
22✔
83
    this.socket.send(JSON.stringify({ command, data }));
111✔
84
    this.lastMessage = Date.now();
111✔
85
  }
111✔
86

22✔
87
  ping() {
22✔
88
    if (Date.now() - this.lastMessage > 5000 && this.socket.readyState === WebSocket.OPEN) {
×
89
      this.socket.send('-');
×
90
      this.lastMessage = Date.now();
×
91
    }
×
92
  }
×
93

22✔
94
  ban() {
22✔
95
    this.#logger.info('ban');
×
96
    this.banned = true;
×
97
    this.send('error', 'You have been banned');
×
98
    this.socket.close(4001, 'ban');
×
99
  }
×
100

22✔
101
  close() {
22✔
102
    this.#logger.info('close');
×
103
    this.socket.close();
×
104
  }
×
105

22✔
106
  removed() {
22✔
107
    this.events.remove();
22✔
108
  }
22✔
109

22✔
110
  toString() {
22✔
111
    return `Authed { user: ${this.user.id} ${this.user.username} }`;
×
112
  }
×
113
}
22✔
114

1✔
115
export default AuthedConnection;
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc