mirror of
https://gitea.tendokyu.moe/Kayori/Medusa.net.git
synced 2026-10-11 08:48:10 +03:00
Add sppass/cardless login support
- SppassOpenHandler/LookupHandler/CloseHandler implementing the eAmuse
sppass.open/lookup/close xrpc methods (request/response schema
confirmed by tracing the client's psmap-based response parser and by
live testing against a real cabinet build)
- SppassSessionService backs open/lookup/close with a token-keyed
session (url + interval for the cabinet to display/poll, later
card_type/card_id once approved)
- CardlessApi: POST /api/cardless/{token}/approve, letting a signed-in
player's phone approve the pending token using their account's
first registered card
- Cardless frontend pages ([token].vue, scan.vue) and useCardlessAuth
composable driving the approval call
- GetConfig GraphQL query + ConfigQuery resolver so the cardless page
can show which server it's talking to
- Wire ISppassSessionService and the cardless routes into Program.cs;
HandlerService now parses model into a GameModel once per request
instead of re-parsing per handler
This commit is contained in:
+27
-4
@@ -4,6 +4,7 @@ using Abstractions.Utils;
|
||||
using KbinXml.Net;
|
||||
using Microsoft.AspNetCore.Hosting.Server;
|
||||
using Microsoft.AspNetCore.Hosting.Server.Features;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Server;
|
||||
@@ -35,6 +36,14 @@ builder.Services.AddAuthorization();
|
||||
builder.Services.AddIdentityApiEndpoints<User>()
|
||||
.AddEntityFrameworkStores<AppDbContext>();
|
||||
|
||||
// AddIdentityApiEndpoints registers a no-op IEmailSender<User> by default; swap it for one that
|
||||
// logs confirmation/reset links to the console until a real email sender is wired up.
|
||||
// Must be Singleton: MapIdentityApi resolves it once via endpoints.ServiceProvider (the root
|
||||
// container, at startup, before any request scope exists) and closes over it for the app's
|
||||
// lifetime - a Scoped registration can't be resolved from the root container.
|
||||
builder.Services.AddHttpContextAccessor();
|
||||
builder.Services.AddSingleton<IEmailSender<User>, ConsoleEmailSender>();
|
||||
|
||||
builder.Services.AddHandlers();
|
||||
|
||||
if (!File.Exists("database/Medusa.db"))
|
||||
@@ -45,7 +54,8 @@ if (!File.Exists("database/Medusa.db"))
|
||||
}
|
||||
}
|
||||
|
||||
builder.Services.AddDbContext<AppDbContext>(options => options.UseSqlite("Data Source=database/Medusa.db;"));
|
||||
builder.Services.AddDbContext<AppDbContext>(options =>
|
||||
options.UseSqlite("Data Source=database/Medusa.db;Default Timeout=5;"));
|
||||
|
||||
builder.Services.AddIdentityCore<User>(config =>
|
||||
{
|
||||
@@ -88,6 +98,7 @@ builder.Services.AddSingleton(pluginUiBroadcaster);
|
||||
var pluginService = new PluginService(logger, pluginRegistry, pluginUiBroadcaster);
|
||||
builder.Services.AddSingleton(pluginRegistry);
|
||||
builder.Services.AddSingleton<IEaCoinSessionService, EaCoinSessionService>();
|
||||
builder.Services.AddSingleton<ISppassSessionService, SppassSessionService>();
|
||||
builder.Services.AddSingleton<IPluginService>(pluginService);
|
||||
builder.Services.AddHostedService<PluginWatcher>();
|
||||
|
||||
@@ -139,6 +150,7 @@ app.UseHandlers();
|
||||
var apiGroup = app.MapGroup("/api").WithTags("API");
|
||||
apiGroup.MapCardsApiEndpoints();
|
||||
apiGroup.MapUserApiEndpoints();
|
||||
apiGroup.MapCardlessApiEndpoints();
|
||||
apiGroup.MapIdentityApi();
|
||||
app.MapPluginStaticFiles();
|
||||
apiGroup.MapPluginApiEndpoints();
|
||||
@@ -154,6 +166,15 @@ eamuseGroup.MapPost("/{model}/{module}/{method}", (string model, string module,
|
||||
return HandleEAmuseRoute(amusementRequest, httpContext, logger, handlerService, pluginService);
|
||||
});
|
||||
|
||||
eamuseGroup.MapPost("/{module}/{model}/{module2}/{method}", (string module, string model, string module2, string method,
|
||||
HttpContext httpContext, [FromServices] ILogger<Program> logger, [FromServices] IHandlerService handlerService,
|
||||
[FromServices] IPluginService pluginService) =>
|
||||
{
|
||||
var amusementRequest = new AmusementRequest() { Model = model, Module = module ?? "", Method = method ?? "" };
|
||||
|
||||
return HandleEAmuseRoute(amusementRequest, httpContext, logger, handlerService, pluginService);
|
||||
});
|
||||
|
||||
eamuseGroup.MapPost("/{m}", (string m, [FromQuery] string model, [FromQuery] string? module, [FromQuery] string? method,
|
||||
[FromQuery] string? f,
|
||||
HttpContext httpContext, [FromServices] ILogger<Program> logger, [FromServices] IHandlerService handlerService,
|
||||
@@ -185,6 +206,8 @@ var appDbContext = scope.ServiceProvider.GetRequiredService<AppDbContext>();
|
||||
|
||||
await appDbContext.Database.MigrateAsync();
|
||||
|
||||
await appDbContext.Database.ExecuteSqlRawAsync("PRAGMA journal_mode=WAL;");
|
||||
|
||||
app.Run();
|
||||
return;
|
||||
|
||||
@@ -252,9 +275,9 @@ async Task<byte[]> HandleEAmuseRequest(AmusementRequest request, string body, st
|
||||
var plugins = pluginService.GetPlugins();
|
||||
var forcedEncoding = plugins.FirstOrDefault(p => p.GameCode == request.Model.Split(":")[0])?.ForcedEncoding;
|
||||
|
||||
var encodingEnum = encoding switch
|
||||
var encodingEnum = encoding.ToLowerInvariant() switch
|
||||
{
|
||||
"shift_jis" or "ShiftJIS" or "SHIFT_JIS" => KnownEncodings.ShiftJIS,
|
||||
"shift_jis" or "shiftjis" => KnownEncodings.ShiftJIS,
|
||||
"us-ascii" => KnownEncodings.ASCII,
|
||||
"utf-8" => KnownEncodings.UTF8,
|
||||
"euc-jp" => KnownEncodings.EUC_JP,
|
||||
@@ -294,4 +317,4 @@ async Task<byte[]> HandleEAmuseRequest(AmusementRequest request, string body, st
|
||||
encodedBody = RC4.Encrypt(rc4Key, encodedBody);
|
||||
|
||||
return encodedBody;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user