public async Task <ActionResult <Object> > PutUserscript(Guid id, Userscript userscript)
        {
            Userscript previousVersion = await _context.Userscripts.FindAsync(id);

            string userId = User.FindFirst(ClaimTypes.NameIdentifier).Value;

            _currentUser = _userManager.FindByIdAsync(userId).Result;
            // check user can edit
            if (_currentUser.Id != previousVersion.Creator.Id)
            {
                return(Unauthorized());
            }

            int version = previousVersion.VersionNumber;

            _context.UserscriptVersions.Add(new UserscriptVersions
            {
                PreviousVersion     = previousVersion.Script, Script = previousVersion,
                VersionCreationTime = previousVersion.LastUpdated, VersionNumber = version
            });
            version += 1;
            previousVersion.VersionNumber = version;

            // strip unneeded header lines
            StringBuilder sb = StripHeader(userscript.Script);

            previousVersion.Script = sb.ToString();

            _context.Entry(previousVersion).State = EntityState.Modified;

            dynamic success = new ExpandoObject();

            success.Success = false;
            try
            {
                await _context.SaveChangesAsync();

                success.Success = true;
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!UserscriptExists(id))
                {
                    return(NotFound());
                }
                else
                {
                    throw;
                }
            }

            return(success);
        }
        public async Task <ActionResult <string> > GetUserscriptDownload(Guid id)
        {
            Userscript userscript = await _context.Userscripts.Where(x => x.ScriptId == id).Include(u => u.Creator)
                                    .FirstOrDefaultAsync();

            if (userscript == null)
            {
                return(NotFound());
            }

            Response.ContentType = "application/javascript";
            return(ApplyHeader(userscript));
        }
        public async Task <ActionResult <Userscript> > GetUserscript(Guid id)
        {
            Userscript userscript = await _context.Userscripts.Where(x => x.ScriptId == id).Include(u => u.Creator).Include(x => x.Categories).ThenInclude(x => x.Category)
                                    .FirstOrDefaultAsync();

            if (userscript == null)
            {
                return(NotFound());
            }

            userscript.Script  = ApplyHeader(userscript);
            userscript.Creator = SanitizeUser(userscript.Creator);
            return(userscript);
        }
        public async Task <ActionResult <Userscript> > DeleteUserscript(Guid id)
        {
            Userscript userscript = await _context.Userscripts.FindAsync(id);

            if (userscript == null)
            {
                return(NotFound());
            }

            _context.Userscripts.Remove(userscript);
            await _context.SaveChangesAsync();

            return(userscript);
        }
        private string ApplyHeader(Userscript userscript)
        {
            StringBuilder sb          = new StringBuilder();
            string        url         = HttpContext.Request.GetDisplayUrl();
            string        description = Regex.Replace(userscript.Description, @"\t|\n|\r", " ");

            sb.AppendLine($"// ==UserScript==");
            sb.AppendLine($"// @name        {userscript.ScriptName}");
            sb.AppendLine($"// @description {description}");
            sb.AppendLine($"// @version     1.{userscript.VersionNumber}");
            sb.AppendLine($"// @downloadURL {url}");
            sb.AppendLine($"// @author      {userscript.Creator.UserName}");
            sb.AppendLine(userscript.Script);
            return(sb.ToString());
        }
        public async Task <ActionResult <Userscript> > PostUserscript(Userscript userscript)
        {
            string id = User.FindFirst(ClaimTypes.NameIdentifier).Value;

            _currentUser       = _userManager.FindByIdAsync(id).Result;
            userscript.Creator = _currentUser;
            userscript.Created = DateTime.UtcNow;

            //filter out unwanted headers
            StringBuilder sb = StripHeader(userscript.Script);

            userscript.Script = sb.ToString();

            _context.Userscripts.Add(userscript);
            await _context.SaveChangesAsync();

            return(CreatedAtAction("GetUserscript", new { id = userscript.ScriptId }, userscript));
        }