♻️ Refactored the authorized device (now client)
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using DysonNetwork.Pass.Auth;
|
||||
using DysonNetwork.Pass.Permission;
|
||||
using DysonNetwork.Pass.Wallet;
|
||||
using DysonNetwork.Shared.Data;
|
||||
@@ -9,7 +10,6 @@ using Microsoft.EntityFrameworkCore;
|
||||
using NodaTime;
|
||||
using AuthService = DysonNetwork.Pass.Auth.AuthService;
|
||||
using AuthSession = DysonNetwork.Pass.Auth.AuthSession;
|
||||
using ChallengePlatform = DysonNetwork.Pass.Auth.ChallengePlatform;
|
||||
|
||||
namespace DysonNetwork.Pass.Account;
|
||||
|
||||
@@ -437,25 +437,16 @@ public class AccountCurrentController(
|
||||
}
|
||||
}
|
||||
|
||||
public class AuthorizedDevice
|
||||
{
|
||||
public string? Label { get; set; }
|
||||
public string UserAgent { get; set; } = null!;
|
||||
public string DeviceId { get; set; } = null!;
|
||||
public ChallengePlatform Platform { get; set; }
|
||||
public List<AuthSession> Sessions { get; set; } = [];
|
||||
}
|
||||
|
||||
[HttpGet("devices")]
|
||||
[Authorize]
|
||||
public async Task<ActionResult<List<AuthorizedDevice>>> GetDevices()
|
||||
public async Task<ActionResult<List<AuthClient>>> GetDevices()
|
||||
{
|
||||
if (HttpContext.Items["CurrentUser"] is not Account currentUser ||
|
||||
HttpContext.Items["CurrentSession"] is not AuthSession currentSession) return Unauthorized();
|
||||
|
||||
Response.Headers.Append("X-Auth-Session", currentSession.Id.ToString());
|
||||
|
||||
var devices = await db.AuthDevices
|
||||
var devices = await db.AuthClients
|
||||
.Where(device => device.AccountId == currentUser.Id)
|
||||
.ToListAsync();
|
||||
|
||||
@@ -525,14 +516,14 @@ public class AccountCurrentController(
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPatch("sessions/{id:guid}/label")]
|
||||
public async Task<ActionResult<AuthSession>> UpdateSessionLabel(Guid id, [FromBody] string label)
|
||||
[HttpPatch("devices/{id}/label")]
|
||||
public async Task<ActionResult<AuthSession>> UpdateDeviceLabel(string id, [FromBody] string label)
|
||||
{
|
||||
if (HttpContext.Items["CurrentUser"] is not Account currentUser) return Unauthorized();
|
||||
|
||||
try
|
||||
{
|
||||
await accounts.UpdateSessionLabel(currentUser, id, label);
|
||||
await accounts.UpdateDeviceName(currentUser, id, label);
|
||||
return NoContent();
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -541,15 +532,18 @@ public class AccountCurrentController(
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPatch("sessions/current/label")]
|
||||
public async Task<ActionResult<AuthSession>> UpdateCurrentSessionLabel([FromBody] string label)
|
||||
[HttpPatch("devices/current/label")]
|
||||
public async Task<ActionResult<AuthSession>> UpdateCurrentDeviceLabel([FromBody] string label)
|
||||
{
|
||||
if (HttpContext.Items["CurrentUser"] is not Account currentUser ||
|
||||
HttpContext.Items["CurrentSession"] is not AuthSession currentSession) return Unauthorized();
|
||||
|
||||
var device = await db.AuthClients.FirstOrDefaultAsync(d => d.Id == currentSession.Challenge.ClientId);
|
||||
if (device is null) return NotFound();
|
||||
|
||||
try
|
||||
{
|
||||
await accounts.UpdateSessionLabel(currentUser, currentSession.Id, label);
|
||||
await accounts.UpdateDeviceName(currentUser, device.DeviceId, label);
|
||||
return NoContent();
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -637,7 +631,7 @@ public class AccountCurrentController(
|
||||
return BadRequest(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[HttpPost("contacts/{id:guid}/public")]
|
||||
[Authorize]
|
||||
public async Task<ActionResult<AccountContact>> SetPublicContact(Guid id)
|
||||
@@ -659,7 +653,7 @@ public class AccountCurrentController(
|
||||
return BadRequest(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[HttpDelete("contacts/{id:guid}/public")]
|
||||
[Authorize]
|
||||
public async Task<ActionResult<AccountContact>> UnsetPublicContact(Guid id)
|
||||
@@ -733,4 +727,4 @@ public class AccountCurrentController(
|
||||
return BadRequest(ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -11,7 +11,6 @@ using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using NodaTime;
|
||||
using OtpNet;
|
||||
using AuthSession = DysonNetwork.Pass.Auth.AuthSession;
|
||||
|
||||
namespace DysonNetwork.Pass.Account;
|
||||
|
||||
@@ -458,37 +457,28 @@ public class AccountService(
|
||||
|
||||
public async Task<bool> IsDeviceActive(Guid id)
|
||||
{
|
||||
return await db.AuthChallenges.AnyAsync(d => d.DeviceId == id);
|
||||
return await db.AuthSessions
|
||||
.Include(s => s.Challenge)
|
||||
.AnyAsync(s => s.Challenge.ClientId == id);
|
||||
}
|
||||
|
||||
public async Task<AuthSession> UpdateSessionLabel(Account account, Guid sessionId, string label)
|
||||
public async Task<AuthClient> UpdateDeviceName(Account account, string deviceId, string label)
|
||||
{
|
||||
var session = await db.AuthSessions
|
||||
.Include(s => s.Challenge)
|
||||
.Where(s => s.Id == sessionId && s.AccountId == account.Id)
|
||||
.FirstOrDefaultAsync();
|
||||
if (session is null) throw new InvalidOperationException("Session was not found.");
|
||||
var device = await db.AuthClients.FirstOrDefaultAsync(d => d.DeviceId == deviceId && d.AccountId == account.Id);
|
||||
if (device is null) throw new InvalidOperationException("Device was not found.");
|
||||
|
||||
await db.AuthSessions
|
||||
.Include(s => s.Challenge)
|
||||
.Where(s => s.Challenge.DeviceId == session.Challenge.DeviceId)
|
||||
.ExecuteUpdateAsync(p => p.SetProperty(s => s.Label, label));
|
||||
device.DeviceLabel = label;
|
||||
db.Update(device);
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
var sessions = await db.AuthSessions
|
||||
.Include(s => s.Challenge)
|
||||
.Where(s => s.AccountId == session.Id && s.Challenge.DeviceId == session.Challenge.DeviceId)
|
||||
.ToListAsync();
|
||||
foreach (var item in sessions)
|
||||
await cache.RemoveAsync($"{DysonTokenAuthHandler.AuthCachePrefix}{item.Id}");
|
||||
|
||||
return session;
|
||||
return device;
|
||||
}
|
||||
|
||||
public async Task DeleteSession(Account account, Guid sessionId)
|
||||
{
|
||||
var session = await db.AuthSessions
|
||||
.Include(s => s.Challenge)
|
||||
.ThenInclude(s => s.Device)
|
||||
.ThenInclude(s => s.Client)
|
||||
.Where(s => s.Id == sessionId && s.AccountId == account.Id)
|
||||
.FirstOrDefaultAsync();
|
||||
if (session is null) throw new InvalidOperationException("Session was not found.");
|
||||
@@ -498,10 +488,13 @@ public class AccountService(
|
||||
.Where(s => s.AccountId == session.Id && s.Challenge.DeviceId == session.Challenge.DeviceId)
|
||||
.ToListAsync();
|
||||
|
||||
if (!await IsDeviceActive(session.Challenge.DeviceId))
|
||||
await pusher.UnsubscribePushNotificationsAsync(new UnsubscribePushNotificationsRequest()
|
||||
{ DeviceId = session.Challenge.Device.DeviceId }
|
||||
);
|
||||
if (session.Challenge.ClientId.HasValue)
|
||||
{
|
||||
if (!await IsDeviceActive(session.Challenge.ClientId.Value))
|
||||
await pusher.UnsubscribePushNotificationsAsync(new UnsubscribePushNotificationsRequest()
|
||||
{ DeviceId = session.Challenge.Client!.DeviceId }
|
||||
);
|
||||
}
|
||||
|
||||
// The current session should be included in the sessions' list
|
||||
await db.AuthSessions
|
||||
@@ -679,4 +672,4 @@ public class AccountService(
|
||||
await db.BulkInsertAsync(newProfiles);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user