using Microsoft.AspNetCore.Components; using Microsoft.EntityFrameworkCore; using SpotifyAPI.Web; using SpotiParty.Web.Models; namespace SpotiParty.Web.Services; public sealed class AuthorizationHandler(NavigationManager navigator, DatabaseContext context, ClientSideStorage storage, IConfiguration configuration) { private async Task<(string clientId, string clientSecret)> GetClientSecrets() { #if DEBUG var fileLines = await File.ReadAllLinesAsync(Path.Combine(Environment.CurrentDirectory, ".dev-token")); return (fileLines[0], fileLines[1]); #endif #pragma warning disable CS0162 // Unreachable code detected return (configuration["ClientId"]!, configuration["ClientSecret"]!); #pragma warning restore CS0162 // Unreachable code detected } public async Task ConfigureClient(Guid userId) { var user = await context.Users.FindAsync(userId); if (user is null) return null; var (clientId, clientSecret) = await GetClientSecrets(); var request = new AuthorizationCodeRefreshRequest(clientId, clientSecret, user.RefreshToken); var response = await new OAuthClient().RequestToken(request); return new SpotifyClient(response.AccessToken); } public async Task ConstructLoginUri() { var (clientId, _) = await GetClientSecrets(); var request = new LoginRequest( new Uri(navigator.BaseUri + "callback"), clientId, LoginRequest.ResponseType.Code) { Scope = [Scopes.UserReadPlaybackState, Scopes.UserModifyPlaybackState, Scopes.UserReadPrivate, Scopes.UserReadEmail] }; return request.ToUri(); } public async Task HandleCallback(string code) { var (clientId, clientSecret) = await GetClientSecrets(); var response = await new OAuthClient().RequestToken( new AuthorizationCodeTokenRequest( clientId, clientSecret, code, new Uri(navigator.BaseUri + "callback"))); var client = new SpotifyClient(response.AccessToken); var spotiUser = await client.UserProfile.Current(); var user = await context.Users.FirstOrDefaultAsync(u => u.SpotifyUserId == spotiUser.Id); if (user is null) { user = new User { DisplayName = spotiUser.DisplayName, RefreshToken = response.RefreshToken, SpotifyUserId = spotiUser.Id, IsAdmin = await context.Users.CountAsync() == 0 }; await context.Users.AddAsync(user); await context.SaveChangesAsync(); } else { user.RefreshToken = response.RefreshToken; await context.SaveChangesAsync(); } storage.SaveUserToken(response.RefreshToken); } }