diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..c9c2c18 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +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 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b233b23 --- /dev/null +++ b/.gitignore @@ -0,0 +1,28 @@ +.DS_Store + +# dotnet core +bin/ +obj/ +project.lock.json + +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/*.retry + +# other +*.js.map + diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..4fcbf47 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,50 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Debug api/ (server)", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build", + "program": "${workspaceRoot}/api/bin/Debug/netcoreapp1.1/api.dll", + "args": [], + "env": { + "ASPNETCORE_ENVIRONMENT": "Development", + "NODE_PATH": "../node_modules/" + }, + "cwd": "${workspaceRoot}/api", + "externalConsole": false, + "stopAtEntry": false, + "internalConsoleOptions": "openOnSessionStart" + }, + { + "name": "Debug client-web.test/ (Mocha tests)", + "type": "node", + "request": "launch", + "protocol": "inspector", + "program": "${workspaceRoot}/node_modules/mocha/bin/_mocha", + "stopOnEntry": false, + "args": [ + "--require", + "ignore-styles", + "--recursive", + "client-web.test/build/client-web.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}" + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..2d748b5 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "files.exclude": { + "**/.git": true, + "**/.svn": true, + "**/.hg": true, + "**/CVS": true, + "**/.DS_Store": true, + "**/bin": true, + "**/obj": true + } +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..ca29787 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,34 @@ +{ + // 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" + ] + } + ] +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..19c0391 --- /dev/null +++ b/README.md @@ -0,0 +1,116 @@ +# ASP.NET Core / Vue.js SPA Template App + +This app is a template application using ASP.NET Core for a REST/JSON API server and Vue.js for a web client. + +## Overview of Stack +- Server + - ASP.NET Core + - PostgresSQL + - Entity Framework Core w/ EF Migrations + - JSON Web Token (JWT) authorization with OpenIddict + - Docker used for development PostgresSQL database and MailCatcher server +- Client + - Vue.js + - Webpack for asset bundling and HMR (Hot Module Replacement) + - CSS Modules +- Testing + - xUnit for .NET Core + - MailCatcher for development email delivery +- DevOps + - Ansible playbook for provisioning (Nginx reverse proxy, SSL via Let's Encrypt, PostgresSQL backups to S3) + - Ansible playbook for deployment + +## Setup + +1. Install the following: + - [.NET Core 1.1](https://www.microsoft.com/net/core) + - [Node.js >= v7.8.0](https://nodejs.org/en/download/) + - [Ansible >= 2.0](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). + +## 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 Vue.js tests in client-web.test/. + +### `npm run provision:prod` + + _Before running this script, you need to create an ops/hosts 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. 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 PostgresSQL 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/hosts 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/hosts inventory file. This does the following: + - Copies the build assets to the remote host(s) + - Updates the `appsettings.json` file with PostgresSQL credentials specified in ops/hosts file and the app URL (needed for JWT tokens) + - Restarts the app so that changes will be picked up + +## 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/). + +## 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-web.test/ (Mocha tests)** - Runs the vscode debugger on the client-web.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) +- My own perseverance because this took a _lot_ of time to get right 😁 diff --git a/api.test/Controller/Tests.cs b/api.test/Controller/Tests.cs new file mode 100755 index 0000000..3dfc9b6 --- /dev/null +++ b/api.test/Controller/Tests.cs @@ -0,0 +1,19 @@ +using System.Collections.Generic; +using System.Linq; +using Xunit; +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); + // } + } +} diff --git a/api.test/ControllerTests.cs b/api.test/ControllerTests.cs new file mode 100755 index 0000000..e452b1b --- /dev/null +++ b/api.test/ControllerTests.cs @@ -0,0 +1,14 @@ +using Xunit; + +namespace Tests +{ + public class ControllerTests + { + [Fact] + public void Test1() + { + var contact = new aspnetCoreReactTemplate.Models.Contact(); + Assert.True(string.IsNullOrEmpty(contact.email)); + } + } +} diff --git a/api.test/NuGet.Config b/api.test/NuGet.Config new file mode 100644 index 0000000..ae8aea9 --- /dev/null +++ b/api.test/NuGet.Config @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/api.test/Unit/Tests.cs b/api.test/Unit/Tests.cs new file mode 100755 index 0000000..4ff8a27 --- /dev/null +++ b/api.test/Unit/Tests.cs @@ -0,0 +1,19 @@ +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)); + } + } +} diff --git a/api.test/api.test.csproj b/api.test/api.test.csproj new file mode 100755 index 0000000..d31386e --- /dev/null +++ b/api.test/api.test.csproj @@ -0,0 +1,20 @@ + + + netcoreapp1.1 + portable + api.test + api.test + true + $(PackageTargetFallback);dotnet5.4;portable-net451+win8 + + + + + + + + + + + + diff --git a/api/Controllers/AuthController.cs b/api/Controllers/AuthController.cs new file mode 100644 index 0000000..3ec5466 --- /dev/null +++ b/api/Controllers/AuthController.cs @@ -0,0 +1,198 @@ +using System.Linq; +using System.Threading.Tasks; +using System.Collections.Generic; +using AspNet.Security.OpenIdConnect.Extensions; +using AspNet.Security.OpenIdConnect.Primitives; +using AspNet.Security.OpenIdConnect.Server; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http.Authentication; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using OpenIddict.Core; +using aspnetCoreReactTemplate.Models; +using aspnetCoreReactTemplate.Services; +using aspnetCoreReactTemplate.ViewModels; + +namespace aspnetCoreReactTemplate.aspnetCoreReactTemplate.Controllers +{ + public class AuthController : Controller + { + private readonly UserManager _userManager; + private readonly IOptions _identityOptions; + private readonly IEmailSender _emailSender; + private readonly SignInManager _signInManager; + private readonly ILogger _logger; + + public AuthController( + UserManager userManager, + IOptions identityOptions, + IEmailSender emailSender, + SignInManager signInManager, + ILoggerFactory loggerFactory) + { + _userManager = userManager; + _identityOptions = identityOptions; + _emailSender = emailSender; + _signInManager = signInManager; + _logger = loggerFactory.CreateLogger(); + } + + [AllowAnonymous] + [HttpPost("~/api/auth/login")] + [Produces("application/json")] + public async Task Login(OpenIdConnectRequest request) + { + if (!request.IsPasswordGrantType()) + { + return BadRequest(new + { + error = OpenIdConnectConstants.Errors.UnsupportedGrantType, + error_description = "The specified grant type is not supported." + }); + } + + // Ensure the username and password is valid. + var user = await _userManager.FindByNameAsync(request.Username); + if (user == null || !await _userManager.CheckPasswordAsync(user, request.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." + }); + } + + // Create a new authentication ticket. + var ticket = await CreateTicket(user); + + _logger.LogInformation($"User logged in (id: {user.Id})"); + + // Returning a SignInResult will ask OpenIddict to issue the appropriate access/identity tokens. + return SignIn(ticket.Principal, ticket.Properties, ticket.AuthenticationScheme); + } + + [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"); + } + } + + private async Task CreateTicket(ApplicationUser user) + { + // Create a new ClaimsPrincipal containing the claims that + // will be used to create an id_token, a token or a code. + var principal = await _signInManager.CreateUserPrincipalAsync(user); + + // Create a new authentication ticket holding the user identity. + var ticket = new AuthenticationTicket(principal, + new AuthenticationProperties(), + OpenIdConnectServerDefaults.AuthenticationScheme); + + // Set the list of scopes granted to the client application. + ticket.SetScopes(new[] + { + OpenIdConnectConstants.Scopes.OpenId, + OpenIdConnectConstants.Scopes.Email, + OpenIdConnectConstants.Scopes.Profile, + OpenIddictConstants.Scopes.Roles + }); + + ticket.SetResources("resource-server"); + + // Note: by default, claims are NOT automatically included in the access and identity tokens. + // To allow OpenIddict to serialize them, you must attach them a destination, that specifies + // whether they should be included in access tokens, in identity tokens or in both. + + foreach (var claim in ticket.Principal.Claims) + { + // Never include the security stamp in the access and identity tokens, as it's a secret value. + if (claim.Type == _identityOptions.Value.ClaimsIdentity.SecurityStampClaimType) + { + continue; + } + + var destinations = new List + { + OpenIdConnectConstants.Destinations.AccessToken + }; + + // Only add the iterated claim to the id_token if the corresponding scope was granted to the client application. + // The other claims will only be added to the access_token, which is encrypted when using the default format. + if ((claim.Type == OpenIdConnectConstants.Claims.Name && ticket.HasScope(OpenIdConnectConstants.Scopes.Profile)) || + (claim.Type == OpenIdConnectConstants.Claims.Email && ticket.HasScope(OpenIdConnectConstants.Scopes.Email)) || + (claim.Type == OpenIdConnectConstants.Claims.Role && ticket.HasScope(OpenIddictConstants.Claims.Roles))) + { + destinations.Add(OpenIdConnectConstants.Destinations.IdentityToken); + } + + claim.SetDestinations(OpenIdConnectConstants.Destinations.AccessToken); + } + + return ticket; + } + } +} diff --git a/api/Controllers/ContactController.cs b/api/Controllers/ContactController.cs new file mode 100644 index 0000000..7674cb9 --- /dev/null +++ b/api/Controllers/ContactController.cs @@ -0,0 +1,85 @@ +using System.Collections.Generic; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using aspnetCoreReactTemplate.Models; +using Microsoft.EntityFrameworkCore; +using System.Threading.Tasks; +using System.Linq; + +namespace aspnetCoreReactTemplate.Controllers +{ + [Authorize] + [Route("api/[controller]")] + public class ContactsController : Controller + { + 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.Contains(q) || c.firstName.Contains(q)). + 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.contactId }, model); + } + + // PUT api/contacts/5 + [HttpPut("{id}")] + public async Task Put(int id, [FromBody]Contact model) + { + if (!ModelState.IsValid) + { + return BadRequest(ModelState); + } + + model.contactId = id; + _context.Update(model); + await _context.SaveChangesAsync(); + return Ok(); + } + + // DELETE api/contacts/5 + [HttpDelete("{id}")] + public async Task Delete(int id) + { + Contact contact = new Contact() { contactId = id }; + _context.Entry(contact).State = EntityState.Deleted; + + await _context.SaveChangesAsync(); + return Ok(); + } + } +} diff --git a/api/Middleware/SpaFallbackMiddleware.cs b/api/Middleware/SpaFallbackMiddleware.cs new file mode 100644 index 0000000..6cf3a6b --- /dev/null +++ b/api/Middleware/SpaFallbackMiddleware.cs @@ -0,0 +1,48 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Logging; + +namespace aspnetCoreReactTemplate +{ + 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); + } + } +} diff --git a/api/Middleware/SpaFallbackOptions.cs b/api/Middleware/SpaFallbackOptions.cs new file mode 100644 index 0000000..65868de --- /dev/null +++ b/api/Middleware/SpaFallbackOptions.cs @@ -0,0 +1,13 @@ +namespace aspnetCoreReactTemplate +{ + public class SpaFallbackOptions + { + public SpaFallbackOptions() + { + this.ApiPathPrefix = "/api"; + this.RewritePath = "/"; + } + public string ApiPathPrefix { get; set; } + public string RewritePath { get; set; } + } +} diff --git a/api/Migrations/20170420031935_Initial.Designer.cs b/api/Migrations/20170420031935_Initial.Designer.cs new file mode 100755 index 0000000..a07f72d --- /dev/null +++ b/api/Migrations/20170420031935_Initial.Designer.cs @@ -0,0 +1,328 @@ +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using aspnetCoreReactTemplate.Models; + +namespace api.Migrations +{ + [DbContext(typeof(DefaultDbContext))] + [Migration("20170420031935_Initial")] + partial class Initial + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { + modelBuilder + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn) + .HasAnnotation("ProductVersion", "1.1.1"); + + modelBuilder.Entity("aspnetCoreReactTemplate.Models.ApplicationUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AccessFailedCount"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken(); + + b.Property("Email") + .HasMaxLength(256); + + b.Property("EmailConfirmed"); + + b.Property("GivenName"); + + b.Property("LockoutEnabled"); + + b.Property("LockoutEnd"); + + b.Property("NormalizedEmail") + .HasMaxLength(256); + + b.Property("NormalizedUserName") + .HasMaxLength(256); + + b.Property("PasswordHash"); + + b.Property("PhoneNumber"); + + b.Property("PhoneNumberConfirmed"); + + b.Property("SecurityStamp"); + + b.Property("TwoFactorEnabled"); + + b.Property("UserName") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasName("UserNameIndex"); + + b.ToTable("AspNetUsers"); + }); + + modelBuilder.Entity("aspnetCoreReactTemplate.Models.Contact", b => + { + b.Property("contactId") + .ValueGeneratedOnAdd(); + + b.Property("email"); + + b.Property("name"); + + b.Property("phone"); + + b.HasKey("contactId"); + + b.ToTable("Contacts"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken(); + + b.Property("Name") + .HasMaxLength(256); + + b.Property("NormalizedName") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasName("RoleNameIndex"); + + b.ToTable("AspNetRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ClaimType"); + + b.Property("ClaimValue"); + + b.Property("RoleId") + .IsRequired(); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ClaimType"); + + b.Property("ClaimValue"); + + b.Property("UserId") + .IsRequired(); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserLogin", b => + { + b.Property("LoginProvider"); + + b.Property("ProviderKey"); + + b.Property("ProviderDisplayName"); + + b.Property("UserId") + .IsRequired(); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserRole", b => + { + b.Property("UserId"); + + b.Property("RoleId"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserToken", b => + { + b.Property("UserId"); + + b.Property("LoginProvider"); + + b.Property("Name"); + + b.Property("Value"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens"); + }); + + modelBuilder.Entity("OpenIddict.Models.OpenIddictApplication", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ClientId"); + + b.Property("ClientSecret"); + + b.Property("DisplayName"); + + b.Property("LogoutRedirectUri"); + + b.Property("RedirectUri"); + + b.Property("Type"); + + b.HasKey("Id"); + + b.HasIndex("ClientId") + .IsUnique(); + + b.ToTable("OpenIddictApplications"); + }); + + modelBuilder.Entity("OpenIddict.Models.OpenIddictAuthorization", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ApplicationId"); + + b.Property("Scope"); + + b.Property("Subject"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationId"); + + b.ToTable("OpenIddictAuthorizations"); + }); + + modelBuilder.Entity("OpenIddict.Models.OpenIddictScope", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Description"); + + b.HasKey("Id"); + + b.ToTable("OpenIddictScopes"); + }); + + modelBuilder.Entity("OpenIddict.Models.OpenIddictToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ApplicationId"); + + b.Property("AuthorizationId"); + + b.Property("Subject"); + + b.Property("Type"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationId"); + + b.HasIndex("AuthorizationId"); + + b.ToTable("OpenIddictTokens"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRole") + .WithMany("Claims") + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserClaim", b => + { + b.HasOne("aspnetCoreReactTemplate.Models.ApplicationUser") + .WithMany("Claims") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserLogin", b => + { + b.HasOne("aspnetCoreReactTemplate.Models.ApplicationUser") + .WithMany("Logins") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRole") + .WithMany("Users") + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("aspnetCoreReactTemplate.Models.ApplicationUser") + .WithMany("Roles") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("OpenIddict.Models.OpenIddictAuthorization", b => + { + b.HasOne("OpenIddict.Models.OpenIddictApplication", "Application") + .WithMany("Authorizations") + .HasForeignKey("ApplicationId"); + }); + + modelBuilder.Entity("OpenIddict.Models.OpenIddictToken", b => + { + b.HasOne("OpenIddict.Models.OpenIddictApplication", "Application") + .WithMany("Tokens") + .HasForeignKey("ApplicationId"); + + b.HasOne("OpenIddict.Models.OpenIddictAuthorization", "Authorization") + .WithMany("Tokens") + .HasForeignKey("AuthorizationId"); + }); + } + } +} diff --git a/api/Migrations/20170420031935_Initial.cs b/api/Migrations/20170420031935_Initial.cs new file mode 100755 index 0000000..7cbcc56 --- /dev/null +++ b/api/Migrations/20170420031935_Initial.cs @@ -0,0 +1,341 @@ +using System; +using System.Collections.Generic; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Metadata; + +namespace api.Migrations +{ + public partial class Initial : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "AspNetUsers", + columns: table => new + { + Id = table.Column(nullable: false), + AccessFailedCount = table.Column(nullable: false), + ConcurrencyStamp = table.Column(nullable: true), + Email = table.Column(maxLength: 256, nullable: true), + EmailConfirmed = table.Column(nullable: false), + GivenName = table.Column(nullable: true), + LockoutEnabled = table.Column(nullable: false), + LockoutEnd = table.Column(nullable: true), + NormalizedEmail = table.Column(maxLength: 256, nullable: true), + NormalizedUserName = table.Column(maxLength: 256, nullable: true), + PasswordHash = table.Column(nullable: true), + PhoneNumber = table.Column(nullable: true), + PhoneNumberConfirmed = table.Column(nullable: false), + SecurityStamp = table.Column(nullable: true), + TwoFactorEnabled = table.Column(nullable: false), + UserName = table.Column(maxLength: 256, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUsers", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Contacts", + columns: table => new + { + contactId = table.Column(nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn), + email = table.Column(nullable: true), + name = table.Column(nullable: true), + phone = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Contacts", x => x.contactId); + }); + + migrationBuilder.CreateTable( + name: "AspNetRoles", + columns: table => new + { + Id = table.Column(nullable: false), + ConcurrencyStamp = table.Column(nullable: true), + Name = table.Column(maxLength: 256, nullable: true), + NormalizedName = table.Column(maxLength: 256, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetRoles", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserTokens", + columns: table => new + { + UserId = table.Column(nullable: false), + LoginProvider = table.Column(nullable: false), + Name = table.Column(nullable: false), + Value = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name }); + }); + + migrationBuilder.CreateTable( + name: "OpenIddictApplications", + columns: table => new + { + Id = table.Column(nullable: false), + ClientId = table.Column(nullable: true), + ClientSecret = table.Column(nullable: true), + DisplayName = table.Column(nullable: true), + LogoutRedirectUri = table.Column(nullable: true), + RedirectUri = table.Column(nullable: true), + Type = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_OpenIddictApplications", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "OpenIddictScopes", + columns: table => new + { + Id = table.Column(nullable: false), + Description = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_OpenIddictScopes", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserClaims", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn), + ClaimType = table.Column(nullable: true), + ClaimValue = table.Column(nullable: true), + UserId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserClaims", x => x.Id); + table.ForeignKey( + name: "FK_AspNetUserClaims_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserLogins", + columns: table => new + { + LoginProvider = table.Column(nullable: false), + ProviderKey = table.Column(nullable: false), + ProviderDisplayName = table.Column(nullable: true), + UserId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey }); + table.ForeignKey( + name: "FK_AspNetUserLogins_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetRoleClaims", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn), + ClaimType = table.Column(nullable: true), + ClaimValue = table.Column(nullable: true), + RoleId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id); + table.ForeignKey( + name: "FK_AspNetRoleClaims_AspNetRoles_RoleId", + column: x => x.RoleId, + principalTable: "AspNetRoles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserRoles", + columns: table => new + { + UserId = table.Column(nullable: false), + RoleId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId }); + table.ForeignKey( + name: "FK_AspNetUserRoles_AspNetRoles_RoleId", + column: x => x.RoleId, + principalTable: "AspNetRoles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_AspNetUserRoles_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "OpenIddictAuthorizations", + columns: table => new + { + Id = table.Column(nullable: false), + ApplicationId = table.Column(nullable: true), + Scope = table.Column(nullable: true), + Subject = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_OpenIddictAuthorizations", x => x.Id); + table.ForeignKey( + name: "FK_OpenIddictAuthorizations_OpenIddictApplications_ApplicationId", + column: x => x.ApplicationId, + principalTable: "OpenIddictApplications", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "OpenIddictTokens", + columns: table => new + { + Id = table.Column(nullable: false), + ApplicationId = table.Column(nullable: true), + AuthorizationId = table.Column(nullable: true), + Subject = table.Column(nullable: true), + Type = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_OpenIddictTokens", x => x.Id); + table.ForeignKey( + name: "FK_OpenIddictTokens_OpenIddictApplications_ApplicationId", + column: x => x.ApplicationId, + principalTable: "OpenIddictApplications", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_OpenIddictTokens_OpenIddictAuthorizations_AuthorizationId", + column: x => x.AuthorizationId, + principalTable: "OpenIddictAuthorizations", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateIndex( + name: "EmailIndex", + table: "AspNetUsers", + column: "NormalizedEmail"); + + migrationBuilder.CreateIndex( + name: "UserNameIndex", + table: "AspNetUsers", + column: "NormalizedUserName", + unique: true); + + migrationBuilder.CreateIndex( + name: "RoleNameIndex", + table: "AspNetRoles", + column: "NormalizedName", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_AspNetRoleClaims_RoleId", + table: "AspNetRoleClaims", + column: "RoleId"); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserClaims_UserId", + table: "AspNetUserClaims", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserLogins_UserId", + table: "AspNetUserLogins", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserRoles_RoleId", + table: "AspNetUserRoles", + column: "RoleId"); + + migrationBuilder.CreateIndex( + name: "IX_OpenIddictApplications_ClientId", + table: "OpenIddictApplications", + column: "ClientId", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_OpenIddictAuthorizations_ApplicationId", + table: "OpenIddictAuthorizations", + column: "ApplicationId"); + + migrationBuilder.CreateIndex( + name: "IX_OpenIddictTokens_ApplicationId", + table: "OpenIddictTokens", + column: "ApplicationId"); + + migrationBuilder.CreateIndex( + name: "IX_OpenIddictTokens_AuthorizationId", + table: "OpenIddictTokens", + column: "AuthorizationId"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Contacts"); + + migrationBuilder.DropTable( + name: "AspNetRoleClaims"); + + migrationBuilder.DropTable( + name: "AspNetUserClaims"); + + migrationBuilder.DropTable( + name: "AspNetUserLogins"); + + migrationBuilder.DropTable( + name: "AspNetUserRoles"); + + migrationBuilder.DropTable( + name: "AspNetUserTokens"); + + migrationBuilder.DropTable( + name: "OpenIddictScopes"); + + migrationBuilder.DropTable( + name: "OpenIddictTokens"); + + migrationBuilder.DropTable( + name: "AspNetRoles"); + + migrationBuilder.DropTable( + name: "AspNetUsers"); + + migrationBuilder.DropTable( + name: "OpenIddictAuthorizations"); + + migrationBuilder.DropTable( + name: "OpenIddictApplications"); + } + } +} diff --git a/api/Migrations/20170421213657_1492810608.Designer.cs b/api/Migrations/20170421213657_1492810608.Designer.cs new file mode 100755 index 0000000..3185fe2 --- /dev/null +++ b/api/Migrations/20170421213657_1492810608.Designer.cs @@ -0,0 +1,330 @@ +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using aspnetCoreReactTemplate.Models; + +namespace api.Migrations +{ + [DbContext(typeof(DefaultDbContext))] + [Migration("20170421213657_1492810608")] + partial class _1492810608 + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { + modelBuilder + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn) + .HasAnnotation("ProductVersion", "1.1.1"); + + modelBuilder.Entity("aspnetCoreReactTemplate.Models.ApplicationUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AccessFailedCount"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken(); + + b.Property("Email") + .HasMaxLength(256); + + b.Property("EmailConfirmed"); + + b.Property("GivenName"); + + b.Property("LockoutEnabled"); + + b.Property("LockoutEnd"); + + b.Property("NormalizedEmail") + .HasMaxLength(256); + + b.Property("NormalizedUserName") + .HasMaxLength(256); + + b.Property("PasswordHash"); + + b.Property("PhoneNumber"); + + b.Property("PhoneNumberConfirmed"); + + b.Property("SecurityStamp"); + + b.Property("TwoFactorEnabled"); + + b.Property("UserName") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasName("UserNameIndex"); + + b.ToTable("AspNetUsers"); + }); + + modelBuilder.Entity("aspnetCoreReactTemplate.Models.Contact", b => + { + b.Property("contactId") + .ValueGeneratedOnAdd(); + + b.Property("email"); + + b.Property("firstName"); + + b.Property("lastName"); + + b.Property("phone"); + + b.HasKey("contactId"); + + b.ToTable("Contacts"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken(); + + b.Property("Name") + .HasMaxLength(256); + + b.Property("NormalizedName") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasName("RoleNameIndex"); + + b.ToTable("AspNetRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ClaimType"); + + b.Property("ClaimValue"); + + b.Property("RoleId") + .IsRequired(); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ClaimType"); + + b.Property("ClaimValue"); + + b.Property("UserId") + .IsRequired(); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserLogin", b => + { + b.Property("LoginProvider"); + + b.Property("ProviderKey"); + + b.Property("ProviderDisplayName"); + + b.Property("UserId") + .IsRequired(); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserRole", b => + { + b.Property("UserId"); + + b.Property("RoleId"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserToken", b => + { + b.Property("UserId"); + + b.Property("LoginProvider"); + + b.Property("Name"); + + b.Property("Value"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens"); + }); + + modelBuilder.Entity("OpenIddict.Models.OpenIddictApplication", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ClientId"); + + b.Property("ClientSecret"); + + b.Property("DisplayName"); + + b.Property("LogoutRedirectUri"); + + b.Property("RedirectUri"); + + b.Property("Type"); + + b.HasKey("Id"); + + b.HasIndex("ClientId") + .IsUnique(); + + b.ToTable("OpenIddictApplications"); + }); + + modelBuilder.Entity("OpenIddict.Models.OpenIddictAuthorization", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ApplicationId"); + + b.Property("Scope"); + + b.Property("Subject"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationId"); + + b.ToTable("OpenIddictAuthorizations"); + }); + + modelBuilder.Entity("OpenIddict.Models.OpenIddictScope", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Description"); + + b.HasKey("Id"); + + b.ToTable("OpenIddictScopes"); + }); + + modelBuilder.Entity("OpenIddict.Models.OpenIddictToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ApplicationId"); + + b.Property("AuthorizationId"); + + b.Property("Subject"); + + b.Property("Type"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationId"); + + b.HasIndex("AuthorizationId"); + + b.ToTable("OpenIddictTokens"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRole") + .WithMany("Claims") + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserClaim", b => + { + b.HasOne("aspnetCoreReactTemplate.Models.ApplicationUser") + .WithMany("Claims") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserLogin", b => + { + b.HasOne("aspnetCoreReactTemplate.Models.ApplicationUser") + .WithMany("Logins") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRole") + .WithMany("Users") + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("aspnetCoreReactTemplate.Models.ApplicationUser") + .WithMany("Roles") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("OpenIddict.Models.OpenIddictAuthorization", b => + { + b.HasOne("OpenIddict.Models.OpenIddictApplication", "Application") + .WithMany("Authorizations") + .HasForeignKey("ApplicationId"); + }); + + modelBuilder.Entity("OpenIddict.Models.OpenIddictToken", b => + { + b.HasOne("OpenIddict.Models.OpenIddictApplication", "Application") + .WithMany("Tokens") + .HasForeignKey("ApplicationId"); + + b.HasOne("OpenIddict.Models.OpenIddictAuthorization", "Authorization") + .WithMany("Tokens") + .HasForeignKey("AuthorizationId"); + }); + } + } +} diff --git a/api/Migrations/20170421213657_1492810608.cs b/api/Migrations/20170421213657_1492810608.cs new file mode 100755 index 0000000..b8fcc78 --- /dev/null +++ b/api/Migrations/20170421213657_1492810608.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace api.Migrations +{ + public partial class _1492810608 : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.RenameColumn( + name: "name", + table: "Contacts", + newName: "lastName"); + + migrationBuilder.AddColumn( + name: "firstName", + table: "Contacts", + nullable: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "firstName", + table: "Contacts"); + + migrationBuilder.RenameColumn( + name: "lastName", + table: "Contacts", + newName: "name"); + } + } +} diff --git a/api/Migrations/DefaultDbContextModelSnapshot.cs b/api/Migrations/DefaultDbContextModelSnapshot.cs new file mode 100755 index 0000000..e06d0ff --- /dev/null +++ b/api/Migrations/DefaultDbContextModelSnapshot.cs @@ -0,0 +1,329 @@ +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using aspnetCoreReactTemplate.Models; + +namespace api.Migrations +{ + [DbContext(typeof(DefaultDbContext))] + partial class DefaultDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { + modelBuilder + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn) + .HasAnnotation("ProductVersion", "1.1.1"); + + modelBuilder.Entity("aspnetCoreReactTemplate.Models.ApplicationUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AccessFailedCount"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken(); + + b.Property("Email") + .HasMaxLength(256); + + b.Property("EmailConfirmed"); + + b.Property("GivenName"); + + b.Property("LockoutEnabled"); + + b.Property("LockoutEnd"); + + b.Property("NormalizedEmail") + .HasMaxLength(256); + + b.Property("NormalizedUserName") + .HasMaxLength(256); + + b.Property("PasswordHash"); + + b.Property("PhoneNumber"); + + b.Property("PhoneNumberConfirmed"); + + b.Property("SecurityStamp"); + + b.Property("TwoFactorEnabled"); + + b.Property("UserName") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasName("UserNameIndex"); + + b.ToTable("AspNetUsers"); + }); + + modelBuilder.Entity("aspnetCoreReactTemplate.Models.Contact", b => + { + b.Property("contactId") + .ValueGeneratedOnAdd(); + + b.Property("email"); + + b.Property("firstName"); + + b.Property("lastName"); + + b.Property("phone"); + + b.HasKey("contactId"); + + b.ToTable("Contacts"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken(); + + b.Property("Name") + .HasMaxLength(256); + + b.Property("NormalizedName") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasName("RoleNameIndex"); + + b.ToTable("AspNetRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ClaimType"); + + b.Property("ClaimValue"); + + b.Property("RoleId") + .IsRequired(); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ClaimType"); + + b.Property("ClaimValue"); + + b.Property("UserId") + .IsRequired(); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserLogin", b => + { + b.Property("LoginProvider"); + + b.Property("ProviderKey"); + + b.Property("ProviderDisplayName"); + + b.Property("UserId") + .IsRequired(); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserRole", b => + { + b.Property("UserId"); + + b.Property("RoleId"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserToken", b => + { + b.Property("UserId"); + + b.Property("LoginProvider"); + + b.Property("Name"); + + b.Property("Value"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens"); + }); + + modelBuilder.Entity("OpenIddict.Models.OpenIddictApplication", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ClientId"); + + b.Property("ClientSecret"); + + b.Property("DisplayName"); + + b.Property("LogoutRedirectUri"); + + b.Property("RedirectUri"); + + b.Property("Type"); + + b.HasKey("Id"); + + b.HasIndex("ClientId") + .IsUnique(); + + b.ToTable("OpenIddictApplications"); + }); + + modelBuilder.Entity("OpenIddict.Models.OpenIddictAuthorization", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ApplicationId"); + + b.Property("Scope"); + + b.Property("Subject"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationId"); + + b.ToTable("OpenIddictAuthorizations"); + }); + + modelBuilder.Entity("OpenIddict.Models.OpenIddictScope", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Description"); + + b.HasKey("Id"); + + b.ToTable("OpenIddictScopes"); + }); + + modelBuilder.Entity("OpenIddict.Models.OpenIddictToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ApplicationId"); + + b.Property("AuthorizationId"); + + b.Property("Subject"); + + b.Property("Type"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationId"); + + b.HasIndex("AuthorizationId"); + + b.ToTable("OpenIddictTokens"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRole") + .WithMany("Claims") + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserClaim", b => + { + b.HasOne("aspnetCoreReactTemplate.Models.ApplicationUser") + .WithMany("Claims") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserLogin", b => + { + b.HasOne("aspnetCoreReactTemplate.Models.ApplicationUser") + .WithMany("Logins") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRole") + .WithMany("Users") + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("aspnetCoreReactTemplate.Models.ApplicationUser") + .WithMany("Roles") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("OpenIddict.Models.OpenIddictAuthorization", b => + { + b.HasOne("OpenIddict.Models.OpenIddictApplication", "Application") + .WithMany("Authorizations") + .HasForeignKey("ApplicationId"); + }); + + modelBuilder.Entity("OpenIddict.Models.OpenIddictToken", b => + { + b.HasOne("OpenIddict.Models.OpenIddictApplication", "Application") + .WithMany("Tokens") + .HasForeignKey("ApplicationId"); + + b.HasOne("OpenIddict.Models.OpenIddictAuthorization", "Authorization") + .WithMany("Tokens") + .HasForeignKey("AuthorizationId"); + }); + } + } +} diff --git a/api/Models/ApplicationUser.cs b/api/Models/ApplicationUser.cs new file mode 100644 index 0000000..250b026 --- /dev/null +++ b/api/Models/ApplicationUser.cs @@ -0,0 +1,9 @@ +using Microsoft.AspNetCore.Identity.EntityFrameworkCore; + +namespace aspnetCoreReactTemplate.Models +{ + public class ApplicationUser: IdentityUser + { + public string GivenName { get; set; } + } +} diff --git a/api/Models/Contact.cs b/api/Models/Contact.cs new file mode 100644 index 0000000..01e8710 --- /dev/null +++ b/api/Models/Contact.cs @@ -0,0 +1,23 @@ +using System.ComponentModel.DataAnnotations; + +namespace aspnetCoreReactTemplate.Models +{ + public class Contact + { + public int contactId { 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; } + } +} diff --git a/api/Models/DefaultDbContext.cs b/api/Models/DefaultDbContext.cs new file mode 100644 index 0000000..1d70cd3 --- /dev/null +++ b/api/Models/DefaultDbContext.cs @@ -0,0 +1,21 @@ +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); + } + } +} diff --git a/api/Models/DefaultDbContextInitializer.cs b/api/Models/DefaultDbContextInitializer.cs new file mode 100644 index 0000000..598b889 --- /dev/null +++ b/api/Models/DefaultDbContextInitializer.cs @@ -0,0 +1,69 @@ +using Microsoft.AspNetCore.Identity; +using Microsoft.EntityFrameworkCore; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Identity.EntityFrameworkCore; + +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 void Migrate() + { + _context.Database.Migrate(); + } + + public async Task Seed() + { + var email = "user@test.com"; + if (await _userManager.FindByEmailAsync(email) == null) + { + ApplicationUser 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(); + void Migrate(); + Task Seed(); + + } +} diff --git a/api/NuGet.Config b/api/NuGet.Config new file mode 100644 index 0000000..ae8aea9 --- /dev/null +++ b/api/NuGet.Config @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/api/Program.cs b/api/Program.cs new file mode 100755 index 0000000..67ebb58 --- /dev/null +++ b/api/Program.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; + +namespace aspnetCoreReactTemplate +{ + public class Program + { + public static void Main(string[] args) + { + var host = new WebHostBuilder() + .UseKestrel() + .UseUrls($"http://0.0.0.0:5000") + .UseContentRoot(Directory.GetCurrentDirectory()) + .UseStartup() + .Build(); + + host.Run(); + } + } +} diff --git a/api/Services/EmailSender.cs b/api/Services/EmailSender.cs new file mode 100644 index 0000000..cdfd86f --- /dev/null +++ b/api/Services/EmailSender.cs @@ -0,0 +1,54 @@ +using System.Threading.Tasks; +using MailKit.Net.Smtp; +using Microsoft.Extensions.Options; +using MimeKit; + +namespace aspnetCoreReactTemplate.Services +{ + public class EmailSender : IEmailSender + { + public EmailSender(IOptions optionsAccessor) + { + Options = optionsAccessor.Value; + } + + public EmailSenderOptions Options { get; } + + public Task SendEmailAsync(string toEmail, string subject, string htmlMessage, string textMessage = null) + { + var mimeMessage = new MimeMessage(); + mimeMessage.From.Add(new MailboxAddress(this.Options.emailFromName, this.Options.emailFromAddress)); + mimeMessage.To.Add(new MailboxAddress(toEmail)); + mimeMessage.Subject = subject; + + var bodyBuilder = new BodyBuilder(); + bodyBuilder.HtmlBody = htmlMessage; + bodyBuilder.TextBody = textMessage ?? htmlMessage; + + mimeMessage.Body = bodyBuilder.ToMessageBody(); + + using (var client = new SmtpClient()) + { + // For demo-purposes, accept all SSL certificates (in case the server supports STARTTLS) + client.ServerCertificateValidationCallback = (s, c, h, e) => true; + + client.Connect(this.Options.host, this.Options.port, false); + + // Note: since we don't have an OAuth2 token, disable + // the XOAUTH2 authentication mechanism. + client.AuthenticationMechanisms.Remove("XOAUTH2"); + + // Note: only needed if the SMTP server requires authentication + if (!string.IsNullOrEmpty(this.Options.username)) + { + client.Authenticate(this.Options.username, this.Options.password); + } + + client.Send(mimeMessage); + client.Disconnect(true); + } + + return Task.FromResult(0); + } + } +} diff --git a/api/Services/EmailSenderOptions.cs b/api/Services/EmailSenderOptions.cs new file mode 100644 index 0000000..4a9842a --- /dev/null +++ b/api/Services/EmailSenderOptions.cs @@ -0,0 +1,35 @@ +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 string username { get; protected set; } + public string password { get; protected set; } + public string host { get; protected set; } + public int port { get; protected set; } + } +} diff --git a/api/Services/IEmailSender.cs b/api/Services/IEmailSender.cs new file mode 100644 index 0000000..aac0932 --- /dev/null +++ b/api/Services/IEmailSender.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; + +namespace aspnetCoreReactTemplate.Services +{ + public interface IEmailSender + { + Task SendEmailAsync(string toEmail, string subject, string htmlMessage, string textMessage = null); + } +} diff --git a/api/Startup.cs b/api/Startup.cs new file mode 100644 index 0000000..a57d6a2 --- /dev/null +++ b/api/Startup.cs @@ -0,0 +1,176 @@ +using System; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Identity.EntityFrameworkCore; +using Microsoft.AspNetCore.SpaServices.Webpack; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.EntityFrameworkCore; +using aspnetCoreReactTemplate.Models; +using System.IdentityModel.Tokens.Jwt; +using AspNet.Security.OpenIdConnect.Primitives; +using aspnetCoreReactTemplate.Services; +using Microsoft.AspNetCore.HttpOverrides; + +namespace aspnetCoreReactTemplate +{ + public class Startup + { + public IHostingEnvironment CurrentEnvironment { get; protected set; } + public IConfigurationRoot Configuration { get; } + + public Startup(IHostingEnvironment env) + { + this.CurrentEnvironment = env; + + var builder = new ConfigurationBuilder() + .SetBasePath(env.ContentRootPath) + .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) + .AddEnvironmentVariables(); + + Configuration = builder.Build(); + } + + // This method gets called by the runtime. Use this method to add services to the container. + public void ConfigureServices(IServiceCollection services) + { + services.AddEntityFrameworkNpgsql().AddDbContext(options => + { + options.UseNpgsql(Configuration.GetConnectionString("defaultConnection")); + options.UseOpenIddict(); + }); + + // Configure Entity Framework Initializer for seeding + services.AddTransient(); + + // Configure Entity Framework Identity for Auth + services.AddIdentity(o => + { + // Do not 302 redirect when Unauthorized; just return 401 status code (ref: http://stackoverflow.com/a/38801130/626911) + o.Cookies.ApplicationCookie.AutomaticChallenge = false; + }) + .AddEntityFrameworkStores() + .AddDefaultTokenProviders(); + + // Configure Identity to use the same JWT claims as OpenIddict instead + // of the legacy WS-Federation claims it uses by default (ClaimTypes), + // which saves you from doing the mapping in your authorization controller. + services.Configure(options => + { + options.ClaimsIdentity.UserNameClaimType = OpenIdConnectConstants.Claims.Name; + options.ClaimsIdentity.UserIdClaimType = OpenIdConnectConstants.Claims.Subject; + options.ClaimsIdentity.RoleClaimType = OpenIdConnectConstants.Claims.Role; + options.SignIn.RequireConfirmedEmail = true; + }); + + // Configure OpenIddict for JSON Web Token (JWT) generation (Ref: http://capesean.co.za/blog/asp-net-5-jwt-tokens/) + // Register the OpenIddict services. + // Note: use the generic overload if you need + // to replace the default OpenIddict entities. + services.AddOpenIddict(options => + { + // Register the Entity Framework stores. + options.AddEntityFrameworkCoreStores(); + + // Register the ASP.NET Core MVC binder used by OpenIddict. + // Note: if you don't call this method, you won't be able to + // bind OpenIdConnectRequest or OpenIdConnectResponse parameters. + options.AddMvcBinders(); + + // Enable the token endpoint (required to use the password flow). + options.EnableTokenEndpoint("/api/auth/login"); + + // Allow client applications to use the grant_type=password flow. + options.AllowPasswordFlow(); + + // During development, you can disable the HTTPS requirement. + options.DisableHttpsRequirement(); + + options.AllowRefreshTokenFlow(); + options.UseJsonWebTokens(); + options.AddEphemeralSigningKey(); + options.SetAccessTokenLifetime(TimeSpan.FromDays(1)); + }); + + services.AddTransient(); + services.Configure(Configuration.GetSection("email")); + + // Add framework services + services.AddMvc().AddJsonOptions(options => + { + options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore; + }); + } + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IDefaultDbContextInitializer databaseInitializer) + { + // Log to console (stdout) - in production stdout will be written to /var/log/{{app_name}}.out.log + loggerFactory.AddConsole(Configuration.GetSection("logging")); + loggerFactory.AddDebug(); + + // Apply any pending migrations + // Do not call EnsureCreated() b/c it does not log to _EFMigrationsHistory table (Ref: https://github.com/aspnet/EntityFramework/issues/3875) + databaseInitializer.Migrate(); + + if (env.IsDevelopment()) + { + databaseInitializer.Seed().GetAwaiter().GetResult(); + + // Configure Webpack Middleware (Ref: http://blog.stevensanderson.com/2016/05/02/angular2-react-knockout-apps-on-aspnet-core/) + // - Intercepts requests for webpack bundles and routes them through Webpack - this prevents needing to run Webpack file watcher separately + // - Enables Hot module replacement (HMR) + app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions + { + HotModuleReplacement = true, + ReactHotModuleReplacement = true, + ConfigFile = System.IO.Path.Combine(Configuration["webClientPath"], "webpack.config.js") + }); + + app.UseDeveloperExceptionPage(); + app.UseDatabaseErrorPage(); + } + + // If not requesting /api*, rewrite to / so SPA app will be returned + app.UseSpaFallback(new SpaFallbackOptions() + { + ApiPathPrefix = "/api", + RewritePath = "/" + }); + + app.UseDefaultFiles(); + 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 + }); + + // Register the validation middleware, that is used to decrypt + // the access tokens and populate the HttpContext.User property. + app.UseOAuthValidation(); + + + JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); + JwtSecurityTokenHandler.DefaultOutboundClaimTypeMap.Clear(); + + // Use JWT Bearer Authentication (i.e. authenitcate with JWT in HTTP request header) + app.UseJwtBearerAuthentication(new JwtBearerOptions + { + AutomaticAuthenticate = true, + AutomaticChallenge = true, + RequireHttpsMetadata = false, + Audience = "resource-server", + Authority = Configuration["url"] + }); + + app.UseOpenIddict(); + app.UseIdentity(); + app.UseMvc(); + } + } +} diff --git a/api/ViewModels/ConfirmEmail.cs b/api/ViewModels/ConfirmEmail.cs new file mode 100644 index 0000000..59e0af3 --- /dev/null +++ b/api/ViewModels/ConfirmEmail.cs @@ -0,0 +1,8 @@ +namespace aspnetCoreReactTemplate.ViewModels +{ + public class ConfirmEmail + { + public string user_id { get; set; } + public string token { get; set; } + } +} diff --git a/api/ViewModels/NewUser.cs b/api/ViewModels/NewUser.cs new file mode 100644 index 0000000..bfc1bbd --- /dev/null +++ b/api/ViewModels/NewUser.cs @@ -0,0 +1,15 @@ +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; } +} +} diff --git a/api/api.csproj b/api/api.csproj new file mode 100755 index 0000000..a4f3a98 --- /dev/null +++ b/api/api.csproj @@ -0,0 +1,42 @@ + + + netcoreapp1.1 + $(PackageTargetFallback);portable-win+net45+wp8+win81+wpa8 + api + Exe + api + + + + PreserveNewest + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/api/appsettings.json b/api/appsettings.json new file mode 100644 index 0000000..2607802 --- /dev/null +++ b/api/appsettings.json @@ -0,0 +1,20 @@ +{ + "connectionStrings": { + "defaultConnection": "Host=localhost;Port=5433;Username=postgres;Password=postgres;Database=dotnetcore" + }, + "url": "http://localhost:5000", + "logging": { + "includeScopes": false, + "logLevel": { + "default": "Debug", + "system": "Information", + "microsoft": "Information" + } + }, + "webClientPath": "../client-web", + "email": { + "smtpConfig": ":@localhost:1025", + "emailFromName": "aspnet-core-vuejs-template", + "emailFromAddress": "noreply@aspnet-core-react-template.com" + } +} diff --git a/api/log/development-20170420.log b/api/log/development-20170420.log new file mode 100755 index 0000000..a4354fd --- /dev/null +++ b/api/log/development-20170420.log @@ -0,0 +1,1196 @@ +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) diff --git a/api/wwwroot/favicon.ico b/api/wwwroot/favicon.ico new file mode 100644 index 0000000..85a4d9f Binary files /dev/null and b/api/wwwroot/favicon.ico differ diff --git a/api/wwwroot/scratch.html b/api/wwwroot/scratch.html new file mode 100644 index 0000000..2f96329 --- /dev/null +++ b/api/wwwroot/scratch.html @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + +
+ +
+

Bootstrap starter template

+

Use this document as a way to quickly start any new project.
All you get is this text and a mostly barebones HTML + document.

+
+ +
+ + + + + + + + + diff --git a/client-web.test/tests.ts b/client-web.test/tests.ts new file mode 100644 index 0000000..3683eb3 --- /dev/null +++ b/client-web.test/tests.ts @@ -0,0 +1,13 @@ +import * as jsdom from "jsdom"; + +before(function () { + const doc = jsdom.jsdom(''); + const win = doc.defaultView; + + (global as any).document = doc; + (global as any).window = win; + + localStorage.polyfill(); + + console.log("Successfully mocked a DOM with jsdom and polyfilled localStorage."); +}); diff --git a/client-web.test/tsconfig.json b/client-web.test/tsconfig.json new file mode 100644 index 0000000..5edfd4f --- /dev/null +++ b/client-web.test/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "sourceMap": true, + "noImplicitAny": true, + "module": "commonjs", + "target":"es2015", + "jsx": "react", + "allowJs": true, + "outDir": "./build" + }, + "files": [ + "./tests.tsx" + ], + "include": [ + "./tests/*.ts*" + ] +} diff --git a/client-web/App.vue b/client-web/App.vue new file mode 100644 index 0000000..fa6c524 --- /dev/null +++ b/client-web/App.vue @@ -0,0 +1,42 @@ + + + + + diff --git a/client-web/boot.ts b/client-web/boot.ts new file mode 100644 index 0000000..23c3c58 --- /dev/null +++ b/client-web/boot.ts @@ -0,0 +1,38 @@ +import Vue from 'vue' +import VueRouter from 'vue-router'; +import App from './App.vue' +import AuthLayout from './layouts/Auth.vue'; +import DefaultLayout from './layouts/Default.vue'; +import SignIn from './pages/SignIn.vue'; +import Register from './pages/Register.vue'; +import Contacts from './pages/Contacts.vue'; +import ContactForm from './components/ContactForm.vue'; + +Vue.use(VueRouter); + +let router = new VueRouter({ + mode: 'history', + routes: [ + { + path: '', component: AuthLayout, + children: [ + { path: '/', component: SignIn }, + { path: '/register', component: Register }, + ] + }, + { + path: '', component: DefaultLayout, + children: [ + { path: '/contacts', component: Contacts }, + { path: '/contacts/new', component: ContactForm }, + { path: '/contacts/edit/:id', name: 'editContact', component: ContactForm } + ] + }, + ] +}); + +new Vue({ + el: '#app', + router: router, + render: h => h(App, {}) +}); diff --git a/client-web/components/ContactForm.vue b/client-web/components/ContactForm.vue new file mode 100644 index 0000000..06275ab --- /dev/null +++ b/client-web/components/ContactForm.vue @@ -0,0 +1,79 @@ + + + diff --git a/client-web/components/RegisterComplete.vue b/client-web/components/RegisterComplete.vue new file mode 100644 index 0000000..21d7d22 --- /dev/null +++ b/client-web/components/RegisterComplete.vue @@ -0,0 +1,27 @@ + + + + + diff --git a/client-web/index.template.html b/client-web/index.template.html new file mode 100644 index 0000000..a3467d3 --- /dev/null +++ b/client-web/index.template.html @@ -0,0 +1,22 @@ + + + + + + + + aspnet-core-vuejs-template + + + +
+ + <%if (htmlWebpackPlugin.options.useCdn) { %> + + + <% } %> + + + + + diff --git a/client-web/layouts/Auth.vue b/client-web/layouts/Auth.vue new file mode 100644 index 0000000..10bd164 --- /dev/null +++ b/client-web/layouts/Auth.vue @@ -0,0 +1,13 @@ + + + diff --git a/client-web/layouts/Default.vue b/client-web/layouts/Default.vue new file mode 100644 index 0000000..ff4f26b --- /dev/null +++ b/client-web/layouts/Default.vue @@ -0,0 +1,53 @@ + + + diff --git a/client-web/pages/Contacts.vue b/client-web/pages/Contacts.vue new file mode 100644 index 0000000..c77cd8c --- /dev/null +++ b/client-web/pages/Contacts.vue @@ -0,0 +1,85 @@ + + + + + diff --git a/client-web/pages/Register.vue b/client-web/pages/Register.vue new file mode 100644 index 0000000..cfc734e --- /dev/null +++ b/client-web/pages/Register.vue @@ -0,0 +1,56 @@ + + + + + diff --git a/client-web/pages/SignIn.vue b/client-web/pages/SignIn.vue new file mode 100644 index 0000000..2d60c9e --- /dev/null +++ b/client-web/pages/SignIn.vue @@ -0,0 +1,67 @@ + + + + + diff --git a/client-web/polyfills/array-find.d.ts b/client-web/polyfills/array-find.d.ts new file mode 100644 index 0000000..d4f50b8 --- /dev/null +++ b/client-web/polyfills/array-find.d.ts @@ -0,0 +1,3 @@ +interface Array { + find(predicate: (search: T) => boolean): T; +} diff --git a/client-web/polyfills/array-find.ts b/client-web/polyfills/array-find.ts new file mode 100644 index 0000000..6f2f427 --- /dev/null +++ b/client-web/polyfills/array-find.ts @@ -0,0 +1,46 @@ +/// + +// 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; + } + }); +} diff --git a/client-web/polyfills/object-assign.d.ts b/client-web/polyfills/object-assign.d.ts new file mode 100644 index 0000000..7841625 --- /dev/null +++ b/client-web/polyfills/object-assign.d.ts @@ -0,0 +1,3 @@ +declare interface ObjectConstructor { + assign(...objects: Object[]): Object; +} diff --git a/client-web/polyfills/object-assign.ts b/client-web/polyfills/object-assign.ts new file mode 100644 index 0000000..ec26dff --- /dev/null +++ b/client-web/polyfills/object-assign.ts @@ -0,0 +1,26 @@ +/// + +if (typeof Object.assign != 'function') { + Object.assign = function (target, varArgs) { // .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; + }; +} diff --git a/client-web/polyfills/string-startsWith.d.ts b/client-web/polyfills/string-startsWith.d.ts new file mode 100644 index 0000000..0dc97c0 --- /dev/null +++ b/client-web/polyfills/string-startsWith.d.ts @@ -0,0 +1,3 @@ +interface String { + startsWith(searchString: String, position?: number): boolean; +} diff --git a/client-web/polyfills/string-startsWith.ts b/client-web/polyfills/string-startsWith.ts new file mode 100644 index 0000000..403cbc6 --- /dev/null +++ b/client-web/polyfills/string-startsWith.ts @@ -0,0 +1,7 @@ +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith +if (!String.prototype.startsWith) { + String.prototype.startsWith = function(searchString, position){ + position = position || 0; + return this.substr(position, searchString.length) === searchString; + }; +} diff --git a/client-web/services/Auth.ts b/client-web/services/Auth.ts new file mode 100644 index 0000000..209a847 --- /dev/null +++ b/client-web/services/Auth.ts @@ -0,0 +1,45 @@ +import RestUtilities from './RestUtilities'; +import AuthStore from '../stores/Auth'; + +interface IAuthResponse { + access_token: string; +} + +export default class Auth { + static isSignedInIn(): 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.access_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(); + } +} diff --git a/client-web/services/Contacts.ts b/client-web/services/Contacts.ts new file mode 100644 index 0000000..b11529b --- /dev/null +++ b/client-web/services/Contacts.ts @@ -0,0 +1,44 @@ +import RestUtilities from './RestUtilities'; + +export interface IContact { + contactId?: 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.contactId}`, contact); + } + + create(contact: IContact) { + return RestUtilities.post('/api/contacts', contact); + } + + save(contact: IContact) { + if (contact.contactId) { + return this.update(contact); + } else { + return this.create(contact); + } + } + + delete(contactId: number) { + return RestUtilities.delete(`/api/contacts/${contactId}`); + } +} + diff --git a/client-web/services/RestUtilities.ts b/client-web/services/RestUtilities.ts new file mode 100644 index 0000000..38c1c22 --- /dev/null +++ b/client-web/services/RestUtilities.ts @@ -0,0 +1,81 @@ +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: { [key: string]: string } = { + 'Authorization': `Bearer ${AuthStore.getToken()}`, + 'Accept': 'application/json' + }; + + if (data) { + if ((typeof data === 'object')) { + headers['Content-Type'] = 'application/json'; + body = JSON.stringify(data); + } else { + headers['Content-Type'] = 'application/x-www-form-urlencoded'; + } + } + + return fetch(url, { + method: method, + headers: headers, + body: body, + }).then((response) => { + if (response.status == 401) { + // Unauthorized; redirect to sign-in + AuthStore.removeToken(); + window.location.replace(`/?expired=1`); + } + + isBadRequest = !response.status.toString().startsWith("2"); + + 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; + }); + } +} diff --git a/client-web/sfc.d.ts b/client-web/sfc.d.ts new file mode 100644 index 0000000..7a4c31b --- /dev/null +++ b/client-web/sfc.d.ts @@ -0,0 +1,4 @@ +declare module "*.vue" { + import Vue from 'vue' + export default typeof Vue +} diff --git a/client-web/stores/Auth.ts b/client-web/stores/Auth.ts new file mode 100644 index 0000000..887d2b5 --- /dev/null +++ b/client-web/stores/Auth.ts @@ -0,0 +1,15 @@ +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); + } +} diff --git a/client-web/styles/auth.styl b/client-web/styles/auth.styl new file mode 100644 index 0000000..7d93b3a --- /dev/null +++ b/client-web/styles/auth.styl @@ -0,0 +1,46 @@ +.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; + } +} diff --git a/client-web/styles/contacts.styl b/client-web/styles/contacts.styl new file mode 100644 index 0000000..196558a --- /dev/null +++ b/client-web/styles/contacts.styl @@ -0,0 +1,3 @@ +.content { + padding: 3rem 1.5rem; +} diff --git a/client-web/styles/global.css b/client-web/styles/global.css new file mode 100644 index 0000000..2a8fbc5 --- /dev/null +++ b/client-web/styles/global.css @@ -0,0 +1,13 @@ +body { + padding-top: 5rem; + font-family: "century gothic", verdana; + +} + +.btn-link { + cursor: pointer; +} + +.btn { + margin: 10px 3px 10px 3px; +} diff --git a/client-web/styles/styles.d.ts b/client-web/styles/styles.d.ts new file mode 100644 index 0000000..cac309d --- /dev/null +++ b/client-web/styles/styles.d.ts @@ -0,0 +1,9 @@ +declare module "*.styl" { + let styles: any; + export default styles; +} + +declare module "*.css" { + let styles: any; + export default styles; +} diff --git a/client-web/tsconfig.json b/client-web/tsconfig.json new file mode 100644 index 0000000..b881d3e --- /dev/null +++ b/client-web/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "sourceMap": true, + "noImplicitAny": true, + "allowSyntheticDefaultImports": true, + "experimentalDecorators": true, + "module": "es2015", + "target": "es5", + "lib": [ + "dom", + "es5", + "es2015.promise" + ], + "moduleResolution": "node" + }, + "files": [ + "./boot.ts" + ], + "include": [ + "./**/*.d.ts" + ] +} diff --git a/client-web/webpack.config.js b/client-web/webpack.config.js new file mode 100644 index 0000000..c3b1f12 --- /dev/null +++ b/client-web/webpack.config.js @@ -0,0 +1,69 @@ +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 = { + entry: { + main: path.join(__dirname, 'boot.ts') + }, + output: { + path: path.join(__dirname, '../api/', 'wwwroot'), + filename: '[name].js', + publicPath: '/' + }, + resolve: { + extensions: ['.ts', '.js', '.vue', '.styl', '.css'] + }, + module: { + rules: [ + { + test: /\.styl$/, + use: [{ + loader: 'style-loader' + }, { + loader: 'css-loader', + options: { + modules: true, + camelCase: true, + importLoaders: 2, + sourceMap: false, + localIdentName: "[local]___[hash:base64:5]" + } + }, { + loader: 'stylus-loader' + }] + }, + { + test: /\.ts$/, + loader: 'ts-loader', + options: { + appendTsSuffixTo: [/\.vue$/] + } + }, + { + test: /\.vue$/, + loader: 'vue-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.template.html'), 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; diff --git a/client-web/webpack.config.release.js b/client-web/webpack.config.release.js new file mode 100644 index 0000000..b97555e --- /dev/null +++ b/client-web/webpack.config.release.js @@ -0,0 +1,37 @@ +var webpack = require('webpack'); +var HtmlWebpackPlugin = require('html-webpack-plugin'); +var ExtractTextPlugin = require("extract-text-webpack-plugin"); +var path = require('path'); + +var config = { + module: { + rules: [ + { 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: { + vue: 'Vue', + 'vue-router': 'Router' + }, + plugins: [ + new HtmlWebpackPlugin({ + release: true, + template: path.join(__dirname, 'index.template.html'), + useCdn: true, + minify: { + collapseWhitespace: true, + removeComments: true + } + }), + new webpack.optimize.UglifyJsPlugin({ + compress: { + warnings: false + } + }), + new ExtractTextPlugin("styles.css") + + ] +}; diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..969eccf --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,17 @@ +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" diff --git a/global.json b/global.json new file mode 100644 index 0000000..d2ebb8a --- /dev/null +++ b/global.json @@ -0,0 +1,6 @@ +{ + "projects": [ + "api", + "api.test" + ] +} diff --git a/ops/README.md b/ops/README.md new file mode 100644 index 0000000..976d76a --- /dev/null +++ b/ops/README.md @@ -0,0 +1,17 @@ +This folder contains [Ansible](https://www.ansible.com/) assets responsible for provisioning hosts and deploying this application. + +## Setup + +1. Procure access to Ubuntu 16 host(s) 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 `hosts` file in this directory, using `hosts.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 hosts file. +- `npm run deploy:prod`: This will deploy the app to all production hosts specified in hosts 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 (hosts) to define environment and global variables. Because of this, all the variables are in a single location and easily managed. diff --git a/ops/deploy.yml b/ops/deploy.yml new file mode 100644 index 0000000..a53622a --- /dev/null +++ b/ops/deploy.yml @@ -0,0 +1,9 @@ +--- +- name: deploy + hosts: all + gather_facts: false + remote_user: "{{ deploy_user }}" + roles: + - deploy + post_tasks: + - debug: msg="Deployed to http://{{webserver_name}}" diff --git a/ops/group_vars/all b/ops/group_vars/all new file mode 100644 index 0000000..ff5ca40 --- /dev/null +++ b/ops/group_vars/all @@ -0,0 +1,13 @@ +--- +database_name: "{{ app_name }}" +database_username: "{{ app_name }}" +deploy_directory: "/home/{{ deploy_user }}/apps/{{ app_name }}" +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 }}" + diff --git a/ops/hosts.example b/ops/hosts.example new file mode 100644 index 0000000..80c399e --- /dev/null +++ b/ops/hosts.example @@ -0,0 +1,27 @@ +# Global variables +[all:vars] +app_name=aspnetCoreReactTemplate # Name of the application +source_directory=../../../../appName/bin/Release/netcoreapp1.1/publish/ # The local deploy build asset source location (source files for deploy) +entry_dll_file_name=AppName.dll # The name of the .NET Core DLL to run + +# Production variables +[production_web] +0.0.0.0 # The IP address or hostname of the production web server + +[production: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 +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 + +[production:children] +production_web + +[all:children] +production diff --git a/ops/provision.yml b/ops/provision.yml new file mode 100644 index 0000000..be76c84 --- /dev/null +++ b/ops/provision.yml @@ -0,0 +1,25 @@ +--- +- 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 diff --git a/ops/roles/deploy/defaults/main.yml b/ops/roles/deploy/defaults/main.yml new file mode 100644 index 0000000..679b24f --- /dev/null +++ b/ops/roles/deploy/defaults/main.yml @@ -0,0 +1,2 @@ +--- +appsetting_file: appsettings.json diff --git a/ops/roles/deploy/meta/main.yml b/ops/roles/deploy/meta/main.yml new file mode 100644 index 0000000..22d708f --- /dev/null +++ b/ops/roles/deploy/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: +- role: supervisor diff --git a/ops/roles/deploy/tasks/main.yml b/ops/roles/deploy/tasks/main.yml new file mode 100644 index 0000000..79fa961 --- /dev/null +++ b/ops/roles/deploy/tasks/main.yml @@ -0,0 +1,33 @@ +- 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 email.smtpConfig + lineinfile: dest="{{ deploy_directory }}/{{ appsetting_file }}" + regexp="smtpConfig\":" + line="\"smtpConfig\"{{':'}} \"{{smtp_config}}\"," + state="present" + +- name: Configure email.emailFromName + lineinfile: dest="{{ deploy_directory }}/{{ appsetting_file }}" + regexp="emailFromName\":" + line="\"emailFromName\"{{':'}} \"{{email_from_name}}\"," + state="present" + +- name: Configure email.emailFromAddress + lineinfile: dest="{{ deploy_directory }}/{{ appsetting_file }}" + regexp="emailFromAddress\":" + line="\"emailFromAddress\"{{':'}} \"{{email_from_address}}\"" + state="present" + +- name: Configure app url + lineinfile: dest="{{ deploy_directory }}/{{ appsetting_file }}" + regexp="url\":" + line="\"url\"{{':'}} \"http://{{webserver_name}}/\"," + state="present" diff --git a/ops/roles/deploy_user/meta/main.yml b/ops/roles/deploy_user/meta/main.yml new file mode 100644 index 0000000..731ba3f --- /dev/null +++ b/ops/roles/deploy_user/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: +- role: postgresql diff --git a/ops/roles/deploy_user/tasks/main.yml b/ops/roles/deploy_user/tasks/main.yml new file mode 100644 index 0000000..955e17a --- /dev/null +++ b/ops/roles/deploy_user/tasks/main.yml @@ -0,0 +1,20 @@ +- 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 diff --git a/ops/roles/dotnetcore/defaults/main.yml b/ops/roles/dotnetcore/defaults/main.yml new file mode 100644 index 0000000..5c1aec5 --- /dev/null +++ b/ops/roles/dotnetcore/defaults/main.yml @@ -0,0 +1,2 @@ +--- +dotnetcore_package_name: dotnet-dev-1.0.1 diff --git a/ops/roles/dotnetcore/tasks/main.yml b/ops/roles/dotnetcore/tasks/main.yml new file mode 100644 index 0000000..45e51af --- /dev/null +++ b/ops/roles/dotnetcore/tasks/main.yml @@ -0,0 +1,17 @@ +--- +- name: Create dotnetdev.list file + command: touch /etc/apt/sources.list.d/dotnetdev.list creates="/etc/apt/sources.list.d/dotnetdev.list" + +- name: Set apt-get feed for Ubuntu Xenial + lineinfile: dest=/etc/apt/sources.list.d/dotnetdev.list line="deb [arch=amd64] https://apt-mo.trafficmanager.net/repos/dotnet-release/ xenial main" + when: ansible_distribution == "Ubuntu" and ansible_distribution_major_version == "16" + +- name: Set apt-get feed for Ubuntu Trusty + lineinfile: dest=/etc/apt/sources.list.d/dotnetdev.list line="deb [arch=amd64] https://apt-mo.trafficmanager.net/repos/dotnet-release/ trusty main" + when: ansible_distribution == "Ubuntu" and ansible_distribution_major_version == "14" + +- name: Add apt key + apt_key: keyserver=apt-mo.trafficmanager.net id=417A0893 + +- name: Install dotnet core SDK + apt: name={{ dotnetcore_package_name }} state=present update_cache=yes diff --git a/ops/roles/firewall/handlers/main.yml b/ops/roles/firewall/handlers/main.yml new file mode 100644 index 0000000..2f37afe --- /dev/null +++ b/ops/roles/firewall/handlers/main.yml @@ -0,0 +1,3 @@ +--- +- name: Restart ufw + service: name=ufw state=restarted diff --git a/ops/roles/firewall/tasks/main.yml b/ops/roles/firewall/tasks/main.yml new file mode 100644 index 0000000..adb1659 --- /dev/null +++ b/ops/roles/firewall/tasks/main.yml @@ -0,0 +1,26 @@ +--- +- 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 diff --git a/ops/roles/nginx/defaults/main.yml b/ops/roles/nginx/defaults/main.yml new file mode 100755 index 0000000..713676b --- /dev/null +++ b/ops/roles/nginx/defaults/main.yml @@ -0,0 +1,4 @@ +--- +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" diff --git a/ops/roles/nginx/handlers/main.yml b/ops/roles/nginx/handlers/main.yml new file mode 100755 index 0000000..f57fcfc --- /dev/null +++ b/ops/roles/nginx/handlers/main.yml @@ -0,0 +1,3 @@ +--- +- name: Reload nginx + service: name=nginx state=reloaded enabled=true \ No newline at end of file diff --git a/ops/roles/nginx/tasks/main.yml b/ops/roles/nginx/tasks/main.yml new file mode 100755 index 0000000..3507cf9 --- /dev/null +++ b/ops/roles/nginx/tasks/main.yml @@ -0,0 +1,14 @@ +--- +- 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 diff --git a/ops/roles/nginx/templates/etc_nginx_sites-available.conf.j2 b/ops/roles/nginx/templates/etc_nginx_sites-available.conf.j2 new file mode 100644 index 0000000..1eeae3a --- /dev/null +++ b/ops/roles/nginx/templates/etc_nginx_sites-available.conf.j2 @@ -0,0 +1,36 @@ +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://localhost: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 diff --git a/ops/roles/postgresql/LICENSE b/ops/roles/postgresql/LICENSE new file mode 100644 index 0000000..de682fe --- /dev/null +++ b/ops/roles/postgresql/LICENSE @@ -0,0 +1,21 @@ +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. diff --git a/ops/roles/postgresql/README.md b/ops/roles/postgresql/README.md new file mode 100644 index 0000000..aab9be5 --- /dev/null +++ b/ops/roles/postgresql/README.md @@ -0,0 +1,41 @@ +# 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 diff --git a/ops/roles/postgresql/defaults/main.yml b/ops/roles/postgresql/defaults/main.yml new file mode 100644 index 0000000..33c14de --- /dev/null +++ b/ops/roles/postgresql/defaults/main.yml @@ -0,0 +1,18 @@ +--- +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 diff --git a/ops/roles/postgresql/handlers/main.yml b/ops/roles/postgresql/handlers/main.yml new file mode 100644 index 0000000..1c20b17 --- /dev/null +++ b/ops/roles/postgresql/handlers/main.yml @@ -0,0 +1,7 @@ +--- +- name: Reload Service | postgres + service: + state: reloaded + name: postgresql + tags: + - disruptive diff --git a/ops/roles/postgresql/tasks/backup.yml b/ops/roles/postgresql/tasks/backup.yml new file mode 100644 index 0000000..7c56d60 --- /dev/null +++ b/ops/roles/postgresql/tasks/backup.yml @@ -0,0 +1,31 @@ +--- +- 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 diff --git a/ops/roles/postgresql/tasks/configure.yml b/ops/roles/postgresql/tasks/configure.yml new file mode 100644 index 0000000..dd63c38 --- /dev/null +++ b/ops/roles/postgresql/tasks/configure.yml @@ -0,0 +1,48 @@ +--- +- 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_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_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_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 diff --git a/ops/roles/postgresql/tasks/install.yml b/ops/roles/postgresql/tasks/install.yml new file mode 100644 index 0000000..d872fb3 --- /dev/null +++ b/ops/roles/postgresql/tasks/install.yml @@ -0,0 +1,84 @@ +--- +- name: Install Packages | apt + apt: + state: latest + pkg: "{{ item }}" + with_items: + - postgresql-client + when: postgresql_client + tags: + - software-installation + - using-apt + +- name: Install Packages | apt + apt: + state: latest + pkg: "{{ item }}" + with_items: + - 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: "{{ item }}" + with_items: + - psycopg2 + when: postgresql_server + tags: + - software-installation + - using-pip + +- name: Install Packages | apt + apt: + state: latest + pkg: "{{ item }}" + with_items: + - 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 diff --git a/ops/roles/postgresql/tasks/main.yml b/ops/roles/postgresql/tasks/main.yml new file mode 100644 index 0000000..d7a93c0 --- /dev/null +++ b/ops/roles/postgresql/tasks/main.yml @@ -0,0 +1,4 @@ +--- +- include: install.yml +- { include: backup.yml, when: postgresql_server } +- { include: configure.yml, when: postgresql_server } diff --git a/ops/roles/postgresql/templates/pgsql_backup.sh.j2 b/ops/roles/postgresql/templates/pgsql_backup.sh.j2 new file mode 100644 index 0000000..19aec68 --- /dev/null +++ b/ops/roles/postgresql/templates/pgsql_backup.sh.j2 @@ -0,0 +1,21 @@ +#!/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 %} diff --git a/ops/roles/postgresql/vars/main.yml b/ops/roles/postgresql/vars/main.yml new file mode 100644 index 0000000..99c16c4 --- /dev/null +++ b/ops/roles/postgresql/vars/main.yml @@ -0,0 +1,2 @@ +--- +postgresql_version: '9.5' diff --git a/ops/roles/s3cmd/meta/main.yml b/ops/roles/s3cmd/meta/main.yml new file mode 100644 index 0000000..731ba3f --- /dev/null +++ b/ops/roles/s3cmd/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: +- role: postgresql diff --git a/ops/roles/s3cmd/tasks/main.yml b/ops/roles/s3cmd/tasks/main.yml new file mode 100644 index 0000000..d0f82a6 --- /dev/null +++ b/ops/roles/s3cmd/tasks/main.yml @@ -0,0 +1,9 @@ +- 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" diff --git a/ops/roles/s3cmd/templates/s3cfg.j2 b/ops/roles/s3cmd/templates/s3cfg.j2 new file mode 100644 index 0000000..af62f27 --- /dev/null +++ b/ops/roles/s3cmd/templates/s3cfg.j2 @@ -0,0 +1,4 @@ +[default] +access_key = {{ s3_key }} +secret_key = {{ s3_secret }} +use_https = True \ No newline at end of file diff --git a/ops/roles/ssl/defaults/main.yml b/ops/roles/ssl/defaults/main.yml new file mode 100644 index 0000000..9c5ca35 --- /dev/null +++ b/ops/roles/ssl/defaults/main.yml @@ -0,0 +1,5 @@ +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 diff --git a/ops/roles/ssl/meta/main.yml b/ops/roles/ssl/meta/main.yml new file mode 100644 index 0000000..d4436e4 --- /dev/null +++ b/ops/roles/ssl/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: +- role: nginx diff --git a/ops/roles/ssl/tasks/main.yml b/ops/roles/ssl/tasks/main.yml new file mode 100644 index 0000000..2341d84 --- /dev/null +++ b/ops/roles/ssl/tasks/main.yml @@ -0,0 +1,84 @@ +# Source: https://gist.github.com/raphaelm/10226edb0e46f7ce844e +--- +- 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=installed + +- 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" diff --git a/ops/roles/ssl/templates/config.j2 b/ops/roles/ssl/templates/config.j2 new file mode 100644 index 0000000..2afa3f9 --- /dev/null +++ b/ops/roles/ssl/templates/config.j2 @@ -0,0 +1,85 @@ +######################################################## +# 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-v01.api.letsencrypt.org/directory) +CA="{{ "https://acme-v01.api.letsencrypt.org/directory" if (letsencrypt_use_live_ca | bool) == true else "https://acme-staging.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" diff --git a/ops/roles/supervisor/defaults/main.yml b/ops/roles/supervisor/defaults/main.yml new file mode 100644 index 0000000..daddaa7 --- /dev/null +++ b/ops/roles/supervisor/defaults/main.yml @@ -0,0 +1,3 @@ +entry_dll_file_name: "{{app_name}}.dll" +log_file: "/var/log/{{app_name}}.out.log" +error_file: "/var/log/{{app_name}}.err.log" diff --git a/ops/roles/supervisor/handlers/main.yml b/ops/roles/supervisor/handlers/main.yml new file mode 100755 index 0000000..40636a9 --- /dev/null +++ b/ops/roles/supervisor/handlers/main.yml @@ -0,0 +1,8 @@ +--- +- name: Reload supervisor + service: name=supervisor state=reloaded enabled=true + +- name: Reload supervisor app config + become: yes + become_method: sudo + command: supervisorctl restart {{app_name}} diff --git a/ops/roles/supervisor/tasks/main.yml b/ops/roles/supervisor/tasks/main.yml new file mode 100644 index 0000000..d6875ab --- /dev/null +++ b/ops/roles/supervisor/tasks/main.yml @@ -0,0 +1,10 @@ +--- +- name: Install Supervisor + apt: pkg=supervisor state=present cache_valid_time=86400 + +- name: Setup app config + 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 }} + file: path=/var/www/.dotnet/corefx/cryptography/crls state=directory owner={{ webserver_user }} group={{ webserver_user }} mode=0775 diff --git a/ops/roles/supervisor/templates/etc_supervisor_conf.d_app_name.conf.j2 b/ops/roles/supervisor/templates/etc_supervisor_conf.d_app_name.conf.j2 new file mode 100644 index 0000000..2de26e7 --- /dev/null +++ b/ops/roles/supervisor/templates/etc_supervisor_conf.d_app_name.conf.j2 @@ -0,0 +1,12 @@ +[program:{{app_name}}] +command=/usr/bin/dotnet {{deploy_directory}}/{{entry_dll_file_name}} +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 diff --git a/package.json b/package.json new file mode 100644 index 0000000..312113c --- /dev/null +++ b/package.json @@ -0,0 +1,59 @@ +{ + "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 xunit", + "pretest:client": "./node_modules/typescript/bin/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/ && dotnet ef migrations add $(date +%s) && dotnet ef database update", + "prestart": "docker-compose up -d", + "start": "cd ./api && cross-env NODE_PATH=../node_modules/ ASPNETCORE_ENVIRONMENT=Development dotnet watch run", + "start:release": "npm run prerelease && cd ./api/bin/Release/netcoreapp1.0/publish/ && dotnet api.dll", + "provision:prod": "ansible-playbook -l production -i ./ops/hosts ./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/hosts ./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": "^3.4.32", + "@types/mocha": "^2.2.31", + "aspnet-webpack": "^1.0.11", + "aspnet-webpack-react": "^1.0.5", + "bootstrap": "^4.0.0-alpha.6", + "chai": "^3.5.0", + "cross-env": "^3.1.3", + "css-loader": "^0.28.0", + "extendify": "^1.0.0", + "extract-text-webpack-plugin": "^2.1.0", + "file-loader": "^0.11.1", + "global": "^4.3.1", + "html-webpack-plugin": "^2.22.0", + "ignore-styles": "^5.0.1", + "mocha": "^3.0.2", + "prop-types": "^15.5.4", + "source-map-loader": "^0.1.5", + "style-loader": "^0.13.1", + "stylus": "^0.54.5", + "stylus-loader": "^3.0.1", + "ts-loader": "^2.0.3", + "typescript": "^2.2.2", + "url-loader": "^0.5.8", + "vue": "^2.2.6", + "vue-class-component": "^5.0.1", + "vue-loader": "^11.3.4", + "vue-property-decorator": "^5.0.1", + "vue-router": "^2.3.1", + "vue-template-compiler": "^2.2.6", + "webpack": "^2.3.3", + "webpack-hot-middleware": "^2.18.0", + "whatwg-fetch": "^2.0.3" + } +} diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..a68f64c --- /dev/null +++ b/yarn.lock @@ -0,0 +1,3923 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@types/chai@^3.4.32": + version "3.4.35" + resolved "https://registry.yarnpkg.com/@types/chai/-/chai-3.4.35.tgz#e8d65f83492d2944f816fc620741821c28a8c900" + +"@types/mocha@^2.2.31": + version "2.2.40" + resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-2.2.40.tgz#9811dd800ece544cd84b5b859917bf584a150c4c" + +abbrev@1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.0.tgz#d0554c2256636e2f56e7c2e5ad183f859428d81f" + +acorn-dynamic-import@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz#c752bd210bef679501b6c6cb7fc84f8f47158cc4" + dependencies: + acorn "^4.0.3" + +acorn@^4.0.3, acorn@^4.0.4: + version "4.0.11" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.11.tgz#edcda3bd937e7556410d42ed5860f67399c794c0" + +ajv-keywords@^1.1.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" + +ajv@^4.11.2, ajv@^4.7.0, ajv@^4.9.1: + version "4.11.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.6.tgz#947e93049790942b2a2d60a8289b28924d39f987" + dependencies: + co "^4.6.0" + json-stable-stringify "^1.0.1" + +align-text@^0.1.1, align-text@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" + dependencies: + kind-of "^3.0.2" + longest "^1.0.1" + repeat-string "^1.5.2" + +alphanum-sort@^1.0.1, alphanum-sort@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" + +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + +ansi-html@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + +anymatch@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.0.tgz#a3e52fa39168c825ff57b0248126ce5a8ff95507" + dependencies: + arrify "^1.0.0" + micromatch "^2.1.5" + +aproba@^1.0.3: + version "1.1.1" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.1.1.tgz#95d3600f07710aa0e9298c726ad5ecf2eacbabab" + +are-we-there-yet@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.2.tgz#80e470e95a084794fe1899262c5667c6e88de1b3" + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.0 || ^1.1.13" + +argparse@^1.0.7: + version "1.0.9" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" + dependencies: + sprintf-js "~1.0.2" + +arr-diff@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" + dependencies: + arr-flatten "^1.0.1" + +arr-flatten@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.0.1.tgz#e5ffe54d45e19f32f216e91eb99c8ce892bb604b" + +array-unique@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + +arrify@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + +asap@~2.0.3: + version "2.0.5" + resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.5.tgz#522765b50c3510490e52d7dcfe085ef9ba96958f" + +asn1.js@^4.0.0: + version "4.9.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.9.1.tgz#48ba240b45a9280e94748990ba597d216617fd40" + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +asn1@~0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" + +aspnet-webpack-react@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/aspnet-webpack-react/-/aspnet-webpack-react-1.0.5.tgz#f4ae2a6b2afebc490edf66714a86244322c26cf6" + dependencies: + babel-core "^6.7.2" + babel-loader "^6.2.4" + babel-plugin-react-transform "^2.0.2" + babel-preset-es2015 "^6.6.0" + babel-preset-react "^6.5.0" + react "^15.0.0" + react-transform-hmr "^1.0.4" + +aspnet-webpack@^1.0.11: + version "1.0.28" + resolved "https://registry.yarnpkg.com/aspnet-webpack/-/aspnet-webpack-1.0.28.tgz#12fb4e1672554f8b4db9ce6d1c37507a4c472c16" + dependencies: + connect "^3.4.1" + es6-promise "^3.1.2" + memory-fs "^0.3.0" + require-from-string "^1.1.0" + webpack-dev-middleware "^1.8.4" + webpack-node-externals "^1.4.3" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + +assert-plus@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" + +assert@^1.1.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" + dependencies: + util "0.10.3" + +assertion-error@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.0.2.tgz#13ca515d86206da0bac66e834dd397d87581094c" + +async-each@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" + +async@^0.9.0: + version "0.9.2" + resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" + +async@^2.1.2: + version "2.3.0" + resolved "https://registry.yarnpkg.com/async/-/async-2.3.0.tgz#1013d1051047dd320fe24e494d5c66ecaf6147d9" + dependencies: + lodash "^4.14.0" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + +autoprefixer@^6.3.1: + version "6.7.7" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-6.7.7.tgz#1dbd1c835658e35ce3f9984099db00585c782014" + dependencies: + browserslist "^1.7.6" + caniuse-db "^1.0.30000634" + normalize-range "^0.1.2" + num2fraction "^1.2.2" + postcss "^5.2.16" + postcss-value-parser "^3.2.3" + +aws-sign2@~0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" + +aws4@^1.2.1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" + +babel-code-frame@^6.11.0, babel-code-frame@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.22.0.tgz#027620bee567a88c32561574e7fd0801d33118e4" + dependencies: + chalk "^1.1.0" + esutils "^2.0.2" + js-tokens "^3.0.0" + +babel-core@^6.24.1, babel-core@^6.7.2: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.24.1.tgz#8c428564dce1e1f41fb337ec34f4c3b022b5ad83" + dependencies: + babel-code-frame "^6.22.0" + babel-generator "^6.24.1" + babel-helpers "^6.24.1" + babel-messages "^6.23.0" + babel-register "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + babylon "^6.11.0" + convert-source-map "^1.1.0" + debug "^2.1.1" + json5 "^0.5.0" + lodash "^4.2.0" + minimatch "^3.0.2" + path-is-absolute "^1.0.0" + private "^0.1.6" + slash "^1.0.0" + source-map "^0.5.0" + +babel-generator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.24.1.tgz#e715f486c58ded25649d888944d52aa07c5d9497" + dependencies: + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + detect-indent "^4.0.0" + jsesc "^1.3.0" + lodash "^4.2.0" + source-map "^0.5.0" + trim-right "^1.0.1" + +babel-helper-builder-react-jsx@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.24.1.tgz#0ad7917e33c8d751e646daca4e77cc19377d2cbc" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + esutils "^2.0.0" + +babel-helper-call-delegate@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-define-map@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.24.1.tgz#7a9747f258d8947d32d515f6aa1c7bd02204a080" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + lodash "^4.2.0" + +babel-helper-function-name@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" + dependencies: + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-get-function-arity@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-hoist-variables@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-optimise-call-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-regex@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.24.1.tgz#d36e22fab1008d79d88648e32116868128456ce8" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + lodash "^4.2.0" + +babel-helper-replace-supers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" + dependencies: + babel-helper-optimise-call-expression "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helpers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-loader@^6.2.4: + version "6.4.1" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-6.4.1.tgz#0b34112d5b0748a8dcdbf51acf6f9bd42d50b8ca" + dependencies: + find-cache-dir "^0.1.1" + loader-utils "^0.2.16" + mkdirp "^0.5.1" + object-assign "^4.0.1" + +babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-check-es2015-constants@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-react-transform@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/babel-plugin-react-transform/-/babel-plugin-react-transform-2.0.2.tgz#515bbfa996893981142d90b1f9b1635de2995109" + dependencies: + lodash "^4.6.1" + +babel-plugin-syntax-flow@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d" + +babel-plugin-syntax-jsx@^6.3.13, babel-plugin-syntax-jsx@^6.8.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" + +babel-plugin-transform-es2015-arrow-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoping@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.24.1.tgz#76c295dc3a4741b1665adfd3167215dcff32a576" + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + lodash "^4.2.0" + +babel-plugin-transform-es2015-classes@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" + dependencies: + babel-helper-define-map "^6.24.1" + babel-helper-function-name "^6.24.1" + babel-helper-optimise-call-expression "^6.24.1" + babel-helper-replace-supers "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-computed-properties@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-destructuring@^6.22.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-duplicate-keys@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-for-of@^6.22.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-function-name@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-modules-amd@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" + dependencies: + babel-plugin-transform-es2015-modules-commonjs "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-commonjs@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.24.1.tgz#d3e310b40ef664a36622200097c6d440298f2bfe" + dependencies: + babel-plugin-transform-strict-mode "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-modules-systemjs@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-umd@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" + dependencies: + babel-plugin-transform-es2015-modules-amd "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-object-super@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" + dependencies: + babel-helper-replace-supers "^6.24.1" + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-parameters@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" + dependencies: + babel-helper-call-delegate "^6.24.1" + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-shorthand-properties@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-spread@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-sticky-regex@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-template-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-typeof-symbol@^6.22.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-unicode-regex@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + regexpu-core "^2.0.0" + +babel-plugin-transform-flow-strip-types@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz#84cb672935d43714fdc32bce84568d87441cf7cf" + dependencies: + babel-plugin-syntax-flow "^6.18.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-react-display-name@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.23.0.tgz#4398910c358441dc4cef18787264d0412ed36b37" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-react-jsx-self@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-self/-/babel-plugin-transform-react-jsx-self-6.22.0.tgz#df6d80a9da2612a121e6ddd7558bcbecf06e636e" + dependencies: + babel-plugin-syntax-jsx "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-react-jsx-source@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-source/-/babel-plugin-transform-react-jsx-source-6.22.0.tgz#66ac12153f5cd2d17b3c19268f4bf0197f44ecd6" + dependencies: + babel-plugin-syntax-jsx "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-react-jsx@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz#840a028e7df460dfc3a2d29f0c0d91f6376e66a3" + dependencies: + babel-helper-builder-react-jsx "^6.24.1" + babel-plugin-syntax-jsx "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-regenerator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.24.1.tgz#b8da305ad43c3c99b4848e4fe4037b770d23c418" + dependencies: + regenerator-transform "0.9.11" + +babel-plugin-transform-strict-mode@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-preset-es2015@^6.6.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz#d44050d6bc2c9feea702aaf38d727a0210538939" + dependencies: + babel-plugin-check-es2015-constants "^6.22.0" + babel-plugin-transform-es2015-arrow-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoping "^6.24.1" + babel-plugin-transform-es2015-classes "^6.24.1" + babel-plugin-transform-es2015-computed-properties "^6.24.1" + babel-plugin-transform-es2015-destructuring "^6.22.0" + babel-plugin-transform-es2015-duplicate-keys "^6.24.1" + babel-plugin-transform-es2015-for-of "^6.22.0" + babel-plugin-transform-es2015-function-name "^6.24.1" + babel-plugin-transform-es2015-literals "^6.22.0" + babel-plugin-transform-es2015-modules-amd "^6.24.1" + babel-plugin-transform-es2015-modules-commonjs "^6.24.1" + babel-plugin-transform-es2015-modules-systemjs "^6.24.1" + babel-plugin-transform-es2015-modules-umd "^6.24.1" + babel-plugin-transform-es2015-object-super "^6.24.1" + babel-plugin-transform-es2015-parameters "^6.24.1" + babel-plugin-transform-es2015-shorthand-properties "^6.24.1" + babel-plugin-transform-es2015-spread "^6.22.0" + babel-plugin-transform-es2015-sticky-regex "^6.24.1" + babel-plugin-transform-es2015-template-literals "^6.22.0" + babel-plugin-transform-es2015-typeof-symbol "^6.22.0" + babel-plugin-transform-es2015-unicode-regex "^6.24.1" + babel-plugin-transform-regenerator "^6.24.1" + +babel-preset-flow@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-preset-flow/-/babel-preset-flow-6.23.0.tgz#e71218887085ae9a24b5be4169affb599816c49d" + dependencies: + babel-plugin-transform-flow-strip-types "^6.22.0" + +babel-preset-react@^6.5.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-preset-react/-/babel-preset-react-6.24.1.tgz#ba69dfaea45fc3ec639b6a4ecea6e17702c91380" + dependencies: + babel-plugin-syntax-jsx "^6.3.13" + babel-plugin-transform-react-display-name "^6.23.0" + babel-plugin-transform-react-jsx "^6.24.1" + babel-plugin-transform-react-jsx-self "^6.22.0" + babel-plugin-transform-react-jsx-source "^6.22.0" + babel-preset-flow "^6.23.0" + +babel-register@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.24.1.tgz#7e10e13a2f71065bdfad5a1787ba45bca6ded75f" + dependencies: + babel-core "^6.24.1" + babel-runtime "^6.22.0" + core-js "^2.4.0" + home-or-tmp "^2.0.0" + lodash "^4.2.0" + mkdirp "^0.5.1" + source-map-support "^0.4.2" + +babel-runtime@^6.18.0, babel-runtime@^6.22.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.23.0.tgz#0a9489f144de70efb3ce4300accdb329e2fc543b" + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.10.0" + +babel-template@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.24.1.tgz#04ae514f1f93b3a2537f2a0f60a5a45fb8308333" + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + babylon "^6.11.0" + lodash "^4.2.0" + +babel-traverse@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.24.1.tgz#ab36673fd356f9a0948659e7b338d5feadb31695" + dependencies: + babel-code-frame "^6.22.0" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + babylon "^6.15.0" + debug "^2.2.0" + globals "^9.0.0" + invariant "^2.2.0" + lodash "^4.2.0" + +babel-types@^6.19.0, babel-types@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.24.1.tgz#a136879dc15b3606bda0d90c1fc74304c2ff0975" + dependencies: + babel-runtime "^6.22.0" + esutils "^2.0.2" + lodash "^4.2.0" + to-fast-properties "^1.0.1" + +babylon@^6.11.0, babylon@^6.15.0: + version "6.16.1" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.16.1.tgz#30c5a22f481978a9e7f8cdfdf496b11d94b404d3" + +balanced-match@^0.4.1, balanced-match@^0.4.2: + version "0.4.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" + +base64-js@^1.0.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.0.tgz#a39992d723584811982be5e290bb6a53d86700f1" + +bcrypt-pbkdf@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" + dependencies: + tweetnacl "^0.14.3" + +big.js@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.1.3.tgz#4cada2193652eb3ca9ec8e55c9015669c9806978" + +binary-extensions@^1.0.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.8.0.tgz#48ec8d16df4377eae5fa5884682480af4d95c774" + +block-stream@*: + version "0.0.9" + resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + dependencies: + inherits "~2.0.0" + +bluebird@^3.0.5, bluebird@^3.1.1, bluebird@^3.4.7: + version "3.5.0" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.0.tgz#791420d7f551eea2897453a8a77653f96606d67c" + +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: + version "4.11.6" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215" + +boolbase@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + +boom@2.x.x: + version "2.10.1" + resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" + dependencies: + hoek "2.x.x" + +bootstrap@^4.0.0-alpha.6: + version "4.0.0-alpha.6" + resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.0.0-alpha.6.tgz#4f54dd33ac0deac3b28407bc2df7ec608869c9c8" + dependencies: + jquery ">=1.9.1" + tether "^1.4.0" + +brace-expansion@^1.0.0: + version "1.1.7" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.7.tgz#3effc3c50e000531fb720eaff80f0ae8ef23cf59" + dependencies: + balanced-match "^0.4.1" + concat-map "0.0.1" + +braces@^1.8.2: + version "1.8.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" + dependencies: + expand-range "^1.8.1" + preserve "^0.2.0" + repeat-element "^1.1.2" + +brorand@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + +browser-stdout@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f" + +browserify-aes@^1.0.0, browserify-aes@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.0.6.tgz#5e7725dbdef1fd5930d4ebab48567ce451c48a0a" + dependencies: + buffer-xor "^1.0.2" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.0" + inherits "^2.0.1" + +browserify-cipher@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.0.tgz#9988244874bf5ed4e28da95666dcd66ac8fc363a" + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.0.tgz#daa277717470922ed2fe18594118a175439721dd" + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + +browserify-rsa@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" + dependencies: + bn.js "^4.1.0" + randombytes "^2.0.1" + +browserify-sign@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" + dependencies: + bn.js "^4.1.1" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.2" + elliptic "^6.0.0" + inherits "^2.0.1" + parse-asn1 "^5.0.0" + +browserify-zlib@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.1.4.tgz#bb35f8a519f600e0fa6b8485241c979d0141fb2d" + dependencies: + pako "~0.2.0" + +browserslist@^1.3.6, browserslist@^1.5.2, browserslist@^1.7.6: + version "1.7.7" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-1.7.7.tgz#0bd76704258be829b2398bb50e4b62d1a166b0b9" + dependencies: + caniuse-db "^1.0.30000639" + electron-to-chromium "^1.2.7" + +buffer-shims@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51" + +buffer-xor@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + +buffer@^4.3.0: + version "4.9.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + +builtin-modules@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + +builtin-status-codes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + +camel-case@3.0.x: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73" + dependencies: + no-case "^2.2.0" + upper-case "^1.1.1" + +camelcase@^1.0.2: + version "1.2.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" + +camelcase@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" + +caniuse-api@^1.5.2: + version "1.6.1" + resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-1.6.1.tgz#b534e7c734c4f81ec5fbe8aca2ad24354b962c6c" + dependencies: + browserslist "^1.3.6" + caniuse-db "^1.0.30000529" + lodash.memoize "^4.1.2" + lodash.uniq "^4.5.0" + +caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639: + version "1.0.30000649" + resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000649.tgz#1ee1754a6df235450c8b7cd15e0ebf507221a86a" + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + +center-align@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" + dependencies: + align-text "^0.1.3" + lazy-cache "^1.0.3" + +chai@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/chai/-/chai-3.5.0.tgz#4d02637b067fe958bdbfdd3a40ec56fef7373247" + dependencies: + assertion-error "^1.0.1" + deep-eql "^0.1.3" + type-detect "^1.0.0" + +chalk@^1.1.0, chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chokidar@^1.4.3: + version "1.6.1" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.6.1.tgz#2f4447ab5e96e50fb3d789fd90d4c72e0e4c70c2" + dependencies: + anymatch "^1.3.0" + async-each "^1.0.0" + glob-parent "^2.0.0" + inherits "^2.0.1" + is-binary-path "^1.0.0" + is-glob "^2.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.0.0" + optionalDependencies: + fsevents "^1.0.0" + +cipher-base@^1.0.0, cipher-base@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.3.tgz#eeabf194419ce900da3018c207d212f2a6df0a07" + dependencies: + inherits "^2.0.1" + +clap@^1.0.9: + version "1.1.3" + resolved "https://registry.yarnpkg.com/clap/-/clap-1.1.3.tgz#b3bd36e93dd4cbfb395a3c26896352445265c05b" + dependencies: + chalk "^1.1.3" + +clean-css@4.0.x: + version "4.0.11" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.0.11.tgz#a6d88bffb399420b24298db49d99a1ed067534a8" + dependencies: + source-map "0.5.x" + +cliui@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" + dependencies: + center-align "^0.1.1" + right-align "^0.1.1" + wordwrap "0.0.2" + +cliui@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrap-ansi "^2.0.0" + +clone@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.2.tgz#260b7a99ebb1edfe247538175f783243cb19d149" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + +coa@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/coa/-/coa-1.0.1.tgz#7f959346cfc8719e3f7233cd6852854a7c67d8a3" + dependencies: + q "^1.1.2" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + +color-convert@^1.3.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.0.tgz#1accf97dd739b983bf994d56fec8f95853641b7a" + dependencies: + color-name "^1.1.1" + +color-name@^1.0.0, color-name@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.2.tgz#5c8ab72b64bd2215d617ae9559ebb148475cf98d" + +color-string@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-0.3.0.tgz#27d46fb67025c5c2fa25993bfbf579e47841b991" + dependencies: + color-name "^1.0.0" + +color@^0.11.0: + version "0.11.4" + resolved "https://registry.yarnpkg.com/color/-/color-0.11.4.tgz#6d7b5c74fb65e841cd48792ad1ed5e07b904d764" + dependencies: + clone "^1.0.2" + color-convert "^1.3.0" + color-string "^0.3.0" + +colormin@^1.0.5: + version "1.1.2" + resolved "https://registry.yarnpkg.com/colormin/-/colormin-1.1.2.tgz#ea2f7420a72b96881a38aae59ec124a6f7298133" + dependencies: + color "^0.11.0" + css-color-names "0.0.4" + has "^1.0.1" + +colors@^1.0.3, colors@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" + +combined-stream@^1.0.5, combined-stream@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" + dependencies: + delayed-stream "~1.0.0" + +commander@2.9.0, commander@2.9.x, commander@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" + dependencies: + graceful-readlink ">= 1.0.0" + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + +config-chain@~1.1.5: + version "1.1.11" + resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.11.tgz#aba09747dfbe4c3e70e766a6e41586e1859fc6f2" + dependencies: + ini "^1.3.4" + proto-list "~1.2.1" + +connect@^3.4.1: + version "3.6.0" + resolved "https://registry.yarnpkg.com/connect/-/connect-3.6.0.tgz#f09a4f7dcd17324b663b725c815bdb1c4158a46e" + dependencies: + debug "2.6.1" + finalhandler "1.0.0" + parseurl "~1.3.1" + utils-merge "1.0.0" + +console-browserify@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10" + dependencies: + date-now "^0.1.4" + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + +consolidate@^0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/consolidate/-/consolidate-0.14.5.tgz#5a25047bc76f73072667c8cb52c989888f494c63" + dependencies: + bluebird "^3.1.1" + +constants-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + +convert-source-map@^1.1.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.0.tgz#9acd70851c6d5dfdd93d9282e5edf94a03ff46b5" + +core-js@^1.0.0: + version "1.2.7" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" + +core-js@^2.4.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e" + +core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + +cosmiconfig@^2.1.0, cosmiconfig@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-2.1.3.tgz#952771eb0dddc1cb3fa2f6fbe51a522e93b3ee0a" + dependencies: + is-directory "^0.3.1" + js-yaml "^3.4.3" + minimist "^1.2.0" + object-assign "^4.1.0" + os-homedir "^1.0.1" + parse-json "^2.2.0" + require-from-string "^1.1.0" + +create-ecdh@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.0.tgz#888c723596cdf7612f6498233eebd7a35301737d" + dependencies: + bn.js "^4.1.0" + elliptic "^6.0.0" + +create-hash@^1.1.0, create-hash@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.1.2.tgz#51210062d7bb7479f6c65bb41a92208b1d61abad" + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + ripemd160 "^1.0.0" + sha.js "^2.3.6" + +create-hmac@^1.1.0, create-hmac@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.4.tgz#d3fb4ba253eb8b3f56e39ea2fbcb8af747bd3170" + dependencies: + create-hash "^1.1.0" + inherits "^2.0.1" + +cross-env@^3.1.3: + version "3.2.4" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-3.2.4.tgz#9e0585f277864ed421ce756f81a980ff0d698aba" + dependencies: + cross-spawn "^5.1.0" + is-windows "^1.0.0" + +cross-spawn@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + +cryptiles@2.x.x: + version "2.0.5" + resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" + dependencies: + boom "2.x.x" + +crypto-browserify@^3.11.0: + version "3.11.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.11.0.tgz#3652a0906ab9b2a7e0c3ce66a408e957a2485522" + dependencies: + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + +css-color-names@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" + +css-loader@^0.28.0: + version "0.28.0" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-0.28.0.tgz#417cfa9789f8cde59a30ccbf3e4da7a806889bad" + dependencies: + babel-code-frame "^6.11.0" + css-selector-tokenizer "^0.7.0" + cssnano ">=2.6.1 <4" + loader-utils "^1.0.2" + lodash.camelcase "^4.3.0" + object-assign "^4.0.1" + postcss "^5.0.6" + postcss-modules-extract-imports "^1.0.0" + postcss-modules-local-by-default "^1.0.1" + postcss-modules-scope "^1.0.0" + postcss-modules-values "^1.1.0" + source-list-map "^0.1.7" + +css-parse@1.7.x: + version "1.7.0" + resolved "https://registry.yarnpkg.com/css-parse/-/css-parse-1.7.0.tgz#321f6cf73782a6ff751111390fc05e2c657d8c9b" + +css-select@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" + dependencies: + boolbase "~1.0.0" + css-what "2.1" + domutils "1.5.1" + nth-check "~1.0.1" + +css-selector-tokenizer@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.6.0.tgz#6445f582c7930d241dcc5007a43d6fcb8f073152" + dependencies: + cssesc "^0.1.0" + fastparse "^1.1.1" + regexpu-core "^1.0.0" + +css-selector-tokenizer@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz#e6988474ae8c953477bf5e7efecfceccd9cf4c86" + dependencies: + cssesc "^0.1.0" + fastparse "^1.1.1" + regexpu-core "^1.0.0" + +css-what@2.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.0.tgz#9467d032c38cfaefb9f2d79501253062f87fa1bd" + +cssesc@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-0.1.0.tgz#c814903e45623371a0477b40109aaafbeeaddbb4" + +"cssnano@>=2.6.1 <4": + version "3.10.0" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-3.10.0.tgz#4f38f6cea2b9b17fa01490f23f1dc68ea65c1c38" + dependencies: + autoprefixer "^6.3.1" + decamelize "^1.1.2" + defined "^1.0.0" + has "^1.0.1" + object-assign "^4.0.1" + postcss "^5.0.14" + postcss-calc "^5.2.0" + postcss-colormin "^2.1.8" + postcss-convert-values "^2.3.4" + postcss-discard-comments "^2.0.4" + postcss-discard-duplicates "^2.0.1" + postcss-discard-empty "^2.0.1" + postcss-discard-overridden "^0.1.1" + postcss-discard-unused "^2.2.1" + postcss-filter-plugins "^2.0.0" + postcss-merge-idents "^2.1.5" + postcss-merge-longhand "^2.0.1" + postcss-merge-rules "^2.0.3" + postcss-minify-font-values "^1.0.2" + postcss-minify-gradients "^1.0.1" + postcss-minify-params "^1.0.4" + postcss-minify-selectors "^2.0.4" + postcss-normalize-charset "^1.1.0" + postcss-normalize-url "^3.0.7" + postcss-ordered-values "^2.1.0" + postcss-reduce-idents "^2.2.2" + postcss-reduce-initial "^1.0.0" + postcss-reduce-transforms "^1.0.3" + postcss-svgo "^2.1.1" + postcss-unique-selectors "^2.0.2" + postcss-value-parser "^3.2.3" + postcss-zindex "^2.0.1" + +csso@~2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/csso/-/csso-2.3.2.tgz#ddd52c587033f49e94b71fc55569f252e8ff5f85" + dependencies: + clap "^1.0.9" + source-map "^0.5.3" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + dependencies: + assert-plus "^1.0.0" + +date-now@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" + +de-indent@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d" + +debug@*, debug@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" + dependencies: + ms "0.7.1" + +debug@2.6.1, debug@^2.1.1, debug@^2.2.0: + version "2.6.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.1.tgz#79855090ba2c4e3115cc7d8769491d58f0491351" + dependencies: + ms "0.7.2" + +decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + +deep-eql@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-0.1.3.tgz#ef558acab8de25206cd713906d74e56930eb69f2" + dependencies: + type-detect "0.1.1" + +deep-extend@~0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.1.tgz#efe4113d08085f4e6f9687759810f807469e2253" + +defined@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + +des.js@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc" + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +detect-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" + dependencies: + repeating "^2.0.0" + +diff@1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-1.4.0.tgz#7f28d2eb9ee7b15a97efd89ce63dcfdaa3ccbabf" + +diffie-hellman@^5.0.0: + version "5.0.2" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.2.tgz#b5835739270cfe26acf632099fded2a07f209e5e" + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + +dom-converter@~0.1: + version "0.1.4" + resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.1.4.tgz#a45ef5727b890c9bffe6d7c876e7b19cb0e17f3b" + dependencies: + utila "~0.3" + +dom-serializer@0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82" + dependencies: + domelementtype "~1.1.1" + entities "~1.1.1" + +dom-walk@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018" + +domain-browser@^1.1.1: + version "1.1.7" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.1.7.tgz#867aa4b093faa05f1de08c06f4d7b21fdf8698bc" + +domelementtype@1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.0.tgz#b17aed82e8ab59e52dd9c19b1756e0fc187204c2" + +domelementtype@~1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b" + +domhandler@2.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.1.0.tgz#d2646f5e57f6c3bab11cf6cb05d3c0acf7412594" + dependencies: + domelementtype "1" + +domutils@1.1: + version "1.1.6" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.1.6.tgz#bddc3de099b9a2efacc51c623f28f416ecc57485" + dependencies: + domelementtype "1" + +domutils@1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" + dependencies: + dom-serializer "0" + domelementtype "1" + +ecc-jsbn@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" + dependencies: + jsbn "~0.1.0" + +editorconfig@^0.13.2: + version "0.13.2" + resolved "https://registry.yarnpkg.com/editorconfig/-/editorconfig-0.13.2.tgz#8e57926d9ee69ab6cb999f027c2171467acceb35" + dependencies: + bluebird "^3.0.5" + commander "^2.9.0" + lru-cache "^3.2.0" + sigmund "^1.0.1" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + +electron-to-chromium@^1.2.7: + version "1.3.2" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.2.tgz#b8ce5c93b308db0e92f6d0435c46ddec8f6363ab" + +elliptic@^6.0.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.0.tgz#cac9af8762c85836187003c8dfe193e5e2eae5df" + dependencies: + bn.js "^4.4.0" + brorand "^1.0.1" + hash.js "^1.0.0" + hmac-drbg "^1.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.0" + +emojis-list@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" + +encodeurl@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.1.tgz#79e3d58655346909fe6f0f45a5de68103b294d20" + +encoding@^0.1.11: + version "0.1.12" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" + dependencies: + iconv-lite "~0.4.13" + +enhanced-resolve@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-3.1.0.tgz#9f4b626f577245edcf4b2ad83d86e17f4f421dec" + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.4.0" + object-assign "^4.0.1" + tapable "^0.2.5" + +entities@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0" + +errno@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.4.tgz#b896e23a9e5e8ba33871fc996abd3635fc9a1c7d" + dependencies: + prr "~0.0.0" + +error-ex@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" + dependencies: + is-arrayish "^0.2.1" + +es6-promise@^3.1.2: + version "3.3.1" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.3.1.tgz#a08cdde84ccdbf34d027a1451bc91d4bcd28a613" + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + +escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + +esprima@^2.6.0: + version "2.7.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" + +esutils@^2.0.0, esutils@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + +events@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" + +evp_bytestokey@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.0.tgz#497b66ad9fef65cd7c08a6180824ba1476b66e53" + dependencies: + create-hash "^1.1.1" + +expand-brackets@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" + dependencies: + is-posix-bracket "^0.1.0" + +expand-range@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + dependencies: + fill-range "^2.1.0" + +extend@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.0.tgz#5a474353b9f3353ddd8176dfd37b91c83a46f1d4" + +extendify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/extendify/-/extendify-1.0.0.tgz#99ddcff7ad45c716f5c63ac3bbcb4d9ff0401e61" + dependencies: + lodash "^2.4.1" + +extglob@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" + dependencies: + is-extglob "^1.0.0" + +extract-text-webpack-plugin@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/extract-text-webpack-plugin/-/extract-text-webpack-plugin-2.1.0.tgz#69315b885f876dbf96d3819f6a9f1cca7aebf159" + dependencies: + ajv "^4.11.2" + async "^2.1.2" + loader-utils "^1.0.2" + webpack-sources "^0.1.0" + +extsprintf@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.0.2.tgz#e1080e0658e300b06294990cc70e1502235fd550" + +fastparse@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.1.tgz#d1e2643b38a94d7583b479060e6c4affc94071f8" + +fbjs@^0.8.9: + version "0.8.12" + resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.12.tgz#10b5d92f76d45575fd63a217d4ea02bea2f8ed04" + dependencies: + core-js "^1.0.0" + isomorphic-fetch "^2.1.1" + loose-envify "^1.0.0" + object-assign "^4.1.0" + promise "^7.1.1" + setimmediate "^1.0.5" + ua-parser-js "^0.7.9" + +file-loader@^0.11.1: + version "0.11.1" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-0.11.1.tgz#6b328ee1234a729e4e47d36375dd6d35c0e1db84" + dependencies: + loader-utils "^1.0.2" + +filename-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.0.tgz#996e3e80479b98b9897f15a8a58b3d084e926775" + +fill-range@^2.1.0: + version "2.2.3" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" + dependencies: + is-number "^2.1.0" + isobject "^2.0.0" + randomatic "^1.1.3" + repeat-element "^1.1.2" + repeat-string "^1.5.2" + +finalhandler@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.0.0.tgz#b5691c2c0912092f18ac23e9416bde5cd7dc6755" + dependencies: + debug "2.6.1" + encodeurl "~1.0.1" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.1" + statuses "~1.3.1" + unpipe "~1.0.0" + +find-cache-dir@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-0.1.1.tgz#c8defae57c8a52a8a784f9e31c57c742e993a0b9" + dependencies: + commondir "^1.0.1" + mkdirp "^0.5.1" + pkg-dir "^1.0.0" + +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +flatten@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782" + +for-in@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + +for-own@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + dependencies: + for-in "^1.0.1" + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + +form-data@~2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.2.tgz#89c3534008b97eada4cbb157d58f6f5df025eae4" + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.5" + mime-types "^2.1.12" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + +fsevents@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.1.1.tgz#f19fd28f43eeaf761680e519a203c4d0b3d31aff" + dependencies: + nan "^2.3.0" + node-pre-gyp "^0.6.29" + +fstream-ignore@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105" + dependencies: + fstream "^1.0.0" + inherits "2" + minimatch "^3.0.0" + +fstream@^1.0.0, fstream@^1.0.10, fstream@^1.0.2: + version "1.0.11" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + +function-bind@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.0.tgz#16176714c801798e4e8f2cf7f7529467bb4a5771" + +gauge@~2.7.1: + version "2.7.3" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.3.tgz#1c23855f962f17b3ad3d0dc7443f304542edfe09" + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +get-caller-file@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" + +getpass@^0.1.1: + version "0.1.6" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.6.tgz#283ffd9fc1256840875311c1b60e8c40187110e6" + dependencies: + assert-plus "^1.0.0" + +glob-base@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + dependencies: + glob-parent "^2.0.0" + is-glob "^2.0.0" + +glob-parent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + dependencies: + is-glob "^2.0.0" + +glob@7.0.5, glob@7.0.x, glob@^7.0.5: + version "7.0.5" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.5.tgz#b4202a69099bbb4d292a7c1b95b6682b67ebdc95" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.2" + once "^1.3.0" + path-is-absolute "^1.0.0" + +global@^4.3.0, global@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/global/-/global-4.3.1.tgz#5f757908c7cbabce54f386ae440e11e26b7916df" + dependencies: + min-document "^2.19.0" + process "~0.5.1" + +globals@^9.0.0: + version "9.17.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.17.0.tgz#0c0ca696d9b9bb694d2e5470bd37777caad50286" + +graceful-fs@^4.1.2: + version "4.1.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" + +"graceful-readlink@>= 1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" + +growl@1.9.2: + version "1.9.2" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f" + +har-schema@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e" + +har-validator@~4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a" + dependencies: + ajv "^4.9.1" + har-schema "^1.0.5" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + dependencies: + ansi-regex "^2.0.0" + +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + +has@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28" + dependencies: + function-bind "^1.0.2" + +hash-sum@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/hash-sum/-/hash-sum-1.0.2.tgz#33b40777754c6432573c120cc3808bbd10d47f04" + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.0.3.tgz#1332ff00156c0a0ffdd8236013d07b77a0451573" + dependencies: + inherits "^2.0.1" + +hawk@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" + dependencies: + boom "2.x.x" + cryptiles "2.x.x" + hoek "2.x.x" + sntp "1.x.x" + +he@1.1.x, he@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" + +hmac-drbg@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.0.tgz#3db471f45aae4a994a0688322171f51b8b91bee5" + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +hoek@2.x.x: + version "2.16.3" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" + +home-or-tmp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.1" + +hosted-git-info@^2.1.4: + version "2.4.1" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.4.1.tgz#4b0445e41c004a8bd1337773a4ff790ca40318c8" + +html-comment-regex@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.1.tgz#668b93776eaae55ebde8f3ad464b307a4963625e" + +html-entities@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.0.tgz#41948caf85ce82fed36e4e6a0ed371a6664379e2" + +html-minifier@^3.2.3: + version "3.4.2" + resolved "https://registry.yarnpkg.com/html-minifier/-/html-minifier-3.4.2.tgz#31896baaf735c1d95f7a0b7291f9dc36c0720752" + dependencies: + camel-case "3.0.x" + clean-css "4.0.x" + commander "2.9.x" + he "1.1.x" + ncname "1.0.x" + param-case "2.1.x" + relateurl "0.2.x" + uglify-js "2.8.x" + +html-webpack-plugin@^2.22.0: + version "2.28.0" + resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-2.28.0.tgz#2e7863b57e5fd48fe263303e2ffc934c3064d009" + dependencies: + bluebird "^3.4.7" + html-minifier "^3.2.3" + loader-utils "^0.2.16" + lodash "^4.17.3" + pretty-error "^2.0.2" + toposort "^1.0.0" + +htmlparser2@~3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.3.0.tgz#cc70d05a59f6542e43f0e685c982e14c924a9efe" + dependencies: + domelementtype "1" + domhandler "2.1" + domutils "1.1" + readable-stream "1.0" + +http-signature@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" + dependencies: + assert-plus "^0.2.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +https-browserify@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-0.0.1.tgz#3f91365cabe60b77ed0ebba24b454e3e09d95a82" + +iconv-lite@~0.4.13: + version "0.4.13" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.13.tgz#1f88aba4ab0b1508e8312acc39345f36e992e2f2" + +icss-replace-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.0.2.tgz#cb0b6054eb3af6edc9ab1d62d01933e2d4c8bfa5" + +ieee754@^1.1.4: + version "1.1.8" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" + +ignore-styles@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ignore-styles/-/ignore-styles-5.0.1.tgz#b49ef2274bdafcd8a4880a966bfe38d1a0bf4671" + +indexes-of@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" + +indexof@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@^2.0.1, inherits@~2.0.0, inherits@~2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + +inherits@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + +ini@^1.3.4, ini@~1.3.0: + version "1.3.4" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" + +interpret@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.2.tgz#f4f623f0bb7122f15f5717c8e254b8161b5c5b2d" + +invariant@^2.2.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360" + dependencies: + loose-envify "^1.0.0" + +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + +is-absolute-url@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + dependencies: + binary-extensions "^1.0.0" + +is-buffer@^1.0.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.5.tgz#1f3b26ef613b214b88cbca23cc6c01d87961eecc" + +is-builtin-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" + dependencies: + builtin-modules "^1.0.0" + +is-directory@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" + +is-dotfile@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.2.tgz#2c132383f39199f8edc268ca01b9b007d205cc4d" + +is-equal-shallow@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" + dependencies: + is-primitive "^2.0.0" + +is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + +is-extglob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + +is-finite@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + dependencies: + number-is-nan "^1.0.0" + +is-glob@^2.0.0, is-glob@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" + dependencies: + is-extglob "^1.0.0" + +is-number@^2.0.2, is-number@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" + dependencies: + kind-of "^3.0.2" + +is-plain-obj@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + +is-posix-bracket@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" + +is-primitive@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" + +is-stream@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + +is-svg@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-2.1.0.tgz#cf61090da0d9efbcab8722deba6f032208dbb0e9" + dependencies: + html-comment-regex "^1.1.0" + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + +is-windows@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.0.tgz#c61d61020c3ebe99261b781bd3d1622395f547f8" + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + dependencies: + isarray "1.0.0" + +isomorphic-fetch@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" + dependencies: + node-fetch "^1.0.1" + whatwg-fetch ">=0.10.0" + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + +jodid25519@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/jodid25519/-/jodid25519-1.0.2.tgz#06d4912255093419477d425633606e0e90782967" + dependencies: + jsbn "~0.1.0" + +jquery@>=1.9.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.2.1.tgz#5c4d9de652af6cd0a770154a631bba12b015c787" + +js-base64@^2.1.9: + version "2.1.9" + resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.1.9.tgz#f0e80ae039a4bd654b5f281fc93f04a914a7fcce" + +js-beautify@^1.6.3: + version "1.6.12" + resolved "https://registry.yarnpkg.com/js-beautify/-/js-beautify-1.6.12.tgz#78b75933505d376da6e5a28e9b7887e0094db8b5" + dependencies: + config-chain "~1.1.5" + editorconfig "^0.13.2" + mkdirp "~0.5.0" + nopt "~3.0.1" + +js-tokens@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.1.tgz#08e9f132484a2c45a30907e9dc4d5567b7f114d7" + +js-yaml@^3.4.3, js-yaml@~3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.7.0.tgz#5c967ddd837a9bfdca5f2de84253abe8a1c03b80" + dependencies: + argparse "^1.0.7" + esprima "^2.6.0" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + +jsesc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + +json-loader@^0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/json-loader/-/json-loader-0.5.4.tgz#8baa1365a632f58a3c46d20175fc6002c96e37de" + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + +json-stable-stringify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" + dependencies: + jsonify "~0.0.0" + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + +json3@3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" + +json5@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + +jsonify@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + +jsprim@^1.2.2: + version "1.4.0" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.0.tgz#a3b87e40298d8c380552d8cc7628a0bb95a22918" + dependencies: + assert-plus "1.0.0" + extsprintf "1.0.2" + json-schema "0.2.3" + verror "1.3.6" + +kind-of@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.1.0.tgz#475d698a5e49ff5e53d14e3e732429dc8bf4cf47" + dependencies: + is-buffer "^1.0.2" + +lazy-cache@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" + +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + dependencies: + invert-kv "^1.0.0" + +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + +loader-runner@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2" + +loader-utils@^0.2.16, loader-utils@~0.2.2: + version "0.2.17" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348" + dependencies: + big.js "^3.1.3" + emojis-list "^2.0.0" + json5 "^0.5.0" + object-assign "^4.0.1" + +loader-utils@^1.0.2, loader-utils@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd" + dependencies: + big.js "^3.1.3" + emojis-list "^2.0.0" + json5 "^0.5.0" + +lodash._baseassign@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e" + dependencies: + lodash._basecopy "^3.0.0" + lodash.keys "^3.0.0" + +lodash._basecopy@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" + +lodash._basecreate@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz#1bc661614daa7fc311b7d03bf16806a0213cf821" + +lodash._getnative@^3.0.0: + version "3.9.1" + resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" + +lodash._isiterateecall@^3.0.0: + version "3.0.9" + resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" + +lodash.camelcase@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" + +lodash.clonedeep@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + +lodash.create@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lodash.create/-/lodash.create-3.1.1.tgz#d7f2849f0dbda7e04682bb8cd72ab022461debe7" + dependencies: + lodash._baseassign "^3.0.0" + lodash._basecreate "^3.0.0" + lodash._isiterateecall "^3.0.0" + +lodash.isarguments@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" + +lodash.isarray@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" + +lodash.keys@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" + dependencies: + lodash._getnative "^3.0.0" + lodash.isarguments "^3.0.0" + lodash.isarray "^3.0.0" + +lodash.memoize@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + +lodash.uniq@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" + +lodash@^2.4.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-2.4.2.tgz#fadd834b9683073da179b3eae6d9c0d15053f73e" + +lodash@^4.14.0, lodash@^4.17.3, lodash@^4.2.0, lodash@^4.6.1: + version "4.17.4" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" + +longest@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" + +loose-envify@^1.0.0, loose-envify@^1.1.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" + dependencies: + js-tokens "^3.0.0" + +lower-case@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" + +lru-cache@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-3.2.0.tgz#71789b3b7f5399bec8565dda38aa30d2a097efee" + dependencies: + pseudomap "^1.0.1" + +lru-cache@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.0.2.tgz#1d17679c069cda5d040991a09dbc2c0db377e55e" + dependencies: + pseudomap "^1.0.1" + yallist "^2.0.0" + +macaddress@^0.2.8: + version "0.2.8" + resolved "https://registry.yarnpkg.com/macaddress/-/macaddress-0.2.8.tgz#5904dc537c39ec6dbefeae902327135fa8511f12" + +math-expression-evaluator@^1.2.14: + version "1.2.16" + resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.2.16.tgz#b357fa1ca9faefb8e48d10c14ef2bcb2d9f0a7c9" + +memory-fs@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.3.0.tgz#7bcc6b629e3a43e871d7e29aca6ae8a7f15cbb20" + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +memory-fs@^0.4.0, memory-fs@~0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +micromatch@^2.1.5: + version "2.3.11" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" + dependencies: + arr-diff "^2.0.0" + array-unique "^0.2.1" + braces "^1.8.2" + expand-brackets "^0.1.4" + extglob "^0.3.1" + filename-regex "^2.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.1" + kind-of "^3.0.2" + normalize-path "^2.0.1" + object.omit "^2.0.0" + parse-glob "^3.0.4" + regex-cache "^0.4.2" + +miller-rabin@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.0.tgz#4a62fb1d42933c05583982f4c716f6fb9e6c6d3d" + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + +mime-db@~1.27.0: + version "1.27.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.27.0.tgz#820f572296bbd20ec25ed55e5b5de869e5436eb1" + +mime-types@^2.1.12, mime-types@~2.1.7: + version "2.1.15" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.15.tgz#a4ebf5064094569237b8cf70046776d09fc92aed" + dependencies: + mime-db "~1.27.0" + +mime@1.3.x, mime@^1.3.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.4.tgz#115f9e3b6b3daf2959983cb38f149a2d40eb5d53" + +min-document@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" + dependencies: + dom-walk "^0.1.0" + +minimalistic-assert@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz#702be2dda6b37f4836bcb3f5db56641b64a1d3d3" + +minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + +minimatch@^3.0.0, minimatch@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774" + dependencies: + brace-expansion "^1.0.0" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + +minimist@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + +mkdirp@0.5.1, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + dependencies: + minimist "0.0.8" + +mocha@^3.0.2: + version "3.2.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-3.2.0.tgz#7dc4f45e5088075171a68896814e6ae9eb7a85e3" + dependencies: + browser-stdout "1.3.0" + commander "2.9.0" + debug "2.2.0" + diff "1.4.0" + escape-string-regexp "1.0.5" + glob "7.0.5" + growl "1.9.2" + json3 "3.3.2" + lodash.create "3.1.1" + mkdirp "0.5.1" + supports-color "3.1.2" + +ms@0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" + +ms@0.7.2: + version "0.7.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.2.tgz#ae25cf2512b3885a1d95d7f037868d8431124765" + +nan@^2.3.0: + version "2.6.1" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.6.1.tgz#8c84f7b14c96b89f57fbc838012180ec8ca39a01" + +ncname@1.0.x: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ncname/-/ncname-1.0.0.tgz#5b57ad18b1ca092864ef62b0b1ed8194f383b71c" + dependencies: + xml-char-classes "^1.0.0" + +no-case@^2.2.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.1.tgz#7aeba1c73a52184265554b7dc03baf720df80081" + dependencies: + lower-case "^1.1.1" + +node-fetch@^1.0.1: + version "1.6.3" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.6.3.tgz#dc234edd6489982d58e8f0db4f695029abcd8c04" + dependencies: + encoding "^0.1.11" + is-stream "^1.0.1" + +node-libs-browser@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.0.0.tgz#a3a59ec97024985b46e958379646f96c4b616646" + dependencies: + assert "^1.1.1" + browserify-zlib "^0.1.4" + buffer "^4.3.0" + console-browserify "^1.1.0" + constants-browserify "^1.0.0" + crypto-browserify "^3.11.0" + domain-browser "^1.1.1" + events "^1.0.0" + https-browserify "0.0.1" + os-browserify "^0.2.0" + path-browserify "0.0.0" + process "^0.11.0" + punycode "^1.2.4" + querystring-es3 "^0.2.0" + readable-stream "^2.0.5" + stream-browserify "^2.0.1" + stream-http "^2.3.1" + string_decoder "^0.10.25" + timers-browserify "^2.0.2" + tty-browserify "0.0.0" + url "^0.11.0" + util "^0.10.3" + vm-browserify "0.0.4" + +node-pre-gyp@^0.6.29: + version "0.6.34" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.34.tgz#94ad1c798a11d7fc67381b50d47f8cc18d9799f7" + dependencies: + mkdirp "^0.5.1" + nopt "^4.0.1" + npmlog "^4.0.2" + rc "^1.1.7" + request "^2.81.0" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^2.2.1" + tar-pack "^3.4.0" + +nopt@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" + dependencies: + abbrev "1" + osenv "^0.1.4" + +nopt@~3.0.1: + version "3.0.6" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + dependencies: + abbrev "1" + +normalize-package-data@^2.3.2: + version "2.3.6" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.3.6.tgz#498fa420c96401f787402ba21e600def9f981fff" + dependencies: + hosted-git-info "^2.1.4" + is-builtin-module "^1.0.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + dependencies: + remove-trailing-separator "^1.0.1" + +normalize-range@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" + +normalize-url@^1.4.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-1.9.1.tgz#2cc0d66b31ea23036458436e3620d85954c66c3c" + dependencies: + object-assign "^4.0.1" + prepend-http "^1.0.0" + query-string "^4.1.0" + sort-keys "^1.0.0" + +npmlog@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.0.2.tgz#d03950e0e78ce1527ba26d2a7592e9348ac3e75f" + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.1" + set-blocking "~2.0.0" + +nth-check@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.1.tgz#9929acdf628fc2c41098deab82ac580cf149aae4" + dependencies: + boolbase "~1.0.0" + +num2fraction@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + +oauth-sign@~0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" + +object-assign@^4.0.1, object-assign@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + +object.omit@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" + dependencies: + for-own "^0.1.4" + is-extendable "^0.1.1" + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + dependencies: + ee-first "1.1.1" + +once@^1.3.0, once@^1.3.3: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + dependencies: + wrappy "1" + +os-browserify@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.2.1.tgz#63fc4ccee5d2d7763d26bbf8601078e6c2e0044f" + +os-homedir@^1.0.0, os-homedir@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + +os-locale@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" + dependencies: + lcid "^1.0.0" + +os-tmpdir@^1.0.0, os-tmpdir@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + +osenv@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.4.tgz#42fe6d5953df06c8064be6f176c3d05aaaa34644" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + +pako@~0.2.0: + version "0.2.9" + resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75" + +param-case@2.1.x: + version "2.1.1" + resolved "https://registry.yarnpkg.com/param-case/-/param-case-2.1.1.tgz#df94fd8cf6531ecf75e6bef9a0858fbc72be2247" + dependencies: + no-case "^2.2.0" + +parse-asn1@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.0.tgz#37c4f9b7ed3ab65c74817b5f2480937fbf97c712" + dependencies: + asn1.js "^4.0.0" + browserify-aes "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + +parse-glob@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + dependencies: + glob-base "^0.3.0" + is-dotfile "^1.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.0" + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + dependencies: + error-ex "^1.2.0" + +parseurl@~1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.1.tgz#c8ab8c9223ba34888aa64a297b28853bec18da56" + +path-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a" + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + dependencies: + pinkie-promise "^2.0.0" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +pbkdf2@^3.0.3: + version "3.0.9" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.9.tgz#f2c4b25a600058b3c3773c086c37dbbee1ffe693" + dependencies: + create-hmac "^1.1.2" + +performance-now@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" + +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + +pkg-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" + dependencies: + find-up "^1.0.0" + +postcss-calc@^5.2.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-5.3.1.tgz#77bae7ca928ad85716e2fda42f261bf7c1d65b5e" + dependencies: + postcss "^5.0.2" + postcss-message-helpers "^2.0.0" + reduce-css-calc "^1.2.6" + +postcss-colormin@^2.1.8: + version "2.2.2" + resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-2.2.2.tgz#6631417d5f0e909a3d7ec26b24c8a8d1e4f96e4b" + dependencies: + colormin "^1.0.5" + postcss "^5.0.13" + postcss-value-parser "^3.2.3" + +postcss-convert-values@^2.3.4: + version "2.6.1" + resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-2.6.1.tgz#bbd8593c5c1fd2e3d1c322bb925dcae8dae4d62d" + dependencies: + postcss "^5.0.11" + postcss-value-parser "^3.1.2" + +postcss-discard-comments@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz#befe89fafd5b3dace5ccce51b76b81514be00e3d" + dependencies: + postcss "^5.0.14" + +postcss-discard-duplicates@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-2.1.0.tgz#b9abf27b88ac188158a5eb12abcae20263b91932" + dependencies: + postcss "^5.0.4" + +postcss-discard-empty@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz#d2b4bd9d5ced5ebd8dcade7640c7d7cd7f4f92b5" + dependencies: + postcss "^5.0.14" + +postcss-discard-overridden@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz#8b1eaf554f686fb288cd874c55667b0aa3668d58" + dependencies: + postcss "^5.0.16" + +postcss-discard-unused@^2.2.1: + version "2.2.3" + resolved "https://registry.yarnpkg.com/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz#bce30b2cc591ffc634322b5fb3464b6d934f4433" + dependencies: + postcss "^5.0.14" + uniqs "^2.0.0" + +postcss-filter-plugins@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/postcss-filter-plugins/-/postcss-filter-plugins-2.0.2.tgz#6d85862534d735ac420e4a85806e1f5d4286d84c" + dependencies: + postcss "^5.0.4" + uniqid "^4.0.0" + +postcss-load-config@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-1.2.0.tgz#539e9afc9ddc8620121ebf9d8c3673e0ce50d28a" + dependencies: + cosmiconfig "^2.1.0" + object-assign "^4.1.0" + postcss-load-options "^1.2.0" + postcss-load-plugins "^2.3.0" + +postcss-load-options@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/postcss-load-options/-/postcss-load-options-1.2.0.tgz#b098b1559ddac2df04bc0bb375f99a5cfe2b6d8c" + dependencies: + cosmiconfig "^2.1.0" + object-assign "^4.1.0" + +postcss-load-plugins@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/postcss-load-plugins/-/postcss-load-plugins-2.3.0.tgz#745768116599aca2f009fad426b00175049d8d92" + dependencies: + cosmiconfig "^2.1.1" + object-assign "^4.1.0" + +postcss-merge-idents@^2.1.5: + version "2.1.7" + resolved "https://registry.yarnpkg.com/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz#4c5530313c08e1d5b3bbf3d2bbc747e278eea270" + dependencies: + has "^1.0.1" + postcss "^5.0.10" + postcss-value-parser "^3.1.1" + +postcss-merge-longhand@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-2.0.2.tgz#23d90cd127b0a77994915332739034a1a4f3d658" + dependencies: + postcss "^5.0.4" + +postcss-merge-rules@^2.0.3: + version "2.1.2" + resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-2.1.2.tgz#d1df5dfaa7b1acc3be553f0e9e10e87c61b5f721" + dependencies: + browserslist "^1.5.2" + caniuse-api "^1.5.2" + postcss "^5.0.4" + postcss-selector-parser "^2.2.2" + vendors "^1.0.0" + +postcss-message-helpers@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-message-helpers/-/postcss-message-helpers-2.0.0.tgz#a4f2f4fab6e4fe002f0aed000478cdf52f9ba60e" + +postcss-minify-font-values@^1.0.2: + version "1.0.5" + resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz#4b58edb56641eba7c8474ab3526cafd7bbdecb69" + dependencies: + object-assign "^4.0.1" + postcss "^5.0.4" + postcss-value-parser "^3.0.2" + +postcss-minify-gradients@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz#5dbda11373703f83cfb4a3ea3881d8d75ff5e6e1" + dependencies: + postcss "^5.0.12" + postcss-value-parser "^3.3.0" + +postcss-minify-params@^1.0.4: + version "1.2.2" + resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz#ad2ce071373b943b3d930a3fa59a358c28d6f1f3" + dependencies: + alphanum-sort "^1.0.1" + postcss "^5.0.2" + postcss-value-parser "^3.0.2" + uniqs "^2.0.0" + +postcss-minify-selectors@^2.0.4: + version "2.1.1" + resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz#b2c6a98c0072cf91b932d1a496508114311735bf" + dependencies: + alphanum-sort "^1.0.2" + has "^1.0.1" + postcss "^5.0.14" + postcss-selector-parser "^2.0.0" + +postcss-modules-extract-imports@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.0.1.tgz#8fb3fef9a6dd0420d3f6d4353cf1ff73f2b2a341" + dependencies: + postcss "^5.0.4" + +postcss-modules-local-by-default@^1.0.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.1.1.tgz#29a10673fa37d19251265ca2ba3150d9040eb4ce" + dependencies: + css-selector-tokenizer "^0.6.0" + postcss "^5.0.4" + +postcss-modules-scope@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-1.0.2.tgz#ff977395e5e06202d7362290b88b1e8cd049de29" + dependencies: + css-selector-tokenizer "^0.6.0" + postcss "^5.0.4" + +postcss-modules-values@^1.1.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-1.2.2.tgz#f0e7d476fe1ed88c5e4c7f97533a3e772ad94ca1" + dependencies: + icss-replace-symbols "^1.0.2" + postcss "^5.0.14" + +postcss-normalize-charset@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz#ef9ee71212d7fe759c78ed162f61ed62b5cb93f1" + dependencies: + postcss "^5.0.5" + +postcss-normalize-url@^3.0.7: + version "3.0.8" + resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz#108f74b3f2fcdaf891a2ffa3ea4592279fc78222" + dependencies: + is-absolute-url "^2.0.0" + normalize-url "^1.4.0" + postcss "^5.0.14" + postcss-value-parser "^3.2.3" + +postcss-ordered-values@^2.1.0: + version "2.2.3" + resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-2.2.3.tgz#eec6c2a67b6c412a8db2042e77fe8da43f95c11d" + dependencies: + postcss "^5.0.4" + postcss-value-parser "^3.0.1" + +postcss-reduce-idents@^2.2.2: + version "2.4.0" + resolved "https://registry.yarnpkg.com/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz#c2c6d20cc958284f6abfbe63f7609bf409059ad3" + dependencies: + postcss "^5.0.4" + postcss-value-parser "^3.0.2" + +postcss-reduce-initial@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz#68f80695f045d08263a879ad240df8dd64f644ea" + dependencies: + postcss "^5.0.4" + +postcss-reduce-transforms@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz#ff76f4d8212437b31c298a42d2e1444025771ae1" + dependencies: + has "^1.0.1" + postcss "^5.0.8" + postcss-value-parser "^3.0.1" + +postcss-selector-parser@^2.0.0, postcss-selector-parser@^2.2.2: + version "2.2.3" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz#f9437788606c3c9acee16ffe8d8b16297f27bb90" + dependencies: + flatten "^1.0.2" + indexes-of "^1.0.1" + uniq "^1.0.1" + +postcss-svgo@^2.1.1: + version "2.1.6" + resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-2.1.6.tgz#b6df18aa613b666e133f08adb5219c2684ac108d" + dependencies: + is-svg "^2.0.0" + postcss "^5.0.14" + postcss-value-parser "^3.2.3" + svgo "^0.7.0" + +postcss-unique-selectors@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz#981d57d29ddcb33e7b1dfe1fd43b8649f933ca1d" + dependencies: + alphanum-sort "^1.0.1" + postcss "^5.0.4" + uniqs "^2.0.0" + +postcss-value-parser@^3.0.1, postcss-value-parser@^3.0.2, postcss-value-parser@^3.1.1, postcss-value-parser@^3.1.2, postcss-value-parser@^3.2.3, postcss-value-parser@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz#87f38f9f18f774a4ab4c8a232f5c5ce8872a9d15" + +postcss-zindex@^2.0.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/postcss-zindex/-/postcss-zindex-2.2.0.tgz#d2109ddc055b91af67fc4cb3b025946639d2af22" + dependencies: + has "^1.0.1" + postcss "^5.0.4" + uniqs "^2.0.0" + +postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0.14, postcss@^5.0.16, postcss@^5.0.2, postcss@^5.0.21, postcss@^5.0.4, postcss@^5.0.5, postcss@^5.0.6, postcss@^5.0.8, postcss@^5.2.16: + version "5.2.16" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.16.tgz#732b3100000f9ff8379a48a53839ed097376ad57" + dependencies: + chalk "^1.1.3" + js-base64 "^2.1.9" + source-map "^0.5.6" + supports-color "^3.2.3" + +prepend-http@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + +preserve@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" + +pretty-error@^2.0.2: + version "2.1.0" + resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-2.1.0.tgz#87f4e9d706a24c87d6cbee9fabec001fcf8c75d8" + dependencies: + renderkid "^2.0.1" + utila "~0.4" + +private@^0.1.6: + version "0.1.7" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.7.tgz#68ce5e8a1ef0a23bb570cc28537b5332aba63ef1" + +process-nextick-args@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" + +process@^0.11.0: + version "0.11.9" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.9.tgz#7bd5ad21aa6253e7da8682264f1e11d11c0318c1" + +process@~0.5.1: + version "0.5.2" + resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf" + +promise@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/promise/-/promise-7.1.1.tgz#489654c692616b8aa55b0724fa809bb7db49c5bf" + dependencies: + asap "~2.0.3" + +prop-types@^15.5.2, prop-types@^15.5.4: + version "15.5.4" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.5.4.tgz#2ed3692716a5060f8cc020946d8238e7419d92c0" + dependencies: + fbjs "^0.8.9" + +proto-list@~1.2.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" + +prr@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/prr/-/prr-0.0.0.tgz#1a84b85908325501411853d0081ee3fa86e2926a" + +pseudomap@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + +public-encrypt@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.0.tgz#39f699f3a46560dd5ebacbca693caf7c65c18cc6" + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + +punycode@^1.2.4, punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + +q@^1.1.2: + version "1.5.0" + resolved "https://registry.yarnpkg.com/q/-/q-1.5.0.tgz#dd01bac9d06d30e6f219aecb8253ee9ebdc308f1" + +qs@~6.4.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" + +query-string@^4.1.0: + version "4.3.2" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-4.3.2.tgz#ec0fd765f58a50031a3968c2431386f8947a5cdd" + dependencies: + object-assign "^4.1.0" + strict-uri-encode "^1.0.0" + +querystring-es3@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + +querystring@0.2.0, querystring@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + +randomatic@^1.1.3: + version "1.1.6" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.6.tgz#110dcabff397e9dcff7c0789ccc0a49adf1ec5bb" + dependencies: + is-number "^2.0.2" + kind-of "^3.0.2" + +randombytes@^2.0.0, randombytes@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.3.tgz#674c99760901c3c4112771a31e521dc349cc09ec" + +range-parser@^1.0.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" + +rc@^1.1.7: + version "1.2.1" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.1.tgz#2e03e8e42ee450b8cb3dce65be1bf8974e1dfd95" + dependencies: + deep-extend "~0.4.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +react-deep-force-update@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/react-deep-force-update/-/react-deep-force-update-1.0.1.tgz#f911b5be1d2a6fe387507dd6e9a767aa2924b4c7" + +react-proxy@^1.1.7: + version "1.1.8" + resolved "https://registry.yarnpkg.com/react-proxy/-/react-proxy-1.1.8.tgz#9dbfd9d927528c3aa9f444e4558c37830ab8c26a" + dependencies: + lodash "^4.6.1" + react-deep-force-update "^1.0.0" + +react-transform-hmr@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/react-transform-hmr/-/react-transform-hmr-1.0.4.tgz#e1a40bd0aaefc72e8dfd7a7cda09af85066397bb" + dependencies: + global "^4.3.0" + react-proxy "^1.1.7" + +react@^15.0.0: + version "15.5.3" + resolved "https://registry.yarnpkg.com/react/-/react-15.5.3.tgz#84055382c025dec4e3b902bb61a8697cc79c1258" + dependencies: + fbjs "^0.8.9" + loose-envify "^1.1.0" + object-assign "^4.1.0" + prop-types "^15.5.2" + +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + +readable-stream@1.0: + version "1.0.34" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +"readable-stream@^2.0.0 || ^1.1.13", readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.1.4, readable-stream@^2.2.6: + version "2.2.8" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.8.tgz#ad28b686f3554c73d39bc32347fa058356624705" + dependencies: + buffer-shims "~1.0.0" + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + string_decoder "~1.0.0" + util-deprecate "~1.0.1" + +readdirp@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" + dependencies: + graceful-fs "^4.1.2" + minimatch "^3.0.2" + readable-stream "^2.0.2" + set-immediate-shim "^1.0.1" + +reduce-css-calc@^1.2.6: + version "1.3.0" + resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz#747c914e049614a4c9cfbba629871ad1d2927716" + dependencies: + balanced-match "^0.4.2" + math-expression-evaluator "^1.2.14" + reduce-function-call "^1.0.1" + +reduce-function-call@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/reduce-function-call/-/reduce-function-call-1.0.2.tgz#5a200bf92e0e37751752fe45b0ab330fd4b6be99" + dependencies: + balanced-match "^0.4.2" + +reflect-metadata@^0.1.9: + version "0.1.10" + resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.10.tgz#b4f83704416acad89988c9b15635d47e03b9344a" + +regenerate@^1.2.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.2.tgz#d1941c67bad437e1be76433add5b385f95b19260" + +regenerator-runtime@^0.10.0: + version "0.10.3" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.3.tgz#8c4367a904b51ea62a908ac310bf99ff90a82a3e" + +regenerator-transform@0.9.11: + version "0.9.11" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.9.11.tgz#3a7d067520cb7b7176769eb5ff868691befe1283" + dependencies: + babel-runtime "^6.18.0" + babel-types "^6.19.0" + private "^0.1.6" + +regex-cache@^0.4.2: + version "0.4.3" + resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.3.tgz#9b1a6c35d4d0dfcef5711ae651e8e9d3d7114145" + dependencies: + is-equal-shallow "^0.1.3" + is-primitive "^2.0.0" + +regexpu-core@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-1.0.0.tgz#86a763f58ee4d7c2f6b102e4764050de7ed90c6b" + dependencies: + regenerate "^1.2.1" + regjsgen "^0.2.0" + regjsparser "^0.1.4" + +regexpu-core@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" + dependencies: + regenerate "^1.2.1" + regjsgen "^0.2.0" + regjsparser "^0.1.4" + +regjsgen@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" + +regjsparser@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" + dependencies: + jsesc "~0.5.0" + +relateurl@0.2.x: + version "0.2.7" + resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" + +remove-trailing-separator@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.0.1.tgz#615ebb96af559552d4bf4057c8436d486ab63cc4" + +renderkid@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-2.0.1.tgz#898cabfc8bede4b7b91135a3ffd323e58c0db319" + dependencies: + css-select "^1.1.0" + dom-converter "~0.1" + htmlparser2 "~3.3.0" + strip-ansi "^3.0.0" + utila "~0.3" + +repeat-element@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" + +repeat-string@^1.5.2: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + dependencies: + is-finite "^1.0.0" + +request@^2.81.0: + version "2.81.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" + dependencies: + aws-sign2 "~0.6.0" + aws4 "^1.2.1" + caseless "~0.12.0" + combined-stream "~1.0.5" + extend "~3.0.0" + forever-agent "~0.6.1" + form-data "~2.1.1" + har-validator "~4.2.1" + hawk "~3.1.3" + http-signature "~1.1.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.7" + oauth-sign "~0.8.1" + performance-now "^0.2.0" + qs "~6.4.0" + safe-buffer "^5.0.1" + stringstream "~0.0.4" + tough-cookie "~2.3.0" + tunnel-agent "^0.6.0" + uuid "^3.0.0" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + +require-from-string@^1.1.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-1.2.1.tgz#529c9ccef27380adfec9a2f965b649bbee636418" + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + +right-align@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" + dependencies: + align-text "^0.1.1" + +rimraf@2, rimraf@^2.5.1, rimraf@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d" + dependencies: + glob "^7.0.5" + +ripemd160@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-1.0.1.tgz#93a4bbd4942bc574b69a8fa57c71de10ecca7d6e" + +safe-buffer@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.0.1.tgz#d263ca54696cd8a306b5ca6551e92de57918fbe7" + +sax@0.5.x: + version "0.5.8" + resolved "https://registry.yarnpkg.com/sax/-/sax-0.5.8.tgz#d472db228eb331c2506b0e8c15524adb939d12c1" + +sax@~1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.2.tgz#fd8631a23bc7826bef5d871bdb87378c95647828" + +"semver@2 || 3 || 4 || 5", semver@^5.0.1, semver@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" + +set-blocking@^2.0.0, set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + +set-immediate-shim@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" + +setimmediate@^1.0.4, setimmediate@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + +sha.js@^2.3.6: + version "2.4.8" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.8.tgz#37068c2c476b6baf402d14a49c67f597921f634f" + dependencies: + inherits "^2.0.1" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + +sigmund@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" + +signal-exit@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + +sntp@1.x.x: + version "1.0.9" + resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" + dependencies: + hoek "2.x.x" + +sort-keys@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" + dependencies: + is-plain-obj "^1.0.0" + +source-list-map@^0.1.7, source-list-map@~0.1.7: + version "0.1.8" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-0.1.8.tgz#c550b2ab5427f6b3f21f5afead88c4f5587b2106" + +source-list-map@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-1.1.1.tgz#1a33ac210ca144d1e561f906ebccab5669ff4cb4" + +source-map-loader@^0.1.5: + version "0.1.6" + resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-0.1.6.tgz#c09903da6d73b9e53b7ed8ee5245597051e98e91" + dependencies: + async "^0.9.0" + loader-utils "~0.2.2" + source-map "~0.1.33" + +source-map-support@^0.4.2: + version "0.4.14" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.14.tgz#9d4463772598b86271b4f523f6c1f4e02a7d6aef" + dependencies: + source-map "^0.5.6" + +source-map@0.1.x, source-map@~0.1.33: + version "0.1.43" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" + dependencies: + amdefine ">=0.0.4" + +source-map@0.5.x, source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1, source-map@~0.5.3: + version "0.5.6" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" + +spdx-correct@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40" + dependencies: + spdx-license-ids "^1.0.2" + +spdx-expression-parse@~1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c" + +spdx-license-ids@^1.0.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + +sshpk@^1.7.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.11.0.tgz#2d8d5ebb4a6fab28ffba37fa62a90f4a3ea59d77" + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + dashdash "^1.12.0" + getpass "^0.1.1" + optionalDependencies: + bcrypt-pbkdf "^1.0.0" + ecc-jsbn "~0.1.1" + jodid25519 "^1.0.0" + jsbn "~0.1.0" + tweetnacl "~0.14.0" + +statuses@~1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" + +stream-browserify@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db" + dependencies: + inherits "~2.0.1" + readable-stream "^2.0.2" + +stream-http@^2.3.1: + version "2.7.0" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.7.0.tgz#cec1f4e3b494bc4a81b451808970f8b20b4ed5f6" + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.1" + readable-stream "^2.2.6" + to-arraybuffer "^1.0.0" + xtend "^4.0.0" + +strict-uri-encode@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" + +string-width@^1.0.1, string-width@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +string_decoder@^0.10.25, string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + +string_decoder@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.0.tgz#f06f41157b664d86069f84bdbdc9b0d8ab281667" + dependencies: + buffer-shims "~1.0.0" + +stringstream@~0.0.4: + version "0.0.5" + resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + dependencies: + ansi-regex "^2.0.0" + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + dependencies: + is-utf8 "^0.2.0" + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + +style-loader@^0.13.1: + version "0.13.2" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.13.2.tgz#74533384cf698c7104c7951150b49717adc2f3bb" + dependencies: + loader-utils "^1.0.2" + +stylus-loader@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/stylus-loader/-/stylus-loader-3.0.1.tgz#77f4b34fd030d25b2617bcf5513db5b0730c4089" + dependencies: + loader-utils "^1.0.2" + lodash.clonedeep "^4.5.0" + when "~3.6.x" + +stylus@^0.54.5: + version "0.54.5" + resolved "https://registry.yarnpkg.com/stylus/-/stylus-0.54.5.tgz#42b9560931ca7090ce8515a798ba9e6aa3d6dc79" + dependencies: + css-parse "1.7.x" + debug "*" + glob "7.0.x" + mkdirp "0.5.x" + sax "0.5.x" + source-map "0.1.x" + +supports-color@3.1.2, supports-color@^3.1.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5" + dependencies: + has-flag "^1.0.0" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + +supports-color@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" + dependencies: + has-flag "^1.0.0" + +svgo@^0.7.0: + version "0.7.2" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-0.7.2.tgz#9f5772413952135c6fefbf40afe6a4faa88b4bb5" + dependencies: + coa "~1.0.1" + colors "~1.1.2" + csso "~2.3.1" + js-yaml "~3.7.0" + mkdirp "~0.5.1" + sax "~1.2.1" + whet.extend "~0.9.9" + +tapable@^0.2.5, tapable@~0.2.5: + version "0.2.6" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.2.6.tgz#206be8e188860b514425375e6f1ae89bfb01fd8d" + +tar-pack@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.4.0.tgz#23be2d7f671a8339376cbdb0b8fe3fdebf317984" + dependencies: + debug "^2.2.0" + fstream "^1.0.10" + fstream-ignore "^1.0.5" + once "^1.3.3" + readable-stream "^2.1.4" + rimraf "^2.5.1" + tar "^2.2.1" + uid-number "^0.0.6" + +tar@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" + dependencies: + block-stream "*" + fstream "^1.0.2" + inherits "2" + +tether@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/tether/-/tether-1.4.0.tgz#0f9fa171f75bf58485d8149e94799d7ae74d1c1a" + +timers-browserify@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.2.tgz#ab4883cf597dcd50af211349a00fbca56ac86b86" + dependencies: + setimmediate "^1.0.4" + +to-arraybuffer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" + +to-fast-properties@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.2.tgz#f3f5c0c3ba7299a7ef99427e44633257ade43320" + +toposort@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/toposort/-/toposort-1.0.3.tgz#f02cd8a74bd8be2fc0e98611c3bacb95a171869c" + +tough-cookie@~2.3.0: + version "2.3.2" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.2.tgz#f081f76e4c85720e6c37a5faced737150d84072a" + dependencies: + punycode "^1.4.1" + +trim-right@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + +ts-loader@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-2.0.3.tgz#89b8c87598f048df065766e07e1538f0eaeb1165" + dependencies: + colors "^1.0.3" + enhanced-resolve "^3.0.0" + loader-utils "^1.0.2" + semver "^5.0.1" + +tty-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + +type-detect@0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-0.1.1.tgz#0ba5ec2a885640e470ea4e8505971900dac58822" + +type-detect@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-1.0.0.tgz#762217cc06db258ec48908a1298e8b95121e8ea2" + +typescript@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.2.2.tgz#606022508479b55ffa368b58fee963a03dfd7b0c" + +ua-parser-js@^0.7.9: + version "0.7.12" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.12.tgz#04c81a99bdd5dc52263ea29d24c6bf8d4818a4bb" + +uglify-js@2.8.x, uglify-js@^2.8.5: + version "2.8.21" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.21.tgz#1733f669ae6f82fc90c7b25ec0f5c783ee375314" + dependencies: + source-map "~0.5.1" + yargs "~3.10.0" + optionalDependencies: + uglify-to-browserify "~1.0.0" + +uglify-to-browserify@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" + +uid-number@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" + +uniq@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" + +uniqid@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/uniqid/-/uniqid-4.1.1.tgz#89220ddf6b751ae52b5f72484863528596bb84c1" + dependencies: + macaddress "^0.2.8" + +uniqs@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02" + +unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + +upper-case@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598" + +url-loader@^0.5.8: + version "0.5.8" + resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-0.5.8.tgz#b9183b1801e0f847718673673040bc9dc1c715c5" + dependencies: + loader-utils "^1.0.2" + mime "1.3.x" + +url@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + +util@0.10.3, util@^0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + dependencies: + inherits "2.0.1" + +utila@~0.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/utila/-/utila-0.3.3.tgz#d7e8e7d7e309107092b05f8d9688824d633a4226" + +utila@~0.4: + version "0.4.0" + resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" + +utils-merge@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.0.tgz#0294fb922bb9375153541c4f7096231f287c8af8" + +uuid@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1" + +validate-npm-package-license@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc" + dependencies: + spdx-correct "~1.0.0" + spdx-expression-parse "~1.0.0" + +vendors@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.1.tgz#37ad73c8ee417fb3d580e785312307d274847f22" + +verror@1.3.6: + version "1.3.6" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.3.6.tgz#cff5df12946d297d2baaefaa2689e25be01c005c" + dependencies: + extsprintf "1.0.2" + +vm-browserify@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73" + dependencies: + indexof "0.0.1" + +vue-class-component@^5.0.0, vue-class-component@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/vue-class-component/-/vue-class-component-5.0.1.tgz#feda06c3da266cee9064e224ba491e089923dce8" + +vue-hot-reload-api@^2.0.11: + version "2.1.0" + resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.1.0.tgz#9ca58a6e0df9078554ce1708688b6578754d86de" + +vue-loader@^11.3.4: + version "11.3.4" + resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-11.3.4.tgz#65e10a44ce092d906e14bbc72981dec99eb090d2" + dependencies: + consolidate "^0.14.0" + hash-sum "^1.0.2" + js-beautify "^1.6.3" + loader-utils "^1.1.0" + lru-cache "^4.0.1" + postcss "^5.0.21" + postcss-load-config "^1.1.0" + postcss-selector-parser "^2.0.0" + source-map "^0.5.6" + vue-hot-reload-api "^2.0.11" + vue-style-loader "^2.0.0" + vue-template-es2015-compiler "^1.2.2" + +vue-property-decorator@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/vue-property-decorator/-/vue-property-decorator-5.0.1.tgz#1be12d62e84b0c83732a03df7a4a8f882a410001" + dependencies: + reflect-metadata "^0.1.9" + vue-class-component "^5.0.0" + +vue-router@^2.3.1: + version "2.5.3" + resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-2.5.3.tgz#073783f564b6aece6c8a59c63e298dc2aabfb51b" + +vue-style-loader@^2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/vue-style-loader/-/vue-style-loader-2.0.5.tgz#f0efac992febe3f12e493e334edb13cd235a3d22" + dependencies: + hash-sum "^1.0.2" + loader-utils "^1.0.2" + +vue-template-compiler@^2.2.6: + version "2.3.2" + resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.3.2.tgz#d48a7f53df5f497033827182ceb4f0d340803017" + dependencies: + de-indent "^1.0.2" + he "^1.1.0" + +vue-template-es2015-compiler@^1.2.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.5.2.tgz#a0a6c50c941d2a4abda963f2f42c337ac450ee95" + +vue@^2.2.6: + version "2.3.2" + resolved "https://registry.yarnpkg.com/vue/-/vue-2.3.2.tgz#9e52aae3593480be235ff227557837e69f98203a" + +watchpack@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.3.1.tgz#7d8693907b28ce6013e7f3610aa2a1acf07dad87" + dependencies: + async "^2.1.2" + chokidar "^1.4.3" + graceful-fs "^4.1.2" + +webpack-dev-middleware@^1.8.4: + version "1.10.1" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-1.10.1.tgz#c6b4cf428139cf1aefbe06a0c00fdb4f8da2f893" + dependencies: + memory-fs "~0.4.1" + mime "^1.3.4" + path-is-absolute "^1.0.0" + range-parser "^1.0.3" + +webpack-hot-middleware@^2.18.0: + version "2.18.0" + resolved "https://registry.yarnpkg.com/webpack-hot-middleware/-/webpack-hot-middleware-2.18.0.tgz#a16bb535b83a6ac94a78ac5ebce4f3059e8274d3" + dependencies: + ansi-html "0.0.7" + html-entities "^1.2.0" + querystring "^0.2.0" + strip-ansi "^3.0.0" + +webpack-node-externals@^1.4.3: + version "1.5.4" + resolved "https://registry.yarnpkg.com/webpack-node-externals/-/webpack-node-externals-1.5.4.tgz#ea05ba17108a23e776c35c42e7bb0e86c225be00" + +webpack-sources@^0.1.0: + version "0.1.5" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-0.1.5.tgz#aa1f3abf0f0d74db7111c40e500b84f966640750" + dependencies: + source-list-map "~0.1.7" + source-map "~0.5.3" + +webpack-sources@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-0.2.3.tgz#17c62bfaf13c707f9d02c479e0dcdde8380697fb" + dependencies: + source-list-map "^1.1.1" + source-map "~0.5.3" + +webpack@^2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-2.3.3.tgz#eecc083c18fb7bf958ea4f40b57a6640c5a0cc78" + dependencies: + acorn "^4.0.4" + acorn-dynamic-import "^2.0.0" + ajv "^4.7.0" + ajv-keywords "^1.1.1" + async "^2.1.2" + enhanced-resolve "^3.0.0" + interpret "^1.0.0" + json-loader "^0.5.4" + loader-runner "^2.3.0" + loader-utils "^0.2.16" + memory-fs "~0.4.1" + mkdirp "~0.5.0" + node-libs-browser "^2.0.0" + source-map "^0.5.3" + supports-color "^3.1.0" + tapable "~0.2.5" + uglify-js "^2.8.5" + watchpack "^1.3.1" + webpack-sources "^0.2.3" + yargs "^6.0.0" + +whatwg-fetch@>=0.10.0, whatwg-fetch@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84" + +when@~3.6.x: + version "3.6.4" + resolved "https://registry.yarnpkg.com/when/-/when-3.6.4.tgz#473b517ec159e2b85005497a13983f095412e34e" + +whet.extend@~0.9.9: + version "0.9.9" + resolved "https://registry.yarnpkg.com/whet.extend/-/whet.extend-0.9.9.tgz#f877d5bf648c97e5aa542fadc16d6a259b9c11a1" + +which-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" + +which@^1.2.9: + version "1.2.14" + resolved "https://registry.yarnpkg.com/which/-/which-1.2.14.tgz#9a87c4378f03e827cecaf1acdf56c736c01c14e5" + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.0.tgz#40edde802a71fea1f070da3e62dcda2e7add96ad" + dependencies: + string-width "^1.0.1" + +window-size@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" + +wordwrap@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" + +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + +xml-char-classes@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/xml-char-classes/-/xml-char-classes-1.0.0.tgz#64657848a20ffc5df583a42ad8a277b4512bbc4d" + +xtend@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + +y18n@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" + +yallist@^2.0.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + +yargs-parser@^4.2.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-4.2.1.tgz#29cceac0dc4f03c6c87b4a9f217dd18c9f74871c" + dependencies: + camelcase "^3.0.0" + +yargs@^6.0.0: + version "6.6.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-6.6.0.tgz#782ec21ef403345f830a808ca3d513af56065208" + dependencies: + camelcase "^3.0.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^1.4.0" + read-pkg-up "^1.0.1" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^1.0.2" + which-module "^1.0.0" + y18n "^3.2.1" + yargs-parser "^4.2.0" + +yargs@~3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" + dependencies: + camelcase "^1.0.2" + cliui "^2.1.0" + decamelize "^1.0.0" + window-size "0.1.0"