feat(online-inbox): carry ownerId on sync to prepare for multi-user
Plumb a per-resource owner (Zitadel sub) through the sync contract without enforcing isolation client-side — the server stays the authority. - Dtos: add optional ownerId to RemoteList/RemoteTask/MirrorTask - JwtClaims: decode the sub claim from the access token (never throws) - OnlineSyncService: stamp ownerId on pushed lists + mirror; defensively skip pulled tasks owned by a different user (unowned tasks still sync, so single-user behavior is unchanged) - docs: contract documents ownerId + multi-user readiness Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
40
tests/ClaudeDo.Worker.Tests/Online/JwtClaimsTests.cs
Normal file
40
tests/ClaudeDo.Worker.Tests/Online/JwtClaimsTests.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using System.Text;
|
||||
using ClaudeDo.Worker.Online;
|
||||
|
||||
namespace ClaudeDo.Worker.Tests.Online;
|
||||
|
||||
public sealed class JwtClaimsTests
|
||||
{
|
||||
// Builds a fake JWT (header.payload.signature) carrying the given JSON payload.
|
||||
internal static string MakeToken(string payloadJson)
|
||||
{
|
||||
static string B64Url(string s) =>
|
||||
Convert.ToBase64String(Encoding.UTF8.GetBytes(s))
|
||||
.TrimEnd('=').Replace('+', '-').Replace('/', '_');
|
||||
return $"{B64Url("{\"alg\":\"RS256\"}")}.{B64Url(payloadJson)}.sig";
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetSubject_ReturnsSub()
|
||||
{
|
||||
var token = MakeToken("{\"sub\":\"user-123\",\"email\":\"a@b.c\"}");
|
||||
Assert.Equal("user-123", JwtClaims.GetSubject(token));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetSubject_Null_WhenNoSub()
|
||||
{
|
||||
var token = MakeToken("{\"email\":\"a@b.c\"}");
|
||||
Assert.Null(JwtClaims.GetSubject(token));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(null)]
|
||||
[InlineData("")]
|
||||
[InlineData("not-a-jwt")]
|
||||
[InlineData("opaque.token")]
|
||||
public void GetSubject_Null_ForUnparseableInput(string? token)
|
||||
{
|
||||
Assert.Null(JwtClaims.GetSubject(token));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user