From 03b28296638ae83cb1907e4e4f7ddfa02a48bbbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20Can=20Karag=C3=B6z?= Date: Sun, 10 May 2026 18:55:41 +0300 Subject: [PATCH] Fix Expired Chain Doesn't Rotate on Successful Login --- .../uauth.db-shm | Bin 32768 -> 32768 bytes .../uauth.db-wal | Bin 935272 -> 914672 bytes .../Flows/Login/LoginOrchestrator.cs | 11 +++++++++-- .../Issuers/UAuthSessionIssuer.cs | 9 +++++++-- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/uauth.db-shm b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/uauth.db-shm index f64b9c90f143a9cc183059d3bc8a17ba03fcadff..1c694283171adb6b6d4ac8d607e9879c9933e66d 100644 GIT binary patch delta 193 zcmZo@U}|V!s+V}A%K!p0K+MR%AaD;z`vCEhc1JIc{J9TaJ&jYFnUwTiqG-BePV}69 zQq=>E0t1k_|B(Pxcw>Dd^JWp2X*QD;SVT6ja=5`VS%{@-^B>nMTtLQ>%_V^mtYAh# RxRlanAr=+J&FiWliU4;oK*In4 delta 213 zcmZo@U}|V!s+V}A%K!qhK+MR%An+JS`v9?;YKdjf;-$wYhp%Q%>v}vVKREEnS~H<- zq^buR1qL8<|04mY@W%Q^W|(`H7NnKqkOIox1jd_0+vrE>Eh*DG9% k_cvb*_|3}r04TC}b3wS265~UlLS@Fy>#BeXAAuAC07n-@6aWAK diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/uauth.db-wal b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/uauth.db-wal index 05f8b7830017fe7e251c85558bdb58197b83fcb3..b5380fc80a8a159a31f3efece8fb0ae39bc5e748 100644 GIT binary patch delta 12975 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 diff --git a/src/CodeBeam.UltimateAuth.Server/Flows/Login/LoginOrchestrator.cs b/src/CodeBeam.UltimateAuth.Server/Flows/Login/LoginOrchestrator.cs index 54c018d5..1b353d97 100644 --- a/src/CodeBeam.UltimateAuth.Server/Flows/Login/LoginOrchestrator.cs +++ b/src/CodeBeam.UltimateAuth.Server/Flows/Login/LoginOrchestrator.cs @@ -131,8 +131,15 @@ public async Task LoginAsync(AuthFlowContext flow, LoginRequest req { var chain = await sessionStore.GetChainByDeviceAsync(userKey.Value, deviceId, ct); - if (chain is not null && !chain.IsRevoked) - chainId = chain.ChainId; + if (chain is not null) + { + var chainState = chain.GetState(now, _options.Session.IdleTimeout); + + if (chainState == SessionState.Active) + { + chainId = chain.ChainId; + } + } } // TODO: Add accountState here, currently it only checks factor state diff --git a/src/CodeBeam.UltimateAuth.Server/Infrastructure/Issuers/UAuthSessionIssuer.cs b/src/CodeBeam.UltimateAuth.Server/Infrastructure/Issuers/UAuthSessionIssuer.cs index 38cf330d..343bac0c 100644 --- a/src/CodeBeam.UltimateAuth.Server/Infrastructure/Issuers/UAuthSessionIssuer.cs +++ b/src/CodeBeam.UltimateAuth.Server/Infrastructure/Issuers/UAuthSessionIssuer.cs @@ -92,8 +92,13 @@ await kernel.ExecuteAsync(async _ => //chain = await kernel.GetChainAsync(context.ChainId.Value) // ?? throw new UAuthNotFoundException("Chain not found."); - if (chain.IsRevoked) - throw new UAuthValidationException("Chain revoked."); + var chainState = chain.GetState(now, _options.Session.IdleTimeout); + + if (chainState != SessionState.Active) + throw new UAuthValidationException("Chain is not active."); + + //if (chain.IsRevoked) + // throw new UAuthValidationException("Chain revoked."); if (chain.UserKey != context.UserKey || chain.Tenant != context.Tenant) throw new UAuthValidationException("Invalid chain ownership.");