Pass URL with Notifying - ibm-mobilefirst

I am wondering if it possible to configure the remote notify option to pass a URL.
I see there is a function for onErrorRemoteDisableDenial. I tried to modify it, but it seems to disables the app. Even if i put code to continue, the next call to the backend does not work.
But what we are looking for is giving the user the option to update via URL, or just continue with the app version they currently have.
Using Worklight 6.1

There is a way to customize both Remote Disable and Remote Notify, but the downloadLink (the link that you've set in Worklight Console) is available only when setting Remote Disable, not Remote Notify. Only the message (the text set in Worklight Console) will be available.
You can customize the Remote Notify flow by using the following in main.js (outside of any function):
wl_remoteDisableChallengeHandler.handleChallenge = function(message,downloadLink) {
WL.SimpleDialog.show(
"New Version",
message,
[
{text: "Download", handler: function() {
// Maybe use WL.App.openURL(downloadLink) to go to the app store
}},
{text: "Close", handler: function() {
// Continue with the app
}}
]);
};
wl_remoteDisableChallengeHandler.handleChallenge overrides the default Remote Notify code path. wl_remoteDisableChallengeHandler.handleFailure will override the default Remote Disable code path (and this is another way to customize Remote Disable).
Edit: per the findings in the comments, in order to get both the message and downloadLink, you will first need to temporary set Remote Disable and then change to Remote Notify, this is a workaround because Remote Notify by default is not meant to also pass the downloadLink to the default provided dialog.
Note: Remote Notify is meant to be displayed only once per a message's life cycle, so after it was displayed - it will not be displayed again until a the message is set again in the console.
A way to get the code to work on each application launch is to clear the application's HTML local storage (at some point while the app is running), where a "flag" is stored to tell the application not to display the message again (I forgot its name, but you could print the contents of the local storage and debug that).
Sounds like a nice feature request: https://developer.ibm.com/mobilefirstplatform/help

Related

Workstation hosted vscode extension not processing message from remote hosted extension

QV https://github.com/microsoft/vscode-remote-release/issues/7736
I have two extensions. One of them is of uiKind workspace and may run locally or remotely depending on the workspace, and the other is of uiKind ui and always runs locally.
The ui extension is responsible for spawning a browser on the user's workstation to load a URI provided by the argument of a command print.launchBrowser that it registers using vscode.commands.registerCommand
The workspace extension uses vscode.commands.executeCommand to invoke print.launchBrowser.
The point of this arrangement is to allow the browser to be launched on the workstation irrespective of whether the extension host is local or remote.
This should work. The following documentation explicitly says it works: https://code.visualstudio.com/api/advanced-topics/remote-extensions#communicating-between-extensions-using-commands
However, when I test it works only when both extensions run on the workstation.
Before anyone tells me to use vscode.env.openExternal(Uri) I am aware of this and am using it to launch the default browser, but this is no use for launching a non-default browser. Many of my users exploit the support for an alternate browser to use Chrome for printing while using a less invasive alternative as their daily drive.
What could cause this to fail? Here's the abovementioned documentation:
Some extensions return APIs as a part of their activation that are intended for use by other extensions (via vscode.extension.getExtension(extensionName).exports). While these will work if all extensions involved are on the same side (either all UI Extensions or all Workspace Extensions), these will not work between UI and Workspace Extensions.
Fortunately, VS Code automatically routes any executed commands to the correct extension regardless of its location. You can freely invoke any command (including those provided by other extensions) without worrying about impacts.
That's not ambiguous.
Since the code for the browser agent is very short I present it in its entirety.
import * as vscode from 'vscode';
import * as child_process from "child_process";
export function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(vscode.commands.registerCommand("print.launchBrowser", url => {
const browserPath = vscode.workspace.getConfiguration("print").browserPath;
child_process.exec(`${escapePath(browserPath)} ${url}`, (error: child_process.ExecException | null, stdout: string, stderr: string) => {
if (error || stderr) {
const err = error ? error.message : stderr;
if (!err.startsWith("[")) {
vscode.window.showErrorMessage(err);
}
}
});
}));
}
function escapePath(path: string) {
switch (process.platform) {
case "win32":
return path.includes('"') || !path.includes(" ") ? path : `"${path}"`;
default:
return path.replace(/ /g, "\\ ");
}
}
Code to call it is straightforward. Any extension containing the following should open a browser window and load the bing.com default page, although if you want to use the agent above you'll need to either supply the print.browserPath setting with a value containing the workstation path to a browser or put in such a path as a literal for testing purposes.
There aren't any tests for things like whether browserPath has a value that resolves to a file. That's all in the calling extension, which is designed to use the agent only when it runs in a remote workspace. The agent is essentially nothing but a platform independent remote procedure call.
vscode.commands.executeCommand("print.launchBrowser", "https://bing.com");
All this has been tested and failed on two separate computers and also with VS Code Insiders 1.75.0, which also resolves the question of whether I have a borked VS Code installation.

PouchDB using remoteDB and not local DB instance by default in online mode not not in offline mode

I have attachments saved in a CouchDB database server-side that I want to replicate on a client-side app using PouchDB.
In my app.js file where I handle my application logic, this is at the top:
import PouchDB from 'pouchdb'
var remoteDB = new PouchDB('http://dev04:5984/documentation')
var db = new PouchDB('documentation')
remoteDB.replicate.to(db).on('complete', function () {
// yay, we're done!
}).on('error', function (err) {
// boo, something went wrong!
});
When I turn off access to port 5984 in my firewall, my file can no longer be retrieved and I lose access to my index.html file.
What I am expecting is for all contents of the database 'documentaion' to be copied to my local browser storage -- including pdfs and such -- so that when I turn off port 5984 and then hit refresh, I should still have access to the contents. What am I doing wrong? (see edit -- I figured out that the db is actually replicating, but the local instance isn't being preferred)
EDIT:
I've determined that the database is actually being replicated, but the local storage is only 'preferred' when the browser is in offline mode. So when I refresh while in online mode, with port 5984 blocked, the page is not found. But when I do the same in offline mode (once the contents have been cached already, of course), then the contents can be retrieved.
It would not be an ideal solution to ask my users to always work in offline mode. Is there some way to make the local PouchDB instance the default, even in online mode?
I write to the local db first and "sync" that to a remote db if it's available.
And I use app.cache to provide offline functionality and configure the app to run "offline first".
I read last week that Apple has finally implemented Service Workers in Safari so I'll be looking into implementing that as well now.

Defining administrator messages from MobileFirst Operations Console

Hi I am Defining administrator messages from MobileFirst Operations Console for access disabled in mobilefirst 8.0.
Is there any way to change header of the message alert box like we can change message? Now its "Application Disabled". I want to change this.
See this documentation topic: https://mobilefirstplatform.ibmcloud.com/tutorials/en/foundation/8.0/application-development/translation/#cordova-applications
You should be able to find the corresponding variable for the header of the dialog in the messages.json file. The file is available after the application has been built.
Android: [Cordova-project]\platforms\android\assets\www\plugins\cordova-plugin-mfp\worklight\messages
iOS, Windows: [Cordova-project]\platforms[ios or windows]\www\plugins\cordova-plugin-mfp\worklight\messages
The variable to look for is this:
"applicationDenied" : "Application Disabled",
You will then need to override it in your applicative code.
For example:
WL.ClienMessages.applicationDenied = "Sorry!";
Should work...

Simulate Access disable feature in Worklight , when worklight server itself is down.

I am trying show end users maintainence window such as "we are down please try later" and disable the application but my problem is what if my worklight server itself is down and not reachable and i cannot use the feature provided by worklight console,
Is there a way i make my app talk to a different server which returns back the below json data when a app is disabled , can i simulate this behaviour is this possible.
json recieved on access disabled in worklight :-
/*-secure-
{"WL-Authentication-Failure":{"wl_remoteDisableRealm":{"message”:”We are down, Please try again soon","downloadLink":null,"messageType":"BLOCK"}}}*/
I have some conceptual problems with this question.
Typically a production environment (simplified) would not consist of a single server serving your end-users... meaning, there would be a cluster of nodes, each node being a Worklight Server, and this cluster would be behind a load balancer that would direct the incoming requests. And so in a situation where a node is down for maintenance like in your scenario there would still be more servers able to serve - there would be no down time.
And thus at this point your suggestion to simulate a Remote Disable by sending it from another(?) Worklight Server seems not so much the correct path to take (it may even be simply wrong). Have you had this second Worklight Server, why wouldn't it just serve the apps business like usual? See again my first paragraph about clustering.
Now lets assume there is still a downtime, that affects all servers. The application's client logic should be able to handle failed connections to the Worklight Server. In such a case you should handle this in the WL.Client.connect()'s onFailure callback function to display a WL.SimpleDialog that looks just like a Remote Disable's dialog... or perhaps via the initOption.js's onConnectionFailure callback.
Bottom line: you cannot simulate the JSON that is sent back for the wl_RemoteDisable realm; it is part of a larger security mechanism.
Additionally though, perhaps a way to better handle maintenance mode on your server is to have the HTTP server return a specific HTTP status code, check for this code and display a proper message based on the returned HTTP status code.
To check for this code in a simple example:
Note: the getStatus method is available starting MobileFirst Platform Foundation 7.0 (formerly "Worklight").
function wlCommonInit(){
WL.Client.connect({onSuccess:success, onFailure:failure});
}
function success(response) {
// ...
}
function failure(response) {
if (response.getStatus() == "503") {
// site is down for maintenance - display a proper message.
} else if ...
}

Worklight - connection on startup fails

using Worklight server v6.1 i'm trying to develop a simple app that connects to the production server at startup. To get this i do:
in initOptions.js file i set connectOnStartup to true
in wlCommonInit method of <my-app>.js file i call :
WL.Client.connect({
onSuccess: connected,
onFailure: failure
});
where connected and failure are two callback to two simple functions that load some data in a listview. When i trie it on a production or development environment i get a spot over my app's layout stating it's loading as you can see in the pic below(even if the application loaded data correctly):
i notice that after installing and running it on an iOS or Android device i don't have this strange behaviour, but on Windows8 devices i do have.
i set to false connectOnStartup and left only the call to WL.Client.connect.
Now the app doesn't get blocked anymore(i suppose becouse WL.Client.connect runs asynchronously while WL.Client.init does not but it's only my opinion).
i can't connect to the server yet, this is strange becouse(you can see in the pic) there is a listview filled with data returned by a sql adapter,
so it looks like the app can connect to the server for calling adapters but not for updates
You have already set connectOnStartup:true in initOption.js, this means that the app will try to connect to the Worklight Server on startup - basically it calls to connect, so why do you call WL.Client.connect in wlCommonInit() as well?
As for the onSuccess and onFailure, I think that in this what you may want is the following:
See the options for WL.Client.init.
There is an initOption that you can uncomment in initOptions.js:
onConnectionFailure
A failure-handling function invoked when connection to the Worklight
Server, performed on initialization by default, or if the
connectOnStartup flag is true, fails.
The "success" by default is wlCommonInit(), but you want something else then in initOptions.js you can also add onSuccess: something.
BTW, where did you see what you've done as a "best practice" by Worklight?