fix: handle cache tags for service tokens
This commit is contained in:
committed by
Pontus Dreij
parent
e5f85e0499
commit
3c548923ff
@@ -1,35 +1,58 @@
|
||||
import { revalidateTag, unstable_cache } from "next/cache"
|
||||
|
||||
import { env } from "@/env/server"
|
||||
|
||||
import { generateServiceTokenTag } from "@/utils/generateTag"
|
||||
|
||||
import { ServiceTokenScope } from "@/types/enums/serviceToken"
|
||||
import { ServiceTokenResponse } from "@/types/tokens"
|
||||
|
||||
const SERVICE_TOKEN_REVALIDATE_SECONDS = 3599 // 59 minutes and 59 seconds.
|
||||
async function getServiceToken(scopes: ServiceTokenScope[]) {
|
||||
const response = await fetch(`${env.CURITY_ISSUER_USER}/oauth/v2/token`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
Accept: "application/json",
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
grant_type: "client_credentials",
|
||||
client_id: env.CURITY_CLIENT_ID_SERVICE,
|
||||
client_secret: env.CURITY_CLIENT_SECRET_SERVICE,
|
||||
scope: scopes.join(" "),
|
||||
}),
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to obtain service token")
|
||||
}
|
||||
|
||||
return response.json()
|
||||
}
|
||||
|
||||
export async function fetchServiceToken(
|
||||
scopes: string[]
|
||||
scopes: ServiceTokenScope[]
|
||||
): Promise<ServiceTokenResponse> {
|
||||
try {
|
||||
const response = await fetch(`${env.CURITY_ISSUER_USER}/oauth/v2/token`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
Accept: "application/json",
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
grant_type: "client_credentials",
|
||||
client_id: env.CURITY_CLIENT_ID_SERVICE,
|
||||
client_secret: env.CURITY_CLIENT_SECRET_SERVICE,
|
||||
scope: scopes.join(" "),
|
||||
}),
|
||||
next: {
|
||||
revalidate: SERVICE_TOKEN_REVALIDATE_SECONDS,
|
||||
},
|
||||
})
|
||||
const tag = generateServiceTokenTag(scopes)
|
||||
const getCachedJwt = unstable_cache(
|
||||
async (scopes) => {
|
||||
const jwt = await getServiceToken(scopes)
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to obtain service token")
|
||||
const expiresAt = Date.now() + jwt.expires_in * 1000
|
||||
return { expiresAt, jwt }
|
||||
},
|
||||
scopes,
|
||||
{ tags: [tag] }
|
||||
)
|
||||
|
||||
const cachedJwt = await getCachedJwt(scopes)
|
||||
if (cachedJwt.expiresAt < Date.now()) {
|
||||
revalidateTag(tag)
|
||||
const newToken = await getServiceToken(scopes)
|
||||
return newToken
|
||||
}
|
||||
|
||||
return response.json()
|
||||
return cachedJwt.jwt
|
||||
} catch (error) {
|
||||
console.error("Error fetching service token:", error)
|
||||
throw error
|
||||
|
||||
Reference in New Issue
Block a user