cleaned up
authorebelcrom <ebelcrom@gmail.com>
Sun, 16 Feb 2020 20:44:08 +0000 (21:44 +0100)
committerebelcrom <ebelcrom@gmail.com>
Sun, 16 Feb 2020 20:44:08 +0000 (21:44 +0100)
12 files changed:
app.js
init/initcloud.js [deleted file]
init/settings.json [new file with mode: 0644]
init/vapid.json [deleted file]
lib/db.js
lib/gpio.js
lib/notify.js [new file with mode: 0644]
lib/webcam.js
routes/v1/events.js
routes/v1/notification.js
routes/v1/test/notification.js
routes/v1/test/settings.js

diff --git a/app.js b/app.js
index 38455b26ddae4228aeb33fef43003ab035a7d6d4..e11e36e66cc7c139b255f9528017955d8c9431d7 100644 (file)
--- a/app.js
+++ b/app.js
@@ -6,6 +6,7 @@ const cors = require('cors');
 
 const log = require('./lib/logger')(__filename.slice(__dirname.length + 1));
 const ver = 'v1';
+const notify = require('./lib/notify');
 
 const indexRouter = require('./routes/index');
 
@@ -65,4 +66,11 @@ app.use('/' + ver + '/test/settings', testSettings);
 // api-docs
 app.use('/' + ver + '/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument));
 
+// subscribe notification after 2s
+setTimeout(subscribeNotification, 2000);
+
+function subscribeNotification() {
+  notify.subscribe('prod', null);
+}
+
 module.exports = app;
diff --git a/init/initcloud.js b/init/initcloud.js
deleted file mode 100644 (file)
index a986f70..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-function generateVAPIDKeys() {
-  var curve = crypto.createECDH('prime256v1');
-  curve.generateKeys();
-
-  return {
-    publicKey: curve.getPublicKey(),
-    privateKey: curve.getPrivateKey(),
-  };
-}
-
diff --git a/init/settings.json b/init/settings.json
new file mode 100644 (file)
index 0000000..20e6a70
--- /dev/null
@@ -0,0 +1,7 @@
+{
+  "publicKey":  "<enter_your_public_vapid_key_here>",
+  "privateKey": "<enter_your_private_vapid_key_here>",
+  "fcmApiKey":  "<enter_your_public_fcm_api_key_here>",
+  "prodApiKey": "<enter_your_production_api_key_here>",
+  "testApiKey": "2TTqCD4mNNny"
+}
diff --git a/init/vapid.json b/init/vapid.json
deleted file mode 100644 (file)
index 530596e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-{"publicKey":"BLDSdGasI5sLks30brbIWvlLMFqzoxxkOs7aW_E9PDBzIO_mDs6-tvtb2U0-BVFDafNd58DJgoXxdK5711FF29c","privateKey":"_AFTIegzYV_l_5RYwzOCc22cpYcMUmpkA8bLbrlNq9I"}
index 8d35a619c17b80d336bb7e67921bff1db09a387a..64f7b1c4d9d948d78e0f42899d6326c7bae49add 100644 (file)
--- a/lib/db.js
+++ b/lib/db.js
@@ -206,8 +206,11 @@ function getNotification(data, callback) {
         return reject(msg.dbError);
       }
       if (res.key !== data.key) {
-        log.info('API key doesn\'t match');
-        return reject(msg.keyMismatch);
+        // notification request on start?
+        if (data.key !== null) {
+          log.info('API key doesn\'t match');
+          return reject(msg.keyMismatch);
+        }
       }
       log.debug('API key is valid');
       resolve(msg.ok);
index a39204a950eb7741429805b296de7d3664429491..9f9d376dbe9c8be42d64d83d455134dc16a75ebe 100644 (file)
@@ -8,7 +8,6 @@ const DELAY = 300;
 var reedState;
 var controlCallback = null;
 var notificationCallback = null;
-var apiKey = null;
 var timer = null;
 
 function init() {
@@ -26,7 +25,7 @@ function trigger() {
   rpio.msleep(500);
   rpio.write(RELAIS, rpio.LOW);
 
-  log.debug('relais triggered');
+  log.debug('Relais triggered');
 }
 
 function readDebounced(pin) {
@@ -35,7 +34,7 @@ function readDebounced(pin) {
   rpio.msleep(1000);
 
   if (state != rpio.read(pin)) {
-    log.debug('state unknown');
+    log.debug('State unknown');
     return UNKNOWN;
   } else {
     return state;
@@ -48,7 +47,7 @@ function pollcb(pin)
 
   if (state != UNKNOWN && reedState != UNKNOWN) {
     if (state != reedState) {
-      log.debug('reed state changed, now:', state);
+      log.debug('Reed state changed, now:', state);
 
       if (controlCallback != null) {
         // handle callbacks
@@ -91,15 +90,14 @@ function read() {
   }
 }
 
-function subscribe(callback, key) {
+function subscribe(callback) {
   notificationCallback = callback;
-  apiKey = key;
 }
 
 function evaluation(state) {
   if (notificationCallback != null) {
     if (state == rpio.HIGH) {
-      timer = setTimeout(notificationCallback, DELAY * 1000, apiKey);
+      timer = setTimeout(notificationCallback, DELAY * 1000);
       log.debug('Open door evaluation started');
     } else {
       clearTimeout(timer);
diff --git a/lib/notify.js b/lib/notify.js
new file mode 100644 (file)
index 0000000..0a28a87
--- /dev/null
@@ -0,0 +1,93 @@
+const log = require('./logger')(__filename.slice(__dirname.length + 1));
+const db = require('./db');
+const gpio = require('./gpio');
+const settings = require('./../init/settings.json');
+const fs = require('fs');
+const webpush = require('web-push');
+
+var data = {
+  area: null,
+  key: null
+};
+
+function subscribe(area, key) {
+  data.area = area;
+  data.key = key;
+
+  // subscribe notification
+  gpio.subscribe(onDoorOpen);
+  log.info('Open door event subscribed');
+}
+
+function onDoorOpen() {
+  // get settings
+  db.getNotification({
+      area: data.area,
+      key: data.key
+    }, (err, data) => {
+    if (err) {
+      switch (err) {
+        case db.msg.dbError:
+          log.info('Server error response');
+          break;
+        case db.msg.keyMismatch:
+          log.info('Unauthorized access');
+          break;
+        default:
+          log.error('Error result unexpected');
+          break;
+      }
+    } else {
+      executeNotification(data);
+    }
+  });
+}
+
+function executeNotification(notification) {
+  const pushSubscription = {
+    endpoint: notification.endpoint,
+    keys: {
+      auth: notification.keys.auth,
+      p256dh: notification.keys.p256dh
+    }
+  };
+
+  const options = {
+    gcmAPIKey: settings.fcmApiKey,
+    vapidDetails: {
+      subject: 'mailto:ebelcrom@gmail.com',
+      publicKey: settings.publicKey,
+      privateKey: settings.privateKey
+    },
+    headers: {
+      'Urgency': 'high'
+    },
+    contentEncoding: 'aes128gcm'
+  };
+
+  const icon = 'data:image/png;base64,' +
+    fs.readFileSync(__dirname + '/../public/images/icon.png', 'base64');
+  const payload = {
+    message: 'The garage door is open!',
+    icon: icon
+  };
+  log.debug('Paylod length:', JSON.stringify(payload).length);
+/*
+  const details = webpush.generateRequestDetails(pushSubscription, JSON.stringify(payload), options);
+  log.debug('Request details:', JSON.stringify(details));
+*/
+  webpush.sendNotification(pushSubscription, JSON.stringify(payload), options)
+  .then(data => {
+    if (data) {
+      log.debug('Notification sent, data:', JSON.stringify(data));
+    }
+  })
+  .catch(err => {
+    log.error('Notification sending failed:', JSON.stringify(err));
+  });
+}
+
+module.exports = {
+  subscribe,
+  executeNotification
+}
index 2ace8fa45752f102d85da49d9ebf68087004be06..bf822c194eae246e8063fbd19ca55b24237ef01f 100644 (file)
@@ -5,7 +5,7 @@ const username = 'view';
 const options = {
   host: '192.168.3.2',
   path: '/snapshot.cgi',
-  mthod: 'GET',
+  method: 'GET',
   headers: {
     'Authorization': 'Basic ' + new Buffer(username + ':').toString('base64')
   }
index 3b34896576e637fa5a4695b9f9cf6f79a484fb1d..96762cdba6b1b3b032a2a22ed4370c3aae85b556 100644 (file)
@@ -4,6 +4,7 @@ const qStr = require('query-string');
 const router = express.Router();
 const db = require('./../../lib/db');
 const EventEmitter = require('events');
+const webcam = require('./../../lib/webcam');
 
 const events = new EventEmitter();
 var response = null;
@@ -86,18 +87,20 @@ events.on('stateChanged', (state) => {
     };
     if (image) {
       webcam.getImage()
-      .then(image => {
-        content['image'] = new Buffer(image).toString('base64');
-        res.json(content);
+      .then(img => {
+        content['image'] = new Buffer(img).toString('base64');
+        response.json(content);
+        response = null;
       })
       .catch(err => {
         log.error('Error on getting webcam image', JSON.stringify(err));
-        res.status(500).send();
+        response.status(500).send();
+        response = null;
       });
     } else {
-      res.json(content);
+      response.json(content);
+      response = null;
     }
-    response = null;
   }
 });
 
index cf2c6990bebaeaeb462f1e126481293198d8ef73..81e90e703823e568e1748985d864dd2025fdcf51 100644 (file)
@@ -4,8 +4,8 @@ const qStr = require('query-string');
 const router = express.Router();
 const db = require('./../../lib/db');
 const gpio = require('./../../lib/gpio');
+const notify = require('./../../lib/notify');
 const fs = require('fs');
-const webpush = require('web-push');
 
 /* Disables caching in client */
 function nocache(req, res, next) {
@@ -85,86 +85,12 @@ router.post('/', nocache, function(req, res, next) {
         }
       } else {
         // subscribe notification
-        gpio.subscribe(onDoorOpen, req.header('X-API-Key'));
-        log.debug('Open door event subscribed');
+        notify.subscribe('prod', req.header('X-API-Key'));
+        log.debug('Notification subscribed');
         res.status(200).send();
       }
     });
   }
 });
 
-function onDoorOpen(key) {
-  // get settings
-  db.getNotification({
-      area: 'prod',
-      key: key
-    }, (err, data) => {
-    if (err) {
-      switch (err) {
-        case db.msg.dbError:
-          log.info('Server error response');
-          res.status(500).send();
-          break;
-        case db.msg.keyMismatch:
-          log.info('Unauthorized access');
-          res.status(401).send();
-          break;
-        default:
-          log.error('Error result unexpected');
-          res.status(500).send();
-          break;
-      }
-    } else {
-      executeNotification(data);
-    }
-  });
-}
-
-function executeNotification(notification) {
-  const pushSubscription = {
-    endpoint: notification.endpoint,
-    keys: {
-      auth: notification.keys.auth,
-      p256dh: notification.keys.p256dh
-    }
-  };
-
-  const options = {
-    gcmAPIKey: 'AAAAUtHuYco:APA91bEBTxCRGaez9_glljXAlit3PY5HMwhLSqWYMC1j-jFSp6'
-      + 'nvnNqjI42jAVFApQbM0oyAOQjCUilIovB76cwTFxyZTP96wm9n09XwiMRXJjhwiJX1hO3'
-      + '2mBB2zwK6X-w7epE1V67K',
-    vapidDetails: {
-      subject: 'mailto:ebelcrom@gmail.com',
-      publicKey: 'BLDSdGasI5sLks30brbIWvlLMFqzoxxkOs7aW_E9PDBzIO_mDs6-tvtb2U0-'
-        + 'BVFDafNd58DJgoXxdK5711FF29c',
-      privateKey: '_AFTIegzYV_l_5RYwzOCc22cpYcMUmpkA8bLbrlNq9I'
-    },
-    headers: {
-      'Urgency': 'high'
-    },
-    contentEncoding: 'aes128gcm'
-  };
-
-  const icon = 'data:image/png;base64,' +
-    fs.readFileSync(__dirname + '/../../public/images/icon.png', 'base64');
-  const payload = {
-    message: 'The garage door is open!',
-    icon: icon
-  };
-  log.debug('Paylod length:', JSON.stringify(payload).length);
-
-  const details = webpush.generateRequestDetails(pushSubscription, JSON.stringify(payload), options);
-  log.debug('Request details:', JSON.stringify(details));
-
-  webpush.sendNotification(pushSubscription, JSON.stringify(payload), options)
-  .then(data => {
-    if (data) {
-      log.info('sent, data:', JSON.stringify(data));
-    }
-  })
-  .catch(err => {
-    log.info('sent, err:', JSON.stringify(err));
-  });
-}
-
 module.exports = router;
index 8295a9647703a8d56569ffa230bd69930dfaac3a..3d59eaec88ad99f87b1670d453018906cac149f4 100644 (file)
@@ -3,6 +3,8 @@ const log = require('./../../../lib/logger')(__filename.slice(__dirname.length +
 const qStr = require('query-string');
 const router = express.Router();
 const db = require('./../../../lib/db');
+const notify = require('./../../../lib/notify');
+const fs = require('fs');
 
 /* Disables caching in client */
 function nocache(req, res, next) {
index 27e3f13b74f30f37dc05c5a8a1c4d68f7a311d6b..8236567e8112db5eb208abc78600124f1d30ecec 100644 (file)
@@ -4,6 +4,7 @@ const qStr = require('query-string');
 const router = express.Router();
 const db = require('./../../../lib/db');
 const fs = require('fs');
+const notify = require('./../../../lib/notify');
 const webpush = require('web-push');
 
 const delayMin = -1;
@@ -154,7 +155,7 @@ router.post('/', function(req, res, next) {
         if (typeof req.body.notification == 'object' ) {
           if (typeof req.body.notification.delay == 'number' &&
                                                req.body.notification.delay !== delayMin) {
-            notify(req, res, next, settings.notification.delay);
+            subscribe(req, res, next, settings.notification.delay);
           } else {
             res.status(200).send();
           }
@@ -164,7 +165,7 @@ router.post('/', function(req, res, next) {
   }
 });
 
-function notify(req, res, next, delay) {
+function subscribe(req, res, next, delay) {
   // get settings
   db.getNotification({
       area: 'test',
@@ -206,50 +207,7 @@ function executeNotification(notification) {
   clearTimeout(timer);
   timer = null;
 
-  const pushSubscription = {
-    endpoint: notification.endpoint,
-    keys: {
-      auth: notification.keys.auth,
-      p256dh: notification.keys.p256dh
-    }
-  };
-
-  const options = {
-    gcmAPIKey: 'AAAAUtHuYco:APA91bEBTxCRGaez9_glljXAlit3PY5HMwhLSqWYMC1j-jFSp6'
-      + 'nvnNqjI42jAVFApQbM0oyAOQjCUilIovB76cwTFxyZTP96wm9n09XwiMRXJjhwiJX1hO3'
-      + '2mBB2zwK6X-w7epE1V67K',
-    vapidDetails: {
-      subject: 'mailto:ebelcrom@gmail.com',
-      publicKey: 'BLDSdGasI5sLks30brbIWvlLMFqzoxxkOs7aW_E9PDBzIO_mDs6-tvtb2U0-'
-        + 'BVFDafNd58DJgoXxdK5711FF29c',
-      privateKey: '_AFTIegzYV_l_5RYwzOCc22cpYcMUmpkA8bLbrlNq9I'
-    },
-    headers: {
-      'Urgency': 'high'
-    },
-    contentEncoding: 'aes128gcm'
-  };
-
-  const icon = 'data:image/png;base64,' +
-    fs.readFileSync(__dirname + '/../../../public/images/icon.png', 'base64');
-  const payload = {
-    message: 'The garage door is open!',
-    icon: icon
-  };
-  log.debug('Paylod length:', JSON.stringify(payload).length);
-
-  const details = webpush.generateRequestDetails(pushSubscription, JSON.stringify(payload), options);
-  log.debug('Request details:', JSON.stringify(details));
-
-  webpush.sendNotification(pushSubscription, JSON.stringify(payload), options)
-  .then(data => {
-    if (data) {
-      log.info('sent, data:', JSON.stringify(data));
-    }
-  })
-  .catch(err => {
-    log.info('sent, err:', JSON.stringify(err));
-  });
+  notify.executeNotification(notification);
 }
 
 module.exports = router;