Domino Authentication using AJAX and JSON

November 25th, 2013

A while back, I had a requirement for a Domino hosted public jQuery Mobile web application to access private data held on the same Domino server in a database which required authentication, but from within the app itself, using either stored credentials or those provided via an in-app pop-up dialog.

Whist I found plenty of useful How-to’s on Domino Authentication via web pages and associated customisations, I just couldn’t seem to find what I was specifically looking for – although they did provide me with plenty of pointers and ideas to try…

Eventually, after much research and even more experimentation, I finally managed to pull all of the pieces of the puzzle together and produced a very simple solution which not only fulfilled all of my requirements, but is also as secure as it can to be (when using HTTPS).

Alas, this aspect of the web app has yet to make it into the app as originally planned, so in the meantime I thought that I’d document how to do this should anyone else out there be struggling to do the same…

It uses traditional Domino web design techniques, and I assume that the reader is comfitable with using javascript to make AJAX/JSON calls using jQuery, and is already familiar with Domino ACL settings for both Anonymous and Authenticated database access.

For the purposes of this article and to keep this simple for now, I shall assume that both the web application and the private data are stored in separate databases, called for example, PublicApp.nsf and PrivateData.nsf respectively, but on the same Domino server.

Stage 1 – Domino Pages.

First we need to create a couple of very basic Pages – each of which simply returns JSON data back to the caller using Computed Fields to fill in the missing blanks.

In the web app database (ie PublicApp.nsf), create a single page called getLoginStatus – which just returns some basic JSON data pertaining to the connected user, in particular whether they are authenticated or not.

This Page contains just the following:-

{

"authenticated": Computed Value,

"user":
{

"username":"Computed Value"

},

"returnStatus": "0",
"returnResponse": "Success"

}

Now set the authenticated Computed Value to:-

@If(@Name([CN];@UserName)= “Anonymous”;”false”; “true”)

and the username Computed Value (note the enclosing quotes) to:-

@Name([CN];@UserName)

Finally in its Page Properties, set Web Access = Other of type application/json, and ensure that this page is accessible by both Anonymous and Authenticated users.

After saving this page, copy it into the Private Database (ie PrivateData.nsf), renaming it as doLoginSuccessAuth in the process.

Ensure that this second page is only accessible to Authenticated users of the database. It is this second page that we actually use for login attempts.

Stage 2 – Javascipt.

Second, we need to add to the web app, some javascript functions plus a couple of global variables which act as URL pointers to the web app and private data.

The functions are:-

getLogonStatus – gets the getLogonStatus page data (returned as JSON) from PublicApp.nsf.

doLogout – sends the logout parameter (to PrivateData.nsf).

doLogin – attempts to get the doLogonSuccessAuth page data from PrivateData.nsf after POSTing to it the users login credentials.

getPrivateData – attempts to get the private page data from PrivateData.nsf.

This is the minimum code required – I’ve stripped out all of the original code – and whilst there is minimal comment, the code should be fairly self explanatory:-

// Global URL pointers for separate public and private databases

var homeURL = "http://MyServerName/PublicApp.nsf"
var dataURL = "http://MyServerName/PrivateData.nsf"

function getLogonStatus() {

function onSuccess(ajax_results, status, xhr) {

// get a value from returned JSON
var usernameLoggedOn = ajax_results.user.username;

if (ajax_results.authenticated) {

alert("getLogonStatus - Authenticated");

/*
* We are successfully accessing Domino
* as an Authenticated
* (non-anonymous) user.
* Code appropriate actions here...
*/

} else {

alert("getLogonStatus - Non-authenticated");

/*
* We are successfully accessing Domino
* as a Non-authenticated
* (Anonymous) user.
* Code appropriate actions here...
*/

}

};

function onError(xhr, status, errorThrown) {

alert("getLogonStatus - Error");

/*
* An error has occurred.
* Code appropriate actions here...
*/

};

$.ajax( {

url : homeURL + "/getLoginStatus?OpenPage",
dataType : 'json',
success : onSuccess,
error : onError

});

};

function doLogout() {

function onSuccess(ajax_results, status, xhr) {

alert("doLogout - Successful");

/*
* We have successfully logged out of Domino.
* Code appropriate actions here...
*/

};

function onError(xhr, status, errorThrown) {

alert("doLogout - Error");

/*
* An error has occurred.
* Code appropriate actions here...
*/

};

$.ajax( {

url : dataURL + "/?Logout&RedirectTo=" + homeURL
+ "/getLoginStatus?OpenPage",
dataType : 'json',
success : onSuccess,
error : onError

});

};

function doLogin(loginUsername, loginPassword) {

var loginRedirectTo = dataURL
+ "/dologinSuccessAuth?OpenPage";

var loginObject = {
username : loginUsername,
password : loginPassword,
redirectto : loginRedirectTo
};

function onSuccess(ajax_results, status, xhr) {

alert("doLogin - Successful");

/*
* We have successfully logged in to Domino
* using the provided
* credentials.
* Code appropriate actions here...
*/

};

function onError(xhr, status, errorThrown) {

if (status == "parsererror") {
// invalid JSON returned

alert("doLogin - Error Authentication");

/*
* An authentication error has occurred.
* Code appropriate actions here...
*/

} else {

alert("doLogin - Error");

/*
* An error has occurred.
* Code appropriate actions here...
*/

}

};

$.ajax( {

// If login successful returns the contents of
// doLoginSuccessAuth page
// (which requires authentication).
// else, Domino returns the HTML login page
// which we do not use

url : dataURL + "/?Login",
dataType : 'json',
type : 'POST',
data : loginObject,
success : onSuccess,
error : onError
});

};

function getPrivateData() {

function onSuccess(ajax_results, status, xhr) {

alert("getPrivateData - Successful");

/*
* We have successfully logged in to Domino
* using the provided
* credentials.
* Code appropriate actions here...
*/

};

function onError(xhr, status, errorThrown) {

if (status == "parsererror") {

alert("getPrivateData - Error Authentication");

/*
* An authentication error has occurred.
* Code appropriate actions here...
*/

} else {

alert("getPrivateData - Error");

/*
* An error has occurred.
* Code appropriate actions here...
*/

}

};

$.ajax( {

url : dataURL + "/getDataPrivateAuth?OpenPage",
dataType : 'json',
success : onSuccess,
error : onError

});

};

And that is all there is to it!

The above has been successfully tested against Domino 9 – I’ve not tried using Domino Data Services (DDS), although I see no reason why it would not work – and it should also be fine with all recent Domino versions, as it has no dependancies on XPages. That said, your own mileage may vary.

Enjoy!

iOS Device Remote Web Debugging in Three Easy Steps (but only if you’ve already got a Mac!)

September 12th, 2013

I’ve recently been doing a lot of iOS (and Android) mobile web application development, and its often been useful to be able to inspect an application on an actual device, particularly when looking at performance issues.

As of iOS 6 Apple made this very easy to do with the Web Inspector function, which replaced the original Debug Console:-

1. Enable Web Inspector on the mobile device using Settings > Safari > Advanced

developersettings_2x

debugconsoleon_2x

2. Connect the iOS device to your Mac using a USB cable, and open the website that you want to inspect

3. On the Mac’s desktop Safari (assuming that you already have the Develop menu enabled in your Preferences), from the Develop drop-down menu simply select the connected iOS device type/name, and then from it’s sub-menu, the name of the website to inspect.

developmenu_2x

Most of the desktop Safari Web Inspector functions are now available to remotely inspect and debug the selected iOS website.

webinspector

Symphony Removed During Upgrade to Ubuntu 9.10 “Karmic Koala”

October 30th, 2009

As Mark Myers mentioned, the on-line upgrade to Ubuntu 9.10 “Karmic Koala” is nice and neat, if a bit slow. I did however notice that during this automated upgrade, Lotus Symphony 1.3 which I had originally installed via the Ubuntu 9.04 partner repositories, was explicitly removed 🙁

I’m sure that this will be fixed in due course by IBM/Canonical, but in the meantime, if you need Symphony then you’ll have to manually download it and install it outside of the repository . . .

SnTT: In Situ Domino Server Rename

October 1st, 2009

One of the benefits of Domino server upgrades, when compared to some other emails systems, is the ease with which it is possible to perform upgrades in situ, without having to migrate to new hardware.

So with this in mind, it came as somewhat of a surprise to discover that when renaming an existing Domino server, Lotus actually advise that “The easiest way is to create a new server and move all users, databases, and needed functions to the new server using the AdminP task”.

Whilst I agreed that this approach is certainly appropriate if you are renaming a mail, or other user facing server (in order to maintain service availability), however if you need to rename a hub, or other non-user facing server, there is absolutely no reason why not to perform a very simple in situ upgrade as detailed below:-

1. Register the new Domino server name in the normal way

2. Add the new Domino server name to DNS (I assume the OS host name will remain the same)

3. Review and update the new Server Document, comparing it with the original server. This should include (but is not limited to):
– Directory Assistance
– Directory Catalog
– Transaction Logging

4. Create a new Server Configuration Settings Document for the new server, and copy across any necessary settings from the original server’s Configurations Settings Document

5. Review events4.nsf and create new probes and monitors for the new server as required, based on those configured against the original server

6. Review all mail routing and replication Connection Documents for the original server and create equivalent documents for the new server (as appropriate)

7. Review Program Documents for the original server and create equivalent documents for the new server (as appropriate)

8. Add the new server name to any relevant ACL groups in the Domino Directory

9. Add the new server name to the relevant DDM collection hierarchy (if appropriate)

10. Take a local (i.e. to your workstation) non-replica copy of catalog.nsf (for future reference)

11. Immediately prior to starting the actual rename process on the original server:
– Force AdminP to process any pending requests using tell adminp process new
– Force routing of any pending emails, ensure that there is no undelivered mail in any mail.box
– Force a database cache flush using dbcache flush

12. Shutdown Domino in the normal way

13. Take backup copies (outside of the Domino Data folder) of the following files:
– notes.ini
– server ID file
– log.nsf
– catalog.nsf
– busytime.nsf, or clubusy.nsf (as appropriate)
– all mail.box(es)

14. Delete the following files:
– original server ID file
– log.nsf
– catalog.nsf
– busytime.nsf, or clubusy.nsf (as appropriate)
– all mail.box(es)

15. Copy the new server ID file to the existing server

16. Edit notes.ini as follows:
– Replace any instances of the original server name with the new one name. Typically for the settings: mailserver and servername
– Edit the serverkeyfilename setting to reflect the file name of the new server ID file

17. Start the newly renamed server, ensuring that it recognises it’s new name and check the console and log file for any unexpected errors

18. Verify that you can access the new server from a Notes Client, and a web browser (if appropriate) using it’s new Domino and DNS name

19. Update the ACLs and Administration Server Database property of all server specific databases on the server, to reflect the new server name (making use of the previously saved catalog.nsf to help identify appropriate databases)

20. Review the directory assistance database (if applicable) and update any instances of the original name with the new one

21. Review any application databases and update the ‘run on server’ agent settings to reflect the new server name (if appropriate)

22. Decommission the original server from the Domino Directory (and of course DNS) in the normal way

Please let me know if you think I’ve missed anything, or if you have any suggestions on how to improve this process.

Enjoy!

My CV Presented as a Wordle Tag Cloud

July 1st, 2008

My Curriculum Vitae presented as a Wordle tag cloud:

resume wordle tag cloud

SnTT: Confirm OTA Message Delivery to Blackberry Devices

May 22nd, 2008

Have you ever quickly needed to check whether or not, a Blackberry device is active and successfully receiving mail over-the-air?

Well you can, by simply adding <$Confirm> at the very start of a message subject line, and sending it to the email address that it is associated with. Upon receipt at the device itself, it will send back a return receipt, similar to the following example:

Your message:

TO: xxxx.yyy@xxx.com
Sent: Thu May 22 07:35:32 2008
Subject: <$Confirm> Return Receipt Confirm Test

has been delivered to the recipient’s BlackBerry Handheld.

PS You can also use the following variation on this, but I’ll leave you to work out how this differs:

<$Confirm,RemoveOnDelivery,SuppressSaveInSentItems>

Enjoy!

SnTT: Nested Group Display Behaviour in Sametime

April 4th, 2008

For those of you who are not already noticed, Sametime Connect Client 7.51 or later (and also the embedded version in the Notes 8.0.1 Client), only displays server groups (from the Domino Directory) as a single concatenated level. As a result, any nested groups or sub-groups within it, are automatically ‘expanded’ into their (unique) constitute members and the merged result displayed. This is useful.

Conversely, user defined ‘local’ Sametime groups, are permitted to contain one additional layer of collapsable groups to be displayed. This is also useful.

So, how could these two differing behaviours be beneficially used?

Many organisations make use of nested groups and sub-groups, to create an hierarchical structure for organisational, departmental, or even functional mailing purposes. Often these individual, and sometimes unrelated, sub-groups, contain ‘duplicate’ names, which when added as individual buddy groups in Sametime, results in multiple entries (in different groups) for the same individual. So, by using a higher level nested server group, containing multiple sub-groups, it is possible to have a single collapsable section for all (unique) Sametime users in a particular department etc., or even perhaps, for an entire organisation.

Local Sametime groups can be used to save screen real estate and allow sets of multiple server groups to be brought together into a single collapsable section. This is achieved by simply creating a local Sametime group and adding the necessary multiple server sub-groups or even groups to it.

SnTT: Busytime, Mail-in Database Calendars and Upgrading from ND6.x

March 6th, 2008

If your organisation is planning an upgrade from ND6.x and uses Mail-in Databases (based on the standard mail file template) for room or resource calendars etc., then beware that in ND7 and later, Busytime has undergone a very subtle but important change . . .

Now, instead of processing both Mail files and Mail-in Databases, in ND7 and later, Busytime will only processes the former. This means that following any upgrade, Busytime information will no longer be collected and displayed for Mail-In Databases.

To prevent this potential issue from occuring, simply create a new Person Document using the the same name, file path etc., as per the original Mail-in Database Document, and then delete the now superfluous Mail-in Database Document.

SnTT: PlanetLotus on your Notes 8.0.1 Sidebar, without using RSS

January 24th, 2008

One of the great new features in the new Notes 8.0.1 Client, is the “My Widgets” sidebar add-in. This enables web pages, or even Notes Views, to be easily rendered in a sidebar panel.

However because we are displaying information in a sidebar, we should endeavor to ensure that it’s content is concise and in particular, not too “wide” for a normally sized sidebar.

To my mind, the quickest and easiest way to achieve this for web pages, is to make use of readily available content, that has already been optimized for mobile devices and one such good example, is the mobile version of the highly addictive PlanetLotus. The following screenshot shows what it looks like once it’s been added:

full_sidebar.png

So, to actually add our new PlanetLotus sidebar panel, we simply select the Get Started… option from the My Widgets sidebar panel drop-down menu, and leaving most of its Wizard screens at default, simply add the the URL of the mobile version of PlanetLotus (http://mobile.planetlotus.org), when prompted to enter the Web page by URL: as per the following example screenshot:

url_dialog.png

Then continue hitting Next on each of the remaining Wizard dialogs, until you have no option left but to Finish.

So now all that is left, is to open your newly created Widget (from the My Widgets panel) and use just it as you would any other sidebar panel. Hint: Once in the PlanetLotus panel, use a combination of the PlanetLotus preview hotspot and the backspace key to easily navigate around its content.

Enjoy!

SnTT: Is There a Problem with Internet Mail?

January 11th, 2008

Okay Admins, how many times have you been asked this question and what do you do to test it? Immediately drop everything that you’re doing and quickly send a couple of test emails in/out to your personal Internet email account and then take any necessary corrective action if required?

Whilst that works, wouldn’t it be way more efficient if you could proactively monitor Internet mail 24/7 and automatically raise alerts if there is a problem, plus also produce availability stats, and all from the comfort of your internal Notes environment? Now I fully realise that you cannot monitor every single email, but if you periodically send and monitor receipt of, a token message every few minutes, then that would certainly give you a nice warm indicative feel for exactly how Internet mail is performing and more importantly, flag potential issues before they become problems.

Well you can and quite easily, with the aid of a very useful third party commercial application called GSX Monitor, which is specifically written for Notes/Domino environments (there maybe other suitable applications). Amongst its many supervisory/reporting/alerting functions and capabilities, GSX Monitor can monitor server/network availability, database replication, Domino/BES/Sametime server tasks plus internal Notes mail routing. And it is this last item that we will focus on here, as it is provides all of our required core functionality, to which we simply need to add the ability to monitor external SMTP mail.

GSX Monitor monitors Mail Routing by regularly sending ‘coded’ emails to a nominated target email address and deposits them into the router mail.box of a source server. Notes then routes the message to its destination address in the normal way and after a pre-configured (SLA) time, GSX Monitor then checks the target’s mailbox for the relevant emails, where it logs the delivery times and then if the SLA criteria has been broken, can optionally raise an alert.

Alas things are not always that easy, even with commercial software, and one “limitation” of GSX Monitor, is that it requires a direct network connection (NRPC) to all of the Domino servers that it monitors. Furthermore, Notes attempts to route mail intelligently by its shortest path, which is kind of a problem when monitoring external Internet mail, as you would need two Domino servers, with different Internet Mail Domain addresses and external SMTP connectivity, in order to fully test both inbound and outbound Internet traffic.

My solution to this issue is really quite obvious and very easy to implement at little or no cost (apart of course from GSX Monitor!). . . Simply configure GSX Monitor to send its test emails out to an externally hosted POP/IMAP account, which is inturn, configured to auto-forward or redirect it, back to a nominated internal account, which GSX Monitor can then monitor as its target mailbox!

As for the POP/IMAP mail hosting, it is best if it supports auto-forward/redirection of the entire message and for this, I currently use and highly recommend, 1&1 Internet. Although in the past I’ve also successfully used bigfoot.com and I suspect that it might also work with GoogleMail (although I’ve not yet have the opportunity to test this).

The following diagram outlines the end-to-end process which will hopefully make more sense:

gsxdiagram.PNG

The following is an example of the Mail Routing stats that GSX Monitor automatically outputs:

gsxstats.png

Oh, one last thing. don’t forget to ensure that the address which GSX Monitor uses to send its emails, is enabled for sending Internet mail, and also that it is added to any SMTP Whitelists in your environment, in order to prevent the test messages falling fowl of any anti-spam/spoofing policies that your company may have implemented.