Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
178 commits
Select commit Hold shift + click to select a range
394e3db
feat(account): V27 migration — account disable + token version + audi…
MichaelUray May 23, 2026
3098397
feat(account): extend Account interface with disabledAt + tokenVersio…
MichaelUray May 23, 2026
b8eba0a
feat(account): AdminAuditLogCollection — types + Postgres implementation
MichaelUray May 23, 2026
7dc5365
feat(account): generateTokenWithVersion + verifyTokenVersion helpers
MichaelUray May 23, 2026
e6be973
feat(account): route all token issuance through generateTokenWithVersion
MichaelUray May 23, 2026
9abca6d
feat(account): wire verifyTokenVersion into selectWorkspace + getLogi…
MichaelUray May 23, 2026
aeaf654
feat(account): touchLastActivity helper with 5-min throttle
MichaelUray May 23, 2026
6b70872
feat(account): touch lastActivityAt from all login + workspace-select…
MichaelUray May 23, 2026
f79a43d
feat(account-client): admin user management DTOs + workspace-dep in s…
MichaelUray May 23, 2026
4ad9dbf
feat(account): listAccountsAdmin endpoint (admin-gated, filter+sort+p…
MichaelUray May 23, 2026
a95ad6e
feat(account): getAccountDetails endpoint (admin, identities + member…
MichaelUray May 23, 2026
bc9ddb7
feat(account): setWorkspaceMemberRole endpoint (admin, last-Owner guard)
MichaelUray May 23, 2026
665fb1d
feat(account): removeWorkspaceMember endpoint (idempotent, last-Owner…
MichaelUray May 23, 2026
f48053f
feat(account): triggerPasswordReset endpoint (strict reject for OIDC-…
MichaelUray May 23, 2026
557215a
feat(core): WorkspaceEvent.AccountDisabled + QueueAccountLifecycleMes…
MichaelUray May 23, 2026
eb54502
feat(account): disableAccount endpoint (queue producer DI + token-ver…
MichaelUray May 23, 2026
b213722
feat(account): enableAccount endpoint (clear disabledAt + bump tokenV…
MichaelUray May 23, 2026
2bef21b
feat(account-service): serveAccount(deps) + account-pod queue produce…
MichaelUray May 23, 2026
be838f4
feat(server): TSessionManager.accountLifecycleConsumer broadcasts Acc…
MichaelUray May 23, 2026
8507f5e
feat(client-resources+login-resources): detect AccountDisabled Tx + f…
MichaelUray May 23, 2026
f79169e
feat(login-resources): ForceLogoutModal component + mount in LoginApp
MichaelUray May 23, 2026
2b0ed15
feat(login-resources): /login/admin/users sub-route + AdminUsers plac…
MichaelUray May 23, 2026
50f0520
feat(account-client): interface + RPC stubs for admin user management…
MichaelUray May 23, 2026
2f5f391
feat(login-resources): AdminUsers page — filter bar + sortable table …
MichaelUray May 23, 2026
aeae3e1
feat(login-resources): AdminUsersDrawer — detail view + admin actions
MichaelUray May 23, 2026
45ebbb9
test(account): integration flow — disable/enable round-trip + audit l…
MichaelUray May 23, 2026
e525824
test(sanity): E2E skeleton for admin users management
MichaelUray May 23, 2026
caa6c5b
fix(admin-users): Svelte parses TS 'as' casts poorly inside attribute…
MichaelUray May 23, 2026
2afe12d
fix(account+login-resources): address Codex review findings
MichaelUray May 23, 2026
fd1496b
fix(login-resources+tests): clear LoginAccount on force-logout + real…
MichaelUray May 23, 2026
60db30c
build: bump version.txt to 0.7.423 to match deployed workspace schema
MichaelUray May 23, 2026
ab29275
feat(admin): complete redesign of admin UI + workbench entry point
MichaelUray May 23, 2026
4e56ae5
feat(admin): native Huly UI — antiPanel-navigator + hulyComponent + H…
MichaelUray May 23, 2026
9ca53fb
fix(admin): Back-to-workbench routes through selectWorkspace + Worksp…
MichaelUray May 23, 2026
248b3e0
feat(admin): admin link on /login/selectWorkspace + Workspaces layout…
MichaelUray May 23, 2026
ebf2d64
fix(admin): deterministic table grids + visible search + Accounts tab…
MichaelUray May 23, 2026
91ac43f
fix(account): include V27 columns in Account SELECT + drawer popups v…
MichaelUray May 24, 2026
1782373
fix(authProviders): drop double URL-encoding of provider-auth redirec…
MichaelUray May 24, 2026
2731749
fix(admin): coerce int8 timestamps to Number + default status filter …
MichaelUray May 24, 2026
b17c518
build(dev): support HMR WebSocket through reverse proxy via HULY_DEV_…
MichaelUray May 24, 2026
4d1fc98
types(account): extend AdminAuditAction with create_account + add_wor…
MichaelUray May 24, 2026
aa5aa2b
types(account-client): extend ListAccountsAdminParams + add 5 new DTOs
MichaelUray May 24, 2026
c6d7366
refactor(account): extract assertAdmin helper used by every admin end…
MichaelUray May 24, 2026
0d8fde1
refactor(account): extract sendPasswordResetEmail helper returning bo…
MichaelUray May 24, 2026
71d6d20
feat(account): addWorkspaceMember endpoint (admin) with guards + audit
MichaelUray May 24, 2026
7fa10f5
feat(account): getWorkspaceMembersAdmin endpoint returning enriched m…
MichaelUray May 24, 2026
f1ae944
feat(account): createAccountAdmin endpoint with invite/set modes + op…
MichaelUray May 24, 2026
d83af20
fix(account): tighten createAccountAdmin email regex back to require …
MichaelUray May 24, 2026
776156a
feat(account): four bulk endpoints (add/remove workspace, disable/ena…
MichaelUray May 24, 2026
e315862
feat(account): listAccountsAdmin sort by email/auth/status + 7 new fi…
MichaelUray May 24, 2026
8d339d3
feat(account-client): add 7 AccountClient wrappers for admin endpoints
MichaelUray May 24, 2026
d4b650a
feat(setting): admin-panel link in NavFooter for admin users
MichaelUray May 24, 2026
f985cf9
feat(admin): left-aligned bounded user table + sort on every column
MichaelUray May 24, 2026
eb29a50
feat(admin): per-column filter popovers with column-specific inputs
MichaelUray May 24, 2026
b128bc2
feat(admin): add-to-workspace from user drawer
MichaelUray May 24, 2026
1eeda01
feat(admin): per-workspace drawer with members list (read-only)
MichaelUray May 24, 2026
c3136de
feat(admin): workspace drawer — add/change-role/remove member
MichaelUray May 24, 2026
06e5342
feat(admin): bulk action bar with add/remove/disable/enable/reset
MichaelUray May 24, 2026
4085da1
fix(admin): preserve selection + drawer state across filter/sort/bulk…
MichaelUray May 24, 2026
3c36db9
feat(admin): CreateAccountPopup with invite/set modes + initial works…
MichaelUray May 24, 2026
adfe53d
fix(admin): workspace.mode lookup via WorkspaceInfoWithStatus + bulk-…
MichaelUray May 24, 2026
a716aa1
fix(admin): strip TS `as any` casts from Svelte attribute braces
MichaelUray May 24, 2026
d0fdf01
polish(admin): apply 7 quick-wins from frontend-design review
MichaelUray May 24, 2026
11317ba
polish(admin): apply remaining 4 frontend-design findings F3/F6/F9/F12
MichaelUray May 24, 2026
510c3f2
redesign(admin): users table — full-width, uniform row heights, polis…
MichaelUray May 24, 2026
311efa7
polish(admin): drop drawer scrim, highlight active row, keep drawer o…
MichaelUray May 24, 2026
e7a6849
fix(admin): workspaces visible by default + user-table headers left-a…
MichaelUray May 24, 2026
7ab2a03
redesign(admin): flat workspace list, drop Hour/Day/Weeks grouping
MichaelUray May 24, 2026
a95346e
refactor(admin): per-column sort+filter on workspaces, drop accounts …
MichaelUray May 24, 2026
e1173a9
fix(admin): import AccountRole in AdminUsers.svelte (bulk-add crasher)
MichaelUray May 24, 2026
6dda9a0
fix(admin): admin-gate via reactive {#if} so admin slot never mounts …
MichaelUray May 24, 2026
07a4f4e
feat(admin): MassActionConfirm component for mass-action footgun prot…
MichaelUray May 24, 2026
218ee70
fix(admin): typed-confirm guard on Workspaces Mass-Archive + Mass-Mig…
MichaelUray May 24, 2026
a92639e
fix(admin): typed-confirm guard on Users bulk-disable/enable/reset
MichaelUray May 24, 2026
ae62f68
fix(account): populate adminFirstName/adminLastName in audit entries
MichaelUray May 24, 2026
b98d91d
fix(admin): honest UI copy for bulk-disable (no realtime eviction yet)
MichaelUray May 24, 2026
e626b3e
fix(account): atomic $inc for tokenVersion in disable/enable (race-free)
MichaelUray May 24, 2026
cf4958c
fix(account): bulkRemoveFromWorkspace excludes admin self
MichaelUray May 24, 2026
317ac2e
fix(admin): strip TS type annotation from showPopup template callbacks
MichaelUray May 24, 2026
8092f6a
refactor(admin): delete dead sortArrow()/isSorted() helpers
MichaelUray May 24, 2026
31479b6
refactor(admin): centralize parseRole in admin-users/util.ts
MichaelUray May 24, 2026
c138b31
perf(admin): debounce AddMemberToWorkspacePopup search 300ms
MichaelUray May 24, 2026
330c383
refactor(admin): consolidate confirmAction + notify in util.ts
MichaelUray May 24, 2026
e741fd1
refactor(admin): type AdminUsersDrawer.accountUuid as AccountUuid
MichaelUray May 24, 2026
6a054ed
refactor(admin): data-drawer-keep-open attribute replaces popup-class…
MichaelUray May 24, 2026
678e74c
refactor(admin): standardize column-filter key on workspace_count
MichaelUray May 24, 2026
57e4728
refactor(account): drop workspaceUuids in favor of workspaceUuidsIn
MichaelUray May 24, 2026
5cc55dc
fix(admin): clamp wsMin/wsMax negatives (client + server)
MichaelUray May 24, 2026
67c6c4a
feat(admin): password hygiene on CreateAccountPopup
MichaelUray May 24, 2026
da95030
perf(admin): memoize per-row session-ops sum
MichaelUray May 24, 2026
57a32a8
feat(account): V28 migration — admin_audit_log relax + admin-panel in…
MichaelUray May 24, 2026
f59cbe0
perf(account): SQL pushdown for listAccountsAdmin
MichaelUray May 24, 2026
5886dcd
perf(account): bulk endpoints use internal helpers (no per-row admin …
MichaelUray May 24, 2026
d974520
feat(account): wire lifecycle producer through bulkSetDisabled + audi…
MichaelUray May 24, 2026
01b05cb
feat(admin): dashboard stats revamp + orphan preset
MichaelUray May 24, 2026
d707c56
feat(admin): long-running workspace banner
MichaelUray May 24, 2026
0227ae3
feat(admin): storage column label rename + Top 10 by storage preset
MichaelUray May 24, 2026
253721d
feat(admin): saved filter presets (localStorage)
MichaelUray May 24, 2026
edc7579
feat(account): listAuditAdmin endpoint for Plan 3 Audit UI
MichaelUray May 24, 2026
6bad516
feat(admin): Audit log global page
MichaelUray May 24, 2026
4cac694
feat(admin): per-entity audit tab in user + workspace drawers
MichaelUray May 24, 2026
4aa0422
feat(admin): global search (Ctrl+K) for users
MichaelUray May 24, 2026
a55903d
feat(admin): universal CSV export — accounts + workspaces
MichaelUray May 24, 2026
2b6a97a
feat(admin): keyboard navigation in admin tables
MichaelUray May 24, 2026
f87cb18
feat(admin): drawer copy-UUID + copy-email quick actions
MichaelUray May 24, 2026
387257c
a11y(admin): aria-busy, aria-live, aria-rowindex on admin tables
MichaelUray May 24, 2026
0e24225
feat(admin): admin-badge hover lists configured ADMIN_EMAILS
MichaelUray May 24, 2026
44397c3
feat(admin): confirm dialog when closing drawer during busy operation
MichaelUray May 24, 2026
efe42d1
fix(admin): 5 Svelte-loader + SQL bugs that broke the live dev-front
MichaelUray May 25, 2026
bd93d32
fix(admin): self-review fallout — CSV, GlobalSearch, audit filter, si…
MichaelUray May 25, 2026
f2bb1a6
fix(admin): extract exportAccountsCsv to top-level (svelte-loader fix)
MichaelUray May 25, 2026
c5da4d1
fix(account): decodeFilterParam — hard-reject malformed/poisoned input
MichaelUray May 25, 2026
d6e0e9b
fix(account): cap decodeFilterParam recursion at 32 levels (DoS guard)
MichaelUray May 25, 2026
7cb65b9
refactor(account-client): shared csvEscape + csvLine util
MichaelUray May 25, 2026
97e1d8a
fix(account-client): quote CSV values containing \r (RFC 4180 + Excel)
MichaelUray May 25, 2026
244cfb2
refactor(admin): extract mergeColumnFilters + DEBOUNCE_MS constant
MichaelUray May 25, 2026
5805289
a11y(admin): html lang, th scope, drawer close aria-label
MichaelUray May 25, 2026
563941e
a11y(admin): theme-tokenize drawer-close focus ring color
MichaelUray May 25, 2026
a7ece08
feat(admin): audit empty state + drawer audit-tab action filter
MichaelUray May 25, 2026
e56483a
fix(admin): drawer audit-tab — reuse AuditEmptyState + case-insensiti…
MichaelUray May 25, 2026
3e8af61
perf(admin): throttle workspace overview-stats poll from 10s to 30s
MichaelUray May 25, 2026
d80a971
perf(admin): cap AdminAudit render at 200 rows, show overflow notice
MichaelUray May 25, 2026
9e03bc3
feat(account): per-token rate-limit on /admin/export/accounts.csv (5/…
MichaelUray May 25, 2026
7c12fb1
feat(account): audit-log retention via AUDIT_RETENTION_DAYS env
MichaelUray May 25, 2026
d97b80f
style(account): drop unnecessary as-any cast in pruneAuditOlderThan
MichaelUray May 25, 2026
259d352
feat(admin): batch_id correlation column + visual grouping in audit UI
MichaelUray May 25, 2026
4da2f06
ui(admin): leading Members icon on Users stat-pill row (V3)
MichaelUray May 25, 2026
fbaf07b
ui(admin): tabular-nums + truncate-with-tooltip on Last-activity (V4)
MichaelUray May 25, 2026
96d92b1
ui(admin): collapse audit Details JSON block by default (V5)
MichaelUray May 25, 2026
44b3744
ui(admin): empty-state icon + hint in GlobalSearch panel (V6)
MichaelUray May 25, 2026
cf2b6db
ui(admin): two-band stats (counts vs capacity) on Workspaces page (V7)
MichaelUray May 25, 2026
cff6e8a
fix(account): split batch_id migration into V29 column + V30 index
MichaelUray May 25, 2026
18641e3
fix(admin): wrap MassActionConfirm typedConfirmPhrase placeholder in …
MichaelUray May 25, 2026
2f1abd7
feat(admin): per-row checkbox selection in Workspaces (parity with Us…
MichaelUray May 25, 2026
8e466d6
ui(admin): make "no backup data" state explicit on Workspaces stats
MichaelUray May 25, 2026
f21103a
fix(admin): Workspaces drawer reactive refetch + active-row highlight
MichaelUray May 25, 2026
d383a2c
ui(admin): stronger Workspaces active-row highlight (parity with Users)
MichaelUray May 25, 2026
f1403e9
ui(admin): remove "Find a user..." (Ctrl+K) trigger from sidebar header
MichaelUray May 25, 2026
a267d3d
ui(admin): Audit log nav icon + Workspace drawer outside-click dismiss
MichaelUray May 25, 2026
1442a40
ui(admin): Audit log filter/sort UX redesign
MichaelUray May 25, 2026
1863f11
fix(admin): rewire Users page status/auth filters to server *In arrays
MichaelUray May 25, 2026
b064290
fix(admin): Workspaces column filter — single popup + clear sticky ic…
MichaelUray May 25, 2026
7e85c26
fix(admin): audit log sort-arrow direction reflects asc/desc
MichaelUray May 25, 2026
9e68061
sec(account): LIKE wildcard escape + CSV CRLF/BOM + 429 charset
MichaelUray May 25, 2026
0bb530a
chore(admin): drop unused GlobalSearch + quiet Mongo prune retry
MichaelUray May 25, 2026
d49b3f7
fix(account): wire orphan filter through listAccountsAdmin service ma…
MichaelUray May 25, 2026
778ae3a
fix(admin): emit CSV UTF-8 BOM via fromCharCode / Buffer (svelte-load…
MichaelUray May 25, 2026
1e52ac4
fix(admin): align column headers with body cells when not sorted
MichaelUray May 25, 2026
b591139
feat(admin): per-column filter icons on audit-log table
MichaelUray May 25, 2026
9461de3
feat(admin): date-range preset dropdown on audit log (default 3 days)
MichaelUray May 25, 2026
83b9cde
sec(admin): drop CSV token-in-URL, use Authorization header + blob do…
MichaelUray May 25, 2026
24fc6b1
perf(account): bulkSetDisabled enable branch uses enableAccountInternal
MichaelUray May 25, 2026
6cfc1f2
ui(admin): Workspaces selection-bar shows active subset when mixed
MichaelUray May 25, 2026
b90bbbc
test(account): update postgres.test.ts find-join-passwords expected SQL
MichaelUray May 25, 2026
7a1ebe5
ui(admin): Orphan filter as clickable pill + per-row orphan badge
MichaelUray May 25, 2026
4f13a87
ui(admin): collapse 3 preset buttons into single 'Presets' dropdown
MichaelUray May 25, 2026
fd4cb99
ui(admin): demote Export CSV to ghost; add 'Add workspace' primary bu…
MichaelUray May 25, 2026
5193694
ui(admin): move Export CSV next to Presets, regular kind
MichaelUray May 25, 2026
60e4d27
feat(admin): clickable stat pills for Total/Active/Disabled/Admins fi…
MichaelUray May 25, 2026
0c3af29
ux(admin-users): move bulk-action bar above the table
MichaelUray May 26, 2026
208ab5b
feat(admin-users): add hard-delete account action
MichaelUray May 26, 2026
cddaa1c
fix(admin-users): codex-review fixes for hard-delete
MichaelUray May 26, 2026
384a81d
fix(admin-audit): pass admin token to listAuditAdmin
MichaelUray May 26, 2026
ab25893
fix(admin-users+audit): two UX papercuts found during E2E sweep
MichaelUray May 26, 2026
086b7f9
revert(admin): remove hard-delete from PR #10883 scope
MichaelUray May 27, 2026
08472f4
feat(admin/users): V5a - workspace-root backlink in drawer
MichaelUray May 27, 2026
2869af3
feat(admin/audit): V7 - Custom-range pre-fills From/To from prior preset
MichaelUray May 27, 2026
cb8c4a2
feat(admin/audit): V8 - timezone tooltip on audit timestamps
MichaelUray May 27, 2026
1d61952
feat(account,admin/audit): V13 - admin_action_denied audit event (red…
MichaelUray May 27, 2026
684aa13
Merge remote-tracking branch 'upstream/develop' into feat/admin-user-…
MichaelUray Jul 2, 2026
c037631
chore: apply repo formatting and lint fixes after develop merge
MichaelUray Jul 2, 2026
11adbe8
test: expect account lifecycle consumer in session manager setup
MichaelUray Jul 2, 2026
aed8501
fix(account): Account-Disable am Transactor durchsetzen (C2)
MichaelUray Jul 7, 2026
733bfec
fix(account-service): CSV-Export nur via Authorization-Header (M-CSV)
MichaelUray Jul 8, 2026
49ca255
perf(account): getWorkspaceMembersAdmin gezielte $in-Query statt Full…
MichaelUray Jul 8, 2026
38674fb
fix(account): Audit-Luecken beobachtbar machen (L-AUD)
MichaelUray Jul 8, 2026
ae7d4ee
fix(account): Last-Admin/Owner-Guard gegen Race absichern (L-RACE)
MichaelUray Jul 8, 2026
13675ec
chore(admin): translate leftover German comments, use placeholder hos…
MichaelUray Jul 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions common/config/rush/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion common/scripts/version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
"0.7.422"
"0.7.423"
2 changes: 1 addition & 1 deletion dev/prod/src/index.ejs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!doctype html>
<html>
<html lang="en">

<head>
<meta charset="utf8">
Expand Down
26 changes: 16 additions & 10 deletions dev/prod/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -490,18 +490,24 @@ module.exports = [
hot: true,
client: {
logging: 'info',
overlay: {
errors: true,
warnings: false,
runtimeErrors: (error) => {
if (error.message.includes('ResizeObserver')) {
return false
overlay: false,
progress: false,
// When the dev server runs behind a reverse proxy terminating TLS on 443
// (e.g. dev.example.com -> nginx -> :8080), the default client points
// at the internal 8080 port and the HMR WebSocket breaks.
// Set HULY_DEV_PUBLIC_HOST=<public-host> to point the wss:// URL at the proxy.
...(process.env.HULY_DEV_PUBLIC_HOST != null
? {
webSocketURL: {
hostname: process.env.HULY_DEV_PUBLIC_HOST,
pathname: '/ws',
port: 443,
protocol: 'wss'
}
}
return true
}
},
progress: false
: {})
},
webSocketServer: 'ws',
proxy: proxy[clientType]
}
}
Expand Down
36 changes: 36 additions & 0 deletions foundations/core/packages/account-client/src/__tests__/csv.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { csvEscape, csvLine } from '../util/csv'

describe('csvEscape', () => {
it('returns empty string for null/undefined', () => {
expect(csvEscape(null)).toBe('')
expect(csvEscape(undefined)).toBe('')
})
it('returns plain string unchanged when no quoting is needed', () => {
expect(csvEscape('hello')).toBe('hello')
expect(csvEscape(42)).toBe('42')
})
it('quotes when the value contains a comma', () => {
expect(csvEscape('a, b')).toBe('"a, b"')
})
it('quotes when the value contains a double quote and doubles it', () => {
expect(csvEscape('he said "hi"')).toBe('"he said ""hi"""')
})
it('quotes when the value contains a newline', () => {
expect(csvEscape('line1\nline2')).toBe('"line1\nline2"')
})
it('quotes when the value contains a carriage return', () => {
expect(csvEscape('line1\rline2')).toBe('"line1\rline2"')
})
it('quotes when the value contains CRLF', () => {
expect(csvEscape('line1\r\nline2')).toBe('"line1\r\nline2"')
})
})

describe('csvLine', () => {
it('joins values with commas and appends RFC-4180 CRLF', () => {
expect(csvLine(['a', 1, 'b'])).toBe('a,1,b\r\n')
})
it('escapes each value individually', () => {
expect(csvLine(['a,b', 'c'])).toBe('"a,b",c\r\n')
})
})
154 changes: 143 additions & 11 deletions foundations/core/packages/account-client/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,17 @@ import type {
UserProfile,
WorkspaceConfiguration,
WorkspaceLoginInfo,
WorkspaceOperation
WorkspaceOperation,
ListAccountsAdminParams,
AccountListRow,
AccountDetailsResponse,
AddWorkspaceMemberParams,
WorkspaceMembersAdminResponse,
BulkResult,
CreateAccountParams,
CreateAccountResponse,
ListAuditAdminParams,
ListAuditAdminResponse
} from './types'
import { getClientTimezone, isNetworkError } from './utils'

Expand Down Expand Up @@ -170,7 +180,6 @@ export interface AccountClient {
getMailboxes: () => Promise<MailboxInfo[]>
deleteMailbox: (mailbox: string) => Promise<void>
listAccounts: (search?: string, skip?: number, limit?: number) => Promise<AccountAggregatedInfo[]>
deleteAccount: (uuid: AccountUuid) => Promise<void>

workerHandshake: (region: string, version: Data<Version>, operation: WorkspaceOperation) => Promise<void>
getPendingWorkspace: (
Expand Down Expand Up @@ -267,6 +276,35 @@ export interface AccountClient {
generate2faSecret: () => Promise<{ secret: string, url: string }>
enable2fa: (secret: string, code: string) => Promise<void>
disable2fa: (code: string) => Promise<void>

// Admin user management (V27)
listAccountsAdmin: (params: ListAccountsAdminParams) => Promise<{ total: number, accounts: AccountListRow[] }>
getAccountDetails: (accountUuid: AccountUuid) => Promise<AccountDetailsResponse>
listAuditAdmin: (params: ListAuditAdminParams) => Promise<ListAuditAdminResponse>
setWorkspaceMemberRole: (
accountUuid: AccountUuid,
workspaceUuid: WorkspaceUuid,
newRole: AccountRole
) => Promise<{ ok: true }>
removeWorkspaceMember: (
accountUuid: AccountUuid,
workspaceUuid: WorkspaceUuid
) => Promise<{ ok: true, wasMember: boolean }>
triggerPasswordReset: (accountUuid: AccountUuid) => Promise<{ ok: true, emailSentTo: string }>
disableAccount: (accountUuid: AccountUuid) => Promise<{ ok: true }>
enableAccount: (accountUuid: AccountUuid) => Promise<{ ok: true }>
addWorkspaceMember: (params: AddWorkspaceMemberParams) => Promise<AccountDetailsResponse>
getWorkspaceMembersAdmin: (workspaceUuid: WorkspaceUuid) => Promise<WorkspaceMembersAdminResponse>
createAccountAdmin: (params: CreateAccountParams) => Promise<CreateAccountResponse>
bulkAddToWorkspace: (
accountUuids: AccountUuid[],
workspaceUuid: WorkspaceUuid,
role: AccountRole
) => Promise<BulkResult>
bulkRemoveFromWorkspace: (accountUuids: AccountUuid[], workspaceUuid: WorkspaceUuid) => Promise<BulkResult>
bulkSetDisabled: (accountUuids: AccountUuid[], disabled: boolean) => Promise<BulkResult>
bulkSendPasswordReset: (accountUuids: AccountUuid[]) => Promise<BulkResult>
getAdminEmails: () => Promise<{ emails: string[] }>
}

/** @public */
Expand Down Expand Up @@ -1057,15 +1095,6 @@ class AccountClientImpl implements AccountClient {
return await this.rpc(request)
}

async deleteAccount (uuid: AccountUuid): Promise<void> {
const request = {
method: 'deleteAccount' as const,
params: { uuid }
}

await this.rpc(request)
}

async releaseSocialId (
personUuid: PersonUuid | undefined,
type: SocialIdType,
Expand Down Expand Up @@ -1386,6 +1415,109 @@ class AccountClientImpl implements AccountClient {

await this.rpc(request)
}

async listAccountsAdmin (params: ListAccountsAdminParams): Promise<{ total: number, accounts: AccountListRow[] }> {
const request = { method: 'listAccountsAdmin' as const, params }
return await this.rpc(request)
}

async getAccountDetails (accountUuid: AccountUuid): Promise<AccountDetailsResponse> {
const request = { method: 'getAccountDetails' as const, params: { accountUuid } }
return await this.rpc(request)
}

async listAuditAdmin (params: ListAuditAdminParams): Promise<ListAuditAdminResponse> {
const request = { method: 'listAuditAdmin' as const, params }
return await this.rpc(request)
}

async setWorkspaceMemberRole (
accountUuid: AccountUuid,
workspaceUuid: WorkspaceUuid,
newRole: AccountRole
): Promise<{ ok: true }> {
const request = {
method: 'setWorkspaceMemberRole' as const,
params: { accountUuid, workspaceUuid, newRole }
}
return await this.rpc(request)
}

async removeWorkspaceMember (
accountUuid: AccountUuid,
workspaceUuid: WorkspaceUuid
): Promise<{ ok: true, wasMember: boolean }> {
const request = {
method: 'removeWorkspaceMember' as const,
params: { accountUuid, workspaceUuid }
}
return await this.rpc(request)
}

async triggerPasswordReset (accountUuid: AccountUuid): Promise<{ ok: true, emailSentTo: string }> {
const request = { method: 'triggerPasswordReset' as const, params: { accountUuid } }
return await this.rpc(request)
}

async disableAccount (accountUuid: AccountUuid): Promise<{ ok: true }> {
const request = { method: 'disableAccount' as const, params: { accountUuid } }
return await this.rpc(request)
}

async enableAccount (accountUuid: AccountUuid): Promise<{ ok: true }> {
const request = { method: 'enableAccount' as const, params: { accountUuid } }
return await this.rpc(request)
}

async addWorkspaceMember (params: AddWorkspaceMemberParams): Promise<AccountDetailsResponse> {
const request = { method: 'addWorkspaceMember' as const, params }
return await this.rpc(request)
}

async getWorkspaceMembersAdmin (workspaceUuid: WorkspaceUuid): Promise<WorkspaceMembersAdminResponse> {
const request = { method: 'getWorkspaceMembersAdmin' as const, params: { workspaceUuid } }
return await this.rpc(request)
}

async createAccountAdmin (params: CreateAccountParams): Promise<CreateAccountResponse> {
const request = { method: 'createAccountAdmin' as const, params }
return await this.rpc(request)
}

async bulkAddToWorkspace (
accountUuids: AccountUuid[],
workspaceUuid: WorkspaceUuid,
role: AccountRole
): Promise<BulkResult> {
const request = {
method: 'bulkAddToWorkspace' as const,
params: { accountUuids, workspaceUuid, role }
}
return await this.rpc(request)
}

async bulkRemoveFromWorkspace (accountUuids: AccountUuid[], workspaceUuid: WorkspaceUuid): Promise<BulkResult> {
const request = {
method: 'bulkRemoveFromWorkspace' as const,
params: { accountUuids, workspaceUuid }
}
return await this.rpc(request)
}

async bulkSetDisabled (accountUuids: AccountUuid[], disabled: boolean): Promise<BulkResult> {
const request = { method: 'bulkSetDisabled' as const, params: { accountUuids, disabled } }
return await this.rpc(request)
}

async bulkSendPasswordReset (accountUuids: AccountUuid[]): Promise<BulkResult> {
const request = { method: 'bulkSendPasswordReset' as const, params: { accountUuids } }
return await this.rpc(request)
}

async getAdminEmails (): Promise<{ emails: string[] }> {
const request = { method: 'getAdminEmails' as const, params: {} }
return await this.rpc(request)
}
}

function withRetry<T, F extends (...args: any[]) => Promise<T>> (
Expand Down
1 change: 1 addition & 0 deletions foundations/core/packages/account-client/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@
export * from './client'
export * from './types'
export * from './utils'
export { csvEscape, csvLine } from './util/csv'
Loading