-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProgram.cs
More file actions
140 lines (118 loc) · 5.08 KB
/
Program.cs
File metadata and controls
140 lines (118 loc) · 5.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
using System.Reflection;
using HotChocolate.Execution.Configuration;
using PhantomDave.BankTracking.Api.Services;
using PhantomDave.BankTracking.Data.Extensions;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;
using Microsoft.Extensions.DependencyInjection;
using HotChocolate.AspNetCore;
using HotChocolate.Authorization;
using Microsoft.EntityFrameworkCore;
using PhantomDave.BankTracking.Data.Context;
using PhantomDave.BankTracking.Library.Models;
using HotChocolate.Types;
using OfficeOpenXml;
namespace PhantomDave.BankTracking.Api;
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
ExcelPackage.License.SetNonCommercialPersonal("BankTracker Developer");
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection")
?? throw new InvalidOperationException("Connection string 'DefaultConnection' not configured.");
builder.Services.AddDataAccess(connectionString);
builder.Services.AddScoped<AccountService>();
builder.Services.AddScoped<FinanceRecordService>();
builder.Services.AddScoped<FileImportService>();
builder.Services.AddScoped<ColumnDetectionService>();
builder.Services.AddHttpContextAccessor();
builder.Services.Configure<JwtSettings>(builder.Configuration.GetSection("Jwt"));
builder.Services.AddSingleton<IJwtTokenService, JwtTokenService>();
// Register background service for recurring records
builder.Services.AddHostedService<RecurringFinanceRecordService>();
var jwtSection = builder.Configuration.GetSection("Jwt");
var secret = jwtSection["Secret"];
if (string.IsNullOrWhiteSpace(secret))
{
throw new InvalidOperationException("JWT Secret is not configured. Please set Jwt:Secret in configuration.");
}
var issuer = jwtSection["Issuer"];
var audience = jwtSection["Audience"];
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret));
builder.Services
.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
// WARNING: RequireHttpsMetadata should be true in production environments
// Set to false only for local development
options.RequireHttpsMetadata = builder.Environment.IsDevelopment() == false;
options.SaveToken = true;
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = !string.IsNullOrWhiteSpace(issuer),
ValidIssuer = issuer,
ValidateAudience = !string.IsNullOrWhiteSpace(audience),
ValidAudience = audience,
ValidateIssuerSigningKey = true,
IssuerSigningKey = key,
ValidateLifetime = true,
ClockSkew = TimeSpan.FromMinutes(1)
};
});
builder.Services.AddAuthorization();
builder.Services.AddCors(options =>
{
options.AddDefaultPolicy(policy =>
policy
.WithOrigins("http://localhost:4200", "http://localhost:5095")
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials());
});
var graphqlBuilder = builder.Services
.AddGraphQLServer()
.AddAuthorization()
.AddQueryType()
.AddMutationType()
.AddType<UploadType>()
.BindRuntimeType<RecurrenceFrequency, EnumType<RecurrenceFrequency>>()
.ModifyRequestOptions(options =>
{
options.IncludeExceptionDetails = builder.Environment.IsDevelopment();
});
RegisterTypeExtensions(graphqlBuilder, typeof(Program).Assembly);
var app = builder.Build();
using (var scope = app.Services.CreateScope())
{
var dbContext = scope.ServiceProvider.GetRequiredService<BankTrackerDbContext>();
dbContext.Database.Migrate();
}
app.UseCors();
app.UseAuthentication();
app.UseAuthorization();
app.MapGraphQL()
.WithOptions(new GraphQLServerOptions
{
Tool = {
Enable = builder.Environment.IsDevelopment()
}
});
app.RunWithGraphQLCommands(args);
}
private static void RegisterTypeExtensions(IRequestExecutorBuilder builder, Assembly assembly)
{
var typeExtensions = assembly.GetTypes()
.Where(t => t.GetCustomAttribute<ExtendObjectTypeAttribute>() != null)
.ToList();
foreach (var type in typeExtensions)
{
builder.AddTypeExtension(type);
}
}
}