feat: Add setup token security for initial server setup

- Add setupTokens database table with proper schema
- Implement setup token generation on first server startup
- Add token validation endpoint and modify admin creation
- Update initial setup page to require setup token
- Add migration scripts for both SQLite and PostgreSQL
- Add internationalization support for setup token fields
- Implement proper error handling and logging
- Add CLI command for resetting user security keys

This prevents unauthorized access during initial server setup by requiring
a token that is generated and displayed in the server console.
This commit is contained in:
Adrian Astles
2025-08-03 21:17:18 +08:00
parent 84268e484d
commit 69baa6785f
15 changed files with 322 additions and 115 deletions

View File

@@ -31,6 +31,7 @@ import { passwordSchema } from "@server/auth/passwordSchema";
const formSchema = z
.object({
setupToken: z.string().min(1, "Setup token is required"),
email: z.string().email({ message: "Invalid email address" }),
password: passwordSchema,
confirmPassword: z.string()
@@ -52,6 +53,7 @@ export default function InitialSetupPage() {
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
setupToken: "",
email: "",
password: "",
confirmPassword: ""
@@ -63,6 +65,7 @@ export default function InitialSetupPage() {
setError(null);
try {
const res = await api.put("/auth/set-server-admin", {
setupToken: values.setupToken,
email: values.email,
password: values.password
});
@@ -102,6 +105,23 @@ export default function InitialSetupPage() {
onSubmit={form.handleSubmit(onSubmit)}
className="space-y-4"
>
<FormField
control={form.control}
name="setupToken"
render={({ field }) => (
<FormItem>
<FormLabel>{t("setupToken")}</FormLabel>
<FormControl>
<Input
{...field}
placeholder={t("setupTokenPlaceholder")}
autoComplete="off"
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="email"