refactor(admin): let session auth drive albums/media routes

This commit is contained in:
Justin Edmund 2025-10-07 05:58:49 -07:00
parent e2949bff20
commit 6a0e9c2fdb
6 changed files with 58 additions and 115 deletions

View file

@ -85,14 +85,8 @@
async function loadAlbums() { async function loadAlbums() {
try { try {
const auth = localStorage.getItem('admin_auth')
if (!auth) {
goto('/admin/login')
return
}
const response = await fetch('/api/albums', { const response = await fetch('/api/albums', {
headers: { Authorization: `Basic ${auth}` } credentials: 'same-origin'
}) })
if (!response.ok) { if (!response.ok) {
@ -200,20 +194,21 @@
const album = event.detail.album const album = event.detail.album
try { try {
const auth = localStorage.getItem('admin_auth')
const newStatus = album.status === 'published' ? 'draft' : 'published' const newStatus = album.status === 'published' ? 'draft' : 'published'
const response = await fetch(`/api/albums/${album.id}`, { const response = await fetch(`/api/albums/${album.id}`, {
method: 'PATCH', method: 'PATCH',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json'
Authorization: `Basic ${auth}`
}, },
body: JSON.stringify({ status: newStatus }) body: JSON.stringify({ status: newStatus }),
credentials: 'same-origin'
}) })
if (response.ok) { if (response.ok) {
await loadAlbums() await loadAlbums()
} else if (response.status === 401) {
goto('/admin/login')
} }
} catch (err) { } catch (err) {
console.error('Failed to update album status:', err) console.error('Failed to update album status:', err)
@ -231,15 +226,15 @@
if (!albumToDelete) return if (!albumToDelete) return
try { try {
const auth = localStorage.getItem('admin_auth')
const response = await fetch(`/api/albums/${albumToDelete.id}`, { const response = await fetch(`/api/albums/${albumToDelete.id}`, {
method: 'DELETE', method: 'DELETE',
headers: { Authorization: `Basic ${auth}` } credentials: 'same-origin'
}) })
if (response.ok) { if (response.ok) {
await loadAlbums() await loadAlbums()
} else if (response.status === 401) {
goto('/admin/login')
} else { } else {
const errorData = await response.json() const errorData = await response.json()
error = errorData.error || 'Failed to delete album' error = errorData.error || 'Failed to delete album'

View file

@ -17,17 +17,15 @@
async function loadAlbum() { async function loadAlbum() {
try { try {
const auth = localStorage.getItem('admin_auth')
if (!auth) {
goto('/admin/login')
return
}
const response = await fetch(`/api/albums/${albumId}`, { const response = await fetch(`/api/albums/${albumId}`, {
headers: { Authorization: `Basic ${auth}` } credentials: 'same-origin'
}) })
if (!response.ok) { if (!response.ok) {
if (response.status === 401) {
goto('/admin/login')
return
}
throw new Error('Failed to load album') throw new Error('Failed to load album')
} }

View file

@ -66,19 +66,14 @@
selectedFiles.clear() selectedFiles.clear()
try { try {
const auth = localStorage.getItem('admin_auth')
if (!auth) {
error = 'Not authenticated'
loading = false
return
}
const response = await fetch('/api/admin/cloudinary-audit', { const response = await fetch('/api/admin/cloudinary-audit', {
headers: { credentials: 'same-origin'
Authorization: `Basic ${auth}`
}
}) })
if (!response.ok) { if (!response.ok) {
if (response.status === 401) {
goto('/admin/login')
return
}
throw new Error('Failed to fetch audit data') throw new Error('Failed to fetch audit data')
} }
auditData = await response.json() auditData = await response.json()
@ -119,26 +114,23 @@
deleteResults = null deleteResults = null
try { try {
const auth = localStorage.getItem('admin_auth')
if (!auth) {
error = 'Not authenticated'
deleting = false
return
}
const response = await fetch('/api/admin/cloudinary-audit', { const response = await fetch('/api/admin/cloudinary-audit', {
method: 'DELETE', method: 'DELETE',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json'
Authorization: `Basic ${auth}`
}, },
body: JSON.stringify({ body: JSON.stringify({
publicIds: Array.from(selectedFiles), publicIds: Array.from(selectedFiles),
dryRun dryRun
}) }),
credentials: 'same-origin'
}) })
if (!response.ok) { if (!response.ok) {
if (response.status === 401) {
goto('/admin/login')
return
}
throw new Error('Failed to delete files') throw new Error('Failed to delete files')
} }
@ -175,25 +167,22 @@
cleanupResults = null cleanupResults = null
try { try {
const auth = localStorage.getItem('admin_auth')
if (!auth) {
error = 'Not authenticated'
cleaningUp = false
return
}
const response = await fetch('/api/admin/cloudinary-audit', { const response = await fetch('/api/admin/cloudinary-audit', {
method: 'PATCH', method: 'PATCH',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json'
Authorization: `Basic ${auth}`
}, },
body: JSON.stringify({ body: JSON.stringify({
publicIds: auditData.missingReferences publicIds: auditData.missingReferences
}) }),
credentials: 'same-origin'
}) })
if (!response.ok) { if (!response.ok) {
if (response.status === 401) {
goto('/admin/login')
return
}
throw new Error('Failed to clean up broken references') throw new Error('Failed to clean up broken references')
} }

View file

@ -40,27 +40,20 @@
} | null>(null) } | null>(null)
onMount(() => { onMount(() => {
// Check authentication fetchMediaStats()
const auth = localStorage.getItem('admin_auth')
if (!auth) {
goto('/admin/login')
} else {
fetchMediaStats()
}
}) })
async function fetchMediaStats() { async function fetchMediaStats() {
try { try {
const auth = localStorage.getItem('admin_auth')
if (!auth) return
const response = await fetch('/api/admin/media-stats', { const response = await fetch('/api/admin/media-stats', {
headers: { credentials: 'same-origin'
Authorization: `Basic ${auth}`
}
}) })
if (!response.ok) { if (!response.ok) {
if (response.status === 401) {
goto('/admin/login')
return
}
throw new Error('Failed to fetch media stats') throw new Error('Failed to fetch media stats')
} }
@ -76,20 +69,16 @@
colorExtractionResults = null colorExtractionResults = null
try { try {
const auth = localStorage.getItem('admin_auth')
if (!auth) {
error = 'Not authenticated'
return
}
const response = await fetch('/api/admin/cloudinary-extract-colors', { const response = await fetch('/api/admin/cloudinary-extract-colors', {
method: 'POST', method: 'POST',
headers: { credentials: 'same-origin'
Authorization: `Basic ${auth}`
}
}) })
if (!response.ok) { if (!response.ok) {
if (response.status === 401) {
goto('/admin/login')
return
}
throw new Error('Failed to extract colors') throw new Error('Failed to extract colors')
} }
@ -111,20 +100,16 @@
thumbnailResults = null thumbnailResults = null
try { try {
const auth = localStorage.getItem('admin_auth')
if (!auth) {
error = 'Not authenticated'
return
}
const response = await fetch('/api/admin/regenerate-thumbnails', { const response = await fetch('/api/admin/regenerate-thumbnails', {
method: 'POST', method: 'POST',
headers: { credentials: 'same-origin'
Authorization: `Basic ${auth}`
}
}) })
if (!response.ok) { if (!response.ok) {
if (response.status === 401) {
goto('/admin/login')
return
}
throw new Error('Failed to regenerate thumbnails') throw new Error('Failed to regenerate thumbnails')
} }
@ -146,20 +131,16 @@
reanalysisResults = null reanalysisResults = null
try { try {
const auth = localStorage.getItem('admin_auth')
if (!auth) {
error = 'Not authenticated'
return
}
const response = await fetch('/api/admin/reanalyze-colors', { const response = await fetch('/api/admin/reanalyze-colors', {
method: 'POST', method: 'POST',
headers: { credentials: 'same-origin'
Authorization: `Basic ${auth}`
}
}) })
if (!response.ok) { if (!response.ok) {
if (response.status === 401) {
goto('/admin/login')
return
}
throw new Error('Failed to reanalyze colors') throw new Error('Failed to reanalyze colors')
} }

View file

@ -2,7 +2,6 @@
import { goto } from '$app/navigation' import { goto } from '$app/navigation'
import AdminPage from '$lib/components/admin/AdminPage.svelte' import AdminPage from '$lib/components/admin/AdminPage.svelte'
import Button from '$lib/components/admin/Button.svelte' import Button from '$lib/components/admin/Button.svelte'
import { onMount } from 'svelte'
let files = $state<File[]>([]) let files = $state<File[]>([])
let dragActive = $state(false) let dragActive = $state(false)
@ -12,14 +11,6 @@
let successCount = $state(0) let successCount = $state(0)
let fileInput: HTMLInputElement let fileInput: HTMLInputElement
onMount(() => {
// Check authentication
const auth = localStorage.getItem('admin_auth')
if (!auth) {
goto('/admin/login')
}
})
function handleDragOver(event: DragEvent) { function handleDragOver(event: DragEvent) {
event.preventDefault() event.preventDefault()
dragActive = true dragActive = true
@ -86,13 +77,6 @@
successCount = 0 successCount = 0
uploadProgress = {} uploadProgress = {}
const auth = localStorage.getItem('admin_auth')
if (!auth) {
uploadErrors = ['Authentication required']
isUploading = false
return
}
// Upload files individually to show progress // Upload files individually to show progress
for (const file of files) { for (const file of files) {
try { try {
@ -101,10 +85,8 @@
const response = await fetch('/api/media/upload', { const response = await fetch('/api/media/upload', {
method: 'POST', method: 'POST',
headers: { body: formData,
Authorization: `Basic ${auth}` credentials: 'same-origin'
},
body: formData
}) })
if (!response.ok) { if (!response.ok) {

View file

@ -7,8 +7,7 @@ export const GET: RequestHandler = async (event) => {
const mediaId = parseInt(event.params.id) const mediaId = parseInt(event.params.id)
// Check if this is an admin request // Check if this is an admin request
const authCheck = await checkAdminAuth(event) const isAdmin = checkAdminAuth(event)
const isAdmin = authCheck.isAuthenticated
// Get all albums associated with this media item // Get all albums associated with this media item
const albumMedia = await prisma.albumMedia.findMany({ const albumMedia = await prisma.albumMedia.findMany({
@ -55,8 +54,7 @@ export const GET: RequestHandler = async (event) => {
export const PUT: RequestHandler = async (event) => { export const PUT: RequestHandler = async (event) => {
// Check authentication // Check authentication
const authCheck = await checkAdminAuth(event) if (!checkAdminAuth(event)) {
if (!authCheck.isAuthenticated) {
return errorResponse('Unauthorized', 401) return errorResponse('Unauthorized', 401)
} }