-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathProgram.cs
132 lines (115 loc) · 4.29 KB
/
Program.cs
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
using System.Security.Cryptography.X509Certificates;
using System.Text.Json.Serialization;
using FluentValidation;
using Google.Apis.AndroidPublisher.v3;
using Google.Apis.Auth.OAuth2;
using LiftLog.Api.Db;
using LiftLog.Api.Service;
using LiftLog.Api.Validators;
using LiftLog.Lib.Serialization;
using Microsoft.AspNetCore.Authentication;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddValidatorsFromAssemblyContaining<CreateUserRequestValidator>(
ServiceLifetime.Singleton
);
// Add services to the container.
builder.Services.AddDbContext<UserDataContext>(options =>
options
.UseNpgsql(builder.Configuration.GetConnectionString("UserDataContext"))
.ReplaceService<IHistoryRepository, CamelCaseHistoryContext>()
.UseSnakeCaseNamingConvention()
);
builder.Services.AddDbContext<RateLimitContext>(options =>
options
.UseNpgsql(builder.Configuration.GetConnectionString("RateLimitContext"))
.ReplaceService<IHistoryRepository, CamelCaseHistoryContext>()
.UseSnakeCaseNamingConvention()
);
builder.Services.AddCors(options =>
{
options.AddDefaultPolicy(policy =>
{
policy.WithOrigins("*").AllowAnyHeader().AllowAnyMethod();
});
});
var openAiApiKey =
builder.Configuration.GetValue<string?>("OpenAiApiKey")
?? throw new Exception("OpenAiApiKey configuration is not set.");
builder.Services.RegisterGptAiWorkoutPlanner(openAiApiKey);
builder.Services.AddSingleton<PasswordService>();
builder.Services.AddHttpClient<AppleAppStorePurchaseVerificationService>();
builder.Services.AddScoped<RateLimitService>();
builder.Services.AddScoped<PurchaseVerificationService>();
builder.Services.AddScoped<GooglePlayPurchaseVerificationService>();
builder.Services.AddHostedService<CleanupExpiredDataHostedService>();
builder.Services.AddScoped(
(service) =>
{
var webAuthKey = builder.Configuration.GetValue<string?>("WebAuthApiKey");
return new WebAuthPurchaseVerificationService(webAuthKey);
}
);
builder.Services.AddSingleton(
(service) =>
{
var certificateBase64 =
builder.Configuration.GetValue<string>("GooglePlayServiceAccountKeyBase64")
?? throw new Exception("GooglePlayServiceAccountKeyBase64 configuration is not set.");
var serviceAccountEmail =
builder.Configuration.GetValue<string>("GooglePlayServiceAccountEmail")
?? throw new Exception("GooglePlayServiceAccountEmail configuration is not set.");
var certificateBytes = Convert.FromBase64String(certificateBase64);
var certificate = X509CertificateLoader.LoadPkcs12(
certificateBytes,
"notasecret",
X509KeyStorageFlags.Exportable
);
ServiceAccountCredential credential = new(
new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = new[] { AndroidPublisherService.Scope.Androidpublisher },
}.FromCertificate(certificate)
);
return new AndroidPublisherService(
new AndroidPublisherService.Initializer
{
ApplicationName = "LiftLog",
HttpClientInitializer = credential,
}
);
}
);
builder
.Services.AddControllers()
.AddJsonOptions(opts =>
{
opts.JsonSerializerOptions.AllowTrailingCommas = true;
opts.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
opts.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
opts.JsonSerializerOptions.Converters.Add(new TimespanJsonConverter());
opts.JsonSerializerOptions.Converters.Add(new ImmutableDictionaryJsonConverter());
});
var app = builder.Build();
app.UseCors();
app.UseHttpsRedirection();
app.MapControllers();
app.MapMethods(
"/health",
["GET", "HEAD"],
() =>
{
return "healthy";
}
);
using (var scope = app.Services.CreateScope())
{
var userDb = scope.ServiceProvider.GetRequiredService<UserDataContext>();
await userDb.Database.MigrateAsync();
var rateLimitDb = scope.ServiceProvider.GetRequiredService<RateLimitContext>();
await rateLimitDb.Database.MigrateAsync();
}
app.Run();
public partial class Program { }