import { and, eq } from "drizzle-orm"; import Elysia from "elysia"; import { auth, betterAuthElysia } from "../auth"; import { db } from "../db"; import { account } from "../db/schema"; const SPOTIFY_PLAYBACK_SCOPES = ["streaming", "user-read-private"]; function parseScopes(scope: string | null | undefined) { return new Set(scope?.split(/[\s,]+/).filter(Boolean) ?? []); } export const spotifyRoutes = new Elysia() .use(betterAuthElysia) .group("/spotify", (app) => app.get( "/token", async ({ user, set }) => { const [spotifyAccount] = await db .select({ scope: account.scope }) .from(account) .where( and(eq(account.userId, user.id), eq(account.providerId, "spotify")), ) .limit(1); const grantedScopes = parseScopes(spotifyAccount?.scope); const missingScopes = SPOTIFY_PLAYBACK_SCOPES.filter( (scope) => !grantedScopes.has(scope), ); if (missingScopes.length > 0) { set.status = 403; return { error: "Spotify playback permission required", code: "SPOTIFY_RELINK_REQUIRED", missingScopes, }; } const token = await auth.api.getAccessToken({ body: { userId: user.id, providerId: "spotify", }, }); if (!token?.accessToken) { set.status = 404; return { error: "Spotify access token not found" }; } return { accessToken: token.accessToken, expiresAt: token.accessTokenExpiresAt ? Number(token.accessTokenExpiresAt) : null, }; }, { auth: true }, ), );