🐛 Fix magic spell and email service

This commit is contained in:
2025-04-29 21:52:35 +08:00
parent 0ebeab672b
commit 35792efa9f
10 changed files with 56 additions and 38 deletions

View File

@ -20,7 +20,7 @@ public class EmailService
public EmailService(IConfiguration configuration)
{
var cfg = configuration.GetValue<EmailServiceConfiguration>("Email");
var cfg = configuration.GetSection("Email").Get<EmailServiceConfiguration>();
_configuration = cfg ?? throw new ArgumentException("Email service was not configured.");
}

View File

@ -44,7 +44,7 @@ public class MagicSpellService(AppDatabase db, EmailService email, ILogger<Magic
if (contact is null) throw new ArgumentException("Account has no contact method that can use");
// TODO replace the baseurl
var link = $"https://api.sn.solsynth.dev/spells/{spell}";
var link = $"https://api.sn.solsynth.dev/spells/{Uri.EscapeDataString(spell.Spell)}";
try
{
@ -102,6 +102,7 @@ public class MagicSpellService(AppDatabase db, EmailService email, ILogger<Magic
});
}
db.Remove(spell);
await db.SaveChangesAsync();
break;
default:

View File

@ -24,6 +24,12 @@ public class AuthService(IConfiguration config, IHttpClientFactory httpClientFac
var apiSecret = config.GetSection("Captcha")["ApiSecret"];
var client = httpClientFactory.CreateClient();
var jsonOpts = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower,
DictionaryKeyPolicy = JsonNamingPolicy.SnakeCaseLower
};
switch (provider)
{
@ -33,11 +39,11 @@ public class AuthService(IConfiguration config, IHttpClientFactory httpClientFac
var response = await client.PostAsync("https://challenges.cloudflare.com/turnstile/v0/siteverify",
content);
response.EnsureSuccessStatusCode();
var json = await response.Content.ReadAsStringAsync();
var cfResult = JsonSerializer.Deserialize<CloudflareVerificationResponse>(json);
var result = JsonSerializer.Deserialize<CaptchaVerificationResponse>(json, options: jsonOpts);
return cfResult?.Success == true;
return result?.Success == true;
case "google":
content = new StringContent($"secret={apiSecret}&response={token}", System.Text.Encoding.UTF8,
"application/x-www-form-urlencoded");
@ -45,9 +51,19 @@ public class AuthService(IConfiguration config, IHttpClientFactory httpClientFac
response.EnsureSuccessStatusCode();
json = await response.Content.ReadAsStringAsync();
var capResult = JsonSerializer.Deserialize<GoogleVerificationResponse>(json);
result = JsonSerializer.Deserialize<CaptchaVerificationResponse>(json, options: jsonOpts);
return capResult?.Success == true;
return result?.Success == true;
case "hcaptcha":
content = new StringContent($"secret={apiSecret}&response={token}", System.Text.Encoding.UTF8,
"application/x-www-form-urlencoded");
response = await client.PostAsync("https://hcaptcha.com/siteverify", content);
response.EnsureSuccessStatusCode();
json = await response.Content.ReadAsStringAsync();
result = JsonSerializer.Deserialize<CaptchaVerificationResponse>(json, options: jsonOpts);
return result?.Success == true;
default:
throw new ArgumentException("The server misconfigured for the captcha.");
}

View File

@ -1,17 +1,6 @@
namespace DysonNetwork.Sphere.Auth;
public class CloudflareVerificationResponse
public class CaptchaVerificationResponse
{
public bool Success { get; set; }
public string[]? ErrorCodes { get; set; }
}
public class GoogleVerificationResponse
{
public bool Success { get; set; }
public float Score { get; set; }
public string Action { get; set; }
public DateTime ChallengeTs { get; set; }
public string Hostname { get; set; }
public string[]? ErrorCodes { get; set; }
}

View File

@ -1,5 +1,5 @@
@page "/auth/captcha"
@model DysonNetwork.Sphere.Pages.CheckpointPage
@model DysonNetwork.Sphere.Pages.Checkpoint.CheckpointPage
@{
Layout = null;
@ -73,6 +73,9 @@
defer
></script>
break;
case "hcaptcha":
<script src="https://js.hcaptcha.com/1/api.js" async defer></script>
break;
}
</head>
<body>
@ -95,6 +98,13 @@
data-callback="onSuccess"
></div>
break;
case "hcaptcha":
<div
class="h-captcha"
data-sitekey="@apiKey"
data-callback="onSuccess"
></div>
break;
default:
<p style="color: yellow;">Captcha provider not configured correctly.</p>
break;

View File

@ -1,13 +1,14 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace DysonNetwork.Sphere.Pages;
namespace DysonNetwork.Sphere.Pages.Checkpoint;
public class CheckpointPage(IConfiguration configuration) : PageModel
{
[BindProperty] public IConfiguration Configuration { get; set; } = configuration;
public void OnGet()
public ActionResult OnGet()
{
return Page();
}
}

View File

@ -1,6 +1,6 @@
@page "/spells/{spellWord}"
@using DysonNetwork.Sphere.Account
@model DysonNetwork.Sphere.Pages.MagicSpellPage
@model DysonNetwork.Sphere.Pages.Spell.MagicSpellPage
@{
Layout = null;
@ -8,8 +8,6 @@
var spell = ViewData["Spell"] as MagicSpell;
}
<!DOCTYPE html>
<!DOCTYPE html>
<html lang="en">
<head>
@ -57,10 +55,6 @@
margin-bottom: 5px;
opacity: 0.8;
}
.g-recaptcha {
display: inline-block; /* Adjust as needed */
}
</style>
</head>
<body>

View File

@ -4,21 +4,27 @@ using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using NodaTime;
namespace DysonNetwork.Sphere.Pages;
namespace DysonNetwork.Sphere.Pages.Spell;
public class MagicSpellPage(AppDatabase db, MagicSpellService spells) : PageModel
{
public async Task<ActionResult> OnGet(string spellWord)
public async Task<IActionResult> OnGetAsync(string spellWord)
{
spellWord = Uri.UnescapeDataString(spellWord);
var now = SystemClock.Instance.GetCurrentInstant();
var spell = await db.MagicSpells
.Where(e => e.Spell == spellWord)
.Where(e => e.ExpiresAt == null || now >= e.ExpiresAt)
.Where(e => e.ExpiresAt == null || now < e.ExpiresAt)
.Where(e => e.AffectedAt == null || now >= e.AffectedAt)
.FirstOrDefaultAsync();
ViewData["Spell"] = spell;
if (spell is not null)
{
await spells.ApplyMagicSpell(spell);
}
return Page();
}
}

View File

@ -45,8 +45,8 @@
]
},
"Captcha": {
"Provider": "recaptcha",
"ApiKey": "6LfIzSArAAAAAN413MtycDcPlKa636knBSAhbzj-",
"Provider": "cloudflare",
"ApiKey": "0x4AAAAAABCDUdOujj4feOb_",
"ApiSecret": ""
},
"Notifications": {
@ -62,12 +62,12 @@
}
},
"Email": {
"Server": "",
"Server": "smtpdm.aliyun.com",
"Port": 465,
"Username": "",
"Username": "no-reply@mail.solsynth.dev",
"Password": "",
"FromAddress": "",
"FromName": "",
"FromAddress": "no-reply@mail.solsynth.dev",
"FromName": "Alphabot",
"SubjectPrefix": "Solar Network"
}
}