feat(opsserver-access): add admin user listing to the access dashboard

This commit is contained in:
2026-04-08 09:01:08 +00:00
parent 6099563acd
commit 7971bd249e
21 changed files with 291 additions and 11 deletions

View File

@@ -251,6 +251,34 @@ export const routeManagementStatePart = await appState.getStatePart<IRouteManage
'soft'
);
// ============================================================================
// Users State (read-only list of OpsServer user accounts)
// ============================================================================
export interface IUser {
id: string;
username: string;
role: string;
}
export interface IUsersState {
users: IUser[];
isLoading: boolean;
error: string | null;
lastUpdated: number;
}
export const usersStatePart = await appState.getStatePart<IUsersState>(
'users',
{
users: [],
isLoading: false,
error: null,
lastUpdated: 0,
},
'soft',
);
// Actions for state management
interface IActionContext {
identity: interfaces.data.IIdentity | null;
@@ -1756,6 +1784,35 @@ export const fetchApiTokensAction = routeManagementStatePart.createAction(async
}
});
// Users (read-only list)
export const fetchUsersAction = usersStatePart.createAction(async (statePartArg): Promise<IUsersState> => {
const context = getActionContext();
const currentState = statePartArg.getState()!;
if (!context.identity) return currentState;
try {
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
interfaces.requests.IReq_ListUsers
>('/typedrequest', 'listUsers');
const response = await request.fire({
identity: context.identity,
});
return {
...currentState,
users: response.users,
error: null,
lastUpdated: Date.now(),
};
} catch (error) {
return {
...currentState,
error: error instanceof Error ? error.message : 'Failed to fetch users',
};
}
});
export async function createApiToken(name: string, scopes: interfaces.data.TApiTokenScope[], expiresInDays?: number | null) {
const context = getActionContext();
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<