mirror of
https://github.com/bitwarden/server.git
synced 2025-04-15 18:18:12 -05:00
respect return url on sign in link
This commit is contained in:
parent
ff9f605b7d
commit
14039d7d1a
@ -16,9 +16,12 @@ namespace Bit.Admin.Controllers
|
|||||||
_signInManager = signInManager;
|
_signInManager = signInManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IActionResult Index()
|
public IActionResult Index(string returnUrl = null)
|
||||||
{
|
{
|
||||||
return View();
|
return View(new LoginModel
|
||||||
|
{
|
||||||
|
ReturnUrl = returnUrl
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
@ -28,19 +31,25 @@ namespace Bit.Admin.Controllers
|
|||||||
if(ModelState.IsValid)
|
if(ModelState.IsValid)
|
||||||
{
|
{
|
||||||
await _signInManager.PasswordlessSignInAsync(model.Email,
|
await _signInManager.PasswordlessSignInAsync(model.Email,
|
||||||
Url.Action("Confirm", "Login", null, Request.Scheme));
|
Url.Action("Confirm", "Login", new { returnUrl = model.ReturnUrl }, Request.Scheme));
|
||||||
return RedirectToAction("Index", "Home");
|
return RedirectToAction("Index", "Home");
|
||||||
}
|
}
|
||||||
|
|
||||||
return View(model);
|
return View(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IActionResult> Confirm(string email, string token)
|
public async Task<IActionResult> Confirm(string email, string token, string returnUrl)
|
||||||
{
|
{
|
||||||
var result = await _signInManager.PasswordlessSignInAsync(email, token, false);
|
var result = await _signInManager.PasswordlessSignInAsync(email, token, false);
|
||||||
if(!result.Succeeded)
|
if(!result.Succeeded)
|
||||||
{
|
{
|
||||||
return View("Error");
|
// TODO: error?
|
||||||
|
return RedirectToAction("Index");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!string.IsNullOrWhiteSpace(returnUrl) && Url.IsLocalUrl(returnUrl))
|
||||||
|
{
|
||||||
|
return Redirect(returnUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
return RedirectToAction("Index", "Home");
|
return RedirectToAction("Index", "Home");
|
||||||
|
@ -7,5 +7,6 @@ namespace Bit.Admin.Models
|
|||||||
[Required]
|
[Required]
|
||||||
[EmailAddress]
|
[EmailAddress]
|
||||||
public string Email { get; set; }
|
public string Email { get; set; }
|
||||||
|
public string ReturnUrl { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<p>Please enter your email address below to log in.</p>
|
<p>Please enter your email address below to log in.</p>
|
||||||
<form asp-action="" method="post">
|
<form asp-action="" method="post">
|
||||||
|
<input type="hidden" asp-for="ReturnUrl" />
|
||||||
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
|
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label asp-for="Email" class="sr-only">Email Address</label>
|
<label asp-for="Email" class="sr-only">Email Address</label>
|
||||||
|
@ -6,6 +6,7 @@ using Bit.Core.Models.Mail;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using Bit.Core.Utilities;
|
||||||
|
|
||||||
namespace Bit.Core.Services
|
namespace Bit.Core.Services
|
||||||
{
|
{
|
||||||
@ -172,10 +173,14 @@ namespace Bit.Core.Services
|
|||||||
|
|
||||||
public async Task SendPasswordlessSignInAsync(string baseUrl, string token, string email)
|
public async Task SendPasswordlessSignInAsync(string baseUrl, string token, string email)
|
||||||
{
|
{
|
||||||
|
var url = CoreHelpers.ExtendQuery(new Uri(baseUrl), new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
["email"] = email,
|
||||||
|
["token"] = token,
|
||||||
|
});
|
||||||
var model = new Dictionary<string, string>
|
var model = new Dictionary<string, string>
|
||||||
{
|
{
|
||||||
["url"] = string.Format("{0}?email={1}&token={2}", baseUrl, WebUtility.UrlEncode(email),
|
["url"] = url.ToString()
|
||||||
WebUtility.UrlEncode(token))
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var message = await CreateMessageAsync("Continue Logging In", email, "PasswordlessSignIn", model);
|
var message = await CreateMessageAsync("Continue Logging In", email, "PasswordlessSignIn", model);
|
||||||
|
@ -206,10 +206,15 @@ namespace Bit.Core.Services
|
|||||||
public async Task SendPasswordlessSignInAsync(string baseUrl, string token, string email)
|
public async Task SendPasswordlessSignInAsync(string baseUrl, string token, string email)
|
||||||
{
|
{
|
||||||
var message = CreateDefaultMessage("Continue Logging In", email);
|
var message = CreateDefaultMessage("Continue Logging In", email);
|
||||||
|
|
||||||
|
var url = CoreHelpers.ExtendQuery(new Uri(baseUrl), new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
["email"] = email,
|
||||||
|
["token"] = token,
|
||||||
|
});
|
||||||
var model = new PasswordlessSignInModel
|
var model = new PasswordlessSignInModel
|
||||||
{
|
{
|
||||||
Url = string.Format("{0}?email={1}&token={2}", baseUrl, WebUtility.UrlEncode(email),
|
Url = url.ToString()
|
||||||
WebUtility.UrlEncode(token))
|
|
||||||
};
|
};
|
||||||
message.HtmlContent = await _engine.CompileRenderAsync("PasswordlessSignIn", model);
|
message.HtmlContent = await _engine.CompileRenderAsync("PasswordlessSignIn", model);
|
||||||
message.TextContent = await _engine.CompileRenderAsync("PasswordlessSignIn.text", model);
|
message.TextContent = await _engine.CompileRenderAsync("PasswordlessSignIn.text", model);
|
||||||
|
@ -12,6 +12,7 @@ using System.Text;
|
|||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Dapper;
|
using Dapper;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using System.Web;
|
||||||
|
|
||||||
namespace Bit.Core.Utilities
|
namespace Bit.Core.Utilities
|
||||||
{
|
{
|
||||||
@ -425,5 +426,31 @@ namespace Bit.Core.Utilities
|
|||||||
|
|
||||||
return _max.Subtract(date.Value).TotalMilliseconds.ToString(CultureInfo.InvariantCulture);
|
return _max.Subtract(date.Value).TotalMilliseconds.ToString(CultureInfo.InvariantCulture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ref: https://stackoverflow.com/a/27545010/1090359
|
||||||
|
public static Uri ExtendQuery(Uri uri, IDictionary<string, string> values)
|
||||||
|
{
|
||||||
|
var baseUri = uri.ToString();
|
||||||
|
var queryString = string.Empty;
|
||||||
|
if(baseUri.Contains("?"))
|
||||||
|
{
|
||||||
|
var urlSplit = baseUri.Split('?');
|
||||||
|
baseUri = urlSplit[0];
|
||||||
|
queryString = urlSplit.Length > 1 ? urlSplit[1] : string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
var queryCollection = HttpUtility.ParseQueryString(queryString);
|
||||||
|
foreach(var kvp in values ?? new Dictionary<string, string>())
|
||||||
|
{
|
||||||
|
queryCollection[kvp.Key] = kvp.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
var uriKind = uri.IsAbsoluteUri ? UriKind.Absolute : UriKind.Relative;
|
||||||
|
if(queryCollection.Count == 0)
|
||||||
|
{
|
||||||
|
return new Uri(baseUri, uriKind);
|
||||||
|
}
|
||||||
|
return new Uri(string.Format("{0}?{1}", baseUri, queryCollection), uriKind);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user