Skip to content

Commit

Permalink
Store access token expiry in apps login page
Browse files Browse the repository at this point in the history
  • Loading branch information
mpgxvii committed Nov 27, 2024
1 parent 74bae26 commit 426f638
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 21 deletions.
48 changes: 36 additions & 12 deletions pages/fitbit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import Head from "next/head"
import Link from "next/link"
import { useRouter } from "next/router"
import { ReactNode, useEffect, useState } from "react"
import QRCode from "react-qr-code"

import { ActionCard, CenterLink, Methods, CardTitle } from "../pkg"
import ory from "../pkg/sdk"
Expand All @@ -28,12 +27,18 @@ const Fitbit: NextPage = () => {
const { flow: flowId, return_to: returnTo } = router.query
const [traits, setTraits] = useState<any>()
const [projects, setProjects] = useState<any>([])
const [tokenHandled, setTokenHandled] = useState(false) // Flag to ensure token is handled once
const [tokenHandled, setTokenHandled] = useState(false)
const [isFetchingToken, setIsFetchingToken] = useState(false) // Prevent multiple calls

const handleNavigation = () => {
return restSourceClient.redirectToAuthRequestLink()
}

const isTokenExpired = (expiryTime: string | null) => {
if (!expiryTime) return true
return new Date().getTime() > new Date(expiryTime).getTime()
}

useEffect(() => {
ory.toSession().then(({ data }) => {
const traits = data?.identity?.traits
Expand All @@ -44,29 +49,48 @@ const Fitbit: NextPage = () => {

useEffect(() => {
const handleToken = async () => {
if (!router.isReady || !projects.length || tokenHandled) return
if (!router.isReady || !projects.length || tokenHandled || isFetchingToken) return

const existingToken = localStorage.getItem("access_token")
const tokenExpiry = localStorage.getItem("access_token_expiry")

if (existingToken) {
if (existingToken && !isTokenExpired(tokenExpiry)) {
await restSourceClient.redirectToRestSourceAuthLink(
existingToken,
projects[0],
projects[0]
)
setTokenHandled(true)
return
}

const token = await restSourceClient.getAccessTokenFromRedirect()
if (token) {
localStorage.setItem("access_token", token)
await restSourceClient.redirectToRestSourceAuthLink(token, projects[0])
setTokenHandled(true)
// Token is either missing or expired; fetch a new one
setIsFetchingToken(true)
try {
const tokenResponse = await restSourceClient.getAccessTokenFromRedirect()
if (tokenResponse?.access_token && tokenResponse?.expires_in) {
const accessToken = tokenResponse.access_token
const expiryTime = new Date(
new Date().getTime() + tokenResponse.expires_in * 1000
).toISOString()

localStorage.setItem("access_token", accessToken)
localStorage.setItem("access_token_expiry", expiryTime)

await restSourceClient.redirectToRestSourceAuthLink(
accessToken,
projects[0]
)
setTokenHandled(true)
}
} catch (error) {
console.error("Failed to fetch token:", error)
} finally {
setIsFetchingToken(false)
}
}

handleToken()
}, [router.isReady, projects, tokenHandled])
}, [router.isReady, projects, tokenHandled, isFetchingToken])

return (
<>
Expand Down Expand Up @@ -122,4 +146,4 @@ const QrForm: React.FC<QrFormProps> = ({ projects, navigate }) => {
}
}

export default Fitbit
export default Fitbit
3 changes: 2 additions & 1 deletion pkg/hooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ export function LogoutLink(deps?: DependencyList) {
if (logoutToken) {
ory
.updateLogoutFlow({ token: logoutToken })
.then(() => Promise.resolve(localStorage.clear()))
.then(() => router.push("/login"))
.then(() => router.reload())
}
}
}
}
14 changes: 6 additions & 8 deletions services/rest-source-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export class RestSourceClient {
async getAccessToken(
code: string,
redirectUri: string,
): Promise<string | null> {
): Promise<any> {
const bodyParams = new URLSearchParams({
grant_type: this.GRANT_TYPE,
code,
Expand All @@ -77,14 +77,14 @@ export class RestSourceClient {
}

const data = await response.json()
return data.access_token || null
return data || null
} catch (error) {
console.error(error)
return null
}
}

async getAccessTokenFromRedirect(): Promise<string | null> {
async getAccessTokenFromRedirect(): Promise<any> {
const url = new URL(window.location.href)
const code = url.searchParams.get("code")
if (!code) return null
Expand All @@ -102,11 +102,9 @@ export class RestSourceClient {
"SUBJECT.CREATE",
].join("%20")

const authUrl = `${this.AUTH_BASE_URL}/auth?client_id=${
this.CLIENT_ID
}&response_type=code&state=${Date.now()}&audience=res_restAuthorizer&scope=${scopes}&redirect_uri=${
window.location.href.split("?")[0]
}`
const authUrl = `${this.AUTH_BASE_URL}/auth?client_id=${this.CLIENT_ID
}&response_type=code&state=${Date.now()}&audience=res_restAuthorizer&scope=${scopes}&redirect_uri=${window.location.href.split("?")[0]
}`

window.location.href = authUrl
}
Expand Down

0 comments on commit 426f638

Please sign in to comment.