Files
Ten31-Portal/deploy/startos/actions/index.ts
T
Johnny 5 ba9f026545 Wire Import and Audit Log pages, add Create User action
- Import page: schedule (XLSX/CSV) and entity import with dry-run toggle
- Audit Log page: paginated, filterable by object type
- Nav items now clickable (removed stubs)
- StartOS Action: Create User with name/email/password/role inputs
- Default first-boot creds: jonathan@ten31.xyz
2026-06-07 22:26:14 +00:00

130 lines
3.1 KiB
TypeScript

import { sdk } from '../sdk'
const { InputSpec, Value, Action } = sdk
// ============================================
// Action: Create User
// ============================================
const createUserInputSpec = InputSpec.of({
name: Value.text({
name: 'Full Name',
description: 'Display name for the user',
default: '',
required: true,
placeholder: 'Jane Smith',
}),
email: Value.text({
name: 'Email',
description: 'Login email address',
default: '',
required: true,
placeholder: 'jane@ten31.com',
patterns: [
{
regex: '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$',
description: 'Must be a valid email address',
},
],
}),
password: Value.text({
name: 'Password',
description: 'Initial password (user should change after first login)',
default: '',
required: true,
placeholder: 'minimum 4 characters',
}),
role: Value.select({
name: 'Role',
description:
'approver: full access including sign-off. cfo: read + edit + submit. fund_admin: read + edit + submit. viewer: read only.',
default: 'viewer',
values: {
approver: 'Approver',
cfo: 'CFO',
fund_admin: 'Fund Admin',
viewer: 'Viewer',
},
}),
})
const createUserAction = Action.withInput(
'create-user',
{
name: 'Create User',
description: 'Add a new user account with a role',
warning: null,
allowedStatuses: 'only-running',
group: null,
visibility: 'enabled',
},
createUserInputSpec,
async () => ({
name: '',
email: '',
password: '',
role: 'viewer' as const,
}),
async ({ input, effects }) => {
try {
const sub = await sdk.SubContainer.of(
effects,
{ imageId: 'main' },
sdk.Mounts.of().mountVolume({
volumeId: 'main',
subpath: null,
mountpoint: '/data',
readonly: false,
}),
'create-user-task',
)
const result = await sub.exec(
[
'python3',
'-m',
'ten31portal.cli',
'create-user',
'--name',
input.name,
'--email',
input.email,
'--role',
input.role,
'--password',
input.password,
],
{
env: { TEN31_DB_PATH: '/data/portal.db' },
},
30000,
)
if (result.exitCode !== 0) {
const stderr = result.stderr?.toString() || 'Unknown error'
return {
version: '1' as const,
title: 'Error',
message: `Failed to create user: ${stderr}`,
result: null,
}
}
return {
version: '1' as const,
title: 'User Created',
message: `Created user ${input.name} (${input.email}) with role: ${input.role}`,
result: null,
}
} catch (e: any) {
return {
version: '1' as const,
title: 'Error',
message: `Failed to create user: ${e.message || e}`,
result: null,
}
}
},
)
export const actions = sdk.Actions.of().addAction(createUserAction)