The next generation of the Teknik Services. Written in ASP.NET. https://www.teknik.io/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

UserController.cs 60KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using Teknik.Areas.Users.Models;
  5. using Teknik.Areas.Users.ViewModels;
  6. using Teknik.Controllers;
  7. using Teknik.Utilities;
  8. using Teknik.Areas.Users.Utility;
  9. using Teknik.Filters;
  10. using QRCoder;
  11. using TwoStepsAuthenticator;
  12. using Teknik.Attributes;
  13. using Teknik.Utilities.Cryptography;
  14. using Microsoft.Extensions.Logging;
  15. using Teknik.Configuration;
  16. using Teknik.Data;
  17. using Microsoft.AspNetCore.Authorization;
  18. using Microsoft.AspNetCore.Mvc;
  19. using Microsoft.EntityFrameworkCore;
  20. using System.Net;
  21. using Microsoft.AspNetCore.Mvc.ViewEngines;
  22. using System.Threading.Tasks;
  23. using Teknik.Logging;
  24. using System.Security.Claims;
  25. using Microsoft.AspNetCore.Authentication.Cookies;
  26. using Microsoft.AspNetCore.Authentication;
  27. using IdentityServer4.Services;
  28. using Microsoft.AspNetCore.Identity;
  29. using IdentityModel.Client;
  30. using System.Net.Http;
  31. using Newtonsoft.Json.Linq;
  32. using Teknik.Security;
  33. using Microsoft.IdentityModel.Tokens;
  34. using IdentityModel;
  35. using System.Security.Cryptography;
  36. using System.IdentityModel.Tokens.Jwt;
  37. using Microsoft.AspNetCore.Http;
  38. using IdentityServer4.Models;
  39. namespace Teknik.Areas.Users.Controllers
  40. {
  41. [Authorize]
  42. [Area("User")]
  43. [ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]
  44. public class UserController : DefaultController
  45. {
  46. private static readonly UsedCodesManager usedCodesManager = new UsedCodesManager();
  47. private const string _AuthSessionKey = "AuthenticatedUser";
  48. private readonly IHttpContextAccessor _httpContextAccessor;
  49. private ISession _session => _httpContextAccessor.HttpContext.Session;
  50. public UserController(ILogger<Logger> logger, Config config, TeknikEntities dbContext, IHttpContextAccessor httpContextAccessor) : base(logger, config, dbContext)
  51. {
  52. _httpContextAccessor = httpContextAccessor;
  53. }
  54. [HttpGet]
  55. [AllowAnonymous]
  56. public IActionResult Index()
  57. {
  58. return Redirect(Url.SubRouteUrl("www", "Home.Index"));
  59. }
  60. [HttpGet]
  61. public IActionResult Login(string returnUrl)
  62. {
  63. // Let's double check their email and git accounts to make sure they exist
  64. string email = UserHelper.GetUserEmailAddress(_config, User.Identity.Name);
  65. if (_config.EmailConfig.Enabled && !UserHelper.UserEmailExists(_config, email))
  66. {
  67. //UserHelper.AddUserEmail(_config, email, model.Password);
  68. }
  69. if (_config.GitConfig.Enabled && !UserHelper.UserGitExists(_config, User.Identity.Name))
  70. {
  71. //UserHelper.AddUserGit(_config, User.Identity.Name, model.Password);
  72. }
  73. if (!string.IsNullOrEmpty(returnUrl))
  74. {
  75. return Redirect(returnUrl);
  76. }
  77. return Redirect(Url.SubRouteUrl("www", "Home.Index"));
  78. }
  79. [HttpGet]
  80. [TrackPageView]
  81. public async Task Logout()
  82. {
  83. // these are the sub & sid to signout
  84. //var sub = User.FindFirst("sub")?.Value;
  85. //var sid = User.FindFirst("sid")?.Value;
  86. await HttpContext.SignOutAsync("Cookies");
  87. await HttpContext.SignOutAsync("oidc");
  88. //_logoutSessions.Add(sub, sid);
  89. }
  90. [AllowAnonymous]
  91. [TrackPageView]
  92. public IActionResult GetPremium()
  93. {
  94. ViewBag.Title = "Get a Premium Account";
  95. GetPremiumViewModel model = new GetPremiumViewModel();
  96. return View(model);
  97. }
  98. [HttpGet]
  99. [AllowAnonymous]
  100. [TrackPageView]
  101. public IActionResult Register(string inviteCode, string ReturnUrl)
  102. {
  103. RegisterViewModel model = new RegisterViewModel();
  104. model.InviteCode = inviteCode;
  105. model.ReturnUrl = ReturnUrl;
  106. return View("/Areas/User/Views/User/ViewRegistration.cshtml", model);
  107. }
  108. [HttpOptions]
  109. [HttpPost]
  110. [AllowAnonymous]
  111. public async Task<IActionResult> Register([Bind(Prefix = "Register")]RegisterViewModel model)
  112. {
  113. model.Error = false;
  114. model.ErrorMessage = string.Empty;
  115. if (ModelState.IsValid)
  116. {
  117. if (_config.UserConfig.RegistrationEnabled)
  118. {
  119. if (!model.Error && !UserHelper.ValidUsername(_config, model.Username))
  120. {
  121. model.Error = true;
  122. model.ErrorMessage = "That username is not valid";
  123. }
  124. if (!model.Error && !(await UserHelper.UsernameAvailable(_dbContext, _config, model.Username)))
  125. {
  126. model.Error = true;
  127. model.ErrorMessage = "That username is not available";
  128. }
  129. if (!model.Error && string.IsNullOrEmpty(model.Password))
  130. {
  131. model.Error = true;
  132. model.ErrorMessage = "You must enter a password";
  133. }
  134. if (!model.Error && model.Password.Length < _config.UserConfig.MinPasswordLength)
  135. {
  136. model.Error = true;
  137. model.ErrorMessage = $"Password must be at least {_config.UserConfig.MinPasswordLength} characters long";
  138. }
  139. if (!model.Error && model.Password != model.ConfirmPassword)
  140. {
  141. model.Error = true;
  142. model.ErrorMessage = "Passwords must match";
  143. }
  144. // Validate the Invite Code
  145. if (!model.Error && _config.UserConfig.InviteCodeRequired && string.IsNullOrEmpty(model.InviteCode))
  146. {
  147. model.Error = true;
  148. model.ErrorMessage = "An Invite Code is required to register";
  149. }
  150. if (!model.Error && !string.IsNullOrEmpty(model.InviteCode) && _dbContext.InviteCodes.Where(c => c.Code == model.InviteCode && c.Active && c.ClaimedUser == null).FirstOrDefault() == null)
  151. {
  152. model.Error = true;
  153. model.ErrorMessage = "Invalid Invite Code";
  154. }
  155. if (!model.Error)
  156. {
  157. try
  158. {
  159. await UserHelper.CreateAccount(_dbContext, _config, Url, model.Username, model.Password, model.RecoveryEmail, model.InviteCode);
  160. }
  161. catch (Exception ex)
  162. {
  163. model.Error = true;
  164. model.ErrorMessage = ex.GetFullMessage(true);
  165. }
  166. if (!model.Error)
  167. {
  168. // Let's log them in
  169. return GenerateActionResult(new { success = true, redirectUrl = Url.SubRouteUrl("account", "User.Login", new { returnUrl = model.ReturnUrl }) }, Redirect(Url.SubRouteUrl("account", "User.Login", new { returnUrl = model.ReturnUrl })));
  170. }
  171. }
  172. }
  173. if (!model.Error)
  174. {
  175. model.Error = true;
  176. model.ErrorMessage = "User Registration is Disabled";
  177. }
  178. }
  179. else
  180. {
  181. model.Error = true;
  182. model.ErrorMessage = "Missing Required Fields";
  183. }
  184. return GenerateActionResult(new { error = model.ErrorMessage }, View("/Areas/User/Views/User/ViewRegistration.cshtml", model));
  185. }
  186. // GET: Profile/Profile
  187. [AllowAnonymous]
  188. [TrackPageView]
  189. public async Task<IActionResult> ViewProfile(string username)
  190. {
  191. if (string.IsNullOrEmpty(username))
  192. {
  193. username = User.Identity.Name;
  194. }
  195. ProfileViewModel model = new ProfileViewModel();
  196. ViewBag.Title = "User Does Not Exist";
  197. ViewBag.Description = "The User does not exist";
  198. try
  199. {
  200. User user = UserHelper.GetUser(_dbContext, username);
  201. if (user != null)
  202. {
  203. ViewBag.Title = username + "'s Profile";
  204. ViewBag.Description = "Viewing " + username + "'s Profile";
  205. model.UserID = user.UserId;
  206. model.Username = user.Username;
  207. if (_config.EmailConfig.Enabled)
  208. {
  209. model.Email = string.Format("{0}@{1}", user.Username, _config.EmailConfig.Domain);
  210. }
  211. // Get the user claims for this user
  212. model.IdentityUserInfo = await IdentityHelper.GetIdentityUserInfo(_config, user.Username);
  213. model.LastSeen = UserHelper.GetLastAccountActivity(_dbContext, _config, user.Username, model.IdentityUserInfo);
  214. model.UserSettings = user.UserSettings;
  215. model.BlogSettings = user.BlogSettings;
  216. model.UploadSettings = user.UploadSettings;
  217. model.Uploads = _dbContext.Uploads.Where(u => u.UserId == user.UserId).OrderByDescending(u => u.DateUploaded).ToList();
  218. model.Pastes = _dbContext.Pastes.Where(u => u.UserId == user.UserId).OrderByDescending(u => u.DatePosted).ToList();
  219. model.ShortenedUrls = _dbContext.ShortenedUrls.Where(s => s.UserId == user.UserId).OrderByDescending(s => s.DateAdded).ToList();
  220. model.Vaults = _dbContext.Vaults.Where(v => v.UserId == user.UserId).OrderByDescending(v => v.DateCreated).ToList();
  221. return View(model);
  222. }
  223. model.Error = true;
  224. model.ErrorMessage = "The user does not exist";
  225. }
  226. catch (Exception ex)
  227. {
  228. model.Error = true;
  229. model.ErrorMessage = ex.GetFullMessage(true);
  230. }
  231. return View(model);
  232. }
  233. [TrackPageView]
  234. public IActionResult ViewServiceData()
  235. {
  236. string username = User.Identity.Name;
  237. ViewServiceDataViewModel model = new ViewServiceDataViewModel();
  238. ViewBag.Title = "User Does Not Exist";
  239. ViewBag.Description = "The User does not exist";
  240. try
  241. {
  242. User user = UserHelper.GetUser(_dbContext, username);
  243. if (user != null)
  244. {
  245. ViewBag.Title = "Service Data";
  246. ViewBag.Description = "Viewing all of your service data";
  247. model.Uploads = _dbContext.Uploads.Where(u => u.UserId == user.UserId).OrderByDescending(u => u.DateUploaded).ToList();
  248. model.Pastes = _dbContext.Pastes.Where(u => u.UserId == user.UserId).OrderByDescending(u => u.DatePosted).ToList();
  249. model.ShortenedUrls = _dbContext.ShortenedUrls.Where(s => s.UserId == user.UserId).OrderByDescending(s => s.DateAdded).ToList();
  250. model.Vaults = _dbContext.Vaults.Where(v => v.UserId == user.UserId).OrderByDescending(v => v.DateCreated).ToList();
  251. return View(model);
  252. }
  253. model.Error = true;
  254. model.ErrorMessage = "The user does not exist";
  255. }
  256. catch (Exception ex)
  257. {
  258. model.Error = true;
  259. model.ErrorMessage = ex.GetFullMessage(true);
  260. }
  261. return View(model);
  262. }
  263. [TrackPageView]
  264. public IActionResult Settings()
  265. {
  266. return Redirect(Url.SubRouteUrl("account", "User.ProfileSettings"));
  267. }
  268. [TrackPageView]
  269. public IActionResult ProfileSettings()
  270. {
  271. string username = User.Identity.Name;
  272. User user = UserHelper.GetUser(_dbContext, username);
  273. if (user != null)
  274. {
  275. ViewBag.Title = "Profile Settings";
  276. ViewBag.Description = "Your " + _config.Title + " Profile Settings";
  277. ProfileSettingsViewModel model = new ProfileSettingsViewModel();
  278. model.Page = "Profile";
  279. model.UserID = user.UserId;
  280. model.Username = user.Username;
  281. model.About = user.UserSettings.About;
  282. model.Quote = user.UserSettings.Quote;
  283. model.Website = user.UserSettings.Website;
  284. return View("/Areas/User/Views/User/Settings/ProfileSettings.cshtml", model);
  285. }
  286. return new StatusCodeResult(StatusCodes.Status403Forbidden);
  287. }
  288. [TrackPageView]
  289. public IActionResult AccountSettings()
  290. {
  291. string username = User.Identity.Name;
  292. User user = UserHelper.GetUser(_dbContext, username);
  293. if (user != null)
  294. {
  295. ViewBag.Title = "Account Settings";
  296. ViewBag.Description = "Your " + _config.Title + " Account Settings";
  297. AccountSettingsViewModel model = new AccountSettingsViewModel();
  298. model.Page = "Account";
  299. model.UserID = user.UserId;
  300. model.Username = user.Username;
  301. return View("/Areas/User/Views/User/Settings/AccountSettings.cshtml", model);
  302. }
  303. return new StatusCodeResult(StatusCodes.Status403Forbidden);
  304. }
  305. [TrackPageView]
  306. public async Task<IActionResult> SecuritySettings()
  307. {
  308. string username = User.Identity.Name;
  309. User user = UserHelper.GetUser(_dbContext, username);
  310. if (user != null)
  311. {
  312. ViewBag.Title = "Security Settings";
  313. ViewBag.Description = "Your " + _config.Title + " Security Settings";
  314. SecuritySettingsViewModel model = new SecuritySettingsViewModel();
  315. model.Page = "Security";
  316. model.UserID = user.UserId;
  317. model.Username = user.Username;
  318. // Get the user secure info
  319. IdentityUserInfo userInfo = await IdentityHelper.GetIdentityUserInfo(_config, user.Username);
  320. //model.TrustedDeviceCount = user.TrustedDevices.Count;
  321. //model.AuthTokens = new List<AuthTokenViewModel>();
  322. //foreach (AuthToken token in user.AuthTokens)
  323. //{
  324. // AuthTokenViewModel tokenModel = new AuthTokenViewModel();
  325. // tokenModel.AuthTokenId = token.AuthTokenId;
  326. // tokenModel.Name = token.Name;
  327. // tokenModel.LastDateUsed = token.LastDateUsed;
  328. // model.AuthTokens.Add(tokenModel);
  329. //}
  330. model.PgpPublicKey = userInfo.PGPPublicKey;
  331. model.RecoveryEmail = userInfo.RecoveryEmail;
  332. if (userInfo.RecoveryVerified.HasValue)
  333. model.RecoveryVerified = userInfo.RecoveryVerified.Value;
  334. if (userInfo.TwoFactorEnabled.HasValue)
  335. model.TwoFactorEnabled = userInfo.TwoFactorEnabled.Value;
  336. return View("/Areas/User/Views/User/Settings/SecuritySettings.cshtml", model);
  337. }
  338. return new StatusCodeResult(StatusCodes.Status403Forbidden);
  339. }
  340. [TrackPageView]
  341. public async Task<IActionResult> DeveloperSettings()
  342. {
  343. string username = User.Identity.Name;
  344. User user = UserHelper.GetUser(_dbContext, username);
  345. if (user != null)
  346. {
  347. ViewBag.Title = "Developer Settings";
  348. ViewBag.Description = "Your " + _config.Title + " Developer Settings";
  349. DeveloperSettingsViewModel model = new DeveloperSettingsViewModel();
  350. model.Page = "Developer";
  351. model.UserID = user.UserId;
  352. model.Username = user.Username;
  353. model.AuthTokens = new List<AuthTokenViewModel>();
  354. model.Clients = new List<ClientViewModel>();
  355. //foreach (AuthToken token in user.AuthTokens)
  356. //{
  357. // AuthTokenViewModel tokenModel = new AuthTokenViewModel();
  358. // tokenModel.AuthTokenId = token.AuthTokenId;
  359. // tokenModel.Name = token.Name;
  360. // tokenModel.LastDateUsed = token.LastDateUsed;
  361. // model.AuthTokens.Add(tokenModel);
  362. //}
  363. Client[] clients = await IdentityHelper.GetClients(_config, username);
  364. foreach (Client client in clients)
  365. {
  366. model.Clients.Add(new ClientViewModel()
  367. {
  368. Id = client.ClientId,
  369. Name = client.ClientName,
  370. HomepageUrl = client.ClientUri,
  371. LogoUrl = client.LogoUri,
  372. CallbackUrl = string.Join(',', client.RedirectUris),
  373. AllowedScopes = client.AllowedScopes
  374. });
  375. }
  376. return View("/Areas/User/Views/User/Settings/DeveloperSettings.cshtml", model);
  377. }
  378. return new StatusCodeResult(StatusCodes.Status403Forbidden);
  379. }
  380. [TrackPageView]
  381. public IActionResult InviteSettings()
  382. {
  383. string username = User.Identity.Name;
  384. User user = UserHelper.GetUser(_dbContext, username);
  385. if (user != null)
  386. {
  387. ViewBag.Title = "Invite Settings";
  388. ViewBag.Description = "Your " + _config.Title + " Invite Settings";
  389. InviteSettingsViewModel model = new InviteSettingsViewModel();
  390. model.Page = "Invite";
  391. model.UserID = user.UserId;
  392. model.Username = user.Username;
  393. List<InviteCodeViewModel> availableCodes = new List<InviteCodeViewModel>();
  394. List<InviteCodeViewModel> claimedCodes = new List<InviteCodeViewModel>();
  395. if (user.OwnedInviteCodes != null)
  396. {
  397. foreach (InviteCode inviteCode in user.OwnedInviteCodes.Where(c => c.Active))
  398. {
  399. InviteCodeViewModel inviteCodeViewModel = new InviteCodeViewModel();
  400. inviteCodeViewModel.ClaimedUser = inviteCode.ClaimedUser;
  401. inviteCodeViewModel.Active = inviteCode.Active;
  402. inviteCodeViewModel.Code = inviteCode.Code;
  403. inviteCodeViewModel.InviteCodeId = inviteCode.InviteCodeId;
  404. inviteCodeViewModel.Owner = inviteCode.Owner;
  405. if (inviteCode.ClaimedUser == null)
  406. availableCodes.Add(inviteCodeViewModel);
  407. if (inviteCode.ClaimedUser != null)
  408. claimedCodes.Add(inviteCodeViewModel);
  409. }
  410. }
  411. model.AvailableCodes = availableCodes;
  412. model.ClaimedCodes = claimedCodes;
  413. return View("/Areas/User/Views/User/Settings/InviteSettings.cshtml", model);
  414. }
  415. return new StatusCodeResult(StatusCodes.Status403Forbidden);
  416. }
  417. [TrackPageView]
  418. public IActionResult BlogSettings()
  419. {
  420. string username = User.Identity.Name;
  421. User user = UserHelper.GetUser(_dbContext, username);
  422. if (user != null)
  423. {
  424. ViewBag.Title = "Blog Settings";
  425. ViewBag.Description = "Your " + _config.Title + " Blog Settings";
  426. BlogSettingsViewModel model = new BlogSettingsViewModel();
  427. model.Page = "Blog";
  428. model.UserID = user.UserId;
  429. model.Username = user.Username;
  430. model.Title = user.BlogSettings.Title;
  431. model.Description = user.BlogSettings.Description;
  432. return View("/Areas/User/Views/User/Settings/BlogSettings.cshtml", model);
  433. }
  434. return new StatusCodeResult(StatusCodes.Status403Forbidden);
  435. }
  436. [TrackPageView]
  437. public IActionResult UploadSettings()
  438. {
  439. string username = User.Identity.Name;
  440. User user = UserHelper.GetUser(_dbContext, username);
  441. if (user != null)
  442. {
  443. ViewBag.Title = "Upload Settings";
  444. ViewBag.Description = "Your " + _config.Title + " Upload Settings";
  445. UploadSettingsViewModel model = new UploadSettingsViewModel();
  446. model.Page = "Upload";
  447. model.UserID = user.UserId;
  448. model.Username = user.Username;
  449. model.Encrypt = user.UploadSettings.Encrypt;
  450. model.ExpirationLength = user.UploadSettings.ExpirationLength;
  451. model.ExpirationUnit = user.UploadSettings.ExpirationUnit;
  452. return View("/Areas/User/Views/User/Settings/UploadSettings.cshtml", model);
  453. }
  454. return new StatusCodeResult(StatusCodes.Status403Forbidden);
  455. }
  456. [HttpGet]
  457. [AllowAnonymous]
  458. [TrackPageView]
  459. public async Task<IActionResult> ViewRawPGP(string username)
  460. {
  461. ViewBag.Title = username + "'s Public Key";
  462. ViewBag.Description = "The PGP public key for " + username;
  463. IdentityUserInfo userClaims = await IdentityHelper.GetIdentityUserInfo(_config, username);
  464. if (!string.IsNullOrEmpty(userClaims.PGPPublicKey))
  465. {
  466. return Content(userClaims.PGPPublicKey, "text/plain");
  467. }
  468. return new StatusCodeResult(StatusCodes.Status404NotFound);
  469. }
  470. [HttpPost]
  471. [ValidateAntiForgeryToken]
  472. public IActionResult EditBlog(BlogSettingsViewModel settings)
  473. {
  474. if (ModelState.IsValid)
  475. {
  476. try
  477. {
  478. User user = UserHelper.GetUser(_dbContext, User.Identity.Name);
  479. if (user != null)
  480. {
  481. // Blogs
  482. user.BlogSettings.Title = settings.Title;
  483. user.BlogSettings.Description = settings.Description;
  484. UserHelper.EditAccount(_dbContext, _config, user);
  485. return Json(new { result = true });
  486. }
  487. return Json(new { error = "User does not exist" });
  488. }
  489. catch (Exception ex)
  490. {
  491. return Json(new { error = ex.GetFullMessage(true) });
  492. }
  493. }
  494. return Json(new { error = "Invalid Parameters" });
  495. }
  496. [HttpPost]
  497. [ValidateAntiForgeryToken]
  498. public IActionResult EditProfile(ProfileSettingsViewModel settings)
  499. {
  500. if (ModelState.IsValid)
  501. {
  502. try
  503. {
  504. User user = UserHelper.GetUser(_dbContext, User.Identity.Name);
  505. if (user != null)
  506. {
  507. // Profile Info
  508. user.UserSettings.Website = settings.Website;
  509. user.UserSettings.Quote = settings.Quote;
  510. user.UserSettings.About = settings.About;
  511. UserHelper.EditAccount(_dbContext, _config, user);
  512. return Json(new { result = true });
  513. }
  514. return Json(new { error = "User does not exist" });
  515. }
  516. catch (Exception ex)
  517. {
  518. return Json(new { error = ex.GetFullMessage(true) });
  519. }
  520. }
  521. return Json(new { error = "Invalid Parameters" });
  522. }
  523. [HttpPost]
  524. [ValidateAntiForgeryToken]
  525. public async Task<IActionResult> EditSecurity(SecuritySettingsViewModel settings)
  526. {
  527. if (ModelState.IsValid)
  528. {
  529. try
  530. {
  531. User user = UserHelper.GetUser(_dbContext, User.Identity.Name);
  532. if (user != null)
  533. {
  534. // PGP Key valid?
  535. if (!string.IsNullOrEmpty(settings.PgpPublicKey) && !PGP.IsPublicKey(settings.PgpPublicKey))
  536. {
  537. return Json(new { error = "Invalid PGP Public Key" });
  538. }
  539. // Get the user secure info
  540. IdentityUserInfo userInfo = await IdentityHelper.GetIdentityUserInfo(_config, user.Username);
  541. if (userInfo.PGPPublicKey != settings.PgpPublicKey)
  542. {
  543. var result = await IdentityHelper.UpdatePGPPublicKey(_config, user.Username, settings.PgpPublicKey);
  544. if (!result.Success)
  545. return Json(new { error = result.Message });
  546. }
  547. if (userInfo.RecoveryEmail != settings.RecoveryEmail)
  548. {
  549. var token = await IdentityHelper.UpdateRecoveryEmail(_config, user.Username, settings.RecoveryEmail);
  550. // If they have a recovery email, let's send a verification
  551. if (!string.IsNullOrEmpty(settings.RecoveryEmail))
  552. {
  553. string resetUrl = Url.SubRouteUrl("account", "User.ResetPassword", new { Username = user.Username });
  554. string verifyUrl = Url.SubRouteUrl("account", "User.VerifyRecoveryEmail", new { Username = user.Username, Code = WebUtility.UrlEncode(token) });
  555. UserHelper.SendRecoveryEmailVerification(_config, user.Username, settings.RecoveryEmail, resetUrl, verifyUrl);
  556. }
  557. }
  558. //if (!settings.TwoFactorEnabled && (!userInfo.TwoFactorEnabled.HasValue || userInfo.TwoFactorEnabled.Value))
  559. //{
  560. // var result = await IdentityHelper.Disable2FA(_config, user.Username);
  561. // if (!result.Success)
  562. // return Json(new { error = result.Message });
  563. //}
  564. //UserHelper.EditAccount(_dbContext, _config, user, changePass, settings.NewPassword);
  565. //if (!oldTwoFactor && settings.TwoFactorEnabled)
  566. //{
  567. // return Json(new { result = new { checkAuth = true, key = newKey, qrUrl = Url.SubRouteUrl("account", "User.Action", new { action = "GenerateAuthQrCode", key = newKey }) } });
  568. //}
  569. return Json(new { result = true });
  570. }
  571. return Json(new { error = "User does not exist" });
  572. }
  573. catch (Exception ex)
  574. {
  575. return Json(new { error = ex.GetFullMessage(true) });
  576. }
  577. }
  578. return Json(new { error = "Invalid Parameters" });
  579. }
  580. [HttpPost]
  581. [ValidateAntiForgeryToken]
  582. public IActionResult EditUpload(UploadSettingsViewModel settings)
  583. {
  584. if (ModelState.IsValid)
  585. {
  586. try
  587. {
  588. User user = UserHelper.GetUser(_dbContext, User.Identity.Name);
  589. if (user != null)
  590. {
  591. // Profile Info
  592. user.UploadSettings.Encrypt = settings.Encrypt;
  593. user.UploadSettings.ExpirationUnit = settings.ExpirationUnit;
  594. user.UploadSettings.ExpirationLength = settings.ExpirationLength;
  595. UserHelper.EditAccount(_dbContext, _config, user);
  596. return Json(new { result = true });
  597. }
  598. return Json(new { error = "User does not exist" });
  599. }
  600. catch (Exception ex)
  601. {
  602. return Json(new { error = ex.GetFullMessage(true) });
  603. }
  604. }
  605. return Json(new { error = "Invalid Parameters" });
  606. }
  607. public async Task<IActionResult> ChangePassword(AccountSettingsViewModel settings)
  608. {
  609. if (ModelState.IsValid)
  610. {
  611. try
  612. {
  613. User user = UserHelper.GetUser(_dbContext, User.Identity.Name);
  614. if (user != null)
  615. {
  616. // Did they enter their old password
  617. if (string.IsNullOrEmpty(settings.CurrentPassword))
  618. return Json(new { error = "You must enter your current password" });
  619. // Did they enter a new password
  620. if (string.IsNullOrEmpty(settings.NewPassword) || string.IsNullOrEmpty(settings.NewPasswordConfirm))
  621. return Json(new { error = "You must enter your new password" });
  622. // Old Password Valid?
  623. if (!(await UserHelper.UserPasswordCorrect(_config, user.Username, settings.CurrentPassword)))
  624. return Json(new { error = "Invalid Original Password" });
  625. // Does the new password meet the length requirement?
  626. if (settings.NewPassword.Length < _config.UserConfig.MinPasswordLength)
  627. return Json(new { error = $"New Password must be at least {_config.UserConfig.MinPasswordLength} characters long" });
  628. // The New Password Match?
  629. if (settings.NewPassword != settings.NewPasswordConfirm)
  630. return Json(new { error = "New Password must match confirmation" });
  631. // Are password resets enabled?
  632. if (!_config.UserConfig.PasswordResetEnabled)
  633. return Json(new { error = "Password resets are disabled" });
  634. // Change their password
  635. await UserHelper.ChangeAccountPassword(_dbContext, _config, user.Username, settings.CurrentPassword, settings.NewPassword);
  636. return Json(new { result = true });
  637. }
  638. return Json(new { error = "User does not exist" });
  639. }
  640. catch (Exception ex)
  641. {
  642. return Json(new { error = ex.GetFullMessage(true) });
  643. }
  644. }
  645. return Json(new { error = "Invalid Parameters" });
  646. }
  647. [HttpPost]
  648. [ValidateAntiForgeryToken]
  649. public async Task<IActionResult> Delete()
  650. {
  651. if (ModelState.IsValid)
  652. {
  653. try
  654. {
  655. User user = UserHelper.GetUser(_dbContext, User.Identity.Name);
  656. if (user != null)
  657. {
  658. await UserHelper.DeleteAccount(_dbContext, _config, user);
  659. // Sign Out
  660. await HttpContext.SignOutAsync("Cookies");
  661. await HttpContext.SignOutAsync("oidc");
  662. return Json(new { result = true });
  663. }
  664. }
  665. catch (Exception ex)
  666. {
  667. return Json(new { error = ex.GetFullMessage(true) });
  668. }
  669. }
  670. return Json(new { error = "Unable to delete user" });
  671. }
  672. [HttpGet]
  673. public async Task<IActionResult> VerifyRecoveryEmail(string username, string code)
  674. {
  675. bool verified = true;
  676. if (string.IsNullOrEmpty(code))
  677. verified &= false;
  678. // Is there a code?
  679. if (verified)
  680. {
  681. var result = await IdentityHelper.VerifyRecoveryEmail(_config, username, WebUtility.UrlDecode(code));
  682. verified &= result.Success;
  683. }
  684. RecoveryEmailVerificationViewModel model = new RecoveryEmailVerificationViewModel();
  685. model.Success = verified;
  686. return View("/Areas/User/Views/User/ViewRecoveryEmailVerification.cshtml", model);
  687. }
  688. [HttpPost]
  689. [ValidateAntiForgeryToken]
  690. public async Task<IActionResult> ResendVerifyRecoveryEmail()
  691. {
  692. if (ModelState.IsValid)
  693. {
  694. try
  695. {
  696. IdentityUserInfo userInfo = await IdentityHelper.GetIdentityUserInfo(_config, User.Identity.Name);
  697. User user = UserHelper.GetUser(_dbContext, User.Identity.Name);
  698. if (user != null)
  699. {
  700. //If they have a recovery email, let's send a verification
  701. if (!string.IsNullOrEmpty(userInfo.RecoveryEmail))
  702. {
  703. if (!userInfo.RecoveryVerified.HasValue || !userInfo.RecoveryVerified.Value)
  704. {
  705. var token = await IdentityHelper.UpdateRecoveryEmail(_config, user.Username, userInfo.RecoveryEmail);
  706. string resetUrl = Url.SubRouteUrl("account", "User.ResetPassword", new { Username = user.Username });
  707. string verifyUrl = Url.SubRouteUrl("account", "User.VerifyRecoveryEmail", new { Username = user.Username, Code = WebUtility.UrlEncode(token) });
  708. UserHelper.SendRecoveryEmailVerification(_config, user.Username, userInfo.RecoveryEmail, resetUrl, verifyUrl);
  709. return Json(new { result = true });
  710. }
  711. return Json(new { error = "The recovery email is already verified" });
  712. }
  713. }
  714. }
  715. catch (Exception ex)
  716. {
  717. return Json(new { error = ex.GetFullMessage(true) });
  718. }
  719. }
  720. return Json(new { error = "Unable to resend verification" });
  721. }
  722. [HttpGet]
  723. [AllowAnonymous]
  724. [TrackPageView]
  725. public IActionResult ResetPassword(string username)
  726. {
  727. ResetPasswordViewModel model = new ResetPasswordViewModel();
  728. model.Username = username;
  729. return View("/Areas/User/Views/User/ResetPassword.cshtml", model);
  730. }
  731. [HttpPost]
  732. [AllowAnonymous]
  733. [ValidateAntiForgeryToken]
  734. public async Task<IActionResult> SendResetPasswordVerification(string username)
  735. {
  736. if (ModelState.IsValid)
  737. {
  738. try
  739. {
  740. User user = UserHelper.GetUser(_dbContext, username);
  741. if (user != null)
  742. {
  743. IdentityUserInfo userClaims = await IdentityHelper.GetIdentityUserInfo(_config, user.Username);
  744. // If they have a recovery email, let's send a verification
  745. if (!string.IsNullOrEmpty(userClaims.RecoveryEmail) && userClaims.RecoveryVerified.HasValue && userClaims.RecoveryVerified.Value)
  746. {
  747. string verifyCode = await IdentityHelper.GeneratePasswordResetToken(_config, user.Username);
  748. string resetUrl = Url.SubRouteUrl("account", "User.VerifyResetPassword", new { Username = user.Username, Code = WebUtility.UrlEncode(verifyCode) });
  749. UserHelper.SendResetPasswordVerification(_config, user.Username, userClaims.RecoveryEmail, resetUrl);
  750. return Json(new { result = true });
  751. }
  752. return Json(new { error = "The user doesn't have a recovery email specified, or has not been verified." });
  753. }
  754. return Json(new { error = "The username is not valid" });
  755. }
  756. catch (Exception ex)
  757. {
  758. return Json(new { error = ex.GetFullMessage(true) });
  759. }
  760. }
  761. return Json(new { error = "Unable to send reset link" });
  762. }
  763. [HttpGet]
  764. [AllowAnonymous]
  765. [TrackPageView]
  766. public async Task<IActionResult> VerifyResetPassword(string username, string code)
  767. {
  768. bool verified = true;
  769. if (string.IsNullOrEmpty(code))
  770. verified &= false;
  771. // Is there a code?
  772. if (verified)
  773. {
  774. // The password reset code is valid, let's get their user account for this session
  775. User user = UserHelper.GetUser(_dbContext, username);
  776. _session.SetString(_AuthSessionKey, user.Username);
  777. _session.SetString("AuthCode", WebUtility.UrlDecode(code));
  778. await _session.CommitAsync();
  779. }
  780. ResetPasswordVerificationViewModel model = new ResetPasswordVerificationViewModel();
  781. model.Success = verified;
  782. return View("/Areas/User/Views/User/ResetPasswordVerification.cshtml", model);
  783. }
  784. [HttpPost]
  785. [AllowAnonymous]
  786. [ValidateAntiForgeryToken]
  787. public async Task<IActionResult> SetUserPassword(SetPasswordViewModel passwordViewModel)
  788. {
  789. if (ModelState.IsValid)
  790. {
  791. try
  792. {
  793. await _session.LoadAsync();
  794. string code = _session.GetString("AuthCode");
  795. if (!string.IsNullOrEmpty(code))
  796. {
  797. string username = _session.GetString(_AuthSessionKey);
  798. if (!string.IsNullOrEmpty(username))
  799. {
  800. if (string.IsNullOrEmpty(passwordViewModel.Password))
  801. {
  802. return Json(new { error = "Password must not be empty" });
  803. }
  804. if (passwordViewModel.Password.Length < _config.UserConfig.MinPasswordLength)
  805. {
  806. return Json(new { error = $"Password must be at least {_config.UserConfig.MinPasswordLength} characters long" });
  807. }
  808. if (passwordViewModel.Password != passwordViewModel.PasswordConfirm)
  809. {
  810. return Json(new { error = "Passwords must match" });
  811. }
  812. try
  813. {
  814. await UserHelper.ResetAccountPassword(_dbContext, _config, username, code, passwordViewModel.Password);
  815. _session.Remove(_AuthSessionKey);
  816. _session.Remove("AuthCode");
  817. return Json(new { result = true });
  818. }
  819. catch (Exception ex)
  820. {
  821. return Json(new { error = ex.Message });
  822. }
  823. }
  824. return Json(new { error = "User does not exist" });
  825. }
  826. return Json(new { error = "Invalid Code" });
  827. }
  828. catch (Exception ex)
  829. {
  830. return Json(new { error = ex.GetFullMessage(true) });
  831. }
  832. }
  833. return Json(new { error = "Unable to reset user password" });
  834. }
  835. [HttpPost]
  836. [ValidateAntiForgeryToken]
  837. public async Task<IActionResult> Generate2FA()
  838. {
  839. User user = UserHelper.GetUser(_dbContext, User.Identity.Name);
  840. if (user != null)
  841. {
  842. // Get User Identity Info
  843. var userInfo = await IdentityHelper.GetIdentityUserInfo(_config, User.Identity.Name);
  844. if (userInfo.TwoFactorEnabled.HasValue && !userInfo.TwoFactorEnabled.Value)
  845. {
  846. // Validate the code with the identity server
  847. var key = await IdentityHelper.Reset2FAKey(_config, user.Username);
  848. if (!string.IsNullOrEmpty(key))
  849. {
  850. return Json(new { result = true, key = key, qrUrl = Url.SubRouteUrl("account", "User.Action", new { action = "GenerateAuthQrCode", key = key }) });
  851. }
  852. return Json(new { error = "Unable to generate Two Factor Authentication key" });
  853. }
  854. return Json(new { error = "User already has Two Factor Authentication enabled" });
  855. }
  856. return Json(new { error = "User does not exist" });
  857. }
  858. [HttpPost]
  859. [ValidateAntiForgeryToken]
  860. public async Task<IActionResult> VerifyAuthenticatorCode(string code)
  861. {
  862. User user = UserHelper.GetUser(_dbContext, User.Identity.Name);
  863. if (user != null)
  864. {
  865. // Get User Identity Info
  866. var userInfo = await IdentityHelper.GetIdentityUserInfo(_config, User.Identity.Name);
  867. if (userInfo.TwoFactorEnabled.HasValue && !userInfo.TwoFactorEnabled.Value)
  868. {
  869. // Validate the code with the identity server
  870. var result = await IdentityHelper.Enable2FA(_config, user.Username, code);
  871. if (result.Any())
  872. {
  873. return Json(new { result = true, recoveryCodes = result });
  874. }
  875. return Json(new { error = "Invalid Authentication Code" });
  876. }
  877. return Json(new { error = "User already has Two Factor Authentication enabled" });
  878. }
  879. return Json(new { error = "User does not exist" });
  880. }
  881. [HttpPost]
  882. [ValidateAntiForgeryToken]
  883. public async Task<IActionResult> ResetRecoveryCodes()
  884. {
  885. User user = UserHelper.GetUser(_dbContext, User.Identity.Name);
  886. if (user != null)
  887. {
  888. // Get User Identity Info
  889. var userInfo = await IdentityHelper.GetIdentityUserInfo(_config, User.Identity.Name);
  890. if (userInfo.TwoFactorEnabled.HasValue && userInfo.TwoFactorEnabled.Value)
  891. {
  892. // Regenerate the recovery codes
  893. var result = await IdentityHelper.GenerateRecoveryCodes(_config, user.Username);
  894. if (result.Any())
  895. {
  896. return Json(new { result = true, recoveryCodes = result });
  897. }
  898. return Json(new { error = "Invalid Authentication Code" });
  899. }
  900. return Json(new { error = "User doesn't have Two Factor Authentication enabled" });
  901. }
  902. return Json(new { error = "User does not exist" });
  903. }
  904. [HttpPost]
  905. [ValidateAntiForgeryToken]
  906. public async Task<IActionResult> Disable2FA()
  907. {
  908. User user = UserHelper.GetUser(_dbContext, User.Identity.Name);
  909. if (user != null)
  910. {
  911. // Get User Identity Info
  912. var userInfo = await IdentityHelper.GetIdentityUserInfo(_config, User.Identity.Name);
  913. if (userInfo.TwoFactorEnabled.HasValue && userInfo.TwoFactorEnabled.Value)
  914. {
  915. // Validate the code with the identity server
  916. var result = await IdentityHelper.Disable2FA(_config, user.Username);
  917. if (result.Success)
  918. {
  919. return Json(new { result = true });
  920. }
  921. return Json(new { error = result.Message });
  922. }
  923. return Json(new { error = "User doesn't have Two Factor Authentication enabled" });
  924. }
  925. return Json(new { error = "User does not exist" });
  926. }
  927. [HttpGet]
  928. public IActionResult GenerateAuthQrCode(string key)
  929. {
  930. var ProvisionUrl = string.Format("otpauth://totp/{0}:{1}?secret={2}", _config.Title, User.Identity.Name, key);
  931. QRCodeGenerator qrGenerator = new QRCodeGenerator();
  932. QRCodeData qrCodeData = qrGenerator.CreateQrCode(ProvisionUrl, QRCodeGenerator.ECCLevel.Q);
  933. PngByteQRCode qrCode = new PngByteQRCode(qrCodeData);
  934. return File(qrCode.GetGraphic(20), "image/png");
  935. }
  936. [HttpPost]
  937. [ValidateAntiForgeryToken]
  938. public IActionResult ClearTrustedDevices()
  939. {
  940. try
  941. {
  942. User user = UserHelper.GetUser(_dbContext, User.Identity.Name);
  943. if (user != null)
  944. {
  945. //if (user.SecuritySettings.AllowTrustedDevices)
  946. //{
  947. // // let's clear the trusted devices
  948. // user.TrustedDevices.Clear();
  949. // List<TrustedDevice> foundDevices = _dbContext.TrustedDevices.Where(d => d.UserId == user.UserId).ToList();
  950. // if (foundDevices != null)
  951. // {
  952. // foreach (TrustedDevice device in foundDevices)
  953. // {
  954. // _dbContext.TrustedDevices.Remove(device);
  955. // }
  956. // }
  957. // _dbContext.Entry(user).State = EntityState.Modified;
  958. // _dbContext.SaveChanges();
  959. // return Json(new { result = true });
  960. //}
  961. return Json(new { error = "User does not allow trusted devices" });
  962. }
  963. return Json(new { error = "User does not exist" });
  964. }
  965. catch (Exception ex)
  966. {
  967. return Json(new { error = ex.GetFullMessage(true) });
  968. }
  969. }
  970. [HttpPost]
  971. [ValidateAntiForgeryToken]
  972. public async Task<IActionResult> GenerateToken(string name, [FromServices] ICompositeViewEngine viewEngine)
  973. {
  974. try
  975. {
  976. User user = UserHelper.GetUser(_dbContext, User.Identity.Name);
  977. if (user != null)
  978. {
  979. //string newTokenStr = UserHelper.GenerateAuthToken(_dbContext, user.Username);
  980. //if (!string.IsNullOrEmpty(newTokenStr))
  981. //{
  982. // AuthToken token = new AuthToken();
  983. // token.UserId = user.UserId;
  984. // token.HashedToken = SHA256.Hash(newTokenStr);
  985. // token.Name = name;
  986. // _dbContext.AuthTokens.Add(token);
  987. // _dbContext.SaveChanges();
  988. // AuthTokenViewModel model = new AuthTokenViewModel();
  989. // model.AuthTokenId = token.AuthTokenId;
  990. // model.Name = token.Name;
  991. // model.LastDateUsed = token.LastDateUsed;
  992. // string renderedView = await RenderPartialViewToString(viewEngine, "~/Areas/User/Views/User/Settings/AuthToken.cshtml", model);
  993. // return Json(new { result = new { token = newTokenStr, html = renderedView } });
  994. //}
  995. return Json(new { error = "Unable to generate Auth Token" });
  996. }
  997. return Json(new { error = "User does not exist" });
  998. }
  999. catch (Exception ex)
  1000. {
  1001. return Json(new { error = ex.GetFullMessage(true) });
  1002. }
  1003. }
  1004. [HttpPost]
  1005. [ValidateAntiForgeryToken]
  1006. public IActionResult RevokeAllTokens()
  1007. {
  1008. try
  1009. {
  1010. User user = UserHelper.GetUser(_dbContext, User.Identity.Name);
  1011. if (user != null)
  1012. {
  1013. //user.AuthTokens.Clear();
  1014. //List<AuthToken> foundTokens = _dbContext.AuthTokens.Where(d => d.UserId == user.UserId).ToList();
  1015. //if (foundTokens != null)
  1016. //{
  1017. // foreach (AuthToken token in foundTokens)
  1018. // {
  1019. // _dbContext.AuthTokens.Remove(token);
  1020. // }
  1021. //}
  1022. _dbContext.Entry(user).State = EntityState.Modified;
  1023. _dbContext.SaveChanges();
  1024. return Json(new { result = true });
  1025. }
  1026. return Json(new { error = "User does not exist" });
  1027. }
  1028. catch (Exception ex)
  1029. {
  1030. return Json(new { error = ex.GetFullMessage(true) });
  1031. }
  1032. }
  1033. [HttpPost]
  1034. [ValidateAntiForgeryToken]
  1035. public IActionResult EditTokenName(int tokenId, string name)
  1036. {
  1037. try
  1038. {
  1039. User user = UserHelper.GetUser(_dbContext, User.Identity.Name);
  1040. if (user != null)
  1041. {
  1042. //AuthToken foundToken = _dbContext.AuthTokens.Where(d => d.UserId == user.UserId && d.AuthTokenId == tokenId).FirstOrDefault();
  1043. //if (foundToken != null)
  1044. //{
  1045. // foundToken.Name = name;
  1046. // _dbContext.Entry(foundToken).State = EntityState.Modified;
  1047. // _dbContext.SaveChanges();
  1048. // return Json(new { result = new { name = name } });
  1049. //}
  1050. return Json(new { error = "Authentication Token does not exist" });
  1051. }
  1052. return Json(new { error = "User does not exist" });
  1053. }
  1054. catch (Exception ex)
  1055. {
  1056. return Json(new { error = ex.GetFullMessage(true) });
  1057. }
  1058. }
  1059. [HttpPost]
  1060. [ValidateAntiForgeryToken]
  1061. public IActionResult DeleteToken(int tokenId)
  1062. {
  1063. try
  1064. {
  1065. User user = UserHelper.GetUser(_dbContext, User.Identity.Name);
  1066. if (user != null)
  1067. {
  1068. //AuthToken foundToken = _dbContext.AuthTokens.Where(d => d.UserId == user.UserId && d.AuthTokenId == tokenId).FirstOrDefault();
  1069. //if (foundToken != null)
  1070. //{
  1071. // _dbContext.AuthTokens.Remove(foundToken);
  1072. // user.AuthTokens.Remove(foundToken);
  1073. // _dbContext.Entry(user).State = EntityState.Modified;
  1074. // _dbContext.SaveChanges();
  1075. // return Json(new { result = true });
  1076. //}
  1077. return Json(new { error = "Authentication Token does not exist" });
  1078. }
  1079. return Json(new { error = "User does not exist" });
  1080. }
  1081. catch (Exception ex)
  1082. {
  1083. return Json(new { error = ex.GetFullMessage(true) });
  1084. }
  1085. }
  1086. [HttpPost]
  1087. [ValidateAntiForgeryToken]
  1088. public async Task<IActionResult> CreateClient(string name, string homepageUrl, string logoUrl, string callbackUrl, [FromServices] ICompositeViewEngine viewEngine)
  1089. {
  1090. try
  1091. {
  1092. if (string.IsNullOrEmpty(name))
  1093. return Json(new { error = "You must enter a client name" });
  1094. if (string.IsNullOrEmpty(callbackUrl))
  1095. return Json(new { error = "You must enter an authorization callback URL" });
  1096. if (!callbackUrl.IsValidUrl())
  1097. return Json(new { error = "Invalid callback URL" });
  1098. if (!string.IsNullOrEmpty(homepageUrl) && !homepageUrl.IsValidUrl())
  1099. return Json(new { error = "Invalid homepage URL" });
  1100. if (!string.IsNullOrEmpty(logoUrl) && !logoUrl.IsValidUrl())
  1101. return Json(new { error = "Invalid logo URL" });
  1102. // Validate the code with the identity server
  1103. var result = await IdentityHelper.CreateClient(_config, User.Identity.Name, name, homepageUrl, logoUrl, callbackUrl, "openid", "role", "account-info", "security-info", "teknik-api.read", "teknik-api.write");
  1104. if (result.Success)
  1105. {
  1106. var client = (JObject)result.Data;
  1107. ClientViewModel model = new ClientViewModel();
  1108. model.Id = client["id"].ToString();
  1109. model.Name = name;
  1110. model.HomepageUrl = homepageUrl;
  1111. model.LogoUrl = logoUrl;
  1112. model.CallbackUrl = callbackUrl;
  1113. string renderedView = await RenderPartialViewToString(viewEngine, "~/Areas/User/Views/User/Settings/ClientView.cshtml", model);
  1114. return Json(new { result = true, clientId = client["id"], secret = client["secret"], html = renderedView });
  1115. }
  1116. return Json(new { error = result.Message });
  1117. }
  1118. catch (Exception ex)
  1119. {
  1120. return Json(new { error = ex.GetFullMessage(true) });
  1121. }
  1122. }
  1123. [HttpPost]
  1124. [ValidateAntiForgeryToken]
  1125. public async Task<IActionResult> GetClient(string clientId)
  1126. {
  1127. Client foundClient = await IdentityHelper.GetClient(_config, User.Identity.Name, clientId);
  1128. if (foundClient != null)
  1129. {
  1130. ClientViewModel model = new ClientViewModel()
  1131. {
  1132. Id = foundClient.ClientId,
  1133. Name = foundClient.ClientName,
  1134. HomepageUrl = foundClient.ClientUri,
  1135. LogoUrl = foundClient.LogoUri,
  1136. CallbackUrl = string.Join(',', foundClient.RedirectUris),
  1137. AllowedScopes = foundClient.AllowedScopes
  1138. };
  1139. return Json(new { result = true, client = model });
  1140. }
  1141. return new StatusCodeResult(StatusCodes.Status403Forbidden);
  1142. }
  1143. [HttpPost]
  1144. [ValidateAntiForgeryToken]
  1145. public async Task<IActionResult> EditClient(string clientId, string name, string homepageUrl, string logoUrl, string callbackUrl, [FromServices] ICompositeViewEngine viewEngine)
  1146. {
  1147. try
  1148. {
  1149. if (string.IsNullOrEmpty(name))
  1150. return Json(new { error = "You must enter a client name" });
  1151. if (string.IsNullOrEmpty(callbackUrl))
  1152. return Json(new { error = "You must enter an authorization callback URL" });
  1153. if (!callbackUrl.IsValidUrl())
  1154. return Json(new { error = "Invalid callback URL" });
  1155. if (!string.IsNullOrEmpty(homepageUrl) && !homepageUrl.IsValidUrl())
  1156. return Json(new { error = "Invalid homepage URL" });
  1157. if (!string.IsNullOrEmpty(logoUrl) && !logoUrl.IsValidUrl())
  1158. return Json(new { error = "Invalid logo URL" });
  1159. Client foundClient = await IdentityHelper.GetClient(_config, User.Identity.Name, clientId);
  1160. if (foundClient == null)
  1161. return Json(new { error = "Client does not exist" });
  1162. // Validate the code with the identity server
  1163. var result = await IdentityHelper.EditClient(_config, User.Identity.Name, clientId, name, homepageUrl, logoUrl, callbackUrl);
  1164. if (result.Success)
  1165. {
  1166. var client = (JObject)result.Data;
  1167. ClientViewModel model = new ClientViewModel();
  1168. model.Id = clientId;
  1169. model.Name = name;
  1170. model.HomepageUrl = homepageUrl;
  1171. model.LogoUrl = logoUrl;
  1172. model.CallbackUrl = callbackUrl;
  1173. string renderedView = await RenderPartialViewToString(viewEngine, "~/Areas/User/Views/User/Settings/ClientView.cshtml", model);
  1174. return Json(new { result = true, clientId = clientId, html = renderedView });
  1175. }
  1176. return Json(new { error = result.Message });
  1177. }
  1178. catch (Exception ex)
  1179. {
  1180. return Json(new { error = ex.GetFullMessage(true) });
  1181. }
  1182. }
  1183. [HttpPost]
  1184. [ValidateAntiForgeryToken]
  1185. public async Task<IActionResult> DeleteClient(string clientId)
  1186. {
  1187. try
  1188. {
  1189. // Validate the code with the identity server
  1190. var result = await IdentityHelper.DeleteClient(_config, clientId);
  1191. if (result.Success)
  1192. {
  1193. return Json(new { result = true });
  1194. }
  1195. return Json(new { error = result.Message });
  1196. }
  1197. catch (Exception ex)
  1198. {
  1199. return Json(new { error = ex.GetFullMessage(true) });
  1200. }
  1201. }
  1202. [HttpPost]
  1203. [ValidateAntiForgeryToken]
  1204. public IActionResult CreateInviteCodeLink(int inviteCodeId)
  1205. {
  1206. try
  1207. {
  1208. InviteCode code = _dbContext.InviteCodes.Where(c => c.InviteCodeId == inviteCodeId).FirstOrDefault();
  1209. if (code != null)
  1210. {
  1211. if (User.Identity.IsAuthenticated)
  1212. {
  1213. if (code.Owner.Username == User.Identity.Name)
  1214. {
  1215. return Json(new { result = Url.SubRouteUrl("account", "User.Register", new { inviteCode = code.Code }) });
  1216. }
  1217. }
  1218. return Json(new { error = "Invite Code not associated with this user" });
  1219. }
  1220. return Json(new { error = "Invalid Invite Code" });
  1221. }
  1222. catch (Exception ex)
  1223. {
  1224. return Json(new { error = ex.GetFullMessage(true) });
  1225. }
  1226. }
  1227. [HttpPost]
  1228. [ValidateAntiForgeryToken]
  1229. public IActionResult DeleteData(string type, string id)
  1230. {
  1231. var context = new ControllerContext();
  1232. context.HttpContext = Request.HttpContext;
  1233. context.RouteData = RouteData;
  1234. context.ActionDescriptor = new Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor();
  1235. switch (type)
  1236. {
  1237. case "upload":
  1238. var uploadController = new Upload.Controllers.UploadController(_logger, _config, _dbContext);
  1239. uploadController.ControllerContext = context;
  1240. return uploadController.Delete(id);
  1241. case "paste":
  1242. var pasteController = new Paste.Controllers.PasteController(_logger, _config, _dbContext);
  1243. pasteController.ControllerContext = context;
  1244. return pasteController.Delete(id);
  1245. case "shortenedUrl":
  1246. var shortenController = new Shortener.Controllers.ShortenerController(_logger, _config, _dbContext);
  1247. shortenController.ControllerContext = context;
  1248. return shortenController.Delete(id);
  1249. case "vault":
  1250. var vaultController = new Vault.Controllers.VaultController(_logger, _config, _dbContext);
  1251. vaultController.ControllerContext = context;
  1252. return vaultController.Delete(id);
  1253. }
  1254. return Json(new { error = "Invalid Type" });
  1255. }
  1256. }
  1257. }