Communication to/from HTMLViewer in desktop app...?

Hi All,

TLDR;

Is there a good way to “communicate” between HTMLViewer and app (including, but not limited to “intercepting” HTTP responses)?

I’m looking to integrate an existing XOJO desktop application with a semi-RESTful, 3rd party multifactor auth. Currently I’m manually hitting endpoints with HTTPSocket and simply walking through the steps to authenticate. This process culminates in a request for a multi-digit code and the user can finally proceed. It works well.

However, now, there’s a wrench. The new MFA method being used involves a secondary device (rather than simply responding with a multi-digit code). So, for example, the app hits the auth endpoint, then must wait for an “OK” from the user’s phone or confirming device. The MFA server either times out, declines, or receives an “OK” and responds to the HTTP request.

I’d much rather use a browser to handle the process from start to finish, and simply “capture” responses as needed. And, given the propensity for change, I think a browser (for auth only) is the way to go. However, there doesn’t appear to be a good way to communicate/hijack HTTP responses to/from the HTMLViewer? Is this the case, and why?

Best,

Michael

Yes. Mostly because the exposed API’s from the various libraries used to implement the HMLViewer don’t provide such an API to intercept and respond. Some of these libraries are OS provided, macOS and native renderer on Windows, and some by third party libraries - webkit for Windows & Linux. It’s wildly inconsistent between them - what is or isn’t available.

you can use something like this, wait until there is a value returning from the html viewer.
put this as a method in a subclass of htmlviewer.
you change the value of boolean property mGetElementByID in the StatusChanged event of the htmlviewer.

Public Function GetElementbyID(anElementID as String, elementProperty as string="textContent") as String
  mGetElementByID = True
  
  Dim jsSrc As String
  jsSrc = "window.status = document.getElementById("""+anElementID+""")."
  jsSrc = jsSrc +elementProperty + ";"
  ExecuteJavaScript(jsSrc)
  
  While mGetElementByID
    app.DoEvents(1)
  Wend
  
  Return mLastResult
  
End Function

[quote=413524:@Michael Williams]Hi All,

Is there a good way to “communicate” between HTMLViewer and app (including, but not limited to “intercepting” HTTP responses)?[/quote]
Historically, the way to do it seems to be, inside the HTMLviewer to set window.status to something, or document.title, and then get that response from the StatusChanged or TitleChanged events in your Xojo code. I’ve been doing some tests on that and can say that:

  1. on macOS, both these events work but the TitleChanged event is limited to 1000 bytes, with StatusChanged able to pass at least a megabyte.

  2. On Win7 (and I think win10), StatusChanged does not work and TitleChanged is limited to 259 bytes. It’s also slow.

  3. On Linux, StatusChanged does not appear to work and TitleChanged is limited to 1000 bytes.

This accords with what Jason said above, sad to say (I worked up a little project to get these numbers). Perhaps we are simply at the mercy of those providing the renderers in this instance.

StatusChanged on Win7 used to work, but then a new renderer appeared and that was that.

I’ve not touched web for many years and I haven’t touched xojo web at all, how about establishing a local websocket as the sending all the data you want over that?

Last time I looked at websockets was some time ago and they were then experimental. Are they now a fixed, established, well-defined “thing”?

I think so, webs full of them now, not 100% sure on backwards compatibility with older browsers or os’s though, someone with more knowledge might be able to chip in on that one.

Thanks - I’ll look into that. I have to do something anyway due to the limitations I mentioned above.

I used html viewer for years until sites required higher browser versions.
Switching to using the default browser and using Tim D’s Aloe to process the Auth responses has worked out well.

HTH

@Jason Parsley
I was afraid of that. Thanks.

@Jean-Yves Pochez @Tim Streater
I appreciate the suggestions, but I really need to work directly with the calls rather than simply check status or “screen scrape”.

@
I don’t have control over the 3rd party MFA, so I’m stuck making a call from my own client. In this cases I’ve been using HTTPSocket to make the calls, but I was hoping to cop out and use the browser in order to make use of existing call-response and JS. Thanks anyway. Am I misunderstanding your recommendation?

@Tim Kearns
Tim D’s Aloe? I’m unfamiliar.

Bah I missed the bit about it being for MFA (didnt read the OP, doh). If you can specify a return address for the response, set that to 127.0.0.1:xyzport then Aloe Express, its perfect for what you need to do. https://aloe.zone/ Its basically a super compact web server that you can use to listen for that redirect to localhost.

@ aaaah, I gotcha. Yeah, generally for things of that nature, I just set up my own server/listener with Ruby, or PHP, or NodeJS or whatever fits the task. In this case though, it still won’t solve the problem of communicating with and/or launching the desktop application. I think at the end of the day, I’m just going to have to muddle through the existing APIs and figure out some way to make HTTPSocket work. =(

Thanks for all the input, I’ll post back if I solve it.

That’s the beauty of using aloe, just drop the aloe class into your desktop app and now your desktop app can respond to the Oauth handshake.

I’m working on Julian’s suggestion of websockets, at the minute. Good progress so far.