207 lines
7.4 KiB
C#
Executable File
207 lines
7.4 KiB
C#
Executable File
using BoredCareers.Controllers.Payment;
|
|
using BoredCareers.Services;
|
|
using BoredCareers.Services.DatabaseService;
|
|
using System.Threading.RateLimiting;
|
|
using Stripe;
|
|
using System.Security.Claims;
|
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
|
using Microsoft.IdentityModel.Tokens;
|
|
using System.IdentityModel.Tokens.Jwt;
|
|
using System.Security.Cryptography;
|
|
using BoredCareers.Services.TimerService;
|
|
|
|
var builder = WebApplication.CreateBuilder(args);
|
|
|
|
// Disable null warnings becuse string.IsNullOrEmpty checks for NULL or Empty
|
|
#pragma warning disable CS8604
|
|
|
|
////////////////////////////////
|
|
/////// Database Service ///////
|
|
////////////////////////////////
|
|
|
|
// Address
|
|
string? _dbserver = Environment.GetEnvironmentVariable("MySQLServer");
|
|
string dbserver = !string.IsNullOrEmpty(_dbserver) ? _dbserver : "localhost";
|
|
|
|
// Database
|
|
string? _dbdatabase = Environment.GetEnvironmentVariable("MySQLDatabase");
|
|
string dbdatabase = !string.IsNullOrEmpty(_dbdatabase) ? _dbdatabase : "boredcareers";
|
|
|
|
// UserName
|
|
string? _dbuser = Environment.GetEnvironmentVariable("MySQLUser");
|
|
string dbUser = !string.IsNullOrEmpty(_dbuser) ? _dbuser : "root";
|
|
|
|
// Password
|
|
string? _dbpass = Environment.GetEnvironmentVariable("MySQLPass");
|
|
string dbPass = !string.IsNullOrEmpty(_dbpass) ? _dbpass : "oasv34$8gpv023dd";
|
|
|
|
// Create the database serivice
|
|
builder.Services.AddSingleton<DatabaseService>(sp =>
|
|
new DatabaseService("server=" + dbserver + ";user=" + dbUser + ";database=" + dbdatabase + ";password=" + dbPass + ";port=3306;OldGuids=true;")
|
|
);
|
|
|
|
////////////////////////////////
|
|
///////// Email Service ////////
|
|
////////////////////////////////
|
|
|
|
// Address
|
|
string? _eServer = Environment.GetEnvironmentVariable("EmailServer");
|
|
string EmailServer = !string.IsNullOrEmpty(_eServer) ? _eServer : "mail.mistox.com";
|
|
|
|
// Port
|
|
string? _ePort = Environment.GetEnvironmentVariable("EmailPort");
|
|
int EmailPort = !string.IsNullOrEmpty(_ePort) ? Convert.ToInt32(_ePort) : 587;
|
|
|
|
// User
|
|
string? _eAddress = Environment.GetEnvironmentVariable("EmailAddress");
|
|
string EmailAddress = !string.IsNullOrEmpty(_eAddress) ? _eAddress : "no-reply@mistox.com";
|
|
|
|
// Password
|
|
string? _ePassword = Environment.GetEnvironmentVariable("EmailPassword");
|
|
string EmailPassword = !string.IsNullOrEmpty(_ePassword) ? _ePassword : "";
|
|
|
|
// Create the email service
|
|
EmailService Emailservice = new EmailService( EmailServer, EmailPort, EmailAddress, EmailPassword );
|
|
builder.Services.Add( new ServiceDescriptor( typeof( EmailService ), Emailservice ));
|
|
|
|
////////////////////////////////
|
|
/////// Payment Service ////////
|
|
////////////////////////////////
|
|
|
|
// Payment service name -> must be name of PaymentType enum
|
|
string? PaymentService = Environment.GetEnvironmentVariable("PaymentService");
|
|
IPayment._PaymentType = (PaymentType)Enum.Parse(typeof(PaymentType), PaymentService, true);
|
|
|
|
if (IPayment._PaymentType == PaymentType.StripeIntent) {
|
|
// Get PublicKey
|
|
string? StripePublicKey = Environment.GetEnvironmentVariable("StripePublicKey");
|
|
IPayment._PublicKey = string.IsNullOrEmpty(StripePublicKey) ? "" : StripePublicKey;
|
|
// Get PrivateKey
|
|
string? StripeAPIKey = Environment.GetEnvironmentVariable("StripeApiKey");
|
|
StripeConfiguration.ApiKey = StripeAPIKey;
|
|
// Get Endpoint secret
|
|
string? StripeEndpointKey = Environment.GetEnvironmentVariable("StripeEndpointSecret");
|
|
IPayment._EndpointSecret = string.IsNullOrEmpty(StripeEndpointKey) ? "" : StripeEndpointKey;
|
|
}
|
|
|
|
////////////////////////////////
|
|
/////// Auth Service ////////
|
|
////////////////////////////////
|
|
|
|
RsaSecurityKey? PublicKey = null;
|
|
using (HttpClient client = new HttpClient()) {
|
|
while (PublicKey == null) {
|
|
HttpResponseMessage PublicKeyResponse = await client.GetAsync("https://auth.mistox.com/api/auth/publickey");
|
|
if (PublicKeyResponse.IsSuccessStatusCode) {
|
|
string publicKey = await PublicKeyResponse.Content.ReadAsStringAsync();
|
|
RSA rsa = RSA.Create();
|
|
rsa.ImportFromPem(publicKey);
|
|
PublicKey = new RsaSecurityKey(rsa);
|
|
} else {
|
|
await Task.Delay(2000); // sleep the main thread for 2 seconds before sending another request. Prevent DDOS of my own equiptment
|
|
}
|
|
}
|
|
}
|
|
|
|
builder.Services.AddAuthentication(options => {
|
|
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
|
|
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
|
|
}).AddJwtBearer(options => {
|
|
options.TokenValidationParameters = new TokenValidationParameters {
|
|
ValidateIssuer = true,
|
|
ValidateAudience = true,
|
|
ValidateLifetime = true,
|
|
ValidateIssuerSigningKey = true,
|
|
ValidIssuer = "https://auth.mistox.com",
|
|
ValidAudience = "mistox-llc-auth-token",
|
|
IssuerSigningKey = PublicKey,
|
|
ClockSkew = TimeSpan.FromMinutes(1)
|
|
};
|
|
options.Events = new JwtBearerEvents {
|
|
OnMessageReceived = context => {
|
|
context.Token = context.Request.Cookies["mistox_session"];
|
|
return Task.CompletedTask;
|
|
},
|
|
OnTokenValidated = context => {
|
|
var jwtToken = context.SecurityToken as JwtSecurityToken;
|
|
if (jwtToken != null) {
|
|
var exp = jwtToken.ValidTo;
|
|
var now = DateTime.UtcNow;
|
|
if ((exp - now) < TimeSpan.FromDays(3)) {
|
|
// Impliment token refresh
|
|
}
|
|
}
|
|
return Task.CompletedTask;
|
|
}
|
|
};
|
|
});
|
|
|
|
////////////////////////////////
|
|
/// Rate Limiting Service ////
|
|
////////////////////////////////
|
|
|
|
List<string> allowedOrigins = new List<string>{ "https://boredcareers.com", "https://www.boredcareers.com" };
|
|
if (builder.Environment.IsDevelopment()) {
|
|
allowedOrigins.Add("http://localhost:5000");
|
|
}
|
|
|
|
builder.Services.AddCors(options => {
|
|
options.AddDefaultPolicy(policy => {
|
|
policy.WithOrigins(allowedOrigins.ToArray())
|
|
.AllowAnyHeader()
|
|
.AllowAnyMethod()
|
|
.AllowCredentials();
|
|
});
|
|
});
|
|
|
|
builder.Services.AddRateLimiter(options => {
|
|
options.AddPolicy("PerUserPolicy", httpContext => {
|
|
var userId = httpContext.User.FindFirst(ClaimTypes.NameIdentifier)?.Value
|
|
?? $"ip:{httpContext.Connection.RemoteIpAddress}";
|
|
|
|
return RateLimitPartition.GetTokenBucketLimiter(userId, key => new TokenBucketRateLimiterOptions {
|
|
TokenLimit = 10, // max 10 requests
|
|
QueueProcessingOrder = QueueProcessingOrder.OldestFirst,
|
|
QueueLimit = 0,
|
|
ReplenishmentPeriod = TimeSpan.FromSeconds(15),
|
|
TokensPerPeriod = 2,
|
|
AutoReplenishment = true
|
|
});
|
|
});
|
|
});
|
|
|
|
////////////////////////////////
|
|
///// Background Services /////
|
|
////////////////////////////////
|
|
|
|
builder.Services.AddHostedService<JobCleanupService>();
|
|
|
|
////////////////////////////////
|
|
///// ASPNET Core Function /////
|
|
////////////////////////////////
|
|
|
|
builder.Services.AddControllers();
|
|
|
|
var app = builder.Build();
|
|
|
|
// Configure the HTTP request pipeline.
|
|
if( !app.Environment.IsDevelopment() ) {
|
|
app.UseHsts();
|
|
}
|
|
|
|
app.UseDefaultFiles();
|
|
app.UseStaticFiles();
|
|
|
|
app.UseRateLimiter();
|
|
|
|
app.UseCors();
|
|
|
|
app.UseRouting();
|
|
|
|
app.UseAuthentication();
|
|
app.MapControllers();
|
|
|
|
app.MapFallbackToFile("index.html");
|
|
|
|
app.Run();
|