docs(quick-261015-w7f): docs since v0.1.14 and the Upgrading to 0.2 notes
- new setup/upgrading.md: version rule, the two 0.2 boot refusals with their fixes, behaviour changes, and what 0.2 adds since 0.1 - architecture module table lists all 28 modules - WinterCMS map: cache and reorder are provided; rows for field types, sanitizing, singletons, API tokens, CORS, Turnstile, menu item types - configuration keys for CORS profiles, api_docs, auth.cookie, turnstile - index, setup intro and frontend page link the new topics
This commit is contained in:
@@ -24,12 +24,12 @@ Each framework module is one Go package under `modules/`, documented by its READ
|
||||
|
||||
| Concern | Modules |
|
||||
|---------|---------|
|
||||
| Plugins and the container | [party](../../modules/party/README.md), [pact](../../modules/pact/README.md), [backpack](../../modules/backpack/README.md), [festival](../../modules/festival/README.md), [compass](../../modules/compass/README.md) |
|
||||
| Plugins and the container | [party](../../modules/party/README.md), [pact](../../modules/pact/README.md), [backpack](../../modules/backpack/README.md), [festival](../../modules/festival/README.md), [compass](../../modules/compass/README.md), [signpost](../../modules/signpost/README.md) |
|
||||
| HTTP | [surf](../../modules/surf/README.md), [towel](../../modules/towel/README.md), [wire](../../modules/wire/README.md), [bouncer](../../modules/bouncer/README.md), [wristband](../../modules/wristband/README.md), [fetchguard](../../modules/fetchguard/README.md) |
|
||||
| Data | [lagoon](../../modules/lagoon/README.md), [beachcomber](../../modules/beachcomber/README.md) |
|
||||
| Admin | [cabana](../../modules/cabana/README.md), [boardwalk](../../modules/boardwalk/README.md) |
|
||||
| Services | [phrasebook](../../modules/phrasebook/README.md), [postcard](../../modules/postcard/README.md), [conga](../../modules/conga/README.md), [lighthouse](../../modules/lighthouse/README.md), [flare](../../modules/flare/README.md), [sunscreen](../../modules/sunscreen/README.md) |
|
||||
| Console and tooling | [bonfire](../../modules/bonfire/README.md), [tide](../../modules/tide/README.md) |
|
||||
| Admin | [cabana](../../modules/cabana/README.md), [boardwalk](../../modules/boardwalk/README.md), [seaglass](../../modules/seaglass/README.md) |
|
||||
| Services | [cooler](../../modules/cooler/README.md), [phrasebook](../../modules/phrasebook/README.md), [postcard](../../modules/postcard/README.md), [conga](../../modules/conga/README.md), [lighthouse](../../modules/lighthouse/README.md), [flare](../../modules/flare/README.md), [sunscreen](../../modules/sunscreen/README.md) |
|
||||
| Console and tooling | [bonfire](../../modules/bonfire/README.md), [tide](../../modules/tide/README.md), [sunrise](../../modules/sunrise/README.md) |
|
||||
| Utilities | [sieve](../../modules/sieve/README.md) |
|
||||
|
||||
## What runs where
|
||||
|
||||
@@ -12,10 +12,10 @@ Start with [Installation](setup/installation.md) to set up the toolchain and the
|
||||
|
||||
## Where to start
|
||||
|
||||
- [Setup](setup/introduction.md): what SummerCMS is, installation, configuration, the move from WinterCMS and a [plugin porting walkthrough](setup/porting-a-plugin.md).
|
||||
- [Setup](setup/introduction.md): what SummerCMS is, installation, configuration, the move from WinterCMS, a [plugin porting walkthrough](setup/porting-a-plugin.md) and [Upgrading](setup/upgrading.md) to a newer release, with what to check before 0.2.
|
||||
- [Architecture](architecture/introduction.md): the single binary, Go modules, the application lifecycle, the request lifecycle and [performance and scaling](architecture/performance-and-scaling.md) compared with PHP-FPM.
|
||||
- [Plugins](plugins/registration.md): registering a plugin, scheduling, extending other plugins and testing.
|
||||
- [Backend](backend/admin-controllers.md): admin controllers, forms, lists, relations, users, settings and the admin SPA.
|
||||
- [Plugins](plugins/registration.md): registering a plugin, scheduling, extending other plugins, [menu item types](plugins/menu-item-types.md) and testing.
|
||||
- [Backend](backend/admin-controllers.md): admin controllers, forms, lists, relations, [plugin field types](backend/field-types.md), users and [API tokens](backend/users-and-permissions.md#api-tokens), settings and the admin SPA.
|
||||
- [Database](database/models.md): models, migrations, queries, relations, casts, attachments and transactions.
|
||||
- [Services](services/configuration.md): configuration, events, routing, authentication, mail, jobs, realtime, search and the other services, plus what SummerCMS does not provide for the frontend.
|
||||
- [Services](services/configuration.md): configuration, events, routing, authentication, [caching](services/caching.md), mail, jobs, realtime, search and the other services, plus what SummerCMS does not provide for the frontend.
|
||||
- [Console](console/introduction.md): the `summer` tool, the application binary's commands and writing your own.
|
||||
|
||||
@@ -27,9 +27,12 @@ A WinterCMS plugin that shipped components and AJAX handlers is ported as routes
|
||||
Build the frontend with any framework that can call a JSON API, as its own project with its own build and deployment:
|
||||
|
||||
- **Data:** call the plugins' JSON routes. [Routing](routing.md) shows how routes, auth groups and JSON responses are declared, and [Queries and pagination](../database/queries-and-pagination.md) the list envelope.
|
||||
- **Signing in:** the user plugin issues JWTs; send them as a bearer token or in the cookie the guard reads. See [Authentication](authentication.md).
|
||||
- **Signing in:** the user plugin issues JWTs; send them as a bearer token or in the cookie the guard reads. A browser frontend can keep the token in an httpOnly cookie that the API sets, with `bouncer.CookieRefreshHandler` and `bouncer.CookieLogoutHandler` as its refresh and logout endpoints. See [Authentication](authentication.md) and [Cookie transport](authentication.md#cookie-transport).
|
||||
- **Live updates:** instead of polling an AJAX handler, subscribe to realtime channels. The frontend connects to Centrifugo with a token from the token route and receives model broadcasts and explicit events. See [Realtime](realtime.md).
|
||||
- **Cross-origin calls:** when the frontend runs on another origin, allow it in `http.cors`, as [Routing](routing.md) describes.
|
||||
- **Cross-origin calls:** when the frontend runs on another origin, allow it in `http.cors`, as [Routing](routing.md#cors) describes. A credentialed single-page app that needs its own policy on some routes names a profile with the `cors:<profile>` middleware; see [CORS profiles](routing.md#cors-profiles).
|
||||
- **Bot protection:** guard public forms such as sign-up or guest entry with Cloudflare Turnstile: the frontend widget's token goes with the request, and the `turnstile:open` or `turnstile:closed` middleware checks it. See [Turnstile](authentication.md#turnstile).
|
||||
- **Page cache:** a server-rendered frontend that caches its pages can have them purged after every admin save, so an edit shows on the next page view. See [Site cache purge](caching.md#site-cache-purge).
|
||||
- **API documentation:** publish a browsable Swagger UI page of the public API for frontend developers with `http.api_docs.enabled`. See [API documentation page](routing.md#api-documentation-page).
|
||||
- **Push notifications:** see [Web Push](push.md).
|
||||
|
||||
The admin is the one frontend SummerCMS ships. It is a single-page app built the same way, against the admin API; see [Admin SPA](../backend/admin-spa.md).
|
||||
|
||||
@@ -26,6 +26,9 @@ Each row names the WinterCMS concept, the SummerCMS identifiers that replace it,
|
||||
| Laravel collections: `map`, `filter`, `reduce`, `keyBy`, `groupBy`, `unique`, `partition`, `first` and `pluck` | Generic functions on plain slices and maps: `sieve.Map`, `sieve.TryMap`, `sieve.Filter`, `sieve.Reduce`, `sieve.KeyBy`, `sieve.GroupBy`, `sieve.Uniq`, `sieve.Partition` and `sieve.Find`. Pluck is `sieve.Map` with a field accessor, unique by key is `sieve.UniqBy`, `chunk` is the standard `slices.Chunk`, and sets are built with `sieve.SetOf` | [sieve](../../modules/sieve/README.md) |
|
||||
| `fields.yaml` and `columns.yaml` | The same YAML, embedded in the plugin through `pact.AdminAssets` and compiled at boot into a `cabana.CompiledController` | [Forms](../backend/forms.md), [Lists and filters](../backend/lists-and-filters.md), [cabana](../../modules/cabana/README.md) |
|
||||
| Backend controllers with the Form, List and Relation behaviours | A `pact.AdminController` returned from `pact.HasAdminControllers`; the generic admin API replaces the behaviours, and hooks such as `pact.FormBeforeCreate` and `pact.ListExtendQuery` replace behaviour overrides | [Admin controllers](../backend/admin-controllers.md), [cabana](../../modules/cabana/README.md) |
|
||||
| The Reorder behaviour and `config_reorder.yaml` | A `config_reorder.yaml` next to `config_list.yaml` and the `reorder` toolbar button: a drag-and-drop tree, or a flat list for records without a parent column; `pact.ReorderAfterSave` runs after a reorder save | [Lists and filters](../backend/lists-and-filters.md#tree-reorder), [cabana](../../modules/cabana/README.md) |
|
||||
| Form widgets and `registerFormWidgets` | A plugin field type: `pact.HasFormFieldTypes` returning `pact.FormFieldType` values, usable as `type:` in any controller's `fields.yaml`; a one-off element with a server action is a `type: widget` field | [Plugin field types](../backend/field-types.md), [Partials and widgets](../backend/partials-and-widgets.md#form-widgets) |
|
||||
| HTML cleaning of rich editor content | Every `richeditor` value is sanitized on save by `seaglass.Sanitize`, an allowlist policy; plugin code calls `seaglass.SanitizeReport` to learn what was removed | [Rich text](../backend/forms.md#rich-text), [seaglass](../../modules/seaglass/README.md) |
|
||||
| `routes.php` | `pact.HasRoutes`, declaring routes on a `pact.Router` with groups, middleware names and `pact.Router.Where` constraints | [Routing](../services/routing.md), [surf](../../modules/surf/README.md) |
|
||||
| Route middleware | Named middleware of type `pact.Middleware`, registered through `pact.HasMiddleware` | [Routing](../services/routing.md), [surf](../../modules/surf/README.md) |
|
||||
| `config/*.php`, `.env` and `Config::get` | `compass.Config` with per-environment directories and `SUMMER_` overrides; plugin defaults through `pact.HasConfig` | [Configuration](../services/configuration.md), [compass](../../modules/compass/README.md) |
|
||||
@@ -37,6 +40,12 @@ Each row names the WinterCMS concept, the SummerCMS identifiers that replace it,
|
||||
| `registerSchedule` and the scheduler | `pact.HasSchedule` returning `pact.ScheduledCommand` entries with a `pact.Cadence` | [Task scheduling](../plugins/scheduling.md), [pact](../../modules/pact/README.md) |
|
||||
| Mail templates in `views/mail` | `pact.HasMailTemplates`, sent through `postcard.Mailer` | [Mail](../services/mail.md), [postcard](../../modules/postcard/README.md) |
|
||||
| Settings models and `registerSettings` | `pact.HasSettings` returning `pact.SettingsItem` entries; an entry with `'url' => Backend::url(...)` sets the `Controller` field to the admin controller ID | [Settings](../backend/settings.md), [cabana](../../modules/cabana/README.md) |
|
||||
| A backend controller that only ever edits one record (its index redirects to the update screen) | A singleton controller: `pact.AdminSingleton` returns the one record, and a settings entry's `Controller` links to it | [Admin controllers](../backend/admin-controllers.md#singleton-controllers), [Settings](../backend/settings.md) |
|
||||
| Personal access tokens for API clients | Administrator API tokens with scopes and expiry, sent as `Authorization: Bearer g15_…` and managed in My account or with `admin:token:create` and the other `admin:token:*` commands | [Users and permissions](../backend/users-and-permissions.md#api-tokens), [cabana](../../modules/cabana/README.md) |
|
||||
| The Laravel `Cache` facade and `Cache::remember` | `cooler.Cache` with `cooler.Cache.Get`, `cooler.Cache.Set`, `cooler.Cache.Remember` and `cooler.Cache.Forget`, kept in memory or in Redis (`cache.driver`) | [Caching](../services/caching.md), [cooler](../../modules/cooler/README.md) |
|
||||
| The Laravel CORS config (`config/cors.php`) | The same keys under `http.cors`, plus named profiles under `http.cors_profiles` applied with the `cors:<profile>` middleware | [Routing](../services/routing.md#cors), [surf](../../modules/surf/README.md) |
|
||||
| A captcha on public forms | Cloudflare Turnstile as the `turnstile:open` and `turnstile:closed` middleware, with `turnstile.secret` | [Authentication](../services/authentication.md#turnstile), [bouncer](../../modules/bouncer/README.md) |
|
||||
| The Static Pages menu item events `pages.menuitem.listTypes`, `pages.menuitem.getTypeInfo` and `pages.menuitem.resolveItem` | Typed menu item types: `pact.HasMenuItemTypes` returning `pact.MenuItemType` values, collected in the `signpost.Registry` that menu and sitemap plugins read | [Menu item types](../plugins/menu-item-types.md), [signpost](../../modules/signpost/README.md) |
|
||||
| Laravel broadcasting | `lighthouse.Publisher` drivers and models that implement `lighthouse.Broadcastable` | [Realtime](../services/realtime.md), [lighthouse](../../modules/lighthouse/README.md) |
|
||||
| Laravel Scout search | Models that implement `beachcomber.Searchable`, synced after commit | [Search](../services/search.md), [beachcomber](../../modules/beachcomber/README.md) |
|
||||
| The Laravel HTTP client | `fetchguard.Fetch` with a `fetchguard.Policy` that blocks private addresses and limits size and time | [Outbound HTTP](../services/outbound-http.md), [fetchguard](../../modules/fetchguard/README.md) |
|
||||
@@ -53,10 +62,8 @@ SummerCMS does not port the WinterCMS frontend or the PHP helpers that Go alread
|
||||
| The AJAX framework and Snowboard | Not provided. The frontend calls the JSON API and subscribes to realtime channels; see [Frontend and AJAX](../services/frontend-and-ajax.md). |
|
||||
| The media manager | Not provided. Store uploads as model attachments; see [Attachments](../database/attachments.md). |
|
||||
| Import and export in backend lists | Not provided. |
|
||||
| Record sorting (the Reorder behaviour) | Not provided. |
|
||||
| The fluent collection object (the Collection class and method chaining) | Not provided. Call the [sieve](../../modules/sieve/README.md) functions and the standard `slices` and `maps` packages on plain slices and maps. |
|
||||
| Behaviours and dynamic class extension | Not provided. Use Go interfaces and composition. |
|
||||
| Cache | Not provided. Use the Go standard library or a service another plugin publishes. |
|
||||
| Session | Not provided. The API is stateless and authenticates with tokens; see [Frontend and AJAX](../services/frontend-and-ajax.md). |
|
||||
|
||||
## Plugin.php in Go
|
||||
|
||||
@@ -52,7 +52,9 @@ These are the keys most applications set. Each module's reference page lists all
|
||||
| `app.timezone` | Timezone of scheduled commands. Defaults to UTC. | [conga](../../modules/conga/README.md) |
|
||||
| `app.locale`, `app.fallback_locale` | Default and fallback translation locales. | [phrasebook](../../modules/phrasebook/README.md) |
|
||||
| `http.body_limits.default_bytes`, `http.body_limits.upload_bytes` | Request body limits. Required by `serve` and `route:list`. | [surf](../../modules/surf/README.md) |
|
||||
| `http.cors.*`, `http.trusted_proxies` | CORS and the proxies whose forwarded client IP is trusted. | [surf](../../modules/surf/README.md) |
|
||||
| `http.cors.*`, `http.trusted_proxies` | CORS and the proxies whose forwarded client IP is trusted. With `supports_credentials: true`, a wildcard host other than the whole leftmost label and an origin pattern not anchored with `^` and `$` fail the start-up. | [surf](../../modules/surf/README.md) |
|
||||
| `http.cors_profiles.*` | Named CORS profiles with the `http.cors` keys except `paths`, applied to a route or group with the `cors:<profile>` middleware; checked like `http.cors`. | [surf](../../modules/surf/README.md) |
|
||||
| `http.api_docs.enabled`, `http.api_docs.path`, `http.api_docs.title` | The opt-in Swagger UI page for the public API (off by default; path `/api-docs`, title `API documentation`). | [surf](../../modules/surf/README.md) |
|
||||
| `http.rate_limit.store` | Where `throttle` counters live: `memory` (per instance, the default) or `redis` (shared by every instance). | [cooler](../../modules/cooler/README.md) |
|
||||
| `cache.driver`, `cache.prefix`, `cache.memory.max_entries` | The cache driver (`memory`, the default, or `redis`), the key prefix (default from `app.name`) and the memory driver's size bound (default 10000). | [cooler](../../modules/cooler/README.md) |
|
||||
| `site_cache.purge_url`, `site_cache.purge_token` | The host site's page-cache purge route and its bearer token (at least 32 characters). Set both or neither; http only to a loopback host. Keep the token in `SUMMER_SITE_CACHE__PURGE_TOKEN`. | [cooler](../../modules/cooler/README.md) |
|
||||
@@ -61,6 +63,8 @@ These are the keys most applications set. Each module's reference page lists all
|
||||
| `storage.uploads.bucket_url` | Uploads bucket, `file://`, `mem://` or `s3://` (the last only in a binary built with the `summercms_s3` tag from `build.tags` in `summer.yaml`; credentials from the AWS environment). Required by `serve`. | [lagoon](../../modules/lagoon/README.md) |
|
||||
| `storage.uploads.public_url` | Absolute `http` or `https` base of a public bucket or CDN; file and thumbnail URLs become that base plus the partition path. Unset keeps `storage.uploads.public_path_prefix`. Only for a bucket holding public files alone. | [lagoon](../../modules/lagoon/README.md) |
|
||||
| `storage.uploads.serve` | Mounts `attach.StaticHandlerPublic` under `storage.uploads.public_path_prefix` with `X-Content-Type-Options: nosniff`, a sandboxing CSP and `Content-Disposition: attachment` for anything but a raster image. Defaults to `false`. | [surf](../../modules/surf/README.md) |
|
||||
| `auth.cookie.name`, `auth.cookie.domain`, `auth.cookie.path`, `auth.cookie.secure`, `auth.cookie.same_site` | The httpOnly token cookie for a browser frontend (defaults `token`, host-only, `/`, Secure when `app.url` is https, `lax`). In production a cookie that is not Secure fails the start-up. | [bouncer](../../modules/bouncer/README.md) |
|
||||
| `turnstile.secret`, `turnstile.field` | The Cloudflare Turnstile secret behind the `turnstile:open` and `turnstile:closed` middleware (keep it in `SUMMER_TURNSTILE__SECRET`) and the request field carrying the token (default `turnstile_token`). | [surf](../../modules/surf/README.md) |
|
||||
| `admin.jwt.secret` | Secret for admin tokens. Required as soon as a plugin registers an admin controller. | [cabana](../../modules/cabana/README.md) |
|
||||
| `backend.uri` | Path the admin is served under. Defaults to `/backend`. | [cabana](../../modules/cabana/README.md) |
|
||||
| `mail.driver`, `mail.from`, `mail.smtp.*` | Mail delivery: `memory`, `log` or `smtp`. | [postcard](../../modules/postcard/README.md) |
|
||||
@@ -69,6 +73,8 @@ These are the keys most applications set. Each module's reference page lists all
|
||||
| `search.driver`, `search.typesense.*` | The search engine and its Typesense settings. | [beachcomber](../../modules/beachcomber/README.md) |
|
||||
| `push.enabled`, `push.public_key`, `push.private_key` | Web Push with VAPID keys. | [flare](../../modules/flare/README.md) |
|
||||
|
||||
Some keys are checked more strictly from 0.2 on, so a value that started an older release can stop the start-up; [Upgrading](upgrading.md#upgrading-to-02) lists them and their fixes.
|
||||
|
||||
> [!NOTE]
|
||||
> The documentation checks every identifier, link and command name it shows against the code, but not configuration keys. The keys on this page are reviewed by hand; the module reference pages are the authority.
|
||||
|
||||
|
||||
@@ -30,9 +30,12 @@ The data layer supports PostgreSQL only, and SummerCMS targets Go 1.27.
|
||||
|
||||
## How these docs are organised
|
||||
|
||||
- **Setup** covers installation, configuration and the move from WinterCMS.
|
||||
- **Setup** covers installation, configuration, the move from WinterCMS and [Upgrading](upgrading.md) to a newer framework release.
|
||||
- **Architecture** explains the single binary, Go modules, the application lifecycle and how a request reaches your code.
|
||||
- **Plugins** covers registering a plugin, scheduling, extending other plugins and testing.
|
||||
- **Plugins** covers registering a plugin, scheduling, extending other plugins, menu item types and testing.
|
||||
- **Backend** covers the admin: controllers, forms and field types, lists and filters, relations, users and API tokens, settings and the admin SPA.
|
||||
- **Database** covers models, migrations, queries and pagination, relations, casts and validation, attachments and transactions.
|
||||
- **Services** covers configuration, events, routing, authentication, caching, rate limiting, storage, logging, mail, jobs, realtime, search, push and the other runtime services.
|
||||
- **Console** lists the `summer` tool's commands and the commands of every application binary, and shows how to write your own.
|
||||
- **API reference** has one page per framework module.
|
||||
|
||||
|
||||
73
docs/setup/upgrading.md
Normal file
73
docs/setup/upgrading.md
Normal file
@@ -0,0 +1,73 @@
|
||||
---
|
||||
title: Upgrading
|
||||
description: Move an application to a newer framework release, what the version numbers promise, and the config to check before you take 0.2.
|
||||
section: setup
|
||||
order: 60
|
||||
---
|
||||
# Upgrading
|
||||
|
||||
An application created by `summer new` builds against a framework checkout next to it; the update script moves that checkout to the newest release tag, reinstalls the `summer` tool and rebuilds the application (see [Updating an application](installation.md#updating-an-application)). An application or plugin that requires a tagged framework version in its `go.mod` moves with the go command instead:
|
||||
|
||||
```sh
|
||||
go get git.golem15.com/golem15/summercms@v0.2.0
|
||||
go mod tidy
|
||||
```
|
||||
|
||||
Then rebuild, run `migrate` with the new binary and restart it.
|
||||
|
||||
## Version numbers
|
||||
|
||||
SummerCMS is in the 0.x series, and the version tells you whether to read before you upgrade:
|
||||
|
||||
- The minor version (0.1 to 0.2) goes up when an upgrade can refuse a configuration that the previous release accepted, or changes a documented behaviour. Read the section for that version below before you deploy it.
|
||||
- A patch version (0.2.0 to 0.2.1) is safe to take without reading: it fixes bugs and adds features, and an application that started on the previous patch starts on it too.
|
||||
|
||||
Applications pin exact versions, so a new release never reaches an application until it moves its `go.mod` or its checkout.
|
||||
|
||||
## Upgrading to 0.2
|
||||
|
||||
0.2 tightens two configuration checks so that settings which leaked credentials stop the start-up instead. Most applications are not affected: the first concerns applications that load an `auth.cookie` block, the second applications that send credentialed CORS answers. Start the new binary once in each environment before you switch traffic to it; a refused configuration fails `serve` at start-up with an error that names the key.
|
||||
|
||||
### Boot refusals
|
||||
|
||||
**A token cookie that is not Secure in production.** In the production environment, `bouncer.LoadCookieConfig` refuses a token cookie whose `Secure` attribute resolves to false. That covers `auth.cookie.secure: false` and, since 0.2, an unset `auth.cookie.secure` with an http or empty `app.url`, from which the cookie inherited `Secure=false` before. The error names `auth.cookie.secure` and `app.url`.
|
||||
|
||||
It affects applications whose plugins load an `auth.cookie` block for a browser frontend (the cookie transport). To fix it, set `app.url` to the application's public https URL, or set `auth.cookie.secure: true` explicitly. See [Cookie transport](../services/authentication.md#cookie-transport).
|
||||
|
||||
**Credentialed CORS with a wildcard host or an unanchored pattern.** With `supports_credentials: true`, globally under `http.cors` or in any profile under `http.cors_profiles.<name>`, these entries now fail the start-up, and the error names the key with its index, such as `http.cors.allowed_origins[1]` or `http.cors_profiles.spa.allowed_origins_patterns[0]`:
|
||||
|
||||
- an `allowed_origins` entry with a `*` that is not the whole leftmost host label after a literal scheme, such as `https://*`, `*://*`, `https://*example.com` or `http*://www.example.com` (`https://*.example.com` stays valid);
|
||||
- an `allowed_origins_patterns` entry not anchored with `^` and `$`, in every alternative of the expression;
|
||||
- any origin rule that matches an origin outside the configured domains, such as `https://*.com` or `^https?://.*$`.
|
||||
|
||||
It affects applications that send credentialed CORS answers, to a browser frontend on another origin that calls the API with cookies. To fix it, list the frontend's exact origins, or write anchored patterns such as `^https://[a-z]+\.example\.com$`. Without credentials these entries load as before. See [CORS](../services/routing.md#cors) and [CORS profiles](../services/routing.md#cors-profiles).
|
||||
|
||||
### Behaviour changes
|
||||
|
||||
These need no configuration change, but a test or an operator may notice them:
|
||||
|
||||
- **Site-cache purges are queued.** After an admin save commits, the purge request to the site is queued and sent by a background worker, with at most one request in flight per purger; saves committed meanwhile collapse into one follow-up request. The save no longer waits for the site. A test that asserts a purge calls `cooler.SiteCachePurger.Wait` first, and `serve` drains the queue on shutdown. See [Site cache purge](../services/caching.md#site-cache-purge).
|
||||
- **Protected uploads need a private bucket.** While `storage.uploads.public_url` is set, `attach.Store` refuses a protected (`is_public` false) upload with `attach.ErrProtectedNeedsPrivateBucket` before it writes anything, and `serve` logs one warning at start-up that the bucket must hold public files only. Keep protected relations on a bucket without `public_url`, or make the relation public. See [Public URL base](../services/storage.md#public-url-base).
|
||||
- **The Journal plugin's purge keys are deprecated.** `golem15.journal.site_cache.purge_url` and `golem15.journal.site_cache.purge_token` still work as aliases of the framework's `site_cache.purge_url` and `site_cache.purge_token`, which win when both are set; the plugin logs a deprecation warning. Move the values to the `site_cache` keys.
|
||||
- **Cookie defaults.** A `bouncer.CookieConfig` built by hand with every field zero writes `SameSite=Lax` and `Secure`; a config with any field set keeps its own `Secure` value.
|
||||
- **The API documentation page** at `/api-docs` runs only scripts that carry the page's per-request nonce. See [API documentation page](../services/routing.md#api-documentation-page).
|
||||
- **Turnstile without a secret.** When `turnstile.secret` is empty and routes name `turnstile:open` or `turnstile:closed`, the start-up logs one warning with the number of such routes. See [Turnstile](../services/authentication.md#turnstile).
|
||||
- **CORS profile headers on every answer.** A route that names `cors:<profile>` carries the profile's headers on every response, including refusals from guards, throttle, Turnstile and the body limit, and recovered panics.
|
||||
|
||||
## What 0.2 adds since 0.1
|
||||
|
||||
The 0.1 series grew through many patch releases. These are the larger features that arrived after its first public releases, with the page that documents each:
|
||||
|
||||
- Caching with memory and Redis drivers, and a Redis store that shares `throttle` counters between instances: [Caching](../services/caching.md), [Rate limiting](../services/rate-limiting.md).
|
||||
- The site-cache purge after admin saves, including reorder saves through `pact.ReorderAfterSave`: [Site cache purge](../services/caching.md#site-cache-purge).
|
||||
- Token cookies with ready-made refresh and logout handlers, and Turnstile bot protection: [Cookie transport](../services/authentication.md#cookie-transport), [Turnstile](../services/authentication.md#turnstile).
|
||||
- Credentialed CORS, per-route CORS profiles (`cors:<profile>`) and the opt-in API documentation page: [CORS](../services/routing.md#cors), [CORS profiles](../services/routing.md#cors-profiles), [API documentation page](../services/routing.md#api-documentation-page).
|
||||
- Go build tags in `summer.yaml` (`build.tags`), S3 uploads buckets behind the `summercms_s3` tag and a public URL base for a bucket or CDN: [The summer.yaml manifest](../architecture/go-modules-and-workspaces.md#the-summeryaml-manifest), [S3 and S3-compatible buckets](../services/storage.md#s3-and-s3-compatible-buckets), [Public URL base](../services/storage.md#public-url-base).
|
||||
- Serving uploads from the application and a per-request access log: [Serving files](../services/storage.md#serving-files), [Request log](../services/logging.md#request-log).
|
||||
- Plugin-provided admin field types: [Plugin field types](../backend/field-types.md).
|
||||
- Rich text, repeater, money, password and taglist fields, and dependent dropdowns: [Rich text](../backend/forms.md#rich-text), [Repeater](../backend/forms.md#repeater), [Money](../backend/forms.md#money), [Form-only fields](../backend/forms.md#form-only-fields), [Taglist](../backend/forms.md#taglist), [Dependent dropdowns](../backend/forms.md#dependent-dropdowns).
|
||||
- Record reordering as a tree or a flat list: [Tree reorder](../backend/lists-and-filters.md#tree-reorder), [Flat reorder](../backend/lists-and-filters.md#flat-reorder).
|
||||
- Singleton controllers, record actions and write-only settings secrets: [Singleton controllers](../backend/admin-controllers.md#singleton-controllers), [Record actions](../backend/admin-controllers.md#record-actions), [Write-only secrets](../backend/settings.md#write-only-secrets).
|
||||
- Personal API tokens for administrators and the `admin:token:*` commands: [API tokens](../backend/users-and-permissions.md#api-tokens), [Admin accounts](../console/setup-and-maintenance.md#admin-accounts).
|
||||
- Menu item types that content plugins register for menus and sitemaps: [Menu item types](../plugins/menu-item-types.md).
|
||||
- New framework modules: [cooler](../../modules/cooler/README.md) (caches, shared counters and the site-cache purge), [seaglass](../../modules/seaglass/README.md) (the rich text sanitizer), [sieve](../../modules/sieve/README.md) (collection helpers) and [signpost](../../modules/signpost/README.md) (the menu item type registry).
|
||||
Reference in New Issue
Block a user