From ab92c230ffcd5daec3519de20d9e9fefa0e7b263 Mon Sep 17 00:00:00 2001 From: fcoppede Date: Thu, 23 Oct 2025 15:45:37 -0300 Subject: [PATCH 1/3] update component --- src/App.tsx | 13 ++++++----- src/components/JWTContainer.tsx | 40 ++++++++++++++++++++------------- 2 files changed, 32 insertions(+), 21 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 4cb3e43..c912b14 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2,7 +2,7 @@ import { useEffect, useState } from "react"; import "./App.css"; import { createZitadelAuth, ZitadelConfig } from "@zitadel/react"; import { BrowserRouter, Route, Routes } from "react-router-dom"; -import Navbar from "./components/Navbar" +import Navbar from "./components/Navbar"; import Login from "./components/Login"; import Callback from "./components/Callback"; @@ -11,12 +11,12 @@ import JWTContainer from "./components/JWTContainer"; function App() { const config: ZitadelConfig = { - authority: "https://CUSTOM_DOMAIN", - client_id: "YOUR_CLIENT_ID", + authority: "https://fcoppede-zitadel-zdho6i.us1.zitadel.cloud", + client_id: "322780308455918550", redirect_uri: "http://localhost:3000/callback", post_logout_redirect_uri: "http://localhost:3000", response_type: 'code', - scope: 'openid profile email' + scope: 'openid profile email offline_access' }; const zitadel = createZitadelAuth(config); @@ -32,6 +32,7 @@ function App() { const [authenticated, setAuthenticated] = useState(null); const [accessToken, setAccessToken] = useState(null); const [idToken, setIdToken] = useState(null); + const [refreshToken, setRefreshToken] = useState(null); useEffect(() => { zitadel.userManager.getUser().then((user) => { @@ -39,10 +40,12 @@ function App() { setAuthenticated(true); setAccessToken(user.access_token ?? null); setIdToken(user.id_token ?? null); + setRefreshToken(user.refresh_token ?? null); } else { setAuthenticated(false); setAccessToken(null); setIdToken(null); + setRefreshToken(null); } }); }, [zitadel]); @@ -53,7 +56,7 @@ function App() { - + { +const JWTContainer = ({ accessToken, idToken, refreshToken }: Props) => { const decodedAccessToken = accessToken ? JSON.stringify(decodeJWT(accessToken), null, 2) : null; const decodedIdToken = idToken ? JSON.stringify(decodeJWT(idToken), null, 2) : null; const [copyState, setCopyState] = useState<{ [key: string]: boolean }>({}); - const handleCopy = (target: "accessToken" | "idToken", text: string) => { + + const handleCopy = (target: "accessToken" | "idToken" | "refreshToken", text: string) => { navigator.clipboard.writeText(text).then(() => { setCopyState((prev) => ({ ...prev, [target]: true })); setTimeout(() => { @@ -48,8 +41,7 @@ const JWTContainer = ({ accessToken, idToken }: Props) => { Access Token {accessToken && ( handleCopy("accessToken", accessToken)} > @@ -59,15 +51,31 @@ const JWTContainer = ({ accessToken, idToken }: Props) => {
{decodedAccessToken || "No token generated yet."}
+ + {refreshToken && ( +
+
+ Refresh Token + handleCopy("refreshToken", refreshToken)} + > +
+
+
{refreshToken}
+
+
+ )} +
ID Token {idToken && ( handleCopy("idToken", idToken)} > @@ -82,4 +90,4 @@ const JWTContainer = ({ accessToken, idToken }: Props) => { ); }; -export default JWTContainer; \ No newline at end of file +export default JWTContainer; From eb7cbeeae73e31c781416f8bc7206ef7beaa564b Mon Sep 17 00:00:00 2001 From: fcoppede Date: Thu, 23 Oct 2025 15:55:59 -0300 Subject: [PATCH 2/3] Update README.md --- README.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/README.md b/README.md index 5e5c5f4..dec0392 100644 --- a/README.md +++ b/README.md @@ -111,3 +111,25 @@ yarn start ``` Your application will then run on `http://localhost:3000` + +## Enable Offline Access (Refresh Tokens) + +To retrieve a refresh token for offline access, follow these steps: + +1. Enable refresh tokens for your application: + - Navigate to your [application settings](https://zitadel.com/docs/guides/manage/console/applications#application-settings) and enable the **Refresh Token** checkbox. + +2. Add the `offline_access` scope: + +```js +const config: ZitadelConfig = { + authority: "https://CUSTOM_DOMAIN", + client_id: "YOUR_CLIENT_ID", + redirect_uri: "http://localhost:3000/callback", + post_logout_redirect_uri: "http://localhost:3000", + response_type: 'code', + scope: 'openid profile email offline_access' +}; +``` + +3. After logging out and logging back in, you will see the refresh token container displaying the refresh token. From 2d9f942c165f41d7de91a5bc058231578505c832 Mon Sep 17 00:00:00 2001 From: fcoppede Date: Thu, 23 Oct 2025 16:12:13 -0300 Subject: [PATCH 3/3] Update App.tsx --- src/App.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index c912b14..cc2e73f 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -11,12 +11,12 @@ import JWTContainer from "./components/JWTContainer"; function App() { const config: ZitadelConfig = { - authority: "https://fcoppede-zitadel-zdho6i.us1.zitadel.cloud", - client_id: "322780308455918550", + authority: "https://CUSTOM_DOMAIN", + client_id: "YOUR_CLIENT_ID", redirect_uri: "http://localhost:3000/callback", post_logout_redirect_uri: "http://localhost:3000", response_type: 'code', - scope: 'openid profile email offline_access' + scope: 'openid profile email' }; const zitadel = createZitadelAuth(config);