mirror of
https://git.teknik.io/Teknikode/Teknik.git
synced 2023-08-02 14:16:22 +02:00
Added trusted device support for Two Factor authentication.
This commit is contained in:
parent
011e737846
commit
000f977dfe
@ -4,6 +4,7 @@ using System.Linq;
|
|||||||
using System.Web;
|
using System.Web;
|
||||||
using System.Web.Mvc;
|
using System.Web.Mvc;
|
||||||
using System.Web.Routing;
|
using System.Web.Routing;
|
||||||
|
using Teknik.Helpers;
|
||||||
|
|
||||||
namespace Teknik
|
namespace Teknik
|
||||||
{
|
{
|
||||||
|
@ -4,6 +4,7 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Teknik.Areas.Shortener.Models;
|
using Teknik.Areas.Shortener.Models;
|
||||||
|
using Teknik.Helpers;
|
||||||
using Teknik.Models;
|
using Teknik.Models;
|
||||||
|
|
||||||
namespace Teknik.Areas.Shortener
|
namespace Teknik.Areas.Shortener
|
||||||
|
@ -5,6 +5,7 @@ using System.Web;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using Teknik.Configuration;
|
using Teknik.Configuration;
|
||||||
using Teknik.Models;
|
using Teknik.Models;
|
||||||
|
using Teknik.Helpers;
|
||||||
|
|
||||||
namespace Teknik.Areas.Upload
|
namespace Teknik.Areas.Upload
|
||||||
{
|
{
|
||||||
|
@ -23,6 +23,7 @@ using Teknik.Filters;
|
|||||||
using QRCoder;
|
using QRCoder;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using TwoStepsAuthenticator;
|
using TwoStepsAuthenticator;
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
namespace Teknik.Areas.Users.Controllers
|
namespace Teknik.Areas.Users.Controllers
|
||||||
{
|
{
|
||||||
@ -167,10 +168,30 @@ namespace Teknik.Areas.Users.Controllers
|
|||||||
bool userValid = UserHelper.UserPasswordCorrect(db, Config, user, model.Password);
|
bool userValid = UserHelper.UserPasswordCorrect(db, Config, user, model.Password);
|
||||||
if (userValid)
|
if (userValid)
|
||||||
{
|
{
|
||||||
|
bool twoFactor = false;
|
||||||
string returnUrl = model.ReturnUrl;
|
string returnUrl = model.ReturnUrl;
|
||||||
if (user.SecuritySettings.TwoFactorEnabled)
|
if (user.SecuritySettings.TwoFactorEnabled)
|
||||||
{
|
{
|
||||||
|
twoFactor = true;
|
||||||
// We need to check their device, and two factor them
|
// We need to check their device, and two factor them
|
||||||
|
if (user.SecuritySettings.AllowTrustedDevices)
|
||||||
|
{
|
||||||
|
// Check for the trusted device cookie
|
||||||
|
HttpCookie cookie = Request.Cookies[Constants.TRUSTEDDEVICECOOKIE + "_" + username];
|
||||||
|
if (cookie != null)
|
||||||
|
{
|
||||||
|
string token = cookie.Value;
|
||||||
|
if (user.TrustedDevices.Where(d => d.Token == token).FirstOrDefault() != null)
|
||||||
|
{
|
||||||
|
// The device token is attached to the user, let's let it slide
|
||||||
|
twoFactor = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (twoFactor)
|
||||||
|
{
|
||||||
Session["AuthenticatedUser"] = user;
|
Session["AuthenticatedUser"] = user;
|
||||||
if (string.IsNullOrEmpty(model.ReturnUrl))
|
if (string.IsNullOrEmpty(model.ReturnUrl))
|
||||||
returnUrl = Request.UrlReferrer.AbsoluteUri.ToString();
|
returnUrl = Request.UrlReferrer.AbsoluteUri.ToString();
|
||||||
@ -295,7 +316,7 @@ namespace Teknik.Areas.Users.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public ActionResult Edit(string curPass, string newPass, string newPassConfirm, string pgpPublicKey, string recoveryEmail, bool twoFactorEnabled, string website, string quote, string about, string blogTitle, string blogDesc, bool saveKey, bool serverSideEncrypt)
|
public ActionResult Edit(string curPass, string newPass, string newPassConfirm, string pgpPublicKey, string recoveryEmail, bool allowTrustedDevices, bool twoFactorEnabled, string website, string quote, string about, string blogTitle, string blogDesc, bool saveKey, bool serverSideEncrypt)
|
||||||
{
|
{
|
||||||
if (ModelState.IsValid)
|
if (ModelState.IsValid)
|
||||||
{
|
{
|
||||||
@ -329,6 +350,7 @@ namespace Teknik.Areas.Users.Controllers
|
|||||||
}
|
}
|
||||||
user.SecuritySettings.PGPSignature = pgpPublicKey;
|
user.SecuritySettings.PGPSignature = pgpPublicKey;
|
||||||
|
|
||||||
|
// Recovery Email
|
||||||
bool newRecovery = false;
|
bool newRecovery = false;
|
||||||
if (recoveryEmail != user.SecuritySettings.RecoveryEmail)
|
if (recoveryEmail != user.SecuritySettings.RecoveryEmail)
|
||||||
{
|
{
|
||||||
@ -337,24 +359,56 @@ namespace Teknik.Areas.Users.Controllers
|
|||||||
user.SecuritySettings.RecoveryVerified = false;
|
user.SecuritySettings.RecoveryVerified = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Trusted Devices
|
||||||
|
user.SecuritySettings.AllowTrustedDevices = allowTrustedDevices;
|
||||||
|
if (!allowTrustedDevices)
|
||||||
|
{
|
||||||
|
// They turned it off, let's clear the trusted devices
|
||||||
|
user.TrustedDevices.Clear();
|
||||||
|
List<TrustedDevice> foundDevices = db.TrustedDevices.Where(d => d.UserId == user.UserId).ToList();
|
||||||
|
if (foundDevices != null)
|
||||||
|
{
|
||||||
|
foreach (TrustedDevice device in foundDevices)
|
||||||
|
{
|
||||||
|
db.TrustedDevices.Remove(device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Two Factor Authentication
|
||||||
bool oldTwoFactor = user.SecuritySettings.TwoFactorEnabled;
|
bool oldTwoFactor = user.SecuritySettings.TwoFactorEnabled;
|
||||||
user.SecuritySettings.TwoFactorEnabled = twoFactorEnabled;
|
user.SecuritySettings.TwoFactorEnabled = twoFactorEnabled;
|
||||||
string newKey = string.Empty;
|
string newKey = string.Empty;
|
||||||
if (twoFactorEnabled)
|
if (!oldTwoFactor && twoFactorEnabled)
|
||||||
{
|
{
|
||||||
|
// They just enabled it, let's regen the key
|
||||||
newKey = Authenticator.GenerateKey();
|
newKey = Authenticator.GenerateKey();
|
||||||
}
|
}
|
||||||
|
else if (!twoFactorEnabled)
|
||||||
|
{
|
||||||
|
// remove the key when it's disabled
|
||||||
|
newKey = string.Empty;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// No change, let's use the old value
|
||||||
|
newKey = user.SecuritySettings.TwoFactorKey;
|
||||||
|
}
|
||||||
user.SecuritySettings.TwoFactorKey = newKey;
|
user.SecuritySettings.TwoFactorKey = newKey;
|
||||||
|
|
||||||
|
// Profile Info
|
||||||
user.UserSettings.Website = website;
|
user.UserSettings.Website = website;
|
||||||
user.UserSettings.Quote = quote;
|
user.UserSettings.Quote = quote;
|
||||||
user.UserSettings.About = about;
|
user.UserSettings.About = about;
|
||||||
|
|
||||||
|
// Blogs
|
||||||
user.BlogSettings.Title = blogTitle;
|
user.BlogSettings.Title = blogTitle;
|
||||||
user.BlogSettings.Description = blogDesc;
|
user.BlogSettings.Description = blogDesc;
|
||||||
|
|
||||||
|
// Uploads
|
||||||
user.UploadSettings.SaveKey = saveKey;
|
user.UploadSettings.SaveKey = saveKey;
|
||||||
user.UploadSettings.ServerSideEncrypt = serverSideEncrypt;
|
user.UploadSettings.ServerSideEncrypt = serverSideEncrypt;
|
||||||
|
|
||||||
UserHelper.EditAccount(db, Config, user, changePass, newPass);
|
UserHelper.EditAccount(db, Config, user, changePass, newPass);
|
||||||
|
|
||||||
// If they have a recovery email, let's send a verification
|
// If they have a recovery email, let's send a verification
|
||||||
@ -556,19 +610,25 @@ namespace Teknik.Areas.Users.Controllers
|
|||||||
[HttpGet]
|
[HttpGet]
|
||||||
[AllowAnonymous]
|
[AllowAnonymous]
|
||||||
public ActionResult ConfirmTwoFactorAuth(string returnUrl, bool rememberMe)
|
public ActionResult ConfirmTwoFactorAuth(string returnUrl, bool rememberMe)
|
||||||
|
{
|
||||||
|
User user = (User)Session["AuthenticatedUser"];
|
||||||
|
if (user != null)
|
||||||
{
|
{
|
||||||
ViewBag.Title = "Unknown Device - " + Config.Title;
|
ViewBag.Title = "Unknown Device - " + Config.Title;
|
||||||
ViewBag.Description = "We do not recognize this device.";
|
ViewBag.Description = "We do not recognize this device.";
|
||||||
LoginViewModel model = new LoginViewModel();
|
TwoFactorViewModel model = new TwoFactorViewModel();
|
||||||
model.ReturnUrl = returnUrl;
|
model.ReturnUrl = returnUrl;
|
||||||
model.RememberMe = rememberMe;
|
model.RememberMe = rememberMe;
|
||||||
|
model.AllowTrustedDevice = user.SecuritySettings.AllowTrustedDevices;
|
||||||
|
|
||||||
return View("/Areas/User/Views/User/TwoFactorCheck.cshtml", model);
|
return View("/Areas/User/Views/User/TwoFactorCheck.cshtml", model);
|
||||||
}
|
}
|
||||||
|
return Redirect(Url.SubRouteUrl("error", "Error.Http403"));
|
||||||
|
}
|
||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[AllowAnonymous]
|
[AllowAnonymous]
|
||||||
public ActionResult ConfirmAuthenticatorCode(string code, string returnUrl, bool rememberMe)
|
public ActionResult ConfirmAuthenticatorCode(string code, string returnUrl, bool rememberMe, bool rememberDevice, string deviceName)
|
||||||
{
|
{
|
||||||
User user = (User)Session["AuthenticatedUser"];
|
User user = (User)Session["AuthenticatedUser"];
|
||||||
if (user != null)
|
if (user != null)
|
||||||
@ -586,6 +646,23 @@ namespace Teknik.Areas.Users.Controllers
|
|||||||
HttpCookie authcookie = UserHelper.CreateAuthCookie(user.Username, rememberMe, Request.Url.Host.GetDomain(), Request.IsLocal);
|
HttpCookie authcookie = UserHelper.CreateAuthCookie(user.Username, rememberMe, Request.Url.Host.GetDomain(), Request.IsLocal);
|
||||||
Response.Cookies.Add(authcookie);
|
Response.Cookies.Add(authcookie);
|
||||||
|
|
||||||
|
if (user.SecuritySettings.AllowTrustedDevices && rememberDevice)
|
||||||
|
{
|
||||||
|
// They want to remember the device, and have allow trusted devices on
|
||||||
|
HttpCookie trustedDeviceCookie = UserHelper.CreateTrustedDeviceCookie(user.Username, Request.Url.Host.GetDomain(), Request.IsLocal);
|
||||||
|
Response.Cookies.Add(trustedDeviceCookie);
|
||||||
|
|
||||||
|
TrustedDevice device = new TrustedDevice();
|
||||||
|
device.UserId = user.UserId;
|
||||||
|
device.Name = (string.IsNullOrEmpty(deviceName)) ? "Unknown" : deviceName;
|
||||||
|
device.DateSeen = DateTime.Now;
|
||||||
|
device.Token = trustedDeviceCookie.Value;
|
||||||
|
|
||||||
|
// Add the token
|
||||||
|
db.TrustedDevices.Add(device);
|
||||||
|
db.SaveChanges();
|
||||||
|
}
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(returnUrl))
|
if (string.IsNullOrEmpty(returnUrl))
|
||||||
returnUrl = Request.UrlReferrer.AbsoluteUri.ToString();
|
returnUrl = Request.UrlReferrer.AbsoluteUri.ToString();
|
||||||
return Json(new { result = returnUrl });
|
return Json(new { result = returnUrl });
|
||||||
@ -628,9 +705,9 @@ namespace Teknik.Areas.Users.Controllers
|
|||||||
|
|
||||||
QRCodeGenerator qrGenerator = new QRCodeGenerator();
|
QRCodeGenerator qrGenerator = new QRCodeGenerator();
|
||||||
QRCodeData qrCodeData = qrGenerator.CreateQrCode(ProvisionUrl, QRCodeGenerator.ECCLevel.Q);
|
QRCodeData qrCodeData = qrGenerator.CreateQrCode(ProvisionUrl, QRCodeGenerator.ECCLevel.Q);
|
||||||
SvgQRCode qrCode = new SvgQRCode(qrCodeData);
|
QRCode qrCode = new QRCode(qrCodeData);
|
||||||
string qrCodeImage = qrCode.GetGraphic(20);
|
Bitmap qrCodeImage = qrCode.GetGraphic(20);
|
||||||
return File(Encoding.UTF8.GetBytes(qrCodeImage), "image/svg+xml");
|
return File(Helpers.Utility.ImageToByte(qrCodeImage), "image/png");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -24,6 +24,8 @@ namespace Teknik.Areas.Users.Models
|
|||||||
|
|
||||||
public bool RecoveryVerified { get; set; }
|
public bool RecoveryVerified { get; set; }
|
||||||
|
|
||||||
|
public bool AllowTrustedDevices { get; set; }
|
||||||
|
|
||||||
public bool TwoFactorEnabled { get; set; }
|
public bool TwoFactorEnabled { get; set; }
|
||||||
|
|
||||||
[CaseSensitive]
|
[CaseSensitive]
|
||||||
@ -35,6 +37,7 @@ namespace Teknik.Areas.Users.Models
|
|||||||
{
|
{
|
||||||
RecoveryEmail = string.Empty;
|
RecoveryEmail = string.Empty;
|
||||||
RecoveryVerified = false;
|
RecoveryVerified = false;
|
||||||
|
AllowTrustedDevices = false;
|
||||||
TwoFactorEnabled = false;
|
TwoFactorEnabled = false;
|
||||||
TwoFactorKey = string.Empty;
|
TwoFactorKey = string.Empty;
|
||||||
PGPSignature = string.Empty;
|
PGPSignature = string.Empty;
|
||||||
|
@ -6,9 +6,9 @@ using Teknik.Attributes;
|
|||||||
|
|
||||||
namespace Teknik.Areas.Users.Models
|
namespace Teknik.Areas.Users.Models
|
||||||
{
|
{
|
||||||
public class UserDevice
|
public class TrustedDevice
|
||||||
{
|
{
|
||||||
public int UserDeviceId { get; set; }
|
public int TrustedDeviceId { get; set; }
|
||||||
|
|
||||||
public int UserId { get; set; }
|
public int UserId { get; set; }
|
||||||
|
|
@ -33,7 +33,7 @@ namespace Teknik.Areas.Users.Models
|
|||||||
|
|
||||||
public virtual UploadSettings UploadSettings { get; set; }
|
public virtual UploadSettings UploadSettings { get; set; }
|
||||||
|
|
||||||
public virtual ICollection<UserDevice> Devices { get; set; }
|
public virtual ICollection<TrustedDevice> TrustedDevices { get; set; }
|
||||||
|
|
||||||
public virtual ICollection<Upload.Models.Upload> Uploads { get; set; }
|
public virtual ICollection<Upload.Models.Upload> Uploads { get; set; }
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ namespace Teknik.Areas.Users.Models
|
|||||||
JoinDate = DateTime.Now;
|
JoinDate = DateTime.Now;
|
||||||
LastSeen = DateTime.Now;
|
LastSeen = DateTime.Now;
|
||||||
Groups = new List<Group>();
|
Groups = new List<Group>();
|
||||||
Devices = new List<UserDevice>();
|
TrustedDevices = new List<TrustedDevice>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,16 +2,18 @@
|
|||||||
$("#authCheckStatus").css('display', 'none', 'important');
|
$("#authCheckStatus").css('display', 'none', 'important');
|
||||||
|
|
||||||
$("#verifyCodeSubmit").click(function () {
|
$("#verifyCodeSubmit").click(function () {
|
||||||
setCode = $("#code").val();
|
setCode = $("#Code").val();
|
||||||
returnUrl = $("#returnUrl").val();
|
returnUrl = $("#ReturnUrl").val();
|
||||||
rememberMe = ($("#rememberMe").val() == 'True');
|
rememberMe = ($("#RememberMe").val() == 'True');
|
||||||
|
rememberDevice = $("#RememberDevice").is(":checked");
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: "POST",
|
type: "POST",
|
||||||
url: confirmAuthCodeURL,
|
url: confirmAuthCodeURL,
|
||||||
data: {
|
data: {
|
||||||
code: setCode,
|
code: setCode,
|
||||||
returnUrl: returnUrl,
|
returnUrl: returnUrl,
|
||||||
rememberMe: rememberMe
|
rememberMe: rememberMe,
|
||||||
|
rememberDevice: rememberDevice
|
||||||
},
|
},
|
||||||
xhrFields: {
|
xhrFields: {
|
||||||
withCredentials: true
|
withCredentials: true
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
$("[name='update_upload_saveKey']").bootstrapSwitch();
|
$("[name='update_upload_saveKey']").bootstrapSwitch();
|
||||||
$("[name='update_upload_serverSideEncrypt']").bootstrapSwitch();
|
$("[name='update_upload_serverSideEncrypt']").bootstrapSwitch();
|
||||||
$("[name='update_security_two_factor']").bootstrapSwitch();
|
$("[name='update_security_two_factor']").bootstrapSwitch();
|
||||||
|
$("[name='update_security_allow_trusted']").bootstrapSwitch();
|
||||||
|
|
||||||
$('#ResendVerification').click(function () {
|
$('#ResendVerification').click(function () {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
@ -98,6 +99,7 @@
|
|||||||
password = $("#update_password").val();
|
password = $("#update_password").val();
|
||||||
password_confirm = $("#update_password_confirm").val();
|
password_confirm = $("#update_password_confirm").val();
|
||||||
update_pgp_public_key = $("#update_pgp_public_key").val();
|
update_pgp_public_key = $("#update_pgp_public_key").val();
|
||||||
|
update_security_allow_trusted = $("#update_security_allow_trusted").is(":checked");
|
||||||
update_security_two_factor = $("#update_security_two_factor").is(":checked");
|
update_security_two_factor = $("#update_security_two_factor").is(":checked");
|
||||||
recovery = $("#update_recovery_email").val();
|
recovery = $("#update_recovery_email").val();
|
||||||
website = $("#update_website").val();
|
website = $("#update_website").val();
|
||||||
@ -115,6 +117,7 @@
|
|||||||
newPass: password,
|
newPass: password,
|
||||||
newPassConfirm: password_confirm,
|
newPassConfirm: password_confirm,
|
||||||
pgpPublicKey: update_pgp_public_key,
|
pgpPublicKey: update_pgp_public_key,
|
||||||
|
allowTrustedDevices: update_security_allow_trusted,
|
||||||
twoFactorEnabled: update_security_two_factor,
|
twoFactorEnabled: update_security_two_factor,
|
||||||
recoveryEmail: recovery,
|
recoveryEmail: recovery,
|
||||||
website: website,
|
website: website,
|
||||||
|
@ -437,7 +437,7 @@ namespace Teknik.Areas.Users.Utility
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a new verification code and add it
|
// Create a new verification code and add it
|
||||||
string verifyCode = Teknik.Utility.RandomString(24);
|
string verifyCode = Helpers.Utility.RandomString(24);
|
||||||
RecoveryEmailVerification ver = new RecoveryEmailVerification();
|
RecoveryEmailVerification ver = new RecoveryEmailVerification();
|
||||||
ver.UserId = user.UserId;
|
ver.UserId = user.UserId;
|
||||||
ver.Code = verifyCode;
|
ver.Code = verifyCode;
|
||||||
@ -518,7 +518,7 @@ Thank you and enjoy!
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a new verification code and add it
|
// Create a new verification code and add it
|
||||||
string verifyCode = Teknik.Utility.RandomString(24);
|
string verifyCode = Helpers.Utility.RandomString(24);
|
||||||
ResetPasswordVerification ver = new ResetPasswordVerification();
|
ResetPasswordVerification ver = new ResetPasswordVerification();
|
||||||
ver.UserId = user.UserId;
|
ver.UserId = user.UserId;
|
||||||
ver.Code = verifyCode;
|
ver.Code = verifyCode;
|
||||||
@ -858,7 +858,7 @@ If you recieved this email and you did not reset your password, you can ignore t
|
|||||||
{
|
{
|
||||||
Config config = Config.Load();
|
Config config = Config.Load();
|
||||||
HttpCookie authcookie = FormsAuthentication.GetAuthCookie(username, remember);
|
HttpCookie authcookie = FormsAuthentication.GetAuthCookie(username, remember);
|
||||||
authcookie.Name = "TeknikAuth";
|
authcookie.Name = Constants.AUTHCOOKIE;
|
||||||
authcookie.HttpOnly = true;
|
authcookie.HttpOnly = true;
|
||||||
authcookie.Secure = true;
|
authcookie.Secure = true;
|
||||||
|
|
||||||
@ -878,5 +878,35 @@ If you recieved this email and you did not reset your password, you can ignore t
|
|||||||
|
|
||||||
return authcookie;
|
return authcookie;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static HttpCookie CreateTrustedDeviceCookie(string username, string domain, bool local)
|
||||||
|
{
|
||||||
|
Config config = Config.Load();
|
||||||
|
|
||||||
|
byte[] time = BitConverter.GetBytes(DateTime.UtcNow.ToBinary());
|
||||||
|
byte[] key = Guid.NewGuid().ToByteArray();
|
||||||
|
string token = Convert.ToBase64String(time.Concat(key).ToArray());
|
||||||
|
HttpCookie trustCookie = new HttpCookie(Constants.TRUSTEDDEVICECOOKIE + "_" + username);
|
||||||
|
trustCookie.Value = token;
|
||||||
|
trustCookie.HttpOnly = true;
|
||||||
|
trustCookie.Secure = true;
|
||||||
|
trustCookie.Expires = DateTime.Now.AddYears(1);
|
||||||
|
|
||||||
|
// Set domain dependent on where it's being ran from
|
||||||
|
if (local) // localhost
|
||||||
|
{
|
||||||
|
trustCookie.Domain = null;
|
||||||
|
}
|
||||||
|
else if (config.DevEnvironment) // dev.example.com
|
||||||
|
{
|
||||||
|
trustCookie.Domain = string.Format("dev.{0}", domain);
|
||||||
|
}
|
||||||
|
else // A production instance
|
||||||
|
{
|
||||||
|
trustCookie.Domain = string.Format(".{0}", domain);
|
||||||
|
}
|
||||||
|
|
||||||
|
return trustCookie;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
17
Teknik/Areas/User/ViewModels/TwoFactorViewModel.cs
Normal file
17
Teknik/Areas/User/ViewModels/TwoFactorViewModel.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using Teknik.ViewModels;
|
||||||
|
|
||||||
|
namespace Teknik.Areas.Users.ViewModels
|
||||||
|
{
|
||||||
|
public class TwoFactorViewModel : ViewModelBase
|
||||||
|
{
|
||||||
|
public bool RememberMe { get; set; }
|
||||||
|
|
||||||
|
public string ReturnUrl { get; set; }
|
||||||
|
|
||||||
|
public bool AllowTrustedDevice { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -125,19 +125,6 @@
|
|||||||
<textarea class="form-control" id="update_pgp_public_key" name="update_pgp_public_key" placeholder="Public Key Here" title="enter your pgp public key" rows="15">@Model.SecuritySettings.PGPSignature</textarea>
|
<textarea class="form-control" id="update_pgp_public_key" name="update_pgp_public_key" placeholder="Public Key Here" title="enter your pgp public key" rows="15">@Model.SecuritySettings.PGPSignature</textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-6 text-left">
|
|
||||||
<label for="update_security_two_factor"><h4>Enable Two Factor Authentication</h4></label>
|
|
||||||
<div class="checkbox">
|
|
||||||
<label>
|
|
||||||
<input id="update_security_two_factor" name="update_security_two_factor" title="whether the key should be saved on the server or not" type="checkbox" value="true" @(Model.SecuritySettings.TwoFactorEnabled ? "checked" : string.Empty) />
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<p class="form-control-static @(Model.SecuritySettings.TwoFactorEnabled ? string.Empty : "hide")" id="setupAuthenticatorLink">
|
|
||||||
<small><a href="#" class="text-primary" id="SetupAuthenticator" data-toggle="modal" data-target="#authenticatorSetup"><i class="fa fa-lock"></i> Set Up Authenticator</a></small>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-4">
|
<div class="col-sm-4">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@ -161,6 +148,27 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-4 text-left">
|
||||||
|
<label for="update_security_two_factor"><h4>Enable Two Factor Authentication</h4></label>
|
||||||
|
<div class="checkbox">
|
||||||
|
<label>
|
||||||
|
<input id="update_security_two_factor" name="update_security_two_factor" title="whether two factor authentication should occur for this account" type="checkbox" value="true" @(Model.SecuritySettings.TwoFactorEnabled ? "checked" : string.Empty) />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<p class="form-control-static @(Model.SecuritySettings.TwoFactorEnabled ? string.Empty : "hide")" id="setupAuthenticatorLink">
|
||||||
|
<small><a href="#" class="text-primary" id="SetupAuthenticator" data-toggle="modal" data-target="#authenticatorSetup"><i class="fa fa-lock"></i> Set Up Authenticator</a></small>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-4 text-left">
|
||||||
|
<label for="update_security_allow_trusted"><h4>Allow Trusted Device Saving</h4></label>
|
||||||
|
<div class="checkbox">
|
||||||
|
<label>
|
||||||
|
<input id="update_security_allow_trusted" name="update_security_allow_trusted" title="whether a device could be cached to bypass two factor authentication" type="checkbox" value="true" @(Model.SecuritySettings.AllowTrustedDevices ? "checked" : string.Empty) />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- Blog Settings -->
|
<!-- Blog Settings -->
|
||||||
<div class="tab-pane" id="blog">
|
<div class="tab-pane" id="blog">
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@model Teknik.Areas.Users.ViewModels.LoginViewModel
|
@model Teknik.Areas.Users.ViewModels.TwoFactorViewModel
|
||||||
|
|
||||||
@using Teknik.Helpers
|
@using Teknik.Helpers
|
||||||
|
|
||||||
@ -22,12 +22,23 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<form role="form" id="twoFactorCheckForm" action="##" method="post" accept-charset="UTF-8">
|
<form role="form" id="twoFactorCheckForm" action="##" method="post" accept-charset="UTF-8">
|
||||||
<input name="returnUrl" id="returnUrl" type="hidden" value="@Model.ReturnUrl" />
|
<input name="ReturnUrl" id="ReturnUrl" type="hidden" value="@Model.ReturnUrl" />
|
||||||
<input name="rememberMe" id="rememberMe" type="hidden" value="@Model.RememberMe" />
|
<input name="RememberMe" id="RememberMe" type="hidden" value="@Model.RememberMe" />
|
||||||
<div class="form-group text-left">
|
<div class="form-group text-left">
|
||||||
<label for="update_website">Authentication code</label>
|
<label for="update_website">Authentication code</label>
|
||||||
<input type="text" class="form-control" id="code" name="code" data-val-required="The Authentication Code is required." data-val="true" />
|
<input type="text" class="form-control" id="Code" name="Code" data-val-required="The Authentication Code is required." data-val="true" />
|
||||||
</div>
|
</div>
|
||||||
|
@if (Model.AllowTrustedDevice)
|
||||||
|
{
|
||||||
|
<div class="checkbox">
|
||||||
|
<label>
|
||||||
|
<input id="RememberDevice" type="checkbox" value="true" name="RememberDevice" /><input name="RememberDevice" type="hidden" value="false"> Remember Device
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<small>Set this device as a trusted device. It is not advised to trust a public computer.</small>
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<button class="btn btn-primary btn-block" id="verifyCodeSubmit" type="button" name="verifyCodeSubmit">Verify</button>
|
<button class="btn btn-primary btn-block" id="verifyCodeSubmit" type="button" name="verifyCodeSubmit">Verify</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -9,6 +9,9 @@ namespace Teknik.Helpers
|
|||||||
public static class Constants
|
public static class Constants
|
||||||
{
|
{
|
||||||
public const string SERVERUSER = "Server Admin";
|
public const string SERVERUSER = "Server Admin";
|
||||||
|
public const string AUTHCOOKIE = "TeknikAuth";
|
||||||
|
public const string TRUSTEDDEVICECOOKIE = "TeknikTrustedDevice";
|
||||||
|
|
||||||
// Paste Constants
|
// Paste Constants
|
||||||
public static Dictionary<string, string> HIGHLIGHTFORMATS = new Dictionary<string, string>()
|
public static Dictionary<string, string> HIGHLIGHTFORMATS = new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
|
@ -8,7 +8,7 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
|
|
||||||
namespace Teknik
|
namespace Teknik.Helpers
|
||||||
{
|
{
|
||||||
public static class Utility
|
public static class Utility
|
||||||
{
|
{
|
||||||
|
@ -22,7 +22,7 @@ namespace Teknik.Models
|
|||||||
public DbSet<User> Users { get; set; }
|
public DbSet<User> Users { get; set; }
|
||||||
public DbSet<Group> Groups { get; set; }
|
public DbSet<Group> Groups { get; set; }
|
||||||
public DbSet<Role> Roles { get; set; }
|
public DbSet<Role> Roles { get; set; }
|
||||||
public DbSet<UserDevice> UserDevices { get; set; }
|
public DbSet<TrustedDevice> TrustedDevices { get; set; }
|
||||||
public DbSet<TransferType> TransferTypes { get; set; }
|
public DbSet<TransferType> TransferTypes { get; set; }
|
||||||
// User Settings
|
// User Settings
|
||||||
public DbSet<UserSettings> UserSettings { get; set; }
|
public DbSet<UserSettings> UserSettings { get; set; }
|
||||||
@ -112,7 +112,7 @@ namespace Teknik.Models
|
|||||||
modelBuilder.Entity<User>().ToTable("Users");
|
modelBuilder.Entity<User>().ToTable("Users");
|
||||||
modelBuilder.Entity<Group>().ToTable("Groups");
|
modelBuilder.Entity<Group>().ToTable("Groups");
|
||||||
modelBuilder.Entity<Role>().ToTable("Roles");
|
modelBuilder.Entity<Role>().ToTable("Roles");
|
||||||
modelBuilder.Entity<UserDevice>().ToTable("UserDevices");
|
modelBuilder.Entity<TrustedDevice>().ToTable("TrustedDevices");
|
||||||
modelBuilder.Entity<TransferType>().ToTable("TransferTypes");
|
modelBuilder.Entity<TransferType>().ToTable("TransferTypes");
|
||||||
modelBuilder.Entity<RecoveryEmailVerification>().ToTable("RecoveryEmailVerifications");
|
modelBuilder.Entity<RecoveryEmailVerification>().ToTable("RecoveryEmailVerifications");
|
||||||
modelBuilder.Entity<ResetPasswordVerification>().ToTable("ResetPasswordVerifications");
|
modelBuilder.Entity<ResetPasswordVerification>().ToTable("ResetPasswordVerifications");
|
||||||
|
@ -224,7 +224,8 @@
|
|||||||
<Compile Include="Areas\User\Models\ResetPasswordVerification.cs" />
|
<Compile Include="Areas\User\Models\ResetPasswordVerification.cs" />
|
||||||
<Compile Include="Areas\User\Models\RecoveryEmailVerification.cs" />
|
<Compile Include="Areas\User\Models\RecoveryEmailVerification.cs" />
|
||||||
<Compile Include="Areas\User\Models\SecuritySettings.cs" />
|
<Compile Include="Areas\User\Models\SecuritySettings.cs" />
|
||||||
<Compile Include="Areas\User\Models\UserDevice.cs" />
|
<Compile Include="Areas\User\Models\TrustedDevice.cs" />
|
||||||
|
<Compile Include="Areas\User\ViewModels\TwoFactorViewModel.cs" />
|
||||||
<Compile Include="Models\TransferTypes.cs" />
|
<Compile Include="Models\TransferTypes.cs" />
|
||||||
<Compile Include="Areas\User\Models\UploadSettings.cs" />
|
<Compile Include="Areas\User\Models\UploadSettings.cs" />
|
||||||
<Compile Include="Areas\User\Models\UserSettings.cs" />
|
<Compile Include="Areas\User\Models\UserSettings.cs" />
|
||||||
|
Loading…
Reference in New Issue
Block a user