Repository: bradymholt/aspnet-core-react-template Branch: master Commit: 2564bc935ee1 Files: 115 Total size: 283.7 KB Directory structure: gitextract_5pf0t787/ ├── .editorconfig ├── .github/ │ └── FUNDING.yml ├── .gitignore ├── .vscode/ │ ├── launch.json │ ├── settings.json │ └── tasks.json ├── LICENSE ├── README.md ├── api/ │ ├── .config/ │ │ └── dotnet-tools.json │ ├── Controllers/ │ │ ├── AuthController.cs │ │ └── ContactController.cs │ ├── Extensions/ │ │ └── StringExtension.cs │ ├── Middleware/ │ │ ├── SpaFallbackMiddleware.cs │ │ └── SpaFallbackOptions.cs │ ├── Migrations/ │ │ ├── 20171204210645_Initial.Designer.cs │ │ ├── 20171204210645_Initial.cs │ │ ├── 20200128145031_1580223026.Designer.cs │ │ ├── 20200128145031_1580223026.cs │ │ └── DefaultDbContextModelSnapshot.cs │ ├── Models/ │ │ ├── ApplicationUser.cs │ │ ├── Contact.cs │ │ ├── DefaultDbContext.cs │ │ ├── DefaultDbContextInitializer.cs │ │ └── DesignTimeDefaultDbContext.cs │ ├── NuGet.Config │ ├── Program.cs │ ├── Properties/ │ │ └── launchSettings.json │ ├── Services/ │ │ ├── EmailSender.cs │ │ ├── EmailSenderOptions.cs │ │ ├── IEmailSender.cs │ │ └── JwtOptions.cs │ ├── Startup.cs │ ├── ViewModels/ │ │ ├── ConfirmEmail.cs │ │ └── NewUser.cs │ ├── api.csproj │ ├── appsettings.json │ └── log/ │ └── development-20170420.log ├── api.sln ├── api.test/ │ ├── Controller/ │ │ └── Tests.cs │ ├── ControllerTests.cs │ ├── NuGet.Config │ ├── Unit/ │ │ └── Tests.cs │ └── api.test.csproj ├── client-react/ │ ├── boot.tsx │ ├── components/ │ │ ├── Auth.tsx │ │ ├── ContactForm.tsx │ │ ├── Contacts.tsx │ │ ├── Error.tsx │ │ ├── Header.tsx │ │ └── Routes.tsx │ ├── index.ejs │ ├── polyfills/ │ │ ├── array-find.d.ts │ │ ├── array-find.ts │ │ ├── object-assign.d.ts │ │ └── object-assign.ts │ ├── services/ │ │ ├── Auth.ts │ │ ├── Contacts.ts │ │ └── RestUtilities.ts │ ├── stores/ │ │ └── Auth.ts │ ├── styles/ │ │ ├── auth.styl │ │ ├── contacts.styl │ │ ├── global.css │ │ └── styles.d.ts │ ├── tsconfig.json │ ├── webpack.config.js │ └── webpack.config.release.js ├── client-react.test/ │ ├── polyfill/ │ │ └── localStorage.js │ ├── tests/ │ │ └── Contacts.tsx │ ├── tests.tsx │ ├── tsconfig.json │ └── utils.ts ├── docker-compose.yml ├── global.json ├── ops/ │ ├── README.md │ ├── config.yml.example │ ├── deploy.yml │ ├── group_vars/ │ │ └── all │ ├── library/ │ │ └── ghetto_json │ ├── provision.yml │ └── roles/ │ ├── deploy/ │ │ ├── defaults/ │ │ │ └── main.yml │ │ ├── meta/ │ │ │ └── main.yml │ │ └── tasks/ │ │ └── main.yml │ ├── deploy_user/ │ │ ├── meta/ │ │ │ └── main.yml │ │ └── tasks/ │ │ └── main.yml │ ├── dotnetcore/ │ │ ├── defaults/ │ │ │ └── main.yml │ │ └── tasks/ │ │ └── main.yml │ ├── firewall/ │ │ ├── handlers/ │ │ │ └── main.yml │ │ └── tasks/ │ │ └── main.yml │ ├── nginx/ │ │ ├── defaults/ │ │ │ └── main.yml │ │ ├── handlers/ │ │ │ └── main.yml │ │ ├── tasks/ │ │ │ └── main.yml │ │ └── templates/ │ │ └── etc_nginx_sites-available.conf.j2 │ ├── postgresql/ │ │ ├── LICENSE │ │ ├── README.md │ │ ├── defaults/ │ │ │ └── main.yml │ │ ├── handlers/ │ │ │ └── main.yml │ │ ├── tasks/ │ │ │ ├── backup.yml │ │ │ ├── configure.yml │ │ │ ├── install.yml │ │ │ └── main.yml │ │ ├── templates/ │ │ │ └── pgsql_backup.sh.j2 │ │ └── vars/ │ │ └── main.yml │ ├── s3cmd/ │ │ ├── meta/ │ │ │ └── main.yml │ │ ├── tasks/ │ │ │ └── main.yml │ │ └── templates/ │ │ └── s3cfg.j2 │ ├── ssl/ │ │ ├── defaults/ │ │ │ └── main.yml │ │ ├── meta/ │ │ │ └── main.yml │ │ ├── tasks/ │ │ │ └── main.yml │ │ └── templates/ │ │ └── config.j2 │ └── supervisor/ │ ├── defaults/ │ │ └── main.yml │ ├── handlers/ │ │ └── main.yml │ ├── tasks/ │ │ └── main.yml │ └── templates/ │ └── etc_supervisor_conf.d_app_name.conf.j2 ├── package.json └── scripts/ └── create-migration.js ================================================ FILE CONTENTS ================================================ ================================================ FILE: .editorconfig ================================================ root = true [*] end_of_line = lf charset = utf-8 indent_style = space trim_trailing_whitespace = true insert_final_newline = true indent_size = 2 [*.{js,ts,tsx}] indent_size = 4 ================================================ FILE: .github/FUNDING.yml ================================================ github: [bradymholt] ================================================ FILE: .gitignore ================================================ .DS_Store # dotnet core bin/ obj/ project.lock.json NuGetScratch/ api/wwwroot/** !api/wwwroot/scratch.html !api/wwwroot/favicon.ico # node node_modules/ typings/ npm-debug.log # client-react client-react/components/*.js client-react.test/build !client-react.test/build/client-react/styles/ # ops ops/hosts ops/config.yml ops/*.retry # other *.js.map # IDE .idea/ .vs/ ================================================ FILE: .vscode/launch.json ================================================ { "version": "0.2.0", "configurations": [ { "name": "Debug api/ (server)", "type": "coreclr", "request": "launch", "preLaunchTask": "build", "program": "${workspaceRoot}/api/bin/Debug/netcoreapp3.1/api.dll", "args": [], "env": { "ASPNETCORE_ENVIRONMENT": "Development", "NODE_PATH": "../node_modules/" }, "cwd": "${workspaceRoot}/api", "externalConsole": false, "stopAtEntry": false, "internalConsoleOptions": "openOnSessionStart" }, { "name": "Debug client-react.test/ (Mocha tests)", "type": "node", "request": "launch", "protocol": "inspector", "program": "${workspaceRoot}/node_modules/mocha/bin/_mocha", "stopOnEntry": false, "args": [ "--require", "ignore-styles", "--recursive", "client-react.test/build/client-react.test" ], "cwd": "${workspaceRoot}", "preLaunchTask": "pretest:client", "runtimeArgs": [ "--nolazy" ], "env": { "NODE_ENV": "development" }, "sourceMaps": true }, { "name": ".NET Core Attach", "type": "coreclr", "request": "attach", "processId": "${command:pickProcess}" } ] } ================================================ FILE: .vscode/settings.json ================================================ { "files.exclude": { "**/.git": true, "**/.svn": true, "**/.hg": true, "**/CVS": true, "**/.DS_Store": true, "**/bin": true, "**/obj": true } } ================================================ FILE: .vscode/tasks.json ================================================ { // See https://go.microsoft.com/fwlink/?LinkId=733558 // for the documentation about the tasks.json format "version": "0.1.0", "command": "npm", "isShellCommand": true, "showOutput": "always", "suppressTaskName": true, "tasks": [ { "taskName": "build", "args": [ "run", "build" ], "isBuildCommand": true }, { "taskName": "test", "args": [ "run", "test" ], "isTestCommand": true }, { "taskName": "pretest:client", "args":[ "run", "pretest:client" ] } ] } ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2017 Brady Holt Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # ASP.NET Core / React SPA Template App
 **Would you take a quick second and ⭐️ my repo?**
This app is a template application using ASP.NET Core 3.1 for a REST/JSON API server and React for a web client. ![screen recording 2017-06-10 at 04 12 pm](https://user-images.githubusercontent.com/759811/27006360-bd3b8152-4df7-11e7-9011-f22204abe4d5.gif) ## Overview of Stack - Server - ASP.NET Core 3.1 - PostgreSQL 10 - Entity Framework Core w/ EF Migrations - JSON Web Token (JWT) authorization - Docker used for development PostgreSQL database and MailCatcher server - Client - React 16 - Webpack for asset bundling and HMR (Hot Module Replacement) - CSS Modules - Fetch API for REST requests - Testing - xUnit for .NET Core - Enzyme for React - MailCatcher for development email delivery - DevOps - Ansible playbook for provisioning (Nginx reverse proxy, SSL via Let's Encrypt, PostgreSQL backups to S3) - Ansible playbook for deployment ## Demo [![Demo Video](https://cloud.githubusercontent.com/assets/759811/26319096/4075a7e2-3ee3-11e7-8017-26df7b278b27.png)](https://www.youtube.com/watch?v=xh5plRGg3Nc) ## Setup 1. Install the following: - [.NET Core 3.1](https://www.microsoft.com/net/core) - [Node.js >= v8](https://nodejs.org/en/download/) - [Ansible >= 2.6](http://docs.ansible.com/ansible/intro_installation.html) - [Docker](https://docs.docker.com/engine/installation/) 2. Run `npm install && npm start` 3. Open browser and navigate to [http://localhost:5000](http://localhost:5000). This template was developed and tested on macOS Sierra but should run on Windows (for development) as well. If you experience any issues getting it to run on Windows and work through them, please submit a PR! The production provisioning and deployment scripts (`provision:prod` and `deploy:prod`) use Ansible and require a Linux/Ubuntu >= 16.04 target host. ## Scripts ### `npm install` When first cloning the repo or adding new dependencies, run this command. This will: - Install Node dependencies from package.json - Install .NET Core dependencies from api/api.csproj and api.test/api.test.csproj (using dotnet restore) ### `npm start` To start the app for development, run this command. This will: - Run `docker-compose up` to ensure the PostgreSQL and MailCatcher Docker images are up and running - Run `dotnet watch run` which will build the app (if changed), watch for changes and start the web server on http://localhost:5000 - Run Webpack dev middleware with HMR via [ASP.NET JavaScriptServices](https://github.com/aspnet/JavaScriptServices) ### `npm run migrate` After making changes to Entity Framework models in `api/Models/`, run this command to generate and run a migration on the database. A timestamp will be used for the migration name. ### `npm test` This will run the xUnit tests in api.test/ and the Mocha/Enzyme tests in client-react.test/. ### `npm run provision:prod` _Before running this script, you need to create an ops/config.yml file first. See the [ops README](ops/) for instructions._ This will run the ops/provision.yml Ansible playbook and provision hosts in ops/hosts inventory file. Ubuntu 16.04 (Xenial) and Ubuntu 18.04 (Bionic) is supported and tested. This prepares the hosts to recieve deployments by doing the following: - Install Nginx - Generate a SSL certificate from [Let's Encrypt](https://letsencrypt.org/) and configure Nginx to use it - Install .Net Core - Install Supervisor (will run/manage the ASP.NET app) - Install PostgreSQL - Setup a cron job to automatically backup the PostgreSQL database, compress it, and upload it to S3. - Setup UFW (firewall) to lock everything down except inbound SSH and web traffic - Create a deploy user, directory for deployments and configure Nginx to serve from this directory ### `npm run deploy:prod` _Before running this script, you need to create a ops/config.yml file first. See the [ops README](ops/) for instructions._ This script will: - Build release Webpack bundles - Package the .NET Core application in Release mode (dotnet publish) - Run the ops/deploy.yml Ansible playbook to deploy this app to hosts in /ops/config.yml inventory file. This does the following: - Copies the build assets to the remote host(s) - Updates the `appsettings.json` file with PostgreSQL credentials specified in ops/group_vars/all file and the app URL (needed for JWT tokens) - Restarts the app so that changes will be picked up Entity Framework Migrations are [automatically applied upon startup](https://github.com/bradymholt/aspnet-core-react-template/blob/master/api/Program.cs#L23-L24) so they will run when the app restarts. ## Development Email Delivery This template includes a [MailCatcher](https://mailcatcher.me/) Docker image so that when email is sent during development (i.e. new user registration), it can be viewed in the MailCacher web interface at [http://localhost:1080/](http://localhost:1080/). ## Older Versions This template was originally created on .NET Core 1.0 and has been upgraded with new versions of .NET Core. Older versions can be found on the [Releases](https://github.com/bradymholt/aspnet-core-react-template/releases) page. ## Visual Studio Code config This project has [Visual Studio Code](https://code.visualstudio.com/) tasks and debugger launch config located in .vscode/. ### Tasks - **Command+Shift+B** - Runs the "build" task which builds the api/ project - **Command+Shift+T** - Runs the "test" task which runs the xUnit tests in api.test/ and Mocha/Enzyme tests in client-react.test/. ### Debug Launcher With the following debugger launch configs, you can set breakpoints in api/ or the the Mocha tests in client-react.test/ and have full debugging support. - **Debug api/ (server)** - Runs the vscode debugger (breakpoints) on the api/ .NET Core app - **Debug client-react.test/ (Mocha tests)** - Runs the vscode debugger on the client-react.test/ Mocha tests ## Credit The following resources were helpful in setting up this template: - [Sample for implementing Authentication with a React Flux app and JWTs](https://github.com/auth0-blog/react-flux-jwt-authentication-sample) - [Angular 2, React, and Knockout apps on ASP.NET Core](http://blog.stevensanderson.com/2016/05/02/angular2-react-knockout-apps-on-aspnet-core/) - [Setting up ASP.NET v5 (vNext) to use JWT tokens (using OpenIddict)](http://capesean.co.za/blog/asp-net-5-jwt-tokens/) - [Cross-platform Single Page Applications with ASP.NET Core 1.0, Angular 2 & TypeScript](https://chsakell.com/2016/01/01/cross-platform-single-page-applications-with-asp-net-5-angular-2-typescript/) - [Stack Overflow - Token Based Authentication in ASP.NET Core](http://stackoverflow.com/questions/30546542/token-based-authentication-in-asp-net-core-refreshed) - [SPA example of a token based authentication implementation using the Aurelia front end framework and ASP.NET core]( https://github.com/alexandre-spieser/AureliaAspNetCoreAuth) - [A Real-World React.js Setup for ASP.NET Core and MVC5](https://www.simple-talk.com/dotnet/asp-net/a-real-world-react-js-setup-for-asp-net-core-and-mvc) - [Customising ASP.NET Core Identity EF Core naming conventions for PostgreSQL](https://andrewlock.net/customising-asp-net-core-identity-ef-core-naming-conventions-for-postgresql) - My own perseverance because this took a _lot_ of time to get right 🤓 ================================================ FILE: api/.config/dotnet-tools.json ================================================ { "version": 1, "isRoot": true, "tools": { "dotnet-ef": { "version": "3.1.1", "commands": [ "dotnet-ef" ] } } } ================================================ FILE: api/Controllers/AuthController.cs ================================================ using System; using System.Text; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using aspnetCoreReactTemplate.Models; using aspnetCoreReactTemplate.Services; using aspnetCoreReactTemplate.ViewModels; using System.Security.Claims; using System.IdentityModel.Tokens.Jwt; using Microsoft.IdentityModel.Tokens; namespace aspnetCoreReactTemplate.Controllers { public class AuthController : Controller { private readonly UserManager _userManager; private readonly IOptions _identityOptions; private readonly JwtOptions _jwtOptions; private readonly IEmailSender _emailSender; private readonly SignInManager _signInManager; private readonly ILogger _logger; public AuthController( UserManager userManager, IOptions identityOptions, IOptions jwtOptions, IEmailSender emailSender, SignInManager signInManager, ILoggerFactory loggerFactory) { _userManager = userManager; _identityOptions = identityOptions; _jwtOptions = jwtOptions.Value; _emailSender = emailSender; _signInManager = signInManager; _logger = loggerFactory.CreateLogger(); } [AllowAnonymous] [HttpPost("~/api/auth/login")] [Produces("application/json")] public async Task Login(string username, string password) { // Ensure the username and password is valid. var user = await _userManager.FindByNameAsync(username); if (user == null || !await _userManager.CheckPasswordAsync(user, password)) { return BadRequest(new { error = "", //OpenIdConnectConstants.Errors.InvalidGrant, error_description = "The username or password is invalid." }); } // Ensure the email is confirmed. if (!await _userManager.IsEmailConfirmedAsync(user)) { return BadRequest(new { error = "email_not_confirmed", error_description = "You must have a confirmed email to log in." }); } _logger.LogInformation($"User logged in (id: {user.Id})"); // Generate and issue a JWT token var claims = new [] { new Claim(ClaimTypes.Name, user.Email), new Claim(JwtRegisteredClaimNames.Sub, user.Email), new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()) }; var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtOptions.key)); var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); var token = new JwtSecurityToken( issuer: _jwtOptions.issuer, audience: _jwtOptions.issuer, claims: claims, expires: DateTime.Now.AddMinutes(30), signingCredentials: creds); return Ok(new { token = new JwtSecurityTokenHandler().WriteToken(token) }); } [AllowAnonymous] [HttpPost("~/api/auth/register")] public async Task Register(NewUser model) { if (!ModelState.IsValid) { return BadRequest(ModelState); } var user = new ApplicationUser { UserName = model.username, Email = model.username }; var result = await _userManager.CreateAsync(user, model.password); if (result.Succeeded) { _logger.LogInformation($"New user registered (id: {user.Id})"); if (!user.EmailConfirmed) { // Send email confirmation email var confirmToken = await _userManager.GenerateEmailConfirmationTokenAsync(user); var emailConfirmUrl = Url.RouteUrl("ConfirmEmail", new { uid = user.Id, token = confirmToken }, this.Request.Scheme); await _emailSender.SendEmailAsync(model.username, "Please confirm your account", $"Please confirm your account by clicking this link." ); _logger.LogInformation($"Sent email confirmation email (id: {user.Id})"); } // Create a new authentication ticket. //var ticket = await CreateTicket(user); _logger.LogInformation($"User logged in (id: {user.Id})"); return Ok(); } else { return BadRequest(new { general = result.Errors.Select(x => x.Description) }); } } [AllowAnonymous] [HttpGet("~/api/auth/confirm", Name = "ConfirmEmail")] public async Task Confirm(string uid, string token) { var user = await _userManager.FindByIdAsync(uid); var confirmResult = await _userManager.ConfirmEmailAsync(user, token); if (confirmResult.Succeeded) { return Redirect("/?confirmed=1"); } else { return Redirect("/error/email-confirm"); } } } } ================================================ FILE: api/Controllers/ContactController.cs ================================================ using System.Linq; using System.Collections.Generic; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using aspnetCoreReactTemplate.Models; using Microsoft.EntityFrameworkCore; using System.Threading.Tasks; namespace aspnetCoreReactTemplate.Controllers { [Authorize] [Route("api/[controller]")] public class ContactsController : Controller { private readonly DefaultDbContext _context; public ContactsController(DefaultDbContext context) { _context = context; } // GET api/contacts [HttpGet] public IEnumerable Get() { return _context.Contacts.OrderBy((o)=> o.LastName); } // GET api/contacts/5 [HttpGet("{id}", Name = "GetContact")] public Contact Get(int id) { return _context.Contacts.Find(id); } // GET api/contacts/?= [HttpGet("search")] public IEnumerable Search(string q) { return _context.Contacts. Where((c)=> c.LastName.ToLower().Contains(q.ToLower()) || c.FirstName.ToLower().Contains(q.ToLower())). OrderBy((o) => o.LastName); } // POST api/contacts [HttpPost] public async Task Post([FromBody]Contact model) { if (!ModelState.IsValid) { return BadRequest(ModelState); } _context.Contacts.Add(model); await _context.SaveChangesAsync(); return CreatedAtRoute("GetContact", new { id = model.Id }, model); } // PUT api/contacts/5 [HttpPut("{id}")] public async Task Put(int id, [FromBody]Contact model) { if (!ModelState.IsValid) { return BadRequest(ModelState); } model.Id = id; _context.Update(model); await _context.SaveChangesAsync(); return Ok(); } // DELETE api/contacts/5 [HttpDelete("{id}")] public async Task Delete(int id) { var contact = new Contact() { Id = id }; _context.Entry(contact).State = EntityState.Deleted; await _context.SaveChangesAsync(); return Ok(); } } } ================================================ FILE: api/Extensions/StringExtension.cs ================================================ using System.Text.RegularExpressions; namespace aspnetCoreReactTemplate.Extensions { public static class StringExtensions { public static string ToSnakeCase(this string input) { if (string.IsNullOrEmpty(input)) { return input; } var startUnderscores = Regex.Match(input, @"^_+"); return startUnderscores + Regex.Replace(input, @"([a-z0-9])([A-Z])", "$1_$2").ToLower(); } } } ================================================ FILE: api/Middleware/SpaFallbackMiddleware.cs ================================================ using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; namespace aspnetCoreReactTemplate { /* Middleware that will rewrite (not redirect!) nested SPA page requests to the SPA root path. For SPA apps that are using client-side routing, a refresh or direct request for a nested path will be received by the server but the root path page should be actually be served because the client is responsible for routing, not the server. Only those requests not prefixed with options.ApiPathPrefix and not containing a path extention (i.e. image.png, scripts.js) will be rewritten. (SpaFallbackOptions options): ApiPathPrefix - The api path prefix is what requests for the REST api begin with. These will be ignored and not rewritten. So, if this is supplied as 'api', any requests starting with 'api' will not be rewritten. RewritePath - What path to rewrite to (usually '/') Examples: (options.ApiPathPrefix == "api", options.RewritePath="/") http://localhost:5000/api/auth/login => (no rewrite) http://localhost:5000/style.css => (no rewrite) http://localhost:5000/contacts => / http://localhost:5000/contacts/5/edit => / */ public class SpaFallbackMiddleware { private readonly RequestDelegate _next; private readonly ILogger _logger; private SpaFallbackOptions _options; public SpaFallbackMiddleware(RequestDelegate next, ILoggerFactory loggerFactory, SpaFallbackOptions options) { _next = next; _logger = loggerFactory.CreateLogger(); _options = options; } public async Task Invoke(HttpContext context) { _logger.LogInformation("Handling request: " + context.Request.Path); // If request path starts with _apiPathPrefix and the path does not have an extension (i.e. .css, .js, .png) if (!context.Request.Path.Value.StartsWith(_options.ApiPathPrefix) && !context.Request.Path.Value.Contains(".")) { _logger.LogInformation($"Rewriting path: {context.Request.Path} > {_options.RewritePath}"); context.Request.Path = _options.RewritePath; } await _next.Invoke(context); _logger.LogInformation("Finished handling request."); } } public static class SpaFallbackExtensions { public static IApplicationBuilder UseSpaFallback(this IApplicationBuilder builder, SpaFallbackOptions options) { if (options == null) { options = new SpaFallbackOptions(); } return builder.UseMiddleware(options); } } } ================================================ FILE: api/Middleware/SpaFallbackOptions.cs ================================================ namespace aspnetCoreReactTemplate { public class SpaFallbackOptions { public SpaFallbackOptions() { this.ApiPathPrefix = "/api"; this.RewritePath = "/"; } public string ApiPathPrefix { get; set; } public string RewritePath { get; set; } } } ================================================ FILE: api/Migrations/20171204210645_Initial.Designer.cs ================================================ // using aspnetCoreReactTemplate.Models; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Storage.Internal; using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; using System; namespace api.Migrations { [DbContext(typeof(DefaultDbContext))] [Migration("20171204210645_Initial")] partial class Initial { protected override void BuildTargetModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn) .HasAnnotation("ProductVersion", "2.0.0-rtm-26452"); modelBuilder.Entity("aspnetCoreReactTemplate.Models.ApplicationUser", b => { b.Property("Id") .ValueGeneratedOnAdd() .HasColumnName("id"); b.Property("AccessFailedCount") .HasColumnName("access_failed_count"); b.Property("ConcurrencyStamp") .IsConcurrencyToken() .HasColumnName("concurrency_stamp"); b.Property("Email") .HasColumnName("email") .HasMaxLength(256); b.Property("EmailConfirmed") .HasColumnName("email_confirmed"); b.Property("GivenName") .HasColumnName("given_name"); b.Property("LockoutEnabled") .HasColumnName("lockout_enabled"); b.Property("LockoutEnd") .HasColumnName("lockout_end"); b.Property("NormalizedEmail") .HasColumnName("normalized_email") .HasMaxLength(256); b.Property("NormalizedUserName") .HasColumnName("normalized_user_name") .HasMaxLength(256); b.Property("PasswordHash") .HasColumnName("password_hash"); b.Property("PhoneNumber") .HasColumnName("phone_number"); b.Property("PhoneNumberConfirmed") .HasColumnName("phone_number_confirmed"); b.Property("SecurityStamp") .HasColumnName("security_stamp"); b.Property("TwoFactorEnabled") .HasColumnName("two_factor_enabled"); b.Property("UserName") .HasColumnName("user_name") .HasMaxLength(256); b.HasKey("Id") .HasName("pk_users"); b.HasIndex("NormalizedEmail") .HasName("email_index"); b.HasIndex("NormalizedUserName") .IsUnique() .HasName("user_name_index"); b.ToTable("users"); }); modelBuilder.Entity("aspnetCoreReactTemplate.Models.Contact", b => { b.Property("id") .ValueGeneratedOnAdd() .HasColumnName("id"); b.Property("email") .HasColumnName("email") .HasMaxLength(30); b.Property("firstName") .IsRequired() .HasColumnName("first_name"); b.Property("lastName") .IsRequired() .HasColumnName("last_name"); b.Property("phone") .HasColumnName("phone"); b.HasKey("id") .HasName("pk_contacts"); b.ToTable("contacts"); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => { b.Property("Id") .ValueGeneratedOnAdd() .HasColumnName("id"); b.Property("ConcurrencyStamp") .IsConcurrencyToken() .HasColumnName("concurrency_stamp"); b.Property("Name") .HasColumnName("name") .HasMaxLength(256); b.Property("NormalizedName") .HasColumnName("normalized_name") .HasMaxLength(256); b.HasKey("Id") .HasName("pk_roles"); b.HasIndex("NormalizedName") .IsUnique() .HasName("role_name_index"); b.ToTable("roles"); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => { b.Property("Id") .ValueGeneratedOnAdd() .HasColumnName("id"); b.Property("ClaimType") .HasColumnName("claim_type"); b.Property("ClaimValue") .HasColumnName("claim_value"); b.Property("RoleId") .IsRequired() .HasColumnName("role_id"); b.HasKey("Id") .HasName("pk_role_claims"); b.HasIndex("RoleId") .HasName("ix_role_claims_role_id"); b.ToTable("role_claims"); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => { b.Property("Id") .ValueGeneratedOnAdd() .HasColumnName("id"); b.Property("ClaimType") .HasColumnName("claim_type"); b.Property("ClaimValue") .HasColumnName("claim_value"); b.Property("UserId") .IsRequired() .HasColumnName("user_id"); b.HasKey("Id") .HasName("pk_user_claims"); b.HasIndex("UserId") .HasName("ix_user_claims_user_id"); b.ToTable("user_claims"); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => { b.Property("LoginProvider") .HasColumnName("login_provider"); b.Property("ProviderKey") .HasColumnName("provider_key"); b.Property("ProviderDisplayName") .HasColumnName("provider_display_name"); b.Property("UserId") .IsRequired() .HasColumnName("user_id"); b.HasKey("LoginProvider", "ProviderKey") .HasName("pk_user_logins"); b.HasIndex("UserId") .HasName("ix_user_logins_user_id"); b.ToTable("user_logins"); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => { b.Property("UserId") .HasColumnName("user_id"); b.Property("RoleId") .HasColumnName("role_id"); b.HasKey("UserId", "RoleId") .HasName("pk_user_roles"); b.HasIndex("RoleId") .HasName("ix_user_roles_role_id"); b.ToTable("user_roles"); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => { b.Property("UserId") .HasColumnName("user_id"); b.Property("LoginProvider") .HasColumnName("login_provider"); b.Property("Name") .HasColumnName("name"); b.Property("Value") .HasColumnName("value"); b.HasKey("UserId", "LoginProvider", "Name") .HasName("pk_user_tokens"); b.ToTable("user_tokens"); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => { b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole") .WithMany() .HasForeignKey("RoleId") .HasConstraintName("fk_role_claims_roles_role_id") .OnDelete(DeleteBehavior.Cascade); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => { b.HasOne("aspnetCoreReactTemplate.Models.ApplicationUser") .WithMany() .HasForeignKey("UserId") .HasConstraintName("fk_user_claims_users_user_id") .OnDelete(DeleteBehavior.Cascade); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => { b.HasOne("aspnetCoreReactTemplate.Models.ApplicationUser") .WithMany() .HasForeignKey("UserId") .HasConstraintName("fk_user_logins_users_user_id") .OnDelete(DeleteBehavior.Cascade); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => { b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole") .WithMany() .HasForeignKey("RoleId") .HasConstraintName("fk_user_roles_roles_role_id") .OnDelete(DeleteBehavior.Cascade); b.HasOne("aspnetCoreReactTemplate.Models.ApplicationUser") .WithMany() .HasForeignKey("UserId") .HasConstraintName("fk_user_roles_users_user_id") .OnDelete(DeleteBehavior.Cascade); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => { b.HasOne("aspnetCoreReactTemplate.Models.ApplicationUser") .WithMany() .HasForeignKey("UserId") .HasConstraintName("fk_user_tokens_users_user_id") .OnDelete(DeleteBehavior.Cascade); }); #pragma warning restore 612, 618 } } } ================================================ FILE: api/Migrations/20171204210645_Initial.cs ================================================ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; using System; using System.Collections.Generic; namespace api.Migrations { public partial class Initial : Migration { protected override void Up(MigrationBuilder migrationBuilder) { migrationBuilder.CreateTable( name: "contacts", columns: table => new { id = table.Column(type: "int4", nullable: false) .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn), email = table.Column(type: "varchar(30)", maxLength: 30, nullable: true), first_name = table.Column(type: "text", nullable: false), last_name = table.Column(type: "text", nullable: false), phone = table.Column(type: "text", nullable: true) }, constraints: table => { table.PrimaryKey("pk_contacts", x => x.id); }); migrationBuilder.CreateTable( name: "roles", columns: table => new { id = table.Column(type: "text", nullable: false), concurrency_stamp = table.Column(type: "text", nullable: true), name = table.Column(type: "varchar(256)", maxLength: 256, nullable: true), normalized_name = table.Column(type: "varchar(256)", maxLength: 256, nullable: true) }, constraints: table => { table.PrimaryKey("pk_roles", x => x.id); }); migrationBuilder.CreateTable( name: "users", columns: table => new { id = table.Column(type: "text", nullable: false), access_failed_count = table.Column(type: "int4", nullable: false), concurrency_stamp = table.Column(type: "text", nullable: true), email = table.Column(type: "varchar(256)", maxLength: 256, nullable: true), email_confirmed = table.Column(type: "bool", nullable: false), given_name = table.Column(type: "text", nullable: true), lockout_enabled = table.Column(type: "bool", nullable: false), lockout_end = table.Column(type: "timestamptz", nullable: true), normalized_email = table.Column(type: "varchar(256)", maxLength: 256, nullable: true), normalized_user_name = table.Column(type: "varchar(256)", maxLength: 256, nullable: true), password_hash = table.Column(type: "text", nullable: true), phone_number = table.Column(type: "text", nullable: true), phone_number_confirmed = table.Column(type: "bool", nullable: false), security_stamp = table.Column(type: "text", nullable: true), two_factor_enabled = table.Column(type: "bool", nullable: false), user_name = table.Column(type: "varchar(256)", maxLength: 256, nullable: true) }, constraints: table => { table.PrimaryKey("pk_users", x => x.id); }); migrationBuilder.CreateTable( name: "role_claims", columns: table => new { id = table.Column(type: "int4", nullable: false) .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn), claim_type = table.Column(type: "text", nullable: true), claim_value = table.Column(type: "text", nullable: true), role_id = table.Column(type: "text", nullable: false) }, constraints: table => { table.PrimaryKey("pk_role_claims", x => x.id); table.ForeignKey( name: "fk_role_claims_roles_role_id", column: x => x.role_id, principalTable: "roles", principalColumn: "id", onDelete: ReferentialAction.Cascade); }); migrationBuilder.CreateTable( name: "user_claims", columns: table => new { id = table.Column(type: "int4", nullable: false) .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn), claim_type = table.Column(type: "text", nullable: true), claim_value = table.Column(type: "text", nullable: true), user_id = table.Column(type: "text", nullable: false) }, constraints: table => { table.PrimaryKey("pk_user_claims", x => x.id); table.ForeignKey( name: "fk_user_claims_users_user_id", column: x => x.user_id, principalTable: "users", principalColumn: "id", onDelete: ReferentialAction.Cascade); }); migrationBuilder.CreateTable( name: "user_logins", columns: table => new { login_provider = table.Column(type: "text", nullable: false), provider_key = table.Column(type: "text", nullable: false), provider_display_name = table.Column(type: "text", nullable: true), user_id = table.Column(type: "text", nullable: false) }, constraints: table => { table.PrimaryKey("pk_user_logins", x => new { x.login_provider, x.provider_key }); table.ForeignKey( name: "fk_user_logins_users_user_id", column: x => x.user_id, principalTable: "users", principalColumn: "id", onDelete: ReferentialAction.Cascade); }); migrationBuilder.CreateTable( name: "user_roles", columns: table => new { user_id = table.Column(type: "text", nullable: false), role_id = table.Column(type: "text", nullable: false) }, constraints: table => { table.PrimaryKey("pk_user_roles", x => new { x.user_id, x.role_id }); table.ForeignKey( name: "fk_user_roles_roles_role_id", column: x => x.role_id, principalTable: "roles", principalColumn: "id", onDelete: ReferentialAction.Cascade); table.ForeignKey( name: "fk_user_roles_users_user_id", column: x => x.user_id, principalTable: "users", principalColumn: "id", onDelete: ReferentialAction.Cascade); }); migrationBuilder.CreateTable( name: "user_tokens", columns: table => new { user_id = table.Column(type: "text", nullable: false), login_provider = table.Column(type: "text", nullable: false), name = table.Column(type: "text", nullable: false), value = table.Column(type: "text", nullable: true) }, constraints: table => { table.PrimaryKey("pk_user_tokens", x => new { x.user_id, x.login_provider, x.name }); table.ForeignKey( name: "fk_user_tokens_users_user_id", column: x => x.user_id, principalTable: "users", principalColumn: "id", onDelete: ReferentialAction.Cascade); }); migrationBuilder.CreateIndex( name: "ix_role_claims_role_id", table: "role_claims", column: "role_id"); migrationBuilder.CreateIndex( name: "role_name_index", table: "roles", column: "normalized_name", unique: true); migrationBuilder.CreateIndex( name: "ix_user_claims_user_id", table: "user_claims", column: "user_id"); migrationBuilder.CreateIndex( name: "ix_user_logins_user_id", table: "user_logins", column: "user_id"); migrationBuilder.CreateIndex( name: "ix_user_roles_role_id", table: "user_roles", column: "role_id"); migrationBuilder.CreateIndex( name: "email_index", table: "users", column: "normalized_email"); migrationBuilder.CreateIndex( name: "user_name_index", table: "users", column: "normalized_user_name", unique: true); } protected override void Down(MigrationBuilder migrationBuilder) { migrationBuilder.DropTable( name: "contacts"); migrationBuilder.DropTable( name: "role_claims"); migrationBuilder.DropTable( name: "user_claims"); migrationBuilder.DropTable( name: "user_logins"); migrationBuilder.DropTable( name: "user_roles"); migrationBuilder.DropTable( name: "user_tokens"); migrationBuilder.DropTable( name: "roles"); migrationBuilder.DropTable( name: "users"); } } } ================================================ FILE: api/Migrations/20200128145031_1580223026.Designer.cs ================================================ // using System; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; using aspnetCoreReactTemplate.Models; namespace api.Migrations { [DbContext(typeof(DefaultDbContext))] [Migration("20200128145031_1580223026")] partial class _1580223026 { protected override void BuildTargetModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) .HasAnnotation("ProductVersion", "3.1.1") .HasAnnotation("Relational:MaxIdentifierLength", 63); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => { b.Property("Id") .HasColumnName("id") .HasColumnType("text"); b.Property("ConcurrencyStamp") .IsConcurrencyToken() .HasColumnName("concurrency_stamp") .HasColumnType("text"); b.Property("Name") .HasColumnName("name") .HasColumnType("character varying(256)") .HasMaxLength(256); b.Property("NormalizedName") .HasColumnName("normalized_name") .HasColumnType("character varying(256)") .HasMaxLength(256); b.HasKey("Id") .HasName("pk_roles"); b.HasIndex("NormalizedName") .IsUnique() .HasName("role_name_index"); b.ToTable("roles"); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => { b.Property("Id") .ValueGeneratedOnAdd() .HasColumnName("id") .HasColumnType("integer") .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); b.Property("ClaimType") .HasColumnName("claim_type") .HasColumnType("text"); b.Property("ClaimValue") .HasColumnName("claim_value") .HasColumnType("text"); b.Property("RoleId") .IsRequired() .HasColumnName("role_id") .HasColumnType("text"); b.HasKey("Id") .HasName("pk_role_claims"); b.HasIndex("RoleId") .HasName("ix_role_claims_role_id"); b.ToTable("role_claims"); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => { b.Property("Id") .ValueGeneratedOnAdd() .HasColumnName("id") .HasColumnType("integer") .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); b.Property("ClaimType") .HasColumnName("claim_type") .HasColumnType("text"); b.Property("ClaimValue") .HasColumnName("claim_value") .HasColumnType("text"); b.Property("UserId") .IsRequired() .HasColumnName("user_id") .HasColumnType("text"); b.HasKey("Id") .HasName("pk_user_claims"); b.HasIndex("UserId") .HasName("ix_user_claims_user_id"); b.ToTable("user_claims"); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => { b.Property("LoginProvider") .HasColumnName("login_provider") .HasColumnType("text"); b.Property("ProviderKey") .HasColumnName("provider_key") .HasColumnType("text"); b.Property("ProviderDisplayName") .HasColumnName("provider_display_name") .HasColumnType("text"); b.Property("UserId") .IsRequired() .HasColumnName("user_id") .HasColumnType("text"); b.HasKey("LoginProvider", "ProviderKey") .HasName("pk_user_logins"); b.HasIndex("UserId") .HasName("ix_user_logins_user_id"); b.ToTable("user_logins"); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => { b.Property("UserId") .HasColumnName("user_id") .HasColumnType("text"); b.Property("RoleId") .HasColumnName("role_id") .HasColumnType("text"); b.HasKey("UserId", "RoleId") .HasName("pk_user_roles"); b.HasIndex("RoleId") .HasName("ix_user_roles_role_id"); b.ToTable("user_roles"); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => { b.Property("UserId") .HasColumnName("user_id") .HasColumnType("text"); b.Property("LoginProvider") .HasColumnName("login_provider") .HasColumnType("text"); b.Property("Name") .HasColumnName("name") .HasColumnType("text"); b.Property("Value") .HasColumnName("value") .HasColumnType("text"); b.HasKey("UserId", "LoginProvider", "Name") .HasName("pk_user_tokens"); b.ToTable("user_tokens"); }); modelBuilder.Entity("aspnetCoreReactTemplate.Models.ApplicationUser", b => { b.Property("Id") .HasColumnName("id") .HasColumnType("text"); b.Property("AccessFailedCount") .HasColumnName("access_failed_count") .HasColumnType("integer"); b.Property("ConcurrencyStamp") .IsConcurrencyToken() .HasColumnName("concurrency_stamp") .HasColumnType("text"); b.Property("Email") .HasColumnName("email") .HasColumnType("character varying(256)") .HasMaxLength(256); b.Property("EmailConfirmed") .HasColumnName("email_confirmed") .HasColumnType("boolean"); b.Property("GivenName") .HasColumnName("given_name") .HasColumnType("text"); b.Property("LockoutEnabled") .HasColumnName("lockout_enabled") .HasColumnType("boolean"); b.Property("LockoutEnd") .HasColumnName("lockout_end") .HasColumnType("timestamp with time zone"); b.Property("NormalizedEmail") .HasColumnName("normalized_email") .HasColumnType("character varying(256)") .HasMaxLength(256); b.Property("NormalizedUserName") .HasColumnName("normalized_user_name") .HasColumnType("character varying(256)") .HasMaxLength(256); b.Property("PasswordHash") .HasColumnName("password_hash") .HasColumnType("text"); b.Property("PhoneNumber") .HasColumnName("phone_number") .HasColumnType("text"); b.Property("PhoneNumberConfirmed") .HasColumnName("phone_number_confirmed") .HasColumnType("boolean"); b.Property("SecurityStamp") .HasColumnName("security_stamp") .HasColumnType("text"); b.Property("TwoFactorEnabled") .HasColumnName("two_factor_enabled") .HasColumnType("boolean"); b.Property("UserName") .HasColumnName("user_name") .HasColumnType("character varying(256)") .HasMaxLength(256); b.HasKey("Id") .HasName("pk_users"); b.HasIndex("NormalizedEmail") .HasName("email_index"); b.HasIndex("NormalizedUserName") .IsUnique() .HasName("user_name_index"); b.ToTable("users"); }); modelBuilder.Entity("aspnetCoreReactTemplate.Models.Contact", b => { b.Property("Id") .ValueGeneratedOnAdd() .HasColumnName("id") .HasColumnType("integer") .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); b.Property("Email") .HasColumnName("email") .HasColumnType("character varying(30)") .HasMaxLength(30); b.Property("FirstName") .IsRequired() .HasColumnName("first_name") .HasColumnType("text"); b.Property("LastName") .IsRequired() .HasColumnName("last_name") .HasColumnType("text"); b.Property("Phone") .HasColumnName("phone") .HasColumnType("text"); b.HasKey("Id") .HasName("pk_contacts"); b.ToTable("contacts"); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => { b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) .WithMany() .HasForeignKey("RoleId") .HasConstraintName("fk_role_claims_roles_role_id") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => { b.HasOne("aspnetCoreReactTemplate.Models.ApplicationUser", null) .WithMany() .HasForeignKey("UserId") .HasConstraintName("fk_user_claims_asp_net_users_user_id") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => { b.HasOne("aspnetCoreReactTemplate.Models.ApplicationUser", null) .WithMany() .HasForeignKey("UserId") .HasConstraintName("fk_user_logins_asp_net_users_user_id") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => { b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) .WithMany() .HasForeignKey("RoleId") .HasConstraintName("fk_user_roles_roles_role_id") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); b.HasOne("aspnetCoreReactTemplate.Models.ApplicationUser", null) .WithMany() .HasForeignKey("UserId") .HasConstraintName("fk_user_roles_asp_net_users_user_id") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => { b.HasOne("aspnetCoreReactTemplate.Models.ApplicationUser", null) .WithMany() .HasForeignKey("UserId") .HasConstraintName("fk_user_tokens_asp_net_users_user_id") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); }); #pragma warning restore 612, 618 } } } ================================================ FILE: api/Migrations/20200128145031_1580223026.cs ================================================ using Microsoft.EntityFrameworkCore.Migrations; namespace api.Migrations { public partial class _1580223026 : Migration { protected override void Up(MigrationBuilder migrationBuilder) { } protected override void Down(MigrationBuilder migrationBuilder) { } } } ================================================ FILE: api/Migrations/DefaultDbContextModelSnapshot.cs ================================================ // using System; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; using aspnetCoreReactTemplate.Models; namespace api.Migrations { [DbContext(typeof(DefaultDbContext))] partial class DefaultDbContextModelSnapshot : ModelSnapshot { protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) .HasAnnotation("ProductVersion", "3.1.1") .HasAnnotation("Relational:MaxIdentifierLength", 63); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => { b.Property("Id") .HasColumnName("id") .HasColumnType("text"); b.Property("ConcurrencyStamp") .IsConcurrencyToken() .HasColumnName("concurrency_stamp") .HasColumnType("text"); b.Property("Name") .HasColumnName("name") .HasColumnType("character varying(256)") .HasMaxLength(256); b.Property("NormalizedName") .HasColumnName("normalized_name") .HasColumnType("character varying(256)") .HasMaxLength(256); b.HasKey("Id") .HasName("pk_roles"); b.HasIndex("NormalizedName") .IsUnique() .HasName("role_name_index"); b.ToTable("roles"); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => { b.Property("Id") .ValueGeneratedOnAdd() .HasColumnName("id") .HasColumnType("integer") .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); b.Property("ClaimType") .HasColumnName("claim_type") .HasColumnType("text"); b.Property("ClaimValue") .HasColumnName("claim_value") .HasColumnType("text"); b.Property("RoleId") .IsRequired() .HasColumnName("role_id") .HasColumnType("text"); b.HasKey("Id") .HasName("pk_role_claims"); b.HasIndex("RoleId") .HasName("ix_role_claims_role_id"); b.ToTable("role_claims"); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => { b.Property("Id") .ValueGeneratedOnAdd() .HasColumnName("id") .HasColumnType("integer") .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); b.Property("ClaimType") .HasColumnName("claim_type") .HasColumnType("text"); b.Property("ClaimValue") .HasColumnName("claim_value") .HasColumnType("text"); b.Property("UserId") .IsRequired() .HasColumnName("user_id") .HasColumnType("text"); b.HasKey("Id") .HasName("pk_user_claims"); b.HasIndex("UserId") .HasName("ix_user_claims_user_id"); b.ToTable("user_claims"); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => { b.Property("LoginProvider") .HasColumnName("login_provider") .HasColumnType("text"); b.Property("ProviderKey") .HasColumnName("provider_key") .HasColumnType("text"); b.Property("ProviderDisplayName") .HasColumnName("provider_display_name") .HasColumnType("text"); b.Property("UserId") .IsRequired() .HasColumnName("user_id") .HasColumnType("text"); b.HasKey("LoginProvider", "ProviderKey") .HasName("pk_user_logins"); b.HasIndex("UserId") .HasName("ix_user_logins_user_id"); b.ToTable("user_logins"); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => { b.Property("UserId") .HasColumnName("user_id") .HasColumnType("text"); b.Property("RoleId") .HasColumnName("role_id") .HasColumnType("text"); b.HasKey("UserId", "RoleId") .HasName("pk_user_roles"); b.HasIndex("RoleId") .HasName("ix_user_roles_role_id"); b.ToTable("user_roles"); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => { b.Property("UserId") .HasColumnName("user_id") .HasColumnType("text"); b.Property("LoginProvider") .HasColumnName("login_provider") .HasColumnType("text"); b.Property("Name") .HasColumnName("name") .HasColumnType("text"); b.Property("Value") .HasColumnName("value") .HasColumnType("text"); b.HasKey("UserId", "LoginProvider", "Name") .HasName("pk_user_tokens"); b.ToTable("user_tokens"); }); modelBuilder.Entity("aspnetCoreReactTemplate.Models.ApplicationUser", b => { b.Property("Id") .HasColumnName("id") .HasColumnType("text"); b.Property("AccessFailedCount") .HasColumnName("access_failed_count") .HasColumnType("integer"); b.Property("ConcurrencyStamp") .IsConcurrencyToken() .HasColumnName("concurrency_stamp") .HasColumnType("text"); b.Property("Email") .HasColumnName("email") .HasColumnType("character varying(256)") .HasMaxLength(256); b.Property("EmailConfirmed") .HasColumnName("email_confirmed") .HasColumnType("boolean"); b.Property("GivenName") .HasColumnName("given_name") .HasColumnType("text"); b.Property("LockoutEnabled") .HasColumnName("lockout_enabled") .HasColumnType("boolean"); b.Property("LockoutEnd") .HasColumnName("lockout_end") .HasColumnType("timestamp with time zone"); b.Property("NormalizedEmail") .HasColumnName("normalized_email") .HasColumnType("character varying(256)") .HasMaxLength(256); b.Property("NormalizedUserName") .HasColumnName("normalized_user_name") .HasColumnType("character varying(256)") .HasMaxLength(256); b.Property("PasswordHash") .HasColumnName("password_hash") .HasColumnType("text"); b.Property("PhoneNumber") .HasColumnName("phone_number") .HasColumnType("text"); b.Property("PhoneNumberConfirmed") .HasColumnName("phone_number_confirmed") .HasColumnType("boolean"); b.Property("SecurityStamp") .HasColumnName("security_stamp") .HasColumnType("text"); b.Property("TwoFactorEnabled") .HasColumnName("two_factor_enabled") .HasColumnType("boolean"); b.Property("UserName") .HasColumnName("user_name") .HasColumnType("character varying(256)") .HasMaxLength(256); b.HasKey("Id") .HasName("pk_users"); b.HasIndex("NormalizedEmail") .HasName("email_index"); b.HasIndex("NormalizedUserName") .IsUnique() .HasName("user_name_index"); b.ToTable("users"); }); modelBuilder.Entity("aspnetCoreReactTemplate.Models.Contact", b => { b.Property("Id") .ValueGeneratedOnAdd() .HasColumnName("id") .HasColumnType("integer") .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); b.Property("Email") .HasColumnName("email") .HasColumnType("character varying(30)") .HasMaxLength(30); b.Property("FirstName") .IsRequired() .HasColumnName("first_name") .HasColumnType("text"); b.Property("LastName") .IsRequired() .HasColumnName("last_name") .HasColumnType("text"); b.Property("Phone") .HasColumnName("phone") .HasColumnType("text"); b.HasKey("Id") .HasName("pk_contacts"); b.ToTable("contacts"); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => { b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) .WithMany() .HasForeignKey("RoleId") .HasConstraintName("fk_role_claims_roles_role_id") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => { b.HasOne("aspnetCoreReactTemplate.Models.ApplicationUser", null) .WithMany() .HasForeignKey("UserId") .HasConstraintName("fk_user_claims_asp_net_users_user_id") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => { b.HasOne("aspnetCoreReactTemplate.Models.ApplicationUser", null) .WithMany() .HasForeignKey("UserId") .HasConstraintName("fk_user_logins_asp_net_users_user_id") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => { b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) .WithMany() .HasForeignKey("RoleId") .HasConstraintName("fk_user_roles_roles_role_id") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); b.HasOne("aspnetCoreReactTemplate.Models.ApplicationUser", null) .WithMany() .HasForeignKey("UserId") .HasConstraintName("fk_user_roles_asp_net_users_user_id") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => { b.HasOne("aspnetCoreReactTemplate.Models.ApplicationUser", null) .WithMany() .HasForeignKey("UserId") .HasConstraintName("fk_user_tokens_asp_net_users_user_id") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); }); #pragma warning restore 612, 618 } } } ================================================ FILE: api/Models/ApplicationUser.cs ================================================ using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity.EntityFrameworkCore; namespace aspnetCoreReactTemplate.Models { public class ApplicationUser: IdentityUser { public string GivenName { get; set; } } } ================================================ FILE: api/Models/Contact.cs ================================================ using System.ComponentModel.DataAnnotations; namespace aspnetCoreReactTemplate.Models { public class Contact { public int Id { get; set; } [Required] [MinLength(3)] public string LastName { get; set; } [Required] public string FirstName { get; set; } public string Phone { get; set; } [DataType(DataType.EmailAddress)] [StringLength(30, MinimumLength = 0)] public string Email { get; set; } } } ================================================ FILE: api/Models/DefaultDbContext.cs ================================================ using aspnetCoreReactTemplate.Extensions; using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; namespace aspnetCoreReactTemplate.Models { public class DefaultDbContext : IdentityDbContext { public DefaultDbContext(DbContextOptions options) : base(options) { } public DbSet ApplicationUsers { get; set; } public DbSet Contacts { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); foreach (var entity in modelBuilder.Model.GetEntityTypes()) { // Remove 'AspNet' prefix and convert table name from PascalCase to snake_case. E.g. AspNetRoleClaims -> role_claims entity.SetTableName(entity.GetTableName().Replace("AspNet", "").ToSnakeCase()); // Convert column names from PascalCase to snake_case. foreach (var property in entity.GetProperties()) { property.SetColumnName(property.Name.ToSnakeCase()); } // Convert primary key names from PascalCase to snake_case. E.g. PK_users -> pk_users foreach (var key in entity.GetKeys()) { key.SetName(key.GetName().ToSnakeCase()); } // Convert foreign key names from PascalCase to snake_case. foreach (var key in entity.GetForeignKeys()) { key.SetConstraintName(key.GetConstraintName().ToSnakeCase()); } // Convert index names from PascalCase to snake_case. foreach (var index in entity.GetIndexes()) { index.SetName(index.GetName().ToSnakeCase()); } } } } } ================================================ FILE: api/Models/DefaultDbContextInitializer.cs ================================================ using Microsoft.AspNetCore.Identity; using System.Linq; using System.Threading.Tasks; namespace aspnetCoreReactTemplate.Models { public class DefaultDbContextInitializer : IDefaultDbContextInitializer { private readonly DefaultDbContext _context; private readonly UserManager _userManager; private readonly RoleManager _roleManager; public DefaultDbContextInitializer(DefaultDbContext context, UserManager userManager, RoleManager roleManager) { _userManager = userManager; _context = context; _roleManager = roleManager; } public bool EnsureCreated() { return _context.Database.EnsureCreated(); } public async Task Seed() { var email = "user@test.com"; if (await _userManager.FindByEmailAsync(email) == null) { var user = new ApplicationUser { UserName = email, Email = email, EmailConfirmed = true, GivenName = "John Doe" }; await _userManager.CreateAsync(user, "P2ssw0rd!"); } if (_context.Contacts.Any()) { foreach (var u in _context.Contacts) { _context.Remove(u); } } _context.Contacts.Add(new Contact() { LastName = "Finkley", FirstName = "Adam", Phone = "555-555-5555", Email = "adam@somewhere.com" }); _context.Contacts.Add(new Contact() { LastName = "Biles", FirstName = "Steven", Phone = "555-555-5555", Email = "sbiles@somewhere.com" }); _context.SaveChanges(); } } public interface IDefaultDbContextInitializer { bool EnsureCreated(); Task Seed(); } } ================================================ FILE: api/Models/DesignTimeDefaultDbContext.cs ================================================ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Design; using Microsoft.Extensions.Configuration; namespace aspnetCoreReactTemplate.Models { public class BloggingContextFactory : IDesignTimeDbContextFactory { public DefaultDbContext CreateDbContext(string[] args) { var config = new ConfigurationBuilder() .SetBasePath(System.IO.Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json") .Build(); var options = new DbContextOptionsBuilder(); options.UseNpgsql(config.GetConnectionString("defaultConnection")); return new DefaultDbContext(options.Options); } } } ================================================ FILE: api/NuGet.Config ================================================ ================================================ FILE: api/Program.cs ================================================ using System.IO; using aspnetCoreReactTemplate.Models; using Microsoft.AspNetCore.Hosting; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; namespace aspnetCoreReactTemplate { public class Program { public static void Main(string[] args) { var config = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json") .Build(); var host = CreateHostBuilder(config, args).Build(); using (var scope = host.Services.CreateScope()) { var dbContext = scope.ServiceProvider.GetService(); dbContext.Database.Migrate(); var env = scope.ServiceProvider.GetRequiredService(); if (env.IsDevelopment()) { // Seed the database in development mode var dbInitializer = scope.ServiceProvider.GetRequiredService(); dbInitializer.Seed().GetAwaiter().GetResult(); } } host.Run(); } public static IHostBuilder CreateHostBuilder(IConfigurationRoot config, string[] args) => Host.CreateDefaultBuilder(args) .ConfigureLogging(logging => { logging.ClearProviders(); // Log to console (stdout) - in production stdout will be written to /var/log/{{app_name}}.out.log logging.AddConsole(); logging.AddDebug(); }) .ConfigureWebHostDefaults(webBuilder => { webBuilder .UseUrls(config["serverBindingUrl"]) .UseStartup(); }); } } ================================================ FILE: api/Properties/launchSettings.json ================================================ { "iisSettings": { "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { "applicationUrl": "http://localhost:5000/", "sslPort": 0 } }, "profiles": { "IIS Express": { "commandName": "IISExpress", "launchBrowser": true, "launchUrl": "http://localhost:5000", "environmentVariables": { "NODE_PATH": "../node_modules/", "ASPNETCORE_ENVIRONMENT": "Development" } }, "api": { "commandName": "Project", "launchBrowser": true, "environmentVariables": { "NODE_PATH": "../node_modules/", "ASPNETCORE_ENVIRONMENT": "Development" }, "applicationUrl": "http://localhost:5000/" } } } ================================================ FILE: api/Services/EmailSender.cs ================================================ using System.Net; using System.Net.Mail; using System.Text; using System.Threading.Tasks; using Microsoft.Extensions.Options; namespace aspnetCoreReactTemplate.Services { public class EmailSender : IEmailSender { public EmailSender(IOptions optionsAccessor) { Options = optionsAccessor.Value; } public EmailSenderOptions Options { get; } public async Task SendEmailAsync(string toEmail, string subject, string htmlMessage, string textMessage = null) { MailMessage mailMessage = new MailMessage(); mailMessage.From = new MailAddress(this.Options.emailFromAddress, this.Options.emailFromName); mailMessage.To.Add(toEmail); mailMessage.Body = textMessage; mailMessage.BodyEncoding = Encoding.UTF8; mailMessage.Subject = subject; mailMessage.SubjectEncoding = Encoding.UTF8; if (!string.IsNullOrEmpty(htmlMessage)) { AlternateView htmlView = AlternateView.CreateAlternateViewFromString(htmlMessage); htmlView.ContentType = new System.Net.Mime.ContentType("text/html"); mailMessage.AlternateViews.Add(htmlView); } using (SmtpClient client = new SmtpClient(this.Options.host, this.Options.port)) { client.UseDefaultCredentials = false; client.Credentials = new NetworkCredential(this.Options.username, this.Options.password); client.EnableSsl = this.Options.enableSSL; await client.SendMailAsync(mailMessage); } } } } ================================================ FILE: api/Services/EmailSenderOptions.cs ================================================ using System; using System.Text.RegularExpressions; namespace aspnetCoreReactTemplate.Services { public class EmailSenderOptions { private string _smtpConfig { get; set; } public string smtpConfig { get { return this._smtpConfig; } set { this._smtpConfig = value; // smtpConfig is in username:password@localhost:1025 format; extract the part var smtpConfigPartsRegEx = new Regex(@"(.*)\:(.*)@(.+)\:(.+)"); var smtpConfigPartsMatch = smtpConfigPartsRegEx.Match(value); this.username = smtpConfigPartsMatch.Groups[1].Value; this.password = smtpConfigPartsMatch.Groups[2].Value; this.host = smtpConfigPartsMatch.Groups[3].Value; this.port = Convert.ToInt32(smtpConfigPartsMatch.Groups[4].Value); } } public string emailFromName { get; set; } public string emailFromAddress { get; set; } public bool enableSSL { get; set; } public string username { get; protected set; } public string password { get; protected set; } public string host { get; protected set; } public int port { get; protected set; } } } ================================================ FILE: api/Services/IEmailSender.cs ================================================ using System.Threading.Tasks; namespace aspnetCoreReactTemplate.Services { public interface IEmailSender { Task SendEmailAsync(string toEmail, string subject, string htmlMessage, string textMessage = null); } } ================================================ FILE: api/Services/JwtOptions.cs ================================================ using System; using System.Text.RegularExpressions; namespace aspnetCoreReactTemplate.Services { public class JwtOptions { public string key { get; set; } public string issuer { get; set; } } } ================================================ FILE: api/Startup.cs ================================================ using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.EntityFrameworkCore; using aspnetCoreReactTemplate.Models; using aspnetCoreReactTemplate.Services; using Microsoft.AspNetCore.HttpOverrides; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.IdentityModel.Tokens; using Microsoft.Extensions.Hosting; using System.Text; namespace aspnetCoreReactTemplate { public class Startup { public IHostEnvironment CurrentEnvironment { get; protected set; } public IConfiguration Configuration { get; } public Startup(IConfiguration configuration) { Configuration = configuration; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); services.AddEntityFrameworkNpgsql().AddDbContext(options => { options.UseNpgsql(Configuration.GetConnectionString("defaultConnection")); }); // Configure Entity Framework Initializer for seeding services.AddTransient(); services.AddDatabaseDeveloperPageExceptionFilter(); // Configure Entity Framework Identity for Auth services.AddIdentity() .AddEntityFrameworkStores() .AddDefaultTokenProviders(); services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(config => { config.RequireHttpsMetadata = false; config.SaveToken = true; config.TokenValidationParameters = new TokenValidationParameters() { ValidIssuer = Configuration["jwt:issuer"], ValidAudience = Configuration["jwt:issuer"], IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["jwt:key"])) }; }); services.AddTransient(); services.Configure(Configuration.GetSection("email")); services.Configure(Configuration.GetSection("jwt")); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostEnvironment env, ILoggerFactory loggerFactory) { // If not requesting /api*, rewrite to / so SPA app will be returned app.UseSpaFallback(new SpaFallbackOptions() { ApiPathPrefix = "/api", RewritePath = "/" }); app.UseDefaultFiles(); app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseForwardedHeaders(new ForwardedHeadersOptions { // Read and use headers coming from reverse proxy: X-Forwarded-For X-Forwarded-Proto // This is particularly important so that HttpContet.Request.Scheme will be correct behind a SSL terminating proxy ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto }); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); }); if (env.IsDevelopment()) { app.UseSpa(spa => { spa.UseProxyToSpaDevelopmentServer("http://localhost:8080/"); }); app.UseDeveloperExceptionPage(); app.UseMigrationsEndPoint(); } } } } ================================================ FILE: api/ViewModels/ConfirmEmail.cs ================================================ namespace aspnetCoreReactTemplate.ViewModels { public class ConfirmEmail { public string user_id { get; set; } public string token { get; set; } } } ================================================ FILE: api/ViewModels/NewUser.cs ================================================ using System.ComponentModel.DataAnnotations; namespace aspnetCoreReactTemplate.ViewModels { public class NewUser { [Required] [EmailAddress] public string username { get; set; } [Required] [MinLength(8)] public string password { get; set; } } } ================================================ FILE: api/api.csproj ================================================  net5.0 runtime; build; native; contentfiles; analyzers; buildtransitive all ================================================ FILE: api/appsettings.json ================================================ { "connectionStrings": { "defaultConnection": "Host=localhost;Port=5433;Username=postgres;Password=postgres;Database=dotnetcore" }, "frontEndUrl": "http://localhost:5000", "serverBindingUrl": "http://0.0.0.0:5000", "logging": { "includeScopes": false, "logLevel": { "default": "Debug", "system": "Information", "microsoft": "Information" } }, "webClientPath": "../client-react", "jwt": { "key" : "2af4ff57-4ca0-4b3a-804b-178ad27aaf88", "issuer": "aspnet-core-react-template" }, "email": { "smtpConfig": ":@localhost:1025", "enableSSL": false, "emailFromName": "aspnet-core-react-template", "emailFromAddress": "noreply@aspnet-core-react-template.com" } } ================================================ FILE: api/log/development-20170420.log ================================================ 2017-04-20T11:35:30.8306170-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:35:30.8800930-05:00 [INF] Executed DbCommand (14ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT EXISTS (SELECT 1 FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace WHERE c.relname='__EFMigrationsHistory'); (6438bdd5) 2017-04-20T11:35:30.8820010-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:35:30.8946950-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:35:30.8966570-05:00 [INF] Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT EXISTS (SELECT 1 FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace WHERE c.relname='__EFMigrationsHistory'); (6438bdd5) 2017-04-20T11:35:30.8967560-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:35:30.9031950-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:35:30.9049280-05:00 [INF] Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT "MigrationId", "ProductVersion" FROM "__EFMigrationsHistory" ORDER BY "MigrationId"; (6438bdd5) 2017-04-20T11:35:30.9054630-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:35:31.3218430-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:35:31.5298490-05:00 [INF] Executed DbCommand (77ms) [Parameters=[@__normalizedEmail_0='?'], CommandType='Text', CommandTimeout='30'] SELECT "u"."Id", "u"."AccessFailedCount", "u"."ConcurrencyStamp", "u"."Email", "u"."EmailConfirmed", "u"."GivenName", "u"."LockoutEnabled", "u"."LockoutEnd", "u"."NormalizedEmail", "u"."NormalizedUserName", "u"."PasswordHash", "u"."PhoneNumber", "u"."PhoneNumberConfirmed", "u"."SecurityStamp", "u"."TwoFactorEnabled", "u"."UserName" FROM "AspNetUsers" AS "u" WHERE "u"."NormalizedEmail" = @__normalizedEmail_0 LIMIT 1 (6438bdd5) 2017-04-20T11:35:31.5958230-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:35:31.6509440-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:35:31.6571590-05:00 [INF] Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT CASE WHEN EXISTS ( SELECT 1 FROM "Contacts" AS "c") THEN TRUE::bool ELSE FALSE::bool END (6438bdd5) 2017-04-20T11:35:31.6583500-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:35:31.6775930-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:35:31.6789170-05:00 [INF] Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT "c"."contactId", "c"."email", "c"."name", "c"."phone" FROM "Contacts" AS "c" (6438bdd5) 2017-04-20T11:35:31.7076610-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:35:31.7669820-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:35:31.7728150-05:00 [DBG] Beginning transaction with isolation level 'Unspecified'. (3b5ca34b) 2017-04-20T11:35:31.8349080-05:00 [INF] Executed DbCommand (4ms) [Parameters=[@p0='?', @p1='?', @p2='?', @p3='?', @p4='?', @p5='?', @p6='?', @p7='?'], CommandType='Text', CommandTimeout='30'] DELETE FROM "Contacts" WHERE "contactId" = @p0; DELETE FROM "Contacts" WHERE "contactId" = @p1; INSERT INTO "Contacts" ("email", "name", "phone") VALUES (@p2, @p3, @p4) RETURNING "contactId"; INSERT INTO "Contacts" ("email", "name", "phone") VALUES (@p5, @p6, @p7) RETURNING "contactId"; (6438bdd5) 2017-04-20T11:35:31.8603320-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:35:33.0652850-05:00 [INF] ts-loader: Using typescript@2.2.2 and /Users/bholt/dev/aspnet-core-react-template/client-react/tsconfig.json (114b565e) 2017-04-20T11:35:33.0802850-05:00 [DBG] Hosting starting (32b26330) 2017-04-20T11:35:33.1537040-05:00 [DBG] Hosting started (e6def423) 2017-04-20T11:35:37.9044370-05:00 [INF] webpack built d5ef16186ce4d979a8ac in 5087ms (83001040) 2017-04-20T11:35:43.1417480-05:00 [DBG] Connection id ""0HL481D4TQDAN"" started. (1426b994) 2017-04-20T11:35:43.2379250-05:00 0HL481D4URNUT [INF] Request starting HTTP/1.1 GET http://localhost:5000/__webpack_hmr (e5be5b71) 2017-04-20T11:36:11.8277120-05:00 [DBG] Connection id ""0HL481D4TQDAQ"" started. (1426b994) 2017-04-20T11:36:11.8277120-05:00 [DBG] Connection id ""0HL481D4TQDAP"" started. (1426b994) 2017-04-20T11:36:11.8277120-05:00 [DBG] Connection id ""0HL481D4TQDAO"" started. (1426b994) 2017-04-20T11:36:11.8279810-05:00 [DBG] Connection id ""0HL481D4TQDAR"" started. (1426b994) 2017-04-20T11:36:11.8280120-05:00 [DBG] Connection id ""0HL481D4TQDAS"" started. (1426b994) 2017-04-20T11:36:11.9435780-05:00 0HL481D4URNUU [INF] Request starting HTTP/1.1 GET http://localhost:5000/sign-in/?expired=1 (e5be5b71) 2017-04-20T11:36:11.9719460-05:00 0HL481D4URNUU [INF] Handling request: /sign-in/ (6455a65b) 2017-04-20T11:36:11.9724410-05:00 0HL481D4URNUU [INF] Rewriting path: /sign-in/ > / (170f1f87) 2017-04-20T11:36:12.0015370-05:00 0HL481D4URNUU [INF] Sending file. Request path: '"/index.html"'. Physical path: '"/Users/bholt/dev/aspnet-core-react-template/api/wwwroot/index.html"' (27b0a520) 2017-04-20T11:36:12.0271890-05:00 0HL481D4URNUU [INF] Finished handling request. (d2c25297) 2017-04-20T11:36:12.0277690-05:00 [DBG] Connection id ""0HL481D4TQDAN"" received FIN. (acf58720) 2017-04-20T11:36:12.0336340-05:00 0HL481D4URNUU [DBG] Connection id ""0HL481D4TQDAP"" completed keep alive response. (9784cde9) 2017-04-20T11:36:12.0426020-05:00 0HL481D4URNUU [INF] Request finished in 91.3023ms 200 text/html (15c52c40) 2017-04-20T11:36:12.0500360-05:00 0HL481D4URNUV [INF] Request starting HTTP/1.1 GET http://localhost:5000/main.js (e5be5b71) 2017-04-20T11:36:12.1321120-05:00 0HL481D4URNUV [DBG] Connection id ""0HL481D4TQDAP"" completed keep alive response. (9784cde9) 2017-04-20T11:36:12.1322260-05:00 0HL481D4URNUV [INF] Request finished in 82.2472ms 200 application/javascript; charset=UTF-8 (15c52c40) 2017-04-20T11:36:12.2905320-05:00 0HL481D4URNV0 [INF] Request starting HTTP/1.1 GET http://localhost:5000/__webpack_hmr (e5be5b71) 2017-04-20T11:36:12.3184020-05:00 [INF] Connection id ""0HL481D4TQDAN"" communication error. (7fa6c29c) Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvException: Error -32 EPIPE broken pipe 2017-04-20T11:36:12.3195980-05:00 [DBG] Connection id ""0HL481D4TQDAN"" disconnecting. (b29b9868) 2017-04-20T11:36:12.3227210-05:00 [DBG] Connection id ""0HL481D4TQDAN"" stopped. (056149f8) 2017-04-20T11:36:14.4920170-05:00 [DBG] Connection id ""0HL481D4TQDAT"" started. (1426b994) 2017-04-20T11:36:14.5987070-05:00 0HL481D4URNV1 [INF] Request starting HTTP/1.1 GET http://localhost:5000/sign-in/?expired=1 (e5be5b71) 2017-04-20T11:36:14.6008020-05:00 0HL481D4URNV1 [INF] Handling request: /sign-in/ (6455a65b) 2017-04-20T11:36:14.6009470-05:00 0HL481D4URNV1 [INF] Rewriting path: /sign-in/ > / (170f1f87) 2017-04-20T11:36:14.6015570-05:00 0HL481D4URNV1 [INF] The file "/index.html" was not modified (f1f8d725) 2017-04-20T11:36:14.6052500-05:00 0HL481D4URNV1 [DBG] Handled. Status code: 304 File: "/index.html" (58f8d392) 2017-04-20T11:36:14.6059120-05:00 0HL481D4URNV1 [INF] Finished handling request. (d2c25297) 2017-04-20T11:36:14.6082100-05:00 0HL481D4URNV1 [DBG] Connection id ""0HL481D4TQDAQ"" completed keep alive response. (9784cde9) 2017-04-20T11:36:14.6083090-05:00 0HL481D4URNV1 [INF] Request finished in 9.6036ms 304 text/html (15c52c40) 2017-04-20T11:36:14.6105660-05:00 [DBG] Connection id ""0HL481D4TQDAP"" received FIN. (acf58720) 2017-04-20T11:36:14.6150570-05:00 0HL481D4URNV2 [INF] Request starting HTTP/1.1 GET http://localhost:5000/main.js (e5be5b71) 2017-04-20T11:36:14.6490190-05:00 0HL481D4URNV2 [DBG] Connection id ""0HL481D4TQDAQ"" completed keep alive response. (9784cde9) 2017-04-20T11:36:14.6491170-05:00 0HL481D4URNV2 [INF] Request finished in 34.0525ms 200 application/javascript; charset=UTF-8 (15c52c40) 2017-04-20T11:36:14.7931650-05:00 0HL481D4URNV3 [INF] Request starting HTTP/1.1 GET http://localhost:5000/__webpack_hmr (e5be5b71) 2017-04-20T11:36:14.8183730-05:00 [INF] Connection id ""0HL481D4TQDAP"" communication error. (7fa6c29c) Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvException: Error -32 EPIPE broken pipe 2017-04-20T11:36:14.8184200-05:00 [DBG] Connection id ""0HL481D4TQDAP"" disconnecting. (b29b9868) 2017-04-20T11:36:14.8185990-05:00 [DBG] Connection id ""0HL481D4TQDAP"" stopped. (056149f8) 2017-04-20T11:36:31.0322080-05:00 [INF] Received SIGINT. Waiting for .NET process to exit... (39e2bf0e) 2017-04-20T11:36:31.0363300-05:00 [DBG] Hosting shutdown (49005419) 2017-04-20T11:36:42.5679710-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:36:42.6172200-05:00 [INF] Executed DbCommand (13ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT EXISTS (SELECT 1 FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace WHERE c.relname='__EFMigrationsHistory'); (6438bdd5) 2017-04-20T11:36:42.6190720-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:36:42.6324510-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:36:42.6352190-05:00 [INF] Executed DbCommand (2ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT EXISTS (SELECT 1 FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace WHERE c.relname='__EFMigrationsHistory'); (6438bdd5) 2017-04-20T11:36:42.6353160-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:36:42.6419620-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:36:42.6434930-05:00 [INF] Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT "MigrationId", "ProductVersion" FROM "__EFMigrationsHistory" ORDER BY "MigrationId"; (6438bdd5) 2017-04-20T11:36:42.6440570-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:36:43.0661490-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:36:43.2727970-05:00 [INF] Executed DbCommand (72ms) [Parameters=[@__normalizedEmail_0='?'], CommandType='Text', CommandTimeout='30'] SELECT "u"."Id", "u"."AccessFailedCount", "u"."ConcurrencyStamp", "u"."Email", "u"."EmailConfirmed", "u"."GivenName", "u"."LockoutEnabled", "u"."LockoutEnd", "u"."NormalizedEmail", "u"."NormalizedUserName", "u"."PasswordHash", "u"."PhoneNumber", "u"."PhoneNumberConfirmed", "u"."SecurityStamp", "u"."TwoFactorEnabled", "u"."UserName" FROM "AspNetUsers" AS "u" WHERE "u"."NormalizedEmail" = @__normalizedEmail_0 LIMIT 1 (6438bdd5) 2017-04-20T11:36:43.3405580-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:36:43.3952030-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:36:43.4003370-05:00 [INF] Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT CASE WHEN EXISTS ( SELECT 1 FROM "Contacts" AS "c") THEN TRUE::bool ELSE FALSE::bool END (6438bdd5) 2017-04-20T11:36:43.4014950-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:36:43.4214390-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:36:43.4230960-05:00 [INF] Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT "c"."contactId", "c"."email", "c"."name", "c"."phone" FROM "Contacts" AS "c" (6438bdd5) 2017-04-20T11:36:43.4509720-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:36:43.5138800-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:36:43.5196070-05:00 [DBG] Beginning transaction with isolation level 'Unspecified'. (3b5ca34b) 2017-04-20T11:36:43.5970100-05:00 [INF] Executed DbCommand (6ms) [Parameters=[@p0='?', @p1='?', @p2='?', @p3='?', @p4='?', @p5='?', @p6='?', @p7='?'], CommandType='Text', CommandTimeout='30'] DELETE FROM "Contacts" WHERE "contactId" = @p0; DELETE FROM "Contacts" WHERE "contactId" = @p1; INSERT INTO "Contacts" ("email", "name", "phone") VALUES (@p2, @p3, @p4) RETURNING "contactId"; INSERT INTO "Contacts" ("email", "name", "phone") VALUES (@p5, @p6, @p7) RETURNING "contactId"; (6438bdd5) 2017-04-20T11:36:43.6252790-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:36:44.8000390-05:00 [INF] ts-loader: Using typescript@2.2.2 and /Users/bholt/dev/aspnet-core-react-template/client-react/tsconfig.json (114b565e) 2017-04-20T11:36:44.8266520-05:00 [DBG] Hosting starting (32b26330) 2017-04-20T11:36:44.9005150-05:00 [DBG] Hosting started (e6def423) 2017-04-20T11:36:46.9926100-05:00 [DBG] Connection id ""0HL481DNUOBGO"" started. (1426b994) 2017-04-20T11:36:46.9926270-05:00 [DBG] Connection id ""0HL481DNUOBGL"" started. (1426b994) 2017-04-20T11:36:46.9926370-05:00 [DBG] Connection id ""0HL481DNUOBGN"" started. (1426b994) 2017-04-20T11:36:46.9926430-05:00 [DBG] Connection id ""0HL481DNUOBGM"" started. (1426b994) 2017-04-20T11:36:46.9982000-05:00 [DBG] Connection id ""0HL481DNUOBGQ"" started. (1426b994) 2017-04-20T11:36:46.9982010-05:00 [DBG] Connection id ""0HL481DNUOBGP"" started. (1426b994) 2017-04-20T11:36:47.1680840-05:00 0HL481DO0HIUT [INF] Request starting HTTP/1.1 GET http://localhost:5000/sign-in/?expired=1 (e5be5b71) 2017-04-20T11:36:49.6840130-05:00 [INF] webpack built d5ef16186ce4d979a8ac in 5127ms (d4c9e226) 2017-04-20T11:36:49.8292910-05:00 0HL481DO0HIUT [INF] Handling request: /sign-in/ (6455a65b) 2017-04-20T11:36:49.8316730-05:00 0HL481DO0HIUT [INF] Rewriting path: /sign-in/ > / (170f1f87) 2017-04-20T11:36:49.8673890-05:00 0HL481DO0HIUT [INF] Sending file. Request path: '"/index.html"'. Physical path: '"/Users/bholt/dev/aspnet-core-react-template/api/wwwroot/index.html"' (27b0a520) 2017-04-20T11:36:49.9422540-05:00 0HL481DO0HIUT [INF] Finished handling request. (d2c25297) 2017-04-20T11:36:49.9487830-05:00 0HL481DO0HIUT [DBG] Connection id ""0HL481DNUOBGO"" completed keep alive response. (9784cde9) 2017-04-20T11:36:49.9574050-05:00 0HL481DO0HIUT [INF] Request finished in 2803.0445ms 200 text/html (15c52c40) 2017-04-20T11:36:49.9652020-05:00 0HL481DO0HIUU [INF] Request starting HTTP/1.1 GET http://localhost:5000/main.js (e5be5b71) 2017-04-20T11:36:50.0631710-05:00 0HL481DO0HIUU [DBG] Connection id ""0HL481DNUOBGO"" completed keep alive response. (9784cde9) 2017-04-20T11:36:50.0633730-05:00 0HL481DO0HIUU [INF] Request finished in 98.145ms 200 application/javascript; charset=UTF-8 (15c52c40) 2017-04-20T11:36:50.2230400-05:00 0HL481DO0HIUV [INF] Request starting HTTP/1.1 GET http://localhost:5000/__webpack_hmr (e5be5b71) 2017-04-20T11:37:43.9188350-05:00 [DBG] Connection id ""0HL481DNUOBGL"" received FIN. (acf58720) 2017-04-20T11:37:43.9188350-05:00 [DBG] Connection id ""0HL481DNUOBGP"" received FIN. (acf58720) 2017-04-20T11:37:43.9188350-05:00 [DBG] Connection id ""0HL481DNUOBGM"" received FIN. (acf58720) 2017-04-20T11:37:43.9189140-05:00 [DBG] Connection id ""0HL481DNUOBGN"" received FIN. (acf58720) 2017-04-20T11:37:43.9190380-05:00 [DBG] Connection id ""0HL481DNUOBGQ"" received FIN. (acf58720) 2017-04-20T11:37:43.9191040-05:00 [DBG] Connection id ""0HL481DNUOBGR"" started. (1426b994) 2017-04-20T11:37:43.9193680-05:00 [DBG] Connection id ""0HL481DNUOBGS"" started. (1426b994) 2017-04-20T11:37:43.9195950-05:00 [DBG] Connection id ""0HL481DNUOBGP"" disconnecting. (b29b9868) 2017-04-20T11:37:43.9196100-05:00 [DBG] Connection id ""0HL481DNUOBGL"" disconnecting. (b29b9868) 2017-04-20T11:37:43.9196140-05:00 [DBG] Connection id ""0HL481DNUOBGT"" started. (1426b994) 2017-04-20T11:37:43.9196310-05:00 [DBG] Connection id ""0HL481DNUOBGQ"" disconnecting. (b29b9868) 2017-04-20T11:37:43.9196490-05:00 [DBG] Connection id ""0HL481DNUOBGU"" started. (1426b994) 2017-04-20T11:37:43.9196590-05:00 [DBG] Connection id ""0HL481DNUOBGM"" disconnecting. (b29b9868) 2017-04-20T11:37:43.9196950-05:00 [DBG] Connection id ""0HL481DNUOBGN"" disconnecting. (b29b9868) 2017-04-20T11:37:43.9231050-05:00 [DBG] Connection id ""0HL481DNUOBGQ"" sending FIN. (ffb251f5) 2017-04-20T11:37:43.9230940-05:00 [DBG] Connection id ""0HL481DNUOBGN"" sending FIN. (ffb251f5) 2017-04-20T11:37:43.9230990-05:00 [DBG] Connection id ""0HL481DNUOBGP"" sending FIN. (ffb251f5) 2017-04-20T11:37:43.9231120-05:00 [DBG] Connection id ""0HL481DNUOBGL"" sending FIN. (ffb251f5) 2017-04-20T11:37:43.9246720-05:00 [DBG] Connection id ""0HL481DNUOBGM"" sending FIN. (ffb251f5) 2017-04-20T11:37:43.9286220-05:00 [DBG] Connection id ""0HL481DNUOBGP"" sent FIN with status "0". (69d90ca7) 2017-04-20T11:37:43.9286400-05:00 [DBG] Connection id ""0HL481DNUOBGN"" sent FIN with status "0". (69d90ca7) 2017-04-20T11:37:43.9286180-05:00 [DBG] Connection id ""0HL481DNUOBGL"" sent FIN with status "0". (69d90ca7) 2017-04-20T11:37:43.9286460-05:00 [DBG] Connection id ""0HL481DNUOBGQ"" sent FIN with status "0". (69d90ca7) 2017-04-20T11:37:43.9320710-05:00 [DBG] Connection id ""0HL481DNUOBGN"" stopped. (056149f8) 2017-04-20T11:37:43.9320770-05:00 [DBG] Connection id ""0HL481DNUOBGL"" stopped. (056149f8) 2017-04-20T11:37:43.9320710-05:00 [DBG] Connection id ""0HL481DNUOBGQ"" stopped. (056149f8) 2017-04-20T11:37:43.9320710-05:00 [DBG] Connection id ""0HL481DNUOBGP"" stopped. (056149f8) 2017-04-20T11:37:43.9322520-05:00 [DBG] Connection id ""0HL481DNUOBGM"" sent FIN with status "0". (69d90ca7) 2017-04-20T11:37:43.9324070-05:00 [DBG] Connection id ""0HL481DNUOBGM"" stopped. (056149f8) 2017-04-20T11:37:44.0243850-05:00 0HL481DO0HIV0 [INF] Request starting HTTP/1.1 GET http://localhost:5000/sign-in/?expired=1 (e5be5b71) 2017-04-20T11:37:44.0274720-05:00 0HL481DO0HIV0 [INF] Handling request: /sign-in/ (6455a65b) 2017-04-20T11:37:44.0276610-05:00 0HL481DO0HIV0 [INF] Rewriting path: /sign-in/ > / (170f1f87) 2017-04-20T11:37:44.0291950-05:00 0HL481DO0HIV0 [INF] The file "/index.html" was not modified (f1f8d725) 2017-04-20T11:37:44.0335380-05:00 0HL481DO0HIV0 [DBG] Handled. Status code: 304 File: "/index.html" (58f8d392) 2017-04-20T11:37:44.0340220-05:00 0HL481DO0HIV0 [INF] Finished handling request. (d2c25297) 2017-04-20T11:37:44.0364350-05:00 0HL481DO0HIV0 [DBG] Connection id ""0HL481DNUOBGR"" completed keep alive response. (9784cde9) 2017-04-20T11:37:44.0365290-05:00 0HL481DO0HIV0 [INF] Request finished in 12.181ms 304 text/html (15c52c40) 2017-04-20T11:37:44.0387160-05:00 [DBG] Connection id ""0HL481DNUOBGO"" received FIN. (acf58720) 2017-04-20T11:37:44.0447030-05:00 0HL481DO0HIV1 [INF] Request starting HTTP/1.1 GET http://localhost:5000/main.js (e5be5b71) 2017-04-20T11:37:44.1497720-05:00 0HL481DO0HIV1 [DBG] Connection id ""0HL481DNUOBGR"" completed keep alive response. (9784cde9) 2017-04-20T11:37:44.1499180-05:00 0HL481DO0HIV1 [INF] Request finished in 105.2445ms 200 application/javascript; charset=UTF-8 (15c52c40) 2017-04-20T11:37:44.3064100-05:00 0HL481DO0HIV2 [INF] Request starting HTTP/1.1 GET http://localhost:5000/__webpack_hmr (e5be5b71) 2017-04-20T11:37:44.3697020-05:00 [INF] Connection id ""0HL481DNUOBGO"" communication error. (7fa6c29c) Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvException: Error -32 EPIPE broken pipe 2017-04-20T11:37:44.3706480-05:00 [DBG] Connection id ""0HL481DNUOBGO"" disconnecting. (b29b9868) 2017-04-20T11:37:44.3707470-05:00 [DBG] Connection id ""0HL481DNUOBGO"" stopped. (056149f8) 2017-04-20T11:37:44.7403160-05:00 0HL481DO0HIV3 [INF] Request starting HTTP/1.1 GET http://localhost:5000/sign-in/?expired=1 (e5be5b71) 2017-04-20T11:37:44.7441180-05:00 0HL481DO0HIV3 [INF] Handling request: /sign-in/ (6455a65b) 2017-04-20T11:37:44.7443270-05:00 0HL481DO0HIV3 [INF] Rewriting path: /sign-in/ > / (170f1f87) 2017-04-20T11:37:44.7445570-05:00 0HL481DO0HIV3 [INF] The file "/index.html" was not modified (f1f8d725) 2017-04-20T11:37:44.7447200-05:00 0HL481DO0HIV3 [DBG] Handled. Status code: 304 File: "/index.html" (58f8d392) 2017-04-20T11:37:44.7447680-05:00 0HL481DO0HIV3 [INF] Finished handling request. (d2c25297) 2017-04-20T11:37:44.7449150-05:00 0HL481DO0HIV3 [DBG] Connection id ""0HL481DNUOBGS"" completed keep alive response. (9784cde9) 2017-04-20T11:37:44.7449890-05:00 0HL481DO0HIV3 [INF] Request finished in 4.8109ms 304 text/html (15c52c40) 2017-04-20T11:37:44.7472770-05:00 [DBG] Connection id ""0HL481DNUOBGR"" received FIN. (acf58720) 2017-04-20T11:37:44.7519900-05:00 0HL481DO0HIV4 [INF] Request starting HTTP/1.1 GET http://localhost:5000/main.js (e5be5b71) 2017-04-20T11:37:44.7881250-05:00 0HL481DO0HIV4 [DBG] Connection id ""0HL481DNUOBGS"" completed keep alive response. (9784cde9) 2017-04-20T11:37:44.7882510-05:00 0HL481DO0HIV4 [INF] Request finished in 36.2429ms 200 application/javascript; charset=UTF-8 (15c52c40) 2017-04-20T11:37:44.9357150-05:00 0HL481DO0HIV5 [INF] Request starting HTTP/1.1 GET http://localhost:5000/__webpack_hmr (e5be5b71) 2017-04-20T11:37:45.0186840-05:00 [INF] Connection id ""0HL481DNUOBGR"" communication error. (7fa6c29c) Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvException: Error -32 EPIPE broken pipe 2017-04-20T11:37:45.0187000-05:00 [DBG] Connection id ""0HL481DNUOBGR"" disconnecting. (b29b9868) 2017-04-20T11:37:45.0188670-05:00 [DBG] Connection id ""0HL481DNUOBGR"" stopped. (056149f8) 2017-04-20T11:37:47.8385420-05:00 [DBG] Connection id ""0HL481DNUOBGV"" started. (1426b994) 2017-04-20T11:37:47.8391390-05:00 0HL481DO0HIV6 [INF] Request starting HTTP/1.1 POST http://localhost:5000/api/auth/register application/x-www-form-urlencoded 41 (e5be5b71) 2017-04-20T11:37:47.8441730-05:00 0HL481DO0HIV6 [INF] Handling request: /api/auth/register (2c1017b8) 2017-04-20T11:37:47.8450270-05:00 0HL481DO0HIV6 [DBG] "POST" requests are not supported (1c759b4c) 2017-04-20T11:37:47.8782690-05:00 0HL481DO0HIV6 [INF] "Bearer" was not authenticated. Failure message: "Authentication failed because the access token was invalid." (48071232) 2017-04-20T11:37:47.9079750-05:00 [DBG] Connection id ""0HL481DNUOBH0"" started. (1426b994) 2017-04-20T11:37:47.9081840-05:00 0HL481DO0HIV7 [INF] Request starting HTTP/1.1 GET http://localhost:5000/.well-known/openid-configuration (e5be5b71) 2017-04-20T11:37:47.9112280-05:00 0HL481DO0HIV7 [INF] Handling request: /.well-known/openid-configuration (28f0d040) 2017-04-20T11:37:47.9124590-05:00 0HL481DO0HIV7 [DBG] The request path "/.well-known/openid-configuration" does not match a supported file type (4910e68e) 2017-04-20T11:37:47.9129630-05:00 0HL481DO0HIV7 [DBG] Authentication was skipped because no bearer token was received. (9de85986) 2017-04-20T11:37:47.9604730-05:00 0HL481DO0HIV7 [INF] The discovery request was successfully extracted from the HTTP request: "{}" (8eb39e75) 2017-04-20T11:37:47.9609200-05:00 0HL481DO0HIV7 [INF] The discovery request was successfully validated. (5773bc23) 2017-04-20T11:37:47.9968510-05:00 0HL481DO0HIV7 [INF] The discovery response was successfully returned: "{ \"issuer\": \"http://localhost:5000/\", \"token_endpoint\": \"http://localhost:5000/api/auth/login\", \"jwks_uri\": \"http://localhost:5000/.well-known/jwks\", \"grant_types_supported\": [ \"refresh_token\", \"password\" ], \"scopes_supported\": [ \"openid\", \"profile\", \"email\", \"phone\", \"roles\", \"offline_access\" ], \"id_token_signing_alg_values_supported\": [ \"RS256\" ], \"subject_types_supported\": [ \"public\" ], \"token_endpoint_auth_methods_supported\": [ \"client_secret_basic\", \"client_secret_post\" ] }" (ee57d974) 2017-04-20T11:37:48.0282260-05:00 0HL481DO0HIV7 [INF] Finished handling request. (d2c25297) 2017-04-20T11:37:48.0298620-05:00 0HL481DO0HIV7 [DBG] Connection id ""0HL481DNUOBH0"" completed keep alive response. (9784cde9) 2017-04-20T11:37:48.0299690-05:00 0HL481DO0HIV7 [INF] Request finished in 121.8068ms 200 application/json;charset=UTF-8 (15c52c40) 2017-04-20T11:37:48.0480060-05:00 0HL481DO0HIV8 [INF] Request starting HTTP/1.1 GET http://localhost:5000/.well-known/jwks (e5be5b71) 2017-04-20T11:37:48.0506240-05:00 0HL481DO0HIV8 [INF] Handling request: /.well-known/jwks (3092411e) 2017-04-20T11:37:48.0509020-05:00 0HL481DO0HIV8 [DBG] The request path "/.well-known/jwks" does not match a supported file type (4910e68e) 2017-04-20T11:37:48.0509530-05:00 0HL481DO0HIV8 [DBG] Authentication was skipped because no bearer token was received. (9de85986) 2017-04-20T11:37:48.0668590-05:00 0HL481DO0HIV8 [INF] The discovery request was successfully extracted from the HTTP request: "{}" (8eb39e75) 2017-04-20T11:37:48.0733790-05:00 0HL481DO0HIV8 [INF] The discovery response was successfully returned: "{ \"keys\": [ { \"kid\": \"ZINIJNEZDR5SICRGXFCAQ2N2M0GJHODRC_YSGCBP\", \"use\": \"sig\", \"kty\": \"RSA\", \"alg\": \"RS256\", \"e\": \"AQAB\", \"n\": \"ziNiJnezDr5SIcRGXFcaQ2n2M0gjhODRc_YSgcbPrt1X3JZ7VSIo1RvPH1P1v37GV5nvF-B4QTTV2I8ZOyPa8OIY9j0qPl5DMEDO8iavf2pMdBjxA5JI_fO1EO-eZRojPtHFrE-dbnt8AOWNgqx3okN5Js-odWL3pg3TybsENv_lxFk3K4v7zlF7-J7gdlqDKTjgoRfU2OzxgOvEAIGQ66hy8alXn8IjJJ1sPBsw77r6ij7jOs1TB6YjE1ZMzRs-jUm4cR8Q2q7vzPHEgelM61sjW9Gac0NTLgS6UNCnNTBYebum1Q-HVhdCJCZ8VDq6R7iWlm-8NeoGT78EC4pLbQ\" } ] }" (ee57d974) 2017-04-20T11:37:48.0735570-05:00 0HL481DO0HIV8 [INF] Finished handling request. (d2c25297) 2017-04-20T11:37:48.0736820-05:00 0HL481DO0HIV8 [DBG] Connection id ""0HL481DNUOBH0"" completed keep alive response. (9784cde9) 2017-04-20T11:37:48.0737980-05:00 0HL481DO0HIV8 [INF] Request finished in 25.7882ms 200 application/json;charset=UTF-8 (15c52c40) 2017-04-20T11:37:48.0922480-05:00 0HL481DO0HIV6 [INF] "Bearer" was not authenticated. Failure message: "No SecurityTokenValidator available for token: null" (48071232) 2017-04-20T11:37:48.3252880-05:00 0HL481DO0HIV6 [DBG] Request successfully matched the route with name 'null' and template '"api/auth/register"'. (555ac2ba) 2017-04-20T11:37:48.3736270-05:00 0HL481DO0HIV6 [DBG] Executing action "aspnetCoreReactTemplate.aspnetCoreReactTemplate.Controllers.AuthController.Register (api)" (3f3ef15a) 2017-04-20T11:37:48.6162920-05:00 0HL481DO0HIV6 [INF] Executing action method "aspnetCoreReactTemplate.aspnetCoreReactTemplate.Controllers.AuthController.Register (api)" with arguments (["aspnetCoreReactTemplate.ViewModels.NewUser"]) - ModelState is Valid (ba7f4ac2) 2017-04-20T11:37:48.7035500-05:00 0HL481DO0HIV6 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:37:48.7151230-05:00 0HL481DO0HIV6 [INF] Executed DbCommand (10ms) [Parameters=[@__normalizedUserName_0='?'], CommandType='Text', CommandTimeout='30'] SELECT "u"."Id", "u"."AccessFailedCount", "u"."ConcurrencyStamp", "u"."Email", "u"."EmailConfirmed", "u"."GivenName", "u"."LockoutEnabled", "u"."LockoutEnd", "u"."NormalizedEmail", "u"."NormalizedUserName", "u"."PasswordHash", "u"."PhoneNumber", "u"."PhoneNumberConfirmed", "u"."SecurityStamp", "u"."TwoFactorEnabled", "u"."UserName" FROM "AspNetUsers" AS "u" WHERE "u"."NormalizedUserName" = @__normalizedUserName_0 LIMIT 1 (6438bdd5) 2017-04-20T11:37:48.7158920-05:00 0HL481DO0HIV6 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:37:48.7245730-05:00 0HL481DO0HIV6 [WRN] User "9bf02c6f-6f89-4282-8ac3-4489462861ad" validation failed: "DuplicateUserName". (5dc28e15) 2017-04-20T11:37:48.7274430-05:00 0HL481DO0HIV6 [DBG] Executed action method "aspnetCoreReactTemplate.aspnetCoreReactTemplate.Controllers.AuthController.Register (api)", returned result "Microsoft.AspNetCore.Mvc.BadRequestObjectResult". (f72615e0) 2017-04-20T11:37:48.7497940-05:00 0HL481DO0HIV6 [DBG] No information found on request to perform content negotiation. (6aec0ec5) 2017-04-20T11:37:48.7547650-05:00 0HL481DO0HIV6 [DBG] Selected output formatter '"Microsoft.AspNetCore.Mvc.Formatters.JsonOutputFormatter"' and content type '"application/json"' to write the response. (fcc32779) 2017-04-20T11:37:48.7550900-05:00 0HL481DO0HIV6 [INF] Executing ObjectResult, writing value "Microsoft.AspNetCore.Mvc.ControllerContext". (4e968210) 2017-04-20T11:37:48.7902840-05:00 0HL481DO0HIV6 [INF] Executed action "aspnetCoreReactTemplate.aspnetCoreReactTemplate.Controllers.AuthController.Register (api)" in 412.9491ms (afa2e885) 2017-04-20T11:37:48.7915380-05:00 0HL481DO0HIV6 [INF] Finished handling request. (d2c25297) 2017-04-20T11:37:48.7952490-05:00 0HL481DO0HIV6 [DBG] Connection id ""0HL481DNUOBGV"" completed keep alive response. (9784cde9) 2017-04-20T11:37:48.7953670-05:00 0HL481DO0HIV6 [INF] Request finished in 956.6813ms 400 application/json; charset=utf-8 (15c52c40) 2017-04-20T11:37:58.3918390-05:00 [DBG] Connection id ""0HL481DNUOBGU"" received FIN. (acf58720) 2017-04-20T11:37:58.3918390-05:00 [DBG] Connection id ""0HL481DNUOBGT"" received FIN. (acf58720) 2017-04-20T11:37:58.3919610-05:00 [DBG] Connection id ""0HL481DNUOBGT"" disconnecting. (b29b9868) 2017-04-20T11:37:58.3919600-05:00 [DBG] Connection id ""0HL481DNUOBGU"" disconnecting. (b29b9868) 2017-04-20T11:37:58.3920110-05:00 [DBG] Connection id ""0HL481DNUOBGT"" sending FIN. (ffb251f5) 2017-04-20T11:37:58.3920570-05:00 [DBG] Connection id ""0HL481DNUOBGU"" sending FIN. (ffb251f5) 2017-04-20T11:37:58.3921150-05:00 [DBG] Connection id ""0HL481DNUOBGU"" sent FIN with status "0". (69d90ca7) 2017-04-20T11:37:58.3921360-05:00 [DBG] Connection id ""0HL481DNUOBGT"" sent FIN with status "0". (69d90ca7) 2017-04-20T11:37:58.3921880-05:00 [DBG] Connection id ""0HL481DNUOBGU"" stopped. (056149f8) 2017-04-20T11:37:58.3921880-05:00 [DBG] Connection id ""0HL481DNUOBGT"" stopped. (056149f8) 2017-04-20T11:39:08.8648310-05:00 [DBG] Connection id ""0HL481DNUOBH2"" started. (1426b994) 2017-04-20T11:39:08.8648300-05:00 [DBG] Connection id ""0HL481DNUOBH1"" started. (1426b994) 2017-04-20T11:39:08.9771260-05:00 0HL481DO0HIV9 [INF] Request starting HTTP/1.1 GET http://localhost:5000/register (e5be5b71) 2017-04-20T11:39:08.9797620-05:00 0HL481DO0HIV9 [INF] Handling request: /register (d15267fc) 2017-04-20T11:39:08.9798190-05:00 0HL481DO0HIV9 [INF] Rewriting path: /register > / (b5db4a63) 2017-04-20T11:39:08.9799910-05:00 0HL481DO0HIV9 [INF] Sending file. Request path: '"/index.html"'. Physical path: '"/Users/bholt/dev/aspnet-core-react-template/api/wwwroot/index.html"' (27b0a520) 2017-04-20T11:39:08.9802130-05:00 0HL481DO0HIV9 [INF] Finished handling request. (d2c25297) 2017-04-20T11:39:08.9802920-05:00 0HL481DO0HIV9 [DBG] Connection id ""0HL481DNUOBH1"" completed keep alive response. (9784cde9) 2017-04-20T11:39:08.9803620-05:00 0HL481DO0HIV9 [INF] Request finished in 3.2755ms 200 text/html (15c52c40) 2017-04-20T11:39:08.9822110-05:00 [DBG] Connection id ""0HL481DNUOBGS"" received FIN. (acf58720) 2017-04-20T11:39:08.9871980-05:00 0HL481DO0HIVA [INF] Request starting HTTP/1.1 GET http://localhost:5000/main.js (e5be5b71) 2017-04-20T11:39:09.0885690-05:00 0HL481DO0HIVA [DBG] Connection id ""0HL481DNUOBH1"" completed keep alive response. (9784cde9) 2017-04-20T11:39:09.0887120-05:00 0HL481DO0HIVA [INF] Request finished in 101.5631ms 200 application/javascript; charset=UTF-8 (15c52c40) 2017-04-20T11:39:09.2537060-05:00 0HL481DO0HIVB [INF] Request starting HTTP/1.1 GET http://localhost:5000/__webpack_hmr (e5be5b71) 2017-04-20T11:39:09.8290340-05:00 0HL481DO0HIVC [INF] Request starting HTTP/1.1 GET http://localhost:5000/register (e5be5b71) 2017-04-20T11:39:09.8308800-05:00 0HL481DO0HIVC [INF] Handling request: /register (d15267fc) 2017-04-20T11:39:09.8309960-05:00 0HL481DO0HIVC [INF] Rewriting path: /register > / (b5db4a63) 2017-04-20T11:39:09.8311750-05:00 0HL481DO0HIVC [INF] The file "/index.html" was not modified (f1f8d725) 2017-04-20T11:39:09.8312350-05:00 0HL481DO0HIVC [DBG] Handled. Status code: 304 File: "/index.html" (58f8d392) 2017-04-20T11:39:09.8312670-05:00 0HL481DO0HIVC [INF] Finished handling request. (d2c25297) 2017-04-20T11:39:09.8313890-05:00 0HL481DO0HIVC [DBG] Connection id ""0HL481DNUOBH2"" completed keep alive response. (9784cde9) 2017-04-20T11:39:09.8314930-05:00 0HL481DO0HIVC [INF] Request finished in 2.4718ms 304 text/html (15c52c40) 2017-04-20T11:39:09.8334490-05:00 [DBG] Connection id ""0HL481DNUOBH1"" received FIN. (acf58720) 2017-04-20T11:39:09.8381890-05:00 0HL481DO0HIVD [INF] Request starting HTTP/1.1 GET http://localhost:5000/main.js (e5be5b71) 2017-04-20T11:39:09.8744170-05:00 0HL481DO0HIVD [DBG] Connection id ""0HL481DNUOBH2"" completed keep alive response. (9784cde9) 2017-04-20T11:39:09.8745270-05:00 0HL481DO0HIVD [INF] Request finished in 36.3432ms 200 application/javascript; charset=UTF-8 (15c52c40) 2017-04-20T11:39:10.0234160-05:00 0HL481DO0HIVE [INF] Request starting HTTP/1.1 GET http://localhost:5000/__webpack_hmr (e5be5b71) 2017-04-20T11:39:10.0562140-05:00 [INF] Connection id ""0HL481DNUOBGS"" communication error. (7fa6c29c) Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvException: Error -32 EPIPE broken pipe 2017-04-20T11:39:10.0562050-05:00 [DBG] Connection id ""0HL481DNUOBGS"" disconnecting. (b29b9868) 2017-04-20T11:39:10.0563640-05:00 [DBG] Connection id ""0HL481DNUOBGS"" stopped. (056149f8) 2017-04-20T11:39:10.0587750-05:00 [INF] Connection id ""0HL481DNUOBH1"" communication error. (7fa6c29c) Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvException: Error -32 EPIPE broken pipe 2017-04-20T11:39:10.0587850-05:00 [DBG] Connection id ""0HL481DNUOBH1"" disconnecting. (b29b9868) 2017-04-20T11:39:10.0589970-05:00 [DBG] Connection id ""0HL481DNUOBH1"" stopped. (056149f8) 2017-04-20T11:39:14.1101400-05:00 0HL481DO0HIVF [INF] Request starting HTTP/1.1 POST http://localhost:5000/api/auth/register application/x-www-form-urlencoded 41 (e5be5b71) 2017-04-20T11:39:14.1120980-05:00 0HL481DO0HIVF [INF] Handling request: /api/auth/register (2c1017b8) 2017-04-20T11:39:14.1121790-05:00 0HL481DO0HIVF [DBG] "POST" requests are not supported (1c759b4c) 2017-04-20T11:39:14.1124730-05:00 0HL481DO0HIVF [INF] "Bearer" was not authenticated. Failure message: "Authentication failed because the access token was invalid." (48071232) 2017-04-20T11:39:14.1125950-05:00 0HL481DO0HIVF [INF] "Bearer" was not authenticated. Failure message: "No SecurityTokenValidator available for token: null" (48071232) 2017-04-20T11:39:14.1127600-05:00 0HL481DO0HIVF [DBG] Request successfully matched the route with name 'null' and template '"api/auth/register"'. (555ac2ba) 2017-04-20T11:39:14.1140020-05:00 0HL481DO0HIVF [DBG] Executing action "aspnetCoreReactTemplate.aspnetCoreReactTemplate.Controllers.AuthController.Register (api)" (3f3ef15a) 2017-04-20T11:39:14.1156750-05:00 0HL481DO0HIVF [INF] Executing action method "aspnetCoreReactTemplate.aspnetCoreReactTemplate.Controllers.AuthController.Register (api)" with arguments (["aspnetCoreReactTemplate.ViewModels.NewUser"]) - ModelState is Valid (ba7f4ac2) 2017-04-20T11:39:14.1415600-05:00 0HL481DO0HIVF [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:39:14.1455590-05:00 0HL481DO0HIVF [INF] Executed DbCommand (1ms) [Parameters=[@__normalizedUserName_0='?'], CommandType='Text', CommandTimeout='30'] SELECT "u"."Id", "u"."AccessFailedCount", "u"."ConcurrencyStamp", "u"."Email", "u"."EmailConfirmed", "u"."GivenName", "u"."LockoutEnabled", "u"."LockoutEnd", "u"."NormalizedEmail", "u"."NormalizedUserName", "u"."PasswordHash", "u"."PhoneNumber", "u"."PhoneNumberConfirmed", "u"."SecurityStamp", "u"."TwoFactorEnabled", "u"."UserName" FROM "AspNetUsers" AS "u" WHERE "u"."NormalizedUserName" = @__normalizedUserName_0 LIMIT 1 (6438bdd5) 2017-04-20T11:39:14.1458010-05:00 0HL481DO0HIVF [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:39:14.1460050-05:00 0HL481DO0HIVF [WRN] User "2f93a607-6b5b-4b6b-899b-f459f4322d02" validation failed: "DuplicateUserName". (5dc28e15) 2017-04-20T11:39:14.1461340-05:00 0HL481DO0HIVF [DBG] Executed action method "aspnetCoreReactTemplate.aspnetCoreReactTemplate.Controllers.AuthController.Register (api)", returned result "Microsoft.AspNetCore.Mvc.BadRequestObjectResult". (f72615e0) 2017-04-20T11:39:14.1463360-05:00 0HL481DO0HIVF [DBG] No information found on request to perform content negotiation. (6aec0ec5) 2017-04-20T11:39:14.1464230-05:00 0HL481DO0HIVF [DBG] Selected output formatter '"Microsoft.AspNetCore.Mvc.Formatters.JsonOutputFormatter"' and content type '"application/json"' to write the response. (fcc32779) 2017-04-20T11:39:14.1464610-05:00 0HL481DO0HIVF [INF] Executing ObjectResult, writing value "Microsoft.AspNetCore.Mvc.ControllerContext". (4e968210) 2017-04-20T11:39:14.1467060-05:00 0HL481DO0HIVF [INF] Executed action "aspnetCoreReactTemplate.aspnetCoreReactTemplate.Controllers.AuthController.Register (api)" in 32.6371ms (afa2e885) 2017-04-20T11:39:14.1468290-05:00 0HL481DO0HIVF [INF] Finished handling request. (d2c25297) 2017-04-20T11:39:14.1470340-05:00 0HL481DO0HIVF [DBG] Connection id ""0HL481DNUOBGV"" completed keep alive response. (9784cde9) 2017-04-20T11:39:14.1471100-05:00 0HL481DO0HIVF [INF] Request finished in 37.0278ms 400 application/json; charset=utf-8 (15c52c40) 2017-04-20T11:39:48.9834480-05:00 [DBG] Connection id ""0HL481DNUOBH0"" disconnecting. (b29b9868) 2017-04-20T11:39:48.9835820-05:00 [DBG] Connection id ""0HL481DNUOBH0"" sending FIN. (ffb251f5) 2017-04-20T11:39:48.9836800-05:00 [DBG] Connection id ""0HL481DNUOBH0"" sent FIN with status "0". (69d90ca7) 2017-04-20T11:39:48.9838000-05:00 [DBG] Connection id ""0HL481DNUOBH0"" stopped. (056149f8) 2017-04-20T11:39:58.9621780-05:00 0HL481DO0HIVG [INF] Request starting HTTP/1.1 POST http://localhost:5000/api/auth/register application/x-www-form-urlencoded 41 (e5be5b71) 2017-04-20T11:39:58.9649200-05:00 0HL481DO0HIVG [INF] Handling request: /api/auth/register (2c1017b8) 2017-04-20T11:39:58.9650300-05:00 0HL481DO0HIVG [DBG] "POST" requests are not supported (1c759b4c) 2017-04-20T11:39:58.9652620-05:00 0HL481DO0HIVG [INF] "Bearer" was not authenticated. Failure message: "Authentication failed because the access token was invalid." (48071232) 2017-04-20T11:39:58.9653330-05:00 0HL481DO0HIVG [INF] "Bearer" was not authenticated. Failure message: "No SecurityTokenValidator available for token: null" (48071232) 2017-04-20T11:39:58.9655650-05:00 0HL481DO0HIVG [DBG] Request successfully matched the route with name 'null' and template '"api/auth/register"'. (555ac2ba) 2017-04-20T11:39:58.9656550-05:00 0HL481DO0HIVG [DBG] Executing action "aspnetCoreReactTemplate.aspnetCoreReactTemplate.Controllers.AuthController.Register (api)" (3f3ef15a) 2017-04-20T11:39:58.9659790-05:00 0HL481DO0HIVG [INF] Executing action method "aspnetCoreReactTemplate.aspnetCoreReactTemplate.Controllers.AuthController.Register (api)" with arguments (["aspnetCoreReactTemplate.ViewModels.NewUser"]) - ModelState is Valid (ba7f4ac2) 2017-04-20T11:39:58.9859840-05:00 0HL481DO0HIVG [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:39:58.9877550-05:00 0HL481DO0HIVG [INF] Executed DbCommand (1ms) [Parameters=[@__normalizedUserName_0='?'], CommandType='Text', CommandTimeout='30'] SELECT "u"."Id", "u"."AccessFailedCount", "u"."ConcurrencyStamp", "u"."Email", "u"."EmailConfirmed", "u"."GivenName", "u"."LockoutEnabled", "u"."LockoutEnd", "u"."NormalizedEmail", "u"."NormalizedUserName", "u"."PasswordHash", "u"."PhoneNumber", "u"."PhoneNumberConfirmed", "u"."SecurityStamp", "u"."TwoFactorEnabled", "u"."UserName" FROM "AspNetUsers" AS "u" WHERE "u"."NormalizedUserName" = @__normalizedUserName_0 LIMIT 1 (6438bdd5) 2017-04-20T11:39:58.9879100-05:00 0HL481DO0HIVG [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:39:58.9880440-05:00 0HL481DO0HIVG [WRN] User "86431f92-3002-4f53-bb99-3becedaaddbe" validation failed: "DuplicateUserName". (5dc28e15) 2017-04-20T11:39:58.9881080-05:00 0HL481DO0HIVG [DBG] Executed action method "aspnetCoreReactTemplate.aspnetCoreReactTemplate.Controllers.AuthController.Register (api)", returned result "Microsoft.AspNetCore.Mvc.BadRequestObjectResult". (f72615e0) 2017-04-20T11:39:58.9881740-05:00 0HL481DO0HIVG [DBG] No information found on request to perform content negotiation. (6aec0ec5) 2017-04-20T11:39:58.9882110-05:00 0HL481DO0HIVG [DBG] Selected output formatter '"Microsoft.AspNetCore.Mvc.Formatters.JsonOutputFormatter"' and content type '"application/json"' to write the response. (fcc32779) 2017-04-20T11:39:58.9882440-05:00 0HL481DO0HIVG [INF] Executing ObjectResult, writing value "Microsoft.AspNetCore.Mvc.ControllerContext". (4e968210) 2017-04-20T11:39:58.9883520-05:00 0HL481DO0HIVG [INF] Executed action "aspnetCoreReactTemplate.aspnetCoreReactTemplate.Controllers.AuthController.Register (api)" in 22.6438ms (afa2e885) 2017-04-20T11:39:58.9884410-05:00 0HL481DO0HIVG [INF] Finished handling request. (d2c25297) 2017-04-20T11:39:58.9884990-05:00 0HL481DO0HIVG [DBG] Connection id ""0HL481DNUOBGV"" completed keep alive response. (9784cde9) 2017-04-20T11:39:58.9885460-05:00 0HL481DO0HIVG [INF] Request finished in 26.4137ms 400 application/json; charset=utf-8 (15c52c40) 2017-04-20T11:40:02.4118890-05:00 0HL481DO0HIVH [INF] Request starting HTTP/1.1 POST http://localhost:5000/api/auth/register application/x-www-form-urlencoded 41 (e5be5b71) 2017-04-20T11:40:02.4152190-05:00 0HL481DO0HIVH [INF] Handling request: /api/auth/register (2c1017b8) 2017-04-20T11:40:02.4153030-05:00 0HL481DO0HIVH [DBG] "POST" requests are not supported (1c759b4c) 2017-04-20T11:40:02.4155360-05:00 0HL481DO0HIVH [INF] "Bearer" was not authenticated. Failure message: "Authentication failed because the access token was invalid." (48071232) 2017-04-20T11:40:02.4156250-05:00 0HL481DO0HIVH [INF] "Bearer" was not authenticated. Failure message: "No SecurityTokenValidator available for token: null" (48071232) 2017-04-20T11:40:02.4157540-05:00 0HL481DO0HIVH [DBG] Request successfully matched the route with name 'null' and template '"api/auth/register"'. (555ac2ba) 2017-04-20T11:40:02.4158230-05:00 0HL481DO0HIVH [DBG] Executing action "aspnetCoreReactTemplate.aspnetCoreReactTemplate.Controllers.AuthController.Register (api)" (3f3ef15a) 2017-04-20T11:40:02.4161110-05:00 0HL481DO0HIVH [INF] Executing action method "aspnetCoreReactTemplate.aspnetCoreReactTemplate.Controllers.AuthController.Register (api)" with arguments (["aspnetCoreReactTemplate.ViewModels.NewUser"]) - ModelState is Valid (ba7f4ac2) 2017-04-20T11:40:02.4384170-05:00 0HL481DO0HIVH [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:40:02.4402280-05:00 0HL481DO0HIVH [INF] Executed DbCommand (1ms) [Parameters=[@__normalizedUserName_0='?'], CommandType='Text', CommandTimeout='30'] SELECT "u"."Id", "u"."AccessFailedCount", "u"."ConcurrencyStamp", "u"."Email", "u"."EmailConfirmed", "u"."GivenName", "u"."LockoutEnabled", "u"."LockoutEnd", "u"."NormalizedEmail", "u"."NormalizedUserName", "u"."PasswordHash", "u"."PhoneNumber", "u"."PhoneNumberConfirmed", "u"."SecurityStamp", "u"."TwoFactorEnabled", "u"."UserName" FROM "AspNetUsers" AS "u" WHERE "u"."NormalizedUserName" = @__normalizedUserName_0 LIMIT 1 (6438bdd5) 2017-04-20T11:40:02.4405080-05:00 0HL481DO0HIVH [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:40:02.4407150-05:00 0HL481DO0HIVH [WRN] User "8a5d0dff-4e0d-47dc-99c6-dfb6f331b36e" validation failed: "DuplicateUserName". (5dc28e15) 2017-04-20T11:40:02.4407910-05:00 0HL481DO0HIVH [DBG] Executed action method "aspnetCoreReactTemplate.aspnetCoreReactTemplate.Controllers.AuthController.Register (api)", returned result "Microsoft.AspNetCore.Mvc.BadRequestObjectResult". (f72615e0) 2017-04-20T11:40:02.4408430-05:00 0HL481DO0HIVH [DBG] No information found on request to perform content negotiation. (6aec0ec5) 2017-04-20T11:40:02.4408950-05:00 0HL481DO0HIVH [DBG] Selected output formatter '"Microsoft.AspNetCore.Mvc.Formatters.JsonOutputFormatter"' and content type '"application/json"' to write the response. (fcc32779) 2017-04-20T11:40:02.4409290-05:00 0HL481DO0HIVH [INF] Executing ObjectResult, writing value "Microsoft.AspNetCore.Mvc.ControllerContext". (4e968210) 2017-04-20T11:40:02.4410590-05:00 0HL481DO0HIVH [INF] Executed action "aspnetCoreReactTemplate.aspnetCoreReactTemplate.Controllers.AuthController.Register (api)" in 25.1783ms (afa2e885) 2017-04-20T11:40:02.4411560-05:00 0HL481DO0HIVH [INF] Finished handling request. (d2c25297) 2017-04-20T11:40:02.4412390-05:00 0HL481DO0HIVH [DBG] Connection id ""0HL481DNUOBGV"" completed keep alive response. (9784cde9) 2017-04-20T11:40:02.4413110-05:00 0HL481DO0HIVH [INF] Request finished in 29.4581ms 400 application/json; charset=utf-8 (15c52c40) 2017-04-20T11:40:06.6871600-05:00 [DBG] Connection id ""0HL481DNUOBH3"" started. (1426b994) 2017-04-20T11:40:06.6873480-05:00 0HL481DO0HIVI [INF] Request starting HTTP/1.1 GET http://localhost:5000/register (e5be5b71) 2017-04-20T11:40:06.6896230-05:00 0HL481DO0HIVI [INF] Handling request: /register (d15267fc) 2017-04-20T11:40:06.6896800-05:00 0HL481DO0HIVI [INF] Rewriting path: /register > / (b5db4a63) 2017-04-20T11:40:06.6899040-05:00 0HL481DO0HIVI [INF] The file "/index.html" was not modified (f1f8d725) 2017-04-20T11:40:06.6899730-05:00 0HL481DO0HIVI [DBG] Handled. Status code: 304 File: "/index.html" (58f8d392) 2017-04-20T11:40:06.6900170-05:00 0HL481DO0HIVI [INF] Finished handling request. (d2c25297) 2017-04-20T11:40:06.6900850-05:00 0HL481DO0HIVI [DBG] Connection id ""0HL481DNUOBH3"" completed keep alive response. (9784cde9) 2017-04-20T11:40:06.6901910-05:00 0HL481DO0HIVI [INF] Request finished in 2.828ms 304 text/html (15c52c40) 2017-04-20T11:40:06.6920350-05:00 [DBG] Connection id ""0HL481DNUOBH2"" received FIN. (acf58720) 2017-04-20T11:40:06.6982060-05:00 0HL481DO0HIVJ [INF] Request starting HTTP/1.1 GET http://localhost:5000/main.js (e5be5b71) 2017-04-20T11:40:06.7981140-05:00 0HL481DO0HIVJ [DBG] Connection id ""0HL481DNUOBH3"" completed keep alive response. (9784cde9) 2017-04-20T11:40:06.7982550-05:00 0HL481DO0HIVJ [INF] Request finished in 100.0866ms 200 application/javascript; charset=UTF-8 (15c52c40) 2017-04-20T11:40:06.9514120-05:00 0HL481DO0HIVK [INF] Request starting HTTP/1.1 GET http://localhost:5000/__webpack_hmr (e5be5b71) 2017-04-20T11:40:07.7135560-05:00 [DBG] Connection id ""0HL481DNUOBH4"" started. (1426b994) 2017-04-20T11:40:07.7137430-05:00 0HL481DO0HIVL [INF] Request starting HTTP/1.1 GET http://localhost:5000/register (e5be5b71) 2017-04-20T11:40:07.7165340-05:00 0HL481DO0HIVL [INF] Handling request: /register (d15267fc) 2017-04-20T11:40:07.7166070-05:00 0HL481DO0HIVL [INF] Rewriting path: /register > / (b5db4a63) 2017-04-20T11:40:07.7168370-05:00 0HL481DO0HIVL [INF] The file "/index.html" was not modified (f1f8d725) 2017-04-20T11:40:07.7169050-05:00 0HL481DO0HIVL [DBG] Handled. Status code: 304 File: "/index.html" (58f8d392) 2017-04-20T11:40:07.7169620-05:00 0HL481DO0HIVL [INF] Finished handling request. (d2c25297) 2017-04-20T11:40:07.7170540-05:00 0HL481DO0HIVL [DBG] Connection id ""0HL481DNUOBH4"" completed keep alive response. (9784cde9) 2017-04-20T11:40:07.7171230-05:00 0HL481DO0HIVL [INF] Request finished in 3.3808ms 304 text/html (15c52c40) 2017-04-20T11:40:07.7190570-05:00 [DBG] Connection id ""0HL481DNUOBH3"" received FIN. (acf58720) 2017-04-20T11:40:07.7245360-05:00 0HL481DO0HIVM [INF] Request starting HTTP/1.1 GET http://localhost:5000/main.js (e5be5b71) 2017-04-20T11:40:07.7679270-05:00 0HL481DO0HIVM [DBG] Connection id ""0HL481DNUOBH4"" completed keep alive response. (9784cde9) 2017-04-20T11:40:07.7680490-05:00 0HL481DO0HIVM [INF] Request finished in 43.5382ms 200 application/javascript; charset=UTF-8 (15c52c40) 2017-04-20T11:40:07.9121720-05:00 0HL481DO0HIVN [INF] Request starting HTTP/1.1 GET http://localhost:5000/__webpack_hmr (e5be5b71) 2017-04-20T11:40:07.9323120-05:00 [INF] Connection id ""0HL481DNUOBH2"" communication error. (7fa6c29c) Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvException: Error -32 EPIPE broken pipe 2017-04-20T11:40:07.9323120-05:00 [DBG] Connection id ""0HL481DNUOBH2"" disconnecting. (b29b9868) 2017-04-20T11:40:07.9325000-05:00 [INF] Connection id ""0HL481DNUOBH2"" communication error. (7fa6c29c) Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvException: Error -32 EPIPE broken pipe 2017-04-20T11:40:07.9327500-05:00 [INF] Connection id ""0HL481DNUOBH3"" communication error. (7fa6c29c) Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvException: Error -32 EPIPE broken pipe 2017-04-20T11:40:07.9328240-05:00 [DBG] Connection id ""0HL481DNUOBH3"" disconnecting. (b29b9868) 2017-04-20T11:40:07.9329040-05:00 [DBG] Connection id ""0HL481DNUOBH2"" stopped. (056149f8) 2017-04-20T11:40:07.9329500-05:00 [DBG] Connection id ""0HL481DNUOBH3"" stopped. (056149f8) 2017-04-20T11:40:12.8112560-05:00 0HL481DO0HIVO [INF] Request starting HTTP/1.1 POST http://localhost:5000/api/auth/register application/x-www-form-urlencoded 41 (e5be5b71) 2017-04-20T11:40:12.8130870-05:00 0HL481DO0HIVO [INF] Handling request: /api/auth/register (2c1017b8) 2017-04-20T11:40:12.8132280-05:00 0HL481DO0HIVO [DBG] "POST" requests are not supported (1c759b4c) 2017-04-20T11:40:12.8134190-05:00 0HL481DO0HIVO [INF] "Bearer" was not authenticated. Failure message: "Authentication failed because the access token was invalid." (48071232) 2017-04-20T11:40:12.8135180-05:00 0HL481DO0HIVO [INF] "Bearer" was not authenticated. Failure message: "No SecurityTokenValidator available for token: null" (48071232) 2017-04-20T11:40:12.8136160-05:00 0HL481DO0HIVO [DBG] Request successfully matched the route with name 'null' and template '"api/auth/register"'. (555ac2ba) 2017-04-20T11:40:12.8136940-05:00 0HL481DO0HIVO [DBG] Executing action "aspnetCoreReactTemplate.aspnetCoreReactTemplate.Controllers.AuthController.Register (api)" (3f3ef15a) 2017-04-20T11:40:12.8139390-05:00 0HL481DO0HIVO [INF] Executing action method "aspnetCoreReactTemplate.aspnetCoreReactTemplate.Controllers.AuthController.Register (api)" with arguments (["aspnetCoreReactTemplate.ViewModels.NewUser"]) - ModelState is Valid (ba7f4ac2) 2017-04-20T11:40:12.8347490-05:00 0HL481DO0HIVO [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:40:12.8363430-05:00 0HL481DO0HIVO [INF] Executed DbCommand (1ms) [Parameters=[@__normalizedUserName_0='?'], CommandType='Text', CommandTimeout='30'] SELECT "u"."Id", "u"."AccessFailedCount", "u"."ConcurrencyStamp", "u"."Email", "u"."EmailConfirmed", "u"."GivenName", "u"."LockoutEnabled", "u"."LockoutEnd", "u"."NormalizedEmail", "u"."NormalizedUserName", "u"."PasswordHash", "u"."PhoneNumber", "u"."PhoneNumberConfirmed", "u"."SecurityStamp", "u"."TwoFactorEnabled", "u"."UserName" FROM "AspNetUsers" AS "u" WHERE "u"."NormalizedUserName" = @__normalizedUserName_0 LIMIT 1 (6438bdd5) 2017-04-20T11:40:12.8365570-05:00 0HL481DO0HIVO [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:40:12.8367310-05:00 0HL481DO0HIVO [WRN] User "ccb83522-ab79-4c44-9b0b-5ff35929e0a2" validation failed: "DuplicateUserName". (5dc28e15) 2017-04-20T11:40:12.8368240-05:00 0HL481DO0HIVO [DBG] Executed action method "aspnetCoreReactTemplate.aspnetCoreReactTemplate.Controllers.AuthController.Register (api)", returned result "Microsoft.AspNetCore.Mvc.BadRequestObjectResult". (f72615e0) 2017-04-20T11:40:12.8368970-05:00 0HL481DO0HIVO [DBG] No information found on request to perform content negotiation. (6aec0ec5) 2017-04-20T11:40:12.8369660-05:00 0HL481DO0HIVO [DBG] Selected output formatter '"Microsoft.AspNetCore.Mvc.Formatters.JsonOutputFormatter"' and content type '"application/json"' to write the response. (fcc32779) 2017-04-20T11:40:12.8370050-05:00 0HL481DO0HIVO [INF] Executing ObjectResult, writing value "Microsoft.AspNetCore.Mvc.ControllerContext". (4e968210) 2017-04-20T11:40:12.8371390-05:00 0HL481DO0HIVO [INF] Executed action "aspnetCoreReactTemplate.aspnetCoreReactTemplate.Controllers.AuthController.Register (api)" in 23.4046ms (afa2e885) 2017-04-20T11:40:12.8373040-05:00 0HL481DO0HIVO [INF] Finished handling request. (d2c25297) 2017-04-20T11:40:12.8373970-05:00 0HL481DO0HIVO [DBG] Connection id ""0HL481DNUOBGV"" completed keep alive response. (9784cde9) 2017-04-20T11:40:12.8374680-05:00 0HL481DO0HIVO [INF] Request finished in 26.2417ms 400 application/json; charset=utf-8 (15c52c40) 2017-04-20T11:40:18.4429330-05:00 0HL481DO0HIVP [INF] Request starting HTTP/1.1 POST http://localhost:5000/api/auth/register application/x-www-form-urlencoded 43 (e5be5b71) 2017-04-20T11:40:18.4456770-05:00 0HL481DO0HIVP [INF] Handling request: /api/auth/register (2c1017b8) 2017-04-20T11:40:18.4458000-05:00 0HL481DO0HIVP [DBG] "POST" requests are not supported (1c759b4c) 2017-04-20T11:40:18.4460320-05:00 0HL481DO0HIVP [INF] "Bearer" was not authenticated. Failure message: "Authentication failed because the access token was invalid." (48071232) 2017-04-20T11:40:18.4461620-05:00 0HL481DO0HIVP [INF] "Bearer" was not authenticated. Failure message: "No SecurityTokenValidator available for token: null" (48071232) 2017-04-20T11:40:18.4463040-05:00 0HL481DO0HIVP [DBG] Request successfully matched the route with name 'null' and template '"api/auth/register"'. (555ac2ba) 2017-04-20T11:40:18.4463950-05:00 0HL481DO0HIVP [DBG] Executing action "aspnetCoreReactTemplate.aspnetCoreReactTemplate.Controllers.AuthController.Register (api)" (3f3ef15a) 2017-04-20T11:40:18.4468380-05:00 0HL481DO0HIVP [INF] Executing action method "aspnetCoreReactTemplate.aspnetCoreReactTemplate.Controllers.AuthController.Register (api)" with arguments (["aspnetCoreReactTemplate.ViewModels.NewUser"]) - ModelState is Valid (ba7f4ac2) 2017-04-20T11:40:18.4673860-05:00 0HL481DO0HIVP [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:40:18.4687650-05:00 0HL481DO0HIVP [INF] Executed DbCommand (1ms) [Parameters=[@__normalizedUserName_0='?'], CommandType='Text', CommandTimeout='30'] SELECT "u"."Id", "u"."AccessFailedCount", "u"."ConcurrencyStamp", "u"."Email", "u"."EmailConfirmed", "u"."GivenName", "u"."LockoutEnabled", "u"."LockoutEnd", "u"."NormalizedEmail", "u"."NormalizedUserName", "u"."PasswordHash", "u"."PhoneNumber", "u"."PhoneNumberConfirmed", "u"."SecurityStamp", "u"."TwoFactorEnabled", "u"."UserName" FROM "AspNetUsers" AS "u" WHERE "u"."NormalizedUserName" = @__normalizedUserName_0 LIMIT 1 (6438bdd5) 2017-04-20T11:40:18.4688690-05:00 0HL481DO0HIVP [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:40:18.5011340-05:00 0HL481DO0HIVP [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:40:18.5012750-05:00 0HL481DO0HIVP [DBG] Beginning transaction with isolation level 'Unspecified'. (3b5ca34b) 2017-04-20T11:40:18.5092810-05:00 0HL481DO0HIVP [INF] Executed DbCommand (2ms) [Parameters=[@p0='?', @p1='?', @p2='?', @p3='?', @p4='?', @p5='?', @p6='?', @p7='?', @p8='?', @p9='?', @p10='?', @p11='?', @p12='?', @p13='?', @p14='?', @p15='?'], CommandType='Text', CommandTimeout='30'] INSERT INTO "AspNetUsers" ("Id", "AccessFailedCount", "ConcurrencyStamp", "Email", "EmailConfirmed", "GivenName", "LockoutEnabled", "LockoutEnd", "NormalizedEmail", "NormalizedUserName", "PasswordHash", "PhoneNumber", "PhoneNumberConfirmed", "SecurityStamp", "TwoFactorEnabled", "UserName") VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10, @p11, @p12, @p13, @p14, @p15); (6438bdd5) 2017-04-20T11:40:18.5199150-05:00 0HL481DO0HIVP [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:40:18.5220720-05:00 0HL481DO0HIVP [INF] New user registered (id: 28e718f7-6d7a-4eb5-9d7d-3983acd1cfeb) (ee102ef0) 2017-04-20T11:40:18.5488350-05:00 0HL481DO0HIVP [DBG] Reading data from file '"/Users/bholt/.aspnet/DataProtection-Keys/key-2115e1cc-6a7a-4f94-a5af-79045dd7268a.xml"'. (5ce001c4) 2017-04-20T11:40:18.5536860-05:00 0HL481DO0HIVP [DBG] Reading data from file '"/Users/bholt/.aspnet/DataProtection-Keys/key-65a1dbdc-ff60-43d0-ad97-4b44b66d8604.xml"'. (5ce001c4) 2017-04-20T11:40:18.5614190-05:00 0HL481DO0HIVP [DBG] Found key {2115e1cc-6a7a-4f94-a5af-79045dd7268a}. (f843275d) 2017-04-20T11:40:18.5668030-05:00 0HL481DO0HIVP [DBG] Found key {65a1dbdc-ff60-43d0-ad97-4b44b66d8604}. (f843275d) 2017-04-20T11:40:18.5819820-05:00 0HL481DO0HIVP [DBG] Considering key {2115e1cc-6a7a-4f94-a5af-79045dd7268a} with expiration date 2017-07-15 20:23:44Z as default key. (ca2e3b22) 2017-04-20T11:40:18.5986940-05:00 0HL481DO0HIVP [DBG] Using managed symmetric algorithm '"System.Security.Cryptography.Aes"'. (0f299fe5) 2017-04-20T11:40:18.5998270-05:00 0HL481DO0HIVP [DBG] Using managed keyed hash algorithm '"System.Security.Cryptography.HMACSHA256"'. (47d8f6fe) 2017-04-20T11:40:18.6142350-05:00 0HL481DO0HIVP [DBG] Using key {2115e1cc-6a7a-4f94-a5af-79045dd7268a} as the default key. (4cf2d764) 2017-04-20T11:40:19.1260690-05:00 0HL481DO0HIVP [INF] Sent email confirmation email (id: 28e718f7-6d7a-4eb5-9d7d-3983acd1cfeb) (88a75a42) 2017-04-20T11:40:19.2434760-05:00 0HL481DO0HIVP [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:40:19.2513050-05:00 0HL481DO0HIVP [INF] Executed DbCommand (6ms) [Parameters=[@__userId_0='?'], CommandType='Text', CommandTimeout='30'] SELECT "role"."Name" FROM "AspNetUserRoles" AS "userRole" INNER JOIN "AspNetRoles" AS "role" ON "userRole"."RoleId" = "role"."Id" WHERE "userRole"."UserId" = @__userId_0 (6438bdd5) 2017-04-20T11:40:19.2522840-05:00 0HL481DO0HIVP [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:40:19.2770190-05:00 0HL481DO0HIVP [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:40:19.2791770-05:00 0HL481DO0HIVP [INF] Executed DbCommand (1ms) [Parameters=[@__user_Id_0='?'], CommandType='Text', CommandTimeout='30'] SELECT "uc"."Id", "uc"."ClaimType", "uc"."ClaimValue", "uc"."UserId" FROM "AspNetUserClaims" AS "uc" WHERE "uc"."UserId" = @__user_Id_0 (6438bdd5) 2017-04-20T11:40:19.2794120-05:00 0HL481DO0HIVP [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:40:19.2890810-05:00 0HL481DO0HIVP [INF] User logged in (id: 28e718f7-6d7a-4eb5-9d7d-3983acd1cfeb) (bf48a8ee) 2017-04-20T11:40:19.2893740-05:00 0HL481DO0HIVP [DBG] Executed action method "aspnetCoreReactTemplate.aspnetCoreReactTemplate.Controllers.AuthController.Register (api)", returned result "Microsoft.AspNetCore.Mvc.OkResult". (f72615e0) 2017-04-20T11:40:19.2922430-05:00 0HL481DO0HIVP [INF] Executing HttpStatusCodeResult, setting HTTP status code 200 (e28ccfae) 2017-04-20T11:40:19.2931220-05:00 0HL481DO0HIVP [INF] Executed action "aspnetCoreReactTemplate.aspnetCoreReactTemplate.Controllers.AuthController.Register (api)" in 846.7138ms (afa2e885) 2017-04-20T11:40:19.2932340-05:00 0HL481DO0HIVP [INF] Finished handling request. (d2c25297) 2017-04-20T11:40:19.2939380-05:00 0HL481DO0HIVP [DBG] Connection id ""0HL481DNUOBGV"" completed keep alive response. (9784cde9) 2017-04-20T11:40:19.2940030-05:00 0HL481DO0HIVP [INF] Request finished in 851.1767ms 200 (15c52c40) 2017-04-20T11:40:19.8710400-05:00 [DBG] Connection id ""0HL481DNUOBH5"" started. (1426b994) 2017-04-20T11:40:19.8712390-05:00 0HL481DO0HIVQ [INF] Request starting HTTP/1.1 GET http://localhost:5000/favicon.ico (e5be5b71) 2017-04-20T11:40:19.8732470-05:00 0HL481DO0HIVQ [INF] Handling request: /favicon.ico (b3d76b52) 2017-04-20T11:40:19.8735140-05:00 0HL481DO0HIVQ [INF] Sending file. Request path: '"/favicon.ico"'. Physical path: '"/Users/bholt/dev/aspnet-core-react-template/api/wwwroot/favicon.ico"' (27b0a520) 2017-04-20T11:40:19.8744590-05:00 0HL481DO0HIVQ [INF] Finished handling request. (d2c25297) 2017-04-20T11:40:19.8745650-05:00 0HL481DO0HIVQ [DBG] Connection id ""0HL481DNUOBH5"" completed keep alive response. (9784cde9) 2017-04-20T11:40:19.8747030-05:00 0HL481DO0HIVQ [INF] Request finished in 3.427ms 200 image/x-icon (15c52c40) 2017-04-20T11:42:20.0860490-05:00 [DBG] Connection id ""0HL481DNUOBGV"" disconnecting. (b29b9868) 2017-04-20T11:42:20.0862240-05:00 [DBG] Connection id ""0HL481DNUOBGV"" sending FIN. (ffb251f5) 2017-04-20T11:42:20.0863450-05:00 [DBG] Connection id ""0HL481DNUOBGV"" sent FIN with status "0". (69d90ca7) 2017-04-20T11:42:20.0864070-05:00 [DBG] Connection id ""0HL481DNUOBGV"" stopped. (056149f8) 2017-04-20T11:42:21.0952590-05:00 [DBG] Connection id ""0HL481DNUOBH5"" disconnecting. (b29b9868) 2017-04-20T11:42:21.0954820-05:00 [DBG] Connection id ""0HL481DNUOBH5"" sending FIN. (ffb251f5) 2017-04-20T11:42:21.0956160-05:00 [DBG] Connection id ""0HL481DNUOBH5"" sent FIN with status "0". (69d90ca7) 2017-04-20T11:42:21.0957040-05:00 [DBG] Connection id ""0HL481DNUOBH5"" stopped. (056149f8) 2017-04-20T11:45:42.4452760-05:00 [DBG] Connection id ""0HL481DNUOBH6"" started. (1426b994) 2017-04-20T11:45:42.4454930-05:00 0HL481DO0HIVR [INF] Request starting HTTP/1.1 GET http://localhost:5000/register (e5be5b71) 2017-04-20T11:45:42.4470350-05:00 0HL481DO0HIVR [INF] Handling request: /register (d15267fc) 2017-04-20T11:45:42.4470960-05:00 0HL481DO0HIVR [INF] Rewriting path: /register > / (b5db4a63) 2017-04-20T11:45:42.4472760-05:00 0HL481DO0HIVR [INF] The file "/index.html" was not modified (f1f8d725) 2017-04-20T11:45:42.4473350-05:00 0HL481DO0HIVR [DBG] Handled. Status code: 304 File: "/index.html" (58f8d392) 2017-04-20T11:45:42.4473680-05:00 0HL481DO0HIVR [INF] Finished handling request. (d2c25297) 2017-04-20T11:45:42.4474200-05:00 0HL481DO0HIVR [DBG] Connection id ""0HL481DNUOBH6"" completed keep alive response. (9784cde9) 2017-04-20T11:45:42.4474760-05:00 0HL481DO0HIVR [INF] Request finished in 2.0026ms 304 text/html (15c52c40) 2017-04-20T11:45:42.4492840-05:00 [DBG] Connection id ""0HL481DNUOBH4"" received FIN. (acf58720) 2017-04-20T11:45:42.4549310-05:00 0HL481DO0HIVS [INF] Request starting HTTP/1.1 GET http://localhost:5000/main.js (e5be5b71) 2017-04-20T11:45:42.5539130-05:00 0HL481DO0HIVS [DBG] Connection id ""0HL481DNUOBH6"" completed keep alive response. (9784cde9) 2017-04-20T11:45:42.5540400-05:00 0HL481DO0HIVS [INF] Request finished in 99.113ms 200 application/javascript; charset=UTF-8 (15c52c40) 2017-04-20T11:45:42.7079810-05:00 0HL481DO0HIVT [INF] Request starting HTTP/1.1 GET http://localhost:5000/__webpack_hmr (e5be5b71) 2017-04-20T11:45:42.7262130-05:00 [DBG] Connection id ""0HL481DNUOBH4"" disconnecting. (b29b9868) 2017-04-20T11:45:42.7262060-05:00 [INF] Connection id ""0HL481DNUOBH4"" communication error. (7fa6c29c) Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvException: Error -32 EPIPE broken pipe 2017-04-20T11:45:42.7265250-05:00 [DBG] Connection id ""0HL481DNUOBH4"" stopped. (056149f8) 2017-04-20T11:45:44.0215750-05:00 [DBG] Connection id ""0HL481DNUOBH7"" started. (1426b994) 2017-04-20T11:45:44.0217810-05:00 0HL481DO0HIVU [INF] Request starting HTTP/1.1 GET http://localhost:5000/register (e5be5b71) 2017-04-20T11:45:44.0246960-05:00 0HL481DO0HIVU [INF] Handling request: /register (d15267fc) 2017-04-20T11:45:44.0247650-05:00 0HL481DO0HIVU [INF] Rewriting path: /register > / (b5db4a63) 2017-04-20T11:45:44.0250240-05:00 0HL481DO0HIVU [INF] The file "/index.html" was not modified (f1f8d725) 2017-04-20T11:45:44.0250900-05:00 0HL481DO0HIVU [DBG] Handled. Status code: 304 File: "/index.html" (58f8d392) 2017-04-20T11:45:44.0251170-05:00 0HL481DO0HIVU [INF] Finished handling request. (d2c25297) 2017-04-20T11:45:44.0252020-05:00 0HL481DO0HIVU [DBG] Connection id ""0HL481DNUOBH7"" completed keep alive response. (9784cde9) 2017-04-20T11:45:44.0252840-05:00 0HL481DO0HIVU [INF] Request finished in 3.5368ms 304 text/html (15c52c40) 2017-04-20T11:45:44.0272240-05:00 [DBG] Connection id ""0HL481DNUOBH6"" received FIN. (acf58720) 2017-04-20T11:45:44.0331880-05:00 0HL481DO0HIVV [INF] Request starting HTTP/1.1 GET http://localhost:5000/main.js (e5be5b71) 2017-04-20T11:45:44.0766880-05:00 0HL481DO0HIVV [DBG] Connection id ""0HL481DNUOBH7"" completed keep alive response. (9784cde9) 2017-04-20T11:45:44.0768270-05:00 0HL481DO0HIVV [INF] Request finished in 43.6235ms 200 application/javascript; charset=UTF-8 (15c52c40) 2017-04-20T11:45:44.2229510-05:00 0HL481DO0HJ00 [INF] Request starting HTTP/1.1 GET http://localhost:5000/__webpack_hmr (e5be5b71) 2017-04-20T11:45:44.2441810-05:00 [INF] Connection id ""0HL481DNUOBH6"" communication error. (7fa6c29c) Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvException: Error -32 EPIPE broken pipe 2017-04-20T11:45:44.2441810-05:00 [DBG] Connection id ""0HL481DNUOBH6"" disconnecting. (b29b9868) 2017-04-20T11:45:44.2445160-05:00 [DBG] Connection id ""0HL481DNUOBH6"" stopped. (056149f8) 2017-04-20T11:45:47.6464490-05:00 [DBG] Connection id ""0HL481DNUOBH8"" started. (1426b994) 2017-04-20T11:45:47.6466580-05:00 0HL481DO0HJ01 [INF] Request starting HTTP/1.1 POST http://localhost:5000/api/auth/register application/x-www-form-urlencoded 41 (e5be5b71) 2017-04-20T11:45:47.6479610-05:00 0HL481DO0HJ01 [INF] Handling request: /api/auth/register (2c1017b8) 2017-04-20T11:45:47.6480340-05:00 0HL481DO0HJ01 [DBG] "POST" requests are not supported (1c759b4c) 2017-04-20T11:45:47.6499000-05:00 0HL481DO0HJ01 [INF] "Bearer" was not authenticated. Failure message: "Authentication failed because the access token was invalid." (48071232) 2017-04-20T11:45:47.6499920-05:00 0HL481DO0HJ01 [INF] "Bearer" was not authenticated. Failure message: "No SecurityTokenValidator available for token: undefined" (48071232) 2017-04-20T11:45:47.6501160-05:00 0HL481DO0HJ01 [DBG] Request successfully matched the route with name 'null' and template '"api/auth/register"'. (555ac2ba) 2017-04-20T11:45:47.6501750-05:00 0HL481DO0HJ01 [DBG] Executing action "aspnetCoreReactTemplate.aspnetCoreReactTemplate.Controllers.AuthController.Register (api)" (3f3ef15a) 2017-04-20T11:45:47.6504120-05:00 0HL481DO0HJ01 [INF] Executing action method "aspnetCoreReactTemplate.aspnetCoreReactTemplate.Controllers.AuthController.Register (api)" with arguments (["aspnetCoreReactTemplate.ViewModels.NewUser"]) - ModelState is Valid (ba7f4ac2) 2017-04-20T11:45:47.6704730-05:00 0HL481DO0HJ01 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:45:47.6722490-05:00 0HL481DO0HJ01 [INF] Executed DbCommand (1ms) [Parameters=[@__normalizedUserName_0='?'], CommandType='Text', CommandTimeout='30'] SELECT "u"."Id", "u"."AccessFailedCount", "u"."ConcurrencyStamp", "u"."Email", "u"."EmailConfirmed", "u"."GivenName", "u"."LockoutEnabled", "u"."LockoutEnd", "u"."NormalizedEmail", "u"."NormalizedUserName", "u"."PasswordHash", "u"."PhoneNumber", "u"."PhoneNumberConfirmed", "u"."SecurityStamp", "u"."TwoFactorEnabled", "u"."UserName" FROM "AspNetUsers" AS "u" WHERE "u"."NormalizedUserName" = @__normalizedUserName_0 LIMIT 1 (6438bdd5) 2017-04-20T11:45:47.6724530-05:00 0HL481DO0HJ01 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:45:47.6726710-05:00 0HL481DO0HJ01 [WRN] User "56e5f22f-fe8e-48e6-948b-df981b56a516" validation failed: "DuplicateUserName". (5dc28e15) 2017-04-20T11:45:47.6727610-05:00 0HL481DO0HJ01 [DBG] Executed action method "aspnetCoreReactTemplate.aspnetCoreReactTemplate.Controllers.AuthController.Register (api)", returned result "Microsoft.AspNetCore.Mvc.BadRequestObjectResult". (f72615e0) 2017-04-20T11:45:47.6728260-05:00 0HL481DO0HJ01 [DBG] No information found on request to perform content negotiation. (6aec0ec5) 2017-04-20T11:45:47.6728740-05:00 0HL481DO0HJ01 [DBG] Selected output formatter '"Microsoft.AspNetCore.Mvc.Formatters.JsonOutputFormatter"' and content type '"application/json"' to write the response. (fcc32779) 2017-04-20T11:45:47.6729030-05:00 0HL481DO0HJ01 [INF] Executing ObjectResult, writing value "Microsoft.AspNetCore.Mvc.ControllerContext". (4e968210) 2017-04-20T11:45:47.6730350-05:00 0HL481DO0HJ01 [INF] Executed action "aspnetCoreReactTemplate.aspnetCoreReactTemplate.Controllers.AuthController.Register (api)" in 22.8055ms (afa2e885) 2017-04-20T11:45:47.6731460-05:00 0HL481DO0HJ01 [INF] Finished handling request. (d2c25297) 2017-04-20T11:45:47.6732390-05:00 0HL481DO0HJ01 [DBG] Connection id ""0HL481DNUOBH8"" completed keep alive response. (9784cde9) 2017-04-20T11:45:47.6733630-05:00 0HL481DO0HJ01 [INF] Request finished in 26.7243ms 400 application/json; charset=utf-8 (15c52c40) 2017-04-20T11:46:32.0935980-05:00 [DBG] Connection id ""0HL481DNUOBH7"" received FIN. (acf58720) 2017-04-20T11:46:44.7399420-05:00 [INF] Connection id ""0HL481DNUOBH7"" communication error. (7fa6c29c) Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvException: Error -32 EPIPE broken pipe 2017-04-20T11:46:44.7399420-05:00 [DBG] Connection id ""0HL481DNUOBH7"" disconnecting. (b29b9868) 2017-04-20T11:46:44.7401040-05:00 [DBG] Connection id ""0HL481DNUOBH7"" stopped. (056149f8) 2017-04-20T11:47:49.3103430-05:00 [DBG] Connection id ""0HL481DNUOBH8"" disconnecting. (b29b9868) 2017-04-20T11:47:49.3104560-05:00 [DBG] Connection id ""0HL481DNUOBH8"" sending FIN. (ffb251f5) 2017-04-20T11:47:49.3105770-05:00 [DBG] Connection id ""0HL481DNUOBH8"" sent FIN with status "0". (69d90ca7) 2017-04-20T11:47:49.3106450-05:00 [DBG] Connection id ""0HL481DNUOBH8"" stopped. (056149f8) 2017-04-20T11:52:20.1843890-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:52:20.2332790-05:00 [INF] Executed DbCommand (12ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT EXISTS (SELECT 1 FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace WHERE c.relname='__EFMigrationsHistory'); (6438bdd5) 2017-04-20T11:52:20.2351180-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:52:20.2481480-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:52:20.2500520-05:00 [INF] Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT EXISTS (SELECT 1 FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace WHERE c.relname='__EFMigrationsHistory'); (6438bdd5) 2017-04-20T11:52:20.2501960-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:52:20.2571800-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:52:20.2592600-05:00 [INF] Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT "MigrationId", "ProductVersion" FROM "__EFMigrationsHistory" ORDER BY "MigrationId"; (6438bdd5) 2017-04-20T11:52:20.2599360-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:52:20.6921930-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:52:20.9067920-05:00 [INF] Executed DbCommand (80ms) [Parameters=[@__normalizedEmail_0='?'], CommandType='Text', CommandTimeout='30'] SELECT "u"."Id", "u"."AccessFailedCount", "u"."ConcurrencyStamp", "u"."Email", "u"."EmailConfirmed", "u"."GivenName", "u"."LockoutEnabled", "u"."LockoutEnd", "u"."NormalizedEmail", "u"."NormalizedUserName", "u"."PasswordHash", "u"."PhoneNumber", "u"."PhoneNumberConfirmed", "u"."SecurityStamp", "u"."TwoFactorEnabled", "u"."UserName" FROM "AspNetUsers" AS "u" WHERE "u"."NormalizedEmail" = @__normalizedEmail_0 LIMIT 1 (6438bdd5) 2017-04-20T11:52:20.9730240-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:52:21.0340690-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:52:21.0403040-05:00 [INF] Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT CASE WHEN EXISTS ( SELECT 1 FROM "Contacts" AS "c") THEN TRUE::bool ELSE FALSE::bool END (6438bdd5) 2017-04-20T11:52:21.0413620-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:52:21.0642120-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:52:21.0653390-05:00 [INF] Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT "c"."contactId", "c"."email", "c"."name", "c"."phone" FROM "Contacts" AS "c" (6438bdd5) 2017-04-20T11:52:21.0931910-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:52:21.1567550-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:52:21.1638260-05:00 [DBG] Beginning transaction with isolation level 'Unspecified'. (3b5ca34b) 2017-04-20T11:52:21.2243800-05:00 [INF] Executed DbCommand (4ms) [Parameters=[@p0='?', @p1='?', @p2='?', @p3='?', @p4='?', @p5='?', @p6='?', @p7='?'], CommandType='Text', CommandTimeout='30'] DELETE FROM "Contacts" WHERE "contactId" = @p0; DELETE FROM "Contacts" WHERE "contactId" = @p1; INSERT INTO "Contacts" ("email", "name", "phone") VALUES (@p2, @p3, @p4) RETURNING "contactId"; INSERT INTO "Contacts" ("email", "name", "phone") VALUES (@p5, @p6, @p7) RETURNING "contactId"; (6438bdd5) 2017-04-20T11:52:21.2502520-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:52:22.7258160-05:00 [INF] ts-loader: Using typescript@2.2.2 and /Users/bholt/dev/aspnet-core-react-template/client-react/tsconfig.json (114b565e) 2017-04-20T11:52:22.8394760-05:00 [DBG] Hosting starting (32b26330) 2017-04-20T11:52:22.9107110-05:00 [DBG] Hosting started (e6def423) 2017-04-20T11:52:27.5521150-05:00 [INF] webpack built d5ef16186ce4d979a8ac in 5111ms (1f3d84b9) 2017-04-20T11:52:47.2953080-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:52:47.3580130-05:00 [INF] Executed DbCommand (19ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT EXISTS (SELECT 1 FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace WHERE c.relname='__EFMigrationsHistory'); (6438bdd5) 2017-04-20T11:52:47.3602790-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:52:47.3782690-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:52:47.3805780-05:00 [INF] Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT EXISTS (SELECT 1 FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace WHERE c.relname='__EFMigrationsHistory'); (6438bdd5) 2017-04-20T11:52:47.3806700-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:52:47.3875940-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:52:47.3896410-05:00 [INF] Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT "MigrationId", "ProductVersion" FROM "__EFMigrationsHistory" ORDER BY "MigrationId"; (6438bdd5) 2017-04-20T11:52:47.3902200-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:52:47.8297450-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:52:48.0395240-05:00 [INF] Executed DbCommand (75ms) [Parameters=[@__normalizedEmail_0='?'], CommandType='Text', CommandTimeout='30'] SELECT "u"."Id", "u"."AccessFailedCount", "u"."ConcurrencyStamp", "u"."Email", "u"."EmailConfirmed", "u"."GivenName", "u"."LockoutEnabled", "u"."LockoutEnd", "u"."NormalizedEmail", "u"."NormalizedUserName", "u"."PasswordHash", "u"."PhoneNumber", "u"."PhoneNumberConfirmed", "u"."SecurityStamp", "u"."TwoFactorEnabled", "u"."UserName" FROM "AspNetUsers" AS "u" WHERE "u"."NormalizedEmail" = @__normalizedEmail_0 LIMIT 1 (6438bdd5) 2017-04-20T11:52:48.1077930-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:52:48.1673110-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:52:48.1728720-05:00 [INF] Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT CASE WHEN EXISTS ( SELECT 1 FROM "Contacts" AS "c") THEN TRUE::bool ELSE FALSE::bool END (6438bdd5) 2017-04-20T11:52:48.1738080-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:52:48.1944370-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:52:48.1957490-05:00 [INF] Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT "c"."contactId", "c"."email", "c"."name", "c"."phone" FROM "Contacts" AS "c" (6438bdd5) 2017-04-20T11:52:48.2256620-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:52:48.2887970-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:52:48.2950040-05:00 [DBG] Beginning transaction with isolation level 'Unspecified'. (3b5ca34b) 2017-04-20T11:52:48.3600290-05:00 [INF] Executed DbCommand (4ms) [Parameters=[@p0='?', @p1='?', @p2='?', @p3='?', @p4='?', @p5='?', @p6='?', @p7='?'], CommandType='Text', CommandTimeout='30'] DELETE FROM "Contacts" WHERE "contactId" = @p0; DELETE FROM "Contacts" WHERE "contactId" = @p1; INSERT INTO "Contacts" ("email", "name", "phone") VALUES (@p2, @p3, @p4) RETURNING "contactId"; INSERT INTO "Contacts" ("email", "name", "phone") VALUES (@p5, @p6, @p7) RETURNING "contactId"; (6438bdd5) 2017-04-20T11:52:48.3845130-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:52:49.8241640-05:00 [INF] ts-loader: Using typescript@2.2.2 and /Users/bholt/dev/aspnet-core-react-template/client-react/tsconfig.json (114b565e) 2017-04-20T11:52:49.9339700-05:00 [DBG] Hosting starting (32b26330) 2017-04-20T11:52:50.0188480-05:00 [DBG] Hosting started (e6def423) 2017-04-20T11:52:55.0134310-05:00 [INF] webpack built d5ef16186ce4d979a8ac in 5531ms (b9c85d60) 2017-04-20T11:54:37.8666580-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:54:37.9142260-05:00 [INF] Executed DbCommand (13ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT EXISTS (SELECT 1 FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace WHERE c.relname='__EFMigrationsHistory'); (6438bdd5) 2017-04-20T11:54:37.9161890-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:54:37.9289630-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:54:37.9304160-05:00 [INF] Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT EXISTS (SELECT 1 FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace WHERE c.relname='__EFMigrationsHistory'); (6438bdd5) 2017-04-20T11:54:37.9304990-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:54:37.9374140-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:54:37.9396900-05:00 [INF] Executed DbCommand (2ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT "MigrationId", "ProductVersion" FROM "__EFMigrationsHistory" ORDER BY "MigrationId"; (6438bdd5) 2017-04-20T11:54:37.9402820-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:54:38.3839950-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:54:38.6121920-05:00 [INF] Executed DbCommand (77ms) [Parameters=[@__normalizedEmail_0='?'], CommandType='Text', CommandTimeout='30'] SELECT "u"."Id", "u"."AccessFailedCount", "u"."ConcurrencyStamp", "u"."Email", "u"."EmailConfirmed", "u"."GivenName", "u"."LockoutEnabled", "u"."LockoutEnd", "u"."NormalizedEmail", "u"."NormalizedUserName", "u"."PasswordHash", "u"."PhoneNumber", "u"."PhoneNumberConfirmed", "u"."SecurityStamp", "u"."TwoFactorEnabled", "u"."UserName" FROM "AspNetUsers" AS "u" WHERE "u"."NormalizedEmail" = @__normalizedEmail_0 LIMIT 1 (6438bdd5) 2017-04-20T11:54:38.6732720-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:54:38.7260900-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:54:38.7327780-05:00 [INF] Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT CASE WHEN EXISTS ( SELECT 1 FROM "Contacts" AS "c") THEN TRUE::bool ELSE FALSE::bool END (6438bdd5) 2017-04-20T11:54:38.7341370-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:54:38.7549120-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:54:38.7562400-05:00 [INF] Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT "c"."contactId", "c"."email", "c"."name", "c"."phone" FROM "Contacts" AS "c" (6438bdd5) 2017-04-20T11:54:38.7832790-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:54:38.8424430-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:54:38.8480970-05:00 [DBG] Beginning transaction with isolation level 'Unspecified'. (3b5ca34b) 2017-04-20T11:54:38.9072120-05:00 [INF] Executed DbCommand (5ms) [Parameters=[@p0='?', @p1='?', @p2='?', @p3='?', @p4='?', @p5='?', @p6='?', @p7='?'], CommandType='Text', CommandTimeout='30'] DELETE FROM "Contacts" WHERE "contactId" = @p0; DELETE FROM "Contacts" WHERE "contactId" = @p1; INSERT INTO "Contacts" ("email", "name", "phone") VALUES (@p2, @p3, @p4) RETURNING "contactId"; INSERT INTO "Contacts" ("email", "name", "phone") VALUES (@p5, @p6, @p7) RETURNING "contactId"; (6438bdd5) 2017-04-20T11:54:38.9331130-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:54:40.1053810-05:00 [INF] ts-loader: Using typescript@2.2.2 and /Users/bholt/dev/aspnet-core-react-template/client-react/tsconfig.json (114b565e) 2017-04-20T11:54:40.2924400-05:00 [DBG] Hosting starting (32b26330) 2017-04-20T11:54:40.3627690-05:00 [DBG] Hosting started (e6def423) 2017-04-20T11:54:50.6248200-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:54:50.6718600-05:00 [INF] Executed DbCommand (12ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT EXISTS (SELECT 1 FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace WHERE c.relname='__EFMigrationsHistory'); (6438bdd5) 2017-04-20T11:54:50.6737260-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:54:50.6870270-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:54:50.6895530-05:00 [INF] Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT EXISTS (SELECT 1 FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace WHERE c.relname='__EFMigrationsHistory'); (6438bdd5) 2017-04-20T11:54:50.6896620-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:54:50.6964780-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:54:50.6985020-05:00 [INF] Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT "MigrationId", "ProductVersion" FROM "__EFMigrationsHistory" ORDER BY "MigrationId"; (6438bdd5) 2017-04-20T11:54:50.6991060-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:54:51.1002400-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:54:51.3094630-05:00 [INF] Executed DbCommand (72ms) [Parameters=[@__normalizedEmail_0='?'], CommandType='Text', CommandTimeout='30'] SELECT "u"."Id", "u"."AccessFailedCount", "u"."ConcurrencyStamp", "u"."Email", "u"."EmailConfirmed", "u"."GivenName", "u"."LockoutEnabled", "u"."LockoutEnd", "u"."NormalizedEmail", "u"."NormalizedUserName", "u"."PasswordHash", "u"."PhoneNumber", "u"."PhoneNumberConfirmed", "u"."SecurityStamp", "u"."TwoFactorEnabled", "u"."UserName" FROM "AspNetUsers" AS "u" WHERE "u"."NormalizedEmail" = @__normalizedEmail_0 LIMIT 1 (6438bdd5) 2017-04-20T11:54:51.3715670-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:54:51.4247370-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:54:51.4297140-05:00 [INF] Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT CASE WHEN EXISTS ( SELECT 1 FROM "Contacts" AS "c") THEN TRUE::bool ELSE FALSE::bool END (6438bdd5) 2017-04-20T11:54:51.4310560-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:54:51.4494260-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:54:51.4508040-05:00 [INF] Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT "c"."contactId", "c"."email", "c"."name", "c"."phone" FROM "Contacts" AS "c" (6438bdd5) 2017-04-20T11:54:51.4763700-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:54:51.5366480-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:54:51.5426550-05:00 [DBG] Beginning transaction with isolation level 'Unspecified'. (3b5ca34b) 2017-04-20T11:54:51.6043500-05:00 [INF] Executed DbCommand (5ms) [Parameters=[@p0='?', @p1='?', @p2='?', @p3='?', @p4='?', @p5='?', @p6='?', @p7='?'], CommandType='Text', CommandTimeout='30'] DELETE FROM "Contacts" WHERE "contactId" = @p0; DELETE FROM "Contacts" WHERE "contactId" = @p1; INSERT INTO "Contacts" ("email", "name", "phone") VALUES (@p2, @p3, @p4) RETURNING "contactId"; INSERT INTO "Contacts" ("email", "name", "phone") VALUES (@p5, @p6, @p7) RETURNING "contactId"; (6438bdd5) 2017-04-20T11:54:51.6280460-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:54:52.8274950-05:00 [INF] ts-loader: Using typescript@2.2.2 and /Users/bholt/dev/aspnet-core-react-template/client-react/tsconfig.json (114b565e) 2017-04-20T11:54:52.8352330-05:00 [DBG] Hosting starting (32b26330) 2017-04-20T11:54:52.9060220-05:00 [DBG] Hosting started (e6def423) 2017-04-20T11:54:57.5428390-05:00 [INF] webpack built d5ef16186ce4d979a8ac in 4979ms (b9b435f5) 2017-04-20T11:55:53.0172200-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:55:53.0730740-05:00 [INF] Executed DbCommand (13ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT EXISTS (SELECT 1 FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace WHERE c.relname='__EFMigrationsHistory'); (6438bdd5) 2017-04-20T11:55:53.0748940-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:55:53.0888600-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:55:53.0904870-05:00 [INF] Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT EXISTS (SELECT 1 FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace WHERE c.relname='__EFMigrationsHistory'); (6438bdd5) 2017-04-20T11:55:53.0906000-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:55:53.0971490-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:55:53.0988070-05:00 [INF] Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT "MigrationId", "ProductVersion" FROM "__EFMigrationsHistory" ORDER BY "MigrationId"; (6438bdd5) 2017-04-20T11:55:53.0993710-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:55:53.5183410-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:55:53.7221070-05:00 [INF] Executed DbCommand (70ms) [Parameters=[@__normalizedEmail_0='?'], CommandType='Text', CommandTimeout='30'] SELECT "u"."Id", "u"."AccessFailedCount", "u"."ConcurrencyStamp", "u"."Email", "u"."EmailConfirmed", "u"."GivenName", "u"."LockoutEnabled", "u"."LockoutEnd", "u"."NormalizedEmail", "u"."NormalizedUserName", "u"."PasswordHash", "u"."PhoneNumber", "u"."PhoneNumberConfirmed", "u"."SecurityStamp", "u"."TwoFactorEnabled", "u"."UserName" FROM "AspNetUsers" AS "u" WHERE "u"."NormalizedEmail" = @__normalizedEmail_0 LIMIT 1 (6438bdd5) 2017-04-20T11:55:53.7940560-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:55:53.8483900-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:55:53.8535630-05:00 [INF] Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT CASE WHEN EXISTS ( SELECT 1 FROM "Contacts" AS "c") THEN TRUE::bool ELSE FALSE::bool END (6438bdd5) 2017-04-20T11:55:53.8547220-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:55:53.8735420-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:55:53.8749900-05:00 [INF] Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT "c"."contactId", "c"."email", "c"."name", "c"."phone" FROM "Contacts" AS "c" (6438bdd5) 2017-04-20T11:55:53.9024970-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:55:53.9601450-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:55:53.9665450-05:00 [DBG] Beginning transaction with isolation level 'Unspecified'. (3b5ca34b) 2017-04-20T11:55:54.0287680-05:00 [INF] Executed DbCommand (4ms) [Parameters=[@p0='?', @p1='?', @p2='?', @p3='?', @p4='?', @p5='?', @p6='?', @p7='?'], CommandType='Text', CommandTimeout='30'] DELETE FROM "Contacts" WHERE "contactId" = @p0; DELETE FROM "Contacts" WHERE "contactId" = @p1; INSERT INTO "Contacts" ("email", "name", "phone") VALUES (@p2, @p3, @p4) RETURNING "contactId"; INSERT INTO "Contacts" ("email", "name", "phone") VALUES (@p5, @p6, @p7) RETURNING "contactId"; (6438bdd5) 2017-04-20T11:55:54.0585200-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T11:55:55.2623320-05:00 [DBG] Hosting starting (32b26330) 2017-04-20T11:55:55.2623220-05:00 [INF] ts-loader: Using typescript@2.2.2 and /Users/bholt/dev/aspnet-core-react-template/client-react/tsconfig.json (114b565e) 2017-04-20T11:55:55.3342570-05:00 [DBG] Hosting started (e6def423) 2017-04-20T11:56:00.1801500-05:00 [INF] webpack built d5ef16186ce4d979a8ac in 5200ms (956f4986) 2017-04-20T12:00:22.4181940-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T12:00:22.4677210-05:00 [INF] Executed DbCommand (13ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT EXISTS (SELECT 1 FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace WHERE c.relname='__EFMigrationsHistory'); (6438bdd5) 2017-04-20T12:00:22.4696350-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T12:00:22.4831110-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T12:00:22.4846130-05:00 [INF] Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT EXISTS (SELECT 1 FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace WHERE c.relname='__EFMigrationsHistory'); (6438bdd5) 2017-04-20T12:00:22.4847230-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T12:00:22.4915870-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T12:00:22.4937610-05:00 [INF] Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT "MigrationId", "ProductVersion" FROM "__EFMigrationsHistory" ORDER BY "MigrationId"; (6438bdd5) 2017-04-20T12:00:22.4944190-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T12:00:22.9182370-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T12:00:23.1413910-05:00 [INF] Executed DbCommand (84ms) [Parameters=[@__normalizedEmail_0='?'], CommandType='Text', CommandTimeout='30'] SELECT "u"."Id", "u"."AccessFailedCount", "u"."ConcurrencyStamp", "u"."Email", "u"."EmailConfirmed", "u"."GivenName", "u"."LockoutEnabled", "u"."LockoutEnd", "u"."NormalizedEmail", "u"."NormalizedUserName", "u"."PasswordHash", "u"."PhoneNumber", "u"."PhoneNumberConfirmed", "u"."SecurityStamp", "u"."TwoFactorEnabled", "u"."UserName" FROM "AspNetUsers" AS "u" WHERE "u"."NormalizedEmail" = @__normalizedEmail_0 LIMIT 1 (6438bdd5) 2017-04-20T12:00:23.2110220-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T12:00:23.2746920-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T12:00:23.2808440-05:00 [INF] Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT CASE WHEN EXISTS ( SELECT 1 FROM "Contacts" AS "c") THEN TRUE::bool ELSE FALSE::bool END (6438bdd5) 2017-04-20T12:00:23.2819780-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T12:00:23.3029210-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T12:00:23.3043030-05:00 [INF] Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT "c"."contactId", "c"."email", "c"."name", "c"."phone" FROM "Contacts" AS "c" (6438bdd5) 2017-04-20T12:00:23.3355490-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T12:00:23.4000400-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T12:00:23.4061710-05:00 [DBG] Beginning transaction with isolation level 'Unspecified'. (3b5ca34b) 2017-04-20T12:00:23.4717800-05:00 [INF] Executed DbCommand (4ms) [Parameters=[@p0='?', @p1='?', @p2='?', @p3='?', @p4='?', @p5='?', @p6='?', @p7='?'], CommandType='Text', CommandTimeout='30'] DELETE FROM "Contacts" WHERE "contactId" = @p0; DELETE FROM "Contacts" WHERE "contactId" = @p1; INSERT INTO "Contacts" ("email", "name", "phone") VALUES (@p2, @p3, @p4) RETURNING "contactId"; INSERT INTO "Contacts" ("email", "name", "phone") VALUES (@p5, @p6, @p7) RETURNING "contactId"; (6438bdd5) 2017-04-20T12:00:23.4978960-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T12:00:25.0319380-05:00 [INF] ts-loader: Using typescript@2.2.2 and /Users/bholt/dev/aspnet-core-react-template/client-react/tsconfig.json (114b565e) 2017-04-20T12:00:25.1801430-05:00 [DBG] Hosting starting (32b26330) 2017-04-20T12:00:25.2532920-05:00 [DBG] Hosting started (e6def423) 2017-04-20T12:00:29.8988860-05:00 [INF] webpack built d5ef16186ce4d979a8ac in 5161ms (08a05fce) 2017-04-20T12:00:41.9349910-05:00 [INF] Received SIGINT. Waiting for .NET process to exit... (39e2bf0e) 2017-04-20T12:00:41.9382870-05:00 [DBG] Hosting shutdown (49005419) 2017-04-20T12:03:38.5101220-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T12:03:38.5572210-05:00 [INF] Executed DbCommand (12ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT EXISTS (SELECT 1 FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace WHERE c.relname='__EFMigrationsHistory'); (6438bdd5) 2017-04-20T12:03:38.5590790-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T12:03:38.5721740-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T12:03:38.5734910-05:00 [INF] Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT EXISTS (SELECT 1 FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace WHERE c.relname='__EFMigrationsHistory'); (6438bdd5) 2017-04-20T12:03:38.5735800-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T12:03:38.5807060-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T12:03:38.5824650-05:00 [INF] Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT "MigrationId", "ProductVersion" FROM "__EFMigrationsHistory" ORDER BY "MigrationId"; (6438bdd5) 2017-04-20T12:03:38.5831840-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T12:03:38.9784220-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T12:03:39.1762800-05:00 [INF] Executed DbCommand (72ms) [Parameters=[@__normalizedEmail_0='?'], CommandType='Text', CommandTimeout='30'] SELECT "u"."Id", "u"."AccessFailedCount", "u"."ConcurrencyStamp", "u"."Email", "u"."EmailConfirmed", "u"."GivenName", "u"."LockoutEnabled", "u"."LockoutEnd", "u"."NormalizedEmail", "u"."NormalizedUserName", "u"."PasswordHash", "u"."PhoneNumber", "u"."PhoneNumberConfirmed", "u"."SecurityStamp", "u"."TwoFactorEnabled", "u"."UserName" FROM "AspNetUsers" AS "u" WHERE "u"."NormalizedEmail" = @__normalizedEmail_0 LIMIT 1 (6438bdd5) 2017-04-20T12:03:39.2326690-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T12:03:39.2856610-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T12:03:39.2914480-05:00 [INF] Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT CASE WHEN EXISTS ( SELECT 1 FROM "Contacts" AS "c") THEN TRUE::bool ELSE FALSE::bool END (6438bdd5) 2017-04-20T12:03:39.2925420-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T12:03:39.3124240-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T12:03:39.3137460-05:00 [INF] Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT "c"."contactId", "c"."email", "c"."name", "c"."phone" FROM "Contacts" AS "c" (6438bdd5) 2017-04-20T12:03:39.3442980-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T12:03:39.4031530-05:00 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T12:03:39.4095790-05:00 [DBG] Beginning transaction with isolation level 'Unspecified'. (3b5ca34b) 2017-04-20T12:03:39.4732710-05:00 [INF] Executed DbCommand (4ms) [Parameters=[@p0='?', @p1='?', @p2='?', @p3='?', @p4='?', @p5='?', @p6='?', @p7='?'], CommandType='Text', CommandTimeout='30'] DELETE FROM "Contacts" WHERE "contactId" = @p0; DELETE FROM "Contacts" WHERE "contactId" = @p1; INSERT INTO "Contacts" ("email", "name", "phone") VALUES (@p2, @p3, @p4) RETURNING "contactId"; INSERT INTO "Contacts" ("email", "name", "phone") VALUES (@p5, @p6, @p7) RETURNING "contactId"; (6438bdd5) 2017-04-20T12:03:39.4988230-05:00 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T12:03:40.6756750-05:00 [INF] ts-loader: Using typescript@2.2.2 and /Users/bholt/dev/aspnet-core-react-template/client-react/tsconfig.json (114b565e) 2017-04-20T12:03:40.7047630-05:00 [DBG] Hosting starting (32b26330) 2017-04-20T12:03:40.7724530-05:00 [DBG] Hosting started (e6def423) 2017-04-20T12:03:45.4096500-05:00 [INF] webpack built ad079844fd07da916916 in 4997ms (4aff4f6d) 2017-04-20T12:03:47.5948830-05:00 [DBG] Connection id ""0HL481SQTVFU1"" started. (1426b994) 2017-04-20T12:03:47.9383650-05:00 0HL481SR1D5UL [INF] Request starting HTTP/1.1 GET http://localhost:5000/ (e5be5b71) 2017-04-20T12:03:48.0400040-05:00 0HL481SR1D5UL [DBG] Connection id ""0HL481SQTVFU1"" completed keep alive response. (9784cde9) 2017-04-20T12:03:48.0498140-05:00 0HL481SR1D5UL [INF] Request finished in 122.973ms 200 text/html; charset=UTF-8 (15c52c40) 2017-04-20T12:03:48.0553960-05:00 0HL481SR1D5UM [INF] Request starting HTTP/1.1 GET http://localhost:5000/main.js (e5be5b71) 2017-04-20T12:03:48.1681380-05:00 0HL481SR1D5UM [DBG] Connection id ""0HL481SQTVFU1"" completed keep alive response. (9784cde9) 2017-04-20T12:03:48.1682940-05:00 0HL481SR1D5UM [INF] Request finished in 112.8857ms 200 application/javascript; charset=UTF-8 (15c52c40) 2017-04-20T12:03:48.3202130-05:00 [DBG] Connection id ""0HL481SQTVFU2"" started. (1426b994) 2017-04-20T12:03:48.3205310-05:00 0HL481SR1D5UN [INF] Request starting HTTP/1.1 GET http://localhost:5000/api/contacts (e5be5b71) 2017-04-20T12:03:48.3448840-05:00 0HL481SR1D5UN [INF] Handling request: /api/contacts (629acf5c) 2017-04-20T12:03:48.3568930-05:00 0HL481SR1D5UO [INF] Request starting HTTP/1.1 GET http://localhost:5000/__webpack_hmr (e5be5b71) 2017-04-20T12:03:48.3576260-05:00 0HL481SR1D5UN [DBG] The request path "/api/contacts" does not match a supported file type (4910e68e) 2017-04-20T12:03:48.4058830-05:00 0HL481SR1D5UN [INF] "Bearer" was not authenticated. Failure message: "Authentication failed because the access token was invalid." (48071232) 2017-04-20T12:03:48.4486980-05:00 [DBG] Connection id ""0HL481SQTVFU3"" started. (1426b994) 2017-04-20T12:03:48.4489960-05:00 0HL481SR1D5UP [INF] Request starting HTTP/1.1 GET http://localhost:5000/.well-known/openid-configuration (e5be5b71) 2017-04-20T12:03:48.4505430-05:00 0HL481SR1D5UP [INF] Handling request: /.well-known/openid-configuration (28f0d040) 2017-04-20T12:03:48.4529540-05:00 0HL481SR1D5UP [DBG] The request path "/.well-known/openid-configuration" does not match a supported file type (4910e68e) 2017-04-20T12:03:48.4534470-05:00 0HL481SR1D5UP [DBG] Authentication was skipped because no bearer token was received. (9de85986) 2017-04-20T12:03:48.5033370-05:00 0HL481SR1D5UP [INF] The discovery request was successfully extracted from the HTTP request: "{}" (8eb39e75) 2017-04-20T12:03:48.5037540-05:00 0HL481SR1D5UP [INF] The discovery request was successfully validated. (5773bc23) 2017-04-20T12:03:48.5400880-05:00 0HL481SR1D5UP [INF] The discovery response was successfully returned: "{ \"issuer\": \"http://localhost:5000/\", \"token_endpoint\": \"http://localhost:5000/api/auth/login\", \"jwks_uri\": \"http://localhost:5000/.well-known/jwks\", \"grant_types_supported\": [ \"refresh_token\", \"password\" ], \"scopes_supported\": [ \"openid\", \"profile\", \"email\", \"phone\", \"roles\", \"offline_access\" ], \"id_token_signing_alg_values_supported\": [ \"RS256\" ], \"subject_types_supported\": [ \"public\" ], \"token_endpoint_auth_methods_supported\": [ \"client_secret_basic\", \"client_secret_post\" ] }" (ee57d974) 2017-04-20T12:03:48.5825080-05:00 0HL481SR1D5UP [INF] Finished handling request. (d2c25297) 2017-04-20T12:03:48.5844190-05:00 0HL481SR1D5UP [DBG] Connection id ""0HL481SQTVFU3"" completed keep alive response. (9784cde9) 2017-04-20T12:03:48.5845260-05:00 0HL481SR1D5UP [INF] Request finished in 135.5407ms 200 application/json;charset=UTF-8 (15c52c40) 2017-04-20T12:03:48.6058940-05:00 0HL481SR1D5UQ [INF] Request starting HTTP/1.1 GET http://localhost:5000/.well-known/jwks (e5be5b71) 2017-04-20T12:03:48.6072710-05:00 0HL481SR1D5UQ [INF] Handling request: /.well-known/jwks (3092411e) 2017-04-20T12:03:48.6074590-05:00 0HL481SR1D5UQ [DBG] The request path "/.well-known/jwks" does not match a supported file type (4910e68e) 2017-04-20T12:03:48.6075200-05:00 0HL481SR1D5UQ [DBG] Authentication was skipped because no bearer token was received. (9de85986) 2017-04-20T12:03:48.6249250-05:00 0HL481SR1D5UQ [INF] The discovery request was successfully extracted from the HTTP request: "{}" (8eb39e75) 2017-04-20T12:03:48.6325910-05:00 0HL481SR1D5UQ [INF] The discovery response was successfully returned: "{ \"keys\": [ { \"kid\": \"YKN8_CMCU_FN-GLM7GYAZWQZXR8VSF63JSHNHSEG\", \"use\": \"sig\", \"kty\": \"RSA\", \"alg\": \"RS256\", \"e\": \"AQAB\", \"n\": \"yKN8_cmCU_fn-glM7gYaZwQzxR8VSF63JShnHsEGs9yGW8-0RzmsK9lL0wSk1fIs9qQy9jsDL0sonpy8pGcMVFkctE8lLORL_k_0ibh8mFhFhcm4UXistOCxEbMdTXv94PG6KiIzanDYez0wbZ3eHyzRsRDoTee62tdVG3c-j_TJg5Hn1Q5lWqZaunrf5EGYzFz6r2AjHBBwWcq_rbUeaH76ngrrMni7Aclc-Ab4gEwR6F8DMnWTflGJgAvQHGDzOgHmAaaIFcJDNd-H0h3JFG8PhX2wPjw1yZQxNGs3Wjpot5KIb9fmS_YhCrSMDaqdMnGKRbIqUv0GrmL23wlQKw\" } ] }" (ee57d974) 2017-04-20T12:03:48.6327880-05:00 0HL481SR1D5UQ [INF] Finished handling request. (d2c25297) 2017-04-20T12:03:48.6328560-05:00 0HL481SR1D5UQ [DBG] Connection id ""0HL481SQTVFU3"" completed keep alive response. (9784cde9) 2017-04-20T12:03:48.6329040-05:00 0HL481SR1D5UQ [INF] Request finished in 27.0548ms 200 application/json;charset=UTF-8 (15c52c40) 2017-04-20T12:03:48.6540530-05:00 0HL481SR1D5UN [INF] "Bearer" was not authenticated. Failure message: "No SecurityTokenValidator available for token: undefined" (48071232) 2017-04-20T12:03:48.9003550-05:00 0HL481SR1D5UN [DBG] Request successfully matched the route with name 'null' and template '"api/Contacts"'. (555ac2ba) 2017-04-20T12:03:48.9291670-05:00 0HL481SR1D5UN [DBG] Action '"aspnetCoreReactTemplate.Controllers.ContactsController.Post (api)"' with id '"455df96b-8ffd-4dea-957a-f523a47b3b25"' did not match the constraint '"Microsoft.AspNetCore.Mvc.Internal.HttpMethodActionConstraint"' (bdbe25b0) 2017-04-20T12:03:48.9549550-05:00 0HL481SR1D5UN [DBG] Executing action "aspnetCoreReactTemplate.Controllers.ContactsController.Get (api)" (3f3ef15a) 2017-04-20T12:03:48.9861310-05:00 0HL481SR1D5UN [INF] Authorization failed for user: null. (a4ab1676) 2017-04-20T12:03:48.9875910-05:00 0HL481SR1D5UN [INF] Authorization failed for the request at filter '"Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter"'. (8b6446cb) 2017-04-20T12:03:48.9936790-05:00 0HL481SR1D5UN [INF] Executing ChallengeResult with authentication schemes ([]). (f3dca807) 2017-04-20T12:03:49.0151770-05:00 0HL481SR1D5UN [INF] AuthenticationScheme: "Bearer" was challenged. (d45f1f38) 2017-04-20T12:03:49.0266850-05:00 0HL481SR1D5UN [INF] AuthenticationScheme: "Bearer" was challenged. (d45f1f38) 2017-04-20T12:03:49.0304770-05:00 0HL481SR1D5UN [INF] Executed action "aspnetCoreReactTemplate.Controllers.ContactsController.Get (api)" in 71.4524ms (afa2e885) 2017-04-20T12:03:49.0389200-05:00 0HL481SR1D5UN [INF] Finished handling request. (d2c25297) 2017-04-20T12:03:49.0415560-05:00 0HL481SR1D5UN [DBG] Connection id ""0HL481SQTVFU2"" completed keep alive response. (9784cde9) 2017-04-20T12:03:49.0417320-05:00 0HL481SR1D5UN [INF] Request finished in 721.201ms 401 (15c52c40) 2017-04-20T12:03:49.0556630-05:00 [DBG] Connection id ""0HL481SQTVFU4"" started. (1426b994) 2017-04-20T12:03:49.0559010-05:00 0HL481SR1D5UR [INF] Request starting HTTP/1.1 GET http://localhost:5000/sign-in/?expired=1 (e5be5b71) 2017-04-20T12:03:49.0575180-05:00 0HL481SR1D5UR [INF] Handling request: /sign-in/ (6455a65b) 2017-04-20T12:03:49.0591650-05:00 0HL481SR1D5UR [INF] Rewriting path: /sign-in/ > / (170f1f87) 2017-04-20T12:03:49.0780580-05:00 0HL481SR1D5UR [INF] Sending file. Request path: '"/index.html"'. Physical path: '"/Users/bholt/dev/aspnet-core-react-template/api/wwwroot/index.html"' (27b0a520) 2017-04-20T12:03:49.0940300-05:00 0HL481SR1D5UR [INF] Finished handling request. (d2c25297) 2017-04-20T12:03:49.0941480-05:00 0HL481SR1D5UR [DBG] Connection id ""0HL481SQTVFU4"" completed keep alive response. (9784cde9) 2017-04-20T12:03:49.0942190-05:00 0HL481SR1D5UR [INF] Request finished in 38.3498ms 200 text/html (15c52c40) 2017-04-20T12:03:49.0949780-05:00 [DBG] Connection id ""0HL481SQTVFU1"" received FIN. (acf58720) 2017-04-20T12:03:49.1001780-05:00 0HL481SR1D5US [INF] Request starting HTTP/1.1 GET http://localhost:5000/main.js (e5be5b71) 2017-04-20T12:03:49.1362530-05:00 0HL481SR1D5US [DBG] Connection id ""0HL481SQTVFU4"" completed keep alive response. (9784cde9) 2017-04-20T12:03:49.1363640-05:00 0HL481SR1D5US [INF] Request finished in 36.2062ms 200 application/javascript; charset=UTF-8 (15c52c40) 2017-04-20T12:03:49.2847120-05:00 0HL481SR1D5UT [INF] Request starting HTTP/1.1 GET http://localhost:5000/__webpack_hmr (e5be5b71) 2017-04-20T12:03:50.4215460-05:00 [INF] Connection id ""0HL481SQTVFU1"" communication error. (7fa6c29c) Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvException: Error -32 EPIPE broken pipe 2017-04-20T12:03:50.4217330-05:00 [INF] Connection id ""0HL481SQTVFU1"" communication error. (7fa6c29c) Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvException: Error -32 EPIPE broken pipe 2017-04-20T12:03:50.4224660-05:00 [DBG] Connection id ""0HL481SQTVFU1"" disconnecting. (b29b9868) 2017-04-20T12:03:50.4249090-05:00 [DBG] Connection id ""0HL481SQTVFU1"" stopped. (056149f8) 2017-04-20T12:03:55.5028440-05:00 0HL481SR1D5UU [INF] Request starting HTTP/1.1 POST http://localhost:5000/api/auth/register application/x-www-form-urlencoded 41 (e5be5b71) 2017-04-20T12:03:55.5043420-05:00 0HL481SR1D5UU [INF] Handling request: /api/auth/register (2c1017b8) 2017-04-20T12:03:55.5047010-05:00 0HL481SR1D5UU [DBG] "POST" requests are not supported (1c759b4c) 2017-04-20T12:03:55.5105050-05:00 0HL481SR1D5UU [INF] "Bearer" was not authenticated. Failure message: "Authentication failed because the access token was invalid." (48071232) 2017-04-20T12:03:55.5106420-05:00 0HL481SR1D5UU [INF] "Bearer" was not authenticated. Failure message: "No SecurityTokenValidator available for token: null" (48071232) 2017-04-20T12:03:55.5108000-05:00 0HL481SR1D5UU [DBG] Request successfully matched the route with name 'null' and template '"api/auth/register"'. (555ac2ba) 2017-04-20T12:03:55.5121460-05:00 0HL481SR1D5UU [DBG] Executing action "aspnetCoreReactTemplate.aspnetCoreReactTemplate.Controllers.AuthController.Register (api)" (3f3ef15a) 2017-04-20T12:03:55.7391590-05:00 0HL481SR1D5UU [INF] Executing action method "aspnetCoreReactTemplate.aspnetCoreReactTemplate.Controllers.AuthController.Register (api)" with arguments (["aspnetCoreReactTemplate.ViewModels.NewUser"]) - ModelState is Invalid (ba7f4ac2) 2017-04-20T12:03:55.7466260-05:00 0HL481SR1D5UU [DBG] Executed action method "aspnetCoreReactTemplate.aspnetCoreReactTemplate.Controllers.AuthController.Register (api)", returned result "Microsoft.AspNetCore.Mvc.BadRequestObjectResult". (f72615e0) 2017-04-20T12:03:55.7642750-05:00 0HL481SR1D5UU [DBG] No information found on request to perform content negotiation. (6aec0ec5) 2017-04-20T12:03:55.7679960-05:00 0HL481SR1D5UU [DBG] Selected output formatter '"Microsoft.AspNetCore.Mvc.Formatters.JsonOutputFormatter"' and content type '"application/json"' to write the response. (fcc32779) 2017-04-20T12:03:55.7682780-05:00 0HL481SR1D5UU [INF] Executing ObjectResult, writing value "Microsoft.AspNetCore.Mvc.ControllerContext". (4e968210) 2017-04-20T12:03:55.7937650-05:00 0HL481SR1D5UU [INF] Executed action "aspnetCoreReactTemplate.aspnetCoreReactTemplate.Controllers.AuthController.Register (api)" in 281.5072ms (afa2e885) 2017-04-20T12:03:55.7939070-05:00 0HL481SR1D5UU [INF] Finished handling request. (d2c25297) 2017-04-20T12:03:55.7970820-05:00 0HL481SR1D5UU [DBG] Connection id ""0HL481SQTVFU2"" completed keep alive response. (9784cde9) 2017-04-20T12:03:55.7971850-05:00 0HL481SR1D5UU [INF] Request finished in 294.7455ms 400 application/json; charset=utf-8 (15c52c40) 2017-04-20T12:03:58.5619700-05:00 0HL481SR1D5UV [INF] Request starting HTTP/1.1 POST http://localhost:5000/api/auth/register application/x-www-form-urlencoded 48 (e5be5b71) 2017-04-20T12:03:58.5634780-05:00 0HL481SR1D5UV [INF] Handling request: /api/auth/register (2c1017b8) 2017-04-20T12:03:58.5635650-05:00 0HL481SR1D5UV [DBG] "POST" requests are not supported (1c759b4c) 2017-04-20T12:03:58.5638350-05:00 0HL481SR1D5UV [INF] "Bearer" was not authenticated. Failure message: "Authentication failed because the access token was invalid." (48071232) 2017-04-20T12:03:58.5639610-05:00 0HL481SR1D5UV [INF] "Bearer" was not authenticated. Failure message: "No SecurityTokenValidator available for token: null" (48071232) 2017-04-20T12:03:58.5640900-05:00 0HL481SR1D5UV [DBG] Request successfully matched the route with name 'null' and template '"api/auth/register"'. (555ac2ba) 2017-04-20T12:03:58.5654830-05:00 0HL481SR1D5UV [DBG] Executing action "aspnetCoreReactTemplate.aspnetCoreReactTemplate.Controllers.AuthController.Register (api)" (3f3ef15a) 2017-04-20T12:03:58.5676940-05:00 0HL481SR1D5UV [INF] Executing action method "aspnetCoreReactTemplate.aspnetCoreReactTemplate.Controllers.AuthController.Register (api)" with arguments (["aspnetCoreReactTemplate.ViewModels.NewUser"]) - ModelState is Valid (ba7f4ac2) 2017-04-20T12:03:58.5927620-05:00 0HL481SR1D5UV [WRN] User "105b322c-970d-47d3-82bd-adb33459da80" password validation failed: "PasswordRequiresDigit;PasswordRequiresUpper". (2f223212) 2017-04-20T12:03:58.5940030-05:00 0HL481SR1D5UV [DBG] Executed action method "aspnetCoreReactTemplate.aspnetCoreReactTemplate.Controllers.AuthController.Register (api)", returned result "Microsoft.AspNetCore.Mvc.BadRequestObjectResult". (f72615e0) 2017-04-20T12:03:58.5942910-05:00 0HL481SR1D5UV [DBG] No information found on request to perform content negotiation. (6aec0ec5) 2017-04-20T12:03:58.5944090-05:00 0HL481SR1D5UV [DBG] Selected output formatter '"Microsoft.AspNetCore.Mvc.Formatters.JsonOutputFormatter"' and content type '"application/json"' to write the response. (fcc32779) 2017-04-20T12:03:58.5946160-05:00 0HL481SR1D5UV [INF] Executing ObjectResult, writing value "Microsoft.AspNetCore.Mvc.ControllerContext". (4e968210) 2017-04-20T12:03:58.5981060-05:00 0HL481SR1D5UV [INF] Executed action "aspnetCoreReactTemplate.aspnetCoreReactTemplate.Controllers.AuthController.Register (api)" in 32.5596ms (afa2e885) 2017-04-20T12:03:58.5982140-05:00 0HL481SR1D5UV [INF] Finished handling request. (d2c25297) 2017-04-20T12:03:58.5983680-05:00 0HL481SR1D5UV [DBG] Connection id ""0HL481SQTVFU2"" completed keep alive response. (9784cde9) 2017-04-20T12:03:58.5984560-05:00 0HL481SR1D5UV [INF] Request finished in 36.5465ms 400 application/json; charset=utf-8 (15c52c40) 2017-04-20T12:04:02.4319320-05:00 0HL481SR1D5V0 [INF] Request starting HTTP/1.1 POST http://localhost:5000/api/auth/register application/x-www-form-urlencoded 42 (e5be5b71) 2017-04-20T12:04:02.4333870-05:00 0HL481SR1D5V0 [INF] Handling request: /api/auth/register (2c1017b8) 2017-04-20T12:04:02.4335050-05:00 0HL481SR1D5V0 [DBG] "POST" requests are not supported (1c759b4c) 2017-04-20T12:04:02.4337520-05:00 0HL481SR1D5V0 [INF] "Bearer" was not authenticated. Failure message: "Authentication failed because the access token was invalid." (48071232) 2017-04-20T12:04:02.4338740-05:00 0HL481SR1D5V0 [INF] "Bearer" was not authenticated. Failure message: "No SecurityTokenValidator available for token: null" (48071232) 2017-04-20T12:04:02.4340060-05:00 0HL481SR1D5V0 [DBG] Request successfully matched the route with name 'null' and template '"api/auth/register"'. (555ac2ba) 2017-04-20T12:04:02.4341090-05:00 0HL481SR1D5V0 [DBG] Executing action "aspnetCoreReactTemplate.aspnetCoreReactTemplate.Controllers.AuthController.Register (api)" (3f3ef15a) 2017-04-20T12:04:02.4344650-05:00 0HL481SR1D5V0 [INF] Executing action method "aspnetCoreReactTemplate.aspnetCoreReactTemplate.Controllers.AuthController.Register (api)" with arguments (["aspnetCoreReactTemplate.ViewModels.NewUser"]) - ModelState is Valid (ba7f4ac2) 2017-04-20T12:04:02.5105070-05:00 0HL481SR1D5V0 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T12:04:02.5130100-05:00 0HL481SR1D5V0 [INF] Executed DbCommand (1ms) [Parameters=[@__normalizedUserName_0='?'], CommandType='Text', CommandTimeout='30'] SELECT "u"."Id", "u"."AccessFailedCount", "u"."ConcurrencyStamp", "u"."Email", "u"."EmailConfirmed", "u"."GivenName", "u"."LockoutEnabled", "u"."LockoutEnd", "u"."NormalizedEmail", "u"."NormalizedUserName", "u"."PasswordHash", "u"."PhoneNumber", "u"."PhoneNumberConfirmed", "u"."SecurityStamp", "u"."TwoFactorEnabled", "u"."UserName" FROM "AspNetUsers" AS "u" WHERE "u"."NormalizedUserName" = @__normalizedUserName_0 LIMIT 1 (6438bdd5) 2017-04-20T12:04:02.5135100-05:00 0HL481SR1D5V0 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T12:04:02.5546810-05:00 0HL481SR1D5V0 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T12:04:02.5548090-05:00 0HL481SR1D5V0 [DBG] Beginning transaction with isolation level 'Unspecified'. (3b5ca34b) 2017-04-20T12:04:02.5626250-05:00 0HL481SR1D5V0 [INF] Executed DbCommand (1ms) [Parameters=[@p0='?', @p1='?', @p2='?', @p3='?', @p4='?', @p5='?', @p6='?', @p7='?', @p8='?', @p9='?', @p10='?', @p11='?', @p12='?', @p13='?', @p14='?', @p15='?'], CommandType='Text', CommandTimeout='30'] INSERT INTO "AspNetUsers" ("Id", "AccessFailedCount", "ConcurrencyStamp", "Email", "EmailConfirmed", "GivenName", "LockoutEnabled", "LockoutEnd", "NormalizedEmail", "NormalizedUserName", "PasswordHash", "PhoneNumber", "PhoneNumberConfirmed", "SecurityStamp", "TwoFactorEnabled", "UserName") VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10, @p11, @p12, @p13, @p14, @p15); (6438bdd5) 2017-04-20T12:04:02.5720760-05:00 0HL481SR1D5V0 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T12:04:02.5739830-05:00 0HL481SR1D5V0 [INF] New user registered (id: 5314c967-f171-4f79-88f5-e75489da4d37) (ffbe08cf) 2017-04-20T12:04:02.5947020-05:00 0HL481SR1D5V0 [DBG] Reading data from file '"/Users/bholt/.aspnet/DataProtection-Keys/key-2115e1cc-6a7a-4f94-a5af-79045dd7268a.xml"'. (5ce001c4) 2017-04-20T12:04:02.5994620-05:00 0HL481SR1D5V0 [DBG] Reading data from file '"/Users/bholt/.aspnet/DataProtection-Keys/key-65a1dbdc-ff60-43d0-ad97-4b44b66d8604.xml"'. (5ce001c4) 2017-04-20T12:04:02.6046770-05:00 0HL481SR1D5V0 [DBG] Found key {2115e1cc-6a7a-4f94-a5af-79045dd7268a}. (f843275d) 2017-04-20T12:04:02.6110710-05:00 0HL481SR1D5V0 [DBG] Found key {65a1dbdc-ff60-43d0-ad97-4b44b66d8604}. (f843275d) 2017-04-20T12:04:02.6232370-05:00 0HL481SR1D5V0 [DBG] Considering key {2115e1cc-6a7a-4f94-a5af-79045dd7268a} with expiration date 2017-07-15 20:23:44Z as default key. (ca2e3b22) 2017-04-20T12:04:02.6380090-05:00 0HL481SR1D5V0 [DBG] Using managed symmetric algorithm '"System.Security.Cryptography.Aes"'. (0f299fe5) 2017-04-20T12:04:02.6389190-05:00 0HL481SR1D5V0 [DBG] Using managed keyed hash algorithm '"System.Security.Cryptography.HMACSHA256"'. (47d8f6fe) 2017-04-20T12:04:02.6506800-05:00 0HL481SR1D5V0 [DBG] Using key {2115e1cc-6a7a-4f94-a5af-79045dd7268a} as the default key. (4cf2d764) 2017-04-20T12:04:02.9026460-05:00 0HL481SR1D5V0 [INF] Sent email confirmation email (id: 5314c967-f171-4f79-88f5-e75489da4d37) (c5bc96c6) 2017-04-20T12:04:03.0144530-05:00 0HL481SR1D5V0 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T12:04:03.0172700-05:00 0HL481SR1D5V0 [INF] Executed DbCommand (1ms) [Parameters=[@__userId_0='?'], CommandType='Text', CommandTimeout='30'] SELECT "role"."Name" FROM "AspNetUserRoles" AS "userRole" INNER JOIN "AspNetRoles" AS "role" ON "userRole"."RoleId" = "role"."Id" WHERE "userRole"."UserId" = @__userId_0 (6438bdd5) 2017-04-20T12:04:03.0186440-05:00 0HL481SR1D5V0 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T12:04:03.0457040-05:00 0HL481SR1D5V0 [DBG] Opening connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T12:04:03.0474650-05:00 0HL481SR1D5V0 [INF] Executed DbCommand (1ms) [Parameters=[@__user_Id_0='?'], CommandType='Text', CommandTimeout='30'] SELECT "uc"."Id", "uc"."ClaimType", "uc"."ClaimValue", "uc"."UserId" FROM "AspNetUserClaims" AS "uc" WHERE "uc"."UserId" = @__user_Id_0 (6438bdd5) 2017-04-20T12:04:03.0476680-05:00 0HL481SR1D5V0 [DBG] Closing connection to database 'dotnetcore' on server 'tcp://localhost:5433'. (3b5ca34b) 2017-04-20T12:04:03.0565200-05:00 0HL481SR1D5V0 [INF] User logged in (id: 5314c967-f171-4f79-88f5-e75489da4d37) (d87185fb) 2017-04-20T12:04:03.0567800-05:00 0HL481SR1D5V0 [DBG] Executed action method "aspnetCoreReactTemplate.aspnetCoreReactTemplate.Controllers.AuthController.Register (api)", returned result "Microsoft.AspNetCore.Mvc.OkResult". (f72615e0) 2017-04-20T12:04:03.0595620-05:00 0HL481SR1D5V0 [INF] Executing HttpStatusCodeResult, setting HTTP status code 200 (e28ccfae) 2017-04-20T12:04:03.0604090-05:00 0HL481SR1D5V0 [INF] Executed action "aspnetCoreReactTemplate.aspnetCoreReactTemplate.Controllers.AuthController.Register (api)" in 626.3141ms (afa2e885) 2017-04-20T12:04:03.0605200-05:00 0HL481SR1D5V0 [INF] Finished handling request. (d2c25297) 2017-04-20T12:04:03.0616630-05:00 0HL481SR1D5V0 [DBG] Connection id ""0HL481SQTVFU2"" completed keep alive response. (9784cde9) 2017-04-20T12:04:03.0617160-05:00 0HL481SR1D5V0 [INF] Request finished in 629.8908ms 200 (15c52c40) 2017-04-20T12:05:49.8207400-05:00 [DBG] Connection id ""0HL481SQTVFU3"" disconnecting. (b29b9868) 2017-04-20T12:05:49.8211020-05:00 [DBG] Connection id ""0HL481SQTVFU3"" sending FIN. (ffb251f5) 2017-04-20T12:05:49.8262480-05:00 [DBG] Connection id ""0HL481SQTVFU3"" sent FIN with status "0". (69d90ca7) 2017-04-20T12:05:49.8263780-05:00 [DBG] Connection id ""0HL481SQTVFU3"" stopped. (056149f8) 2017-04-20T12:06:03.8291950-05:00 [DBG] Connection id ""0HL481SQTVFU2"" disconnecting. (b29b9868) 2017-04-20T12:06:03.8293130-05:00 [DBG] Connection id ""0HL481SQTVFU2"" sending FIN. (ffb251f5) 2017-04-20T12:06:03.8294370-05:00 [DBG] Connection id ""0HL481SQTVFU2"" sent FIN with status "0". (69d90ca7) 2017-04-20T12:06:03.8295040-05:00 [DBG] Connection id ""0HL481SQTVFU2"" stopped. (056149f8) ================================================ FILE: api.sln ================================================  Microsoft Visual Studio Solution File, Format Version 12.00 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "api", "api\api.csproj", "{62842846-868D-4B6E-A191-C37121587533}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "api.test", "api.test\api.test.csproj", "{002B4B4F-3A5D-4342-98AB-C50F7147F863}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {62842846-868D-4B6E-A191-C37121587533}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {62842846-868D-4B6E-A191-C37121587533}.Debug|Any CPU.Build.0 = Debug|Any CPU {62842846-868D-4B6E-A191-C37121587533}.Release|Any CPU.ActiveCfg = Release|Any CPU {62842846-868D-4B6E-A191-C37121587533}.Release|Any CPU.Build.0 = Release|Any CPU {002B4B4F-3A5D-4342-98AB-C50F7147F863}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {002B4B4F-3A5D-4342-98AB-C50F7147F863}.Debug|Any CPU.Build.0 = Debug|Any CPU {002B4B4F-3A5D-4342-98AB-C50F7147F863}.Release|Any CPU.ActiveCfg = Release|Any CPU {002B4B4F-3A5D-4342-98AB-C50F7147F863}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal ================================================ FILE: api.test/Controller/Tests.cs ================================================ using System.Collections.Generic; using System.Linq; using app = aspnetCoreReactTemplate; namespace Tests.Controller { public class Tests { // [Fact] // public void Index_ReturnsAViewResult_WithAListOfBrainstormSessions() // { // var controller = new app.Controllers.ContactsController(null); // var result = (IEnumerable)controller.Get(); // Assert.NotEqual(result.Count(), 0); // } } } ================================================ FILE: api.test/ControllerTests.cs ================================================ using Xunit; namespace Tests { public class ControllerTests { [Fact] public void Test1() { var contact = new aspnetCoreReactTemplate.Models.Contact(); Assert.True(string.IsNullOrEmpty(contact.Email)); } } } ================================================ FILE: api.test/NuGet.Config ================================================ ================================================ FILE: api.test/Unit/Tests.cs ================================================ using Xunit; using app = aspnetCoreReactTemplate; namespace Tests.Unit { public class Tests { [Fact] public void TestNewContactProperties() { var contact = new app.Models.Contact(); Assert.True(string.IsNullOrEmpty(contact.LastName)); Assert.True(string.IsNullOrEmpty(contact.FirstName)); Assert.True(string.IsNullOrEmpty(contact.Email)); Assert.True(string.IsNullOrEmpty(contact.Phone)); } } } ================================================ FILE: api.test/api.test.csproj ================================================  net5.0 runtime; build; native; contentfiles; analyzers; buildtransitive all ================================================ FILE: client-react/boot.tsx ================================================ import * as React from 'react'; import * as ReactDOM from 'react-dom'; import { BrowserRouter as Router } from 'react-router-dom'; import Routes from './components/Routes'; // Polyfills import 'whatwg-fetch'; import './polyfills/object-assign'; import './polyfills/array-find'; // Styles import '../node_modules/bootstrap/dist/css/bootstrap.css'; import './styles/global.css'; ReactDOM.render( , document.getElementById("app") ); // Allow Hot Module Reloading declare var module: any; if (module.hot) { module.hot.accept(); } ================================================ FILE: client-react/components/Auth.tsx ================================================ import * as React from "react"; import { Link, Redirect, RouteComponentProps } from 'react-router-dom'; import { RoutePaths } from './Routes'; import AuthService from '../services/Auth'; let authStyle = require('../styles/auth.styl'); let authService = new AuthService(); export class SignIn extends React.Component, any> { refs: { username: HTMLInputElement; password: HTMLInputElement; }; state = { initialLoad: true, error: null as string }; handleSubmit(event: React.FormEvent) { event.preventDefault(); this.setState({ errors: null, initialLoad: false }); authService.signIn(this.refs.username.value, this.refs.password.value).then(response => { if (!response.is_error) { this.props.history.push(RoutePaths.Contacts); } else { this.setState({ error: response.error_content.error_description }); } }); } render() { const search = this.props.location.search; const params = new URLSearchParams(search); let initialLoadContent = null; if (this.state.initialLoad) { if (params.get('confirmed')) { initialLoadContent =
Your email address has been successfully confirmed.
} if (params.get('expired')) { initialLoadContent =
Sesion Expired You need to sign in again.
} if (this.props.history.location.state && this.props.history.location.state.signedOut) { initialLoadContent =
Signed Out
} } return
this.handleSubmit(e)}>

Please sign in

{initialLoadContent} {this.state.error &&
{this.state.error}
}
Register
; } } export class Register extends React.Component { refs: { email: HTMLInputElement; password: HTMLInputElement; }; state = { registerComplete: false, errors: {} as { [key: string]: string } }; handleSubmit(event: React.FormEvent) { event.preventDefault(); this.setState({ errors: {} }); authService.register(this.refs.email.value, this.refs.password.value).then(response => { if (!response.is_error) { this.setState({ registerComplete: true }) } else { this.setState({ errors: response.error_content }); } }); } _formGroupClass(field: string) { var className = "form-group "; if (field) { className += " has-danger" } return className; } render() { if (this.state.registerComplete) { return } else { return
this.handleSubmit(e)}>

Please register for access

{this.state.errors.general &&
{this.state.errors.general}
}
{this.state.errors.username}
{this.state.errors.password}
; }; } } interface RegisterCompleteProps { email: string; } export class RegisterComplete extends React.Component { render() { return
Success! Your account has been created.

A confirmation email has been sent to {this.props.email}. You will need to follow the provided link to confirm your email address before signing in.

Sign in
; } } ================================================ FILE: client-react/components/ContactForm.tsx ================================================ import 'object-assign'; import * as React from 'react'; import { Link, Redirect, RouteComponentProps } from 'react-router-dom'; import ContactService, { IContact } from '../services/Contacts' import { RoutePaths } from './Routes'; let contactService = new ContactService(); export class ContactForm extends React.Component, any> { state = { contact: null as IContact, errors: {} as { [key: string]: string } } componentDidMount() { if (this.props.match.path == RoutePaths.ContactEdit) { contactService.fetch(this.props.match.params.id).then((response) => { this.setState({ contact: response.content }); }); } else { let newContact: IContact = { lastName: '', firstName: '', email: '', phone: '' }; this.setState({ contact: newContact }); } } handleSubmit(event: React.FormEvent) { event.preventDefault(); this.saveContact(this.state.contact); } handleInputChange(event: React.ChangeEvent) { const target = event.target; const value = target.type === 'checkbox' ? target.checked : target.value; const name = target.name; let contactUpdates = { [name]: value }; this.setState({ contact: Object.assign(this.state.contact, contactUpdates) }); } saveContact(contact: IContact) { this.setState({ errors: {} as { [key: string]: string } }); contactService.save(contact).then((response) => { if (!response.is_error) { this.props.history.push(RoutePaths.Contacts); } else { this.setState({ errors: response.error_content }); } }); } _formGroupClass(field: string) { var className = "form-group "; if (field) { className += " has-danger" } return className; } render() { if (!this.state.contact) { return
Loading...
; } else { return
{this.state.contact.id ? "Edit Contact" : "New Contact" }
this.handleSubmit(e)}>
this.handleInputChange(e)} className="form-control form-control-danger" required />
{this.state.errors.lastName}
this.handleInputChange(e)} className="form-control form-control-danger" required />
{this.state.errors.firstName}
this.handleInputChange(e)} className="form-control form-control-danger" />
{this.state.errors.email}
this.handleInputChange(e)} className="form-control form-control-danger" />
{this.state.errors.phone}
Cancel
} } } ================================================ FILE: client-react/components/Contacts.tsx ================================================ import * as React from "react"; import { Link, Redirect } from 'react-router-dom'; import { RoutePaths } from './Routes'; import { ContactForm } from './ContactForm'; import ContactService, { IContact } from '../services/Contacts'; import { RouteComponentProps } from "react-router"; let contactService = new ContactService(); export class Contacts extends React.Component, any> { refs: { query: HTMLInputElement; }; state = { contacts: [] as Array, editContact: null as Object, isAddMode: false as boolean, searchQuery: '' as string }; componentDidMount() { this.showAll(); } showAll() { contactService.fetchAll().then((response) => { this.setState({ searchQuery: '', contacts: response.content }); }); } handleSearchQueryChange(event: React.ChangeEvent) { this.setState({ searchQuery: event.target.value }); } handleSeachSubmit(event: React.FormEvent) { event.preventDefault(); if(!this.state.searchQuery){ this.showAll(); return; } contactService.search(this.state.searchQuery).then((response) => { this.setState({ contacts: response.content }); }); } delete(contact: IContact) { contactService.delete(contact.id).then((response) => { let updatedContacts = this.state.contacts; updatedContacts.splice(updatedContacts.indexOf(contact), 1); this.setState({ contacts: updatedContacts }); }); } render() { return

Contacts

this.handleSeachSubmit(e)}> this.handleSearchQueryChange(e)} placeholder="Search!" />  
{this.state.searchQuery && this.state.contacts && this.state.contacts.length == 0 &&

No results!

} {this.state.contacts && this.state.contacts.length > 0 && {this.state.contacts.map((contact, index) => )}
Last Name First Name Email Phone
{contact.lastName} {contact.firstName} {contact.email} {contact.phone} edit
} {this.state.searchQuery && } add
}; } ================================================ FILE: client-react/components/Error.tsx ================================================ import * as React from "react"; import { Link, RouteComponentProps } from 'react-router-dom'; export class ErrorPage extends React.Component, any> { getErrorCode() { return this.props.match.params.code; } getErrorMessage() { let message = null; switch (this.props.match.params.code) { case 'email-confirm': message = 'The email confirmation link you used is invalid or expired.' break; default: message = 'An unknown error has occured.' } return message; } render() { let code = this.getErrorCode(); return

Error

{this.getErrorMessage()}

{code &&

Code: {code}

}
; } } ================================================ FILE: client-react/components/Header.tsx ================================================ import * as React from "react"; import { Link, Redirect } from 'react-router-dom'; import { RouteComponentProps } from "react-router"; import { RoutePaths } from './Routes'; import AuthService from '../services/Auth'; import AuthStore from '../stores/Auth'; let authService = new AuthService(); export class Header extends React.Component, any> { signOut() { authService.signOut(); this.props.history.push(RoutePaths.SignIn, { signedOut: true }); } render() { const search = this.props.location.search; const params = new URLSearchParams(search); return ; } } ================================================ FILE: client-react/components/Routes.tsx ================================================ import * as React from 'react'; import * as ReactDOM from 'react-dom'; import { Route, Redirect, Switch } from 'react-router-dom'; import { SignIn, Register } from './Auth'; import AuthService from '../services/Auth'; import { ErrorPage } from './Error'; import { Contacts } from './Contacts'; import { ContactForm } from './ContactForm'; import { Header } from './Header'; export class RoutePaths { public static Contacts: string = "/contacts"; public static ContactEdit: string = "/contacts/edit/:id"; public static ContactNew: string = "/contacts/new"; public static SignIn: string = "/"; public static Register: string = "/register/"; } export default class Routes extends React.Component { render() { return } } const DefaultLayout = ({ component: Component, ...rest }: { component: any, path: string, exact?: boolean }) => ( ( AuthService.isSignedIn() ? (
) : ( ) )} /> ); ================================================ FILE: client-react/index.ejs ================================================ aspnet-core-react-template
<%if (htmlWebpackPlugin.options.useCdn) { %> <% } %> ================================================ FILE: client-react/polyfills/array-find.d.ts ================================================ interface Array { find(predicate: (search: T) => boolean): T; } ================================================ FILE: client-react/polyfills/array-find.ts ================================================ /// // https://tc39.github.io/ecma262/#sec-array.prototype.find if (!Array.prototype.find) { Object.defineProperty(Array.prototype, 'find', { value: function (predicate:any) { // 1. Let O be ? ToObject(this value). if (this == null) { throw new TypeError('"this" is null or not defined'); } var o = Object(this); // 2. Let len be ? ToLength(? Get(O, "length")). var len = o.length >>> 0; // 3. If IsCallable(predicate) is false, throw a TypeError exception. if (typeof predicate !== 'function') { throw new TypeError('predicate must be a function'); } // 4. If thisArg was supplied, let T be thisArg; else let T be undefined. var thisArg = arguments[1]; // 5. Let k be 0. var k = 0; // 6. Repeat, while k < len while (k < len) { // a. Let Pk be ! ToString(k). // b. Let kValue be ? Get(O, Pk). // c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)). // d. If testResult is true, return kValue. var kValue = o[k]; if (predicate.call(thisArg, kValue, k, o)) { return kValue; } // e. Increase k by 1. k++; } // 7. Return undefined. return undefined; } }); } ================================================ FILE: client-react/polyfills/object-assign.d.ts ================================================ declare interface ObjectConstructor { assign(...objects: Object[]): Object; } ================================================ FILE: client-react/polyfills/object-assign.ts ================================================ /// if (typeof Object.assign != 'function') { Object.assign = function (target: any, varArgs: any) { // .length of function is 2 'use strict'; if (target == null) { // TypeError if undefined or null throw new TypeError('Cannot convert undefined or null to object'); } var to = Object(target); for (var index = 1; index < arguments.length; index++) { var nextSource = arguments[index]; if (nextSource != null) { // Skip over if undefined or null for (var nextKey in nextSource) { // Avoid bugs when hasOwnProperty is shadowed if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { to[nextKey] = nextSource[nextKey]; } } } } return to; }; } ================================================ FILE: client-react/services/Auth.ts ================================================ import RestUtilities from './RestUtilities'; import AuthStore from '../stores/Auth'; interface IAuthResponse { token: string; } export default class Auth { static isSignedIn(): boolean { return !!AuthStore.getToken(); } signInOrRegister(email: string, password: string, isRegister: boolean = false) { return RestUtilities.post(`/api/auth/${isRegister ? 'register' : 'login'}`, `username=${email}&password=${password}${!isRegister ? '&grant_type=password' : ''}`) .then((response) => { if (!response.is_error) { AuthStore.setToken(response.content.token); } return response; }); } signIn(email: string, password: string) { return this.signInOrRegister(email, password, false); } register(email: string, password: string) { return this.signInOrRegister(email, password, true); } confirm(token: string): Promise { return RestUtilities.post('/api/auth/confirm', { token: token }) .then((response) => { return true; }).catch((err) => { console.log(err); return false; }); } signOut(): void { AuthStore.removeToken(); } } ================================================ FILE: client-react/services/Contacts.ts ================================================ import RestUtilities from './RestUtilities'; export interface IContact { id?: number, lastName: string; firstName: string; phone: string; email: string; } export default class Contacts { fetchAll() { return RestUtilities.get>('/api/contacts'); } fetch(contactId: number) { return RestUtilities.get(`/api/contacts/${contactId}`); } search(query: string) { return RestUtilities.get>(`/api/contacts/search/?q=${query}`); } update(contact: IContact) { return RestUtilities.put(`/api/contacts/${contact.id}`, contact); } create(contact: IContact) { return RestUtilities.post('/api/contacts', contact); } save(contact: IContact) { if (contact.id) { return this.update(contact); } else { return this.create(contact); } } delete(contactId: number) { return RestUtilities.delete(`/api/contacts/${contactId}`); } } ================================================ FILE: client-react/services/RestUtilities.ts ================================================ import AuthStore from "../stores/Auth"; export interface IErrorContent { error: string; error_description: string; [key: string]: string; } export interface IRestResponse { is_error?: boolean; error_content?: IErrorContent; content?: T; } export default class RestUtilities { static get(url: string): Promise> { return RestUtilities.request("GET", url); } static delete(url: string): Promise> { return RestUtilities.request("DELETE", url); } static put( url: string, data: Object | string ): Promise> { return RestUtilities.request("PUT", url, data); } static post( url: string, data: Object | string ): Promise> { return RestUtilities.request("POST", url, data); } private static request( method: string, url: string, data: Object | string = null ): Promise> { let isJsonResponse: boolean = false; let isBadRequest = false; let body = data; let headers = new Headers(); headers.set('Authorization',`Bearer ${AuthStore.getToken()}`); headers.set('Accept','application/json'); if (data) { if (typeof data === "object") { headers.set('Content-Type','application/json'); body = JSON.stringify(data); } else { headers.set('Content-Type','application/x-www-form-urlencoded'); } } return fetch(url, { method: method, headers: headers, body: body }).then((response: any) => { if (response.status == 401) { // Unauthorized; redirect to sign-in AuthStore.removeToken(); window.location.replace(`/?expired=1`); } isBadRequest = response.status == 400; let responseContentType = response.headers.get("content-type"); if ( responseContentType && responseContentType.indexOf("application/json") !== -1 ) { isJsonResponse = true; return response.json(); } else { return response.text(); } }) .then((responseContent: any) => { let response: IRestResponse = { is_error: isBadRequest, error_content: isBadRequest ? responseContent : null, content: isBadRequest ? null : responseContent }; return response; }); } } ================================================ FILE: client-react/stores/Auth.ts ================================================ export default class Auth { static STORAGE_KEY: string = "token"; static getToken() { return window.localStorage.getItem(Auth.STORAGE_KEY); } static setToken(token: string) { window.localStorage.setItem(Auth.STORAGE_KEY, token); } static removeToken(): void { window.localStorage.removeItem(Auth.STORAGE_KEY); } } ================================================ FILE: client-react/styles/auth.styl ================================================ .auth { margin: 0 auto; width:500px; margin-top:50px; padding: 25px; background-color: #f2f2f2; } .authEtc { margin-top:20px; } .formAuth { .form-signin-heading, .checkbox { margin-bottom: 10px; } .checkbox { font-weight: normal; } .form-control { position: relative; height: auto; -webkit-box-sizing: border-box; box-sizing: border-box; padding: 10px; font-size: 16px; &:focus { z-index: 2; } } input[type="email"] { margin-bottom: -1px; border-bottom-right-radius: 0; border-bottom-left-radius: 0; } input[type="password"] { margin-bottom: 10px; border-top-left-radius: 0; border-top-right-radius: 0; } } ================================================ FILE: client-react/styles/contacts.styl ================================================ .content { padding: 3rem 1.5rem; } ================================================ FILE: client-react/styles/global.css ================================================ body { padding-top: 5rem; font-family: "century gothic", verdana; } .btn-link { cursor: pointer; } .btn { margin: 10px 3px 10px 3px; } .table td{ vertical-align: middle; } ================================================ FILE: client-react/styles/styles.d.ts ================================================ declare module "*.styl" { let styles: any; export default styles; } declare module "*.css" { let styles: any; export default styles; } ================================================ FILE: client-react/tsconfig.json ================================================ { "compilerOptions": { "sourceMap": true, "noImplicitAny": true, "module": "es2015", "target": "es2015", "jsx": "react" }, "files": ["./boot.tsx", "./styles/styles.d.ts"] } ================================================ FILE: client-react/webpack.config.js ================================================ var webpack = require("webpack"); var HtmlWebpackPlugin = require("html-webpack-plugin"); var releaseConfig = require("./webpack.config.release"); var isProductionEnvironment = process.env.ASPNETCORE_ENVIRONMENT === "Production"; var path = require("path"); var merge = require("extendify")({ isDeep: true, arrays: "replace" }); var config = { mode: "development", entry: { main: path.join(__dirname, "boot.tsx") }, output: { path: path.join(__dirname, "../api/", "wwwroot"), filename: "[name].js", publicPath: "/" }, resolve: { extensions: [".ts", ".tsx", ".js", ".styl", ".css"] }, module: { rules: [ { test: /\.styl$/, use: [ { loader: "style-loader" }, { loader: "css-loader", options: { modules: true, importLoaders: 2, sourceMap: false } }, { loader: "stylus-loader" } ] }, { test: /\.ts(x?)$/, loaders: ["ts-loader"] }, { test: /\.css/, loader: "style-loader!css-loader" }, { test: /\.(png|woff|woff2|eot|ttf|svg)$/, loader: "url-loader?limit=100000" } ] }, devtool: "inline-source-map", plugins: [ // plugins should not be empty: https://github.com/aspnet/JavaScriptServices/tree/dev/src/Microsoft.AspNetCore.SpaServices'[ new HtmlWebpackPlugin({ template: path.join(__dirname, "index.ejs"), inject: true }) // new webpack.NamedModulesPlugin() // We do not use ExtractTextPlugin in development mode so that HMR will work with styles ] }; if (isProductionEnvironment) { // Merge production config config = merge(config, releaseConfig); } module.exports = config; ================================================ FILE: client-react/webpack.config.release.js ================================================ var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); var ExtractTextPlugin = require("extract-text-webpack-plugin"); var path = require('path'); var config = { mode: "production", module: { rules: [ // Use react-hot for HMR and then ts-loader to transpile TS (pass path to tsconfig because it is not in root (cwd) path) { test: /\.ts(x?)$/, loaders: ['ts-loader'] }, { test: /\.styl$/, loader: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader?modules&importLoaders=2&sourceMap&localIdentName=[local]___[hash:base64:5]!stylus-loader' }) }, { test: /\.css/, loader: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader' }) } ] }, devtool: '', externals: { react: 'React', 'react-dom': 'ReactDOM' }, plugins: [ new HtmlWebpackPlugin({ release: true, template: path.join(__dirname, 'index.ejs'), useCdn: true, minify: { collapseWhitespace: true, removeComments: true } }), new ExtractTextPlugin("styles.css") ] }; ================================================ FILE: client-react.test/polyfill/localStorage.js ================================================ module.exports = { polyfill: function () { window.localStorage = window.sessionStorage = { getItem: function (key) { return this[key]; }, setItem: function (key, value) { this[key] = value; } }; } } ================================================ FILE: client-react.test/tests/Contacts.tsx ================================================ import { expect } from "chai"; import { mount, shallow, configure } from "enzyme"; import * as Adapter from "enzyme-adapter-react-16"; import * as React from "react"; import { MemoryRouter as Router, Route } from "react-router-dom"; import { stubFetch } from "../utils"; import { Contacts } from "../../client-react/components/Contacts"; configure({ adapter: new Adapter() }); describe(" component ", function() { it("renders a h1", function() { let fakeContactsData = [ { id: 1, lastName: "Smith", firstName: "John" } ]; let fetchStub = stubFetch(fakeContactsData); let emptyArgs: any = {}; const wrapper = shallow(); expect(wrapper.find("h1")).to.have.length(1); fetchStub.restore(); }); it("renders a list of contacts", function(done) { let fakeContactsData = [ { id: 1, lastName: "Smith", firstName: "John" } ]; let fetchStub = stubFetch(fakeContactsData); const wrapper = mount( ); setImmediate(function() { expect(wrapper.html()).to.contain( fakeContactsData[fakeContactsData.length - 1].lastName ); fetchStub.restore(); done(); }); }); }); ================================================ FILE: client-react.test/tests.tsx ================================================ import { JSDOM } from "jsdom"; import * as localStorage from "./polyfill/localStorage.js"; before(function() { const dom = new JSDOM("", { url: "http://localhost" }); (global as any).window = dom.window; (global as any).document = dom.window.document; localStorage.polyfill(); console.log( "Successfully mocked a DOM with jsdom and polyfilled localStorage." ); }); ================================================ FILE: client-react.test/tsconfig.json ================================================ { "compilerOptions": { "sourceMap": true, "noImplicitAny": true, "module": "commonjs", "target":"es2015", "jsx": "react", "allowJs": true, "outDir": "./build" }, "files": [ "./tests.tsx" ], "include": [ "./tests/*.ts*" ] } ================================================ FILE: client-react.test/utils.ts ================================================ import * as sinon from 'sinon'; /** * Stubs browser Fetch API and returns given returnData object * * @param returnData */ function stubFetch(returnData: Object) { let g = (global as any); if (!g.fetch) { // If fetch is not defined; define it as a dummy function because sinon will only stub a defined function g.fetch = function () { } } if (!g.Headers) { g.Headers = function () { this.set = function(){} } } let res = { status: 200, headers: { get: function (key: string) { return 'application/json'; } }, json: function () { return Promise.resolve(returnData) } }; return sinon.stub(global, "fetch" as any).callsFake(()=> Promise.resolve(res)); } export { stubFetch } ================================================ FILE: docker-compose.yml ================================================ version: '2' services: postgres: image: postgres:9.5 environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres ports: - "5433:5432" smtp: image: jeanberu/mailcatcher environment: - SMTP_PORT=1025 - HTTP_PORT=1080 ports: - "1025:1025" - "1080:1080" ================================================ FILE: global.json ================================================ { "sdk": { "version": "5.0.400" } } ================================================ FILE: ops/README.md ================================================ This folder contains [Ansible](https://www.ansible.com/) assets responsible for provisioning hosts and deploying this application. ## Setup 1. Procure access to Ubuntu 16.04 (Xenial) or Ubuntu 18.04 (Bionic) host which will be used to host this application. [AWS](aws.amazon.com) or [Digital Ocean](https://m.do.co/c/974ef9a471c1) are good options. 2. Setup DNS records to point to these host(s). 3. Create `config.yml` file in this directory, using `config.yml.example` as a pattern. ## Usage From the root of this respository, run one of the following commands: - `npm run provision:prod`: This will provision all production hosts specified in config.yml file. - `npm run deploy:prod`: This will deploy the app to all production hosts specified in config.yml file. ## Notes - The deploy.yml and provision.yml playbooks were written against and tested on Ubuntu 16. - The [Ansible Best Practices](http://docs.ansible.com/ansible/playbooks_best_practices.html) document demonstrates using /groups_vars/... for application environment variables (i.e. production / staging) and /group_vars/all for global variables. However, we are using inventory group variables, all contained within the inventory file (config.yml) to define environment and global variables. Because of this, all the variables are in a single location and easily managed. ================================================ FILE: ops/config.yml.example ================================================ all: vars: # The following vars apply globally; additional config is in group_vars/all. app_name: aspnetCoreReactTemplate production: hosts: 0.0.0.0 # The IP address or hostname of the production web server vars: deploy_user: jdoe # The name of the remote user account for provisioning and deployment gh_pubkey_user: johndoe1981 # The GitHub username used to pull the public key for deploy_user authorized_user access use_ssl: true # If true, SSL cert will be obtained from Let's Encrypt and Nginx provisioned for SSL letsencrypt_use_live_ca: true # If true, will use the Live Let's Encrypt ACME servers; otherwise will use staging server database_password: super!secret # PostgreSQL database will be configured with this password postgresql_backup_to_s3: true # If true, PostgresSQL backups will be moved to S3 storage s3_key: ABCDEFGHIJKLMNOP # S3 Access Key used for uploading PostgreSQL backups s3_secret: ABCDEFGHIJKLMNOP # S3 Access Secret used for uploading PostgreSQL backups jwt_key: 6872f99e-cb09 # The key to use for generating JWTs smtp_config: user:pass@smtp.domain.com:587 # The SMTP configuration for sending outgoing mail email_from_address: demo@gmail.com # The email address for outgoing email ================================================ FILE: ops/deploy.yml ================================================ --- - name: deploy hosts: all gather_facts: false remote_user: "{{ deploy_user }}" roles: - deploy post_tasks: - debug: msg="Deployed to https://{{ webserver_name }}" ================================================ FILE: ops/group_vars/all ================================================ --- database_name: "{{ app_name }}" database_username: "{{ app_name }}" source_directory: ../api/bin/Release/netcoreapp3.1/publish/ deploy_directory: "/home/{{ deploy_user }}/apps/{{ app_name }}" email_enable_ssl: true email_from_name: "{{ app_name }}" postgresql_backup_to_s3: false s3_bucket_name: "s3://app.{{ app_name }}" s3_db_backup_location: "{{ s3_bucket_name }}/db_backups" use_ssl: false letsencrypt_use_live_ca: false webserver_user: www-data webserver_name: "{{ inventory_hostname }}" ================================================ FILE: ops/library/ghetto_json ================================================ #!/usr/bin/env python # Source: https://github.com/FauxFaux/ansible-ghetto-json import json import sys import shlex try: import commentjson json_load = commentjson.load except ImportError: json_load = json.load def main(params_list): params = dict(x.split("=", 2) for x in params_list) path = params.pop('path') changed = False for key in params.keys(): if key.startswith('_ansible_'): params.pop(key) with open(path) as f: obj = json_load(f) for (key, target) in params.items(): parts = key.split('.') ref = obj for part in parts[:-1]: if part not in ref: ref[part] = {} ref = ref[part] last_part = parts[-1] if target == 'unset': if last_part in ref: del ref[last_part] changed = True else: if target.isdigit(): target = int(target) if target == 'null': target = None if target == 'false': target = False if target == 'true': target = True if last_part not in ref or ref[last_part] != target: ref[last_part] = target changed = True if changed: with open(path, 'w') as f: json.dump(obj, f, indent=2, separators=(',', ': '), sort_keys=True) print(json.dumps({'changed': changed})) if __name__ == '__main__': if len(sys.argv) == 2: main(shlex.split(open(sys.argv[1]).read())) else: main(sys.argv[1:]) ================================================ FILE: ops/provision.yml ================================================ --- - name: provision hosts: all remote_user: root # Do not gather facts here because if host does not have python2 installed (i.e. Ubuntu 16) this will fail initially. Gather facts later... gather_facts: false pre_tasks: - name: 'install python2' raw: sudo apt-get -y install python-simplejson - name: gather facts setup: # This gather facts: http://stackoverflow.com/a/31060268/626911 roles: - nginx - role: ssl when: use_ssl domainsets: - domains: - "{{ webserver_name }}" - dotnetcore - supervisor - { role: postgresql, postgresql_server: yes, postgresql_client: yes, postgresql_backup_enabled: yes } - role: s3cmd when: postgresql_backup_to_s3 - firewall - deploy_user ================================================ FILE: ops/roles/deploy/defaults/main.yml ================================================ --- appsetting_file: appsettings.json ================================================ FILE: ops/roles/deploy/meta/main.yml ================================================ --- dependencies: - role: supervisor ================================================ FILE: ops/roles/deploy/tasks/main.yml ================================================ - name: Copy app files synchronize: src={{ source_directory }} dest={{ deploy_directory }} delete=yes rsync_opts=--exclude=.git/ notify: Reload supervisor app config - name: Configure PostgresSQL connection string lineinfile: dest="{{ deploy_directory }}/{{ appsetting_file }}" regexp="defaultConnection\":" line="\"defaultConnection\"{{':'}} \"Host=127.0.0.1;Username={{ database_username }};Password={{ database_password }};Database={{ database_name }}\"" state="present" - name: Configure appsettings ghetto_json: path="{{ deploy_directory }}/{{ appsetting_file }}" frontEndUrl="http://{{ webserver_name }}/" jwt.key={{ jwt_key }} jwt.issuer="http://{{ webserver_name }}/" email.smtpConfig={{ smtp_config }} email.enableSSL={{ email_enable_ssl }} email.emailFromName={{ email_from_name }} email.emailFromAddress={{ email_from_address }} ================================================ FILE: ops/roles/deploy_user/meta/main.yml ================================================ --- dependencies: - role: postgresql ================================================ FILE: ops/roles/deploy_user/tasks/main.yml ================================================ - name: Add deploy user user: name={{ deploy_user }} shell=/bin/bash append=true - name: Adding postgres user ({{ postgresql_user }}) to deploy user group ({{ deploy_user }}) to allow usage of psql from /home path user: name={{ postgresql_user }} groups={{ deploy_user }} append=yes - name: Add deploy user public key to authorized_keys authorized_key: user={{ deploy_user }} key=https://github.com/{{ gh_pubkey_user }}.keys - name: Add deploy user to sudoers lineinfile: "dest=/etc/sudoers regexp='^{{ deploy_user }} ALL' line='{{ deploy_user }} ALL=(ALL) NOPASSWD: ALL' state=present" - name: Creates deploy directory for app file: path={{ deploy_directory }} state=directory owner={{deploy_user}} group={{webserver_user}} mode=0775 ================================================ FILE: ops/roles/dotnetcore/defaults/main.yml ================================================ --- dotnetcore_package_name: dotnet-sdk-5.0 ================================================ FILE: ops/roles/dotnetcore/tasks/main.yml ================================================ --- - name: Download product repository file get_url: url: "https://packages.microsoft.com/config/ubuntu/{{ansible_distribution_major_version}}.04/packages-microsoft-prod.deb" dest: "/tmp/packages-microsoft-prod.deb" when: ansible_distribution == "Ubuntu" and ansible_distribution_major_version == "18" - name: Execute dehydrated shell script shell: "dpkg -i /tmp/packages-microsoft-prod.deb" - name: Install transport-https apt: pkg=apt-transport-https state=present update_cache=yes - name: Install dotnet core SDK apt: name={{ dotnetcore_package_name }} state=present ================================================ FILE: ops/roles/firewall/handlers/main.yml ================================================ --- - name: Restart ufw service: name=ufw state=restarted ================================================ FILE: ops/roles/firewall/tasks/main.yml ================================================ --- - name: Install Uncomplicated Firewall (ufw) apt: pkg=ufw state=present cache_valid_time=86400 - name: Configure ufw defaults ufw: direction={{ item.direction }} policy={{ item.policy }} with_items: - { direction: 'incoming', policy: 'deny' } - { direction: 'outgoing', policy: 'allow' } notify: - Restart ufw - name: Allow OpenSSH ufw: rule=allow name=OpenSSH notify: - Restart ufw - name: Allow Nginx ufw: rule=allow name="Nginx Full" notify: - Restart ufw - name: Enable ufw ufw: state=enabled notify: - Restart ufw ================================================ FILE: ops/roles/nginx/defaults/main.yml ================================================ --- nginx_conf_dir: /etc/nginx nginx_conf_file: "{{ nginx_conf_dir }}/sites-available/{{ app_name }}.conf" nginx_conf_enabled_link_file: "{{ nginx_conf_dir }}/sites-enabled/{{ app_name }}.conf" ================================================ FILE: ops/roles/nginx/handlers/main.yml ================================================ --- - name: Reload nginx service: name=nginx state=reloaded enabled=true ================================================ FILE: ops/roles/nginx/tasks/main.yml ================================================ --- - name: Install Nginx apt: pkg=nginx state=present update_cache=yes - name: Disable the default site file: path="{{ nginx_conf_dir }}/sites-enabled/default" state=absent notify: Reload nginx - name: Setup app config template: src="etc_nginx_sites-available.conf.j2" dest={{ nginx_conf_file }} group={{ webserver_user }} owner={{ webserver_user }} - name: Enable app file: src={{ nginx_conf_file }} dest="{{ nginx_conf_enabled_link_file }}" state=link notify: Reload nginx ================================================ FILE: ops/roles/nginx/templates/etc_nginx_sites-available.conf.j2 ================================================ server { listen 80; #default_listen_marker server_name {{ webserver_name }}; #ssl_config_marker gzip_proxied any; gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; root {{ deploy_directory }}/wwwroot; index index.html; # Root path (to be served by Nginx) location = / { } # Static content (to be served by Nginx) location ~ \.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|html|htm|woff2|svg)$ { expires 1d; access_log off; } # Dynamic content (to be served by Kestrel) location / { proxy_pass http://0.0.0.0:5000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection keep-alive; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_cache_bypass $http_upgrade; } } #ssl_forced_config_marker ================================================ FILE: ops/roles/postgresql/LICENSE ================================================ The MIT License (MIT) Copyright (c) 2015 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: ops/roles/postgresql/README.md ================================================ # ansible-postgresql [PostgreSQL](http://www.postgresql.org/) is a powerful, open source object-relational database system. [![Platforms](http://img.shields.io/badge/platforms-ubuntu-lightgrey.svg?style=flat)](#) Tunables -------- * `postgresql_client` (boolean) - Install PostgreSQL client? * `postgresql_server` (boolean) - Install PostgreSQL server? * `postgresql_user` (string) - User to run postgresql as * `postgresql_runtime_root` (string) - Directory for runtime data * `postgresql_pidfile_path` (string) - Path for pidfile * `postgresql_accepts_external_connections` (boolean) - Allow connections from places that aren't localhost? * `postgresql_backup_enabled` (boolean) - Enable backups? * `postgresql_backup_path` (string) - Directory to store backups * `postgresql_backup_frequency` (string) - Frequency of backups Dependencies ------------ * [telusdigital.apt-repository](https://github.com/telusdigital/ansible-apt-repository/) Example Playbook ---------------- - hosts: servers roles: - role: telusdigital.postgresql postgresql_server: yes postgresql_backup_enabled: yes postgresql_backup_frequency: daily postgresql_backup_path: /data/backup/postgresql License ------- [MIT](https://tldrlegal.com/license/mit-license) Contributors ------------ * [Chris Olstrom](https://colstrom.github.io/) | [e-mail](mailto:chris@olstrom.com) | [Twitter](https://twitter.com/ChrisOlstrom) * Aaron Pederson * Steven Harradine ================================================ FILE: ops/roles/postgresql/defaults/main.yml ================================================ --- postgresql_client: no postgresql_server: no postgresql_user: postgres postgresql_runtime_root: "{{ runtime_root | default('/var/run') }}/postgresql" postgresql_pidfile_path: "{{ postgresql_runtime_root }}/postgresql.pid" postgresql_log_root: "{{ log_root | default('/var/log') }}/postgresql" postgresql_log_path: "{{ postgresql_log_root }}/postgresql-main.log" postgresql_accepts_external_connections: yes postgresql_backup_enabled: no postgresql_backup_path: /data/backup/postgresql postgresql_backup_frequency: daily postgresql_backup_to_s3: false ================================================ FILE: ops/roles/postgresql/handlers/main.yml ================================================ --- - name: Reload Service | postgres service: state: reloaded name: postgresql tags: - disruptive ================================================ FILE: ops/roles/postgresql/tasks/backup.yml ================================================ --- - name: "Directory Exists | {{ postgresql_backup_path }}" file: state: directory path: "{{ postgresql_backup_path }}" owner: "{{ postgresql_user }}" group: staff mode: 0775 when: postgresql_backup_enabled tags: - directory-structure - postgres - backup - name: Copy backup script become: true become_user: postgres template: src="pgsql_backup.sh.j2" dest="{{ postgresql_backup_path }}/pgsql_backup.sh" mode="u+x" - name: Setup Automated Backups via cron become: true become_user: postgres cron: name: postgres-backup special_time: "{{ postgresql_backup_frequency }}" job: "{{ postgresql_backup_path }}/pgsql_backup.sh" when: postgresql_backup_enabled tags: - postgres - backup - using-cron ================================================ FILE: ops/roles/postgresql/tasks/configure.yml ================================================ --- - name: "Directory Exists | {{ postgresql_runtime_root }}" file: state: directory path: "{{ postgresql_runtime_root }}" owner: "{{ postgresql_user }}" group: staff mode: 0775 tags: - directory-structure - runtime-data - postgres - name: Configure | postgres | pidfile lineinfile: state: present dest: "/etc/postgresql/{{ postgresql_major_version }}/main/postgresql.conf" regexp: '^#*external_pid_file' line: "external_pid_file = '{{ postgresql_pidfile_path }}'" notify: Reload Service | postgres tags: - pidfile - service - name: Configure | postgres | listen_address lineinfile: state: present dest: "/etc/postgresql/{{ postgresql_major_version }}/main/postgresql.conf" regexp: '^#* *listen_addresses =' line: "listen_addresses = '*'" notify: Reload Service | postgres tags: - networking when: postgresql_accepts_external_connections - name: Configure | postgres | pg_hba.conf lineinfile: state: present dest: "/etc/postgresql/{{ postgresql_major_version }}/main/pg_hba.conf" regexp: "^#* *host {{ item }}" line: "host {{ item }} {{ database_username | default(project) }} all md5" with_items: - template1 - "{{ database_name | default(project) }}" notify: Reload Service | postgres tags: - networking when: postgresql_accepts_external_connections ================================================ FILE: ops/roles/postgresql/tasks/install.yml ================================================ --- - name: Install Packages | apt apt: state: latest pkg: 'postgresql-client' when: postgresql_client tags: - software-installation - using-apt - name: Install Packages | apt apt: state: latest pkg: [ 'libpq-dev', 'python-dev', 'python-pip', 'postgresql', 'postgresql-contrib', 'postgresql-server-dev-all', 'python-dev' ] when: postgresql_server tags: - software-installation - using-apt - name: Install Packages | pip pip: state: latest name: 'psycopg2' when: postgresql_server tags: - software-installation - using-pip - name: Install Packages | apt apt: state: latest pkg: 'p7zip-full' when: postgresql_backup_enabled tags: - p7zip - backup - using-apt - name: Create Database User become: true become_user: postgres postgresql_user: state: present name: "{{ database_username | mandatory }}" password: "{{ database_password | mandatory }}" db: template1 priv: CONNECT # role_attr_flags: SUPERUSER when: postgresql_server - name: Create Database become: true become_user: postgres postgresql_db: state: present name: "{{ database_name | mandatory }}" owner: "{{ database_username | mandatory }}" when: postgresql_server - name: Create Database User become: true become_user: postgres postgresql_user: state: present name: "{{ database_username | mandatory }}" password: "{{ database_password | mandatory }}" db: "{{ database_name | mandatory }}" priv: ALL role_attr_flags: CREATEDB when: postgresql_server ================================================ FILE: ops/roles/postgresql/tasks/main.yml ================================================ --- - include: install.yml - { include: backup.yml, when: postgresql_server } - { include: configure.yml, when: postgresql_server } ================================================ FILE: ops/roles/postgresql/templates/pgsql_backup.sh.j2 ================================================ #!/bin/bash # Halt on error set -e BACKUP_FILENAME=backup-`date +\\%Y\\%m\\%d\\%H.7z` echo -e "Dumping {{ database_name }} to {{ postgresql_backup_path }}/${BACKUP_FILENAME}" pg_dump {{ database_name | default(project) }} | 7z a -an -txz -si -so > {{ postgresql_backup_path }}/${BACKUP_FILENAME} {% if (postgresql_backup_to_s3 | bool) == true %} S3_BUCKET="{{ s3_bucket_name }}/{{ s3_db_backup_location }}" echo -e "Uploading to S3 bucket ${S3_BUCKET}" s3cmd mb {{ s3_bucket_name }} s3cmd put {{ postgresql_backup_path }}/${BACKUP_FILENAME} ${S3_BUCKET}/${BACKUP_FILENAME} # Note: Because we are using set -e above, we should not get to this point if there was a problem uploading the backup # to S3. So, the backup file will just remain on this host. echo -e "Removing backup file" rm -f "{{ postgresql_backup_path }}/${BACKUP_FILENAME}" {% endif %} ================================================ FILE: ops/roles/postgresql/vars/main.yml ================================================ --- postgresql_major_version: '10' ================================================ FILE: ops/roles/s3cmd/meta/main.yml ================================================ --- dependencies: - role: postgresql ================================================ FILE: ops/roles/s3cmd/tasks/main.yml ================================================ - name: Install s3cmd apt: name=s3cmd state=present - name: Configure with .s3cfg file become: yes become_user: "{{ postgresql_user }}" template: src="s3cfg.j2" dest="~/.s3cfg" ================================================ FILE: ops/roles/s3cmd/templates/s3cfg.j2 ================================================ [default] access_key = {{ s3_key }} secret_key = {{ s3_secret }} use_https = True ================================================ FILE: ops/roles/ssl/defaults/main.yml ================================================ dehydrated_install_dir: /etc/dehydrated dehydrated_script_name: dehydrated.sh challenge_root_dir: /var/www/dehydrated challenge_relative_dir: /.well-known/acme-challenge letsencrypt_use_live_ca: false ================================================ FILE: ops/roles/ssl/meta/main.yml ================================================ --- dependencies: - role: nginx ================================================ FILE: ops/roles/ssl/tasks/main.yml ================================================ # Source: https://gist.github.com/raphaelm/10226edb0e46f7ce844e # Source: https://github.com/lukas2511/dehydrated --- - name: Ensure Challenge directory exists file: path="{{ challenge_root_dir }}{{ challenge_relative_dir }}" state=directory mode=0755 owner=root group={{ webserver_user }} recurse=yes - name: Ensure curl is installed apt: name=curl state=present - name: Ensure SSL base directory exists file: path={{ dehydrated_install_dir }} state=directory mode=0750 owner=root group={{ webserver_user }} - name: Ensure SSL domain list exists command: "touch {{ dehydrated_install_dir }}/domains.txt" args: creates: "{{ dehydrated_install_dir }}/domains.txt" - name: Ensure LE config exists template: src=config.j2 dest="{{ dehydrated_install_dir }}/config" mode=0750 owner=root - name: Download dehydrated shell script get_url: url: https://raw.githubusercontent.com/lukas2511/dehydrated/master/dehydrated dest: "{{ dehydrated_install_dir }}/{{ dehydrated_script_name }}" mode: 0700 - name: Add line to domains file lineinfile: dest: "{{ dehydrated_install_dir }}/domains.txt" line: "{{ item.domains | join(' ') }}" with_items: "{{ domainsets }}" - name: Configure Nginx to serve the Challenge directory blockinfile: dest: "{{ nginx_conf_file }}" insertafter: "#ssl_config_marker" marker: "# {mark} ANSIBLE MANAGED BLOCK (CHALLENGE DIR CONFIG)" block: | location ^~ {{ challenge_relative_dir }} { root {{ challenge_root_dir }}; } register: challenge_directory_config - name: Reload nginx # Force reload when challenge_directory_config.changed because we need it to run before running LE script service: name=nginx state=reloaded enabled=true when: challenge_directory_config.changed - name: Execute dehydrated shell script shell: "./{{ dehydrated_script_name }} --register --accept-terms && ./{{ dehydrated_script_name }} -c" args: chdir: "{{ dehydrated_install_dir }}" notify: Reload nginx - name: Configure SSL in Nginx blockinfile: dest: "{{ nginx_conf_file }}" insertafter: "#ssl_config_marker" marker: "# {mark} ANSIBLE MANAGED BLOCK (SSL CONFIG)" block: | listen 443 ssl; ssl_certificate {{ dehydrated_install_dir }}/certs/{{ webserver_name }}/fullchain.pem; ssl_certificate_key {{ dehydrated_install_dir }}/certs/{{ webserver_name }}/privkey.pem; notify: Reload nginx - name: Remove default listen port (will be replaced with another server block) lineinfile: dest: "{{ nginx_conf_file }}" state: absent regexp: '#default_listen_marker' - name: Configure forced SSL redirect in Nginx blockinfile: dest: "{{ nginx_conf_file }}" insertafter: "#ssl_forced_config_marker" marker: "# {mark} ANSIBLE MANAGED BLOCK (FORCE SSL CONFIG)" block: | server { listen 80; server_name {{ webserver_name }}; rewrite ^ https://$server_name$request_uri? permanent; } notify: Reload nginx - name: Add LE cronjob cron: name=lets-encrypt hour=4 minute=23 day=*/3 job="{{ dehydrated_install_dir }}/{{ dehydrated_script_name }} -c && service nginx reload" ================================================ FILE: ops/roles/ssl/templates/config.j2 ================================================ ######################################################## # This is the main config file for dehydrated # # # # This file is looked for in the following locations: # # $SCRIPTDIR/config (next to this script) # # /usr/local/etc/dehydrated/config # # /etc/dehydrated/config # # ${PWD}/config (in current working-directory) # # # # Default values of this config are in comments # ######################################################## # Resolve names to addresses of IP version only. (curl) # supported values: 4, 6 # default: #IP_VERSION= # Path to certificate authority (default: https://acme-v02.api.letsencrypt.org/directory) CA="{{ "https://acme-v02.api.letsencrypt.org/directory" if (letsencrypt_use_live_ca | bool) == true else "https://acme-staging-v02.api.letsencrypt.org/directory" }}" # Path to license agreement (default: https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf) #LICENSE="https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf" # Which challenge should be used? Currently http-01 and dns-01 are supported CHALLENGETYPE="http-01" # Path to a directory containing additional config files, allowing to override # the defaults found in the main configuration file. Additional config files # in this directory needs to be named with a '.sh' ending. # default: #CONFIG_D= # Base directory for account key, generated certificates and list of domains (default: $SCRIPTDIR -- uses config directory if undefined) #BASEDIR=$SCRIPTDIR # File containing the list of domains to request certificates for (default: $BASEDIR/domains.txt) #DOMAINS_TXT="${BASEDIR}/domains.txt" # Output directory for generated certificates #CERTDIR="${BASEDIR}/certs" # Directory for account keys and registration information #ACCOUNTDIR="${BASEDIR}/accounts" # Output directory for challenge-tokens to be served by webserver or deployed in HOOK (default: /var/www/dehydrated) WELLKNOWN="/var/www/dehydrated/.well-known/acme-challenge" # Default keysize for private keys (default: 4096) #KEYSIZE="4096" # Path to openssl config file (default: - tries to figure out system default) #OPENSSL_CNF= # Program or function called in certain situations # # After generating the challenge-response, or after failed challenge (in this case altname is empty) # Given arguments: clean_challenge|deploy_challenge altname token-filename token-content # # After successfully signing certificate # Given arguments: deploy_cert domain path/to/privkey.pem path/to/cert.pem path/to/fullchain.pem # # BASEDIR and WELLKNOWN variables are exported and can be used in an external program # default: #HOOK= # Chain clean_challenge|deploy_challenge arguments together into one hook call per certificate (default: no) #HOOK_CHAIN="no" # Minimum days before expiration to automatically renew certificate (default: 30) #RENEW_DAYS="30" # Regenerate private keys instead of just signing new certificates on renewal (default: yes) #PRIVATE_KEY_RENEW="yes" # Which public key algorithm should be used? Supported: rsa, prime256v1 and secp384r1 #KEY_ALGO=rsa # E-mail to use during the registration (default: ) #CONTACT_EMAIL= # Lockfile location, to prevent concurrent access (default: $BASEDIR/lock) #LOCKFILE="${BASEDIR}/lock" # Option to add CSR-flag indicating OCSP stapling to be mandatory (default: no) #OCSP_MUST_STAPLE="no" ================================================ FILE: ops/roles/supervisor/defaults/main.yml ================================================ log_file: "/var/log/{{ app_name }}.out.log" error_file: "/var/log/{{ app_name }}.err.log" ================================================ FILE: ops/roles/supervisor/handlers/main.yml ================================================ --- - name: Reload supervisor become: true service: name=supervisor state=reloaded enabled=true - name: Reload supervisor app config become: true command: supervisorctl restart {{ app_name }} ================================================ FILE: ops/roles/supervisor/tasks/main.yml ================================================ --- - name: Install Supervisor become: true apt: pkg=supervisor state=present cache_valid_time=86400 - name: Setup app config become: true template: src=etc_supervisor_conf.d_app_name.conf.j2 dest=/etc/supervisor/conf.d/{{ app_name }}.conf notify: Reload supervisor - name: Create .NET Core cert cache directory and give access to {{ webserver_user }} become: true file: path=/var/www/.dotnet/corefx/cryptography/crls state=directory owner={{ webserver_user }} group={{ webserver_user }} mode=0775 ================================================ FILE: ops/roles/supervisor/templates/etc_supervisor_conf.d_app_name.conf.j2 ================================================ [program:{{ app_name }}] command=/usr/bin/dotnet {{ deploy_directory }}/api.dll directory={{ deploy_directory }} autostart=true autorestart=true stderr_logfile={{ error_file }} stdout_logfile={{ log_file }} environment=HOME=/var/www/,ASPNETCORE_ENVIRONMENT=Production user={{ webserver_user }} stopsignal=INT stopasgroup=true killasgroup=true ================================================ FILE: package.json ================================================ { "name": "aspnet.core.react.template", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "postinstall": "dotnet restore ./api && dotnet restore ./api.test", "build": "dotnet build ./api", "test:api": "cd ./api.test && dotnet test", "pretest:client": "npx tsc -p ./client-react.test/", "test:client": "mocha --require ignore-styles --recursive client-react.test/build/client-react.test", "test": "npm run test:api && npm run test:client", "migrate": "cd ./api/ && node ../scripts/create-migration.js && dotnet ef database update", "prestart": "docker-compose up -d", "start": "concurrently \"cd ./api && cross-env NODE_PATH=../node_modules/ ASPNETCORE_ENVIRONMENT=Development dotnet watch run\" \"cd ./client-react && webpack-dev-server\"", "start:release": "npm run prerelease && cd ./api/bin/Release/netcoreapp2.1/publish/ && dotnet api.dll", "provision:prod": "ansible-playbook -l production -i ./ops/config.yml ./ops/provision.yml", "prerelease": "cross-env ASPNETCORE_ENVIRONMENT=Production webpack --config ./client-react/webpack.config.js && cd ./api && dotnet publish --configuration Release", "deploy:prod": "npm run prerelease && ansible-playbook -l production -i ./ops/config.yml ./ops/deploy.yml", "ssh:prod": "ssh `grep 'deploy_user=' ./ops/hosts | tail -n1 | awk -F'=' '{ print $2}'`@`awk 'f{print;f=0} /[production]/{f=1}' ./ops/hosts | head -n 1`" }, "author": "", "license": "ISC", "devDependencies": {}, "dependencies": { "@types/chai": "^4.2.7", "@types/enzyme": "^3.10.4", "@types/enzyme-adapter-react-16": "^1.0.5", "@types/jsdom": "^12.2.4", "@types/mocha": "^5.2.7", "@types/react": "^16.9.16", "@types/react-addons-test-utils": "^0.14.25", "@types/react-dom": "^16.9.4", "@types/react-router-dom": "^5.1.3", "@types/sinon": "7.5.1", "aspnet-webpack": "^3.0.0", "aspnet-webpack-react": "^4.0.0", "bootstrap": "4.4.1", "chai": "^4.2.0", "concurrently": "^5.0.1", "cross-env": "^6.0.3", "css-loader": "^3.3.2", "dom": "^0.0.3", "enzyme": "^3.10.0", "enzyme-adapter-react-16": "^1.15.1", "extendify": "^1.0.0", "extract-text-webpack-plugin": "^3.0.2", "file-loader": "^5.0.2", "global": "^4.4.0", "html-webpack-plugin": "^3.2.0", "ignore-styles": "^5.0.1", "jsdom": "^15.2.1", "mocha": "^6.2.2", "prop-types": "^15.7.2", "react": "^16.12.0", "react-addons-test-utils": "^15.6.2", "react-dom": "^16.12.0", "react-hot-loader": "^4.12.18", "react-router": "^5.1.2", "react-router-dom": "^5.1.2", "sinon": "7.5.0", "source-map-loader": "^0.2.4", "style-loader": "^1.0.1", "stylus": "^0.54.7", "stylus-loader": "^3.0.2", "ts-loader": "^6.2.1", "typescript": "^3.7.3", "url-loader": "^3.0.0", "webpack": "^4.41.2", "webpack-cli": "^3.3.10", "webpack-dev-middleware": "^3.7.2", "webpack-dev-server": "^3.9.0", "webpack-hot-middleware": "^2.25.0", "whatwg-fetch": "^3.0.0" } } ================================================ FILE: scripts/create-migration.js ================================================ const timestamp = Math.floor(new Date().getTime()/1000).toString(); const execSync = require("child_process").execSync; execSync(`dotnet ef migrations add ${timestamp}`);