🐛 Fix magic spell and email service
This commit is contained in:
parent
0ebeab672b
commit
35792efa9f
@ -20,7 +20,7 @@ public class EmailService
|
|||||||
|
|
||||||
public EmailService(IConfiguration configuration)
|
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.");
|
_configuration = cfg ?? throw new ArgumentException("Email service was not configured.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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");
|
if (contact is null) throw new ArgumentException("Account has no contact method that can use");
|
||||||
|
|
||||||
// TODO replace the baseurl
|
// 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
|
try
|
||||||
{
|
{
|
||||||
@ -102,6 +102,7 @@ public class MagicSpellService(AppDatabase db, EmailService email, ILogger<Magic
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
db.Remove(spell);
|
||||||
await db.SaveChangesAsync();
|
await db.SaveChangesAsync();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -25,6 +25,12 @@ public class AuthService(IConfiguration config, IHttpClientFactory httpClientFac
|
|||||||
|
|
||||||
var client = httpClientFactory.CreateClient();
|
var client = httpClientFactory.CreateClient();
|
||||||
|
|
||||||
|
var jsonOpts = new JsonSerializerOptions
|
||||||
|
{
|
||||||
|
PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower,
|
||||||
|
DictionaryKeyPolicy = JsonNamingPolicy.SnakeCaseLower
|
||||||
|
};
|
||||||
|
|
||||||
switch (provider)
|
switch (provider)
|
||||||
{
|
{
|
||||||
case "cloudflare":
|
case "cloudflare":
|
||||||
@ -35,9 +41,9 @@ public class AuthService(IConfiguration config, IHttpClientFactory httpClientFac
|
|||||||
response.EnsureSuccessStatusCode();
|
response.EnsureSuccessStatusCode();
|
||||||
|
|
||||||
var json = await response.Content.ReadAsStringAsync();
|
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":
|
case "google":
|
||||||
content = new StringContent($"secret={apiSecret}&response={token}", System.Text.Encoding.UTF8,
|
content = new StringContent($"secret={apiSecret}&response={token}", System.Text.Encoding.UTF8,
|
||||||
"application/x-www-form-urlencoded");
|
"application/x-www-form-urlencoded");
|
||||||
@ -45,9 +51,19 @@ public class AuthService(IConfiguration config, IHttpClientFactory httpClientFac
|
|||||||
response.EnsureSuccessStatusCode();
|
response.EnsureSuccessStatusCode();
|
||||||
|
|
||||||
json = await response.Content.ReadAsStringAsync();
|
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:
|
default:
|
||||||
throw new ArgumentException("The server misconfigured for the captcha.");
|
throw new ArgumentException("The server misconfigured for the captcha.");
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
namespace DysonNetwork.Sphere.Auth;
|
namespace DysonNetwork.Sphere.Auth;
|
||||||
|
|
||||||
public class CloudflareVerificationResponse
|
public class CaptchaVerificationResponse
|
||||||
{
|
{
|
||||||
public bool Success { get; set; }
|
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; }
|
|
||||||
}
|
}
|
@ -1,5 +1,5 @@
|
|||||||
@page "/auth/captcha"
|
@page "/auth/captcha"
|
||||||
@model DysonNetwork.Sphere.Pages.CheckpointPage
|
@model DysonNetwork.Sphere.Pages.Checkpoint.CheckpointPage
|
||||||
|
|
||||||
@{
|
@{
|
||||||
Layout = null;
|
Layout = null;
|
||||||
@ -73,6 +73,9 @@
|
|||||||
defer
|
defer
|
||||||
></script>
|
></script>
|
||||||
break;
|
break;
|
||||||
|
case "hcaptcha":
|
||||||
|
<script src="https://js.hcaptcha.com/1/api.js" async defer></script>
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@ -95,6 +98,13 @@
|
|||||||
data-callback="onSuccess"
|
data-callback="onSuccess"
|
||||||
></div>
|
></div>
|
||||||
break;
|
break;
|
||||||
|
case "hcaptcha":
|
||||||
|
<div
|
||||||
|
class="h-captcha"
|
||||||
|
data-sitekey="@apiKey"
|
||||||
|
data-callback="onSuccess"
|
||||||
|
></div>
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
<p style="color: yellow;">Captcha provider not configured correctly.</p>
|
<p style="color: yellow;">Captcha provider not configured correctly.</p>
|
||||||
break;
|
break;
|
@ -1,13 +1,14 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
|
||||||
namespace DysonNetwork.Sphere.Pages;
|
namespace DysonNetwork.Sphere.Pages.Checkpoint;
|
||||||
|
|
||||||
public class CheckpointPage(IConfiguration configuration) : PageModel
|
public class CheckpointPage(IConfiguration configuration) : PageModel
|
||||||
{
|
{
|
||||||
[BindProperty] public IConfiguration Configuration { get; set; } = configuration;
|
[BindProperty] public IConfiguration Configuration { get; set; } = configuration;
|
||||||
|
|
||||||
public void OnGet()
|
public ActionResult OnGet()
|
||||||
{
|
{
|
||||||
|
return Page();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,6 +1,6 @@
|
|||||||
@page "/spells/{spellWord}"
|
@page "/spells/{spellWord}"
|
||||||
@using DysonNetwork.Sphere.Account
|
@using DysonNetwork.Sphere.Account
|
||||||
@model DysonNetwork.Sphere.Pages.MagicSpellPage
|
@model DysonNetwork.Sphere.Pages.Spell.MagicSpellPage
|
||||||
|
|
||||||
@{
|
@{
|
||||||
Layout = null;
|
Layout = null;
|
||||||
@ -8,8 +8,6 @@
|
|||||||
var spell = ViewData["Spell"] as MagicSpell;
|
var spell = ViewData["Spell"] as MagicSpell;
|
||||||
}
|
}
|
||||||
|
|
||||||
<!DOCTYPE html>
|
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
@ -57,10 +55,6 @@
|
|||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
|
|
||||||
.g-recaptcha {
|
|
||||||
display: inline-block; /* Adjust as needed */
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
@ -4,21 +4,27 @@ using Microsoft.AspNetCore.Mvc.RazorPages;
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using NodaTime;
|
using NodaTime;
|
||||||
|
|
||||||
namespace DysonNetwork.Sphere.Pages;
|
namespace DysonNetwork.Sphere.Pages.Spell;
|
||||||
|
|
||||||
public class MagicSpellPage(AppDatabase db, MagicSpellService spells) : PageModel
|
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 now = SystemClock.Instance.GetCurrentInstant();
|
||||||
var spell = await db.MagicSpells
|
var spell = await db.MagicSpells
|
||||||
.Where(e => e.Spell == spellWord)
|
.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)
|
.Where(e => e.AffectedAt == null || now >= e.AffectedAt)
|
||||||
.FirstOrDefaultAsync();
|
.FirstOrDefaultAsync();
|
||||||
|
|
||||||
ViewData["Spell"] = spell;
|
ViewData["Spell"] = spell;
|
||||||
|
|
||||||
|
if (spell is not null)
|
||||||
|
{
|
||||||
|
await spells.ApplyMagicSpell(spell);
|
||||||
|
}
|
||||||
|
|
||||||
return Page();
|
return Page();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -45,8 +45,8 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"Captcha": {
|
"Captcha": {
|
||||||
"Provider": "recaptcha",
|
"Provider": "cloudflare",
|
||||||
"ApiKey": "6LfIzSArAAAAAN413MtycDcPlKa636knBSAhbzj-",
|
"ApiKey": "0x4AAAAAABCDUdOujj4feOb_",
|
||||||
"ApiSecret": ""
|
"ApiSecret": ""
|
||||||
},
|
},
|
||||||
"Notifications": {
|
"Notifications": {
|
||||||
@ -62,12 +62,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Email": {
|
"Email": {
|
||||||
"Server": "",
|
"Server": "smtpdm.aliyun.com",
|
||||||
"Port": 465,
|
"Port": 465,
|
||||||
"Username": "",
|
"Username": "no-reply@mail.solsynth.dev",
|
||||||
"Password": "",
|
"Password": "",
|
||||||
"FromAddress": "",
|
"FromAddress": "no-reply@mail.solsynth.dev",
|
||||||
"FromName": "",
|
"FromName": "Alphabot",
|
||||||
"SubjectPrefix": "Solar Network"
|
"SubjectPrefix": "Solar Network"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIntentType_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F8bb08a178b5b43c5bac20a5a54159a5b2a800_003Fbf_003Ffcb84131_003FIntentType_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIntentType_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F8bb08a178b5b43c5bac20a5a54159a5b2a800_003Fbf_003Ffcb84131_003FIntentType_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIServiceCollectionQuartzConfigurator_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F1edbd6e24d7b430fabce72177269baa19200_003F67_003Faee36f5b_003FIServiceCollectionQuartzConfigurator_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIServiceCollectionQuartzConfigurator_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F1edbd6e24d7b430fabce72177269baa19200_003F67_003Faee36f5b_003FIServiceCollectionQuartzConfigurator_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AITusStore_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F8bb08a178b5b43c5bac20a5a54159a5b2a800_003Fb1_003F7e861de5_003FITusStore_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AITusStore_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F8bb08a178b5b43c5bac20a5a54159a5b2a800_003Fb1_003F7e861de5_003FITusStore_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AJsonSerializerOptions_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F5703920a18f94462b4354fab05326e6519a200_003F35_003F8536fc49_003FJsonSerializerOptions_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AKestrelServerLimits_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F1e2e5dfcafad4407b569dd5df56a2fbf274e00_003Fa4_003F39445f62_003FKestrelServerLimits_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AKestrelServerLimits_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F1e2e5dfcafad4407b569dd5df56a2fbf274e00_003Fa4_003F39445f62_003FKestrelServerLimits_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AMailboxAddress_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F8e03e47c46b7469f97abc40667cbcf9b133000_003Fa6_003F83324248_003FMailboxAddress_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AMailboxAddress_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F8e03e47c46b7469f97abc40667cbcf9b133000_003Fa6_003F83324248_003FMailboxAddress_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AMediaAnalysis_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Ffef366b36a224d469ff150d30f9a866d23c00_003Fd7_003F5c138865_003FMediaAnalysis_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AMediaAnalysis_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Ffef366b36a224d469ff150d30f9a866d23c00_003Fd7_003F5c138865_003FMediaAnalysis_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user