2022-11-25 02:42:55 +01:00
|
|
|
#nullable enable
|
|
|
|
using System;
|
|
|
|
using BTCPayServer.Abstractions.Constants;
|
|
|
|
using BTCPayServer.Abstractions.Form;
|
|
|
|
using BTCPayServer.Client;
|
|
|
|
using BTCPayServer.Controllers;
|
|
|
|
using BTCPayServer.Data.Data;
|
|
|
|
using BTCPayServer.Forms.Models;
|
|
|
|
using BTCPayServer.Models;
|
|
|
|
using BTCPayServer.Services.Stores;
|
|
|
|
using Microsoft.AspNetCore.Authorization;
|
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
|
|
|
|
namespace BTCPayServer.Forms;
|
|
|
|
|
|
|
|
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
|
|
|
|
public class UIFormsController : Controller
|
|
|
|
{
|
2022-11-26 05:01:00 +01:00
|
|
|
private FormComponentProviders FormProviders { get; }
|
2022-11-25 18:14:33 +09:00
|
|
|
|
|
|
|
public UIFormsController(FormComponentProviders formProviders)
|
|
|
|
{
|
|
|
|
FormProviders = formProviders;
|
|
|
|
}
|
2022-11-25 19:28:46 +09:00
|
|
|
|
2022-11-25 02:42:55 +01:00
|
|
|
[AllowAnonymous]
|
|
|
|
[HttpGet("~/forms/{formId}")]
|
|
|
|
[HttpPost("~/forms")]
|
|
|
|
public IActionResult ViewPublicForm(string? formId, string? redirectUrl)
|
|
|
|
{
|
2022-11-25 19:28:46 +09:00
|
|
|
if (!IsValidRedirectUri(redirectUrl))
|
|
|
|
return BadRequest();
|
2023-01-06 14:18:07 +01:00
|
|
|
|
2022-11-25 02:42:55 +01:00
|
|
|
FormData? formData = string.IsNullOrEmpty(formId) ? null : GetFormData(formId);
|
|
|
|
if (formData == null)
|
|
|
|
{
|
|
|
|
return string.IsNullOrEmpty(redirectUrl)
|
|
|
|
? NotFound()
|
|
|
|
: Redirect(redirectUrl);
|
|
|
|
}
|
2023-01-06 14:18:07 +01:00
|
|
|
|
2022-11-25 18:14:33 +09:00
|
|
|
return GetFormView(formData, redirectUrl);
|
2022-11-25 02:42:55 +01:00
|
|
|
}
|
|
|
|
|
2022-11-25 18:14:33 +09:00
|
|
|
ViewResult GetFormView(FormData formData, string? redirectUrl)
|
|
|
|
{
|
2022-11-26 05:01:00 +01:00
|
|
|
return View("View", new FormViewModel { FormData = formData, RedirectUrl = redirectUrl });
|
2022-11-25 18:14:33 +09:00
|
|
|
}
|
2022-11-25 02:42:55 +01:00
|
|
|
[AllowAnonymous]
|
|
|
|
[HttpPost("~/forms/{formId}")]
|
2022-11-26 05:01:00 +01:00
|
|
|
public IActionResult SubmitForm(string formId, string? redirectUrl, string? command)
|
2022-11-25 02:42:55 +01:00
|
|
|
{
|
2022-11-25 19:28:46 +09:00
|
|
|
if (!IsValidRedirectUri(redirectUrl))
|
|
|
|
return BadRequest();
|
2023-01-06 14:18:07 +01:00
|
|
|
|
2022-11-25 02:42:55 +01:00
|
|
|
var formData = GetFormData(formId);
|
|
|
|
if (formData?.Config is null)
|
|
|
|
return NotFound();
|
2023-01-06 14:18:07 +01:00
|
|
|
|
2022-11-28 20:50:09 +09:00
|
|
|
if (!Request.HasFormContentType)
|
2022-11-25 18:14:33 +09:00
|
|
|
return GetFormView(formData, redirectUrl);
|
|
|
|
|
2022-11-25 16:11:13 +09:00
|
|
|
var conf = Form.Parse(formData.Config);
|
|
|
|
conf.ApplyValuesFromForm(Request.Form);
|
2022-11-25 18:14:33 +09:00
|
|
|
if (!FormProviders.Validate(conf, ModelState))
|
|
|
|
return GetFormView(formData, redirectUrl);
|
2022-11-25 02:42:55 +01:00
|
|
|
|
2022-11-25 16:11:13 +09:00
|
|
|
var form = new MultiValueDictionary<string, string>();
|
|
|
|
foreach (var kv in Request.Form)
|
|
|
|
form.Add(kv.Key, kv.Value);
|
2023-01-06 14:18:07 +01:00
|
|
|
|
2022-11-25 02:42:55 +01:00
|
|
|
// With redirect, the form comes from another entity that we need to send the data back to
|
|
|
|
if (!string.IsNullOrEmpty(redirectUrl))
|
|
|
|
{
|
|
|
|
return View("PostRedirect", new PostRedirectViewModel
|
|
|
|
{
|
|
|
|
FormUrl = redirectUrl,
|
2022-11-25 16:11:13 +09:00
|
|
|
FormParameters = form
|
2022-11-25 02:42:55 +01:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
return NotFound();
|
|
|
|
}
|
|
|
|
|
2022-11-25 16:11:13 +09:00
|
|
|
internal static FormData? GetFormData(string id)
|
2022-11-25 02:42:55 +01:00
|
|
|
{
|
|
|
|
FormData? form = id switch
|
|
|
|
{
|
|
|
|
{ } formId when formId == GenericFormOption.Address.ToString() => new FormData
|
|
|
|
{
|
|
|
|
Config = FormDataService.StaticFormAddress.ToString(),
|
|
|
|
Id = GenericFormOption.Address.ToString(),
|
|
|
|
Name = "Provide your address",
|
|
|
|
},
|
|
|
|
{ } formId when formId == GenericFormOption.Email.ToString() => new FormData
|
|
|
|
{
|
|
|
|
Config = FormDataService.StaticFormEmail.ToString(),
|
|
|
|
Id = GenericFormOption.Email.ToString(),
|
|
|
|
Name = "Provide your email address",
|
|
|
|
},
|
|
|
|
_ => null
|
|
|
|
};
|
|
|
|
return form;
|
|
|
|
}
|
2023-01-06 14:18:07 +01:00
|
|
|
|
2022-11-26 05:01:00 +01:00
|
|
|
private bool IsValidRedirectUri(string? redirectUrl) =>
|
|
|
|
!string.IsNullOrEmpty(redirectUrl) && Uri.TryCreate(redirectUrl, UriKind.RelativeOrAbsolute, out var uri) &&
|
|
|
|
(Url.IsLocalUrl(redirectUrl) || uri.Host.Equals(Request.Host.Host));
|
2022-11-25 02:42:55 +01:00
|
|
|
}
|