|
|
@@ -1,62 +1,22 @@
|
|
|
|
module MyPrayerJournal.Api
|
|
|
|
module MyPrayerJournal.Api
|
|
|
|
|
|
|
|
|
|
|
|
open Microsoft.AspNetCore.Builder
|
|
|
|
open Microsoft.AspNetCore.Http
|
|
|
|
open Microsoft.AspNetCore.Hosting
|
|
|
|
|
|
|
|
open System.IO
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Configuration functions for the application
|
|
|
|
|
|
|
|
module Configure =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Configure the content root
|
|
|
|
|
|
|
|
let contentRoot root =
|
|
|
|
|
|
|
|
WebApplicationOptions (ContentRootPath = root) |> WebApplication.CreateBuilder
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
open Microsoft.Extensions.Configuration
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Configure the application configuration
|
|
|
|
|
|
|
|
let appConfiguration (bldr : WebApplicationBuilder) =
|
|
|
|
|
|
|
|
bldr.Configuration
|
|
|
|
|
|
|
|
.SetBasePath(bldr.Environment.ContentRootPath)
|
|
|
|
|
|
|
|
.AddJsonFile("appsettings.json", optional = false, reloadOnChange = true)
|
|
|
|
|
|
|
|
.AddJsonFile($"appsettings.{bldr.Environment.EnvironmentName}.json", optional = true, reloadOnChange = true)
|
|
|
|
|
|
|
|
.AddEnvironmentVariables "MPJ_"
|
|
|
|
|
|
|
|
|> ignore
|
|
|
|
|
|
|
|
bldr
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
open Microsoft.AspNetCore.Server.Kestrel.Core
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Configure Kestrel from appsettings.json
|
|
|
|
|
|
|
|
let kestrel (bldr : WebApplicationBuilder) =
|
|
|
|
|
|
|
|
let kestrelOpts (ctx : WebHostBuilderContext) (opts : KestrelServerOptions) =
|
|
|
|
|
|
|
|
(ctx.Configuration.GetSection >> opts.Configure >> ignore) "Kestrel"
|
|
|
|
|
|
|
|
bldr.WebHost.UseKestrel().ConfigureKestrel kestrelOpts |> ignore
|
|
|
|
|
|
|
|
bldr
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Configure the web root directory
|
|
|
|
|
|
|
|
let webRoot pathSegments (bldr : WebApplicationBuilder) =
|
|
|
|
|
|
|
|
Array.concat [ [| bldr.Environment.ContentRootPath |]; pathSegments ]
|
|
|
|
|
|
|
|
|> (Path.Combine >> bldr.WebHost.UseWebRoot >> ignore)
|
|
|
|
|
|
|
|
bldr
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
open Microsoft.Extensions.Logging
|
|
|
|
|
|
|
|
open Microsoft.Extensions.Hosting
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Configure logging
|
|
|
|
|
|
|
|
let logging (bldr : WebApplicationBuilder) =
|
|
|
|
|
|
|
|
if bldr.Environment.IsDevelopment () then bldr.Logging.AddFilter (fun l -> l > LogLevel.Information) |> ignore
|
|
|
|
|
|
|
|
bldr.Logging.AddConsole().AddDebug() |> ignore
|
|
|
|
|
|
|
|
bldr
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let sameSite (opts : CookieOptions) =
|
|
|
|
|
|
|
|
match opts.SameSite, opts.Secure with
|
|
|
|
|
|
|
|
| SameSiteMode.None, false -> opts.SameSite <- SameSiteMode.Unspecified
|
|
|
|
|
|
|
|
| _, _ -> ()
|
|
|
|
|
|
|
|
|
|
|
|
open Giraffe
|
|
|
|
open Giraffe
|
|
|
|
|
|
|
|
open Giraffe.EndpointRouting
|
|
|
|
open Microsoft.AspNetCore.Authentication.Cookies
|
|
|
|
open Microsoft.AspNetCore.Authentication.Cookies
|
|
|
|
open Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|
|
|
open Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|
|
|
open Microsoft.AspNetCore.Http
|
|
|
|
open Microsoft.AspNetCore.Builder
|
|
|
|
|
|
|
|
open Microsoft.AspNetCore.HttpOverrides
|
|
|
|
|
|
|
|
open Microsoft.Extensions.Configuration
|
|
|
|
open Microsoft.Extensions.DependencyInjection
|
|
|
|
open Microsoft.Extensions.DependencyInjection
|
|
|
|
|
|
|
|
open Microsoft.Extensions.Hosting
|
|
|
|
|
|
|
|
open Microsoft.Extensions.Logging
|
|
|
|
open Microsoft.IdentityModel.Protocols.OpenIdConnect
|
|
|
|
open Microsoft.IdentityModel.Protocols.OpenIdConnect
|
|
|
|
open MyPrayerJournal.Data
|
|
|
|
open MyPrayerJournal.Data
|
|
|
|
open NodaTime
|
|
|
|
open NodaTime
|
|
|
@@ -64,35 +24,39 @@ module Configure =
|
|
|
|
open System.Text.Json
|
|
|
|
open System.Text.Json
|
|
|
|
open System.Threading.Tasks
|
|
|
|
open System.Threading.Tasks
|
|
|
|
|
|
|
|
|
|
|
|
/// Configure dependency injection
|
|
|
|
[<EntryPoint>]
|
|
|
|
let services (bldr : WebApplicationBuilder) =
|
|
|
|
let main args =
|
|
|
|
let sameSite (opts : CookieOptions) =
|
|
|
|
//use host = Configure.webHost [| "wwwroot" |] (Directory.GetCurrentDirectory ())
|
|
|
|
match opts.SameSite, opts.Secure with
|
|
|
|
//host.Run ()
|
|
|
|
| SameSiteMode.None, false -> opts.SameSite <- SameSiteMode.Unspecified
|
|
|
|
let builder = WebApplication.CreateBuilder args
|
|
|
|
| _, _ -> ()
|
|
|
|
let _ = builder.Configuration.AddEnvironmentVariables "MPJ_"
|
|
|
|
|
|
|
|
let svc = builder.Services
|
|
|
|
|
|
|
|
let cfg = svc.BuildServiceProvider().GetRequiredService<IConfiguration> ()
|
|
|
|
|
|
|
|
|
|
|
|
let _ = bldr.Services.AddRouting ()
|
|
|
|
let _ = svc.AddRouting ()
|
|
|
|
let _ = bldr.Services.AddGiraffe ()
|
|
|
|
let _ = svc.AddGiraffe ()
|
|
|
|
let _ = bldr.Services.AddSingleton<IClock> SystemClock.Instance
|
|
|
|
let _ = svc.AddSingleton<IClock> SystemClock.Instance
|
|
|
|
let _ = bldr.Services.AddSingleton<IDateTimeZoneProvider> DateTimeZoneProviders.Tzdb
|
|
|
|
let _ = svc.AddSingleton<IDateTimeZoneProvider> DateTimeZoneProviders.Tzdb
|
|
|
|
|
|
|
|
let _ = svc.Configure<ForwardedHeadersOptions>(fun (opts : ForwardedHeadersOptions) ->
|
|
|
|
|
|
|
|
opts.ForwardedHeaders <- ForwardedHeaders.XForwardedFor ||| ForwardedHeaders.XForwardedProto)
|
|
|
|
|
|
|
|
|
|
|
|
let _ =
|
|
|
|
let _ =
|
|
|
|
bldr.Services.Configure<CookiePolicyOptions>(fun (opts : CookiePolicyOptions) ->
|
|
|
|
svc.Configure<CookiePolicyOptions>(fun (opts : CookiePolicyOptions) ->
|
|
|
|
opts.MinimumSameSitePolicy <- SameSiteMode.Unspecified
|
|
|
|
opts.MinimumSameSitePolicy <- SameSiteMode.Unspecified
|
|
|
|
opts.OnAppendCookie <- fun ctx -> sameSite ctx.CookieOptions
|
|
|
|
opts.OnAppendCookie <- fun ctx -> sameSite ctx.CookieOptions
|
|
|
|
opts.OnDeleteCookie <- fun ctx -> sameSite ctx.CookieOptions)
|
|
|
|
opts.OnDeleteCookie <- fun ctx -> sameSite ctx.CookieOptions)
|
|
|
|
let _ =
|
|
|
|
let _ =
|
|
|
|
bldr.Services.AddAuthentication(fun opts ->
|
|
|
|
svc.AddAuthentication(fun opts ->
|
|
|
|
opts.DefaultAuthenticateScheme <- CookieAuthenticationDefaults.AuthenticationScheme
|
|
|
|
opts.DefaultAuthenticateScheme <- CookieAuthenticationDefaults.AuthenticationScheme
|
|
|
|
opts.DefaultSignInScheme <- CookieAuthenticationDefaults.AuthenticationScheme
|
|
|
|
opts.DefaultSignInScheme <- CookieAuthenticationDefaults.AuthenticationScheme
|
|
|
|
opts.DefaultChallengeScheme <- CookieAuthenticationDefaults.AuthenticationScheme)
|
|
|
|
opts.DefaultChallengeScheme <- CookieAuthenticationDefaults.AuthenticationScheme)
|
|
|
|
.AddCookie()
|
|
|
|
.AddCookie()
|
|
|
|
.AddOpenIdConnect("Auth0", fun opts ->
|
|
|
|
.AddOpenIdConnect("Auth0", fun opts ->
|
|
|
|
// Configure OIDC with Auth0 options from configuration
|
|
|
|
// Configure OIDC with Auth0 options from configuration
|
|
|
|
let cfg = bldr.Configuration.GetSection "Auth0"
|
|
|
|
let auth0 = cfg.GetSection "Auth0"
|
|
|
|
opts.Authority <- $"""https://{cfg["Domain"]}/"""
|
|
|
|
opts.Authority <- $"""https://{auth0["Domain"]}/"""
|
|
|
|
opts.ClientId <- cfg["Id"]
|
|
|
|
opts.ClientId <- auth0["Id"]
|
|
|
|
opts.ClientSecret <- cfg["Secret"]
|
|
|
|
opts.ClientSecret <- auth0["Secret"]
|
|
|
|
opts.ResponseType <- OpenIdConnectResponseType.Code
|
|
|
|
opts.ResponseType <- OpenIdConnectResponseType.Code
|
|
|
|
|
|
|
|
|
|
|
|
opts.Scope.Clear ()
|
|
|
|
opts.Scope.Clear ()
|
|
|
@@ -117,48 +81,31 @@ module Configure =
|
|
|
|
$"{request.Scheme}://{request.Host.Value}{request.PathBase.Value}{redirUri}"
|
|
|
|
$"{request.Scheme}://{request.Host.Value}{request.PathBase.Value}{redirUri}"
|
|
|
|
| false -> redirUri
|
|
|
|
| false -> redirUri
|
|
|
|
Uri.EscapeDataString $"&returnTo={finalRedirUri}"
|
|
|
|
Uri.EscapeDataString $"&returnTo={finalRedirUri}"
|
|
|
|
ctx.Response.Redirect $"""https://{cfg["Domain"]}/v2/logout?client_id={cfg["Id"]}{returnTo}"""
|
|
|
|
ctx.Response.Redirect $"""https://{auth0["Domain"]}/v2/logout?client_id={auth0["Id"]}{returnTo}"""
|
|
|
|
ctx.HandleResponse ()
|
|
|
|
ctx.HandleResponse ()
|
|
|
|
Task.CompletedTask
|
|
|
|
Task.CompletedTask
|
|
|
|
opts.Events.OnRedirectToIdentityProvider <- fun ctx ->
|
|
|
|
opts.Events.OnRedirectToIdentityProvider <- fun ctx ->
|
|
|
|
let bldr = UriBuilder ctx.ProtocolMessage.RedirectUri
|
|
|
|
let uri = UriBuilder ctx.ProtocolMessage.RedirectUri
|
|
|
|
bldr.Scheme <- cfg["Scheme"]
|
|
|
|
uri.Scheme <- auth0["Scheme"]
|
|
|
|
bldr.Port <- int cfg["Port"]
|
|
|
|
uri.Port <- int auth0["Port"]
|
|
|
|
ctx.ProtocolMessage.RedirectUri <- string bldr
|
|
|
|
ctx.ProtocolMessage.RedirectUri <- string uri
|
|
|
|
Task.CompletedTask)
|
|
|
|
Task.CompletedTask)
|
|
|
|
|
|
|
|
|
|
|
|
let _ = bldr.Services.AddSingleton<JsonSerializerOptions> Json.options
|
|
|
|
let _ = svc.AddSingleton<JsonSerializerOptions> Json.options
|
|
|
|
let _ = bldr.Services.AddSingleton<Json.ISerializer> (SystemTextJson.Serializer Json.options)
|
|
|
|
let _ = svc.AddSingleton<Json.ISerializer> (SystemTextJson.Serializer Json.options)
|
|
|
|
let _ = Connection.setUp bldr.Configuration |> Async.AwaitTask |> Async.RunSynchronously
|
|
|
|
let _ = Connection.setUp cfg |> Async.AwaitTask |> Async.RunSynchronously
|
|
|
|
|
|
|
|
|
|
|
|
bldr.Build ()
|
|
|
|
if builder.Environment.IsDevelopment () then builder.Logging.AddFilter (fun l -> l > LogLevel.Information) |> ignore
|
|
|
|
|
|
|
|
let _ = builder.Logging.AddConsole().AddDebug() |> ignore
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
use app = builder.Build ()
|
|
|
|
open Giraffe.EndpointRouting
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Configure the web application
|
|
|
|
|
|
|
|
let application (app : WebApplication) =
|
|
|
|
|
|
|
|
let _ = app.UseStaticFiles ()
|
|
|
|
let _ = app.UseStaticFiles ()
|
|
|
|
let _ = app.UseCookiePolicy ()
|
|
|
|
let _ = app.UseCookiePolicy ()
|
|
|
|
let _ = app.UseRouting ()
|
|
|
|
let _ = app.UseRouting ()
|
|
|
|
let _ = app.UseAuthentication ()
|
|
|
|
let _ = app.UseAuthentication ()
|
|
|
|
let _ = app.UseGiraffeErrorHandler Handlers.Error.error
|
|
|
|
let _ = app.UseGiraffeErrorHandler Handlers.Error.error
|
|
|
|
let _ = app.UseEndpoints (fun e -> e.MapGiraffeEndpoints Handlers.routes)
|
|
|
|
let _ = app.UseEndpoints (fun e -> e.MapGiraffeEndpoints Handlers.routes)
|
|
|
|
app
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Compose all the configurations into one
|
|
|
|
app.Run ()
|
|
|
|
let webHost pathSegments =
|
|
|
|
|
|
|
|
contentRoot
|
|
|
|
|
|
|
|
>> appConfiguration
|
|
|
|
|
|
|
|
>> kestrel
|
|
|
|
|
|
|
|
>> webRoot pathSegments
|
|
|
|
|
|
|
|
>> logging
|
|
|
|
|
|
|
|
>> services
|
|
|
|
|
|
|
|
>> application
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[<EntryPoint>]
|
|
|
|
|
|
|
|
let main _ =
|
|
|
|
|
|
|
|
use host = Configure.webHost [| "wwwroot" |] (Directory.GetCurrentDirectory ())
|
|
|
|
|
|
|
|
host.Run ()
|
|
|
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|