# Unchained Engine v5.0 (Breaking Changes) ## Major Breaking Changes ### Plugin System Modernization - **REMOVED**: All legacy adapter exports from plugin files. Use new `*Plugin` exports instead: - `Invoice` → `InvoicePlugin` - `InvoicePrepaid` → `InvoicePrepaidPlugin` - `Datatrans` → `DatatransPlugin` - `Stripe` → `StripePlugin` - `Post` → `PostPlugin` - `SendMessage` → `SendMessagePlugin` - `PickUp` → `PickMupPlugin` - `GridFS` → `GridFSPlugin` - `Store` → `StorePlugin` - **REMOVED**: `Director.registerAdapter()` method from all 14 Directors. Use preset registration functions (`registerBasePlugins()`, `registerAllPlugins()`) or `pluginRegistry.register()` instead. - **REMOVED**: Default exports from `@unchainedshop/plugins/presets/base.js` and `all.js`. Import named registration functions instead. - **REMOVED**: `PluginRegistry.registerAdapters()` method (was deprecated and non-functional). ### GraphQL API Changes - **REMOVED**: Deprecated mutations (replaced by cart-based mutations in v4): - `setOrderDeliveryProvider` → use `updateCart` - `setOrderPaymentProvider` → use `updateCart` - `updateOrderDeliveryShipping` → use `updateCartDeliveryShipping` - `updateOrderDeliveryPickUp` → use `updateCartDeliveryPickUp` - `updateOrderPaymentInvoice` → use `updateCartPaymentInvoice` - `updateOrderPaymentGeneric` → use `updateCartPaymentGeneric` - **REMOVED**: `OrderDeliveryPickUp.pickUpLocations` field. Use `DeliveryProviderPickUp.pickUpLocations` instead. - **REMOVED**: Router export aliases: - `expressRouter` → use `adminUIRouter` from `@unchainedshop/api/express` - `fastifyRouter` → use `adminUIRouter` from `@unchainedshop/api/fastify` ### Authentication (Stateless JWT) - **CHANGED**: Authentication moved from stateful Express/Passport sessions to stateless JWTs (HS256, signed/verified with `jose`). Server-side session storage — `express-session`, `@fastify/session`, `passport`, and the bundled MongoDB session store — has been removed. **All existing sessions are invalidated on upgrade; clients must re-authenticate.** - **REMOVED**: `express-session`, `@fastify/session`, `passport`, and `jsonwebtoken` dependencies. `cookie-parser` is now a required peer dependency. The `sessions` collection is no longer used. - **NEW (required)**: `UNCHAINED_TOKEN_SECRET` must be set and be at least 32 characters (256 bits) or token signing/verification throws. Optional `UNCHAINED_TOKEN_EXPIRY_SECONDS` (default `3600`, previously effectively 7 days) and `UNCHAINED_TOKEN_ISSUER` (default `unchained-engine`). - **CHANGED**: Token revocation is stateless via a `User.tokenVersion` counter — incrementing it invalidates every outstanding token for that user. `modules.users.markDeleted` now bumps `tokenVersion` instead of deleting session rows. - **CHANGED**: Default cookie `SameSite` changed from `none` to `lax` (CSRF hardening). Set `UNCHAINED_COOKIE_SAMESITE=none` if you rely on cross-site/embedded auth flows. - **CHANGED**: `signAccessToken()` and `verifyLocalToken()` are now async. - **CHANGED**: `Mutation.logoutAllSessions` return type changed from `LogoutAllSessionsResponse!` to `SuccessResponse` (no longer exposes `tokenVersion`). - **CHANGED**: `changePassword` is no longer self-permitted by the default ACL — review custom roles if you relied on this. ### Roles - **CHANGED**: The global `Roles` singleton is replaced by a `createRoles()` factory that returns an isolated instance (removes shared global state across server instances). The `Role` constructor no longer auto-registers into a global registry and no longer throws on duplicate names; register explicitly via `addRole()` / `configureRoles()`. Default `admin` / `__loggedIn__` / `__all__` roles are no longer created at module import. `UnchainedServerOptions.roles` and `Context.roles` are now typed `RolesInterface` (was `any`). ### Admin UI - **CHANGED**: Permissions moved from a build-time generated artifact (`generate-permissions.js`, `window.AdminUiPermissions`) to a typed runtime model in `src/modules/Auth/permissionConfig.ts`. The build no longer runs `generate-permissions.js` or emits `public/admin-ui-permissions.js`. - **CHANGED**: Access control is now **deny-by-default** — routes absent from `ROUTE_ROLES` are denied. Custom pages must be added to `ROUTE_ROLES` or `UNRESTRICTED_PAGES`. Dashboard widgets, mutating controls, and form fields gate on `hasRole()` / `isAdmin()`, and data hooks skip GraphQL queries the user is not authorized for. - **CHANGED**: 54 UI primitives consolidated into a canonical `src/components/ui/` kit (with `@/components/ui` and `@/components/ui/form` barrels). Importing them from the old `**/common/components/*` / `**/forms/components/*` paths is now an ESLint error. `DeleteButton`, `HeaderDeleteButton`, and `EditIcon` were removed (use `