feat(settings): validate BaseUrl + cron on save, add BaseUrl hint
- Reject a non-absolute / non-http(s) BaseUrl and an implausible (not 5- or 6-field) cron expression before the section is written to disk, mirroring the existing storage-path validation (snackbar + early return). - Add a hint to the BaseUrl field. Cron check is a lightweight UI guard; the worker still does the authoritative Cronos parse at startup.
This commit is contained in:
@@ -49,7 +49,7 @@
|
|||||||
<Field Label="@L["Settings.Scraping.RetryBaseDelayMs"]">
|
<Field Label="@L["Settings.Scraping.RetryBaseDelayMs"]">
|
||||||
<MudNumericField T="int" @bind-Value="_scraping.RetryPolicy.BaseDelayMs" Min="100" Max="60000" Variant="Variant.Outlined" />
|
<MudNumericField T="int" @bind-Value="_scraping.RetryPolicy.BaseDelayMs" Min="100" Max="60000" Variant="Variant.Outlined" />
|
||||||
</Field>
|
</Field>
|
||||||
<Field Label="@L["Settings.Scraping.BaseUrl"]">
|
<Field Label="@L["Settings.Scraping.BaseUrl"]" Hint="@L["Settings.Scraping.BaseUrl.Hint"]">
|
||||||
<MudTextField T="string" @bind-Value="_scraping.BaseUrl" Variant="Variant.Outlined" />
|
<MudTextField T="string" @bind-Value="_scraping.BaseUrl" Variant="Variant.Outlined" />
|
||||||
</Field>
|
</Field>
|
||||||
<Field Label="@L["Settings.Scraping.RequestTimeoutSeconds"]">
|
<Field Label="@L["Settings.Scraping.RequestTimeoutSeconds"]">
|
||||||
@@ -242,6 +242,20 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (payload is ScrapingSettingsForm scraping
|
||||||
|
&& !(Uri.TryCreate(scraping.BaseUrl, UriKind.Absolute, out var baseUri)
|
||||||
|
&& (baseUri.Scheme == Uri.UriSchemeHttp || baseUri.Scheme == Uri.UriSchemeHttps)))
|
||||||
|
{
|
||||||
|
Snackbar.Add(L["Settings.Scraping.BaseUrl.Invalid"], Severity.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (payload is WorkerOptions workers && !IsPlausibleCron(workers.UpcomingScheduleCron))
|
||||||
|
{
|
||||||
|
Snackbar.Add(L["Settings.Workers.Cron.Invalid"], Severity.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var confirmed = await ConfirmAsync();
|
var confirmed = await ConfirmAsync();
|
||||||
if (!confirmed)
|
if (!confirmed)
|
||||||
{
|
{
|
||||||
@@ -260,6 +274,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Lightweight 5- or 6-field cron sanity check — avoids a Cronos dependency in the
|
||||||
|
// UI layer; the worker still does the authoritative parse at startup.
|
||||||
|
private static bool IsPlausibleCron(string? expression)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(expression)) return false;
|
||||||
|
var fields = expression.Split(' ', StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
return fields.Length is 5 or 6;
|
||||||
|
}
|
||||||
|
|
||||||
private async Task ResetSectionAsync(string section)
|
private async Task ResetSectionAsync(string section)
|
||||||
{
|
{
|
||||||
var confirmed = await ConfirmAsync();
|
var confirmed = await ConfirmAsync();
|
||||||
|
|||||||
Reference in New Issue
Block a user