using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Authorization; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.IdentityModel.Tokens; using MisIngredientesVue.Core.Extensions; using MisIngredientesVue.Core.Models; using MisIngredientesVue.Core.Services; using MisIngredientesVue.Hubs; using MisIngredientesVue.Middleware; using System.Text; using Wkhtmltopdf.NetCore; //using Hangfire; //using Hangfire.Mongo; //using Hangfire.Mongo.Migration.Strategies; //using Hangfire.Mongo.Migration.Strategies.Backup; using MongoDB.Driver; using Microsoft.AspNetCore.Diagnostics; using Newtonsoft.Json; using Microsoft.AspNetCore.Http; using MisIngredientesVue.Core.Exceptions; using System; using Microsoft.AspNetCore.SignalR; using System.Threading.Tasks; namespace MisIngredientesVue { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } private readonly string AllowLocalhostOrigin = "_AllowLocalhostOrigin"; public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddWkhtmltopdf(); services.AddSingleton(); services.AddSingleton, LogRepository>(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.Configure(Configuration.GetSection("Database")); //var mongoUrlBuilder = new MongoUrlBuilder("mongodb://localhost/misingredientes_jobs"); //var mongoClient = new MongoClient(mongoUrlBuilder.ToMongoUrl()); // Add Hangfire services. Hangfire.AspNetCore nuget required //services.AddHangfire(configuration => configuration // .SetDataCompatibilityLevel(CompatibilityLevel.Version_170) // .UseSimpleAssemblyNameTypeSerializer() // .UseRecommendedSerializerSettings() // .UseMongoStorage(mongoClient, mongoUrlBuilder.DatabaseName, new MongoStorageOptions // { // MigrationOptions = new MongoMigrationOptions // { // MigrationStrategy = new MigrateMongoMigrationStrategy(), // BackupStrategy = new CollectionMongoBackupStrategy() // }, // Prefix = "hangfire.mongo", // CheckConnection = true // }) //); // Add the processing server as IHostedService //services.AddHangfireServer(serverOptions => //{ // serverOptions.ServerName = "Hangfire.Mongo server 1"; //}); services.AddCors(options => { options.AddPolicy(AllowLocalhostOrigin, builder => { builder.WithOrigins(new string[] { "https://misingredientes.mx", "http://localhost:3000" }) .AllowAnyMethod() .AllowAnyHeader() .AllowCredentials(); }); }); services.AddMvc(o => { o.EnableEndpointRouting = false; var policy = new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .Build(); o.Filters.Add(new AuthorizeFilter(policy)); //o.Filters.Add(new CorsAuthorizationFilterFactory(AllowLocalhostOrigin)); }).SetCompatibilityVersion(CompatibilityVersion.Version_3_0); // In production, the Vue files will be served from this directory services.AddSpaStaticFiles(configuration => { //QAPROD //configuration.RootPath = "ClientApp/dist"; configuration.RootPath = "/app_qa/ClientApp/dist"; //configuration.RootPath = "/app/ClientApp/dist"; }); var key = Encoding.ASCII.GetBytes("this is my custom Secret key for authnetication"); services.AddAuthentication(x => { x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(x => { x.RequireHttpsMetadata = false; x.SaveToken = true; x.TokenValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(key), ValidateIssuer = false, ValidateAudience = false }; x.Events = new JwtBearerEvents { OnMessageReceived = context => { var accessToken = context.Request.Query["access_token"]; // If the request is for our hub... var path = context.HttpContext.Request.Path; if (!string.IsNullOrEmpty(accessToken) && (path.StartsWithSegments("/apiCallNotificationHub"))) { // Read the token out of the query string context.Token = accessToken; } return Task.CompletedTask; } }; }); //services.AddSwaggerGen(c => //{ // c.SwaggerDoc("v1", new Info { Title = "Mis Ingredientes API", Version = "v1" }); // c.AddSecurityDefinition("Bearer", new ApiKeyScheme // { // Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"", // Name = "Authorization", // In = "header", // Type = "apiKey" // }); // c.AddSecurityRequirement(new Dictionary> // { // { "Bearer", Enumerable.Empty() } // }); //}); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_3_0); services.AddControllers().AddNewtonsoftJson(); services.AddSignalR(); services.AddSingleton(); } public class NameUserIdProvider : IUserIdProvider { public string GetUserId(HubConnectionContext connection) { return connection.User?.Identity?.Name; } } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapHub("/apicallnotificationhub"); }); app.UseExceptionHandler(a => a.Run(async context => { var exceptionHandlerPathFeature = context.Features.Get(); var exception = exceptionHandlerPathFeature.Error; if (exception is UserFriendlyException) { context.Response.StatusCode = 200; var result = JsonConvert.SerializeObject(new { errorMessage = exception.Message }); context.Response.ContentType = "application/json"; await context.Response.WriteAsync(result); } else if (exception is BadRequestException) { context.Response.StatusCode = 400; } //else if(exception is NotFoundException) //{ // context.Response.StatusCode = 404; //} else { //Console.WriteLine($@"[{DateTime.UtcNow.ToString()}] {exception.Message} {exception.StackTrace}"); context.Response.StatusCode = 500; } })); if (env.IsDevelopment()) { //app.UseDeveloperExceptionPage(); } else { app.UseHsts(); } app.UseCors(AllowLocalhostOrigin); app.UseAuthentication(); app.Use((context, next) => { if (context.User.Identity.IsAuthenticated && context.User.Identity.ShouldResetPassword() && !context.Request.Path.Value.ToLower().EndsWith("/api/account/resetpassword")) context.Response.Headers["x-change-password"] = "1"; return next.Invoke(); }); //app.UseHttpsRedirection(); app.UseMvc(); app.UseStaticFiles(); app.UseSpaStaticFiles(); //app.ConfigureExceptionHandler(); //app.UseSwagger(); //app.UseSwaggerUI(c => //{ // c.SwaggerEndpoint("/swagger/v1/swagger.json", "Mis Ingredientes API V1"); //}); app.UseSpa(spa => { spa.Options.SourcePath = "ClientApp"; if (env.IsDevelopment()) { spa.UseNuxtDevelopmentServer(npmScript: "dev"); } }); } } }