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

suculent / thinx-device-api / #252646768

01 Nov 2025 03:31PM UTC coverage: 46.298% (-25.7%) from 71.971%
#252646768

push

suculent
testing upgraded mqtt package

1123 of 3470 branches covered (32.36%)

Branch coverage included in aggregate %.

5324 of 10455 relevant lines covered (50.92%)

4.07 hits per line

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

8.7
/lib/router.deviceapi.js
1
// /api/v2/ Device router
2

3
const Util = require("./thinx/util");
1✔
4
const Sanitka = require("./thinx/sanitka"); var sanitka = new Sanitka();
1✔
5

6
module.exports = function (app) {
1✔
7

8
  const device = app.device;
2✔
9

10
  //
11
  // Main Device API
12
  //
13

14
  // Firmware update retrieval for OTT requests
15
  app.get("/device/firmware", function (req, res) {
2✔
16
    const ott = req.query.ott;
×
17
    if (typeof (ott) === "undefined" || ott === null) {
×
18
      console.log("☣️ [error] GET request for FW update with no OTT!");
×
19
      return Util.responder(res, false, "OTT_MISSING");
×
20
    }
21
    console.log("GET request for FW update with OTT: " + ott);
×
22

23
    device.ott_update(ott, (success, response) => {
×
24
      if (success) {
×
25
        console.log("SUCCESS! Responding with contents...");
×
26
        res.setHeader('Content-Type', 'application/octet-stream');
×
27
        res.setHeader('Content-Disposition', 'attachment; filename=firmware.bin');
×
28
        // deepcode ignore ContentLengthInCode: this is not code for browsers but for legacy OTA device updates
29
        res.setHeader('Content-Length', response.filesize);
×
30
        res.setHeader('x-MD5', response.md5);
×
31
        Util.responder(res, response.payload);
×
32
      } else {
33
        console.log("No successful firmware build found: " + JSON.stringify(response));
×
34
        Util.respond(res, response);
×
35
      }
36
    });
37
  });
38

39
  // Firmware update retrieval. Serves binary [by owner (?) - should not be required] and device MAC.
40
  app.post("/device/firmware", function (req, res) {
2✔
41

42
    res.set("Connection", "close");
×
43

44
    // Device will create OTT request and fetch firmware from given OTT-URL
45
    if ((typeof (req.body.use) !== "undefined") && (req.body.use == "ott")) {
×
46
      device.ott_request(req, (_success, response) => {
×
47
        console.log("Responding to OTT request with :", { response });
×
48
        Util.respond(res, response);
×
49
      });
50

51
      // Device will fetch firmware/files now (wrapped as JSON or in binary, depending on type (firmware/file))
52
    } else {
53
      device.firmware(req, (success, response) => {
×
54
        console.log("Responding to Firmware request with :", { response }, "and success:", success);
×
55
        Util.respond(res, response);
×
56
      });
57
    }
58
  });
59

60
  // Device login/registration
61
  // MAC is be allowed for initial regitration where device is given new UDID
62

63
  app.post("/device/register", function (req, res) {
2✔
64

65
    if (typeof (req.body) === "undefined") return Util.failureResponse(res, 400, "no_body");
×
66
    if (typeof (req.body.registration) === "undefined") return Util.failureResponse(res, 400, "request_invalid");
×
67
    if (Object.keys(req.body.registration).length < 1) return Util.failureResponse(res, 400, "request_invalid");
×
68

69
    device.register(
×
70
      req.body.registration,
71
      req.headers.authentication,
72
      res,
73
      (r, success, response) => {
74
        // Append timestamp inside as library is not parsing HTTP response JSON properly
75
        // when it ends with anything else than }}
76
        if ((success === true) && (typeof (response.registration) !== "undefined")) {
×
77
          response.registration.timestamp = Math.floor(new Date() / 1000);
×
78
        }
79
        if (success === false) return Util.responder(res, success, response);
×
80
        Util.respond(res, response);
×
81
      });
82
  });
83

84
  // Device push attach
85
  // UDID is required, valid Push token is required. Potential point for DDoS attacks,
86
  // would use at least SOME authentication.
87

88
  app.post("/device/addpush", function (req, res) {
2✔
89

90
    if (
×
91
          ((typeof(req.body) === "undefined") || (req.body === null)) ||
×
92
          ((typeof(req.body.push) === "undefined") || (req.body.push === null))
93
    ) return Util.responder(res, false, "no_body");
×
94

95
    if (!Util.isDefined(req.body)) return Util.responder(res, false, "no_body");
×
96

97
    let body = req.body;
×
98

99
    if (typeof(body.push) !== "string") return Util.responder(res, false, "no_token");
×
100
    if (!Util.isDefined(body.push)) return Util.responder(res, false, "no_token");
×
101

102
    let push = body.push;
×
103

104
    if (!Util.isDefined(push)) return Util.responder(res, false, "no_data");
×
105
    
106
    if (!sanitka.pushToken(push)) return Util.responder(res, false, "no_token");
×
107

108
    let api_key = sanitka.apiKey(req.headers.authentication);
×
109
    if (api_key === null) return res.status(403).end();
×
110

111
    device.push(req.body, api_key, (success, response) => {
×
112
      Util.responder(res, success, response);
×
113
    });
114
  });
115

116
};
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