Add Audible region config and user password change modal

Implements configurable Audible region selection in setup and admin settings, affecting all Audible API calls and triggering data refresh on change. Adds a user-facing 'Change Password' modal in the header for local users, moving password change from admin-only to all local users via a new /api/auth/change-password endpoint. Updates documentation, API routes, and context to support these features, and removes the old admin-only password change flow.
This commit is contained in:
kikootwo
2026-01-13 01:51:22 -05:00
parent 50fb5a68af
commit e346f88f42
24 changed files with 932 additions and 317 deletions
+6
View File
@@ -22,6 +22,7 @@ import { PathsStep } from './steps/PathsStep';
import { BookDateStep } from './steps/BookDateStep';
import { ReviewStep } from './steps/ReviewStep';
import { FinalizeStep } from './steps/FinalizeStep';
import { AudibleRegion } from '@/lib/types/audible';
interface SelectedIndexer {
id: number;
@@ -34,6 +35,7 @@ interface SetupState {
// Backend selection
backendMode: 'plex' | 'audiobookshelf';
audibleRegion: AudibleRegion;
// Admin account (for Plex mode and ABS + Manual mode)
adminUsername: string;
@@ -106,6 +108,7 @@ export default function SetupWizard() {
// Backend selection
backendMode: 'plex',
audibleRegion: 'us',
// Admin account
adminUsername: 'admin',
@@ -215,6 +218,7 @@ export default function SetupWizard() {
try {
const payload: any = {
backendMode: state.backendMode,
audibleRegion: state.audibleRegion,
prowlarr: {
url: state.prowlarrUrl,
api_key: state.prowlarrApiKey,
@@ -363,6 +367,8 @@ export default function SetupWizard() {
<BackendSelectionStep
value={state.backendMode}
onChange={(value) => updateField('backendMode', value)}
audibleRegion={state.audibleRegion}
onAudibleRegionChange={(region) => updateField('audibleRegion', region)}
onNext={() => goToStep(currentStepNumber + 1)}
onBack={() => goToStep(currentStepNumber - 1)}
/>
@@ -6,10 +6,13 @@
'use client';
import { Button } from '@/components/ui/Button';
import { AudibleRegion } from '@/lib/types/audible';
interface BackendSelectionStepProps {
value: 'plex' | 'audiobookshelf';
onChange: (value: 'plex' | 'audiobookshelf') => void;
audibleRegion: AudibleRegion;
onAudibleRegionChange: (region: AudibleRegion) => void;
onNext: () => void;
onBack: () => void;
}
@@ -17,6 +20,8 @@ interface BackendSelectionStepProps {
export function BackendSelectionStep({
value,
onChange,
audibleRegion,
onAudibleRegionChange,
onNext,
onBack,
}: BackendSelectionStepProps) {
@@ -94,6 +99,32 @@ export function BackendSelectionStep({
</label>
</div>
{/* Audible Region Selection */}
<div className="space-y-2">
<label
htmlFor="audible-region"
className="block text-sm font-medium text-gray-900 dark:text-gray-100"
>
Audible Region
</label>
<select
id="audible-region"
value={audibleRegion}
onChange={(e) => onAudibleRegionChange(e.target.value as AudibleRegion)}
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500"
>
<option value="us">United States</option>
<option value="ca">Canada</option>
<option value="uk">United Kingdom</option>
<option value="au">Australia</option>
<option value="in">India</option>
</select>
<p className="text-sm text-gray-600 dark:text-gray-400">
Select the Audible region that matches your metadata engine (Audnexus/Audible Agent)
configuration in {value === 'plex' ? 'Plex' : 'Audiobookshelf'}. This ensures accurate book matching and metadata.
</p>
</div>
<div className="bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 rounded-lg p-4">
<div className="flex gap-3">
<svg