Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions e2e/oidc-app/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,7 @@
*/

import './styles.css';

// window.addEventListener('load', () => {
// console.log('loaded parent');
// });
8 changes: 6 additions & 2 deletions e2e/oidc-app/src/ping-am/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@
#logout {
display: none;
}
#app {
display: none;
}
</style>
</head>
<body>
<a href="/">Home</a>
<h1>OIDC App | PingAM Login</h1>
<p id="loading">Loading...</p>
<div id="app">
<a href="/">Home</a>
<h1>OIDC App | PingAM Login</h1>
<button id="login-background">Login (Background)</button>
<button id="login-redirect">Login (Redirect)</button>
<button id="get-tokens">Get Tokens</button>
Expand Down
8 changes: 6 additions & 2 deletions e2e/oidc-app/src/ping-am/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,9 @@ const config = {
'https://openam-sdks.forgeblocks.com/am/oauth2/alpha/.well-known/openid-configuration',
},
};

oidcApp({ config, urlParams });
document.addEventListener('DOMContentLoaded', async () => {
console.log('loaded outside');
// (async () => {
await oidcApp({ config, urlParams });
// })();
});
8 changes: 6 additions & 2 deletions e2e/oidc-app/src/ping-one/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@
#logout {
display: none;
}
#app {
display: none;
}
</style>
</head>
<body>
<a href="/">Home</a>
<h1>OIDC App | PingOne Login</h1>
<p id="loading">Loading...</p>
<div id="app">
<a href="/">Home</a>
<h1>OIDC App | P1 Login</h1>
<button id="login-background">Login (Background)</button>
<button id="login-redirect">Login (Redirect)</button>
<button id="get-tokens">Get Tokens</button>
Expand Down
74 changes: 44 additions & 30 deletions e2e/oidc-app/src/utils/oidc-app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import type {
let tokenIndex = 0;

function displayError(error) {
// const appEl = document.getElementById('app');
const errorEl = document.createElement('div');
errorEl.innerHTML = `<p><strong>Error:</strong> <span class="error">${JSON.stringify(error, null, 2)}</span></p>`;
document.body.appendChild(errorEl);
Expand Down Expand Up @@ -52,39 +53,51 @@ export async function oidcApp({ config, urlParams }) {
const oidcClient = await oidc({ config });
if ('error' in oidcClient) {
displayError(oidcClient);
} else if (oidcClient) {
document.getElementById('app').style.display = 'block';
document.getElementById('loading').style.display = 'none';
}

document.getElementById('login-background').addEventListener('click', async () => {
const authorizeOptions: GetAuthorizationUrlOptions =
piflow === 'true'
? {
clientId: config.clientId,
redirectUri: config.redirectUri,
scope: config.scope,
responseType: config.responseType ?? 'code',
responseMode: 'pi.flow',
}
: undefined;
const response = await oidcClient.authorize.background(authorizeOptions);

if ('error' in response) {
console.error('Authorization Error:', response);
displayError(response);

if (response.redirectUrl) {
window.location.assign(response.redirectUrl);
} else {
console.log('Authorization failed with no ability to redirect:', response);
console.log('oidc app called');
// window.addEventListener('load', () => {
// console.log('loaded');
const myButton = document.getElementById('login-background');
if (myButton) {
console.log('button found');
myButton.addEventListener('click', async () => {
const authorizeOptions: GetAuthorizationUrlOptions =
piflow === 'true'
? {
clientId: config.clientId,
redirectUri: config.redirectUri,
scope: config.scope,
responseType: config.responseType ?? 'code',
responseMode: 'pi.flow',
}
: undefined;
const response = await oidcClient.authorize.background(authorizeOptions);

if ('error' in response) {
console.error('Authorization Error:', response);
displayError(response);

if (response.redirectUrl) {
window.location.assign(response.redirectUrl);
} else {
console.log('Authorization failed with no ability to redirect:', response);
}
return;

// Handle success response from background authorization
} else if ('code' in response) {
console.log('Authorization Code:', response.code);
const tokenResponse = await oidcClient.token.exchange(response.code, response.state);
displayTokenResponse(tokenResponse);
}
return;

// Handle success response from background authorization
} else if ('code' in response) {
console.log('Authorization Code:', response.code);
const tokenResponse = await oidcClient.token.exchange(response.code, response.state);
displayTokenResponse(tokenResponse);
}
});
});
} else {
console.log('not found');
}

document.getElementById('login-redirect').addEventListener('click', async () => {
const authorizeUrl = await oidcClient.authorize.url();
Expand Down Expand Up @@ -153,6 +166,7 @@ export async function oidcApp({ config, urlParams }) {
window.location.assign(window.location.origin + window.location.pathname);
}
});
// });

if (code && state) {
const response = await oidcClient.token.exchange(code, state);
Expand Down
10 changes: 10 additions & 0 deletions e2e/oidc-suites/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import baseConfig from '../../eslint.config.mjs';
import playwright from 'eslint-plugin-playwright';

export default [
...baseConfig,
Expand All @@ -19,4 +20,13 @@ export default [
// Override or add rules here
rules: {},
},
{
...playwright.configs['flat/recommended'],
files: ['src/*.spec.ts', 'src/utils/async-events.ts'],
rules: {
...playwright.configs['flat/recommended'].rules,
// Customize Playwright rules
// ...
},
},
];
48 changes: 29 additions & 19 deletions e2e/oidc-suites/src/login.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ import { asyncEvents } from './utils/async-events.js';

test.describe('PingAM login and get token tests', () => {
test('background login with valid credentials', async ({ page }) => {
const { navigate, clickButton } = asyncEvents(page);
await navigate('/ping-am/');
const { /* navigate, */ clickButton } = asyncEvents(page);
// await page.goto('/ping-am/');
await page.goto('/ping-am/');
expect(page.url()).toBe('http://localhost:8443/ping-am/');
await expect(page.locator('#loading')).toBeHidden();

await clickButton('Login (Background)', '/authorize');

Expand All @@ -33,9 +35,10 @@ test.describe('PingAM login and get token tests', () => {
});

test('redirect login with valid credentials', async ({ page }) => {
const { navigate, clickButton } = asyncEvents(page);
await navigate('/ping-am/');
const { clickButton } = asyncEvents(page);
await page.goto('/ping-am/');
expect(page.url()).toBe('http://localhost:8443/ping-am/');
await expect(page.locator('#loading')).toBeHidden();

await clickButton('Login (Redirect)', '/authorize');

Expand All @@ -49,9 +52,10 @@ test.describe('PingAM login and get token tests', () => {
});

test('background login with invalid client id fails', async ({ page }) => {
const { navigate } = asyncEvents(page);
await navigate('/ping-am/?clientid=bad-id');
// const { navigate } = asyncEvents(page);
await page.goto('/ping-am/?clientid=bad-id');
expect(page.url()).toBe('http://localhost:8443/ping-am/?clientid=bad-id');
await expect(page.locator('#loading')).toBeHidden();

await page.getByRole('button', { name: 'Login (Background)' }).click();

Expand All @@ -65,9 +69,10 @@ test.describe('PingAM login and get token tests', () => {

test.describe('PingOne login and get token tests', () => {
test('background login with valid credentials', async ({ page }) => {
const { navigate, clickButton } = asyncEvents(page);
await navigate('/ping-one/');
const { clickButton } = asyncEvents(page);
await page.goto('/ping-one/');
expect(page.url()).toBe('http://localhost:8443/ping-one/');
await expect(page.locator('#loading')).toBeHidden();

await clickButton('Login (Background)', '/authorize');

Expand All @@ -82,9 +87,10 @@ test.describe('PingOne login and get token tests', () => {
});

test('redirect login with valid credentials', async ({ page }) => {
const { navigate, clickButton } = asyncEvents(page);
await navigate('/ping-one/');
const { clickButton } = asyncEvents(page);
await page.goto('/ping-one/');
expect(page.url()).toBe('http://localhost:8443/ping-one/');
await expect(page.locator('#loading')).toBeHidden();

await clickButton('Login (Redirect)', '/authorize');

Expand All @@ -99,9 +105,10 @@ test.describe('PingOne login and get token tests', () => {
});

test('login with invalid client id fails', async ({ page }) => {
const { navigate } = asyncEvents(page);
await navigate('/ping-one/?clientid=bad-id');
// const { navigate } = asyncEvents(page);
await page.goto('/ping-one/?clientid=bad-id');
expect(page.url()).toBe('http://localhost:8443/ping-one/?clientid=bad-id');
await expect(page.locator('#loading')).toBeHidden();

await page.getByRole('button', { name: 'Login (Background)' }).click();

Expand All @@ -113,11 +120,12 @@ test.describe('PingOne login and get token tests', () => {
});

test('login with pi.flow response mode', async ({ page }) => {
const { navigate, clickButton } = asyncEvents(page);
await navigate('/ping-one/?piflow=true');
const { clickButton } = asyncEvents(page);
await page.goto('/ping-one/?piflow=true');
expect(page.url()).toBe('http://localhost:8443/ping-one/?piflow=true');
await expect(page.locator('#loading')).toBeHidden();

await page.on('request', (request) => {
page.on('request', (request) => {
const method = request.method();
const requestUrl = request.url();

Expand All @@ -140,9 +148,10 @@ test.describe('PingOne login and get token tests', () => {
});

test('login with invalid state fails with error', async ({ page }) => {
const { navigate } = asyncEvents(page);
await navigate('/ping-am/?code=12345&state=abcxyz');
// const { navigate } = asyncEvents(page);
await page.goto('/ping-am/?code=12345&state=abcxyz');
expect(page.url()).toBe('http://localhost:8443/ping-am/?code=12345&state=abcxyz');
await expect(page.locator('#loading')).toBeHidden();

await expect(page.locator('.error')).toContainText(`"error": "State mismatch"`);
await expect(page.locator('.error')).toContainText(`"type": "state_error"`);
Expand All @@ -152,9 +161,10 @@ test('login with invalid state fails with error', async ({ page }) => {
});

test('oidc client fails to initialize with bad wellknown', async ({ page }) => {
const { navigate } = asyncEvents(page);
await navigate('/ping-am/?wellknown=bad-wellknown');
// const { navigate } = asyncEvents(page);
await page.goto('/ping-am/?wellknown=bad-wellknown');
expect(page.url()).toBe('http://localhost:8443/ping-am/?wellknown=bad-wellknown');
await expect(page.locator('#loading')).toBeHidden();

await page.getByRole('button', { name: 'Login (Background)' }).click();

Expand Down
32 changes: 21 additions & 11 deletions e2e/oidc-suites/src/token.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,17 +105,20 @@ test.describe('PingAM tokens', () => {

test.describe('PingOne tokens', () => {
test('login and get tokens', async ({ page }) => {
const { navigate, clickButton } = asyncEvents(page);
await navigate('/ping-one/');
const { clickButton } = asyncEvents(page);
await page.goto('/ping-one/');
expect(page.url()).toBe('http://localhost:8443/ping-one/');
await expect(page.locator('#loading')).toBeHidden();

await clickButton('Login (Background)', 'https://apps.pingone.ca/');

await page.getByLabel('Username').fill(pingOneUsername);
await page.getByRole('textbox', { name: 'Password' }).fill(pingOnePassword);
const promise = page.waitForURL('http://localhost:8443/ping-one/**');
await page.getByRole('button', { name: 'Sign On' }).click();

await page.waitForURL('http://localhost:8443/ping-one/**', { waitUntil: 'networkidle' });
await promise;
await expect(page.locator('#loading')).toBeHidden();
expect(page.url()).toContain('code');
expect(page.url()).toContain('state');

Expand All @@ -128,17 +131,20 @@ test.describe('PingOne tokens', () => {
});

test('login and renew tokens', async ({ page }) => {
const { navigate, clickButton } = asyncEvents(page);
await navigate('/ping-one/');
const { clickButton } = asyncEvents(page);
await page.goto('/ping-one/');
expect(page.url()).toBe('http://localhost:8443/ping-one/');
await expect(page.locator('#loading')).toBeHidden();

await clickButton('Login (Background)', 'https://apps.pingone.ca/');

await page.getByLabel('Username').fill(pingOneUsername);
await page.getByRole('textbox', { name: 'Password' }).fill(pingOnePassword);
const promise = page.waitForURL('http://localhost:8443/ping-one/**');
await page.getByRole('button', { name: 'Sign On' }).click();

await page.waitForURL('http://localhost:8443/ping-one/**', { waitUntil: 'networkidle' });
await promise;
await expect(page.locator('#loading')).toBeHidden();
expect(page.url()).toContain('code');
expect(page.url()).toContain('state');

Expand All @@ -153,17 +159,20 @@ test.describe('PingOne tokens', () => {
});

test('login and revoke tokens', async ({ page }) => {
const { navigate, clickButton } = asyncEvents(page);
await navigate('/ping-one/');
const { clickButton } = asyncEvents(page);
await page.goto('/ping-one/');
expect(page.url()).toBe('http://localhost:8443/ping-one/');
await expect(page.locator('#loading')).toBeHidden();

await clickButton('Login (Background)', 'https://apps.pingone.ca/');

await page.getByLabel('Username').fill(pingOneUsername);
await page.getByRole('textbox', { name: 'Password' }).fill(pingOnePassword);
const promise = page.waitForURL('http://localhost:8443/ping-one/**');
await page.getByRole('button', { name: 'Sign On' }).click();

await page.waitForURL('http://localhost:8443/ping-one/**', { waitUntil: 'networkidle' });
await promise;
await expect(page.locator('#loading')).toBeHidden();
expect(page.url()).toContain('code');
expect(page.url()).toContain('state');

Expand All @@ -176,9 +185,10 @@ test.describe('PingOne tokens', () => {
});

test('renew tokens without logging in should error', async ({ page }) => {
const { navigate } = asyncEvents(page);
await navigate('/ping-one/');
// const { clickButton } = asyncEvents(page);
await page.goto('/ping-one/');
expect(page.url()).toBe('http://localhost:8443/ping-one/');
await expect(page.locator('#loading')).toBeHidden();

await page.getByRole('button', { name: 'Renew Tokens' }).click();

Expand Down
Loading
Loading