Before you upgrade1
- 1
Security: an anonymous create, update or delete now needs an access rule that allows it #2751
This applies to a checked write with no signed-in caller: the Direct API with
overrideAccess: falseand nouser, or a plugin service call made{ as: "public" }, as apublic: trueplugin route makes one. On a collection or Single whoseaccessnamed no rule for that write, it used to be allowed; it is now refused. If a collection takes writes from visitors on purpose, such as a contact form, say so with a rule, for exampleaccess: { create: () => true }, and add areadrule if visitors must not read the entries back, because reads keep the public default. The form builder's submissions already declarecreate: true. The admin's REST API is unchanged.
Correction
0.0.2-alpha.69's notes said creating a user with roles and deleting a role "no longer deadlock". On MySQL they still could, and one of them failed with a retryable 409. This release fixes that (#2734).
Notes that belong to 0.0.2-alpha.69
These two changes shipped in 0.0.2-alpha.69's code; their changelog entries appear in this release:
- A code access rule allows only by returning
true(#2679). 0.0.2-alpha.69's "Before you upgrade" already described it (item 30). - Refusals that aren't about permission say why (#2728). The admin's schema routes now answer a thing defined in code with 403
FORBIDDENand a sentence, where they answered 500.
What's changed8
Released 21 packages at 0.0.2-alpha.70 in lockstep. Every package below ships at this version.
Patch Changes
- Two refusals that aren't about permission now say why, and stay 403
FORBIDDEN.More
A change or delete of a collection, Single or component defined in code, made from anywhere but its code, reads "This collection is defined in code, so it can't be changed here." (or "deleted", or "Single", or "component"). An autosave where the collection or Single doesn't autosave reads "Autosave is turned off for this collection." (or "this Single"). Both used to read "You don't have permission to perform this action.", which sent people looking for a permission that wouldn't help.
One status changes. The admin's schema routes checked the lock themselves and answered a thing defined in code with a 500 internal error: changing a Single's schema, previewing or applying a schema change to a collection, Single or component, and deleting a Single. They now answer 403 with the same sentence.
Refusals for want of permission are unchanged: they never say which check refused.
- Creating a user with roles takes the super-admin lock before it writes the account, the same order as every other change to who is a super-admin.
More
Run at the same moment as such a change, a role deletion for instance, it could otherwise deadlock on MySQL and fail with a retryable
409. - Security: an anonymous create, update or delete now needs a rule that allows it. A checked write with no signed-in caller (the Direct API with
overrideAccess: falseand nouser, or a plugin service call made{ as: "public" }, as apublic: trueroute makes one) used to be allowed on a collection or Single whoseaccessnamed no rule for that write.More
It is now refused. Reads keep the public default, publishing still needs a signed-in user, and the admin's REST API is unchanged.
If you take anonymous writes on purpose, say so in the collection's
access, for example a public form-like collection:access: { create: () => true }. The form builder's submissions already declarecreate: trueand keep working.A plugin's
deleteEntryInTransactionmade{ as: "system" }is now trusted, as its other{ as: "system" }writes are; it was judged as an anonymous caller. - Core's built-in emails (welcome, password reset, email verification) and the default layout's footer now meet WCAG AA contrast: the small print under each button is darker on the card, and the footer line and links paragraph are darker on the page.
More
Installs that never edited these templates get the new colours on their next boot; an edited template keeps its own.
- A code access rule now allows only by returning
true.More
A rule that returns
null,undefined, a string or any other value refuses, asfalsedoes, for every caller and at every way in. Before, a visitor was refused only byfalse, sonullandundefinedlet one through, and a signed-in user was let in by any truthy value. Returntrueto allow.ctx.caller.canin a plugin route andnextly.access.checknow return a boolean. Before, a rule's own answer could come back as it was,nullor a string included.For this release, each request refused this way that a rule allowed before is logged once, naming the collection or Single, the action and the kind of caller, so a rule that relied on the old reading can be found and changed.
- A route handler's error now answers as that error on a host whose function bundle lacks part of
next/navigation.More
Nextly loads Next's
unstable_rethrowlazily, which file tracing cannot follow, and on such a bundle (seen on Vercel with Next 16.4.3) loading it failed for every error a handler caught: a signed-out caller's 401, for one, became a 500, so the admin stopped working for anyone signed out. Where it cannot be loaded, Nextly now makes the same check from the errors' digests, soredirect()andnotFound()still pass through and every other error gets its own response. - nextly's route handler, boot and role and user services no longer load the service registry or every core service just by being imported.
More
They load them when they first register or build services, so a module that needs one service loads far fewer. The services barrel no longer re-exports the dispatcher; the root
nextlyentry exports the same names as before. - Asking nextly's DI container for a service no longer loads every service registration.
More
getServiceandisServicesRegisteredread the container without importing the registry, so code that only looks services up loads far fewer modules. The rootnextlyentry exports the same names as before.
Packages
@nextlyhq/adapter-drizzle@nextlyhq/adapter-mysql@nextlyhq/adapter-postgres@nextlyhq/adapter-sqlite@nextlyhq/admin@nextlyhq/admin-css@nextlyhq/blocks-engine@nextlyhq/blocks-react@nextlyhq/builder@nextlyhq/eslint-plugin@nextlyhq/plugin-form-builder@nextlyhq/plugin-mcp@nextlyhq/plugin-page-builder@nextlyhq/plugin-sdk@nextlyhq/plugin-seo@nextlyhq/storage-s3@nextlyhq/storage-uploadthing@nextlyhq/storage-vercel-blob@nextlyhq/uicreate-nextly-appnextly
Earlier releases
Releases before 0.0.2-alpha.66 are listed in Nextly's changelog on GitHub.