mirror of
https://git.teknik.io/Teknikode/Teknik.git
synced 2023-08-02 14:16:22 +02:00
- Implemented invite codes to use for registration.
- Reorganized settings pages into individual pages.
This commit is contained in:
parent
61e0204361
commit
a7c314d728
@ -132,5 +132,24 @@ namespace Teknik.Areas.Admin.Controllers
|
|||||||
}
|
}
|
||||||
return Redirect(Url.SubRouteUrl("error", "Error.Http404"));
|
return Redirect(Url.SubRouteUrl("error", "Error.Http404"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[ValidateAntiForgeryToken]
|
||||||
|
public ActionResult CreateInviteCode(string username)
|
||||||
|
{
|
||||||
|
if (UserHelper.UserExists(db, username))
|
||||||
|
{
|
||||||
|
User user = UserHelper.GetUser(db, username);
|
||||||
|
InviteCode inviteCode = db.InviteCodes.Create();
|
||||||
|
inviteCode.Active = true;
|
||||||
|
inviteCode.Code = Guid.NewGuid().ToString();
|
||||||
|
inviteCode.Owner = user;
|
||||||
|
db.InviteCodes.Add(inviteCode);
|
||||||
|
db.SaveChanges();
|
||||||
|
|
||||||
|
return Json(new { result = new { code = inviteCode.Code } });
|
||||||
|
}
|
||||||
|
return Redirect(Url.SubRouteUrl("error", "Error.Http404"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,15 +9,15 @@ $(function () {
|
|||||||
data: AddAntiForgeryToken({ username: username, accountType: selected }),
|
data: AddAntiForgeryToken({ username: username, accountType: selected }),
|
||||||
success: function (html) {
|
success: function (html) {
|
||||||
if (html) {
|
if (html) {
|
||||||
if (html.error) {
|
if (html.result.success) {
|
||||||
$("#top_msg").css('display', 'inline', 'important');
|
|
||||||
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + html.error.message + '</div>');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$("#top_msg").css('display', 'none');
|
$("#top_msg").css('display', 'none');
|
||||||
$("#top_msg").html('');
|
$("#top_msg").html('');
|
||||||
alert('Successfully changed the account type for \'' + username + '\' to type: ' + selected);
|
alert('Successfully changed the account type for \'' + username + '\' to type: ' + selected);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
$("#top_msg").css('display', 'inline', 'important');
|
||||||
|
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + parseErrorMessage(html) + '</div>');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -32,18 +32,36 @@ $(function () {
|
|||||||
data: AddAntiForgeryToken({ username: username, accountStatus: selected }),
|
data: AddAntiForgeryToken({ username: username, accountStatus: selected }),
|
||||||
success: function (html) {
|
success: function (html) {
|
||||||
if (html) {
|
if (html) {
|
||||||
if (html.error) {
|
if (html.result.success) {
|
||||||
$("#top_msg").css('display', 'inline', 'important');
|
|
||||||
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + html.error.message + '</div>');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$("#top_msg").css('display', 'none');
|
$("#top_msg").css('display', 'none');
|
||||||
$("#top_msg").html('');
|
$("#top_msg").html('');
|
||||||
alert('Successfully changed the account status for \'' + username + '\' to: ' + selected);
|
alert('Successfully changed the account status for \'' + username + '\' to: ' + selected);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
$("#top_msg").css('display', 'inline', 'important');
|
||||||
|
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + parseErrorMessage(html) + '</div>');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('#createInviteCode').click(function () {
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: createInviteCode,
|
||||||
|
data: AddAntiForgeryToken({ username: username }),
|
||||||
|
success: function (html) {
|
||||||
|
if (html.result) {
|
||||||
|
$("#top_msg").css('display', 'none');
|
||||||
|
$("#top_msg").html('');
|
||||||
|
alert('Successfully created invite code for \'' + username + '\': ' + html.result.code);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$("#top_msg").css('display', 'inline', 'important');
|
||||||
|
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + parseErrorMessage(html) + '</div>');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
// We need to define the action URLs for the script
|
// We need to define the action URLs for the script
|
||||||
var editAccountType = '@Url.SubRouteUrl("admin", "Admin.Action", new { action = "EditUserAccountType" })';
|
var editAccountType = '@Url.SubRouteUrl("admin", "Admin.Action", new { action = "EditUserAccountType" })';
|
||||||
var editAccountStatus = '@Url.SubRouteUrl("admin", "Admin.Action", new { action = "EditUserAccountStatus" })';
|
var editAccountStatus = '@Url.SubRouteUrl("admin", "Admin.Action", new { action = "EditUserAccountStatus" })';
|
||||||
|
var createInviteCode = '@Url.SubRouteUrl("admin", "Admin.Action", new { action = "CreateInviteCode" })';
|
||||||
var username = '@Model.Username';
|
var username = '@Model.Username';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -52,4 +53,10 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<br />
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-2 col-sm-offset-1">
|
||||||
|
<button type="button" class="list-group-item btn-info" id="createInviteCode">Create Invite Code</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -102,23 +102,56 @@ namespace Teknik.Areas.Users.Controllers
|
|||||||
[TrackPageView]
|
[TrackPageView]
|
||||||
public ActionResult Settings()
|
public ActionResult Settings()
|
||||||
{
|
{
|
||||||
string username = User.Identity.Name;
|
return Redirect(Url.SubRouteUrl("user", "User.SecuritySettings"));
|
||||||
|
}
|
||||||
SettingsViewModel model = new SettingsViewModel();
|
|
||||||
ViewBag.Title = "User Does Not Exist - " + Config.Title;
|
|
||||||
ViewBag.Description = "The User does not exist";
|
|
||||||
|
|
||||||
|
[TrackPageView]
|
||||||
|
public ActionResult ProfileSettings()
|
||||||
|
{
|
||||||
using (TeknikEntities db = new TeknikEntities())
|
using (TeknikEntities db = new TeknikEntities())
|
||||||
{
|
{
|
||||||
|
string username = User.Identity.Name;
|
||||||
User user = UserHelper.GetUser(db, username);
|
User user = UserHelper.GetUser(db, username);
|
||||||
|
|
||||||
if (user != null)
|
if (user != null)
|
||||||
{
|
{
|
||||||
Session["AuthenticatedUser"] = user;
|
Session["AuthenticatedUser"] = user;
|
||||||
|
|
||||||
ViewBag.Title = "Settings - " + Config.Title;
|
ViewBag.Title = "Profile Settings - " + Config.Title;
|
||||||
ViewBag.Description = "Your " + Config.Title + " Settings";
|
ViewBag.Description = "Your " + Config.Title + " Profile Settings";
|
||||||
|
|
||||||
|
ProfileSettingsViewModel model = new ProfileSettingsViewModel();
|
||||||
|
model.Page = "Profile";
|
||||||
|
model.UserID = user.UserId;
|
||||||
|
model.Username = user.Username;
|
||||||
|
model.About = user.UserSettings.About;
|
||||||
|
model.Quote = user.UserSettings.Quote;
|
||||||
|
model.Website = user.UserSettings.Website;
|
||||||
|
|
||||||
|
return View("/Areas/User/Views/User/Settings/ProfileSettings.cshtml", model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Redirect(Url.SubRouteUrl("error", "Error.Http403"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TrackPageView]
|
||||||
|
public ActionResult SecuritySettings()
|
||||||
|
{
|
||||||
|
using (TeknikEntities db = new TeknikEntities())
|
||||||
|
{
|
||||||
|
string username = User.Identity.Name;
|
||||||
|
User user = UserHelper.GetUser(db, username);
|
||||||
|
|
||||||
|
if (user != null)
|
||||||
|
{
|
||||||
|
Session["AuthenticatedUser"] = user;
|
||||||
|
|
||||||
|
ViewBag.Title = "Security Settings - " + Config.Title;
|
||||||
|
ViewBag.Description = "Your " + Config.Title + " Security Settings";
|
||||||
|
|
||||||
|
SecuritySettingsViewModel model = new SecuritySettingsViewModel();
|
||||||
|
model.Page = "Security";
|
||||||
model.UserID = user.UserId;
|
model.UserID = user.UserId;
|
||||||
model.Username = user.Username;
|
model.Username = user.Username;
|
||||||
model.TrustedDeviceCount = user.TrustedDevices.Count;
|
model.TrustedDeviceCount = user.TrustedDevices.Count;
|
||||||
@ -133,16 +166,126 @@ namespace Teknik.Areas.Users.Controllers
|
|||||||
model.AuthTokens.Add(tokenModel);
|
model.AuthTokens.Add(tokenModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
model.UserSettings = user.UserSettings;
|
model.PgpPublicKey = user.SecuritySettings.PGPSignature;
|
||||||
model.SecuritySettings = user.SecuritySettings;
|
model.RecoveryEmail = user.SecuritySettings.RecoveryEmail;
|
||||||
model.BlogSettings = user.BlogSettings;
|
model.RecoveryVerified = user.SecuritySettings.RecoveryVerified;
|
||||||
model.UploadSettings = user.UploadSettings;
|
model.AllowTrustedDevices = user.SecuritySettings.AllowTrustedDevices;
|
||||||
|
model.TwoFactorEnabled = user.SecuritySettings.TwoFactorEnabled;
|
||||||
|
model.TwoFactorKey = user.SecuritySettings.TwoFactorKey;
|
||||||
|
|
||||||
return View(model);
|
return View("/Areas/User/Views/User/Settings/SecuritySettings.cshtml", model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
model.Error = true;
|
|
||||||
return View(model);
|
return Redirect(Url.SubRouteUrl("error", "Error.Http403"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TrackPageView]
|
||||||
|
public ActionResult InviteSettings()
|
||||||
|
{
|
||||||
|
using (TeknikEntities db = new TeknikEntities())
|
||||||
|
{
|
||||||
|
string username = User.Identity.Name;
|
||||||
|
User user = UserHelper.GetUser(db, username);
|
||||||
|
|
||||||
|
if (user != null)
|
||||||
|
{
|
||||||
|
Session["AuthenticatedUser"] = user;
|
||||||
|
|
||||||
|
ViewBag.Title = "Invite Settings - " + Config.Title;
|
||||||
|
ViewBag.Description = "Your " + Config.Title + " Invite Settings";
|
||||||
|
|
||||||
|
InviteSettingsViewModel model = new InviteSettingsViewModel();
|
||||||
|
model.Page = "Invite";
|
||||||
|
model.UserID = user.UserId;
|
||||||
|
model.Username = user.Username;
|
||||||
|
|
||||||
|
List<InviteCodeViewModel> availableCodes = new List<InviteCodeViewModel>();
|
||||||
|
List<InviteCodeViewModel> claimedCodes = new List<InviteCodeViewModel>();
|
||||||
|
if (user.OwnedInviteCodes != null)
|
||||||
|
{
|
||||||
|
foreach (InviteCode inviteCode in user.OwnedInviteCodes.Where(c => c.Active))
|
||||||
|
{
|
||||||
|
InviteCodeViewModel inviteCodeViewModel = new InviteCodeViewModel();
|
||||||
|
inviteCodeViewModel.ClaimedUser = inviteCode.ClaimedUser;
|
||||||
|
inviteCodeViewModel.Active = inviteCode.Active;
|
||||||
|
inviteCodeViewModel.Code = inviteCode.Code;
|
||||||
|
inviteCodeViewModel.InviteCodeId = inviteCode.InviteCodeId;
|
||||||
|
inviteCodeViewModel.Owner = inviteCode.Owner;
|
||||||
|
|
||||||
|
if (inviteCode.ClaimedUser == null)
|
||||||
|
availableCodes.Add(inviteCodeViewModel);
|
||||||
|
|
||||||
|
if (inviteCode.ClaimedUser != null)
|
||||||
|
claimedCodes.Add(inviteCodeViewModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
model.AvailableCodes = availableCodes;
|
||||||
|
model.ClaimedCodes = claimedCodes;
|
||||||
|
|
||||||
|
return View("/Areas/User/Views/User/Settings/InviteSettings.cshtml", model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Redirect(Url.SubRouteUrl("error", "Error.Http403"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TrackPageView]
|
||||||
|
public ActionResult BlogSettings()
|
||||||
|
{
|
||||||
|
using (TeknikEntities db = new TeknikEntities())
|
||||||
|
{
|
||||||
|
string username = User.Identity.Name;
|
||||||
|
User user = UserHelper.GetUser(db, username);
|
||||||
|
|
||||||
|
if (user != null)
|
||||||
|
{
|
||||||
|
Session["AuthenticatedUser"] = user;
|
||||||
|
|
||||||
|
ViewBag.Title = "Blog Settings - " + Config.Title;
|
||||||
|
ViewBag.Description = "Your " + Config.Title + " Blog Settings";
|
||||||
|
|
||||||
|
BlogSettingsViewModel model = new BlogSettingsViewModel();
|
||||||
|
model.Page = "Blog";
|
||||||
|
model.UserID = user.UserId;
|
||||||
|
model.Username = user.Username;
|
||||||
|
model.Title = user.BlogSettings.Title;
|
||||||
|
model.Description = user.BlogSettings.Description;
|
||||||
|
|
||||||
|
return View("/Areas/User/Views/User/Settings/BlogSettings.cshtml", model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Redirect(Url.SubRouteUrl("error", "Error.Http403"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TrackPageView]
|
||||||
|
public ActionResult UploadSettings()
|
||||||
|
{
|
||||||
|
using (TeknikEntities db = new TeknikEntities())
|
||||||
|
{
|
||||||
|
string username = User.Identity.Name;
|
||||||
|
User user = UserHelper.GetUser(db, username);
|
||||||
|
|
||||||
|
if (user != null)
|
||||||
|
{
|
||||||
|
Session["AuthenticatedUser"] = user;
|
||||||
|
|
||||||
|
ViewBag.Title = "Upload Settings - " + Config.Title;
|
||||||
|
ViewBag.Description = "Your " + Config.Title + " Upload Settings";
|
||||||
|
|
||||||
|
UploadSettingsViewModel model = new UploadSettingsViewModel();
|
||||||
|
model.Page = "Upload";
|
||||||
|
model.UserID = user.UserId;
|
||||||
|
model.Username = user.Username;
|
||||||
|
model.Encrypt = user.UploadSettings.Encrypt;
|
||||||
|
|
||||||
|
return View("/Areas/User/Views/User/Settings/UploadSettings.cshtml", model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Redirect(Url.SubRouteUrl("error", "Error.Http403"));
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
@ -295,9 +438,10 @@ namespace Teknik.Areas.Users.Controllers
|
|||||||
[HttpGet]
|
[HttpGet]
|
||||||
[TrackPageView]
|
[TrackPageView]
|
||||||
[AllowAnonymous]
|
[AllowAnonymous]
|
||||||
public ActionResult Register(string ReturnUrl)
|
public ActionResult Register(string inviteCode, string ReturnUrl)
|
||||||
{
|
{
|
||||||
RegisterViewModel model = new RegisterViewModel();
|
RegisterViewModel model = new RegisterViewModel();
|
||||||
|
model.InviteCode = inviteCode;
|
||||||
model.ReturnUrl = ReturnUrl;
|
model.ReturnUrl = ReturnUrl;
|
||||||
|
|
||||||
return View("/Areas/User/Views/User/ViewRegistration.cshtml", model);
|
return View("/Areas/User/Views/User/ViewRegistration.cshtml", model);
|
||||||
@ -331,6 +475,18 @@ namespace Teknik.Areas.Users.Controllers
|
|||||||
model.ErrorMessage = "Passwords must match";
|
model.ErrorMessage = "Passwords must match";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validate the Invite Code
|
||||||
|
if (!model.Error && Config.UserConfig.InviteCodeRequired && string.IsNullOrEmpty(model.InviteCode))
|
||||||
|
{
|
||||||
|
model.Error = true;
|
||||||
|
model.ErrorMessage = "An Invite Code is required to register";
|
||||||
|
}
|
||||||
|
if (!model.Error && !string.IsNullOrEmpty(model.InviteCode) && db.InviteCodes.Where(c => c.Code == model.InviteCode && c.Active && c.ClaimedUser == null).FirstOrDefault() == null)
|
||||||
|
{
|
||||||
|
model.Error = true;
|
||||||
|
model.ErrorMessage = "Invalid Invite Code";
|
||||||
|
}
|
||||||
|
|
||||||
// PGP Key valid?
|
// PGP Key valid?
|
||||||
if (!model.Error && !string.IsNullOrEmpty(model.PublicKey) && !PGP.IsPublicKey(model.PublicKey))
|
if (!model.Error && !string.IsNullOrEmpty(model.PublicKey) && !PGP.IsPublicKey(model.PublicKey))
|
||||||
{
|
{
|
||||||
@ -355,6 +511,16 @@ namespace Teknik.Areas.Users.Controllers
|
|||||||
if (!string.IsNullOrEmpty(model.RecoveryEmail))
|
if (!string.IsNullOrEmpty(model.RecoveryEmail))
|
||||||
newUser.SecuritySettings.RecoveryEmail = model.RecoveryEmail;
|
newUser.SecuritySettings.RecoveryEmail = model.RecoveryEmail;
|
||||||
|
|
||||||
|
// if they provided an invite code, let's assign them to it
|
||||||
|
if (!string.IsNullOrEmpty(model.InviteCode))
|
||||||
|
{
|
||||||
|
InviteCode code = db.InviteCodes.Where(c => c.Code == model.InviteCode).FirstOrDefault();
|
||||||
|
db.Entry(code).State = EntityState.Modified;
|
||||||
|
db.SaveChanges();
|
||||||
|
|
||||||
|
newUser.ClaimedInviteCode = code;
|
||||||
|
}
|
||||||
|
|
||||||
UserHelper.AddAccount(db, Config, newUser, model.Password);
|
UserHelper.AddAccount(db, Config, newUser, model.Password);
|
||||||
|
|
||||||
// If they have a recovery email, let's send a verification
|
// If they have a recovery email, let's send a verification
|
||||||
@ -389,7 +555,70 @@ namespace Teknik.Areas.Users.Controllers
|
|||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[ValidateAntiForgeryToken]
|
[ValidateAntiForgeryToken]
|
||||||
public ActionResult Edit(EditSettingsViewModel settings)
|
public ActionResult EditBlog(BlogSettingsViewModel settings)
|
||||||
|
{
|
||||||
|
if (ModelState.IsValid)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (TeknikEntities db = new TeknikEntities())
|
||||||
|
{
|
||||||
|
User user = UserHelper.GetUser(db, User.Identity.Name);
|
||||||
|
if (user != null)
|
||||||
|
{
|
||||||
|
// Blogs
|
||||||
|
user.BlogSettings.Title = settings.Title;
|
||||||
|
user.BlogSettings.Description = settings.Description;
|
||||||
|
|
||||||
|
UserHelper.EditAccount(db, Config, user);
|
||||||
|
return Json(new { result = true });
|
||||||
|
}
|
||||||
|
return Json(new { error = "User does not exist" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return Json(new { error = ex.GetFullMessage(true) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Json(new { error = "Invalid Parameters" });
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[ValidateAntiForgeryToken]
|
||||||
|
public ActionResult EditProfile(ProfileSettingsViewModel settings)
|
||||||
|
{
|
||||||
|
if (ModelState.IsValid)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (TeknikEntities db = new TeknikEntities())
|
||||||
|
{
|
||||||
|
User user = UserHelper.GetUser(db, User.Identity.Name);
|
||||||
|
if (user != null)
|
||||||
|
{
|
||||||
|
// Profile Info
|
||||||
|
user.UserSettings.Website = settings.Website;
|
||||||
|
user.UserSettings.Quote = settings.Quote;
|
||||||
|
user.UserSettings.About = settings.About;
|
||||||
|
|
||||||
|
UserHelper.EditAccount(db, Config, user);
|
||||||
|
return Json(new { result = true });
|
||||||
|
}
|
||||||
|
return Json(new { error = "User does not exist" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return Json(new { error = ex.GetFullMessage(true) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Json(new { error = "Invalid Parameters" });
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[ValidateAntiForgeryToken]
|
||||||
|
public ActionResult EditSecurity(SecuritySettingsViewModel settings)
|
||||||
{
|
{
|
||||||
if (ModelState.IsValid)
|
if (ModelState.IsValid)
|
||||||
{
|
{
|
||||||
@ -401,7 +630,6 @@ namespace Teknik.Areas.Users.Controllers
|
|||||||
if (user != null)
|
if (user != null)
|
||||||
{
|
{
|
||||||
bool changePass = false;
|
bool changePass = false;
|
||||||
string email = string.Format("{0}@{1}", User.Identity.Name, Config.EmailConfig.Domain);
|
|
||||||
// Changing Password?
|
// Changing Password?
|
||||||
if (!string.IsNullOrEmpty(settings.CurrentPassword) && (!string.IsNullOrEmpty(settings.NewPassword) || !string.IsNullOrEmpty(settings.NewPasswordConfirm)))
|
if (!string.IsNullOrEmpty(settings.CurrentPassword) && (!string.IsNullOrEmpty(settings.NewPassword) || !string.IsNullOrEmpty(settings.NewPasswordConfirm)))
|
||||||
{
|
{
|
||||||
@ -488,18 +716,6 @@ namespace Teknik.Areas.Users.Controllers
|
|||||||
}
|
}
|
||||||
user.SecuritySettings.TwoFactorKey = newKey;
|
user.SecuritySettings.TwoFactorKey = newKey;
|
||||||
|
|
||||||
// Profile Info
|
|
||||||
user.UserSettings.Website = settings.Website;
|
|
||||||
user.UserSettings.Quote = settings.Quote;
|
|
||||||
user.UserSettings.About = settings.About;
|
|
||||||
|
|
||||||
// Blogs
|
|
||||||
user.BlogSettings.Title = settings.BlogTitle;
|
|
||||||
user.BlogSettings.Description = settings.BlogDesc;
|
|
||||||
|
|
||||||
// Uploads
|
|
||||||
user.UploadSettings.Encrypt = settings.Encrypt;
|
|
||||||
|
|
||||||
UserHelper.EditAccount(db, Config, user, changePass, settings.NewPassword);
|
UserHelper.EditAccount(db, Config, user, changePass, settings.NewPassword);
|
||||||
|
|
||||||
// If they have a recovery email, let's send a verification
|
// If they have a recovery email, let's send a verification
|
||||||
@ -528,6 +744,36 @@ namespace Teknik.Areas.Users.Controllers
|
|||||||
return Json(new { error = "Invalid Parameters" });
|
return Json(new { error = "Invalid Parameters" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[ValidateAntiForgeryToken]
|
||||||
|
public ActionResult EditUpload(UploadSettingsViewModel settings)
|
||||||
|
{
|
||||||
|
if (ModelState.IsValid)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (TeknikEntities db = new TeknikEntities())
|
||||||
|
{
|
||||||
|
User user = UserHelper.GetUser(db, User.Identity.Name);
|
||||||
|
if (user != null)
|
||||||
|
{
|
||||||
|
// Profile Info
|
||||||
|
user.UploadSettings.Encrypt = settings.Encrypt;
|
||||||
|
|
||||||
|
UserHelper.EditAccount(db, Config, user);
|
||||||
|
return Json(new { result = true });
|
||||||
|
}
|
||||||
|
return Json(new { error = "User does not exist" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return Json(new { error = ex.GetFullMessage(true) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Json(new { error = "Invalid Parameters" });
|
||||||
|
}
|
||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[ValidateAntiForgeryToken]
|
[ValidateAntiForgeryToken]
|
||||||
public ActionResult Delete()
|
public ActionResult Delete()
|
||||||
@ -913,7 +1159,7 @@ namespace Teknik.Areas.Users.Controllers
|
|||||||
model.Name = token.Name;
|
model.Name = token.Name;
|
||||||
model.LastDateUsed = token.LastDateUsed;
|
model.LastDateUsed = token.LastDateUsed;
|
||||||
|
|
||||||
return Json(new { result = new { token = newTokenStr, html = PartialView("~/Areas/User/Views/User/AuthToken.cshtml", model).RenderToString() } });
|
return Json(new { result = new { token = newTokenStr, html = PartialView("~/Areas/User/Views/User/Settings/AuthToken.cshtml", model).RenderToString() } });
|
||||||
}
|
}
|
||||||
return Json(new { error = "Unable to generate Auth Token" });
|
return Json(new { error = "Unable to generate Auth Token" });
|
||||||
}
|
}
|
||||||
@ -1022,5 +1268,31 @@ namespace Teknik.Areas.Users.Controllers
|
|||||||
return Json(new { error = ex.GetFullMessage(true) });
|
return Json(new { error = ex.GetFullMessage(true) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[ValidateAntiForgeryToken]
|
||||||
|
public ActionResult CreateInviteCodeLink(int inviteCodeId)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (TeknikEntities db = new TeknikEntities())
|
||||||
|
{
|
||||||
|
InviteCode code = db.InviteCodes.Where(c => c.InviteCodeId == inviteCodeId).FirstOrDefault();
|
||||||
|
if (code != null)
|
||||||
|
{
|
||||||
|
if (code.Owner.UserId == User.Info.UserId)
|
||||||
|
{
|
||||||
|
return Json(new { result = Url.SubRouteUrl("user", "User.Register", new { inviteCode = code.Code })});
|
||||||
|
}
|
||||||
|
return Json(new { error = "Invite Code not associated with this user"});
|
||||||
|
}
|
||||||
|
return Json(new { error = "Invalid Invite Code" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return Json(new { error = ex.GetFullMessage(true) });
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
27
Teknik/Areas/User/Models/InviteCode.cs
Normal file
27
Teknik/Areas/User/Models/InviteCode.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using Teknik.Attributes;
|
||||||
|
|
||||||
|
namespace Teknik.Areas.Users.Models
|
||||||
|
{
|
||||||
|
public class InviteCode
|
||||||
|
{
|
||||||
|
public int InviteCodeId { get; set; }
|
||||||
|
|
||||||
|
public bool Active { get; set; }
|
||||||
|
|
||||||
|
[CaseSensitive]
|
||||||
|
public string Code { get; set; }
|
||||||
|
|
||||||
|
public virtual User Owner { get; set; }
|
||||||
|
|
||||||
|
public virtual User ClaimedUser { get; set; }
|
||||||
|
|
||||||
|
public InviteCode()
|
||||||
|
{
|
||||||
|
Active = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -24,6 +24,10 @@ namespace Teknik.Areas.Users.Models
|
|||||||
|
|
||||||
public DateTime LastSeen { get; set; }
|
public DateTime LastSeen { get; set; }
|
||||||
|
|
||||||
|
public virtual InviteCode ClaimedInviteCode { get; set; }
|
||||||
|
|
||||||
|
public virtual ICollection<InviteCode> OwnedInviteCodes { get; set; }
|
||||||
|
|
||||||
public AccountType AccountType { get; set; }
|
public AccountType AccountType { get; set; }
|
||||||
|
|
||||||
public AccountStatus AccountStatus { get; set; }
|
public AccountStatus AccountStatus { get; set; }
|
||||||
@ -62,6 +66,8 @@ namespace Teknik.Areas.Users.Models
|
|||||||
Groups = new List<Group>();
|
Groups = new List<Group>();
|
||||||
TrustedDevices = new List<TrustedDevice>();
|
TrustedDevices = new List<TrustedDevice>();
|
||||||
AuthTokens = new List<AuthToken>();
|
AuthTokens = new List<AuthToken>();
|
||||||
|
ClaimedInviteCode = null;
|
||||||
|
OwnedInviteCodes = new List<InviteCode>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
29
Teknik/Areas/User/Scripts/BlogSettings.js
Normal file
29
Teknik/Areas/User/Scripts/BlogSettings.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
$(document).ready(function () {
|
||||||
|
$("#update_submit").click(function () {
|
||||||
|
// Start Updating Animation
|
||||||
|
$.blockUI({ message: '<div class="text-center"><h3>Updating...</h3></div>' });
|
||||||
|
|
||||||
|
blog_title = $("#update_blog_title").val();
|
||||||
|
blog_desc = $("#update_blog_description").val();
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: editURL,
|
||||||
|
data: AddAntiForgeryToken({
|
||||||
|
Title: blog_title,
|
||||||
|
Description: blog_desc,
|
||||||
|
}),
|
||||||
|
success: function (html) {
|
||||||
|
$.unblockUI();
|
||||||
|
if (html.result) {
|
||||||
|
$("#top_msg").css('display', 'inline', 'important');
|
||||||
|
$("#top_msg").html('<div class="alert alert-success alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>Settings Saved!</div>');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$("#top_msg").css('display', 'inline', 'important');
|
||||||
|
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + parseErrorMessage(html) + '</div>');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
});
|
35
Teknik/Areas/User/Scripts/InviteSettings.js
Normal file
35
Teknik/Areas/User/Scripts/InviteSettings.js
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
$(document).ready(function () {
|
||||||
|
$('[data-toggle="popover"]').popover();
|
||||||
|
|
||||||
|
$('[data-toggle="popover"]').on('shown.bs.popover', function () {
|
||||||
|
var $this = $(this);
|
||||||
|
setTimeout(function() {
|
||||||
|
$this.popover('hide');
|
||||||
|
}, 3000);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function copyCode(inviteCodeId, inviteCode) {
|
||||||
|
copyTextToClipboard(inviteCode);
|
||||||
|
$('#copyCode_' + inviteCodeId + '').popover('show');
|
||||||
|
}
|
||||||
|
|
||||||
|
function createExternalLink(inviteCodeId) {
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: createExternalLinkURL,
|
||||||
|
data: AddAntiForgeryToken({ inviteCodeId: inviteCodeId }),
|
||||||
|
success: function (response) {
|
||||||
|
if (response.result) {
|
||||||
|
bootbox.dialog({
|
||||||
|
title: "Send this link to someone to claim this invite code.",
|
||||||
|
message: '<input type="text" class="form-control" id="inviteCodeLink" onClick="this.select();" value="' + response.result + '">'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$("#top_msg").css('display', 'inline', 'important');
|
||||||
|
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + parseErrorMessage(response) + '</div>');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
31
Teknik/Areas/User/Scripts/ProfileSettings.js
Normal file
31
Teknik/Areas/User/Scripts/ProfileSettings.js
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
$(document).ready(function () {
|
||||||
|
$("#update_submit").click(function () {
|
||||||
|
// Start Updating Animation
|
||||||
|
$.blockUI({ message: '<div class="text-center"><h3>Updating...</h3></div>' });
|
||||||
|
|
||||||
|
website = $("#update_website").val();
|
||||||
|
quote = $("#update_quote").val();
|
||||||
|
about = $("#update_about").val();
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: editURL,
|
||||||
|
data: AddAntiForgeryToken({
|
||||||
|
Website: website,
|
||||||
|
Quote: quote,
|
||||||
|
About: about
|
||||||
|
}),
|
||||||
|
success: function (html) {
|
||||||
|
$.unblockUI();
|
||||||
|
if (html.result) {
|
||||||
|
$("#top_msg").css('display', 'inline', 'important');
|
||||||
|
$("#top_msg").html('<div class="alert alert-success alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>Settings Saved!</div>');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$("#top_msg").css('display', 'inline', 'important');
|
||||||
|
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + parseErrorMessage(html) + '</div>');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
});
|
49
Teknik/Areas/User/Scripts/ResetPass.js
Normal file
49
Teknik/Areas/User/Scripts/ResetPass.js
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
$(document).ready(function () {
|
||||||
|
$("#reset_pass_send_submit").click(function () {
|
||||||
|
var form = $('#reset_pass_send');
|
||||||
|
username = $("#reset_username").val();
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: form.attr('action'),
|
||||||
|
data: AddAntiForgeryToken({
|
||||||
|
username: username
|
||||||
|
}),
|
||||||
|
success: function (html) {
|
||||||
|
if (html.result) {
|
||||||
|
$("#top_msg").css('display', 'inline', 'important');
|
||||||
|
$("#top_msg").html('<div class="alert alert-success alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>The Password Reset Link has been sent to your recovery email.</div>');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$("#top_msg").css('display', 'inline', 'important');
|
||||||
|
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + parseErrorMessage(html) + '</div>');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#setNewPass_submit").click(function () {
|
||||||
|
var form = $('#setNewPass');
|
||||||
|
password = $("#setNewPass_Password").val();
|
||||||
|
confirmPassword = $("#setNewPass_ConfirmPassword").val();
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: form.attr('action'),
|
||||||
|
data: AddAntiForgeryToken({
|
||||||
|
Password: password,
|
||||||
|
PasswordConfirm: confirmPassword
|
||||||
|
}),
|
||||||
|
success: function (html) {
|
||||||
|
if (html.result) {
|
||||||
|
$("#top_msg").css('display', 'inline', 'important');
|
||||||
|
$("#top_msg").html('<div class="alert alert-success alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>Password has successfully been reset.</div>');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$("#top_msg").css('display', 'inline', 'important');
|
||||||
|
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + parseErrorMessage(html) + '</div>');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
});
|
@ -1,5 +1,4 @@
|
|||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
$("[name='update_upload_encrypt']").bootstrapSwitch();
|
|
||||||
$("[name='update_security_two_factor']").bootstrapSwitch();
|
$("[name='update_security_two_factor']").bootstrapSwitch();
|
||||||
$("[name='update_security_allow_trusted']").bootstrapSwitch();
|
$("[name='update_security_allow_trusted']").bootstrapSwitch();
|
||||||
|
|
||||||
@ -10,18 +9,12 @@
|
|||||||
data: AddAntiForgeryToken({}),
|
data: AddAntiForgeryToken({}),
|
||||||
success: function (html) {
|
success: function (html) {
|
||||||
if (html.result) {
|
if (html.result) {
|
||||||
window.location.reload();
|
$("#top_msg").css('display', 'inline', 'important');
|
||||||
|
$("#top_msg").html('<div class="alert alert-info alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>Recovery Email Verification Sent.</div>');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
errorMsg = html;
|
|
||||||
if (html.error) {
|
|
||||||
errorMsg = html.error;
|
|
||||||
if (html.error.message) {
|
|
||||||
errorMsg = html.error.message;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$("#top_msg").css('display', 'inline', 'important');
|
$("#top_msg").css('display', 'inline', 'important');
|
||||||
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + errorMsg + '</div>');
|
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + parseErrorMessage(html) + '</div>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -51,15 +44,8 @@
|
|||||||
$("#authSetupStatus").html('<div class="alert alert-success alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>Success!</div>');
|
$("#authSetupStatus").html('<div class="alert alert-success alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>Success!</div>');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
errorMsg = html;
|
|
||||||
if (html.error) {
|
|
||||||
errorMsg = html.error;
|
|
||||||
if (html.error.message) {
|
|
||||||
errorMsg = html.error.message;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$("#authSetupStatus").css('display', 'inline', 'important');
|
$("#authSetupStatus").css('display', 'inline', 'important');
|
||||||
$("#authSetupStatus").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + errorMsg + '</div>');
|
$("#authSetupStatus").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + parseErrorMessage(html) + '</div>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -77,15 +63,8 @@
|
|||||||
$("#top_msg").html('<div class="alert alert-success alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>Successfully Cleared Trusted Devices</div>');
|
$("#top_msg").html('<div class="alert alert-success alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>Successfully Cleared Trusted Devices</div>');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
errorMsg = html;
|
|
||||||
if (html.error) {
|
|
||||||
errorMsg = html.error;
|
|
||||||
if (html.error.message) {
|
|
||||||
errorMsg = html.error.message;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$("#top_msg").css('display', 'inline', 'important');
|
$("#top_msg").css('display', 'inline', 'important');
|
||||||
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + errorMsg + '</div>');
|
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + parseErrorMessage(html) + '</div>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -119,15 +98,8 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
errorMsg = response;
|
|
||||||
if (response.error) {
|
|
||||||
errorMsg = response.error;
|
|
||||||
if (response.error.message) {
|
|
||||||
errorMsg = response.error.message;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$("#top_msg").css('display', 'inline', 'important');
|
$("#top_msg").css('display', 'inline', 'important');
|
||||||
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + errorMsg + '</div>');
|
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + parseErrorMessage(response) + '</div>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -147,43 +119,8 @@
|
|||||||
$('#authTokenList').html('<li class="list-group-item text-center" id="noAuthTokens">No Authentication Tokens</li>');
|
$('#authTokenList').html('<li class="list-group-item text-center" id="noAuthTokens">No Authentication Tokens</li>');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
errorMsg = response;
|
|
||||||
if (response.error) {
|
|
||||||
errorMsg = response.error;
|
|
||||||
if (response.error.message) {
|
|
||||||
errorMsg = response.error.message;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$("#top_msg").css('display', 'inline', 'important');
|
$("#top_msg").css('display', 'inline', 'important');
|
||||||
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + errorMsg + '</div>');
|
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + parseErrorMessage(response) + '</div>');
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#delete_account').click(function () {
|
|
||||||
bootbox.confirm("Are you sure you want to delete your account?", function (result) {
|
|
||||||
if (result) {
|
|
||||||
$.ajax({
|
|
||||||
type: "POST",
|
|
||||||
url: deleteUserURL,
|
|
||||||
data: AddAntiForgeryToken({}),
|
|
||||||
success: function (html) {
|
|
||||||
if (html.result) {
|
|
||||||
window.location.replace(homeUrl);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
errorMsg = html;
|
|
||||||
if (html.error) {
|
|
||||||
errorMsg = html.error;
|
|
||||||
if (html.error.message) {
|
|
||||||
errorMsg = html.error.message;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$("#top_msg").css('display', 'inline', 'important');
|
|
||||||
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + errorMsg + '</div>');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -202,15 +139,9 @@
|
|||||||
update_security_allow_trusted = $("#update_security_allow_trusted").is(":checked");
|
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();
|
|
||||||
quote = $("#update_quote").val();
|
|
||||||
about = $("#update_about").val();
|
|
||||||
blog_title = $("#update_blog_title").val();
|
|
||||||
blog_desc = $("#update_blog_description").val();
|
|
||||||
upload_encrypt = $("#update_upload_encrypt").is(":checked");
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: "POST",
|
type: "POST",
|
||||||
url: editUserURL,
|
url: editURL,
|
||||||
data: AddAntiForgeryToken({
|
data: AddAntiForgeryToken({
|
||||||
CurrentPassword: current_password,
|
CurrentPassword: current_password,
|
||||||
NewPassword: password,
|
NewPassword: password,
|
||||||
@ -218,13 +149,7 @@
|
|||||||
PgpPublicKey: update_pgp_public_key,
|
PgpPublicKey: update_pgp_public_key,
|
||||||
AllowTrustedDevices: update_security_allow_trusted,
|
AllowTrustedDevices: update_security_allow_trusted,
|
||||||
TwoFactorEnabled: update_security_two_factor,
|
TwoFactorEnabled: update_security_two_factor,
|
||||||
RecoveryEmail: recovery,
|
RecoveryEmail: recovery
|
||||||
Website: website,
|
|
||||||
Quote: quote,
|
|
||||||
About: about,
|
|
||||||
BlogTitle: blog_title,
|
|
||||||
BlogDesc: blog_desc,
|
|
||||||
Encrypt: upload_encrypt
|
|
||||||
}),
|
}),
|
||||||
success: function (html) {
|
success: function (html) {
|
||||||
$.unblockUI();
|
$.unblockUI();
|
||||||
@ -238,15 +163,13 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
window.location.reload();
|
$("#top_msg").css('display', 'inline', 'important');
|
||||||
|
$("#top_msg").html('<div class="alert alert-success alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>Settings Saved!</div>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var error = html;
|
|
||||||
if (html.error)
|
|
||||||
error = html.error;
|
|
||||||
$("#top_msg").css('display', 'inline', 'important');
|
$("#top_msg").css('display', 'inline', 'important');
|
||||||
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + error + '</div>');
|
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + parseErrorMessage(html) + '</div>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -268,11 +191,8 @@
|
|||||||
$("#top_msg").html('<div class="alert alert-success alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>The Password Reset Link has been sent to your recovery email.</div>');
|
$("#top_msg").html('<div class="alert alert-success alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>The Password Reset Link has been sent to your recovery email.</div>');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var error = html;
|
|
||||||
if (html.error)
|
|
||||||
error = html.error;
|
|
||||||
$("#top_msg").css('display', 'inline', 'important');
|
$("#top_msg").css('display', 'inline', 'important');
|
||||||
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + html.error + '</div>');
|
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + parseErrorMessage(html) + '</div>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -296,11 +216,8 @@
|
|||||||
$("#top_msg").html('<div class="alert alert-success alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>Password has successfully been reset.</div>');
|
$("#top_msg").html('<div class="alert alert-success alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>Password has successfully been reset.</div>');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var error = html;
|
|
||||||
if (html.error)
|
|
||||||
error = html.error;
|
|
||||||
$("#top_msg").css('display', 'inline', 'important');
|
$("#top_msg").css('display', 'inline', 'important');
|
||||||
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + html.error + '</div>');
|
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + parseErrorMessage(html) + '</div>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -320,15 +237,8 @@ function editAuthToken(authTokenId) {
|
|||||||
$('#authTokenName_' + authTokenId).html(response.result.name);
|
$('#authTokenName_' + authTokenId).html(response.result.name);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
errorMsg = response;
|
|
||||||
if (response.error) {
|
|
||||||
errorMsg = response.error;
|
|
||||||
if (response.error.message) {
|
|
||||||
errorMsg = response.error.message;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$("#top_msg").css('display', 'inline', 'important');
|
$("#top_msg").css('display', 'inline', 'important');
|
||||||
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + errorMsg + '</div>');
|
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + parseErrorMessage(response) + '</div>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -351,18 +261,11 @@ function deleteAuthToken(authTokenId) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
errorMsg = response;
|
|
||||||
if (response.error) {
|
|
||||||
errorMsg = response.error;
|
|
||||||
if (response.error.message) {
|
|
||||||
errorMsg = response.error.message;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$("#top_msg").css('display', 'inline', 'important');
|
$("#top_msg").css('display', 'inline', 'important');
|
||||||
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + errorMsg + '</div>');
|
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + parseErrorMessage(response) + '</div>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
22
Teknik/Areas/User/Scripts/Settings.js
Normal file
22
Teknik/Areas/User/Scripts/Settings.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
$(document).ready(function () {
|
||||||
|
$('#delete_account').click(function () {
|
||||||
|
bootbox.confirm("Are you sure you want to delete your account?", function (result) {
|
||||||
|
if (result) {
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: deleteUserURL,
|
||||||
|
data: AddAntiForgeryToken({}),
|
||||||
|
success: function (html) {
|
||||||
|
if (html.result) {
|
||||||
|
window.location.replace(homeUrl);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$("#top_msg").css('display', 'inline', 'important');
|
||||||
|
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + parseErrorMessage(html) + '</div>');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
29
Teknik/Areas/User/Scripts/UploadSettings.js
Normal file
29
Teknik/Areas/User/Scripts/UploadSettings.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
$(document).ready(function () {
|
||||||
|
$("[name='update_upload_encrypt']").bootstrapSwitch();
|
||||||
|
|
||||||
|
$("#update_submit").click(function () {
|
||||||
|
// Start Updating Animation
|
||||||
|
$.blockUI({ message: '<div class="text-center"><h3>Updating...</h3></div>' });
|
||||||
|
|
||||||
|
upload_encrypt = $("#update_upload_encrypt").is(":checked");
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: editURL,
|
||||||
|
data: AddAntiForgeryToken({
|
||||||
|
Encrypt: upload_encrypt
|
||||||
|
}),
|
||||||
|
success: function (html) {
|
||||||
|
$.unblockUI();
|
||||||
|
if (html.result) {
|
||||||
|
$("#top_msg").css('display', 'inline', 'important');
|
||||||
|
$("#top_msg").html('<div class="alert alert-success alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>Settings Saved!</div>');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$("#top_msg").css('display', 'inline', 'important');
|
||||||
|
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + parseErrorMessage(html) + '</div>');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
});
|
@ -1,4 +1,4 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Web.Mvc;
|
using System.Web.Mvc;
|
||||||
using System.Web.Optimization;
|
using System.Web.Optimization;
|
||||||
using Teknik.Configuration;
|
using Teknik.Configuration;
|
||||||
@ -59,6 +59,46 @@ namespace Teknik.Areas.Users
|
|||||||
new { controller = "User", action = "Settings" }, // Parameter defaults
|
new { controller = "User", action = "Settings" }, // Parameter defaults
|
||||||
new[] { typeof(Controllers.UserController).Namespace }
|
new[] { typeof(Controllers.UserController).Namespace }
|
||||||
);
|
);
|
||||||
|
context.MapSubdomainRoute(
|
||||||
|
"User.SecuritySettings", // Route name
|
||||||
|
new List<string>() { "user" }, // Subdomains
|
||||||
|
new List<string>() { config.Host }, // domains
|
||||||
|
"Settings/Security", // URL with parameters
|
||||||
|
new { controller = "User", action = "SecuritySettings" }, // Parameter defaults
|
||||||
|
new[] { typeof(Controllers.UserController).Namespace }
|
||||||
|
);
|
||||||
|
context.MapSubdomainRoute(
|
||||||
|
"User.ProfileSettings", // Route name
|
||||||
|
new List<string>() { "user" }, // Subdomains
|
||||||
|
new List<string>() { config.Host }, // domains
|
||||||
|
"Settings/Profile", // URL with parameters
|
||||||
|
new { controller = "User", action = "ProfileSettings" }, // Parameter defaults
|
||||||
|
new[] { typeof(Controllers.UserController).Namespace }
|
||||||
|
);
|
||||||
|
context.MapSubdomainRoute(
|
||||||
|
"User.InviteSettings", // Route name
|
||||||
|
new List<string>() { "user" }, // Subdomains
|
||||||
|
new List<string>() { config.Host }, // domains
|
||||||
|
"Settings/Invites", // URL with parameters
|
||||||
|
new { controller = "User", action = "InviteSettings" }, // Parameter defaults
|
||||||
|
new[] { typeof(Controllers.UserController).Namespace }
|
||||||
|
);
|
||||||
|
context.MapSubdomainRoute(
|
||||||
|
"User.BlogSettings", // Route name
|
||||||
|
new List<string>() { "user" }, // Subdomains
|
||||||
|
new List<string>() { config.Host }, // domains
|
||||||
|
"Settings/Blog", // URL with parameters
|
||||||
|
new { controller = "User", action = "BlogSettings" }, // Parameter defaults
|
||||||
|
new[] { typeof(Controllers.UserController).Namespace }
|
||||||
|
);
|
||||||
|
context.MapSubdomainRoute(
|
||||||
|
"User.UploadSettings", // Route name
|
||||||
|
new List<string>() { "user" }, // Subdomains
|
||||||
|
new List<string>() { config.Host }, // domains
|
||||||
|
"Settings/Uploads", // URL with parameters
|
||||||
|
new { controller = "User", action = "UploadSettings" }, // Parameter defaults
|
||||||
|
new[] { typeof(Controllers.UserController).Namespace }
|
||||||
|
);
|
||||||
context.MapSubdomainRoute(
|
context.MapSubdomainRoute(
|
||||||
"User.ResetPassword", // Route name
|
"User.ResetPassword", // Route name
|
||||||
new List<string>() { "user" }, // Subdomains
|
new List<string>() { "user" }, // Subdomains
|
||||||
@ -123,11 +163,37 @@ namespace Teknik.Areas.Users
|
|||||||
"~/Scripts/bootstrap-switch.js",
|
"~/Scripts/bootstrap-switch.js",
|
||||||
"~/Areas/User/Scripts/User.js"));
|
"~/Areas/User/Scripts/User.js"));
|
||||||
|
|
||||||
// Register Script Bundle
|
BundleTable.Bundles.Add(new CdnScriptBundle("~/bundles/user/reset", config.CdnHost).Include(
|
||||||
|
"~/Areas/User/Scripts/ResetPass.js"));
|
||||||
|
|
||||||
|
BundleTable.Bundles.Add(new CdnScriptBundle("~/bundles/user/settings", config.CdnHost).Include(
|
||||||
|
"~/Scripts/bootbox/bootbox.min.js",
|
||||||
|
"~/Areas/User/Scripts/Settings.js"));
|
||||||
|
|
||||||
|
BundleTable.Bundles.Add(new CdnScriptBundle("~/bundles/user/settings/blog", config.CdnHost).Include(
|
||||||
|
"~/Scripts/jquery.blockUI.js",
|
||||||
|
"~/Areas/User/Scripts/BlogSettings.js"));
|
||||||
|
|
||||||
|
BundleTable.Bundles.Add(new CdnScriptBundle("~/bundles/user/settings/invite", config.CdnHost).Include(
|
||||||
|
"~/Areas/User/Scripts/InviteSettings.js"));
|
||||||
|
|
||||||
|
BundleTable.Bundles.Add(new CdnScriptBundle("~/bundles/user/settings/profile", config.CdnHost).Include(
|
||||||
|
"~/Scripts/jquery.blockUI.js",
|
||||||
|
"~/Areas/User/Scripts/ProfileSettings.js"));
|
||||||
|
|
||||||
|
BundleTable.Bundles.Add(new CdnScriptBundle("~/bundles/user/settings/security", config.CdnHost).Include(
|
||||||
|
"~/Scripts/jquery.blockUI.js",
|
||||||
|
"~/Scripts/bootstrap-switch.js",
|
||||||
|
"~/Areas/User/Scripts/SecuritySettings.js"));
|
||||||
|
|
||||||
|
BundleTable.Bundles.Add(new CdnScriptBundle("~/bundles/user/settings/upload", config.CdnHost).Include(
|
||||||
|
"~/Scripts/jquery.blockUI.js",
|
||||||
|
"~/Scripts/bootstrap-switch.js",
|
||||||
|
"~/Areas/User/Scripts/UploadSettings.js"));
|
||||||
|
|
||||||
BundleTable.Bundles.Add(new CdnScriptBundle("~/bundles/checkAuthCode", config.CdnHost).Include(
|
BundleTable.Bundles.Add(new CdnScriptBundle("~/bundles/checkAuthCode", config.CdnHost).Include(
|
||||||
"~/Areas/User/Scripts/CheckAuthCode.js"));
|
"~/Areas/User/Scripts/CheckAuthCode.js"));
|
||||||
|
|
||||||
// Register Script Bundle
|
|
||||||
BundleTable.Bundles.Add(new CdnScriptBundle("~/bundles/profile", config.CdnHost).Include(
|
BundleTable.Bundles.Add(new CdnScriptBundle("~/bundles/profile", config.CdnHost).Include(
|
||||||
"~/Scripts/bootbox/bootbox.min.js",
|
"~/Scripts/bootbox/bootbox.min.js",
|
||||||
"~/Areas/User/Scripts/Profile.js"));
|
"~/Areas/User/Scripts/Profile.js"));
|
||||||
@ -135,6 +201,12 @@ namespace Teknik.Areas.Users
|
|||||||
// Register Style Bundles
|
// Register Style Bundles
|
||||||
BundleTable.Bundles.Add(new CdnStyleBundle("~/Content/user", config.CdnHost).Include(
|
BundleTable.Bundles.Add(new CdnStyleBundle("~/Content/user", config.CdnHost).Include(
|
||||||
"~/Content/bootstrap-switch/bootstrap3/bootstrap-switch.css"));
|
"~/Content/bootstrap-switch/bootstrap3/bootstrap-switch.css"));
|
||||||
|
|
||||||
|
BundleTable.Bundles.Add(new CdnStyleBundle("~/Content/user/settings/security", config.CdnHost).Include(
|
||||||
|
"~/Content/bootstrap-switch/bootstrap3/bootstrap-switch.css"));
|
||||||
|
|
||||||
|
BundleTable.Bundles.Add(new CdnStyleBundle("~/Content/user/settings/upload", config.CdnHost).Include(
|
||||||
|
"~/Content/bootstrap-switch/bootstrap3/bootstrap-switch.css"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -186,6 +186,11 @@ namespace Teknik.Areas.Users.Utility
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void EditAccount(TeknikEntities db, Config config, User user)
|
||||||
|
{
|
||||||
|
EditAccount(db, config, user, false, string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
public static void EditAccount(TeknikEntities db, Config config, User user, bool changePass, string password)
|
public static void EditAccount(TeknikEntities db, Config config, User user, bool changePass, string password)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@ -656,6 +661,34 @@ namespace Teknik.Areas.Users.Utility
|
|||||||
db.SaveChanges();
|
db.SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delete Owned Invite Codes
|
||||||
|
if (user.OwnedInviteCodes != null)
|
||||||
|
{
|
||||||
|
foreach (InviteCode code in user.OwnedInviteCodes)
|
||||||
|
{
|
||||||
|
db.InviteCodes.Remove(code);
|
||||||
|
}
|
||||||
|
db.SaveChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete Claimed Invite Code
|
||||||
|
if (user.ClaimedInviteCode != null)
|
||||||
|
{
|
||||||
|
db.InviteCodes.Remove(user.ClaimedInviteCode);
|
||||||
|
db.SaveChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete Auth Tokens
|
||||||
|
List<AuthToken> authTokens = db.AuthTokens.Where(t => t.User.UserId == user.UserId).ToList();
|
||||||
|
if (authTokens != null)
|
||||||
|
{
|
||||||
|
foreach (AuthToken authToken in authTokens)
|
||||||
|
{
|
||||||
|
db.AuthTokens.Remove(authToken);
|
||||||
|
}
|
||||||
|
db.SaveChanges();
|
||||||
|
}
|
||||||
|
|
||||||
// Delete User
|
// Delete User
|
||||||
db.Users.Remove(user);
|
db.Users.Remove(user);
|
||||||
db.SaveChanges();
|
db.SaveChanges();
|
||||||
|
22
Teknik/Areas/User/ViewModels/BlogSettingsViewModel.cs
Normal file
22
Teknik/Areas/User/ViewModels/BlogSettingsViewModel.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using Teknik.Areas.Users.Models;
|
||||||
|
using Teknik.ViewModels;
|
||||||
|
|
||||||
|
namespace Teknik.Areas.Users.ViewModels
|
||||||
|
{
|
||||||
|
public class BlogSettingsViewModel : SettingsViewModel
|
||||||
|
{
|
||||||
|
public string Title { get; set; }
|
||||||
|
|
||||||
|
public string Description { get; set; }
|
||||||
|
|
||||||
|
public BlogSettingsViewModel()
|
||||||
|
{
|
||||||
|
Title = string.Empty;
|
||||||
|
Description = string.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
21
Teknik/Areas/User/ViewModels/InviteCodeViewModel.cs
Normal file
21
Teknik/Areas/User/ViewModels/InviteCodeViewModel.cs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using Teknik.ViewModels;
|
||||||
|
|
||||||
|
namespace Teknik.Areas.Users.ViewModels
|
||||||
|
{
|
||||||
|
public class InviteCodeViewModel : ViewModelBase
|
||||||
|
{
|
||||||
|
public int InviteCodeId { get; set; }
|
||||||
|
|
||||||
|
public bool Active { get; set; }
|
||||||
|
|
||||||
|
public string Code { get; set; }
|
||||||
|
|
||||||
|
public virtual Models.User Owner { get; set; }
|
||||||
|
|
||||||
|
public virtual Models.User ClaimedUser { get; set; }
|
||||||
|
}
|
||||||
|
}
|
21
Teknik/Areas/User/ViewModels/InviteSettingsViewModel.cs
Normal file
21
Teknik/Areas/User/ViewModels/InviteSettingsViewModel.cs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using Teknik.Areas.Users.Models;
|
||||||
|
using Teknik.ViewModels;
|
||||||
|
|
||||||
|
namespace Teknik.Areas.Users.ViewModels
|
||||||
|
{
|
||||||
|
public class InviteSettingsViewModel : SettingsViewModel
|
||||||
|
{
|
||||||
|
public List<InviteCodeViewModel> AvailableCodes { get; set; }
|
||||||
|
public List<InviteCodeViewModel> ClaimedCodes { get; set; }
|
||||||
|
|
||||||
|
public InviteSettingsViewModel()
|
||||||
|
{
|
||||||
|
AvailableCodes = new List<InviteCodeViewModel>();
|
||||||
|
ClaimedCodes = new List<InviteCodeViewModel>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
27
Teknik/Areas/User/ViewModels/ProfileSettingsViewModel.cs
Normal file
27
Teknik/Areas/User/ViewModels/ProfileSettingsViewModel.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.Mvc;
|
||||||
|
using Teknik.Areas.Users.Models;
|
||||||
|
using Teknik.ViewModels;
|
||||||
|
|
||||||
|
namespace Teknik.Areas.Users.ViewModels
|
||||||
|
{
|
||||||
|
public class ProfileSettingsViewModel : SettingsViewModel
|
||||||
|
{
|
||||||
|
[AllowHtml]
|
||||||
|
public string About { get; set; }
|
||||||
|
|
||||||
|
public string Website { get; set; }
|
||||||
|
|
||||||
|
public string Quote { get; set; }
|
||||||
|
|
||||||
|
public ProfileSettingsViewModel()
|
||||||
|
{
|
||||||
|
About = string.Empty;
|
||||||
|
Website = string.Empty;
|
||||||
|
Quote = string.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using Teknik.Areas.Users.Models;
|
using Teknik.Areas.Users.Models;
|
||||||
using Teknik.Utilities;
|
using Teknik.Utilities;
|
||||||
@ -24,6 +24,9 @@ namespace Teknik.Areas.Users.ViewModels
|
|||||||
[DataType(DataType.Password)]
|
[DataType(DataType.Password)]
|
||||||
public string ConfirmPassword { get; set; }
|
public string ConfirmPassword { get; set; }
|
||||||
|
|
||||||
|
[Display(Name = "InviteCode")]
|
||||||
|
public string InviteCode { get; set; }
|
||||||
|
|
||||||
[Display(Name = "Recovery Email")]
|
[Display(Name = "Recovery Email")]
|
||||||
[DataType(DataType.EmailAddress)]
|
[DataType(DataType.EmailAddress)]
|
||||||
public string RecoveryEmail { get; set; }
|
public string RecoveryEmail { get; set; }
|
||||||
@ -34,4 +37,4 @@ namespace Teknik.Areas.Users.ViewModels
|
|||||||
|
|
||||||
public string ReturnUrl { get; set; }
|
public string ReturnUrl { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
50
Teknik/Areas/User/ViewModels/SecuritySettingsViewModel.cs
Normal file
50
Teknik/Areas/User/ViewModels/SecuritySettingsViewModel.cs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.Mvc;
|
||||||
|
using Teknik.Areas.Users.Models;
|
||||||
|
using Teknik.ViewModels;
|
||||||
|
|
||||||
|
namespace Teknik.Areas.Users.ViewModels
|
||||||
|
{
|
||||||
|
public class SecuritySettingsViewModel : SettingsViewModel
|
||||||
|
{
|
||||||
|
[AllowHtml]
|
||||||
|
public string CurrentPassword { get; set; }
|
||||||
|
|
||||||
|
[AllowHtml]
|
||||||
|
public string NewPassword { get; set; }
|
||||||
|
|
||||||
|
[AllowHtml]
|
||||||
|
public string NewPasswordConfirm { get; set; }
|
||||||
|
|
||||||
|
public string PgpPublicKey { get; set; }
|
||||||
|
|
||||||
|
public string RecoveryEmail { get; set; }
|
||||||
|
|
||||||
|
public bool RecoveryVerified { get; set; }
|
||||||
|
|
||||||
|
public bool AllowTrustedDevices { get; set; }
|
||||||
|
|
||||||
|
public bool TwoFactorEnabled { get; set; }
|
||||||
|
|
||||||
|
public string TwoFactorKey { get; set; }
|
||||||
|
|
||||||
|
public int TrustedDeviceCount { get; set; }
|
||||||
|
|
||||||
|
public List<AuthTokenViewModel> AuthTokens { get; set; }
|
||||||
|
|
||||||
|
public SecuritySettingsViewModel()
|
||||||
|
{
|
||||||
|
TrustedDeviceCount = 0;
|
||||||
|
AuthTokens = new List<AuthTokenViewModel>();
|
||||||
|
RecoveryEmail = string.Empty;
|
||||||
|
RecoveryVerified = false;
|
||||||
|
AllowTrustedDevices = false;
|
||||||
|
TwoFactorEnabled = false;
|
||||||
|
TwoFactorKey = string.Empty;
|
||||||
|
PgpPublicKey = string.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
@ -13,16 +13,6 @@ namespace Teknik.Areas.Users.ViewModels
|
|||||||
|
|
||||||
public string Username { get; set; }
|
public string Username { get; set; }
|
||||||
|
|
||||||
public int TrustedDeviceCount { get; set; }
|
public string Page { get; set; }
|
||||||
|
|
||||||
public List<AuthTokenViewModel> AuthTokens { get; set; }
|
|
||||||
|
|
||||||
public UserSettings UserSettings { get; set; }
|
|
||||||
|
|
||||||
public SecuritySettings SecuritySettings { get; set; }
|
|
||||||
|
|
||||||
public BlogSettings BlogSettings { get; set; }
|
|
||||||
|
|
||||||
public UploadSettings UploadSettings { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
19
Teknik/Areas/User/ViewModels/UploadSettingsViewModel.cs
Normal file
19
Teknik/Areas/User/ViewModels/UploadSettingsViewModel.cs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using Teknik.Areas.Users.Models;
|
||||||
|
using Teknik.ViewModels;
|
||||||
|
|
||||||
|
namespace Teknik.Areas.Users.ViewModels
|
||||||
|
{
|
||||||
|
public class UploadSettingsViewModel : SettingsViewModel
|
||||||
|
{
|
||||||
|
public bool Encrypt { get; set; }
|
||||||
|
|
||||||
|
public UploadSettingsViewModel()
|
||||||
|
{
|
||||||
|
Encrypt = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
@model Teknik.Areas.Users.ViewModels.RegisterViewModel
|
@model Teknik.Areas.Users.ViewModels.RegisterViewModel
|
||||||
|
|
||||||
@using Teknik.Utilities
|
@using Teknik.Utilities
|
||||||
|
|
||||||
@ -17,19 +17,30 @@
|
|||||||
<form id="registrationForm" action="@Url.SubRouteUrl("user", "User.Register")" method="post" accept-charset="UTF-8">
|
<form id="registrationForm" action="@Url.SubRouteUrl("user", "User.Register")" method="post" accept-charset="UTF-8">
|
||||||
<input name="Register.ReturnUrl" id="registerReturnUrl" type="hidden" value="@Model.ReturnUrl" />
|
<input name="Register.ReturnUrl" id="registerReturnUrl" type="hidden" value="@Model.ReturnUrl" />
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<input type="text" class="form-control" id="registerUsername" value="" placeholder="Username" name="Register.Username" data-val-required="The Username field is required." data-val="true"/>
|
<label for="registerUsername">Username</label>
|
||||||
|
<input type="text" class="form-control" id="registerUsername" value="" placeholder="Bob" name="Register.Username" data-val-required="The Username field is required." data-val="true"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<input type="password" class="form-control" id="registerPassword" value="" placeholder="Password" name="Register.Password" data-val-required="The Password field is required." data-val="true"/>
|
<label for="registerPassword">Password</label>
|
||||||
|
<input type="password" class="form-control" id="registerPassword" value="" placeholder="********" name="Register.Password" data-val-required="The Password field is required." data-val="true"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<input type="password" class="form-control" id="registerConfirmPassword" value="" placeholder="Confirm Password" name="Register.ConfirmPassword" data-val-required="The Confirm Password field is required." data-val="true" />
|
<label for="registerConfirmPassword">Confirm Password</label>
|
||||||
|
<input type="password" class="form-control" id="registerConfirmPassword" value="" placeholder="********" name="Register.ConfirmPassword" data-val-required="The Confirm Password field is required." data-val="true"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<input type="text" class="form-control" id="registerRecoveryEmail" value="" placeholder="Recovery Email (Optional)" name="Register.RecoveryEmail" />
|
<label for="registerInviteCode">Invite Code@(Model.Config.UserConfig.InviteCodeRequired ? string.Empty : " (Optional)")</label>
|
||||||
|
<input type="text" class="form-control" id="registerInviteCode" value="@Model.InviteCode" placeholder="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" name="Register.InviteCode"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<textarea class="form-control" id="registerPublicKey" name="Register.PublicKey" placeholder="PGP Public Key (Optional)" title="enter your pgp public key" rows="5"></textarea>
|
<label for="registerRecoveryEmail">Recovery Email (Optional)</label>
|
||||||
|
<input type="text" class="form-control" id="registerRecoveryEmail" value="" placeholder="user@example.com" name="Register.RecoveryEmail"/>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="registerPublicKey">PGP Public Key (Optional)</label>
|
||||||
|
<textarea class="form-control" id="registerPublicKey" name="Register.PublicKey" placeholder="-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
...
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----" title="enter your pgp public key" rows="5"></textarea>
|
||||||
</div>
|
</div>
|
||||||
<p class="text-center">
|
<p class="text-center">
|
||||||
<small>
|
<small>
|
||||||
@ -48,4 +59,4 @@
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
<h3>Registration has been disabled</h3>
|
<h3>Registration has been disabled</h3>
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
@model Teknik.Areas.Users.ViewModels.ResetPasswordViewModel
|
@model Teknik.Areas.Users.ViewModels.ResetPasswordViewModel
|
||||||
|
|
||||||
@using Teknik.Utilities
|
@using Teknik.Utilities
|
||||||
|
|
||||||
@Scripts.Render("~/bundles/user")
|
@Scripts.Render("~/bundles/user/reset")
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@ -31,4 +31,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
@model Teknik.Areas.Users.ViewModels.ResetPasswordVerificationViewModel
|
@model Teknik.Areas.Users.ViewModels.ResetPasswordVerificationViewModel
|
||||||
|
|
||||||
@using Teknik.Utilities
|
@using Teknik.Utilities
|
||||||
|
|
||||||
@Scripts.Render("~/bundles/user")
|
@Scripts.Render("~/bundles/user/reset")
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
@ -1,255 +0,0 @@
|
|||||||
@model Teknik.Areas.Users.ViewModels.SettingsViewModel
|
|
||||||
|
|
||||||
@using Teknik.Utilities
|
|
||||||
@using Teknik.Areas.Users.ViewModels
|
|
||||||
|
|
||||||
<script>
|
|
||||||
var homeUrl = '@Url.SubRouteUrl("www", "Home.Index")';
|
|
||||||
var editUserURL = '@Url.SubRouteUrl("user", "User.Action", new { action = "Edit" })';
|
|
||||||
var deleteUserURL = '@Url.SubRouteUrl("user", "User.Action", new { action = "Delete" })';
|
|
||||||
var resendVerifyURL = '@Url.SubRouteUrl("user", "User.Action", new { action = "ResendVerifyRecoveryEmail"})';
|
|
||||||
var confirmAuthSetupURL = '@Url.SubRouteUrl("user", "User.Action", new { action = "VerifyAuthenticatorCode" })';
|
|
||||||
var clearTrustedDevicesURL = '@Url.SubRouteUrl("user", "User.Action", new { action = "ClearTrustedDevices" })';
|
|
||||||
var generateTokenURL = '@Url.SubRouteUrl("user", "User.Action", new { action = "GenerateToken" })';
|
|
||||||
var revokeAllTokensURL = '@Url.SubRouteUrl("user", "User.Action", new { action = "RevokeAllTokens" })';
|
|
||||||
var editTokenNameURL = '@Url.SubRouteUrl("user", "User.Action", new { action = "EditTokenName" })';
|
|
||||||
var deleteTokenURL = '@Url.SubRouteUrl("user", "User.Action", new { action = "DeleteToken" })';
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@Styles.Render("~/Content/user")
|
|
||||||
@Scripts.Render("~/bundles/user")
|
|
||||||
|
|
||||||
<div class="container">
|
|
||||||
@if (!Model.Error)
|
|
||||||
{
|
|
||||||
<div class="modal fade" id="authenticatorSetup" tabindex="-1" role="dialog" aria-labelledby="authenticatorSetupLabel" aria-hidden="true">
|
|
||||||
<div class="modal-dialog">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span></button>
|
|
||||||
<h4 class="modal-title" id="authSetupTitleLabel">Set Up a Third Party App to Generate Codes</h4>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-12 text-center">
|
|
||||||
<div id="authSetupStatus"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<form class="form" action="##" method="post" id="confirmAuthSetup">
|
|
||||||
<p>To get a third party app working, either scan the QR code below or type the secret key into the app.</p>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-4">
|
|
||||||
<p class="text-muted">QR Code:</p>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-8">
|
|
||||||
<img id="authQRCode" src="@Url.SubRouteUrl("user", "User.Action", new { action = "GenerateAuthQrCode", key = Model.SecuritySettings.TwoFactorKey })" width="200" height="200" alt="qr code" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-4">
|
|
||||||
<p class="text-muted">Secret Key:</p>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-8">
|
|
||||||
<span class="text-success" id="authSetupSecretKey">@Model.SecuritySettings.TwoFactorKey</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<hr />
|
|
||||||
<p>To confirm the third party app is set up correctly, enter the security code that appears on your phone.</p>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-4">
|
|
||||||
<p class="text-muted">Security Code:</p>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-6">
|
|
||||||
<input class="form-control" id="auth_setup_code" name="auth_setup_code" title="Authenticator Security Code" type="text" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<hr />
|
|
||||||
<div class="form-group text-right">
|
|
||||||
<button class="btn btn-primary" id="auth_setup_verify" type="button" name="auth_setup_verify">Verify</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-12">
|
|
||||||
<form class="form" action="##" method="post" id="updateForm">
|
|
||||||
<input name="update_userid" id="update_userid" type="hidden" value="@Model.UserID" />
|
|
||||||
<!-- Tab Navigation -->
|
|
||||||
<ul class="nav nav-tabs" id="settingTabs">
|
|
||||||
<li class="active"><a href="#profile" data-toggle="tab"> Profile </a></li>
|
|
||||||
<li><a href="#security" data-toggle="tab"> Security </a></li>
|
|
||||||
<li><a href="#blog" data-toggle="tab"> Blog </a></li>
|
|
||||||
<li><a href="#uploads" data-toggle="tab"> Uploads </a></li>
|
|
||||||
</ul>
|
|
||||||
<div class="tab-content">
|
|
||||||
<!-- Profile Settings -->
|
|
||||||
<div class="tab-pane active" id="profile">
|
|
||||||
<div class="row">
|
|
||||||
<div class="form-group col-sm-4">
|
|
||||||
<label for="update_website"><h4>Website</h4></label>
|
|
||||||
<input class="form-control" id="update_website" name="update_website" placeholder="http://www.noneofyourbusiness.com/" title="enter your website" type="text" value="@Model.UserSettings.Website" />
|
|
||||||
</div>
|
|
||||||
<div class="form-group col-sm-8">
|
|
||||||
<label for="update_quote"><h4>Quote</h4></label>
|
|
||||||
<input class="form-control" id="update_quote" name="update_quote" placeholder="I have a dream!" title="enter a memorable quote" type="text" value="@Model.UserSettings.Quote" maxlength="140" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="form-group col-sm-12">
|
|
||||||
<label for="update_about"><h4>About Yourself</h4></label>
|
|
||||||
<textarea class="form-control" name="update_about" id="update_about" placeholder="I'm awesome" title="enter any information you want to share with the world." data-provide="markdown" rows="10">@Model.UserSettings.About</textarea>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- Security Settings -->
|
|
||||||
<div class="tab-pane" id="security">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-4">
|
|
||||||
<div class="row">
|
|
||||||
<div class="form-group col-sm-12">
|
|
||||||
<label for="update_password_current"><h4>Current Password</h4></label>
|
|
||||||
<input class="form-control" name="update_password_current" id="update_password_current" placeholder="current password" title="enter your current password." type="password" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="form-group col-sm-12">
|
|
||||||
<label for="update_password"><h4>New Password</h4></label>
|
|
||||||
<input class="form-control" name="update_password" id="update_password" placeholder="new password" title="enter your password." type="password" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="form-group col-sm-12">
|
|
||||||
<label for="update_password_confirm"><h4>Verify New Password</h4></label>
|
|
||||||
<input class="form-control" name="update_password_confirm" id="update_password_confirm" placeholder="new password confirmed" title="enter your password again." type="password" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-8">
|
|
||||||
<label for="update_pgp_public_key"><h4>Public Key</h4></label>
|
|
||||||
<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 class="row">
|
|
||||||
<div class="col-sm-4 text-left">
|
|
||||||
<div class="row">
|
|
||||||
<div class="form-group col-sm-12">
|
|
||||||
<label for="update_recovery_email"><h4>Recovery Email</h4></label>
|
|
||||||
<input class="form-control" name="update_recovery_email" id="update_recovery_email" placeholder="user@example.com" title="enter a recovery email." type="text" value="@Model.SecuritySettings.RecoveryEmail" />
|
|
||||||
@if (!string.IsNullOrEmpty(Model.SecuritySettings.RecoveryEmail))
|
|
||||||
{
|
|
||||||
<p class="form-control-static">
|
|
||||||
@if (Model.SecuritySettings.RecoveryVerified)
|
|
||||||
{
|
|
||||||
<span class="text-success"><i class="fa fa-check"></i> Verified</span>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<span class="text-danger"><i class="fa fa-ban"></i> Unverified</span> <small><a href="#" class="text-primary" id="ResendVerification"><i class="fa fa-repeat"></i> Resend</a></small>
|
|
||||||
}
|
|
||||||
</p>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="form-group col-sm-12 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>
|
|
||||||
<div class="row">
|
|
||||||
<div class="form-group col-sm-12 text-left">
|
|
||||||
<label for="update_security_allow_trusted"><h4>Allow Trusted Devices</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>
|
|
||||||
<p class="form-control-static @(Model.SecuritySettings.AllowTrustedDevices ? string.Empty : "hide")" id="ClearDevicesLink">
|
|
||||||
<small><a href="#" class="text-primary" id="ClearDevices">Clear Trusted Devices (@Model.TrustedDeviceCount)</a></small>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-8">
|
|
||||||
<br />
|
|
||||||
<label for="authTokens"><h4>Authentication Tokens</h4></label><span class="pull-right"><button type="button" class="btn btn-default" id="generate_token">Generate Token</button> <button type="button" class="btn btn-danger" id="revoke_all_tokens">Revoke All</button></span>
|
|
||||||
<div id="authTokens" style="overflow-y: auto; max-height: 400px;">
|
|
||||||
<ul class="list-group" id="authTokenList">
|
|
||||||
@if (Model.AuthTokens.Any())
|
|
||||||
{
|
|
||||||
foreach (AuthTokenViewModel token in Model.AuthTokens)
|
|
||||||
{
|
|
||||||
@Html.Partial("AuthToken", token)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<li class="list-group-item text-center" id="noAuthTokens">No Authentication Tokens</li>
|
|
||||||
}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- Blog Settings -->
|
|
||||||
<div class="tab-pane" id="blog">
|
|
||||||
<div class="row">
|
|
||||||
<div class="form-group col-sm-6">
|
|
||||||
<label for="update_blog_title"><h4>Title</h4></label>
|
|
||||||
<input class="form-control" id="update_blog_title" name="update_blog_title" placeholder="click bait" title="enter your blog's title" type="text" value="@Model.BlogSettings.Title" />
|
|
||||||
</div>
|
|
||||||
<div class="form-group col-sm-6">
|
|
||||||
<label for="update_blog_description"><h4>Description</h4></label>
|
|
||||||
<input class="form-control" id="update_blog_description" name="update_blog_description" placeholder="This blog is not worth reading." title="enter your blog's description" type="text" value="@Model.BlogSettings.Description" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- Upload Settings -->
|
|
||||||
<div class="tab-pane" id="uploads">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-6">
|
|
||||||
<div class="checkbox">
|
|
||||||
<label>
|
|
||||||
<label for="update_upload_encrypt"><h4>Encrypt in Browser</h4></label>
|
|
||||||
<input id="update_upload_encrypt" name="update_upload_encrypt" title="whether the file should be encrypted in the browser before upload" type="checkbox" value="true" @(Model.UploadSettings.Encrypt ? "checked" : string.Empty) />
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- Save Settings -->
|
|
||||||
<div class="row">
|
|
||||||
<div class="form-group col-sm-10">
|
|
||||||
<br />
|
|
||||||
<button class="btn btn-lg btn-success" id="update_submit" type="submit"><i class="glyphicon glyphicon-ok-sign"></i> Save</button>
|
|
||||||
<button class="btn btn-lg" type="reset"><i class="glyphicon glyphicon-repeat"></i> Reset</button>
|
|
||||||
</div>
|
|
||||||
<div class="form-group col-sm-2">
|
|
||||||
<br />
|
|
||||||
<button type="button" class="btn btn-danger" id="delete_account">Delete Account</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
</div><!--/col-9-->
|
|
||||||
</div><!--/row-->
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-12 text-center">
|
|
||||||
<h2>Sorry, but I couldn't find that user.</h2>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
36
Teknik/Areas/User/Views/User/Settings/BlogSettings.cshtml
Normal file
36
Teknik/Areas/User/Views/User/Settings/BlogSettings.cshtml
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
@model Teknik.Areas.Users.ViewModels.BlogSettingsViewModel
|
||||||
|
|
||||||
|
@using Teknik.Utilities
|
||||||
|
@using Teknik.Areas.Users.ViewModels
|
||||||
|
|
||||||
|
@{
|
||||||
|
Layout = "~/Areas/User/Views/User/Settings/Settings.cshtml";
|
||||||
|
}
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var editURL = '@Url.SubRouteUrl("user", "User.Action", new { action = "EditBlog" })';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
@Styles.Render("~/Content/user/settings/blog")
|
||||||
|
@Scripts.Render("~/bundles/user/settings/blog")
|
||||||
|
|
||||||
|
|
||||||
|
<form class="form" action="##" method="post" id="updateForm">
|
||||||
|
<div class="row">
|
||||||
|
<div class="form-group col-sm-6">
|
||||||
|
<label for="update_blog_title"><h4>Title</h4></label>
|
||||||
|
<input class="form-control" id="update_blog_title" name="update_blog_title" placeholder="click bait" title="enter your blog's title" type="text" value="@Model.Title" />
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-sm-6">
|
||||||
|
<label for="update_blog_description"><h4>Description</h4></label>
|
||||||
|
<input class="form-control" id="update_blog_description" name="update_blog_description" placeholder="This blog is not worth reading." title="enter your blog's description" type="text" value="@Model.Description" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="form-group col-sm-10">
|
||||||
|
<br />
|
||||||
|
<button class="btn btn-lg btn-success" id="update_submit" type="submit"><i class="glyphicon glyphicon-ok-sign"></i> Save</button>
|
||||||
|
<button class="btn btn-lg" type="reset"><i class="glyphicon glyphicon-repeat"></i> Reset</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
21
Teknik/Areas/User/Views/User/Settings/InviteCode.cshtml
Normal file
21
Teknik/Areas/User/Views/User/Settings/InviteCode.cshtml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
@using Teknik.Utilities
|
||||||
|
@model Teknik.Areas.Users.ViewModels.InviteCodeViewModel
|
||||||
|
|
||||||
|
@{
|
||||||
|
bool codeClaimed = Model.ClaimedUser != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
<li class="list-group-item @(Model.Active ? string.Empty : ".disabled")" id="inviteCode_@Model.InviteCodeId">
|
||||||
|
@if (!codeClaimed)
|
||||||
|
{
|
||||||
|
<div class="btn-group btn-group-sm pull-right" role="group" aria-label="...">
|
||||||
|
<button type="button" class="btn btn-default" id="copyCode_@Model.InviteCodeId" onclick="copyCode(@(Model.InviteCodeId), '@(Model.Code)');" data-toggle="popover" data-trigger="manual" data-placement="top" data-content="Copied to Clipboard" data-container="body"><i class="fa fa-clipboard"></i></button>
|
||||||
|
<button type="button" class="btn btn-default" onclick="createExternalLink(@Model.InviteCodeId);"><i class="fa fa-external-link"></i></button>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
<h4 class="list-group-item-heading" id="inviteCode_Code_@Model.InviteCodeId">@Model.Code</h4>
|
||||||
|
@if (codeClaimed)
|
||||||
|
{
|
||||||
|
<p class="list-group-item-text">Claimed by <a href="@Url.SubRouteUrl("user", "User.ViewProfile", new {username = Model.ClaimedUser.Username})">@Model.ClaimedUser.Username</a></p>
|
||||||
|
}
|
||||||
|
</li>
|
59
Teknik/Areas/User/Views/User/Settings/InviteSettings.cshtml
Normal file
59
Teknik/Areas/User/Views/User/Settings/InviteSettings.cshtml
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
@model Teknik.Areas.Users.ViewModels.InviteSettingsViewModel
|
||||||
|
|
||||||
|
@using Teknik.Utilities
|
||||||
|
@using Teknik.Areas.Users.ViewModels
|
||||||
|
|
||||||
|
@{
|
||||||
|
Layout = "~/Areas/User/Views/User/Settings/Settings.cshtml";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Styles.Render("~/Content/user/settings/invite")
|
||||||
|
@Scripts.Render("~/bundles/user/settings/invite")
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var createExternalLinkURL = '@Url.SubRouteUrl("user", "User.Action", new { action = "CreateInviteCodeLink" })';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-10 col-sm-offset-1">
|
||||||
|
<br />
|
||||||
|
<label for="availableCodes"><h4>Available Invite Codes</h4></label>
|
||||||
|
<div id="availableCodes" style="overflow-y: auto; max-height: 400px;">
|
||||||
|
<ul class="list-group" id="availableCodeList">
|
||||||
|
@if (Model.AvailableCodes.Any())
|
||||||
|
{
|
||||||
|
foreach (InviteCodeViewModel code in Model.AvailableCodes)
|
||||||
|
{
|
||||||
|
@Html.Partial("Settings/InviteCode", code)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<li class="list-group-item text-center" id="noAvailableCodes">No Invite Codes Available</li>
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-10 col-sm-offset-1">
|
||||||
|
<br />
|
||||||
|
<label for="claimedCodes"><h4>Claimed Invite Codes</h4></label>
|
||||||
|
<div id="claimedCodes" style="overflow-y: auto; max-height: 400px;">
|
||||||
|
<ul class="list-group" id="claimedCodeList">
|
||||||
|
@if (Model.ClaimedCodes.Any())
|
||||||
|
{
|
||||||
|
foreach (InviteCodeViewModel code in Model.ClaimedCodes)
|
||||||
|
{
|
||||||
|
@Html.Partial("Settings/InviteCode", code)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<li class="list-group-item text-center" id="noClaimedCodes">No Invite Codes have been Claimed</li>
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
41
Teknik/Areas/User/Views/User/Settings/ProfileSettings.cshtml
Normal file
41
Teknik/Areas/User/Views/User/Settings/ProfileSettings.cshtml
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
@model Teknik.Areas.Users.ViewModels.ProfileSettingsViewModel
|
||||||
|
|
||||||
|
@using Teknik.Utilities
|
||||||
|
@using Teknik.Areas.Users.ViewModels
|
||||||
|
|
||||||
|
@{
|
||||||
|
Layout = "~/Areas/User/Views/User/Settings/Settings.cshtml";
|
||||||
|
}
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var editURL = '@Url.SubRouteUrl("user", "User.Action", new { action = "EditProfile" })';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
@Styles.Render("~/Content/user/settings/profile")
|
||||||
|
@Scripts.Render("~/bundles/user/settings/profile")
|
||||||
|
|
||||||
|
<form class="form" action="##" method="post" id="updateForm">
|
||||||
|
<div class="row">
|
||||||
|
<div class="form-group col-sm-4">
|
||||||
|
<label for="update_website"><h4>Website</h4></label>
|
||||||
|
<input class="form-control" id="update_website" name="update_website" placeholder="http://www.noneofyourbusiness.com/" title="enter your website" type="text" value="@Model.Website" />
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-sm-8">
|
||||||
|
<label for="update_quote"><h4>Quote</h4></label>
|
||||||
|
<input class="form-control" id="update_quote" name="update_quote" placeholder="I have a dream!" title="enter a memorable quote" type="text" value="@Model.Quote" maxlength="140" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="form-group col-sm-12">
|
||||||
|
<label for="update_about"><h4>About Yourself</h4></label>
|
||||||
|
<textarea class="form-control" name="update_about" id="update_about" placeholder="I'm awesome" title="enter any information you want to share with the world." data-provide="markdown" rows="10">@Model.About</textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="form-group col-sm-10">
|
||||||
|
<br />
|
||||||
|
<button class="btn btn-lg btn-success" id="update_submit" type="submit"><i class="glyphicon glyphicon-ok-sign"></i> Save</button>
|
||||||
|
<button class="btn btn-lg" type="reset"><i class="glyphicon glyphicon-repeat"></i> Reset</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
178
Teknik/Areas/User/Views/User/Settings/SecuritySettings.cshtml
Normal file
178
Teknik/Areas/User/Views/User/Settings/SecuritySettings.cshtml
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
@model Teknik.Areas.Users.ViewModels.SecuritySettingsViewModel
|
||||||
|
|
||||||
|
@using Teknik.Utilities
|
||||||
|
@using Teknik.Areas.Users.ViewModels
|
||||||
|
|
||||||
|
@{
|
||||||
|
Layout = "~/Areas/User/Views/User/Settings/Settings.cshtml";
|
||||||
|
}
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var homeUrl = '@Url.SubRouteUrl("www", "Home.Index")';
|
||||||
|
var editURL = '@Url.SubRouteUrl("user", "User.Action", new { action = "EditSecurity" })';
|
||||||
|
var resendVerifyURL = '@Url.SubRouteUrl("user", "User.Action", new { action = "ResendVerifyRecoveryEmail"})';
|
||||||
|
var confirmAuthSetupURL = '@Url.SubRouteUrl("user", "User.Action", new { action = "VerifyAuthenticatorCode" })';
|
||||||
|
var clearTrustedDevicesURL = '@Url.SubRouteUrl("user", "User.Action", new { action = "ClearTrustedDevices" })';
|
||||||
|
var generateTokenURL = '@Url.SubRouteUrl("user", "User.Action", new { action = "GenerateToken" })';
|
||||||
|
var revokeAllTokensURL = '@Url.SubRouteUrl("user", "User.Action", new { action = "RevokeAllTokens" })';
|
||||||
|
var editTokenNameURL = '@Url.SubRouteUrl("user", "User.Action", new { action = "EditTokenName" })';
|
||||||
|
var deleteTokenURL = '@Url.SubRouteUrl("user", "User.Action", new { action = "DeleteToken" })';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
@Styles.Render("~/Content/user/settings/security")
|
||||||
|
@Scripts.Render("~/bundles/user/settings/security")
|
||||||
|
|
||||||
|
<div class="modal fade" id="authenticatorSetup" tabindex="-1" role="dialog" aria-labelledby="authenticatorSetupLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span></button>
|
||||||
|
<h4 class="modal-title" id="authSetupTitleLabel">Set Up a Third Party App to Generate Codes</h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12 text-center">
|
||||||
|
<div id="authSetupStatus"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<form class="form" action="##" method="post" id="confirmAuthSetup">
|
||||||
|
<p>To get a third party app working, either scan the QR code below or type the secret key into the app.</p>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<p class="text-muted">QR Code:</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<img id="authQRCode" src="@Url.SubRouteUrl("user", "User.Action", new { action = "GenerateAuthQrCode", key = Model.TwoFactorKey })" width="200" height="200" alt="qr code" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<p class="text-muted">Secret Key:</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<span class="text-success" id="authSetupSecretKey">@Model.TwoFactorKey</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
<p>To confirm the third party app is set up correctly, enter the security code that appears on your phone.</p>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<p class="text-muted">Security Code:</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<input class="form-control" id="auth_setup_code" name="auth_setup_code" title="Authenticator Security Code" type="text" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
<div class="form-group text-right">
|
||||||
|
<button class="btn btn-primary" id="auth_setup_verify" type="button" name="auth_setup_verify">Verify</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form class="form" action="##" method="post" id="updateForm">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<div class="row">
|
||||||
|
<div class="form-group col-sm-12">
|
||||||
|
<label for="update_password_current"><h4>Current Password</h4></label>
|
||||||
|
<input class="form-control" name="update_password_current" id="update_password_current" placeholder="current password" title="enter your current password." type="password" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="form-group col-sm-12">
|
||||||
|
<label for="update_password"><h4>New Password</h4></label>
|
||||||
|
<input class="form-control" name="update_password" id="update_password" placeholder="new password" title="enter your password." type="password" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="form-group col-sm-12">
|
||||||
|
<label for="update_password_confirm"><h4>Verify New Password</h4></label>
|
||||||
|
<input class="form-control" name="update_password_confirm" id="update_password_confirm" placeholder="new password confirmed" title="enter your password again." type="password" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<label for="update_pgp_public_key"><h4>Public Key</h4></label>
|
||||||
|
<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.PgpPublicKey</textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-4 text-left">
|
||||||
|
<div class="row">
|
||||||
|
<div class="form-group col-sm-12">
|
||||||
|
<label for="update_recovery_email"><h4>Recovery Email</h4></label>
|
||||||
|
<input class="form-control" name="update_recovery_email" id="update_recovery_email" placeholder="user@example.com" title="enter a recovery email." type="text" value="@Model.RecoveryEmail" />
|
||||||
|
@if (!string.IsNullOrEmpty(Model.RecoveryEmail))
|
||||||
|
{
|
||||||
|
<p class="form-control-static">
|
||||||
|
@if (Model.RecoveryVerified)
|
||||||
|
{
|
||||||
|
<span class="text-success"><i class="fa fa-check"></i> Verified</span>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<span class="text-danger"><i class="fa fa-ban"></i> Unverified</span> <small><a href="#" class="text-primary" id="ResendVerification"><i class="fa fa-repeat"></i> Resend</a></small>
|
||||||
|
}
|
||||||
|
</p>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="form-group col-sm-12 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.TwoFactorEnabled ? "checked" : string.Empty) />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<p class="form-control-static @(Model.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="form-group col-sm-12 text-left">
|
||||||
|
<label for="update_security_allow_trusted"><h4>Allow Trusted Devices</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.AllowTrustedDevices ? "checked" : string.Empty) />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<p class="form-control-static @(Model.AllowTrustedDevices ? string.Empty : "hide")" id="ClearDevicesLink">
|
||||||
|
<small><a href="#" class="text-primary" id="ClearDevices">Clear Trusted Devices (@Model.TrustedDeviceCount)</a></small>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<br />
|
||||||
|
<label for="authTokens"><h4>Authentication Tokens</h4></label><span class="pull-right"><button type="button" class="btn btn-default" id="generate_token">Generate Token</button> <button type="button" class="btn btn-danger" id="revoke_all_tokens">Revoke All</button></span>
|
||||||
|
<div id="authTokens" style="overflow-y: auto; max-height: 400px;">
|
||||||
|
<ul class="list-group" id="authTokenList">
|
||||||
|
@if (Model.AuthTokens.Any())
|
||||||
|
{
|
||||||
|
foreach (AuthTokenViewModel token in Model.AuthTokens)
|
||||||
|
{
|
||||||
|
@Html.Partial("Settings/AuthToken", token)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<li class="list-group-item text-center" id="noAuthTokens">No Authentication Tokens</li>
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="form-group col-sm-10">
|
||||||
|
<br />
|
||||||
|
<button class="btn btn-lg btn-success" id="update_submit" type="submit"><i class="glyphicon glyphicon-ok-sign"></i> Save</button>
|
||||||
|
<button class="btn btn-lg" type="reset"><i class="glyphicon glyphicon-repeat"></i> Reset</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
51
Teknik/Areas/User/Views/User/Settings/Settings.cshtml
Normal file
51
Teknik/Areas/User/Views/User/Settings/Settings.cshtml
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
@model Teknik.Areas.Users.ViewModels.SettingsViewModel
|
||||||
|
|
||||||
|
@{
|
||||||
|
Layout = "~/Views/Shared/_Layout.cshtml";
|
||||||
|
}
|
||||||
|
|
||||||
|
@using Teknik.Utilities
|
||||||
|
@using Teknik.Areas.Users.ViewModels
|
||||||
|
|
||||||
|
@Styles.Render("~/Content/user/settings")
|
||||||
|
@Scripts.Render("~/bundles/user/settings")
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var homeUrl = '@Url.SubRouteUrl("www", "Home.Index")';
|
||||||
|
var deleteUserURL = '@Url.SubRouteUrl("user", "User.Action", new { action = "Delete" })';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
@if (!Model.Error)
|
||||||
|
{
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-2">
|
||||||
|
<!--left col-->
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<ul class="list-group">
|
||||||
|
<div class="panel-heading text-center"><strong>Account Settings</strong></div>
|
||||||
|
<a href="@Url.SubRouteUrl("user", "User.SecuritySettings")" class="list-group-item @(Model.Page == "Security" ? "active" : string.Empty)">Security</a>
|
||||||
|
<a href="@Url.SubRouteUrl("user", "User.ProfileSettings")" class="list-group-item @(Model.Page == "Profile" ? "active" : string.Empty)">Profile</a>
|
||||||
|
<a href="@Url.SubRouteUrl("user", "User.InviteSettings")" class="list-group-item @(Model.Page == "Invite" ? "active" : string.Empty)">Invite Codes (@(User.Info.OwnedInviteCodes.Where(c => c.Active).Count()))</a>
|
||||||
|
<a href="@Url.SubRouteUrl("user", "User.BlogSettings")" class="list-group-item @(Model.Page == "Blog" ? "active" : string.Empty)">Blogging</a>
|
||||||
|
<a href="@Url.SubRouteUrl("user", "User.UploadSettings")" class="list-group-item @(Model.Page == "Upload" ? "active" : string.Empty)">Uploads</a>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="list-group text-center">
|
||||||
|
<button type="button" class="list-group-item btn-danger" id="delete_account">Delete Account</button>
|
||||||
|
</div>
|
||||||
|
</div><!--/col-2-->
|
||||||
|
<div class="col-sm-10">
|
||||||
|
@RenderBody()
|
||||||
|
</div><!--/col-10-->
|
||||||
|
</div><!--/row-->
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12 text-center">
|
||||||
|
<h2>@Model.ErrorMessage</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
12
Teknik/Areas/User/Views/User/Settings/SettingsBase.cshtml
Normal file
12
Teknik/Areas/User/Views/User/Settings/SettingsBase.cshtml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
@model Teknik.Areas.Users.ViewModels.SettingsViewModel
|
||||||
|
|
||||||
|
@{
|
||||||
|
Layout = "~/Areas/User/Views/User/Settings/Settings.cshtml";
|
||||||
|
}
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-10 col-sm-offset-1">
|
||||||
|
<p>Default Account Settings</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
36
Teknik/Areas/User/Views/User/Settings/UploadSettings.cshtml
Normal file
36
Teknik/Areas/User/Views/User/Settings/UploadSettings.cshtml
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
@model Teknik.Areas.Users.ViewModels.UploadSettingsViewModel
|
||||||
|
|
||||||
|
@using Teknik.Utilities
|
||||||
|
@using Teknik.Areas.Users.ViewModels
|
||||||
|
|
||||||
|
@{
|
||||||
|
Layout = "~/Areas/User/Views/User/Settings/Settings.cshtml";
|
||||||
|
}
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var homeUrl = '@Url.SubRouteUrl("www", "Home.Index")';
|
||||||
|
var editURL = '@Url.SubRouteUrl("user", "User.Action", new { action = "EditUpload" })';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
@Styles.Render("~/Content/user/settings/upload")
|
||||||
|
@Scripts.Render("~/bundles/user/settings/upload")
|
||||||
|
|
||||||
|
<form class="form" action="##" method="post" id="updateForm">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<div class="checkbox">
|
||||||
|
<label>
|
||||||
|
<label for="update_upload_encrypt"><h4>Encrypt in Browser</h4></label>
|
||||||
|
<input id="update_upload_encrypt" name="update_upload_encrypt" title="whether the file should be encrypted in the browser before upload" type="checkbox" value="true" @(Model.Encrypt ? "checked" : string.Empty) />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="form-group col-sm-10">
|
||||||
|
<br />
|
||||||
|
<button class="btn btn-lg btn-success" id="update_submit" type="submit"><i class="glyphicon glyphicon-ok-sign"></i> Save</button>
|
||||||
|
<button class="btn btn-lg" type="reset"><i class="glyphicon glyphicon-repeat"></i> Reset</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
@ -1,11 +1,11 @@
|
|||||||
@model Teknik.ViewModels.ViewModelBase
|
@model Teknik.ViewModels.ViewModelBase
|
||||||
|
|
||||||
@using Teknik.Utilities
|
@using Teknik.Utilities
|
||||||
@using Microsoft.AspNet.Identity
|
@using Microsoft.AspNet.Identity
|
||||||
|
|
||||||
@if (Model.Config.UserConfig.RegistrationEnabled || Model.Config.UserConfig.LoginEnabled)
|
@if (Model.Config.UserConfig.RegistrationEnabled || Model.Config.UserConfig.LoginEnabled)
|
||||||
{
|
{
|
||||||
<div class="nav navbar-nav pull-right">
|
<div class="nav navbar-nav pull-right">
|
||||||
@if (Request.IsAuthenticated)
|
@if (Request.IsAuthenticated)
|
||||||
{
|
{
|
||||||
<li class="dropdown">
|
<li class="dropdown">
|
||||||
@ -22,9 +22,9 @@
|
|||||||
</li>
|
</li>
|
||||||
@if (User.IsInRole("Admin"))
|
@if (User.IsInRole("Admin"))
|
||||||
{
|
{
|
||||||
<li>
|
<li>
|
||||||
<a href="@Url.SubRouteUrl("admin", "Admin.Dashboard")">Administration</a>
|
<a href="@Url.SubRouteUrl("admin", "Admin.Dashboard")">Administration</a>
|
||||||
</li>
|
</li>
|
||||||
}
|
}
|
||||||
<li>
|
<li>
|
||||||
<a href="@Url.SubRouteUrl("user", "User.Logout")">Sign Out</a>
|
<a href="@Url.SubRouteUrl("user", "User.Logout")">Sign Out</a>
|
||||||
@ -49,5 +49,5 @@
|
|||||||
</noscript>
|
</noscript>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using Microsoft.AspNet.Identity.EntityFramework;
|
using Microsoft.AspNet.Identity.EntityFramework;
|
||||||
using System.Data.Entity;
|
using System.Data.Entity;
|
||||||
using System.Data.Entity.Infrastructure;
|
using System.Data.Entity.Infrastructure;
|
||||||
using Teknik.Areas.Blog.Models;
|
using Teknik.Areas.Blog.Models;
|
||||||
@ -26,6 +26,7 @@ namespace Teknik.Models
|
|||||||
public DbSet<TrustedDevice> TrustedDevices { get; set; }
|
public DbSet<TrustedDevice> TrustedDevices { get; set; }
|
||||||
public DbSet<AuthToken> AuthTokens { get; set; }
|
public DbSet<AuthToken> AuthTokens { get; set; }
|
||||||
public DbSet<TransferType> TransferTypes { get; set; }
|
public DbSet<TransferType> TransferTypes { get; set; }
|
||||||
|
public DbSet<InviteCode> InviteCodes { get; set; }
|
||||||
// User Settings
|
// User Settings
|
||||||
public DbSet<UserSettings> UserSettings { get; set; }
|
public DbSet<UserSettings> UserSettings { get; set; }
|
||||||
public DbSet<SecuritySettings> SecuritySettings { get; set; }
|
public DbSet<SecuritySettings> SecuritySettings { get; set; }
|
||||||
@ -115,6 +116,16 @@ namespace Teknik.Models
|
|||||||
.WithOptional(u => u.User)
|
.WithOptional(u => u.User)
|
||||||
.WillCascadeOnDelete(false);
|
.WillCascadeOnDelete(false);
|
||||||
|
|
||||||
|
modelBuilder.Entity<User>()
|
||||||
|
.HasMany(u => u.OwnedInviteCodes)
|
||||||
|
.WithOptional(c => c.Owner)
|
||||||
|
.WillCascadeOnDelete(false);
|
||||||
|
|
||||||
|
modelBuilder.Entity<User>()
|
||||||
|
.HasOptional(u => u.ClaimedInviteCode)
|
||||||
|
.WithOptionalPrincipal(c => c.ClaimedUser)
|
||||||
|
.WillCascadeOnDelete(false);
|
||||||
|
|
||||||
// Upload Mappings
|
// Upload Mappings
|
||||||
modelBuilder.Entity<Upload>()
|
modelBuilder.Entity<Upload>()
|
||||||
.HasOptional(u => u.User);
|
.HasOptional(u => u.User);
|
||||||
@ -130,13 +141,14 @@ namespace Teknik.Models
|
|||||||
// Vault Mappings
|
// Vault Mappings
|
||||||
modelBuilder.Entity<Vault>()
|
modelBuilder.Entity<Vault>()
|
||||||
.HasOptional(u => u.User);
|
.HasOptional(u => u.User);
|
||||||
|
|
||||||
// Users
|
// Users
|
||||||
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<TrustedDevice>().ToTable("TrustedDevices");
|
modelBuilder.Entity<TrustedDevice>().ToTable("TrustedDevices");
|
||||||
modelBuilder.Entity<AuthToken>().ToTable("AuthTokens");
|
modelBuilder.Entity<AuthToken>().ToTable("AuthTokens");
|
||||||
|
modelBuilder.Entity<InviteCode>().ToTable("InviteCodes");
|
||||||
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");
|
||||||
@ -176,4 +188,4 @@ namespace Teknik.Models
|
|||||||
base.OnModelCreating(modelBuilder);
|
base.OnModelCreating(modelBuilder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
$("#top_msg").css('display', 'none', 'important');
|
$("#top_msg").css('display', 'none', 'important');
|
||||||
|
|
||||||
// Opt-in for tooltips
|
// Opt-in for tooltips
|
||||||
@ -280,6 +280,41 @@ function addParamsToUrl(origUrl, params) {
|
|||||||
var appendix = (hasQuery ? "&" : "?") + paramStr;
|
var appendix = (hasQuery ? "&" : "?") + paramStr;
|
||||||
return hasHash ? origUrl.replace("#", appendix + "#") : origUrl + appendix;
|
return hasHash ? origUrl.replace("#", appendix + "#") : origUrl + appendix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sleep(ms) {
|
||||||
|
return new Promise(resolve => setTimeout(resolve, ms));
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseErrorMessage(errorObj) {
|
||||||
|
var errorMsg = "";
|
||||||
|
if (errorObj === null || errorObj === undefined) {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
else if (errorObj.constructor === {}.constructor) {
|
||||||
|
if (errorObj.error) {
|
||||||
|
errorMsg = errorObj.error;
|
||||||
|
if (errorObj.error.message) {
|
||||||
|
errorMsg = errorObj.error.message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
try {
|
||||||
|
var json = $.parseJSON(errorObj);
|
||||||
|
if (json.error) {
|
||||||
|
errorMsg = json.error;
|
||||||
|
if (json.error.message) {
|
||||||
|
errorMsg = json.error.message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
// Don't do anything
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return errorMsg;
|
||||||
|
}
|
||||||
|
|
||||||
/***************************** TIMER Page Load *******************************/
|
/***************************** TIMER Page Load *******************************/
|
||||||
var loopTime;
|
var loopTime;
|
||||||
var startTime = new Date();
|
var startTime = new Date();
|
||||||
@ -301,4 +336,4 @@ function pageloadStopTimer() {
|
|||||||
$('#pagetime').show();
|
$('#pagetime').show();
|
||||||
|
|
||||||
clearTimeout(loopTime);
|
clearTimeout(loopTime);
|
||||||
}
|
}
|
||||||
|
@ -293,15 +293,22 @@
|
|||||||
<Compile Include="Areas\Status\ViewModels\TransactionViewModel.cs" />
|
<Compile Include="Areas\Status\ViewModels\TransactionViewModel.cs" />
|
||||||
<Compile Include="Areas\User\Controllers\UserController.cs" />
|
<Compile Include="Areas\User\Controllers\UserController.cs" />
|
||||||
<Compile Include="Areas\User\Models\BlogSettings.cs" />
|
<Compile Include="Areas\User\Models\BlogSettings.cs" />
|
||||||
|
<Compile Include="Areas\User\Models\InviteCode.cs" />
|
||||||
<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\AuthToken.cs" />
|
<Compile Include="Areas\User\Models\AuthToken.cs" />
|
||||||
<Compile Include="Areas\User\Models\TrustedDevice.cs" />
|
<Compile Include="Areas\User\Models\TrustedDevice.cs" />
|
||||||
<Compile Include="Areas\User\ViewModels\AuthTokenViewModel.cs" />
|
<Compile Include="Areas\User\ViewModels\AuthTokenViewModel.cs" />
|
||||||
|
<Compile Include="Areas\User\ViewModels\InviteCodeViewModel.cs" />
|
||||||
|
<Compile Include="Areas\User\ViewModels\InviteSettingsViewModel.cs" />
|
||||||
|
<Compile Include="Areas\User\ViewModels\UploadSettingsViewModel.cs" />
|
||||||
<Compile Include="Areas\User\ViewModels\EditSettingsViewModel.cs" />
|
<Compile Include="Areas\User\ViewModels\EditSettingsViewModel.cs" />
|
||||||
<Compile Include="Areas\User\ViewModels\GetPremiumViewModel.cs" />
|
<Compile Include="Areas\User\ViewModels\GetPremiumViewModel.cs" />
|
||||||
|
<Compile Include="Areas\User\ViewModels\BlogSettingsViewModel.cs" />
|
||||||
|
<Compile Include="Areas\User\ViewModels\SecuritySettingsViewModel.cs" />
|
||||||
<Compile Include="Areas\User\ViewModels\SetPasswordViewModel.cs" />
|
<Compile Include="Areas\User\ViewModels\SetPasswordViewModel.cs" />
|
||||||
|
<Compile Include="Areas\User\ViewModels\ProfileSettingsViewModel.cs" />
|
||||||
<Compile Include="Areas\User\ViewModels\TwoFactorViewModel.cs" />
|
<Compile Include="Areas\User\ViewModels\TwoFactorViewModel.cs" />
|
||||||
<Compile Include="Areas\Vault\ViewModels\ModifyVaultViewModel.cs" />
|
<Compile Include="Areas\Vault\ViewModels\ModifyVaultViewModel.cs" />
|
||||||
<Compile Include="Areas\Vault\ViewModels\ModifyVaultItemViewModel.cs" />
|
<Compile Include="Areas\Vault\ViewModels\ModifyVaultItemViewModel.cs" />
|
||||||
@ -410,7 +417,13 @@
|
|||||||
<Content Include="Areas\Upload\Content\Upload.css" />
|
<Content Include="Areas\Upload\Content\Upload.css" />
|
||||||
<Content Include="Areas\User\Scripts\CheckAuthCode.js" />
|
<Content Include="Areas\User\Scripts\CheckAuthCode.js" />
|
||||||
<Content Include="Areas\User\Scripts\Profile.js" />
|
<Content Include="Areas\User\Scripts\Profile.js" />
|
||||||
<Content Include="Areas\User\Scripts\User.js" />
|
<Content Include="Areas\User\Scripts\Settings.js" />
|
||||||
|
<Content Include="Areas\User\Scripts\BlogSettings.js" />
|
||||||
|
<Content Include="Areas\User\Scripts\InviteSettings.js" />
|
||||||
|
<Content Include="Areas\User\Scripts\ProfileSettings.js" />
|
||||||
|
<Content Include="Areas\User\Scripts\SecuritySettings.js" />
|
||||||
|
<Content Include="Areas\User\Scripts\UploadSettings.js" />
|
||||||
|
<Content Include="Areas\User\Scripts\ResetPass.js" />
|
||||||
<Content Include="Areas\Shortener\Scripts\Shortener.js" />
|
<Content Include="Areas\Shortener\Scripts\Shortener.js" />
|
||||||
<Content Include="Areas\Upload\Scripts\Download.js" />
|
<Content Include="Areas\Upload\Scripts\Download.js" />
|
||||||
<Content Include="Areas\Vault\Content\Vault.css" />
|
<Content Include="Areas\Vault\Content\Vault.css" />
|
||||||
@ -598,7 +611,7 @@
|
|||||||
<Content Include="Areas\Podcast\Views\Podcast\Comments.cshtml" />
|
<Content Include="Areas\Podcast\Views\Podcast\Comments.cshtml" />
|
||||||
<Content Include="Areas\Podcast\Views\Podcast\ViewPodcast.cshtml" />
|
<Content Include="Areas\Podcast\Views\Podcast\ViewPodcast.cshtml" />
|
||||||
<Content Include="App_Data\Config.json" />
|
<Content Include="App_Data\Config.json" />
|
||||||
<Content Include="Areas\User\Views\User\Settings.cshtml" />
|
<Content Include="Areas\User\Views\User\Settings\Settings.cshtml" />
|
||||||
<Content Include="Areas\Vault\Views\_ViewStart.cshtml" />
|
<Content Include="Areas\Vault\Views\_ViewStart.cshtml" />
|
||||||
<Content Include="Areas\Help\Views\Help\RSS.cshtml" />
|
<Content Include="Areas\Help\Views\Help\RSS.cshtml" />
|
||||||
<Content Include="Areas\Stream\Views\web.config" />
|
<Content Include="Areas\Stream\Views\web.config" />
|
||||||
@ -643,7 +656,7 @@
|
|||||||
<Content Include="Fonts\fontawesome-webfont.woff" />
|
<Content Include="Fonts\fontawesome-webfont.woff" />
|
||||||
<Content Include="Fonts\fontawesome-webfont.ttf" />
|
<Content Include="Fonts\fontawesome-webfont.ttf" />
|
||||||
<Content Include="Fonts\fontawesome-webfont.eot" />
|
<Content Include="Fonts\fontawesome-webfont.eot" />
|
||||||
<Content Include="Areas\User\Views\User\AuthToken.cshtml" />
|
<Content Include="Areas\User\Views\User\Settings\AuthToken.cshtml" />
|
||||||
<Content Include="Areas\Error\Views\Error\Http401.cshtml" />
|
<Content Include="Areas\Error\Views\Error\Http401.cshtml" />
|
||||||
<Content Include="Areas\Vault\Views\Vault\ModifyVault.cshtml" />
|
<Content Include="Areas\Vault\Views\Vault\ModifyVault.cshtml" />
|
||||||
<Content Include="Areas\Vault\Views\Vault\ModifyVaultItem.cshtml" />
|
<Content Include="Areas\Vault\Views\Vault\ModifyVaultItem.cshtml" />
|
||||||
@ -666,6 +679,13 @@
|
|||||||
<Content Include="Areas\IRC\Views\web.config" />
|
<Content Include="Areas\IRC\Views\web.config" />
|
||||||
<Content Include="Areas\IRC\Views\IRC\Client.cshtml" />
|
<Content Include="Areas\IRC\Views\IRC\Client.cshtml" />
|
||||||
<Content Include="Areas\IRC\Views\_ViewStart.cshtml" />
|
<Content Include="Areas\IRC\Views\_ViewStart.cshtml" />
|
||||||
|
<Content Include="Areas\User\Views\User\Settings\ProfileSettings.cshtml" />
|
||||||
|
<Content Include="Areas\User\Views\User\Settings\SecuritySettings.cshtml" />
|
||||||
|
<Content Include="Areas\User\Views\User\Settings\InviteSettings.cshtml" />
|
||||||
|
<Content Include="Areas\User\Views\User\Settings\BlogSettings.cshtml" />
|
||||||
|
<Content Include="Areas\User\Views\User\Settings\UploadSettings.cshtml" />
|
||||||
|
<Content Include="Areas\User\Views\User\Settings\SettingsBase.cshtml" />
|
||||||
|
<Content Include="Areas\User\Views\User\Settings\InviteCode.cshtml" />
|
||||||
<None Include="Properties\PublishProfiles\Teknik Dev.pubxml" />
|
<None Include="Properties\PublishProfiles\Teknik Dev.pubxml" />
|
||||||
<None Include="Properties\PublishProfiles\Teknik Production.pubxml" />
|
<None Include="Properties\PublishProfiles\Teknik Production.pubxml" />
|
||||||
<None Include="Scripts\jquery-2.1.4.intellisense.js" />
|
<None Include="Scripts\jquery-2.1.4.intellisense.js" />
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@ -19,6 +19,7 @@ namespace Teknik.Configuration
|
|||||||
public string ReservedUsernameDefinitionFile { get; set; }
|
public string ReservedUsernameDefinitionFile { get; set; }
|
||||||
public decimal PremiumAccountPrice { get; set; }
|
public decimal PremiumAccountPrice { get; set; }
|
||||||
public string PaymentType { get; set; }
|
public string PaymentType { get; set; }
|
||||||
|
public bool InviteCodeRequired { get; set; }
|
||||||
|
|
||||||
public UserConfig()
|
public UserConfig()
|
||||||
{
|
{
|
||||||
@ -32,6 +33,7 @@ namespace Teknik.Configuration
|
|||||||
ReservedUsernameDefinitionFile = string.Empty;
|
ReservedUsernameDefinitionFile = string.Empty;
|
||||||
PremiumAccountPrice = 0;
|
PremiumAccountPrice = 0;
|
||||||
PaymentType = "Donation";
|
PaymentType = "Donation";
|
||||||
|
InviteCodeRequired = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user