feat(auth): first account on a new server needs the setup token from the server log (M462 #4982)
test-go / test (push) Successful in 2m3s
test-web / test (push) Successful in 1m14s
test-go / integration (push) Successful in 4m38s
release / Build signed APK (releases and dev) (push) Successful in 5m36s
release / Build + push container image (push) Successful in 1m24s
release / Verify release artifacts (tag releases only) (push) Skipped
test-go / test (push) Successful in 2m3s
test-web / test (push) Successful in 1m14s
test-go / integration (push) Successful in 4m38s
release / Build signed APK (releases and dev) (push) Successful in 5m36s
release / Build + push container image (push) Successful in 1m24s
release / Verify release artifacts (tag releases only) (push) Skipped
While no accounts exist, the server mints a random setup token at boot and logs it. Registering the first account (which becomes admin) must carry it, so whoever reaches a freshly exposed instance first cannot claim it. The register page asks GET /api/auth/setup-status and shows a "Setup token" field in place of the invite field while setup is pending. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -47,10 +47,19 @@ export async function login(username: string, password: string): Promise<void> {
|
||||
void sendTimezoneIfStale();
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the server has no accounts yet, in which case the first
|
||||
* registration must carry the setup token printed in the server log.
|
||||
*/
|
||||
export async function getSetupStatus(): Promise<{ setup_required: boolean }> {
|
||||
return api.get<{ setup_required: boolean }>('/api/auth/setup-status');
|
||||
}
|
||||
|
||||
export async function register(opts: {
|
||||
username: string;
|
||||
password: string;
|
||||
inviteToken?: string;
|
||||
setupToken?: string;
|
||||
displayName?: string;
|
||||
}): Promise<void> {
|
||||
const body: Record<string, string> = {
|
||||
@@ -58,6 +67,7 @@ export async function register(opts: {
|
||||
password: opts.password,
|
||||
};
|
||||
if (opts.inviteToken) body.invite_token = opts.inviteToken;
|
||||
if (opts.setupToken) body.setup_token = opts.setupToken;
|
||||
if (opts.displayName) body.display_name = opts.displayName;
|
||||
const res = await api.post<LoginResponse>('/api/auth/register', body);
|
||||
setUser(res.user);
|
||||
|
||||
Reference in New Issue
Block a user