Skip to content

Commit d08f3c7

Browse files
authored
Merge pull request #14 from SecureAuthCorp/feat/token-refresh-sample
Add token refresh sample and improve error handling
2 parents 2a9524c + 22ffc00 commit d08f3c7

23 files changed

Lines changed: 3077 additions & 13 deletions

.github/dependabot.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,16 @@ updates:
1010
commit-message:
1111
prefix: "deps"
1212

13+
- package-ecosystem: "npm"
14+
directory: "/samples/react/token-refresh"
15+
schedule:
16+
interval: "weekly"
17+
open-pull-requests-limit: 5
18+
labels:
19+
- "dependencies"
20+
commit-message:
21+
prefix: "deps"
22+
1323
- package-ecosystem: "npm"
1424
directory: "/scripts"
1525
schedule:

.github/workflows/test-js.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
outputs:
2121
matrix: ${{ steps.find.outputs.matrix }}
2222
steps:
23-
- uses: actions/checkout@v4
23+
- uses: actions/checkout@v6
2424
- id: find
2525
run: |
2626
DIRS=$(find samples -name "package.json" -not -path "*/node_modules/*" -exec dirname {} \; 2>/dev/null | sort | jq -R -s -c 'split("\n") | map(select(. != ""))')
@@ -35,8 +35,8 @@ jobs:
3535
matrix:
3636
project: ${{ fromJson(needs.find-projects.outputs.matrix) }}
3737
steps:
38-
- uses: actions/checkout@v4
39-
- uses: actions/setup-node@v4
38+
- uses: actions/checkout@v6
39+
- uses: actions/setup-node@v6
4040
with:
4141
node-version: "22"
4242
- name: Enable Corepack

samples/react/login-pkce/src/App.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,14 @@ function AuthButtons() {
2424
}
2525

2626
if (auth.error) {
27-
return <div>Error: {auth.error.message}</div>;
27+
const hint = new URLSearchParams(window.location.search).get("error_hint");
28+
return (
29+
<div style={{ color: "red" }}>
30+
<p>Error: {auth.error.message}</p>
31+
{hint && <p>{hint}</p>}
32+
<button onClick={() => auth.signinRedirect()}>Try again</button>
33+
</div>
34+
);
2835
}
2936

3037
if (auth.isAuthenticated) {
Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
1-
import React from "react";
21
import ReactDOM from "react-dom/client";
32

43
import App from "./App";
54

6-
ReactDOM.createRoot(document.getElementById("root")!).render(
7-
<React.StrictMode>
8-
<App />
9-
</React.StrictMode>,
10-
);
5+
ReactDOM.createRoot(document.getElementById("root")!).render(<App />);

samples/react/manifest.yaml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,22 @@ scenarios:
2525
value: "{{SCOPES}}"
2626
- label: "Grant"
2727
value: "Authorization Code + PKCE"
28+
29+
spa_token_refresh:
30+
app_type: single_page
31+
display_name: "Token Refresh"
32+
grant: "Refresh Token"
33+
description: "Use refresh tokens to get new access tokens without re-prompting the user. Requires offline_access scope."
34+
callout: "Requires refresh_token grant type enabled in workspace OAuth settings and in the application's Grant Types. Also requires the offline_access scope."
35+
run_command: "yarn install && yarn dev"
36+
required_scopes:
37+
- offline_access
38+
config_rows:
39+
- label: "Client ID"
40+
value: "{{CLIENT_ID}}"
41+
- label: "Issuer URL"
42+
value: "{{ISSUER_URL}}"
43+
- label: "Redirect URI"
44+
value: "{{REDIRECT_URI}}"
45+
- label: "Scopes"
46+
value: "{{SCOPES}}"
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
ISSUER_URL=https://your-tenant.us.secureauth.com/your-workspace
2+
CLIENT_ID=your-client-id
3+
REDIRECT_URI=http://localhost:3000/callback
4+
SCOPES=openid profile email offline_access

samples/react/token-refresh/.yarn/releases/yarn-4.13.0.cjs

Lines changed: 940 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
defaultSemverRangePrefix: ""
2+
3+
nodeLinker: node-modules
4+
5+
npmRegistryServer: "https://registry.npmjs.org"
6+
7+
yarnPath: .yarn/releases/yarn-4.13.0.cjs
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# React SPA — Token Refresh
2+
3+
Minimal React app demonstrating token refresh using `react-oidc-context` with the `offline_access` scope. Tokens are refreshed automatically before they expire, and can also be refreshed manually via a button.
4+
5+
## Prerequisites
6+
7+
- `offline_access` scope enabled on the client
8+
- `refresh_token` grant type enabled in workspace OAuth settings and in the application's Grant Types
9+
10+
## Setup
11+
12+
1. Copy `.env.example` to `.env` and fill in your SecureAuth values
13+
2. `yarn install`
14+
3. `yarn dev`
15+
4. Open http://localhost:3000
16+
17+
## What this demonstrates
18+
19+
- OIDC configuration with `offline_access` scope for refresh tokens
20+
- Automatic token refresh via refresh tokens (no iframe needed)
21+
- Manual token refresh via `signinSilent()` button
22+
- Displaying token expiry information
23+
- Error handling with OAuth error hints
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>SecureAuth React Token Refresh</title>
7+
</head>
8+
<body>
9+
<div id="root"></div>
10+
<script type="module" src="/src/index.tsx"></script>
11+
</body>
12+
</html>

0 commit comments

Comments
 (0)