Skip to content

Commit e1b4cd2

Browse files
committed
feat(oidc-client): add oidc session check with response type of id_token and none
1 parent 354a238 commit e1b4cd2

20 files changed

Lines changed: 1716 additions & 81 deletions

.changeset/brave-foxes-dance.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@forgerock/iframe-manager': minor
3+
'@forgerock/oidc-client': minor
4+
---
5+
6+
Add `session.check()` method to oidc client for OIDC prompt=none session verification, with `response_type=none` and `response_type=id_token` support.

e2e/oidc-app/src/ping-am/index.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ <h1>OIDC App | PingAM Login</h1>
2121
<button id="logout">Logout</button>
2222
<button id="user-info-btn">User Info</button>
2323
<button id="revoke">Revoke Token</button>
24+
<button id="session-check-btn">Session Check (none)</button>
25+
<button id="session-check-id-token-btn">Session Check (id_token)</button>
2426
<a href="/ping-am/">Start Over</a>
2527
</div>
2628
<script type="module" src="./main.ts"></script>

e2e/oidc-app/src/ping-one/index.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ <h1>OIDC App | P1 Login</h1>
2121
<button id="logout">Logout</button>
2222
<button id="user-info-btn">User Info</button>
2323
<button id="revoke">Revoke Token</button>
24+
<button id="session-check-btn">Session Check (none)</button>
25+
<button id="session-check-id-token-btn">Session Check (id_token)</button>
2426
<a href="/ping-one/">Start Over</a>
2527
</div>
2628
<script type="module" src="./main.ts"></script>

e2e/oidc-app/src/utils/oidc-app.ts

Lines changed: 112 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@ import { oidc } from '@forgerock/oidc-client';
1010
import type {
1111
AuthorizationError,
1212
GenericError,
13-
GetAuthorizationUrlOptions,
1413
OauthTokens,
1514
OidcClient,
15+
OidcConfig,
16+
SessionCheckOptions,
1617
TokenExchangeErrorResponse,
1718
} from '@forgerock/oidc-client/types';
18-
1919
let tokenIndex = 0;
2020

21-
function displayError(error) {
21+
function displayError(error: unknown) {
2222
const errorEl = document.createElement('div');
2323
errorEl.innerHTML = `<p><strong>Error:</strong> <span class="error">${JSON.stringify(error, null, 2)}</span></p>`;
2424
document.body.appendChild(errorEl);
@@ -27,25 +27,44 @@ function displayError(error) {
2727
function displayTokenResponse(
2828
response: OauthTokens | TokenExchangeErrorResponse | GenericError | AuthorizationError,
2929
) {
30-
const appEl = document.getElementById('app');
3130
if ('error' in response || !('accessToken' in response)) {
3231
console.error('Token Error:', response);
3332
displayError(response);
3433
} else {
3534
console.log('Token Response:', response);
36-
document.getElementById('logout').style.display = 'block';
37-
document.getElementById('user-info-btn').style.display = 'block';
38-
document.getElementById('login-background').style.display = 'none';
39-
document.getElementById('login-redirect').style.display = 'none';
35+
const appEl = document.getElementById('app');
36+
const logoutEl = document.getElementById('logout');
37+
const userInfoBtnEl = document.getElementById('user-info-btn');
38+
const loginBackgroundEl = document.getElementById('login-background');
39+
const loginRedirectEl = document.getElementById('login-redirect');
40+
41+
if (logoutEl) {
42+
logoutEl.style.display = 'block';
43+
}
44+
if (userInfoBtnEl) {
45+
userInfoBtnEl.style.display = 'block';
46+
}
47+
if (loginBackgroundEl) {
48+
loginBackgroundEl.style.display = 'none';
49+
}
50+
if (loginRedirectEl) {
51+
loginRedirectEl.style.display = 'none';
52+
}
4053

4154
const tokenInfoEl = document.createElement('div');
4255
tokenInfoEl.innerHTML = `<p><strong>Access Token:</strong> <span id="accessToken-${tokenIndex}">${response.accessToken}</span></p>`;
43-
appEl.appendChild(tokenInfoEl);
56+
appEl?.appendChild(tokenInfoEl);
4457
tokenIndex++;
4558
}
4659
}
4760

48-
export async function oidcApp({ config, urlParams }) {
61+
export async function oidcApp({
62+
config,
63+
urlParams,
64+
}: {
65+
config: OidcConfig;
66+
urlParams: URLSearchParams;
67+
}) {
4968
const code = urlParams.get('code');
5069
const state = urlParams.get('state');
5170
const piflow = urlParams.get('piflow');
@@ -56,20 +75,23 @@ export async function oidcApp({ config, urlParams }) {
5675
});
5776
if ('error' in oidcClient) {
5877
displayError(oidcClient);
78+
return;
5979
}
6080

61-
document.getElementById('login-background').addEventListener('click', async () => {
62-
const authorizeOptions: GetAuthorizationUrlOptions =
81+
document.getElementById('login-background')?.addEventListener('click', async () => {
82+
const authorizeOptions =
6383
piflow === 'true'
6484
? {
6585
clientId: config.clientId,
6686
redirectUri: config.redirectUri,
6787
scope: config.scope,
6888
responseType: config.responseType ?? 'code',
69-
responseMode: 'pi.flow',
89+
responseMode: 'pi.flow' as const,
7090
}
7191
: undefined;
72-
const response = await oidcClient.authorize.background(authorizeOptions);
92+
const response = await oidcClient.authorize?.background(authorizeOptions);
93+
94+
if (!response) return;
7395

7496
if ('error' in response) {
7597
console.error('Authorization Error:', response);
@@ -85,13 +107,16 @@ export async function oidcApp({ config, urlParams }) {
85107
// Handle success response from background authorization
86108
} else if ('code' in response) {
87109
console.log('Authorization Code:', response.code);
88-
const tokenResponse = await oidcClient.token.exchange(response.code, response.state);
89-
displayTokenResponse(tokenResponse);
110+
const tokenResponse = await oidcClient.token?.exchange(response.code, response.state);
111+
if (tokenResponse) {
112+
displayTokenResponse(tokenResponse);
113+
}
90114
}
91115
});
92116

93-
document.getElementById('login-redirect').addEventListener('click', async () => {
94-
const authorizeUrl = await oidcClient.authorize.url();
117+
document.getElementById('login-redirect')?.addEventListener('click', async () => {
118+
const authorizeUrl = await oidcClient.authorize?.url();
119+
if (!authorizeUrl) return;
95120
if (typeof authorizeUrl !== 'string' && 'error' in authorizeUrl) {
96121
console.error('Authorization URL Error:', authorizeUrl);
97122
displayError(authorizeUrl);
@@ -102,23 +127,31 @@ export async function oidcApp({ config, urlParams }) {
102127
}
103128
});
104129

105-
document.getElementById('get-tokens').addEventListener('click', async () => {
106-
const response = await oidcClient.token.get();
107-
displayTokenResponse(response);
130+
document.getElementById('get-tokens')?.addEventListener('click', async () => {
131+
const response = await oidcClient.token?.get();
132+
if (response) {
133+
displayTokenResponse(response);
134+
}
108135
});
109136

110-
document.getElementById('get-tokens-background').addEventListener('click', async () => {
111-
const response = await oidcClient.token.get({ backgroundRenew: true });
112-
displayTokenResponse(response);
137+
document.getElementById('get-tokens-background')?.addEventListener('click', async () => {
138+
const response = await oidcClient.token?.get({ backgroundRenew: true });
139+
if (response) {
140+
displayTokenResponse(response);
141+
}
113142
});
114143

115-
document.getElementById('renew-tokens').addEventListener('click', async () => {
116-
const response = await oidcClient.token.get({ backgroundRenew: true, forceRenew: true });
117-
displayTokenResponse(response);
144+
document.getElementById('renew-tokens')?.addEventListener('click', async () => {
145+
const response = await oidcClient.token?.get({ backgroundRenew: true, forceRenew: true });
146+
if (response) {
147+
displayTokenResponse(response);
148+
}
118149
});
119150

120-
document.getElementById('user-info-btn').addEventListener('click', async () => {
121-
const userInfo = await oidcClient.user.info();
151+
document.getElementById('user-info-btn')?.addEventListener('click', async () => {
152+
const userInfo = await oidcClient.user?.info();
153+
154+
if (!userInfo) return;
122155

123156
if ('error' in userInfo) {
124157
console.error('User Info Error:', userInfo);
@@ -129,42 +162,78 @@ export async function oidcApp({ config, urlParams }) {
129162
const appEl = document.getElementById('app');
130163
const userInfoEl = document.createElement('div');
131164
userInfoEl.innerHTML = `<p><strong>User Info:</strong> <span id="userInfo">${JSON.stringify(userInfo, null, 2)}</span></p>`;
132-
appEl.appendChild(userInfoEl);
165+
appEl?.appendChild(userInfoEl);
133166
}
134167
});
135168

136-
document.getElementById('revoke').addEventListener('click', async () => {
137-
const response = await oidcClient.token.revoke();
169+
document.getElementById('revoke')?.addEventListener('click', async () => {
170+
const response = await oidcClient.token?.revoke();
171+
172+
if (!response) return;
138173

139174
if ('error' in response) {
140175
console.error('Token Revocation Error:', response);
141176
displayError(response);
142177
} else {
143178
const appEl = document.getElementById('app');
144-
const userInfoEl = document.createElement('div');
145-
userInfoEl.innerHTML = `<p>Token successfully revoked</p>`;
146-
appEl.appendChild(userInfoEl);
179+
const revokeEl = document.createElement('div');
180+
revokeEl.innerHTML = `<p>Token successfully revoked</p>`;
181+
appEl?.appendChild(revokeEl);
147182
}
148183
});
149184

150-
document.getElementById('logout').addEventListener('click', async () => {
151-
const response = await oidcClient.user.logout();
185+
document.getElementById('logout')?.addEventListener('click', async () => {
186+
const response = await oidcClient.user?.logout();
187+
188+
if (!response) return;
152189

153190
if ('error' in response) {
154191
console.error('Logout Error:', response);
155192
displayError(response);
156193
} else {
157194
console.log('Logout successful');
158-
document.getElementById('logout').style.display = 'none';
159-
document.getElementById('user-info-btn').style.display = 'none';
160-
document.getElementById('login-background').style.display = 'block';
161-
document.getElementById('login-redirect').style.display = 'block';
195+
const logoutEl = document.getElementById('logout');
196+
const userInfoBtnEl = document.getElementById('user-info-btn');
197+
const loginBackgroundEl = document.getElementById('login-background');
198+
const loginRedirectEl = document.getElementById('login-redirect');
199+
200+
if (logoutEl) {
201+
logoutEl.style.display = 'none';
202+
}
203+
if (userInfoBtnEl) {
204+
userInfoBtnEl.style.display = 'none';
205+
}
206+
if (loginBackgroundEl) {
207+
loginBackgroundEl.style.display = 'block';
208+
}
209+
if (loginRedirectEl) {
210+
loginRedirectEl.style.display = 'block';
211+
}
162212
window.location.assign(window.location.origin + window.location.pathname);
163213
}
164214
});
165215

216+
document.getElementById('session-check-btn')?.addEventListener('click', async () => {
217+
const result = await oidcClient.session?.check();
218+
const appEl = document.getElementById('app');
219+
const el = document.createElement('div');
220+
el.innerHTML = `<p><strong>Session Check (none):</strong></p><pre id="session-check-result">${JSON.stringify(result, null, 2)}</pre>`;
221+
appEl?.appendChild(el);
222+
});
223+
224+
document.getElementById('session-check-id-token-btn')?.addEventListener('click', async () => {
225+
const options: SessionCheckOptions = { responseType: 'id_token' };
226+
const result = await oidcClient.session?.check(options);
227+
const appEl = document.getElementById('app');
228+
const el = document.createElement('div');
229+
el.innerHTML = `<p><strong>Session Check (id_token):</strong></p><pre id="session-check-id-token-result">${JSON.stringify(result, null, 2)}</pre>`;
230+
appEl?.appendChild(el);
231+
});
232+
166233
if (code && state) {
167-
const response = await oidcClient.token.exchange(code, state);
168-
displayTokenResponse(response);
234+
const response = await oidcClient.token?.exchange(code, state);
235+
if (response) {
236+
displayTokenResponse(response);
237+
}
169238
}
170239
}

0 commit comments

Comments
 (0)