Commit Graph

19 Commits

Author SHA1 Message Date
Jakub Zych
43fabfa6c3 fix: a group filter value that is not a group id lists nobody (D-23)
User.FilterScope handed the filter value to the database as it came. A
value such as abc failed the query, so the Users list answered 500.

- groupFilterID reads a positive whole number, as a number or its text
- any other value narrows the list to nothing
- TestAdminUsersGroupFilterValue fails with a 500 without the change
2026-10-05 15:15:28 +02:00
Jakub Zych
58595fef27 feat: Organisations admin screen with the avatar and the members manager
- controller golem15.user.organisations behind golem15.users.access_users
- list and form (name, slug preset from the name, description, avatar)
- members relation manager: link sets and unlink clears users.organisation_id
- deleting an organisation releases its members first
- Organisation gains Fillable, Rules, MorphName, AttachRelations, BeforeValidate
  and the Members relation; models.Slugify
- navigation side item organisations
- TestAdminOrganisations, TestAdminOrganisationMembers, TestSlugify
2026-10-05 13:58:54 +02:00
Jakub Zych
a3992879db feat: User Groups admin screen with the users count and privileged codes protected
- controller golem15.user.usergroups behind golem15.users.access_groups
- list with users_count from the list's own query; form with the checkbox
  permission editor stored in user_groups.permissions
- creating a group with a privileged code, changing a code to or from one and
  deleting a privileged group need golem15.users.manage_privileged_groups
- a group delete removes its users_groups rows in the same transaction
- UserGroup gains Fillable, Rules and the read-only UsersCount; PermissionSet.Text
- TestAdminGroups and the D-06 matrix in TestAdminPrivilegedGroups
2026-10-05 13:52:26 +02:00
Jakub Zych
9611708792 feat: manage a user's groups from the user form, privileged groups locked
- groups relation field on the user form, the only writer of users_groups
- UsersGroup pivot model
- AdminRelationLocks: adding or removing a group whose code is in
  golem15.user.privileged_groups needs golem15.users.manage_privileged_groups,
  on create and on update; refused saves answer 403 and write nothing
- TestAdminUserGroupsField and TestAdminPrivilegedGroups
2026-10-05 13:44:15 +02:00
Jakub Zych
f7ca3c4f59 feat: create users with a password and an invitation in the admin
- password with confirmation on create, optional reset on update that
  ends the user's sessions; the hash is never returned
- send_invite sends one invitation with an activation link after the
  create commits
- organisation picker, avatar upload shared with the user API and the
  frontend permission editor on the user form
- an email held by a deactivated user answers 422 instead of failing
  on the unique constraint
- the privileged-member guard now also refuses a submitted password
2026-10-05 13:21:51 +02:00
Jakub Zych
cdea47a178 feat: frontend permissions and the merged-permission resolver
- PermissionSet reads the stored JSON tolerantly and writes an object
  of integers; FrontendPermission is the catalogue row
- MergedPermissions, HasPermission and UserHasPermission port PHP
  getMergedPermissions and Winter's hasPermission: groups merge with
  most positive wins, the user's own values override, held means
  exactly 1, wildcards as in Winter
- User gains Permissions (never serialized) and declares the avatar
  attachment relation the user API already writes
2026-10-05 13:21:51 +02:00
Jakub Zych
970eba7734 feat: user preview, bulk and record actions and the permanent delete
- the list opens the preview, which shows one status hint (banned,
  deactivated, not activated, suspended) and the IP address fields
- bulk actions activate, deactivate, restore, ban and unban; record
  actions activate, unban and unsuspend, offered while they apply
- delete (form button and bulk) removes the user for good with the
  throttle rows, group memberships and attachments in one transaction;
  blobs go after the commit
- a privileged-group member is still refused, a bulk delete as a whole
2026-10-05 13:10:12 +02:00
Jakub Zych
f3f33b809a style: gofmt the user model and the session test 2026-10-05 13:02:23 +02:00
Jakub Zych
b410a7fea9 feat: register the Users admin screen with the privileged-member guard
- permissions (the four Winter codes and manage_privileged_groups),
  the user navigation item and the embedded admin YAML
- Users controller: list with deactivated users, row states, the
  groups, created date and activated filters, and the form's name,
  surname and email
- a member of a group in golem15.user.privileged_groups (default
  admin) keeps their email, password and row unless the administrator
  holds golem15.users.manage_privileged_groups; the refusal is a 403
  that saves nothing
2026-10-05 13:01:48 +02:00
Jakub Zych
e22f7660f3 feat: add the admin columns and the frontend permissions table
- users.permissions and users.last_seen as additive columns
- golem15_user_frontend_permissions (code, label, tab, comment)
- User gains LastSeen, read-only CreatedAt and UpdatedAt and the
  filterByGroup list scope; none of them is serialized
- migration tests roll back by position past the three new steps
2026-10-05 12:51:41 +02:00
Jakub Zych
0fe5b91b63 feat: own shared user API tokens 2026-10-04 22:30:20 +02:00
Jakub Zych
86970074b7 feat: add Winter user groups
- user_groups (seeded with the guest and registered groups) and the
  users_groups pivot, folded from the PHP v1.1.1 and v2.8.0 migrations
  into migration 202610020001_create_user_groups
- models.UserGroup and a User.Groups relation that is never serialized
- classes.UserGroupCodes and classes.HasGroupCode for server-side checks
  such as the site-admin group code admin
- additive only: no route, payload or existing column changes; the user
  payload still answers "groups":[]
2026-10-02 11:44:01 +02:00
Jakub Zych
d94634d5d8 feat(07-07): replay the 15 user-api routes and both nuxt auth flows
Match PHP payloads, already-activated Winter 500 HTML, and direct-DB
seeding so the corpus can flip those routes to ported without onboarding.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-22 23:57:00 +02:00
Jakub Zych
63d6d049b7 feat(07-03): add avatars, mail templates, and password-change command
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-22 16:43:44 +02:00
Jakub Zych
00e6c51abd feat(07-02): throttle failed logins and pick mail template locale
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-22 14:03:31 +02:00
Jakub Zych
1311bd6cad feat(07-02): add user session schema, throttle table, and jwt config
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-22 13:53:16 +02:00
Jakub Zych
feb09823bf fix(05): CR-03 hide User password and require secret columns in Hidden() 2026-09-18 23:45:55 +02:00
Jakub Zych
8d1248c328 feat(05-03): add user-plugin organisations table (structure only)
- create_organisations folds PHP v3.2.0; no users-table ALTER this phase
- Organisation model is an FK target; app.key placeholder in config
2026-09-18 19:37:41 +02:00
Jakub Zych
2d4245681e feat(05-01): restructure fonoteka plugins into Winter directories
- Move models, classes, controllers, middleware, and updates into subpackages
- Add self-registering models/updates/classes registries so later plans add files
- Keep the genres route and shipped migration SQL unchanged
2026-09-18 18:43:31 +02:00