🐛 Fixes bugs

This commit is contained in:
LittleSheep 2025-06-16 01:43:54 +08:00
parent c806c5d139
commit b27b6b8c1b
3 changed files with 79 additions and 9 deletions

View File

@ -4,12 +4,16 @@ using System.Text.Json.Serialization;
namespace DysonNetwork.Sphere.Auth.OpenId; namespace DysonNetwork.Sphere.Auth.OpenId;
public class AppleMobileSignInRequest public class AppleMobileConnectRequest
{ {
[Required] [Required]
public required string IdentityToken { get; set; } public required string IdentityToken { get; set; }
[Required] [Required]
public required string AuthorizationCode { get; set; } public required string AuthorizationCode { get; set; }
}
public class AppleMobileSignInRequest : AppleMobileConnectRequest
{
[Required] [Required]
public required string DeviceId { get; set; } public required string DeviceId { get; set; }
} }

View File

@ -2,12 +2,13 @@ using DysonNetwork.Sphere.Account;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using DysonNetwork.Sphere.Auth.OpenId;
using NodaTime; using NodaTime;
namespace DysonNetwork.Sphere.Auth.OpenId; namespace DysonNetwork.Sphere.Auth.OpenId;
[ApiController] [ApiController]
[Route("/api/accounts/me/connections")] [Route("/accounts/me/connections")]
[Authorize] [Authorize]
public class ConnectionController( public class ConnectionController(
AppDatabase db, AppDatabase db,
@ -24,7 +25,17 @@ public class ConnectionController(
var connections = await db.AccountConnections var connections = await db.AccountConnections
.Where(c => c.AccountId == currentUser.Id) .Where(c => c.AccountId == currentUser.Id)
.Select(c => new { c.Id, c.AccountId, c.Provider, c.ProvidedIdentifier, c.Meta, c.LastUsedAt }) .Select(c => new
{
c.Id,
c.AccountId,
c.Provider,
c.ProvidedIdentifier,
c.Meta,
c.LastUsedAt,
c.CreatedAt,
c.UpdatedAt,
})
.ToListAsync(); .ToListAsync();
return Ok(connections); return Ok(connections);
} }
@ -47,6 +58,63 @@ public class ConnectionController(
return Ok(); return Ok();
} }
[HttpPost("/auth/connect/apple/mobile")]
public async Task<ActionResult> ConnectAppleMobile([FromBody] AppleMobileConnectRequest request)
{
if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser)
return Unauthorized();
if (GetOidcService("apple") is not AppleOidcService appleService)
return StatusCode(503, "Apple OIDC service not available");
var callbackData = new OidcCallbackData
{
IdToken = request.IdentityToken,
Code = request.AuthorizationCode,
};
OidcUserInfo userInfo;
try
{
userInfo = await appleService.ProcessCallbackAsync(callbackData);
}
catch (Exception ex)
{
return BadRequest($"Error processing Apple token: {ex.Message}");
}
var existingConnection = await db.AccountConnections
.FirstOrDefaultAsync(c =>
c.Provider == "apple" &&
c.ProvidedIdentifier == userInfo.UserId);
if (existingConnection != null)
{
return BadRequest(
$"This Apple account is already linked to {(existingConnection.AccountId == currentUser.Id ? "your account" : "another user")}.");
}
db.AccountConnections.Add(new AccountConnection
{
AccountId = currentUser.Id,
Provider = "apple",
ProvidedIdentifier = userInfo.UserId!,
AccessToken = userInfo.AccessToken,
RefreshToken = userInfo.RefreshToken,
LastUsedAt = SystemClock.Instance.GetCurrentInstant(),
Meta = userInfo.ToMetadata(),
});
await db.SaveChangesAsync();
return Ok(new { message = "Successfully connected Apple account." });
}
private OidcService? GetOidcService(string provider)
{
return oidcServices.FirstOrDefault(s => s.ProviderName.Equals(provider, StringComparison.OrdinalIgnoreCase));
}
public class ConnectProviderRequest public class ConnectProviderRequest
{ {
public string Provider { get; set; } = null!; public string Provider { get; set; } = null!;
@ -62,8 +130,7 @@ public class ConnectionController(
if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser) if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser)
return Unauthorized(); return Unauthorized();
var oidcService = oidcServices.FirstOrDefault(s => var oidcService = GetOidcService(request.Provider);
s.ProviderName.Equals(request.Provider, StringComparison.OrdinalIgnoreCase));
if (oidcService == null) if (oidcService == null)
return BadRequest($"Provider '{request.Provider}' is not supported"); return BadRequest($"Provider '{request.Provider}' is not supported");
@ -94,8 +161,7 @@ public class ConnectionController(
[HttpGet, HttpPost] [HttpGet, HttpPost]
public async Task<IActionResult> HandleCallback([FromRoute] string provider) public async Task<IActionResult> HandleCallback([FromRoute] string provider)
{ {
var oidcService = var oidcService = GetOidcService(provider);
oidcServices.FirstOrDefault(s => s.ProviderName.Equals(provider, StringComparison.OrdinalIgnoreCase));
if (oidcService == null) if (oidcService == null)
return BadRequest($"Provider '{provider}' is not supported."); return BadRequest($"Provider '{provider}' is not supported.");

View File

@ -86,8 +86,8 @@
}, },
"Oidc": { "Oidc": {
"Google": { "Google": {
"ClientId": "YOUR_GOOGLE_CLIENT_ID", "ClientId": "961776991058-963m1qin2vtp8fv693b5fdrab5hmpl89.apps.googleusercontent.com",
"ClientSecret": "YOUR_GOOGLE_CLIENT_SECRET" "ClientSecret": ""
}, },
"Apple": { "Apple": {
"ClientId": "dev.solsynth.solian", "ClientId": "dev.solsynth.solian",