Files
web/server/tokenManager.ts
2024-10-10 10:46:31 +02:00

61 lines
1.6 KiB
TypeScript

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"
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: ServiceTokenScope[]
): Promise<ServiceTokenResponse> {
try {
const tag = generateServiceTokenTag(scopes)
const getCachedJwt = unstable_cache(
async (scopes) => {
const jwt = await getServiceToken(scopes)
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 cachedJwt.jwt
} catch (error) {
console.error("Error fetching service token:", error)
throw error
}
}