mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Use real backend
This commit is contained in:
parent
428bbd73e3
commit
1c07bef3cf
@ -5,6 +5,7 @@ using System.Reactive.Disposables;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Artemis.UI.Shared;
|
using Artemis.UI.Shared;
|
||||||
|
using Artemis.WebClient.Workshop;
|
||||||
using Artemis.WebClient.Workshop.Services;
|
using Artemis.WebClient.Workshop.Services;
|
||||||
using Avalonia.Media.Imaging;
|
using Avalonia.Media.Imaging;
|
||||||
using Flurl.Http;
|
using Flurl.Http;
|
||||||
@ -94,7 +95,7 @@ public class CurrentUserViewModel : ActivatableViewModelBase
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Avatar = new Bitmap(await $"{IAuthenticationService.AUTHORITY}/user/avatar/{userId}".GetStreamAsync());
|
Avatar = new Bitmap(await $"{WorkshopConstants.AUTHORITY_URL}/user/avatar/{userId}".GetStreamAsync());
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
"strawberryShake": {
|
"strawberryShake": {
|
||||||
"name": "WorkshopClient",
|
"name": "WorkshopClient",
|
||||||
"namespace": "Artemis.WebClient.Workshop",
|
"namespace": "Artemis.WebClient.Workshop",
|
||||||
"url": "https://localhost:7281/graphql/",
|
"url": "https://workshop.artemis-rgb.com/graphql/",
|
||||||
"emitGeneratedCode": false,
|
"emitGeneratedCode": false,
|
||||||
"records": {
|
"records": {
|
||||||
"inputs": false,
|
"inputs": false,
|
||||||
|
|||||||
@ -13,6 +13,7 @@
|
|||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Http" Version="7.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Http" Version="7.0.0" />
|
||||||
<PackageReference Include="StrawberryShake.Server" Version="13.0.5" />
|
<PackageReference Include="StrawberryShake.Server" Version="13.0.5" />
|
||||||
|
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.31.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@ -22,12 +22,12 @@ public static class ContainerExtensions
|
|||||||
serviceCollection
|
serviceCollection
|
||||||
.AddHttpClient()
|
.AddHttpClient()
|
||||||
.AddWorkshopClient()
|
.AddWorkshopClient()
|
||||||
.ConfigureHttpClient(client => client.BaseAddress = new Uri("https://localhost:7281/graphql"));
|
.ConfigureHttpClient(client => client.BaseAddress = new Uri(WorkshopConstants.WORKSHOP_URL + "/graphql"));
|
||||||
|
|
||||||
serviceCollection.AddSingleton<IDiscoveryCache>(r =>
|
serviceCollection.AddSingleton<IDiscoveryCache>(r =>
|
||||||
{
|
{
|
||||||
IHttpClientFactory factory = r.GetRequiredService<IHttpClientFactory>();
|
IHttpClientFactory factory = r.GetRequiredService<IHttpClientFactory>();
|
||||||
return new DiscoveryCache(IAuthenticationService.AUTHORITY, () => factory.CreateClient());
|
return new DiscoveryCache(WorkshopConstants.AUTHORITY_URL, () => factory.CreateClient());
|
||||||
});
|
});
|
||||||
|
|
||||||
container.WithDependencyInjectionAdapter(serviceCollection);
|
container.WithDependencyInjectionAdapter(serviceCollection);
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.IdentityModel.Tokens.Jwt;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
using Artemis.Core.Services;
|
using Artemis.Core.Services;
|
||||||
@ -11,8 +12,6 @@ namespace Artemis.WebClient.Workshop.Services;
|
|||||||
|
|
||||||
public interface IAuthenticationService : IProtectedArtemisService
|
public interface IAuthenticationService : IProtectedArtemisService
|
||||||
{
|
{
|
||||||
public const string AUTHORITY = "https://localhost:5001";
|
|
||||||
|
|
||||||
bool IsLoggedIn { get; }
|
bool IsLoggedIn { get; }
|
||||||
string? UserCode { get; }
|
string? UserCode { get; }
|
||||||
ReadOnlyObservableCollection<Claim> Claims { get; }
|
ReadOnlyObservableCollection<Claim> Claims { get; }
|
||||||
@ -25,7 +24,7 @@ public interface IAuthenticationService : IProtectedArtemisService
|
|||||||
|
|
||||||
internal class AuthenticationService : CorePropertyChanged, IAuthenticationService
|
internal class AuthenticationService : CorePropertyChanged, IAuthenticationService
|
||||||
{
|
{
|
||||||
internal const string CLIENT_ID = "artemis.desktop";
|
private const string CLIENT_ID = "artemis.desktop";
|
||||||
|
|
||||||
private readonly IDiscoveryCache _discoveryCache;
|
private readonly IDiscoveryCache _discoveryCache;
|
||||||
private readonly IAuthenticationRepository _authenticationRepository;
|
private readonly IAuthenticationRepository _authenticationRepository;
|
||||||
@ -109,7 +108,8 @@ internal class AuthenticationService : CorePropertyChanged, IAuthenticationServi
|
|||||||
DeviceAuthorizationResponse response = await client.RequestDeviceAuthorizationAsync(new DeviceAuthorizationRequest
|
DeviceAuthorizationResponse response = await client.RequestDeviceAuthorizationAsync(new DeviceAuthorizationRequest
|
||||||
{
|
{
|
||||||
Address = disco.DeviceAuthorizationEndpoint,
|
Address = disco.DeviceAuthorizationEndpoint,
|
||||||
ClientId = CLIENT_ID
|
ClientId = CLIENT_ID,
|
||||||
|
Scope = "openid profile email offline_access api"
|
||||||
});
|
});
|
||||||
if (response.IsError)
|
if (response.IsError)
|
||||||
throw new ArtemisWebClientException("Failed to request device authorization: " + response.Error);
|
throw new ArtemisWebClientException("Failed to request device authorization: " + response.Error);
|
||||||
@ -168,33 +168,25 @@ internal class AuthenticationService : CorePropertyChanged, IAuthenticationServi
|
|||||||
throw new ArtemisWebClientException("Failed to request device token: " + response.Error);
|
throw new ArtemisWebClientException("Failed to request device token: " + response.Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
await SetCurrentUser(client, response);
|
SetCurrentUser(response);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task SetCurrentUser(HttpClient client, TokenResponse response)
|
private void SetCurrentUser(TokenResponse response)
|
||||||
{
|
{
|
||||||
_token = new AuthenticationToken(response);
|
_token = new AuthenticationToken(response);
|
||||||
_authenticationRepository.SetRefreshToken(_token.RefreshToken);
|
_authenticationRepository.SetRefreshToken(_token.RefreshToken);
|
||||||
|
|
||||||
await GetUserInfo(client, _token.AccessToken);
|
JwtSecurityTokenHandler handler = new();
|
||||||
IsLoggedIn = true;
|
JwtSecurityToken? token = handler.ReadJwtToken(response.IdentityToken);
|
||||||
}
|
if (token == null)
|
||||||
|
throw new ArtemisWebClientException("Failed to read JWT token");
|
||||||
private async Task GetUserInfo(HttpClient client, string accessToken)
|
|
||||||
{
|
|
||||||
DiscoveryDocumentResponse disco = await GetDiscovery();
|
|
||||||
UserInfoResponse response = await client.GetUserInfoAsync(new UserInfoRequest()
|
|
||||||
{
|
|
||||||
Address = disco.UserInfoEndpoint,
|
|
||||||
Token = accessToken
|
|
||||||
});
|
|
||||||
if (response.IsError)
|
|
||||||
throw new ArtemisWebClientException("Failed to retrieve user info: " + response.Error);
|
|
||||||
|
|
||||||
_claims.Clear();
|
_claims.Clear();
|
||||||
foreach (Claim responseClaim in response.Claims)
|
foreach (Claim responseClaim in token.Claims)
|
||||||
_claims.Add(responseClaim);
|
_claims.Add(responseClaim);
|
||||||
|
|
||||||
|
IsLoggedIn = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<bool> UseRefreshToken(string refreshToken)
|
private async Task<bool> UseRefreshToken(string refreshToken)
|
||||||
@ -216,7 +208,7 @@ internal class AuthenticationService : CorePropertyChanged, IAuthenticationServi
|
|||||||
throw new ArtemisWebClientException("Failed to request refresh token: " + response.Error);
|
throw new ArtemisWebClientException("Failed to request refresh token: " + response.Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
await SetCurrentUser(client, response);
|
SetCurrentUser(response);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
7
src/Artemis.WebClient.Workshop/WorkshopConstants.cs
Normal file
7
src/Artemis.WebClient.Workshop/WorkshopConstants.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
namespace Artemis.WebClient.Workshop;
|
||||||
|
|
||||||
|
public static class WorkshopConstants
|
||||||
|
{
|
||||||
|
public const string AUTHORITY_URL = "https://identity.artemis-rgb.com";
|
||||||
|
public const string WORKSHOP_URL = "https://workshop.artemis-rgb.com";
|
||||||
|
}
|
||||||
@ -2,7 +2,7 @@ schema: schema.graphql
|
|||||||
extensions:
|
extensions:
|
||||||
endpoints:
|
endpoints:
|
||||||
Default GraphQL Endpoint:
|
Default GraphQL Endpoint:
|
||||||
url: https://localhost:7281/graphql
|
url: https://workshop.artemis-rgb.com/graphql
|
||||||
headers:
|
headers:
|
||||||
user-agent: JS GraphQL
|
user-agent: JS GraphQL
|
||||||
introspect: true
|
introspect: true
|
||||||
|
|||||||
@ -32,7 +32,8 @@ type EntriesEdge {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Entry {
|
type Entry {
|
||||||
author: UUID!
|
author: String!
|
||||||
|
authorId: UUID!
|
||||||
categories: [Category!]!
|
categories: [Category!]!
|
||||||
createdAt: DateTime!
|
createdAt: DateTime!
|
||||||
description: String!
|
description: String!
|
||||||
@ -83,6 +84,7 @@ type Query {
|
|||||||
where: EntryFilterInput
|
where: EntryFilterInput
|
||||||
): EntriesConnection
|
): EntriesConnection
|
||||||
entry(id: UUID!): Entry
|
entry(id: UUID!): Entry
|
||||||
|
searchEntries(input: String!, order: [EntrySortInput!], type: EntryType, where: EntryFilterInput): [Entry!]!
|
||||||
}
|
}
|
||||||
|
|
||||||
type Release {
|
type Release {
|
||||||
@ -90,6 +92,7 @@ type Release {
|
|||||||
downloadSize: Long!
|
downloadSize: Long!
|
||||||
downloads: Long!
|
downloads: Long!
|
||||||
entry: Entry!
|
entry: Entry!
|
||||||
|
entryId: UUID!
|
||||||
id: UUID!
|
id: UUID!
|
||||||
md5Hash: String
|
md5Hash: String
|
||||||
version: String!
|
version: String!
|
||||||
@ -100,6 +103,12 @@ type Tag {
|
|||||||
name: String!
|
name: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum ApplyPolicy {
|
||||||
|
AFTER_RESOLVER
|
||||||
|
BEFORE_RESOLVER
|
||||||
|
VALIDATION
|
||||||
|
}
|
||||||
|
|
||||||
enum EntryType {
|
enum EntryType {
|
||||||
LAYOUT
|
LAYOUT
|
||||||
PLUGIN
|
PLUGIN
|
||||||
@ -150,7 +159,8 @@ input DateTimeOperationFilterInput {
|
|||||||
|
|
||||||
input EntryFilterInput {
|
input EntryFilterInput {
|
||||||
and: [EntryFilterInput!]
|
and: [EntryFilterInput!]
|
||||||
author: UuidOperationFilterInput
|
author: StringOperationFilterInput
|
||||||
|
authorId: UuidOperationFilterInput
|
||||||
categories: ListFilterInputTypeOfCategoryFilterInput
|
categories: ListFilterInputTypeOfCategoryFilterInput
|
||||||
createdAt: DateTimeOperationFilterInput
|
createdAt: DateTimeOperationFilterInput
|
||||||
description: StringOperationFilterInput
|
description: StringOperationFilterInput
|
||||||
@ -175,6 +185,7 @@ input EntryInput {
|
|||||||
|
|
||||||
input EntrySortInput {
|
input EntrySortInput {
|
||||||
author: SortEnumType
|
author: SortEnumType
|
||||||
|
authorId: SortEnumType
|
||||||
createdAt: SortEnumType
|
createdAt: SortEnumType
|
||||||
description: SortEnumType
|
description: SortEnumType
|
||||||
downloads: SortEnumType
|
downloads: SortEnumType
|
||||||
@ -268,6 +279,7 @@ input ReleaseFilterInput {
|
|||||||
downloadSize: LongOperationFilterInput
|
downloadSize: LongOperationFilterInput
|
||||||
downloads: LongOperationFilterInput
|
downloads: LongOperationFilterInput
|
||||||
entry: EntryFilterInput
|
entry: EntryFilterInput
|
||||||
|
entryId: UuidOperationFilterInput
|
||||||
id: UuidOperationFilterInput
|
id: UuidOperationFilterInput
|
||||||
md5Hash: StringOperationFilterInput
|
md5Hash: StringOperationFilterInput
|
||||||
or: [ReleaseFilterInput!]
|
or: [ReleaseFilterInput!]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user