diff --git a/Common.Client/Client.cs b/Common.Client/Client.cs index 72ddc88..651ec02 100644 --- a/Common.Client/Client.cs +++ b/Common.Client/Client.cs @@ -35,19 +35,30 @@ public static async Task Run( ns.Notify(NotificationSeverity.Error, l.S(CS.ApiError), message, duration: 6000D), enableRequestStreaming ); - var api = apiFactory(rpcClient); builder.Services.AddSingleton(httpClient); - builder.Services.AddSingleton(rpcClient); - builder.Services.AddSingleton(s); - builder.Services.AddSingleton(l); - builder.Services.AddSingleton(api); - builder.Services.AddSingleton(api); - builder.Services.AddSingleton>(); - builder.Services.AddSingleton(ns); - builder.Services.AddSingleton(); - builder.Services.AddSingleton(); - builder.Services.AddSingleton(); - addServices?.Invoke(builder.Services); + Setup(builder.Services, l, s, ns, apiFactory(rpcClient), addServices); await builder.Build().RunAsync(); } + + public static void Setup( + IServiceCollection services, + L l, + S s, + NotificationService ns, + TApi api, + Action? addServices = null + ) + where TApi : class, IApi + { + services.AddSingleton(s); + services.AddSingleton(l); + services.AddSingleton(api); + services.AddSingleton(api); + services.AddSingleton>(); + services.AddSingleton(ns); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + addServices?.Invoke(services); + } } diff --git a/Common.Client/Common.Client.csproj b/Common.Client/Common.Client.csproj index a019c19..24799ce 100644 --- a/Common.Client/Common.Client.csproj +++ b/Common.Client/Common.Client.csproj @@ -5,7 +5,7 @@ enable enable 0xor1.Common.Client - 3.0.12 + 3.0.13 Daniel Robinson Personal Personal @@ -18,7 +18,7 @@ - + @@ -31,7 +31,4 @@ - - - diff --git a/Common.Client/Localizer.cs b/Common.Client/Localizer.cs index 85776d7..0e20875 100644 --- a/Common.Client/Localizer.cs +++ b/Common.Client/Localizer.cs @@ -4,7 +4,7 @@ namespace Common.Client; -internal class Localizer : L +public class Localizer : L { private readonly S _s; private DateFmt _dateFmt; diff --git a/Common.Server/Auth/AuthEps.cs b/Common.Server/Auth/AuthEps.cs index 73ffccd..782a36e 100644 --- a/Common.Server/Auth/AuthEps.cs +++ b/Common.Server/Auth/AuthEps.cs @@ -11,14 +11,14 @@ public class AuthEps { private readonly int _maxAuthAttemptsPerSecond; private readonly Func _onActivation; - private readonly Func _onDelete; - private readonly Func, Task> _validateFcmTopic; + private readonly Func _onDelete; + private readonly Func, Task> _validateFcmTopic; public AuthEps( int maxAuthAttemptsPerSecond, Func onActivation, - Func onDelete, - Func, Task> validateFcmTopic + Func onDelete, + Func, Task> validateFcmTopic ) { _maxAuthAttemptsPerSecond = maxAuthAttemptsPerSecond; diff --git a/Common.Server/Auth/CommonEps.cs b/Common.Server/Auth/CommonEps.cs index 2277794..9a79733 100644 --- a/Common.Server/Auth/CommonEps.cs +++ b/Common.Server/Auth/CommonEps.cs @@ -1,3 +1,4 @@ +using Common.Shared.Auth; using Microsoft.EntityFrameworkCore; namespace Common.Server.Auth; @@ -10,8 +11,8 @@ public class CommonEps public CommonEps( int maxAuthAttemptsPerSecond, Func onActivation, - Func onDelete, - Func, Task> validateFcmTopic + Func onDelete, + Func, Task> validateFcmTopic ) { _authEps = new AuthEps( diff --git a/Common.Server/Common.Server.csproj b/Common.Server/Common.Server.csproj index ed63e02..c98d5a7 100644 --- a/Common.Server/Common.Server.csproj +++ b/Common.Server/Common.Server.csproj @@ -5,7 +5,7 @@ enable enable 0xor1.Common.Server - 3.0.12 + 3.0.13 Daniel Robinson Personal Personal @@ -17,7 +17,7 @@ - + diff --git a/Common.Server/FcmClient.cs b/Common.Server/FcmClient.cs index 6c5cbda..03c32ca 100644 --- a/Common.Server/FcmClient.cs +++ b/Common.Server/FcmClient.cs @@ -36,7 +36,7 @@ public async Task Send(Message msg, bool fnf = true, CancellationToken ctkn = de public async Task SendTopic( IRpcCtx ctx, TDbCtx db, - Session ses, + ISession ses, IReadOnlyList topic, object? data, bool fnf = true diff --git a/Common.Server/FcmNopClient.cs b/Common.Server/FcmNopClient.cs index 6b8e2ca..c78d988 100644 --- a/Common.Server/FcmNopClient.cs +++ b/Common.Server/FcmNopClient.cs @@ -16,7 +16,7 @@ public async Task Send(Message msg, bool fnf = true, CancellationToken ctkn = de public async Task SendTopic( IRpcCtx ctx, TDbCtx db, - Session ses, + ISession ses, IReadOnlyList topic, object? data, bool fnf = true diff --git a/Common.Server/IFcmClient.cs b/Common.Server/IFcmClient.cs index 4fcd091..6d0a408 100644 --- a/Common.Server/IFcmClient.cs +++ b/Common.Server/IFcmClient.cs @@ -10,7 +10,7 @@ public interface IFcmClient Task SendTopic( IRpcCtx ctx, TDbCtx db, - Session ses, + ISession ses, IReadOnlyList topic, object? data, bool fnf = true diff --git a/Common.Server/IRpcCtx.cs b/Common.Server/IRpcCtx.cs index 361b3b3..95b2dd5 100644 --- a/Common.Server/IRpcCtx.cs +++ b/Common.Server/IRpcCtx.cs @@ -1,4 +1,5 @@ using Common.Shared; +using Common.Shared.Auth; namespace Common.Server; @@ -10,9 +11,9 @@ public T Get() public T GetFeature() where T : notnull; - public Session GetSession(); + public ISession GetSession(); - public Session CreateSession( + public ISession CreateSession( string userId, bool isAuthed, bool rememberMe, @@ -24,7 +25,7 @@ public Session CreateSession( string decimalSeparator, bool fcmEnabled ); - public Session ClearSession(); + public ISession ClearSession(); public string? GetHeader(string name); diff --git a/Common.Server/IRpcHttpSessionManager.cs b/Common.Server/IRpcHttpSessionManager.cs index e159d78..424701b 100644 --- a/Common.Server/IRpcHttpSessionManager.cs +++ b/Common.Server/IRpcHttpSessionManager.cs @@ -1,13 +1,14 @@ using Common.Shared; using Microsoft.AspNetCore.Http; +using ISession = Common.Shared.Auth.ISession; namespace Common.Server; public interface IRpcHttpSessionManager { - internal Session Get(HttpContext ctx); + internal ISession Get(HttpContext ctx); - internal Session Create( + internal ISession Create( HttpContext ctx, string userId, bool isAuthed, @@ -21,5 +22,5 @@ internal Session Create( bool fcmEnabled ); - internal Session Clear(HttpContext ctx); + internal ISession Clear(HttpContext ctx); } diff --git a/Common.Server/RpcCtxExts.cs b/Common.Server/RpcCtxExts.cs index 6064798..7d26894 100644 --- a/Common.Server/RpcCtxExts.cs +++ b/Common.Server/RpcCtxExts.cs @@ -6,6 +6,7 @@ using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using CS = Common.Shared.I18n.S; +using ISession = Common.Shared.Auth.ISession; namespace Common.Server; @@ -17,7 +18,7 @@ public static T Get(this HttpContext ctx) public static T GetFeature(this HttpContext ctx) where T : notnull => ctx.Features.GetRequiredFeature(); - public static Session GetAuthedSession(this IRpcCtx ctx) + public static ISession GetAuthedSession(this IRpcCtx ctx) { var ses = ctx.GetSession(); ctx.ErrorIf(ses.IsAnon, CS.AuthNotAuthenticated, null, HttpStatusCode.Unauthorized); @@ -26,7 +27,7 @@ public static Session GetAuthedSession(this IRpcCtx ctx) public static async Task DbTx( this IRpcCtx ctx, - Func> fn, + Func> fn, bool mustBeAuthedSession = true ) where TDbCtx : DbContext diff --git a/Common.Server/RpcHttpCtx.cs b/Common.Server/RpcHttpCtx.cs index e55863b..11b4cc8 100644 --- a/Common.Server/RpcHttpCtx.cs +++ b/Common.Server/RpcHttpCtx.cs @@ -1,6 +1,7 @@ using System.Net; using Common.Shared; using Microsoft.AspNetCore.Http; +using ISession = Common.Shared.Auth.ISession; namespace Common.Server; @@ -17,9 +18,9 @@ public RpcHttpCtx(HttpContext ctx) public CancellationToken Ctkn => _ctx.RequestAborted; - public Session GetSession() => _sessionManager.Get(_ctx); + public ISession GetSession() => _sessionManager.Get(_ctx); - public Session CreateSession( + public ISession CreateSession( string userId, bool isAuthed, bool rememberMe, @@ -45,7 +46,7 @@ bool fcmEnabled fcmEnabled ); - public Session ClearSession() => _sessionManager.Clear(_ctx); + public ISession ClearSession() => _sessionManager.Clear(_ctx); public string? GetHeader(string name) => _ctx.Request.Headers.ContainsKey(name) ? _ctx.Request.Headers[name].ToString() : null; diff --git a/Common.Server/RpcHttpSessionManager.cs b/Common.Server/RpcHttpSessionManager.cs index 7f3e345..8b27e86 100644 --- a/Common.Server/RpcHttpSessionManager.cs +++ b/Common.Server/RpcHttpSessionManager.cs @@ -3,6 +3,7 @@ using Common.Shared; using MessagePack; using Microsoft.AspNetCore.Http; +using ISession = Common.Shared.Auth.ISession; namespace Common.Server; @@ -27,9 +28,9 @@ public RpcHttpSessionManager(IReadOnlyList signatureKeys, S s) ); } - public Session Get(HttpContext ctx) + public ISession Get(HttpContext ctx) { - Session ses; + ISession ses; if (!ctx.Items.ContainsKey(SessionKey)) { ses = GetCookie(ctx); @@ -43,7 +44,7 @@ public Session Get(HttpContext ctx) return ses; } - public Session Create( + public ISession Create( HttpContext ctx, string userId, bool isAuthed, @@ -76,7 +77,7 @@ bool fcmEnabled return ses; } - public Session Clear(HttpContext ctx) + public ISession Clear(HttpContext ctx) { var ses = _Clear(ctx); ctx.Items[SessionKey] = ses; @@ -85,7 +86,7 @@ public Session Clear(HttpContext ctx) private Session _Clear(HttpContext ctx) { - return Create( + return (Session)Create( ctx, Id.New(), false, diff --git a/Common.Server/Session.cs b/Common.Server/Session.cs index 838f6ec..2cb1949 100644 --- a/Common.Server/Session.cs +++ b/Common.Server/Session.cs @@ -1,10 +1,11 @@ using Common.Shared; +using Common.Shared.Auth; using MessagePack; namespace Common.Server; [MessagePackObject] -public record Session +public record Session : ISession { [Key(0)] public string Id { get; init; } diff --git a/Common.Server/Test/RpcTestCtx.cs b/Common.Server/Test/RpcTestCtx.cs index b063b2d..cf3af67 100644 --- a/Common.Server/Test/RpcTestCtx.cs +++ b/Common.Server/Test/RpcTestCtx.cs @@ -20,7 +20,7 @@ public record RpcTestCtx : IRpcCtxInternal public RpcTestCtx( IServiceProvider services, IFeatureCollection features, - Session? session, + ISession? session, S s, Dictionary headers, object arg, @@ -30,7 +30,7 @@ CancellationToken ctkn _services = services; _features = features; _s = s; - Session = session ?? ClearSession(); + Session = (Session)(session ?? ClearSession()); Headers = headers; Arg = arg; Ctkn = ctkn; @@ -44,9 +44,9 @@ public T Get() public T GetFeature() where T : notnull => _features.GetRequiredFeature(); - public Session GetSession() => Session; + public ISession GetSession() => Session; - public Session CreateSession( + public ISession CreateSession( string userId, bool isAuthed, bool rememberMe, @@ -76,9 +76,9 @@ bool fcmEnabled return Session; } - public Session ClearSession() + public ISession ClearSession() { - Session = new() + Session = new Session() { Id = Id.New(), IsAuthed = false, diff --git a/Common.Server/Test/RpcTestRig.cs b/Common.Server/Test/RpcTestRig.cs index db2c0f9..7299014 100644 --- a/Common.Server/Test/RpcTestRig.cs +++ b/Common.Server/Test/RpcTestRig.cs @@ -3,6 +3,7 @@ using Common.Server.Auth; using Common.Shared; using Common.Shared.Auth; +using Common.Shared.Test; using Microsoft.AspNetCore.Http.Features; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; @@ -58,9 +59,9 @@ public T RunDb(Func fn) return fn(db); } - private async Task<(Session, object)> Exe( + private async Task<(ISession, object)> Exe( string path, - Session? session, + ISession? session, Dictionary headers, object arg, CancellationToken ctkn = default diff --git a/Common.Shared/Auth/ISession.cs b/Common.Shared/Auth/ISession.cs index 9428faa..f4da005 100644 --- a/Common.Shared/Auth/ISession.cs +++ b/Common.Shared/Auth/ISession.cs @@ -5,6 +5,7 @@ public interface ISession string Id { get; } bool IsAuthed { get; } bool IsAnon => !IsAuthed; + bool RememberMe { get; } string DateFmtStr => DateFmtExt.ToString(DateFmt, DateSeparator); string Lang { get; } DateFmt DateFmt { get; } @@ -13,4 +14,6 @@ public interface ISession string ThousandsSeparator { get; } string DecimalSeparator { get; } bool FcmEnabled { get; } + + public Session ToApi(); } diff --git a/Common.Shared/Auth/Session.cs b/Common.Shared/Auth/Session.cs index e7fbac2..c08dab3 100644 --- a/Common.Shared/Auth/Session.cs +++ b/Common.Shared/Auth/Session.cs @@ -47,4 +47,6 @@ public static Session CommonDefault() => Str.DefaultThousandsSeparator, Str.DefaultDecimalSeparator ); + + public Session ToApi() => this; } diff --git a/Common.Shared/Common.Shared.csproj b/Common.Shared/Common.Shared.csproj index e896805..d7f5056 100644 --- a/Common.Shared/Common.Shared.csproj +++ b/Common.Shared/Common.Shared.csproj @@ -5,7 +5,7 @@ enable enable 0xor1.Common.Shared - 3.0.12 + 3.0.13 Daniel Robinson Personal Personal diff --git a/Common.Shared/I18n/Keys.cs b/Common.Shared/I18n/Keys.cs index 6453362..837c6a9 100644 --- a/Common.Shared/I18n/Keys.cs +++ b/Common.Shared/I18n/Keys.cs @@ -1,8 +1,6 @@ // Generated Code File, Do Not Edit. // This file is generated with Common.I18nCodeGen. -using Common.Shared; - namespace Common.Shared.I18n; public static partial class S diff --git a/Common.Shared/I18n/SDE.cs b/Common.Shared/I18n/SDE.cs index a4b6fc9..2b8a254 100644 --- a/Common.Shared/I18n/SDE.cs +++ b/Common.Shared/I18n/SDE.cs @@ -1,8 +1,6 @@ // Generated Code File, Do Not Edit. // This file is generated with Common.I18nCodeGen. -using Common.Shared; - namespace Common.Shared.I18n; public static partial class S diff --git a/Common.Shared/I18n/SEN.cs b/Common.Shared/I18n/SEN.cs index 0c10f93..0370348 100644 --- a/Common.Shared/I18n/SEN.cs +++ b/Common.Shared/I18n/SEN.cs @@ -1,8 +1,6 @@ // Generated Code File, Do Not Edit. // This file is generated with Common.I18nCodeGen. -using Common.Shared; - namespace Common.Shared.I18n; public static partial class S diff --git a/Common.Shared/I18n/SES.cs b/Common.Shared/I18n/SES.cs index a1eb177..ed049b6 100644 --- a/Common.Shared/I18n/SES.cs +++ b/Common.Shared/I18n/SES.cs @@ -1,8 +1,6 @@ // Generated Code File, Do Not Edit. // This file is generated with Common.I18nCodeGen. -using Common.Shared; - namespace Common.Shared.I18n; public static partial class S diff --git a/Common.Shared/I18n/SFR.cs b/Common.Shared/I18n/SFR.cs index ff7cb82..107c94b 100644 --- a/Common.Shared/I18n/SFR.cs +++ b/Common.Shared/I18n/SFR.cs @@ -1,8 +1,6 @@ // Generated Code File, Do Not Edit. // This file is generated with Common.I18nCodeGen. -using Common.Shared; - namespace Common.Shared.I18n; public static partial class S diff --git a/Common.Shared/I18n/SIT.cs b/Common.Shared/I18n/SIT.cs index 94876ac..9a31f90 100644 --- a/Common.Shared/I18n/SIT.cs +++ b/Common.Shared/I18n/SIT.cs @@ -1,8 +1,6 @@ // Generated Code File, Do Not Edit. // This file is generated with Common.I18nCodeGen. -using Common.Shared; - namespace Common.Shared.I18n; public static partial class S diff --git a/Common.Server/Test/RpcTestClient.cs b/Common.Shared/Test/RpcTestClient.cs similarity index 83% rename from Common.Server/Test/RpcTestClient.cs rename to Common.Shared/Test/RpcTestClient.cs index 6077270..d12f3d6 100644 --- a/Common.Server/Test/RpcTestClient.cs +++ b/Common.Shared/Test/RpcTestClient.cs @@ -1,30 +1,30 @@ -using Common.Shared; +using Common.Shared.Auth; -namespace Common.Server.Test; +namespace Common.Shared.Test; public class RpcTestClient : IRpcClient { - private Session? _session; + private ISession? _session; private Dictionary _headers = new(); private Func< string, - Session?, + ISession?, Dictionary, object, CancellationToken, - Task<(Session, object)> + Task<(ISession, object)> > _exe; public RpcTestClient( Func< string, - Session?, + ISession?, Dictionary, object, CancellationToken, - Task<(Session, object)> + Task<(ISession, object)> > exe, - Session? session = null + ISession? session = null ) { _exe = exe; diff --git a/bin/pre b/bin/pre index b5e5a1d..6328b59 100644 --- a/bin/pre +++ b/bin/pre @@ -23,6 +23,7 @@ else rm -r test_coverage reportgenerator -reports:"*\coverage.cobertura.xml" -targetdir:"test_coverage" -reporttypes:Html rm */coverage.cobertura.xml + rm -r */TestResults fi docker-compose -f docker/docker-compose.yml stop \ No newline at end of file