Version 3 #40
|
@ -197,3 +197,13 @@ let trySecurityByToken token = backgroundTask {
|
|||
|> Sql.executeAsync toDocument<SecurityInfo>
|
||||
return List.tryHead results
|
||||
}
|
||||
|
||||
// ~~~ LEGACY MIGRATION ~~~ //
|
||||
|
||||
/// Get all legacy citizens
|
||||
let legacy () = backgroundTask {
|
||||
return!
|
||||
dataSource ()
|
||||
|> Sql.query $"SELECT * FROM {Table.Citizen} WHERE c.data ->> 'isLegacy' = 'true'"
|
||||
|> Sql.executeAsync toDocument<Citizen>
|
||||
}
|
||||
|
|
|
@ -59,6 +59,15 @@ module private Auth =
|
|||
| PasswordVerificationResult.SuccessRehashNeeded -> Some true
|
||||
| _ -> None
|
||||
|
||||
/// Require an administrative user (used for legacy migration endpoints)
|
||||
let requireAdmin : HttpHandler = requireUser >=> fun next ctx -> task {
|
||||
// let adminUser = (config ctx)["AdminUser"]
|
||||
// if adminUser = defaultArg (tryUser ctx) "" then return! next ctx
|
||||
// else return! Error.notAuthorized next ctx
|
||||
// TODO: uncomment the above, remove the line below
|
||||
return! next ctx
|
||||
}
|
||||
|
||||
|
||||
// GET: /citizen/account
|
||||
let account : HttpHandler = fun next ctx -> task {
|
||||
|
@ -324,6 +333,13 @@ let saveAccount : HttpHandler = requireUser >=> validateCsrf >=> fun next ctx ->
|
|||
let soLong : HttpHandler = requireUser >=> fun next ctx ->
|
||||
Views.deletionOptions (csrf ctx) |> render "Account Deletion Options" next ctx
|
||||
|
||||
// ~~~ LEGACY MIGRATION ~~~ //
|
||||
|
||||
// GET: /citizen/legacy/list
|
||||
let listLegacy : HttpHandler = Auth.requireAdmin >=> fun next ctx -> task {
|
||||
let! users = Data.legacy ()
|
||||
return! Views.listLegacy users |> render "Migrate Legacy Account" next ctx
|
||||
}
|
||||
|
||||
open Giraffe.EndpointRouting
|
||||
|
||||
|
@ -342,6 +358,7 @@ let endpoints =
|
|||
route "/register" register
|
||||
routef "/reset-password/%s" resetPassword
|
||||
route "/so-long" soLong
|
||||
route "/legacy/list" listLegacy
|
||||
]
|
||||
POST [
|
||||
route "/delete" delete
|
||||
|
|
|
@ -393,3 +393,23 @@ let resetPassword (m : ResetPasswordForm) isHtmx csrf =
|
|||
jsOnLoad $"jjj.citizen.validatePasswords('{nameof m.Password}', 'ConfirmPassword', true)" isHtmx
|
||||
]
|
||||
]
|
||||
|
||||
// ~~~ LEGACY MIGRATION ~~~ //
|
||||
|
||||
let listLegacy (m : Citizen list) =
|
||||
[ table [ _class "table table-sm table-hover" ] [
|
||||
thead [] [
|
||||
tr [] [
|
||||
th [ _scope "col" ] [ txt "Action" ]
|
||||
th [ _scope "col" ] [ txt "NAS Profile" ]
|
||||
]
|
||||
]
|
||||
m |> List.map (fun it ->
|
||||
tr [] [
|
||||
td [] [ a [ _href $"/citizen/legacy/{CitizenId.toString it.Id}/associate" ] [ txt "Migrate" ] ]
|
||||
td [] [ str it.Email ]
|
||||
])
|
||||
|> tbody []
|
||||
]
|
||||
]
|
||||
|> pageWithTitle "Migrate Legacy Account"
|
||||
|
|
|
@ -93,7 +93,7 @@ task {
|
|||
let! _ =
|
||||
pgConn
|
||||
|> Sql.executeTransactionAsync [
|
||||
$"INSERT INTO jjj.{Table.SecurityInfo} VALUES (@id, @data)",
|
||||
$"INSERT INTO {Table.SecurityInfo} VALUES (@id, @data)",
|
||||
newCitizens |> List.map (fun c ->
|
||||
let info = { SecurityInfo.empty with Id = c.Id; AccountLocked = true }
|
||||
[ "@id", Sql.string (CitizenId.toString c.Id)
|
||||
|
@ -114,7 +114,7 @@ task {
|
|||
let! _ =
|
||||
pgConn
|
||||
|> Sql.executeTransactionAsync [
|
||||
"INSERT INTO jjj.continent VALUES (@id, @data)",
|
||||
$"INSERT INTO {Table.Continent} VALUES (@id, @data)",
|
||||
newContinents |> List.map (fun c -> [
|
||||
"@id", Sql.string (ContinentId.toString c.Id)
|
||||
"@data", Sql.jsonb (JsonSerializer.Serialize (c, Json.options))
|
||||
|
@ -204,10 +204,10 @@ task {
|
|||
let! deleted =
|
||||
pgConn
|
||||
|> Sql.query $"
|
||||
DELETE FROM jjj.{Table.Citizen}
|
||||
WHERE id NOT IN (SELECT id FROM jjj.{Table.Profile})
|
||||
AND id NOT IN (SELECT DISTINCT data->>'citizenId' FROM jjj.{Table.Listing})
|
||||
AND id NOT IN (SELECT DISTINCT data->>'citizenId' FROM jjj.{Table.Success})"
|
||||
DELETE FROM {Table.Citizen}
|
||||
WHERE id NOT IN (SELECT id FROM {Table.Profile})
|
||||
AND id NOT IN (SELECT DISTINCT data ->> 'citizenId' FROM {Table.Listing})
|
||||
AND id NOT IN (SELECT DISTINCT data ->> 'citizenId' FROM {Table.Success})"
|
||||
|> Sql.executeNonQueryAsync
|
||||
printfn $"** Deleted {deleted} citizens who had no profile, listings, or success stories"
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user