feat(cabana): add the My account page with subtitle and password change
- lagoon: 202610090001_backend_users_metadata adds WinterCMS's nullable jsonable backend_users.metadata column (TEXT); rollback drops only it - cabana.BackendUser.Metadata and Subtitle read metadata.subtitle leniently (NULL, blank, null, [], invalid JSON and non-strings read as empty) - GET /auth/me returns subtitle; PUT /account edits the signed-in admin's own names, email and subtitle, and the password with current_password; any other key is a 422 and nothing is written - email: required, valid, 6-255 chars, unique against other admins' email and login ignoring case (soft-deleted included); a unique-index race is 422 - a password change sets tokens_valid_after, revokes the presented token and gives a cookie session a fresh cookie - swag annotation, regenerated admin.json and schema.d.ts; route inventories, CSRF walk (27) and OpenAPI conformance learn the route - SPA: My account item in the user menu opens /account (AccountView), which saves through PUT /account and updates the top bar via setCurrentUser - backend::lang.myaccount strings (en, pl), rebuilt boardwalk dist - cabana and lagoon READMEs, users-and-permissions and admin-spa docs
This commit is contained in:
@@ -15,6 +15,9 @@ export function pageIndicator(route: RouteLocationNormalizedLoaded): string {
|
||||
if (route.name === 'settings') {
|
||||
return t('backend::lang.settings.title')
|
||||
}
|
||||
if (route.name === 'account') {
|
||||
return t('backend::lang.myaccount.menu_label')
|
||||
}
|
||||
if (route.name === 'settings-form') {
|
||||
return settingsEntry(String(route.params.code ?? ''))?.label ?? String(route.params.code ?? '')
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import FormView from '../views/FormView.vue'
|
||||
import PreviewView from '../views/PreviewView.vue'
|
||||
import SettingsFormView from '../views/SettingsFormView.vue'
|
||||
import SettingsIndexView from '../views/SettingsIndexView.vue'
|
||||
import AccountView from '../views/AccountView.vue'
|
||||
import NotFoundView from '../views/NotFoundView.vue'
|
||||
|
||||
declare module 'vue-router' {
|
||||
@@ -67,6 +68,8 @@ export function createAdminRouter(history: RouterHistory = createWebHistory(runt
|
||||
},
|
||||
{ path: '/settings', name: 'settings', component: SettingsIndexView, meta: { shell: true } },
|
||||
{ path: '/settings/:code', name: 'settings-form', component: SettingsFormView, meta: { shell: true } },
|
||||
// My account: the signed-in admin's own profile and password.
|
||||
{ path: '/account', name: 'account', component: AccountView, meta: { shell: true } },
|
||||
{ path: '/:vendor/:plugin/:controller', name: 'list', component: ListView, meta: { shell: true } },
|
||||
{ path: '/:vendor/:plugin/:controller/create', name: 'create', component: FormView, meta: { shell: true } },
|
||||
{ path: '/:vendor/:plugin/:controller/:id(\\d+)', name: 'record', component: FormView, meta: { shell: true } },
|
||||
|
||||
Reference in New Issue
Block a user