fix(inbox|xtracto): Delete/Read msg and allow non-ascii xtractor names

This commit is contained in:
2026-01-20 13:35:48 +01:00
parent fd2b3fe691
commit d8d5e076ba
6 changed files with 37 additions and 51 deletions

View File

@@ -28,8 +28,8 @@
"nixpkgs": {
"type": "Channel",
"name": "nixpkgs-unstable",
"url": "https://releases.nixos.org/nixpkgs/nixpkgs-26.05pre927565.13868c071cc7/nixexprs.tar.xz",
"hash": "sha256-wufp5c0nWh/87f9eK7xy1eZXms5zd4yl6S4SR+LfA08="
"url": "https://releases.nixos.org/nixpkgs/nixpkgs-26.05pre930106.bde090228871/nixexprs.tar.xz",
"hash": "sha256-N1BW0usecHQVLHKlH+d1NW6CS2At1s3sjpE+N0dOgl4="
},
"pre-commit": {
"type": "Git",
@@ -40,9 +40,9 @@
},
"branch": "master",
"submodules": false,
"revision": "f0927703b7b1c8d97511c4116eb9b4ec6645a0fa",
"url": "https://github.com/cachix/git-hooks.nix/archive/f0927703b7b1c8d97511c4116eb9b4ec6645a0fa.tar.gz",
"hash": "sha256-6MkqajPICgugsuZ92OMoQcgSHnD6sJHwk8AxvMcIgTE="
"revision": "be7d943c905ac39110153679404546625757ec5a",
"url": "https://github.com/cachix/git-hooks.nix/archive/be7d943c905ac39110153679404546625757ec5a.tar.gz",
"hash": "sha256-98kaVYyT0tb8CFSkXPxLs+Ezv2FnBH84pwvQVAXrMWw="
}
},
"version": 7

View File

@@ -24,7 +24,7 @@ pkgs.mkShellNoCC {
# JavaScript
pkgs.bun
pkgs.nodejs
pkgs.nodejs_25
# Devlopment tools
pkgs.npins

View File

@@ -14,7 +14,7 @@ pack_path := "../../packages"
vite_prod := "bunx --bun vite build -c ../../vite.config.js -m production --emptyOutDir --outDir " + "../../dist/public"
vite_dev := "bunx --bun vite build -c ../../vite.config.js -m development --minify false --sourcemap true --emptyOutDir --outDir " + "../../dist/public"
vite := "bunx --bun vite -c ../../vite.config.js -m development "
vite := "bunx vite -c ../../vite.config.js -m development "
# Default recipe - show available commands
default:

View File

@@ -43,15 +43,15 @@ let inboxDialog
let table = document.getElementById "inbox-table"
async {
let! mbox = Remoting.inboxApi().getMessages ()
// if mbox.Length = 0 then
// table?items <- [| {
// id = Guid.Empty
// content = ""
// unread = false
// type' = MessageType.Note
// created = DateTime.Now
// } |]
// else
if mbox.Length = 0 then
table?items <- [| {
id = Guid.Empty
content = ""
unread = false
type' = MessageType.Note
created = DateTime.Now
} |]
else
table?items <- mbox
} |> Async.StartImmediate
@@ -65,30 +65,18 @@ let inboxDialog
|> Set.ofSeq
|> setSelected
let doDelete _ =
let doDelete selected _ =
let table = document.getElementById "inbox-table"
let selectedSet : Guid JS.Set = table?selectedSet
let items: InboxItem array = table?items
async {
let toDelete =
items
|> Array.filter (fun item -> selectedSet.has(item.id))
|> Array.map (fun item -> item.id)
|> Array.filter (fun item -> Set.contains item.id selected)
|> Array.iter (fun item ->
console.log("Delete: %A", item.content)
do arg.deleteMessage item.id
)
console.debug("Deleting", toDelete.Length, "messages")
for id in toDelete do
arg.deleteMessage id
// Clear selection immediately
selectedSet.clear()
setSelected Set.empty
// Wait a bit for server to process, then reload
do! Async.Sleep 200
let! mbox = Remoting.inboxApi().getMessages ()
table?items <- mbox
} |> Async.StartImmediate
loadMessages ()
let doRead selected _ =
let table = document.getElementById "inbox-table"
@@ -118,7 +106,7 @@ let inboxDialog
html $"""
<sp-field-group horizontal>
<sp-action-button
@click={Ev(doDelete)}
@click={Ev(doDelete selected)}
?disabled={selected.Count = 0}>
<sp-icon-delete slot="icon"></sp-icon-delete> Delete selected
</sp-action-button>
@@ -308,11 +296,8 @@ let inboxDialog
let sortFn = if sortDir = "asc" then Array.sortBy else Array.sortByDescending
table?items
|> sortFn (fun item -> JS.expr_js $"{item}[{sortKey}]")
|> fun items -> table?items <- items))
let table =
html $"""
"""
|> fun items -> table?items <- items)
)
html $"""
<div class="inbox-dialog">

View File

@@ -101,20 +101,20 @@ type IPrincipalActor =
inherit IActor
abstract IsActive: unit: unit -> Task<bool>
abstract IsRegistered: unit: unit -> Task<bool>
abstract GetGroups: unit: unit -> Task<string[]>
abstract GetRoles: unit: unit -> Task<string[]>
abstract GetGroups: unit: unit -> Task<string array>
abstract GetRoles: unit: unit -> Task<string array>
abstract Register: unit: unit -> Task<bool>
abstract Activate: unit: unit -> Task<bool>
abstract Disable: unit: unit -> Task<bool>
type UserCredentials = { username: string; password: string }
// needed by signalr
// NOTE: Needed by signalr
type UserIdProvider() =
interface IUserIdProvider with
member this.GetUserId(ctx: HubConnectionContext) =
let uid = ctx.User.Identity.Name
Log.Verbose $"UserIdProvider: {uid}"
Log.Verbose $"UserIdProvider: %s{uid}"
uid
[<RequireQualifiedAccess>]
@@ -130,6 +130,7 @@ let tryStr str =
None
else
Some str
let tryGetEnv =
Environment.GetEnvironmentVariable
>> tryStr
@@ -140,7 +141,7 @@ let authorize: HttpHandler =
let addGroupsAndRoles (principal: ClaimsPrincipal) : Async<bool> =
let addToIdentity (identity: ClaimsIdentity) ctype cc =
eprintfn $"[MultiAuth] Adding claim {ctype} to principal: %A{cc}"
eprintfn $"[MultiAuth] Adding claim %s{ctype} to principal: %A{cc}"
cc
|> Array.choose (fun g ->
if not (principal.HasClaim (fun claim -> claim.Type = ctype && claim.Value = g)) then
@@ -295,14 +296,14 @@ let oidOptions (settings: MultiAuthSettings) (o: OpenIdConnectOptions) =
fun e ->
task {
eprintfn "[MultiAuth] RedirectToIdentityProvider: %A" e.Request.Host.Value
// hack for https behind proxy
// HACK: For https behind proxy
e.ProtocolMessage.RedirectUri <- $"https://{e.Request.Host.Value}/signin-oidc"
return ()
}
o.Events.OnRedirectToIdentityProviderForSignOut <-
fun e ->
task {
// hack for https behind proxy
// HACK: For https behind proxy
e.ProtocolMessage.PostLogoutRedirectUri <- $"https://{e.Request.Host.Value}/signout-callback-oidc"
return ()
}

View File

@@ -251,7 +251,7 @@ module Xtract =
Log.Debug $"Sorcerer.Xtract.downloadZip: user={username}, archiveId={archiveId}, jobId={jobId}"
let fileName = $"/data/archives/xtract/{username}/{jobId}/xtract.zip"
if File.Exists fileName then
(setHttpHeader "Content-Disposition" $"attachment; filename={outname}.zip" >=> streamFile true fileName None None) next ctx
(setHttpHeader "Content-Disposition" $"attachment; filename=site-report.zip" >=> streamFile true fileName None None) next ctx
else
Log.Warning $"Xtract file not found: {fileName}"
RequestErrors.NOT_FOUND "File not found" next ctx