Files
minstrel/web/src/lib/api/me.ts
T
bvandeusen 72f46a885b feat(web/m7-user-mgmt): /settings expansion + /forgot-password (U3-T5a)
Lands four of the U3 frontend surfaces. Splits T5 because the
dispatch covering everything in one shot crashed the runtime
mid-execution; this is the salvageable half.

- /settings gains three cards alongside Appearance: Profile
  (display name + email), Password (current + new + confirm with
  client-side mismatch check), API Token (display + copy +
  regenerate-with-double-click-confirm). Server error codes map
  to clear toasts.
- /forgot-password — public; takes an email and always shows the
  success message regardless of whether the email is on file
  (mirrors the server's no-enumeration posture).
- Login page gets a "Forgot password?" link below the existing
  register link.
- API client functions for the four /me endpoints (changePassword,
  updateProfile, getAPIToken, regenerateAPIToken), the SMTP admin
  trio (getSMTPConfig, updateSMTPConfig, testSMTPConfig), and the
  forgot/reset auth pair (forgotPassword, resetPassword).

Tests for these surfaces + /reset-password page + admin SMTP card
land in T5b (next follow-up).
2026-05-07 17:33:48 -04:00

56 lines
1.7 KiB
TypeScript

import { createQuery } from '@tanstack/svelte-query';
import { api } from './client';
import { qk } from './queries';
export type SystemPlaylistsStatus = {
in_flight: boolean;
last_run_at: string | null;
last_error: string | null;
};
export async function getSystemPlaylistsStatus(): Promise<SystemPlaylistsStatus> {
return api.get<SystemPlaylistsStatus>('/api/me/system-playlists-status');
}
// Refresh aggressively while a build is in_flight so the building → built
// transition appears live on the home page. Stale-time is short; manual
// invalidations on the server's POST endpoints are out of scope.
export function createSystemPlaylistsStatusQuery() {
return createQuery({
queryKey: qk.systemPlaylistsStatus(),
queryFn: getSystemPlaylistsStatus,
staleTime: 10_000
});
}
// Self-service profile / password / API-token endpoints (U3) ---------------
export type MyProfile = {
id: string;
username: string;
display_name: string | null;
email: string | null;
is_admin: boolean;
};
export type APITokenResponse = { api_token: string };
export async function changePassword(currentPassword: string, newPassword: string): Promise<void> {
await api.put('/api/me/password', {
current_password: currentPassword,
new_password: newPassword,
});
}
export async function updateProfile(input: { display_name?: string; email?: string }): Promise<MyProfile> {
return api.put<MyProfile>('/api/me/profile', input);
}
export async function getAPIToken(): Promise<APITokenResponse> {
return api.get<APITokenResponse>('/api/me/api-token');
}
export async function regenerateAPIToken(): Promise<APITokenResponse> {
return api.post<APITokenResponse>('/api/me/api-token', {});
}