fix (admin): report validation error

I've seen someone who mistakenly had updated their config secret key,
not sure if it was done by a weird password manager or a manual action
but that did corrupt their entire setup.

We now make sure value like secret key get validated before saving.
Didn't realise this would be necessary to start with as the appraoch has
always been "with great power come great responsability" but if it can
prevent catastrophic failure mode hapening by mistake, then we will be
making an exception to the moto
This commit is contained in:
MickaelK
2025-02-06 21:06:55 +11:00
parent 65bd2fde5c
commit 65cf080af7
6 changed files with 16 additions and 6 deletions
+3 -1
View File
@@ -54,7 +54,8 @@ export function $renderInput(options = {}) {
readonly = false,
path = [],
datalist = null,
options = null
options = null,
pattern = null,
} = props;
const attrs = [];
@@ -67,6 +68,7 @@ export function $renderInput(options = {}) {
$node.setAttribute("autocapitalize", "off");
$node.setAttribute("spellcheck", "off");
});
if (pattern) attrs.push(($node) => $node.setAttribute("pattern", pattern));
if (required) attrs.push(($node) => $node.setAttribute("required", ""));
if (readonly) attrs.push(($node) => $node.setAttribute("disabled", ""));
+1 -1
View File
@@ -74,6 +74,6 @@ export function stateMutation($node: HTMLElement, attr: string);
export function preventDefault(): typeof tap;
export function onClick($node: HTMLElement): ReturnType<typeof fromEvent>;
export function onClick($node: HTMLElement, opts?: { preventDefault?: boolean }): ReturnType<typeof fromEvent>;
export function onLoad($node: HTMLElement): void;
@@ -47,7 +47,7 @@ export default AdminHOC(async function(render) {
const init$ = config$.pipe(
rxjs.mergeMap((formSpec) => createForm(formSpec, tmpl)),
rxjs.map(($form) => [$form]),
applyMutation(qs($container, "[data-bind=\"form\"]"), "replaceChildren"),
applyMutation(qs($container, `[data-bind="form"]`), "replaceChildren"),
rxjs.share(),
);
effect(init$);
@@ -33,6 +33,13 @@ export function useForm$($inputNodeList) {
return rxjs.pipe(
rxjs.mergeMap(() => $inputNodeList()),
rxjs.mergeMap(($el) => rxjs.fromEvent($el, "input")),
rxjs.mergeMap(($el) => {
if ($el.target.checkValidity() === false) {
$el.target.reportValidity();
return rxjs.EMPTY;
}
return rxjs.of($el);
}),
rxjs.map((e) => ({
name: e.target.getAttribute("name"),
value: (function() {
@@ -61,9 +61,9 @@ export default async function(render) {
rxjs.startWith(null),
rxjs.map(() => {
if ($list.getAttribute("data-type") === "grid") {
return gridSize($list.clientWidth, document.body.clientWidth)
return gridSize($list.clientWidth, document.body.clientWidth);
}
return -1;
return 0;
}),
rxjs.distinctUntilChanged(),
rxjs.skip(1),
+2 -1
View File
@@ -38,6 +38,7 @@ type FormElement struct {
Type string `json:"type"`
Description string `json:"description,omitempty"`
Placeholder string `json:"placeholder,omitempty"`
Pattern string `json:"pattern,omitempty"`
Opts []string `json:"options,omitempty"`
Target []string `json:"target,omitempty"`
ReadOnly bool `json:"readonly"`
@@ -67,7 +68,7 @@ func NewConfiguration() Configuration {
FormElement{Name: "name", Type: "text", Default: "Filestash", Description: "Name has shown in the UI", Placeholder: "Default: \"Filestash\""},
FormElement{Name: "port", Type: "number", Default: 8334, Description: "Port on which the application is available.", Placeholder: "Default: 8334"},
FormElement{Name: "host", Type: "text", Description: "The host people need to use to access this server", Placeholder: "Eg: \"demo.filestash.app\""},
FormElement{Name: "secret_key", Type: "password", Description: "The key that's used to encrypt and decrypt content. Update this settings will invalidate existing user sessions and shared links, use with caution!"},
FormElement{Name: "secret_key", Type: "password", Required: true, Pattern: "[a-zA-Z0-9]{16}", Description: "The key that's used to encrypt and decrypt content. Update this settings will invalidate existing user sessions and shared links, use with caution!"},
FormElement{Name: "force_ssl", Type: "boolean", Description: "Enable the web security mechanism called 'Strict Transport Security'"},
FormElement{Name: "editor", Type: "select", Default: "emacs", Opts: []string{"base", "emacs", "vim"}, Description: "Keybinding to be use in the editor. Default: \"emacs\""},
FormElement{Name: "fork_button", Type: "boolean", Default: true, Description: "Display the fork button in the login screen"},