diff --git a/DysonNetwork.Pass/Account/AccountCurrentController.cs b/DysonNetwork.Pass/Account/AccountCurrentController.cs index 8ea02ed..ab57691 100644 --- a/DysonNetwork.Pass/Account/AccountCurrentController.cs +++ b/DysonNetwork.Pass/Account/AccountCurrentController.cs @@ -560,7 +560,7 @@ public class AccountCurrentController( [HttpGet("devices")] [Authorize] - public async Task>> GetDevices() + public async Task>> GetDevices() { if (HttpContext.Items["CurrentUser"] is not SnAccount currentUser || HttpContext.Items["CurrentSession"] is not SnAuthSession currentSession) return Unauthorized(); @@ -571,18 +571,41 @@ public class AccountCurrentController( .Where(device => device.AccountId == currentUser.Id) .ToListAsync(); - var challengeDevices = devices.Select(SnAuthClientWithChallenge.FromClient).ToList(); - var deviceIds = challengeDevices.Select(x => x.DeviceId).ToList(); + var sessionDevices = devices.Select(SnAuthClientWithSessions.FromClient).ToList(); + var clientIds = sessionDevices.Select(x => x.Id).ToList(); - var authChallenges = await db.AuthChallenges - .Where(c => deviceIds.Contains(c.DeviceId)) - .GroupBy(c => c.DeviceId) + var authSessions = await db.AuthSessions + .Where(c => clientIds.Contains(c.Id)) + .GroupBy(c => c.Id) .ToDictionaryAsync(c => c.Key, c => c.ToList()); - foreach (var challengeDevice in challengeDevices) - if (authChallenges.TryGetValue(challengeDevice.DeviceId, out var challenge)) - challengeDevice.Challenges = challenge; + foreach (var dev in sessionDevices) + if (authSessions.TryGetValue(dev.Id, out var challenge)) + dev.Sessions = challenge; - return Ok(challengeDevices); + return Ok(sessionDevices); + } + + [HttpGet("challenges")] + [Authorize] + public async Task>> GetChallenges( + [FromQuery] int take = 20, + [FromQuery] int offset = 0 + ) + { + if (HttpContext.Items["CurrentUser"] is not SnAccount currentUser) return Unauthorized(); + + var query = db.AuthChallenges + .Where(challenge => challenge.AccountId == currentUser.Id) + .OrderByDescending(c => c.CreatedAt); + + var total = await query.CountAsync(); + Response.Headers.Append("X-Total", total.ToString()); + + var challenges = await query + .Skip(offset) + .Take(take) + .ToListAsync(); + return Ok(challenges); } [HttpGet("sessions")] @@ -596,6 +619,7 @@ public class AccountCurrentController( HttpContext.Items["CurrentSession"] is not SnAuthSession currentSession) return Unauthorized(); var query = db.AuthSessions + .OrderByDescending(x => x.LastGrantedAt) .Include(session => session.Account) .Where(session => session.Account.Id == currentUser.Id); @@ -604,7 +628,6 @@ public class AccountCurrentController( Response.Headers.Append("X-Auth-Session", currentSession.Id.ToString()); var sessions = await query - .OrderByDescending(x => x.LastGrantedAt) .Skip(offset) .Take(take) .ToListAsync(); @@ -933,4 +956,4 @@ public class AccountCurrentController( .ToListAsync(); return Ok(records); } -} +} \ No newline at end of file diff --git a/DysonNetwork.Pass/Auth/AuthService.cs b/DysonNetwork.Pass/Auth/AuthService.cs index c2a1cd1..284e67b 100644 --- a/DysonNetwork.Pass/Auth/AuthService.cs +++ b/DysonNetwork.Pass/Auth/AuthService.cs @@ -48,7 +48,8 @@ public class AuthService( .Take(10) .ToListAsync(); - var recentChallengeIds = recentSessions.Where(s => s.ChallengeId != null).Select(s => s.ChallengeId.Value).ToList(); + var recentChallengeIds = + recentSessions.Where(s => s.ChallengeId != null).Select(s => s.ChallengeId.Value).ToList(); var recentChallenges = await db.AuthChallenges.Where(c => recentChallengeIds.Contains(c.Id)).ToListAsync(); var ipAddress = request.HttpContext.Connection.RemoteIpAddress?.ToString(); @@ -192,7 +193,7 @@ public class AuthService( CreatedAt = time, LastGrantedAt = time, IpAddress = HttpContext.Connection.RemoteIpAddress?.ToString(), - UserAgent = HttpContext.Request.Headers.UserAgent, + UserAgent = HttpContext.Request.Headers.UserAgent, AppId = customAppId, ParentSessionId = parentSession?.Id, Type = customAppId is not null ? SessionType.OAuth : SessionType.Oidc, @@ -409,8 +410,12 @@ public class AuthService( if (challenge.StepRemain != 0) throw new ArgumentException("Challenge not yet completed."); - var device = await GetOrCreateDeviceAsync(challenge.AccountId, challenge.DeviceId, challenge.DeviceName, - challenge.Platform); + var device = await GetOrCreateDeviceAsync( + challenge.AccountId, + challenge.DeviceId, + challenge.DeviceName, + challenge.Platform + ); var now = SystemClock.Instance.GetCurrentInstant(); var session = new SnAuthSession @@ -421,7 +426,7 @@ public class AuthService( IpAddress = challenge.IpAddress, UserAgent = challenge.UserAgent, Scopes = challenge.Scopes, - Audiences = challenge.Audiences, + Audiences = challenge.Audiences, ChallengeId = challenge.Id, ClientId = device.Id, }; @@ -537,7 +542,8 @@ public class AuthService( return key; } - public async Task CreateApiKey(Guid accountId, string label, Instant? expiredAt = null, SnAuthSession? parentSession = null) + public async Task CreateApiKey(Guid accountId, string label, Instant? expiredAt = null, + SnAuthSession? parentSession = null) { var key = new SnApiKey { @@ -689,4 +695,4 @@ public class AuthService( return session; } -} +} \ No newline at end of file diff --git a/DysonNetwork.Shared/Models/AuthSession.cs b/DysonNetwork.Shared/Models/AuthSession.cs index f5d204e..dd68d91 100644 --- a/DysonNetwork.Shared/Models/AuthSession.cs +++ b/DysonNetwork.Shared/Models/AuthSession.cs @@ -153,13 +153,13 @@ public class SnAuthClient : ModelBase }; } -public class SnAuthClientWithChallenge : SnAuthClient +public class SnAuthClientWithSessions : SnAuthClient { - public List Challenges { get; set; } = []; + public List Sessions { get; set; } = []; - public static SnAuthClientWithChallenge FromClient(SnAuthClient client) + public static SnAuthClientWithSessions FromClient(SnAuthClient client) { - return new SnAuthClientWithChallenge + return new SnAuthClientWithSessions { Id = client.Id, Platform = client.Platform,