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 { 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 } }