Skip to content

Commit

Permalink
Merge branch 'main' into workspace/v19.2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
johnman committed Nov 7, 2024
2 parents 2100fbe + 1bad456 commit dd17299
Show file tree
Hide file tree
Showing 10 changed files with 340 additions and 10 deletions.
98 changes: 97 additions & 1 deletion how-to/integrate-server-authentication/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,91 @@

Your OpenFin application will often need to authenticate using a server login page before use, this examples demonstrates such an integration.

This application you are about to install is a simple example of plugging in your own content or app. The basic server intercepts a request to the provider window and checks to see if you are authenticated. If you are not it redirects to a login screen. If you are then it will load the provider window. The settings in the manifest make the provider window visible (so it acts as a splash screen or the location where the login form will be displayed). When you have an authenticated session and the splash screen is visible then the provider will hide itself after a period of time and launch the main application window. This example assumes you have already [set up your development environment](https://developers.openfin.co/of-docs/docs/set-up-your-dev-environment)
This application you are about to install is a simple example of plugging in your own content or app. The basic server intercepts a request to the provider window and checks to see if you are authenticated. If you are not it redirects to a login screen. If you are then it will load the provider window.

This example assumes you have already [set up your development environment](https://developers.openfin.co/of-docs/docs/set-up-your-dev-environment)

There are two use cases covered:

## Server side authentication with the platform provider window visible

The settings in the [manifest.fin.json](./public/manifest.fin.json) make the provider window visible (so it acts as a splash screen or the location where the login form will be displayed). When you have an authenticated session and the splash screen is visible then the provider will hide itself after a period of time and launch the main application window.

```json
"platform": {
...
"autoShow": true,
"providerUrl": "http://localhost:8080/platform/provider.html",
},
```

## Server side authentication with the platform provider window invisible

The settings in the [second.manifest.fin.json](./public/second.manifest.fin.json) make the provider window invisible. When the server redirects to a login screen then a preload script which is loaded into the provider window checks to see if the window should be visible (if it is the login screen) or if an error window should be shown (if it isn't the login screen and it isn't the provider window....i.e. it has become stuck as part of a redirect).

```json
"platform": {
...
"autoShow": false,
"providerUrl": "http://localhost:8080/platform/provider.html",
"preloadScripts": [
{
"url": "http://localhost:8080/preload/auth-preload-check.js"
}
]
},
```

The preload script needs to be in an area that does not require authentication (as you haven't been authenticated yet if you are on the login screen).

The [preload script](./public/preload/auth-preload-check.js) is an example and should not be treated as production code:

```javascript
document.addEventListener('DOMContentLoaded', async () => {
console.log('auth-preload-check.js loaded. Performing logic checks.');
// preload scripts can be loaded into an iframe so only check the top level window
if (window === window.top && window.fin !== undefined) {
// TODO: ADD YOUR OWN LOGIC HERE
console.log('auth-preload-check.js logic starting.');
// Create a new URL object from the current window location
const url = new URL(window.location.href);

// TODO: ADD YOUR OWN PATH LOGIC HERE
// determine behavior based on the current URL (we have example paths)
if (url.pathname === '/app/login') {
console.log('Detected we are on the login page.');
// If we are on the login page ensure the page is visible
await fin.me.show();
} else {
// ensure the page is hidden as we may have shown it if it was the login page and we are now on a redirect page or the provider.
console.log('We are on a page that should not be visible. Ensuring the window is hidden.');
await fin.me.hide();
}

// TODO: WHEN STUCK OR UNHAPPY PATH DETERMINE WHAT TO DO NEXT
// We provide an example of launching a new window to show a friendly error message
if (url.pathname === '/app/stuck') {
console.log(
'Detected we are authenticated but a redirect has encountered an error and is stuck so the main provider.html page will not be loaded. Showing a friendly error message.'
);
window.open('/app/friendly-error', '_blank');
}
}
});
```

## Login Accounts

There are two login accounts that simulate a successful scenario and a stuck scenario. The stuck scenario is a redirect page the platform doesn't control so when it happens the manifest.fin.json file will be stuck on that page. The second.manifest.fin.json file uses a preload script that detects it is on a stuck page and launches a user error page.

- Success account: `[email protected] / pass1234`
- Stuck account: `[email protected] / pass1234`

## Things to note

You may have different paths depending on environment. You might decide to have environment based preload scripts that are assigned to the environment specific manifest file.

Consider the unhappy path. What would be helpful to your users and your support team if a user could not login to your platform. In our example we show a pop up window but your business/product owner should be involved in the conversation.

## Running the Sample

Expand Down Expand Up @@ -44,14 +128,26 @@ npm run start
npm run client
```

or to run the hidden provider window using a preload script:

```shell
npm run secondclient
```

5. If you modify and want to build the code you can run the build command.

```shell
npm run build
```

## Scenario 1 - manifest.fin.json - Visible Provider Window

![Server Authentication](openfin-integrate-server-authentication.gif)

## Scenario 2 - second.manifest.fin.json - Invisible Provider Window

![Server Authentication Hidden Provider](openfin-integrate-server-authentication-hidden.gif)

---

### Read more about [working with Workspace](https://developers.openfin.co/of-docs/docs/overview-of-workspace)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions how-to/integrate-server-authentication/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"dos": "node ./scripts/dos.mjs && node ./scripts/kill.mjs",
"kill": "node ./scripts/kill.mjs",
"client": "node ./scripts/launch.mjs",
"secondclient": "node ./scripts/launch.mjs http://localhost:8080/second.manifest.fin.json",
"build-client": "webpack build --config ./client/webpack.config.js --mode=development",
"build-server": "tsc --project ./server",
"build": "npm run build-server && npm run build-client",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<title>Friendly Error Page</title>
<link rel="icon" type="image/x-icon" href="../favicon.ico" />
<meta name="description" content="" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="../common/style/app.css" />
</head>

<body class="col fill gap20">
<header class="row spread middle">
<div class="col">
<h1>Friendly Error Page</h1>
<h1 class="tag">We are on the unhappy path.</h1>
</div>
<div class="row middle gap20">
<image src="../common/images/icon-blue.png" alt="OpenFin" height="40px"></image>
</div>
</header>
<main class="col fill gap10">
<p>
The provider has not been loaded due to an error so the platform cannot perform the necessary
bootstrapping steps to launch the platform.
</p>
<p>If you logout and exit you will be presented with the login screen again.</p>
<p>If you just exit you will be presented with this screen again.</p>
</main>
<footer class="row right gap20">
<button id="btnLogout">Logout and Exit</button>
<button id="btnExit">Exit</button>
</footer>

<script>
const btnLogout = document.querySelector('#btnLogout');
btnLogout.addEventListener('click', () => {
// On logout the session cookies are cleared and close the app
fetch('http://localhost:8080/app/logout', {
method: 'post'
}).then(async (response) => {
await fin.Application.getCurrentSync().quit();
});
});
const btnExit = document.querySelector('#btnExit');
btnExit.addEventListener('click', async () => {
await fin.Application.getCurrentSync().quit();
});
</script>
</body>
</html>
9 changes: 7 additions & 2 deletions how-to/integrate-server-authentication/public/app/login.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,13 @@ <h1 class="tag">Demonstrate integrating Server Authentication.</h1>
<main class="col fill gap10 pad20">
<form class="col left gap20">
<p>
This example only has one set of credentials that work
<i>[email protected] / pass1234</i>
This example only has one set of credentials that work:
<i><b>[email protected] / pass1234</b></i>
</p>
<p>
The other set of credentials will authenticate you but then simulate a failure so that you are stuck
in a redirect before the provider page is loaded (you can logout and exit to clear this session):
<i><b>[email protected] / pass1234</b></i>
</p>
<p>Enter your credentials to login:</p>
<fieldset>
Expand Down
51 changes: 51 additions & 0 deletions how-to/integrate-server-authentication/public/app/stuck.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<title>Stuck Redirect</title>
<link rel="icon" type="image/x-icon" href="../favicon.ico" />
<meta name="description" content="" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="../common/style/app.css" />
</head>

<body class="col fill gap20">
<header class="row spread middle">
<div class="col">
<h1>Stuck Redirect</h1>
<h1 class="tag">An example of a window that the platform doesn't control.</h1>
</div>
<div class="row middle gap20">
<image src="../common/images/icon-blue.png" alt="OpenFin" height="40px"></image>
</div>
</header>
<main class="col fill gap10">
<p>
An example assuming you have logged in and are authenticated or you were already authenticated but
something went wrong before you were redirected to the main provider page.
</p>
<p>If you logout and exit you will be presented with the login screen again.</p>
<p>If you just exit you will be presented with this screen again.</p>
</main>
<footer class="row right gap20">
<button id="btnLogout">Logout and Exit</button>
<button id="btnExit">Exit</button>
</footer>
<script>
const btnLogout = document.querySelector('#btnLogout');
btnLogout.addEventListener('click', () => {
// On logout the session cookies are cleared and close the app
fetch('http://localhost:8080/app/logout', {
method: 'post'
}).then(async (response) => {
await fin.Application.getCurrentSync().quit();
});
});
const btnExit = document.querySelector('#btnExit');
btnExit.addEventListener('click', async () => {
await fin.Application.getCurrentSync().quit();
});
</script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
document.addEventListener('DOMContentLoaded', async () => {
console.log('auth-preload-check.js loaded. Performing logic checks.');
// preload scripts can be loaded into an iframe so only check the top level window
if (window === window.top && window.fin !== undefined) {
// TODO: ADD YOUR OWN LOGIC HERE
console.log('auth-preload-check.js logic starting.');
// Create a new URL object from the current window location
const url = new URL(window.location.href);

// TODO: ADD YOUR OWN PATH LOGIC HERE
// determine behavior based on the current URL (we have example paths)
if (url.pathname === '/app/login') {
console.log('Detected we are on the login page.');
// If we are on the login page ensure the page is visible
await fin.me.show();
} else {
// ensure the page is hidden as we may have shown it if it was the login page and we are now on a redirect page or the provider.
console.log('We are on a page that should not be visible. Ensuring the window is hidden.');
await fin.me.hide();
}

// TODO: WHEN STUCK OR UNHAPPY PATH DETERMINE WHAT TO DO NEXT
// We provide an example of launching a new window to show a friendly error message
if (url.pathname === '/app/stuck') {
console.log(
'Detected we are authenticated but a redirect has encountered an error and is stuck so the main provider.html page will not be loaded. Showing a friendly error message.'
);
window.open('/app/friendly-error', '_blank');
}
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"devtools_port": 9090,
"licenseKey": "openfin-demo-license-key",
"runtime": {
"arguments": "",
"version": "38.126.83.79"
},
"platform": {
"uuid": "integrate-server-authentication-hidden",
"icon": "http://localhost:8080/favicon.ico",
"autoShow": false,
"providerUrl": "http://localhost:8080/platform/provider.html",
"preventQuitOnLastWindowClosed": true,
"frame": false,
"alwaysOnTop": true,
"resizable": false,
"defaultCentered": true,
"defaultHeight": 700,
"defaultWidth": 600,
"saveWindowState": false,
"showTaskbarIcon": false,
"cornerRounding": {
"width": 10,
"height": 10
},
"preloadScripts": [
{
"url": "http://localhost:8080/preload/auth-preload-check.js"
}
]
},
"shortcut": {
"company": "OpenFin",
"description": "A way of showing examples of what OpenFin can do.",
"icon": "http://localhost:8080/favicon.ico",
"name": "Integrate Server Authentication - Hidden Provider - v19.1.0",
"target": ["desktop", "start-menu"]
},
"supportInformation": {
"company": "OpenFin",
"product": "Workspace Starter - Integrate Server Authentication - Client - Hidden Provider",
"email": "[email protected]",
"forwardErrorReports": true
}
}
Loading

0 comments on commit dd17299

Please sign in to comment.