feat(18-01): write-only settings secrets, richeditor and tabs on settings forms (task 3)
- type: password on a settings form binds a lagoon.Encrypted column as a write-only secret (any other column fails boot naming the field): the GET omits it from data and reports stored, env or empty per field in meta.secrets; on PUT an absent key or "" keeps the value, null clears it, a non-string is a 422; the answer never carries a value - cabana.SecretFallbacks (field to config key) gives the env state; cabana.SettingsMeta, SecretStored/SecretEnv/SecretEmpty exported - settings forms accept richeditor: the Put sanitizes through seaglass like a controller save and returns meta.notices; repeater and dependsOn stay refused (settingsFormOnly next to controllerFormOnly) - backend::lang secret.* phrases in en and pl - admin SPA: PasswordField secret status line (stored with Remove stored value, env, empty, pending clear with Undo), SettingsFormView tabs with error-tab activation and the secrets/notices meta, settings payload that never sends an untouched secret; regenerated OpenAPI and TS types; rebuilt dist - vault fixture, TestSettingsSecretCompile, Docker TestSettingsSecretSmoke and TestSettingsRichEditorSmoke, conform settings fixture with a password field; settings.md sections, forms.md notes, cabana README
This commit is contained in:
@@ -298,6 +298,7 @@ func (MembersController) FormVirtualFields() []string {
|
||||
- Every listed name must be a field of the form's `fields.yaml` with the type `password`, `text`, `textarea`, `number`, `checkbox`, `switch` or `dropdown`. Anything else stops the start-up.
|
||||
- `type: password` is always a form-only field: a password field the controller does not list stops the start-up. The admin SPA shows it empty on every load, leaves an empty password out of an update (empty means unchanged), and clears it after a save. A confirmation is a second `password` field, compared by the `confirmed` rule on the server.
|
||||
- Form-only fields are not available on settings forms or relation forms.
|
||||
- On a settings form `type: password` is not a form-only field but a write-only secret backed by a `lagoon.Encrypted` column; see [Write-only secrets](settings.md#write-only-secrets).
|
||||
|
||||
## Permission editor
|
||||
|
||||
@@ -449,7 +450,7 @@ The value travels as a string of HTML, or null. Anything else in a save body is
|
||||
- HTML the policy keeps whole is stored byte for byte, so a value that only differs in escaping is never rewritten.
|
||||
- Otherwise the clean HTML is stored and the save still succeeds. The create or update response then carries `meta.notices` for the field: how many elements and attributes were removed with their names, how many comments, or that some markup changed. The admin shows them under the field.
|
||||
|
||||
The editor's own toolbar keeps to the same allowlist, but the server is the gate: a value posted by any client goes through the policy. The type is supported in controller forms only; settings forms and relation forms refuse it at start-up, so no save path stores an unsanitized value.
|
||||
The editor's own toolbar keeps to the same allowlist, but the server is the gate: a value posted by any client goes through the policy. The type is supported in controller forms and on [settings forms](settings.md#rich-text-on-a-settings-page), whose save runs the same sanitizer; relation forms refuse it at start-up, so no save path stores an unsanitized value.
|
||||
|
||||
In the admin SPA the field is a TipTap editor with a toolbar for bold, italic, underline, a level 3 heading, bullet and numbered lists, quotes, links, undo and redo. The editor code loads on first use, so forms without a rich text field never download it.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user