feat(backend): boxSettings table + box password actions
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
// Pure validation for the box user's password, shared by the Node action and
|
||||
// unit tests. Kept free of Convex imports so it tests without the harness.
|
||||
|
||||
export type BoxPasswordValidation =
|
||||
| { ok: true; value: string | null }
|
||||
| { ok: false; error: string };
|
||||
|
||||
// null/'' is an explicit clear (sudo reverts to NOPASSWD). The applied value
|
||||
// travels to `chpasswd` as a `user:password` stdin line, so control characters
|
||||
// (including newline/tab) are rejected; colons are fine — chpasswd splits on
|
||||
// the first colon only.
|
||||
export const normalizeBoxPassword = (
|
||||
password: string | null | undefined,
|
||||
): BoxPasswordValidation => {
|
||||
if (password == null || password === '') return { ok: true, value: null };
|
||||
if (password.length < 8) {
|
||||
return { ok: false, error: 'Password must be at least 8 characters.' };
|
||||
}
|
||||
if (password.length > 128) {
|
||||
return { ok: false, error: 'Password must be at most 128 characters.' };
|
||||
}
|
||||
// eslint-disable-next-line no-control-regex -- rejecting control chars is the point
|
||||
if (/[\u0000-\u001f\u007f]/.test(password)) {
|
||||
return {
|
||||
ok: false,
|
||||
error: 'Password must not contain control characters.',
|
||||
};
|
||||
}
|
||||
return { ok: true, value: password };
|
||||
};
|
||||
Reference in New Issue
Block a user