attempted upgrade

This commit is contained in:
yohlo
2025-09-24 00:13:41 -05:00
parent 94ea44c66e
commit e4164cbc71
26 changed files with 1390 additions and 1273 deletions

View File

@@ -1,127 +1,131 @@
import { createServerFileRoute } from '@tanstack/react-start/server'
import { createFileRoute } from "@tanstack/react-router";
const SPOTIFY_CLIENT_ID = import.meta.env.VITE_SPOTIFY_CLIENT_ID!
const SPOTIFY_CLIENT_SECRET = process.env.SPOTIFY_CLIENT_SECRET!
const SPOTIFY_CLIENT_ID = import.meta.env.VITE_SPOTIFY_CLIENT_ID!;
const SPOTIFY_CLIENT_SECRET = import.meta.env.SPOTIFY_CLIENT_SECRET!;
export const ServerRoute = createServerFileRoute('/api/spotify/token').methods({
POST: async ({ request }: { request: Request }) => {
try {
const body = await request.json()
const { refresh_token } = body
export const Route = createFileRoute("/api/spotify/token")({
server: {
handlers: {
POST: async ({ request }: { request: Request }) => {
try {
const body = await request.json();
const { refresh_token } = body;
if (!refresh_token) {
return new Response(
JSON.stringify({ error: 'refresh_token is required' }),
{
status: 400,
headers: { 'Content-Type': 'application/json' },
if (!refresh_token) {
return new Response(
JSON.stringify({ error: "refresh_token is required" }),
{
status: 400,
headers: { "Content-Type": "application/json" },
}
);
}
)
}
// Refresh access token
const tokenResponse = await fetch('https://accounts.spotify.com/api/token', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': `Basic ${Buffer.from(`${SPOTIFY_CLIENT_ID}:${SPOTIFY_CLIENT_SECRET}`).toString('base64')}`,
},
body: new URLSearchParams({
grant_type: 'refresh_token',
refresh_token,
}),
})
const tokenResponse = await fetch(
"https://accounts.spotify.com/api/token",
{
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
Authorization: `Basic ${Buffer.from(`${SPOTIFY_CLIENT_ID}:${SPOTIFY_CLIENT_SECRET}`).toString("base64")}`,
},
body: new URLSearchParams({
grant_type: "refresh_token",
refresh_token,
}),
}
);
if (!tokenResponse.ok) {
const error = await tokenResponse.json()
console.error('Token refresh error:', error)
return new Response(
JSON.stringify({ error: 'Failed to refresh token', details: error }),
{
status: tokenResponse.status,
headers: { 'Content-Type': 'application/json' },
if (!tokenResponse.ok) {
const error = await tokenResponse.json();
console.error("Token refresh error:", error);
return new Response(
JSON.stringify({
error: "Failed to refresh token",
details: error,
}),
{
status: tokenResponse.status,
headers: { "Content-Type": "application/json" },
}
);
}
)
}
const tokens = await tokenResponse.json()
const tokens = await tokenResponse.json();
// Return new tokens
return new Response(
JSON.stringify({
access_token: tokens.access_token,
expires_in: tokens.expires_in,
scope: tokens.scope,
token_type: tokens.token_type,
}),
{
status: 200,
headers: { 'Content-Type': 'application/json' },
return new Response(
JSON.stringify({
access_token: tokens.access_token,
expires_in: tokens.expires_in,
scope: tokens.scope,
token_type: tokens.token_type,
}),
{
status: 200,
headers: { "Content-Type": "application/json" },
}
);
} catch (error) {
console.error("Token refresh endpoint error:", error);
return new Response(
JSON.stringify({ error: "Internal server error" }),
{
status: 500,
headers: { "Content-Type": "application/json" },
}
);
}
)
} catch (error) {
console.error('Token refresh endpoint error:', error)
return new Response(
JSON.stringify({ error: 'Internal server error' }),
{
status: 500,
headers: { 'Content-Type': 'application/json' },
},
GET: async ({ request }: { request: Request }) => {
try {
const cookieHeader = request.headers.get("cookie");
if (!cookieHeader) {
return new Response(JSON.stringify({ error: "No cookies found" }), {
status: 401,
headers: { "Content-Type": "application/json" },
});
}
const cookies = Object.fromEntries(
cookieHeader.split("; ").map((c: string) => c.split("="))
);
const accessToken = cookies.spotify_access_token;
const refreshToken = cookies.spotify_refresh_token;
if (!accessToken && !refreshToken) {
return new Response(
JSON.stringify({ error: "No Spotify tokens found" }),
{
status: 401,
headers: { "Content-Type": "application/json" },
}
);
}
return new Response(
JSON.stringify({
access_token: accessToken || null,
refresh_token: refreshToken || null,
has_tokens: !!(accessToken || refreshToken),
}),
{
status: 200,
headers: { "Content-Type": "application/json" },
}
);
} catch (error) {
console.error("Get tokens endpoint error:", error);
return new Response(
JSON.stringify({ error: "Internal server error" }),
{
status: 500,
headers: { "Content-Type": "application/json" },
}
);
}
)
}
},
},
},
// GET endpoint to retrieve current tokens from cookies
GET: async ({ request }: { request: Request }) => {
try {
const cookieHeader = request.headers.get('cookie')
if (!cookieHeader) {
return new Response(
JSON.stringify({ error: 'No cookies found' }),
{
status: 401,
headers: { 'Content-Type': 'application/json' },
}
)
}
const cookies = Object.fromEntries(
cookieHeader.split('; ').map((c: string) => c.split('='))
)
const accessToken = cookies.spotify_access_token
const refreshToken = cookies.spotify_refresh_token
if (!accessToken && !refreshToken) {
return new Response(
JSON.stringify({ error: 'No Spotify tokens found' }),
{
status: 401,
headers: { 'Content-Type': 'application/json' },
}
)
}
return new Response(
JSON.stringify({
access_token: accessToken || null,
refresh_token: refreshToken || null,
has_tokens: !!(accessToken || refreshToken),
}),
{
status: 200,
headers: { 'Content-Type': 'application/json' },
}
)
} catch (error) {
console.error('Get tokens endpoint error:', error)
return new Response(
JSON.stringify({ error: 'Internal server error' }),
{
status: 500,
headers: { 'Content-Type': 'application/json' },
}
)
}
},
})
});