Can I create an IoT Hub Device from browser? - azure-iot-hub

Goal: Create an azure iot hub device from the browser (angular2) using node module azure-iot-hub.
Problem: azure-iot-common depends on a package, crypto , that won't work in browser.
Steps to Recreate:
import { Component, OnInit } from '#angular/core';
let iothub = require(‘azure-iothub’);
const connectionString = ‘HostName=<my-host>.azure-devices.net;SharedAccessKeyName=<my-key-name>;SharedAccessKey=<my-key>=’;
#Component({
selector: 'acn-shop',
template: `
<div class="al-main">
<div class="al-content container-fluid">
<h1>Azure IoT Hub Devices</h1>
</div>
</div>`
})
export class ShopComponent implements OnInit {
constructor() {
}
public ngOnInit() {
this.connect();
}
public connect() {
console.log('Calling connect()');
const registry = iothub.Registry.fromConnectionString(connectionString);
}
}
From Chrome Tools Console
Error: Uncaught (in promise): TypeError: crypto.createHmac is not a function
TypeError: crypto.createHmac is not a function
at Object.hmacHash (authorization.js:36)
at Function.create (shared_access_signature.js:67)
at Object.create (shared_access_signature.js:15)
at Function.fromConnectionString (registry.js:65)
at ShopComponent.Array.concat.ShopComponent.connect (shop.component.ts:32)
… (goes on for a bit) ...
There is a similar problem on github - https://github.com/ipfs/js-ipfs/issues/270 - which suggests switching crypto to webcrypto
Potential Solution: switch crypto to webcrypto - would require rewriting azure-iot-common/lib/authorization.js
Questions:
Has anyone created a hub device from the browser using node module azure-iot-hub?
Has anyone created a hub device from the browser using alternative methods?
If no to Q1,2 - Does my potential solution seem feasible?

The azure-iothub node module is the service client SDK, which is for creating back-end applications that will be used to manage the IoT Hub instance, NOT for devices.
On the devices side of things, you need to use the device client SDK module azure-iot-device.
That said, this will still not work even if you solve the various dependencies issues such as the Crypto one you found as the IoT Hub service doesn't support CORS meaning it will not accept requests coming from web clients. CORS support for IoT Hub is in our backlog but not yet prioritized, so we don't have an ETA.
What you can try to work around this limitation would be to run the device client node module in the back-end of the website, creating a new instance of a device client when a new webbrowser client connects to your site.

The library https://github.com/PeculiarVentures/webcrypto-liner will give you a crypto object you can use in the browser (even downlevel/IE) https://github.com/PeculiarVentures/node-webcrypto-ossl will give you one for Node.
There should be no problem switching to webcrypto, see https://github.com/diafygi/webcrypto-examples#hmac for an example of how to make the call.

Related

Cannot setup service worker with self-signed cert and webpack dev server

I'm new to Progressive Web Apps, and I'm adding a Service Worker to my app for the very first time. It's a simple Service Worker, with my goal being purely to test that it is being registered properly. The file is serviceWorker.js:
console.log('Hello Service Worker');
I'm adding this to an application that I'm running with the Webpack Dev Server. I'm using a self-signed certificate locally with it. I setup the Service Worker in my index.tsx (React Typescript) like this:
if ('serviceWorker' in navigator) {
navigator.serviceWorker
.register('/service-worker.js')
.then(() => console.log('Worker registered'))
.catch((ex) => console.error('Worker registration error', ex));
}
However, when I start the dev server and go to the app, I get an error:
Failed to register a ServiceWorker for scope ('https://localhost:3000/') with script ('https://localhost:3000/service-worker.js'): An SSL certificate error occurred when fetching the script.
The URL, https://localhost:3000/service-worker.js, does indeed work, the browser is just blocking it because of the self-signed piece of the cert.
I'm using Chrome Browser on on M1 Pro MacBook running MacOS Monterey, with Webpack 5.
For the record, I'm aware of plugins like Workbox, I would prefer not to use them at this time because I'm still very new to Service Workers. I believe in working with the low-level constructs when starting with a new tech to understand them better before embracing easier abstractions.
I'm not aware of any features—including service workers—that require HTTPS on localhost.
localhost, and equivalent IP address ranges, are specifically excluded from HTTPS requirements by Chromium-based browsers, and both Firefox and Safari follow that, at least when it comes to service workers.
So I would suggest that you just access your web site via http://localhost:3000 instead.
There are more details in this older answer.

I got some problem on Iot hub and corporate network's proxy

I tried to connect to IOT Hub with Asp.net core but I could not to get devices from IOT hub. When i tried to connect internet directly I can get devices from IOT hub. So i think the reason might be corporate network's proxy. Could you please consider again and let me know if you know anything. Thank you
You can add proxy setting explicitly to the application.
For Registry Manager try the following code:
using System.Net;
// s_proxyServerAddress= ...
// s_connectionString = ...
HttpTransportSettings customTransportSettings = new HttpTransportSettings();
customTransportSettings.Proxy = new WebProxy(s_proxyServerAddress);
JobClient jobClient = JobClient.CreateFromConnectionString(s_connectionString, customTransportSettings);
RegistryManager registryManager = RegistryManager.CreateFromConnectionString(s_connectionString, customTransportSettings);
More detailed info is here.
Please let me know if it helps.

MobileFirst - JavaScript Adapter calling Java Adapter via REST endpoint

This question is related to - [How to invoke Java adapter from HTTP adapter? ][1]
I have 2 adapters in my MobileFirst 7.1 project :
A Java Adapter that is exposing Rest Endpoint.
A JavaScript adapter will call the Java Adapter via Rest Endpoint
To be exact, this is what I call in the JS adapter :
function JSAdapterCalltoJavaAdapter() {
var input = {
method : 'get',
returnedContentType : 'xml',
path : "adapter/JavaAdapterRestPath"
};
return WL.Server.invokeHttp(input);
}
We have run JMeter load test for 800 Threads on Java Adapter, there is no issue. However, when we run load Test on JS Adapter, the MobileFirst server stop responding, and does not accept incoming request from JS Adapter. The new requests timeout and the MobileFirst console become unresponsive. When we stop the load test, the server gradually recovered.
I have configured the following params adapter.xml :
<connectionTimeoutInMilliseconds>, <socketTimeoutInMilliseconds>, and <maxConcurrentConnectionsPerNode>
It seems like there is threading issue when using JS adapter to call Java adapter under load.
Sounds like you need to open a PMR (support ticket) if you are encountering a threading issue in the MobileFirst Server so that the support/dev team could help you. If you have an actual programming question, ask it.

Failed to construct 'RTCPeerConnection': Unsatisfiable constraint IceTransports

I trying to setup RestComm Web SDK demo application on my local system, I just want to create an application for audio/video, chat, IVR, etc(RestComm provide me perfect solution for my needs). Now I have setup RestComm Web SDK on my local system and whenever I an trying to sip call, It throws WebRTCommClient:call(): catched exception:NotSupportedError: Failed to construct 'RTCPeerConnection': Unsatisfiable constraint IceTransports on browser console.
My webRTC confrigration is as below:
// setup WebRTClient
wrtcConfiguration = {
communicationMode: WebRTCommClient.prototype.SIP,
sip: {
sipUserAgent: 'TelScale RestComm Web Client 1.0.0 BETA4',
sipRegisterMode: register,
sipOutboundProxy: parameters['registrar'],
sipDomain: parameters['domain'],
sipDisplayName: parameters['username'],
sipUserName: parameters['username'],
sipLogin: parameters['username'],
sipPassword: parameters['password'],
},
RTCPeerConnection: {
iceServers: undefined,
stunServer: 'stun.l.google.com:19302',
turnServer: undefined,
turnLogin: undefined,
turnPassword: undefined,
}
};
While I can use olympus without any issue in Chrome Browser. I am stuck with this exception, any suggestions would be highly appreciated.
I think the problem here is that the version of Webrtcomm library inside the demo application you are using is outdated and doesn't include a fix for latest Chrome version. So please replace samples/hello-world/scripts/WebRTComm.js within your repository, with:
https://github.com/RestComm/webrtcomm/blob/master/build/WebRTComm.js
That should fix your issue.
Best regards,
Antonis Tsakiridis

SignalR getting 403 on AppHarbor after updating to v. 1.0.1 (Chrome)

I was using SignalR v. 1.0.0 RC2, and it worked fine. When I upgraded to v. 1.0.1 it stopped working. I am now getting a 403 (forbidden) when I am trying to invoke a method on the hub. I did not change any code - I only updated to the newer version of SignalR. It is important to note that I do not have any problems when I run it locally - only when I run it on AppHarbor, and only in the Chrome browser. It works in IE 10 and Firefox 20.
I know that some work has been done in the newer version of SignalR for authorization. Now you can add an Authorize attribute on your hub, or your hub methods. I want to do that, but first I would like it to work without - like it did before.
This is my hub:
using System.Threading.Tasks;
using Microsoft.AspNet.SignalR;
public class ReceptionHub : Hub
{
public Task Join(string group)
{
return Groups.Add(Context.ConnectionId, group);
}
}
And this is the client site script (I get the group from a data attribute in the markup):
$(function () {
var receptionHub = $.connection.receptionHub;
receptionHub.client.updateStatusBar = function (checkedIn, checkedOut, preRegistered)
{
$('#quantityCheckedInToday').html(checkedIn);
$('#quantityCheckedOutToday').html(checkedOut);
$('#quantityPreRegistered').html(preRegistered);
};
$.connection.hub.start().done(function () {
var group = $("#statusBar").data("group");
receptionHub.server.join(group);
});
});
One difference between my local setup and the setup on AppHarbor is that I run the AppHarbor site on HTTPS, but that was not a problem before. Also, there is a loadbalancer infront of the server on AppHarbor.
The request that fails is a POST request to this URL:
/signalr/send?transport=serverSentEvents&connectionToken=5hSSl7wSPrkD51cmPNw-JCrrdxMn2qOgEgmKt5gKrE4jigE4Sxha3gALHREcyDslqb7xjY9fP8rTMpslKuBJzBCIi-q86ZmHt66xhqi2eioAtvQCO03XlcR0Dq9-RW5G0
Any help is much appreciated
I have now tried using SignalR 1.1.2 - and it still did not work in Chrome, but this time it gave a much better error message. It said that CORS was turned off. I tried turning CORS on in the configuration:
var config = new HubConfiguration
{
EnableCrossDomain = true
};
// Register the default hubs route: ~/signalr
RouteTable.Routes.MapHubs(config);
This fixed the problem I was having, and now it works again in Chrome. I am not sure why CORS needs to be turned on to get it working in Chrome... maybe some special AppHarbor setup.