I’m new to developing on the SmartThings platform. I’d like to make an Azure Functions version of https://github.com/SmartThingsCommunity/weather-color-light-smartapp-nodejs
While moving it from an Express app to an Azure Function, I’m having a problem with my httpSignature.verifySignature(parsed, publicKey) statements. They return true in Express, but false my Azure Functions.
Any ideas / suggestions on how to fix this?
// Express App
/**
- Sample WebHook app for integrating with the SmartThings API.
- The app will set the color of a SmartThings-connected Color Control bulb
- according to the current weather conditions of a user-entered US five-digit
- Zip Code.
*/
‘use strict’;
const express = require(‘express’);
const bodyParser = require(‘body-parser’);
const request = require(‘request’);
const fs = require(‘fs’);
const httpSignature = require(‘http-signature’);
const prettyjson = require(‘prettyjson’);
const commands = require(’./lib/commands’);
const stConfig = require(’./lib/config’);
const scheduling = require(’./lib/scheduling’);
const weather = require(’./lib/weather’);
const stApi = ‘https://api.smartthings.com/v1’;
const prettyjsonOptions = {};
const app = express();
app.use(bodyParser.json());
const publicKey = fs.readFileSync(’./config/smartthings_rsa.pub’, ‘utf8’);
/**
- Entry point for callbacks by SmartThings.
- Every incoming call will have a lifecycle, which determines how the
- app should respond.
- All requests will have their HTTP signature verified to ensure the
- request is actually from SmartThings, except for the PING lifecycle
- request (which occurs as the app is being created).
*/
app.post(’/’, function (req, response) {
// We don’t yet have the public key during PING (when the app is created),
// so no need to verify the signature. All other requests are verified.
if (req.body && req.body.lifecycle === “PING” || signatureIsVerified(req)) {
handleRequest(req, response);
} else {
response.status(401).send(“Forbidden”);
}
});
/**
-
Verifies that the request is actually from SmartThings.
-
@returns true if verified, false otherwise.
*/
function signatureIsVerified(req) {try {
let parsed = httpSignature.parseRequest(req);//console.log(JSON.stringify(parsed,null,4));
if (!httpSignature.verifySignature(parsed, publicKey)) {
console.log(‘forbidden - failed verifySignature’);
return false;
}
} catch (error) {
console.error(error);
return false;
}
return true;
}
// added port to read from Azure Services
const port=process.env.PORT || 3005
let server = app.listen(port);
module.exports = server;
console.log(‘Open: http://127.0.0.1:’ + port);
// Azure Function
/**
-
Sample WebHook App for integrating with the SmartThings API.
-
The app will set the color of a SmartThings-connected Color Control bulb
-
according to the current weather conditions of a user-entered US five-digit
-
Zip Code.
/
‘use strict’;
const weatherforecast = require(’./weatherforecast’);
const fs = require(‘fs’);
const httpSignature = require(‘http-signature’);
const publicKey = fs.readFileSync(’./smartthings_rsa.pub’, ‘utf8’);
/* -
All requests will have their HTTP signature verified to ensure the
-
request is actually from SmartThings, except for the PING lifecycle
-
request (which occurs as the app is being created).
*/
module.exports = async function (context, req) {
console.log(‘Weather Forecast function processed a request.’);if (req.body && req.body.lifecycle === “PING”) {
weatherforecast.handleRequest(context.req, context.res);
} else {
// Check signature
let parsed = httpSignature.parseRequest(context.req);
//console.log(“Full Req:”);
//console.log(JSON.stringify(parsed,null,4));
try {
if (!httpSignature.verifySignature(parsed, publicKey)) {console.log('forbidden - failed verifySignature'); context.res.status(401).send("Forbidden"); } else { // OK - good to go! weatherforecast.handleRequest(context.req, context.res); } } catch (error) { console.error(error); context.res.status(401).send("Forbidden"); }
}
};