spotify controls
This commit is contained in:
74
src/lib/spotify/auth.ts
Normal file
74
src/lib/spotify/auth.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
import type { PKCEState, SpotifyTokenResponse } from './types';
|
||||
|
||||
const SPOTIFY_AUTH_BASE = 'https://accounts.spotify.com';
|
||||
const SPOTIFY_SCOPES = [
|
||||
'user-read-playback-state',
|
||||
'user-modify-playback-state',
|
||||
'user-read-currently-playing',
|
||||
'streaming',
|
||||
].join(' ');
|
||||
|
||||
function generateRandomString(length: number): string {
|
||||
const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
const values = crypto.getRandomValues(new Uint8Array(length));
|
||||
return values.reduce((acc, x) => acc + possible[x % possible.length], '');
|
||||
}
|
||||
|
||||
export class SpotifyAuth {
|
||||
private clientId: string;
|
||||
private redirectUri: string;
|
||||
|
||||
constructor(clientId: string, redirectUri: string) {
|
||||
this.clientId = clientId;
|
||||
this.redirectUri = redirectUri;
|
||||
}
|
||||
|
||||
async startAuthFlow(returnPath: string = window.location.pathname): Promise<void> {
|
||||
const randomState = generateRandomString(16);
|
||||
|
||||
const stateWithPath = btoa(JSON.stringify({
|
||||
state: randomState,
|
||||
returnPath: returnPath
|
||||
}));
|
||||
|
||||
sessionStorage.setItem('spotify_state', randomState);
|
||||
|
||||
const params = new URLSearchParams({
|
||||
response_type: 'code',
|
||||
client_id: this.clientId,
|
||||
scope: SPOTIFY_SCOPES,
|
||||
redirect_uri: this.redirectUri,
|
||||
state: stateWithPath,
|
||||
});
|
||||
|
||||
const authUrl = `${SPOTIFY_AUTH_BASE}/authorize?${params.toString()}`;
|
||||
window.location.href = authUrl;
|
||||
}
|
||||
|
||||
async refreshAccessToken(refreshToken: string): Promise<SpotifyTokenResponse> {
|
||||
const response = await fetch('/api/spotify/token', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
refresh_token: refreshToken,
|
||||
}),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.json();
|
||||
throw new Error(`Token refresh failed: ${error.error || 'Unknown error'}`);
|
||||
}
|
||||
|
||||
return response.json();
|
||||
}
|
||||
|
||||
getReturnPath(): string {
|
||||
return '/';
|
||||
}
|
||||
|
||||
clearStoredData(): void {
|
||||
sessionStorage.removeItem('spotify_state');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user