refactor(admin): let session auth drive albums/media routes
This commit is contained in:
parent
e2949bff20
commit
6a0e9c2fdb
6 changed files with 58 additions and 115 deletions
|
|
@ -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'
|
||||||
|
|
|
||||||
|
|
@ -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')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue