@jini-ai/user-management 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +77 -0
- package/LICENSE +201 -0
- package/README.md +104 -0
- package/dist/admin/adapters/http.d.ts +29 -0
- package/dist/admin/adapters/http.js +69 -0
- package/dist/admin/adapters/memory.d.ts +61 -0
- package/dist/admin/adapters/memory.js +217 -0
- package/dist/admin/auth.module.d.ts +30 -0
- package/dist/admin/auth.module.js +12 -0
- package/dist/admin/conformance/index.d.ts +56 -0
- package/dist/admin/conformance/index.js +156 -0
- package/dist/admin/controllers/auth.controller.d.ts +23 -0
- package/dist/admin/controllers/auth.controller.js +33 -0
- package/dist/admin/controllers/controller-store.d.ts +18 -0
- package/dist/admin/controllers/controller-store.js +23 -0
- package/dist/admin/controllers/members.controller.d.ts +33 -0
- package/dist/admin/controllers/members.controller.js +119 -0
- package/dist/admin/controllers/roles.controller.d.ts +47 -0
- package/dist/admin/controllers/roles.controller.js +282 -0
- package/dist/admin/controllers/users.controller.d.ts +53 -0
- package/dist/admin/controllers/users.controller.js +220 -0
- package/dist/admin/index.d.ts +21 -0
- package/dist/admin/index.js +15 -0
- package/dist/admin/members.module.d.ts +34 -0
- package/dist/admin/members.module.js +13 -0
- package/dist/admin/messages.en.d.ts +37 -0
- package/dist/admin/messages.en.js +21 -0
- package/dist/admin/models.d.ts +133 -0
- package/dist/admin/models.js +2 -0
- package/dist/admin/people.rules.d.ts +29 -0
- package/dist/admin/people.rules.js +51 -0
- package/dist/admin/ports.d.ts +187 -0
- package/dist/admin/ports.js +17 -0
- package/dist/admin/react/components/DestructiveDialog.d.ts +5 -0
- package/dist/admin/react/components/DestructiveDialog.js +6 -0
- package/dist/admin/react/components/MemberRow.d.ts +5 -0
- package/dist/admin/react/components/MemberRow.js +8 -0
- package/dist/admin/react/components/MembersConfirmation.d.ts +2 -0
- package/dist/admin/react/components/MembersConfirmation.js +8 -0
- package/dist/admin/react/components/PermissionPanel.d.ts +5 -0
- package/dist/admin/react/components/PermissionPanel.js +9 -0
- package/dist/admin/react/components/PolicyRow.d.ts +5 -0
- package/dist/admin/react/components/PolicyRow.js +11 -0
- package/dist/admin/react/components/RoleRow.d.ts +5 -0
- package/dist/admin/react/components/RoleRow.js +10 -0
- package/dist/admin/react/components/UserRow.d.ts +5 -0
- package/dist/admin/react/components/UserRow.js +8 -0
- package/dist/admin/react/components/UsersConfirmation.d.ts +3 -0
- package/dist/admin/react/components/UsersConfirmation.js +9 -0
- package/dist/admin/react/hooks/AuthBinding.hooks.d.ts +39 -0
- package/dist/admin/react/hooks/AuthBinding.hooks.js +21 -0
- package/dist/admin/react/hooks/LoginPage.hooks.d.ts +54 -0
- package/dist/admin/react/hooks/LoginPage.hooks.js +23 -0
- package/dist/admin/react/hooks/MembersBinding.hooks.d.ts +35 -0
- package/dist/admin/react/hooks/MembersBinding.hooks.js +21 -0
- package/dist/admin/react/hooks/MembersPage.hooks.d.ts +99 -0
- package/dist/admin/react/hooks/MembersPage.hooks.js +38 -0
- package/dist/admin/react/hooks/PeopleController.hooks.d.ts +18 -0
- package/dist/admin/react/hooks/PeopleController.hooks.js +20 -0
- package/dist/admin/react/hooks/PermissionPanel.hooks.d.ts +30 -0
- package/dist/admin/react/hooks/PermissionPanel.hooks.js +15 -0
- package/dist/admin/react/hooks/PoliciesTab.hooks.d.ts +47 -0
- package/dist/admin/react/hooks/PoliciesTab.hooks.js +26 -0
- package/dist/admin/react/hooks/RolesBinding.hooks.d.ts +39 -0
- package/dist/admin/react/hooks/RolesBinding.hooks.js +23 -0
- package/dist/admin/react/hooks/RolesController.hooks.d.ts +43 -0
- package/dist/admin/react/hooks/RolesController.hooks.js +25 -0
- package/dist/admin/react/hooks/RolesPage.hooks.d.ts +105 -0
- package/dist/admin/react/hooks/RolesPage.hooks.js +33 -0
- package/dist/admin/react/hooks/RolesTab.hooks.d.ts +35 -0
- package/dist/admin/react/hooks/RolesTab.hooks.js +19 -0
- package/dist/admin/react/hooks/UsersBinding.hooks.d.ts +36 -0
- package/dist/admin/react/hooks/UsersBinding.hooks.js +21 -0
- package/dist/admin/react/hooks/UsersPage.hooks.d.ts +106 -0
- package/dist/admin/react/hooks/UsersPage.hooks.js +22 -0
- package/dist/admin/react/hooks/UsersTab.hooks.d.ts +101 -0
- package/dist/admin/react/hooks/UsersTab.hooks.js +53 -0
- package/dist/admin/react/index.d.ts +203 -0
- package/dist/admin/react/index.js +32 -0
- package/dist/admin/react/pages/LoginPage.d.ts +3 -0
- package/dist/admin/react/pages/LoginPage.js +13 -0
- package/dist/admin/react/pages/MembersPage.d.ts +3 -0
- package/dist/admin/react/pages/MembersPage.js +19 -0
- package/dist/admin/react/pages/RolesPage.d.ts +3 -0
- package/dist/admin/react/pages/RolesPage.js +19 -0
- package/dist/admin/react/pages/UsersPage.d.ts +3 -0
- package/dist/admin/react/pages/UsersPage.js +19 -0
- package/dist/admin/react/tabs/AuthTab.d.ts +4 -0
- package/dist/admin/react/tabs/AuthTab.js +8 -0
- package/dist/admin/react/tabs/MembersTab.d.ts +4 -0
- package/dist/admin/react/tabs/MembersTab.js +9 -0
- package/dist/admin/react/tabs/PoliciesTab.d.ts +4 -0
- package/dist/admin/react/tabs/PoliciesTab.js +9 -0
- package/dist/admin/react/tabs/RolesTab.d.ts +4 -0
- package/dist/admin/react/tabs/RolesTab.js +9 -0
- package/dist/admin/react/tabs/UsersTab.d.ts +4 -0
- package/dist/admin/react/tabs/UsersTab.js +9 -0
- package/dist/admin/roles.module.d.ts +48 -0
- package/dist/admin/roles.module.js +15 -0
- package/dist/admin/rules.d.ts +32 -0
- package/dist/admin/rules.js +32 -0
- package/dist/admin/users.module.d.ts +39 -0
- package/dist/admin/users.module.js +14 -0
- package/dist/core/builtin-permissions.d.ts +10 -0
- package/dist/core/builtin-permissions.js +402 -0
- package/dist/core/index.d.ts +6 -0
- package/dist/core/index.js +9 -0
- package/dist/core/permissions.d.ts +40 -0
- package/dist/core/permissions.js +52 -0
- package/dist/core/ports.d.ts +237 -0
- package/dist/core/ports.js +2 -0
- package/dist/core/runtime-ports.d.ts +8 -0
- package/dist/core/runtime-ports.js +2 -0
- package/dist/core/types.d.ts +224 -0
- package/dist/core/types.js +93 -0
- package/dist/react/auth/Login.d.ts +9 -0
- package/dist/react/auth/Login.js +8 -0
- package/dist/react/auth/hooks/use-login.hooks.d.ts +22 -0
- package/dist/react/auth/hooks/use-login.hooks.js +24 -0
- package/dist/react/errors.d.ts +10 -0
- package/dist/react/errors.js +13 -0
- package/dist/react/index.d.ts +18 -0
- package/dist/react/index.js +9 -0
- package/dist/react/members/Members.d.ts +6 -0
- package/dist/react/members/Members.js +38 -0
- package/dist/react/members/hooks/use-members.hooks.d.ts +32 -0
- package/dist/react/members/hooks/use-members.hooks.js +120 -0
- package/dist/react/members/rules.d.ts +26 -0
- package/dist/react/members/rules.js +35 -0
- package/dist/react/models.d.ts +50 -0
- package/dist/react/models.js +2 -0
- package/dist/react/ports.d.ts +157 -0
- package/dist/react/ports.js +2 -0
- package/dist/react/roles/Roles.d.ts +100 -0
- package/dist/react/roles/Roles.hooks.d.ts +17 -0
- package/dist/react/roles/Roles.hooks.js +40 -0
- package/dist/react/roles/Roles.js +150 -0
- package/dist/react/roles/hooks/use-roles.hooks.d.ts +80 -0
- package/dist/react/roles/hooks/use-roles.hooks.js +303 -0
- package/dist/react/roles/rules.d.ts +35 -0
- package/dist/react/roles/rules.js +31 -0
- package/dist/react/roles/text.d.ts +27 -0
- package/dist/react/roles/text.js +13 -0
- package/dist/react/testing.d.ts +51 -0
- package/dist/react/testing.js +275 -0
- package/dist/react/users/Users.d.ts +72 -0
- package/dist/react/users/Users.js +129 -0
- package/dist/react/users/hooks/use-reset-password-fields.hooks.d.ts +16 -0
- package/dist/react/users/hooks/use-reset-password-fields.hooks.js +21 -0
- package/dist/react/users/hooks/use-users.hooks.d.ts +77 -0
- package/dist/react/users/hooks/use-users.hooks.js +286 -0
- package/dist/react/users/rules.d.ts +33 -0
- package/dist/react/users/rules.js +61 -0
- package/dist/server/admin-crud-service.d.ts +295 -0
- package/dist/server/admin-crud-service.js +561 -0
- package/dist/server/agent-tool-input.d.ts +58 -0
- package/dist/server/agent-tool-input.js +158 -0
- package/dist/server/agent-tool-registrations.d.ts +51 -0
- package/dist/server/agent-tool-registrations.js +417 -0
- package/dist/server/agent-tools.d.ts +88 -0
- package/dist/server/agent-tools.js +229 -0
- package/dist/server/auth-service.d.ts +107 -0
- package/dist/server/auth-service.js +170 -0
- package/dist/server/authorize.d.ts +92 -0
- package/dist/server/authorize.js +96 -0
- package/dist/server/grant-service.d.ts +219 -0
- package/dist/server/grant-service.js +419 -0
- package/dist/server/hasher.d.ts +64 -0
- package/dist/server/hasher.js +53 -0
- package/dist/server/identity-transaction.d.ts +9 -0
- package/dist/server/identity-transaction.js +8 -0
- package/dist/server/index.d.ts +18 -0
- package/dist/server/index.js +20 -0
- package/dist/server/messages.d.ts +7 -0
- package/dist/server/messages.js +5 -0
- package/dist/server/password-policy.d.ts +59 -0
- package/dist/server/password-policy.js +66 -0
- package/dist/server/permission-migrations.d.ts +84 -0
- package/dist/server/permission-migrations.js +77 -0
- package/dist/server/repo.memory-transactions.d.ts +16 -0
- package/dist/server/repo.memory-transactions.js +79 -0
- package/dist/server/repo.memory.d.ts +186 -0
- package/dist/server/repo.memory.js +230 -0
- package/dist/server/seed.d.ts +56 -0
- package/dist/server/seed.js +435 -0
- package/dist/server/session-tokens.d.ts +10 -0
- package/dist/server/session-tokens.js +12 -0
- package/dist/server/username.d.ts +14 -0
- package/dist/server/username.js +14 -0
- package/package.json +144 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Notice } from '@jini-ai/ui-kit/react';
|
|
3
|
+
import { useMembersView } from '../hooks/MembersPage.hooks.js';
|
|
4
|
+
import { MemberRow } from '../components/MemberRow.js';
|
|
5
|
+
export default function MembersTab(_props = {}, _optional = {}) {
|
|
6
|
+
const v = useMembersView({});
|
|
7
|
+
return _jsx("section", { "aria-label": "Members", children: v.state.members?.length === 0 ? _jsx(Notice, { children: "No members yet. Registered members will show up here." }) : _jsxs("table", { children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { children: "Email" }), _jsx("th", { children: "Name" }), _jsx("th", { children: "Status" }), _jsx("th", { children: "Created" }), _jsx("th", { children: "Actions" })] }) }), _jsx("tbody", { children: v.state.members?.map(member => _jsx(MemberRow, { member: member }, member.id)) })] }) });
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=MembersTab.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Button, TextField, Notice } from '@jini-ai/ui-kit/react';
|
|
3
|
+
import { usePoliciesTab } from '../hooks/PoliciesTab.hooks.js';
|
|
4
|
+
import { PolicyRow } from '../components/PolicyRow.js';
|
|
5
|
+
export default function PoliciesTab(_props, _optional = {}) {
|
|
6
|
+
const v = usePoliciesTab({});
|
|
7
|
+
return _jsxs("section", { children: [_jsx("h2", { children: "Policies" }), v.canManage ? _jsxs("form", { onSubmit: v.submit, children: [v.error ? _jsx(Notice, { tone: "danger", children: v.error }) : null, _jsx(TextField, { label: "Policy name", value: v.name, onValueChange: v.changeName, required: true }), _jsx(TextField, { label: "Description (optional)", value: v.description, onValueChange: v.changeDescription }), _jsx(Button, { type: "submit", pending: v.saving, disabled: v.createDisabled, children: "Create policy" })] }) : null, v.rows.length ? _jsxs("table", { children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { children: "Name" }), _jsx("th", { children: "Description" }), _jsx("th", { children: "Type" }), _jsx("th", { children: "More" })] }) }), _jsx("tbody", { children: v.rows.map(policy => _jsx(PolicyRow, { policy: policy }, policy.id)) })] }) : _jsx("p", { children: "No policies yet." })] });
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=PoliciesTab.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Button, TextField, Notice } from '@jini-ai/ui-kit/react';
|
|
3
|
+
import { useRolesTab } from '../hooks/RolesTab.hooks.js';
|
|
4
|
+
import { RoleRow } from '../components/RoleRow.js';
|
|
5
|
+
export default function RolesTab(_props, _optional = {}) {
|
|
6
|
+
const v = useRolesTab({});
|
|
7
|
+
return _jsxs("section", { children: [_jsx("h2", { children: "Roles" }), v.canManage ? _jsxs("form", { onSubmit: v.submit, children: [v.error ? _jsx(Notice, { tone: "danger", children: v.error }) : null, _jsx(TextField, { label: "Role name", value: v.name, onValueChange: v.changeName, required: true }), _jsx(Button, { type: "submit", pending: v.saving, disabled: v.createDisabled, children: "Create role" })] }) : null, v.rows.length ? _jsxs("table", { children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { children: "Name" }), _jsx("th", { children: "Type" }), _jsx("th", { children: "More" })] }) }), _jsx("tbody", { children: v.rows.map(role => _jsx(RoleRow, { role: role }, role.id)) })] }) : _jsx("p", { children: "No roles yet." })] });
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=RolesTab.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Button, TextField, Notice } from '@jini-ai/ui-kit/react';
|
|
3
|
+
import { useUsersTab, newPasswordAttrs } from '../hooks/UsersTab.hooks.js';
|
|
4
|
+
import { UserRow } from '../components/UserRow.js';
|
|
5
|
+
export default function UsersTab(_props = {}, _optional = {}) {
|
|
6
|
+
const v = useUsersTab({});
|
|
7
|
+
return _jsxs("section", { "aria-label": "Users", children: [v.canCreate ? _jsx(Button, { onPress: v.toggleForm, children: "New user" }) : null, v.canCreate && v.s.formOpen ? _jsxs("form", { onSubmit: v.submit, children: [_jsx(TextField, { label: "Username", value: v.s.username, onValueChange: v.username, required: true }), _jsx(TextField, { label: "Email (optional)", type: "email", value: v.s.email, onValueChange: v.email }), _jsx(TextField, { label: "Password", type: "password", attrs: newPasswordAttrs, value: v.s.password, onValueChange: v.password, required: true }), v.s.formError ? _jsx(Notice, { tone: "danger", children: v.s.formError }) : null, _jsx(Button, { type: "submit", pending: v.s.saving, children: "Create user" }), _jsx(Button, { onPress: v.cancelForm, children: "Cancel" })] }) : null, v.s.users?.length === 0 ? _jsx(Notice, { children: "No users yet. Create your first operator account to get started." }) : _jsxs("table", { children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { children: "Username" }), _jsx("th", { children: "Email" }), _jsx("th", { children: "Status" }), _jsx("th", { children: "Roles" }), _jsx("th", { children: "Policies" }), _jsx("th", { children: "Actions" })] }) }), _jsx("tbody", { children: v.s.users?.map(user => _jsx(UserRow, { user: user }, user.principalId)) })] })] });
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=UsersTab.js.map
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { RolesApiPort } from './ports.js';
|
|
2
|
+
export declare const rolesApiToken: import("@jini-ai/admin/core/module").AdminPortToken<RolesApiPort, "jini.identity.rolesApi">;
|
|
3
|
+
/** Roles and policies show no cross-reference columns, so separating them loses no context.
|
|
4
|
+
* Policy permission editors can grow without pushing the roles list down the page.
|
|
5
|
+
* Counts add density without information: each list is one click away and fully visible.
|
|
6
|
+
* No new read grant is invented; the authenticated server owns read authorization. */
|
|
7
|
+
export declare const rolesModule: {
|
|
8
|
+
readonly id: "roles";
|
|
9
|
+
readonly requires: {
|
|
10
|
+
readonly rolesApi: import("@jini-ai/admin/core/module").AdminPortToken<RolesApiPort, "jini.identity.rolesApi">;
|
|
11
|
+
};
|
|
12
|
+
readonly provides: {};
|
|
13
|
+
readonly messages: Readonly<{
|
|
14
|
+
title: "Roles & Permissions";
|
|
15
|
+
roles: "Roles";
|
|
16
|
+
policies: "Policies";
|
|
17
|
+
people: "People";
|
|
18
|
+
description: "Define roles and policies here. Assign them to people in Users.";
|
|
19
|
+
loading: "Loading roles & permissions…";
|
|
20
|
+
readOnly: "Read-only: managing roles requires role.manage.";
|
|
21
|
+
forbidden: "You do not have permission to do that.";
|
|
22
|
+
conflict: "It is still in use — remove that assignment/attachment first.";
|
|
23
|
+
unknownPermission: "That permission is not recognized.";
|
|
24
|
+
exceedsIssuer: "You cannot grant a permission you do not hold.";
|
|
25
|
+
validation: "Please correct the highlighted fields.";
|
|
26
|
+
immutable: "Built-in roles and built-in or frozen policies cannot be changed.";
|
|
27
|
+
}>;
|
|
28
|
+
readonly pages: {
|
|
29
|
+
readonly roles: {
|
|
30
|
+
readonly path: "/roles";
|
|
31
|
+
readonly label: "Roles & Permissions";
|
|
32
|
+
readonly permissions: readonly [];
|
|
33
|
+
readonly nav: {
|
|
34
|
+
readonly group: "people";
|
|
35
|
+
readonly icon: "users";
|
|
36
|
+
};
|
|
37
|
+
readonly tabs: {
|
|
38
|
+
readonly roles: {
|
|
39
|
+
readonly label: "Roles";
|
|
40
|
+
};
|
|
41
|
+
readonly policies: {
|
|
42
|
+
readonly label: "Policies";
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=roles.module.d.ts.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { adminPort, defineAdminModule } from '@jini-ai/admin/core/module';
|
|
2
|
+
import { rolesMessagesEn } from './messages.en.js';
|
|
3
|
+
export const rolesApiToken = adminPort({ id: 'jini.identity.rolesApi' });
|
|
4
|
+
/** Roles and policies show no cross-reference columns, so separating them loses no context.
|
|
5
|
+
* Policy permission editors can grow without pushing the roles list down the page.
|
|
6
|
+
* Counts add density without information: each list is one click away and fully visible.
|
|
7
|
+
* No new read grant is invented; the authenticated server owns read authorization. */
|
|
8
|
+
export const rolesModule = defineAdminModule({
|
|
9
|
+
id: 'roles', requires: { rolesApi: rolesApiToken }, provides: {}, messages: rolesMessagesEn,
|
|
10
|
+
pages: { roles: {
|
|
11
|
+
path: '/roles', label: rolesMessagesEn.title, permissions: [], nav: { group: 'people', icon: 'users' },
|
|
12
|
+
tabs: { roles: { label: rolesMessagesEn.roles }, policies: { label: rolesMessagesEn.policies } },
|
|
13
|
+
} },
|
|
14
|
+
});
|
|
15
|
+
//# sourceMappingURL=roles.module.js.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { RoleRecord, PolicyRecord, DestructiveTarget } from './models.js';
|
|
2
|
+
/** All writes share the actual server vocabulary. A missing grant is a denial. */
|
|
3
|
+
export declare function canManageRoles({ permissions }: {
|
|
4
|
+
permissions: readonly string[];
|
|
5
|
+
}, _optional?: Record<string, never>): boolean;
|
|
6
|
+
export declare function mutableRole({ role }: {
|
|
7
|
+
role: RoleRecord;
|
|
8
|
+
}, _optional?: Record<string, never>): boolean;
|
|
9
|
+
export declare function mutablePolicy({ policy }: {
|
|
10
|
+
policy: PolicyRecord;
|
|
11
|
+
}, _optional?: Record<string, never>): boolean;
|
|
12
|
+
/** Conflict copy is feature-specific: references, rather than duplicate workspace slugs. */
|
|
13
|
+
export declare function describeRolesError({ error, fallback }: {
|
|
14
|
+
error: unknown;
|
|
15
|
+
fallback: string;
|
|
16
|
+
}, _optional?: Record<string, never>): string;
|
|
17
|
+
export declare function destructiveCopy({ target }: {
|
|
18
|
+
target: DestructiveTarget | null;
|
|
19
|
+
}, _optional?: Record<string, never>): {
|
|
20
|
+
title: string;
|
|
21
|
+
label: string;
|
|
22
|
+
tone: "warning";
|
|
23
|
+
body: string;
|
|
24
|
+
consequence: string;
|
|
25
|
+
} | {
|
|
26
|
+
title: string;
|
|
27
|
+
label: string;
|
|
28
|
+
tone: "danger";
|
|
29
|
+
body: string;
|
|
30
|
+
consequence: string;
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=rules.d.ts.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { rolesMessagesEn as m } from './messages.en.js';
|
|
2
|
+
/** All writes share the actual server vocabulary. A missing grant is a denial. */
|
|
3
|
+
export function canManageRoles({ permissions }, _optional = {}) {
|
|
4
|
+
return permissions.includes('role.manage') || permissions.includes('*');
|
|
5
|
+
}
|
|
6
|
+
export function mutableRole({ role }, _optional = {}) { return !role.isBuiltin; }
|
|
7
|
+
export function mutablePolicy({ policy }, _optional = {}) { return !policy.isBuiltin && !policy.isFrozen; }
|
|
8
|
+
/** Conflict copy is feature-specific: references, rather than duplicate workspace slugs. */
|
|
9
|
+
export function describeRolesError({ error, fallback }, _optional = {}) {
|
|
10
|
+
const messages = {
|
|
11
|
+
FORBIDDEN: m.forbidden, RESOURCE_CONFLICT: m.conflict, PERMISSION_UNKNOWN: m.unknownPermission,
|
|
12
|
+
GRANT_EXCEEDS_ISSUER: m.exceedsIssuer,
|
|
13
|
+
};
|
|
14
|
+
if (error && typeof error === 'object' && 'code' in error && typeof error.code === 'string') {
|
|
15
|
+
if (error.code === 'VALIDATION_ERROR')
|
|
16
|
+
return error instanceof Error && error.message ? error.message : m.validation;
|
|
17
|
+
if (messages[error.code])
|
|
18
|
+
return messages[error.code];
|
|
19
|
+
}
|
|
20
|
+
return error instanceof Error && error.message ? error.message : fallback;
|
|
21
|
+
}
|
|
22
|
+
export function destructiveCopy({ target }, _optional = {}) {
|
|
23
|
+
if (target?.kind === 'permission')
|
|
24
|
+
return { title: 'Remove permission?', label: 'Remove', tone: 'warning',
|
|
25
|
+
body: `Remove "${target.row.permission}"${target.row.resourceType ? ` (${target.row.resourceType})` : ''} from this policy? This changes live access immediately.`, consequence: 'changes live access immediately' };
|
|
26
|
+
if (target?.kind === 'policy')
|
|
27
|
+
return { title: 'Delete policy?', label: 'Delete', tone: 'danger',
|
|
28
|
+
body: `Delete "${target.policy.name}"? Policies still attached to users or roles cannot be deleted.`, consequence: 'cannot be undone' };
|
|
29
|
+
return { title: 'Delete role?', label: 'Delete', tone: 'danger',
|
|
30
|
+
body: target?.kind === 'role' ? `Delete "${target.role.name}"? Roles still assigned to users cannot be deleted.` : '', consequence: 'cannot be undone' };
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=rules.js.map
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { UsersApiPort, UsersSafetyPort } from './ports.js';
|
|
2
|
+
export declare const usersApiToken: import("@jini-ai/admin/core/module").AdminPortToken<UsersApiPort, "jini.identity.usersApi">;
|
|
3
|
+
export declare const usersSafetyToken: import("@jini-ai/admin/core/module").AdminPortToken<UsersSafetyPort, "jini.identity.usersSafety">;
|
|
4
|
+
/** Reads remain server-authorized; grants gate mutation affordances, denied by default.
|
|
5
|
+
* Login is mounted by the signed-out host, before the authenticated shell. */
|
|
6
|
+
export declare const usersModule: {
|
|
7
|
+
readonly id: "users";
|
|
8
|
+
readonly requires: {
|
|
9
|
+
readonly usersApi: import("@jini-ai/admin/core/module").AdminPortToken<UsersApiPort, "jini.identity.usersApi">;
|
|
10
|
+
readonly usersSafety: import("@jini-ai/admin/core/module").AdminPortToken<UsersSafetyPort, "jini.identity.usersSafety">;
|
|
11
|
+
};
|
|
12
|
+
readonly provides: {};
|
|
13
|
+
readonly messages: {
|
|
14
|
+
readonly title: "Users";
|
|
15
|
+
readonly description: "Operator accounts with access to this admin — assign roles and policies, or disable access.";
|
|
16
|
+
readonly loading: "Loading users…";
|
|
17
|
+
readonly readOnly: "Read-only — user administration is unavailable with your current grants.";
|
|
18
|
+
readonly passwordHelp: "No 'forgot password' email yet. If someone is locked out, the owner can reset their password here.";
|
|
19
|
+
readonly protected: "Only an owner can modify an owner. Unresolved owner status prevents changes.";
|
|
20
|
+
readonly forbidden: "You do not have permission to do that.";
|
|
21
|
+
};
|
|
22
|
+
readonly pages: {
|
|
23
|
+
readonly users: {
|
|
24
|
+
readonly path: "/users";
|
|
25
|
+
readonly label: "Users";
|
|
26
|
+
readonly permissions: readonly [];
|
|
27
|
+
readonly nav: {
|
|
28
|
+
readonly group: "people";
|
|
29
|
+
readonly icon: "users";
|
|
30
|
+
};
|
|
31
|
+
readonly tabs: {
|
|
32
|
+
readonly users: {
|
|
33
|
+
readonly label: "Users";
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=users.module.d.ts.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { adminPort, defineAdminModule } from '@jini-ai/admin/core/module';
|
|
2
|
+
import { usersMessagesEn } from './messages.en.js';
|
|
3
|
+
export const usersApiToken = adminPort({ id: 'jini.identity.usersApi' });
|
|
4
|
+
export const usersSafetyToken = adminPort({ id: 'jini.identity.usersSafety' });
|
|
5
|
+
/** Reads remain server-authorized; grants gate mutation affordances, denied by default.
|
|
6
|
+
* Login is mounted by the signed-out host, before the authenticated shell. */
|
|
7
|
+
export const usersModule = defineAdminModule({
|
|
8
|
+
id: 'users', requires: { usersApi: usersApiToken, usersSafety: usersSafetyToken }, provides: {}, messages: usersMessagesEn,
|
|
9
|
+
pages: { users: { path: '/users', label: 'Users', permissions: [],
|
|
10
|
+
nav: { group: 'people', icon: 'users' },
|
|
11
|
+
tabs: { users: { label: 'Users' } },
|
|
12
|
+
} },
|
|
13
|
+
});
|
|
14
|
+
//# sourceMappingURL=users.module.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Built-in permission vocabulary and migration metadata, preserved as data. */
|
|
2
|
+
import type { PermissionDescriptor } from './permissions.js';
|
|
3
|
+
export interface PermissionMigration {
|
|
4
|
+
readonly from: string;
|
|
5
|
+
readonly to: readonly string[];
|
|
6
|
+
readonly reason: string;
|
|
7
|
+
}
|
|
8
|
+
export declare const BUILTIN_PERMISSIONS: readonly PermissionDescriptor[];
|
|
9
|
+
export declare const BUILTIN_PERMISSION_MIGRATIONS: readonly PermissionMigration[];
|
|
10
|
+
//# sourceMappingURL=builtin-permissions.d.ts.map
|