using Microsoft.EntityFrameworkCore; using ODCWeb.DataAccess.Data; using ODCWeb.DataAccess.Repository.IRepository; using ODCWeb.DataAccess.Repository; using Microsoft.AspNetCore.Identity; using ODCWeb.Models; using Microsoft.AspNetCore.Http.Features; using ODCWeb.Utility; using Quartz; using System.Text.Json; using Microsoft.IdentityModel.Tokens; using System.Text; using Microsoft.AspNetCore.Authentication.JwtBearer; using static OpenIddict.Abstractions.OpenIddictConstants; using ODCWeb.Services; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllersWithViews().AddRazorRuntimeCompilation().AddJsonOptions(options => { options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; options.JsonSerializerOptions.WriteIndented = true; }); builder.Services.AddRazorPages(); /*builder.Services.AddHttpContextAccessor();*/ //////////Things to REMEMBER BEFORE PUSHING CHANGES (Model changes only) TO GITHUB///////////////// //before changing model , create migration file (A) through add-migration //then change model //create new migration file (B) using add-migration (it will have new changes of model only) //delete previous migration file (A) //push to github with migration file (B) after changing connection string back to server database ///////////////////////Live WEB APP Connection////////////////// var connectionString = builder.Configuration.GetConnectionString("DefaultConnection"); /////////////////////zeeshan local server connection//////////// /*var connectionString = builder.Configuration.GetConnectionString("MySQL2");*/ //////////////////////////////////////////////////////////////// builder.Services.AddDbContext(options => { try { options.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString)); } catch { // Fallback to a common version if auto-detect fails options.UseMySql(connectionString, new MySqlServerVersion(new Version(8, 0, 32))); } options.UseOpenIddict(); }); builder.Services.AddTransient(); builder.Services.AddScoped(); builder.Services.AddScoped(); /*builder.Services.AddOpenIddict() .AddCore(options => { // Register the OpenIddict core components. options.UseEntityFrameworkCore() .UseDbContext(); }) .AddServer(options => { options.AddDevelopmentSigningCertificate(); // Use a certificate for production options.AddSigningKey(new SymmetricSecurityKey(Encoding.UTF8.GetBytes("dmksd32e2nwjdnwd87dscsc7868787v9877dv76f7d8cd7cd87c887c98d7c8d789sc"))); options.AllowPasswordFlow(); options.AllowRefreshTokenFlow(); options.SetTokenEndpointUris("/connect/token"); // ... other options }) .AddValidation() .SetClientId("766d7s97d98") .SetClientSecret("dsscscs3e3e"); */ /*builder.Services.AddOpenIddict() .AddCore(options => { // Register the OpenIddict core components. options.UseEntityFrameworkCore() .UseDbContext(); }) .AddServer(options => { // Set up OpenIddict for token issuance options.SetTokenEndpointUris("/connect/token"); options.AddClient("your_client_id", client => { client.SetClientSecret("your_client_secret"); client.SetRedirectUris("https://your-app/callback"); client.SetAllowedGrantTypes(OpenIddictConstants.GrantTypes.AuthorizationCode); }); // Enable the password and refresh token flows. options.AllowPasswordFlow() .AllowRefreshTokenFlow(); // Register the signing and encryption credentials. options.AddDevelopmentEncryptionCertificate() .AddDevelopmentSigningCertificate(); // Use a custom symmetric security key for token signing (ensure the key is sufficiently long). options.AddSigningKey(new SymmetricSecurityKey( Encoding.UTF8.GetBytes("supersecretkey123456789012345678901234"))); // Configure token and authorization endpoints options.UseAspNetCore() .EnableTokenEndpointPassthrough(); *//* .DisableTransportSecurityRequirement();*//* // Only in development, remove for production }) .AddValidation(options => { // Configure JWT validation for OpenIddict. options.UseAspNetCore(); options.UseLocalServer(); }); */ ////////////////////////////////////////////////////////////// builder.Services.AddOpenIddict() .AddCore(options => { // Register the Entity Framework stores. options.UseEntityFrameworkCore() .UseDbContext(); }) .AddServer(options => { // Enable the token endpoint. options.SetTokenEndpointUris("/connect/token"); // Enable the password flow. options.AllowPasswordFlow() .AllowRefreshTokenFlow(); options.AcceptAnonymousClients(); // Register the signing and encryption credentials. options.AddEphemeralEncryptionKey() .AddEphemeralSigningKey() .DisableAccessTokenEncryption(); options.UseAspNetCore() .EnableTokenEndpointPassthrough() .DisableTransportSecurityRequirement(); // Register scopes. options.RegisterScopes(Scopes.OpenId, Scopes.Profile, Scopes.OfflineAccess); }) .AddValidation(options => { // Enable the token validation. options.UseLocalServer(); options.UseAspNetCore(); }); // Configure JWT Bearer authentication builder.Services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateIssuerSigningKey = true, ValidIssuer = "https://odc.lyoko.studio", ValidAudience = "https://odc.lyoko.studio", IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("sasa9s87a89da8d7a88das")) }; }); ////////////////////////////////////////// /////////////////////////////////////////// builder.Services.AddAuthorization(); builder.Services.AddIdentity(options => options.SignIn.RequireConfirmedAccount = false) .AddEntityFrameworkStores() .AddDefaultTokenProviders() .AddDefaultUI(); ////////////////////////////////////////////////////// builder.Services.ConfigureApplicationCookie(options => { options.LoginPath = $"/Identity/Account/Login"; options.LogoutPath = $"/Identity/Account/Logout"; options.AccessDeniedPath = $"/Identity/Account/AccessDenied"; }); // Increase form value count limit builder.Services.Configure(options => { options.ValueCountLimit = 100000; // Set this to your desired limit }); builder.Services.AddScoped(); /*TimeZoneInfo info = TimeZoneInfo.Utc;*/ TimeZoneInfo info = TimeZoneInfo.FindSystemTimeZoneById("America/Jamaica"); /*var t = TimeZoneConverter.TZConvert.GetTimeZoneInfo("America/Jamaica");*/ builder.Services.AddQuartz(q => { // Use Scoped container for job dependencies q.UseMicrosoftDependencyInjectionJobFactory(); // Define the job q.AddJob(opt => opt.WithIdentity("sendReminderEmail")); // Define the trigger (run every minute for demonstration) q.AddTrigger(opts => opts .ForJob("sendReminderEmail") .WithIdentity("sendReminderEmailTrigger") /*.WithCronSchedule("0 * * * * ?")); */ //perfect Every minute for demonstration (adjust cron expression for desired schedule) /*.WithCronSchedule("0 16 13 * * ?"));*/ //perfect every 1:16 pm /*.WithCronSchedule("0 30 9 * * ?", x => x.InTimeZone(t)));*/ //perfect every 9:30 am in Jamaican time (causing errors in delpoyed app) .WithCronSchedule("0 30 9 * * ?", x => x.InTimeZone(info))); //perfect every 9:30 am in Jamaican timezone /*.WithCronSchedule("0 30 9 * * ? MON-SAT",x=>x.InTimeZone(info)));*/ // perfect 9:30 am excluding sundays }); builder.Services.AddQuartzHostedService(); ////////////////////////// /*Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense(SD.SKey)*/ ; /* Gantt only */ Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense(SD.SKey2); /* Gantt + Excel */ var app = builder.Build(); ///////////////////////////////////////////////////////////// /*var scopeFactory = app.Services.GetRequiredService(); using (var scope = scopeFactory.CreateScope()) { var manager = scope.ServiceProvider.GetRequiredService(); if (await manager.FindByClientIdAsync("1213h2h31b3kj2") == null) { await manager.CreateAsync(new OpenIddictApplicationDescriptor { ClientId = "1213h2h31b3kj2", // Set your client_id here *//* ClientSecret = "your-client-secret", *//* // Optional: if using client secret DisplayName = "My Client Application", Permissions = { OpenIddictConstants.Permissions.Endpoints.Token, OpenIddictConstants.Permissions.GrantTypes.Password, OpenIddictConstants.Permissions.Prefixes.Scope + "offline_access", OpenIddictConstants.Scopes.OfflineAccess } }); } } */ /////////////////////////migration script//////////////////// try { using (var scope = app.Services.CreateScope()) { var dbContext = scope.ServiceProvider.GetRequiredService(); dbContext.Database.EnsureCreated(); if (dbContext.Database.GetPendingMigrations().Any()) { dbContext.Database.Migrate(); } } } catch (Exception ex) { } ///////////////////////////////////////////////////////////// // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.MapRazorPages(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); app.MapControllerRoute( name: "default", pattern: "{area=Admin}/{controller=Home}/{action=LoginTransfer}/{id?}"); app.Run();