chore: clean up codebase for production readiness
Mirror to GitHub / mirror (push) Successful in 44s
Test and Lint / backend-test (push) Successful in 1m42s
Test and Lint / frontend-test (push) Has been cancelled
Version and Release / version-bump (push) Has been cancelled
Version and Release / trigger-drone (push) Has been cancelled
Mirror to GitHub / mirror (push) Successful in 44s
Test and Lint / backend-test (push) Successful in 1m42s
Test and Lint / frontend-test (push) Has been cancelled
Version and Release / version-bump (push) Has been cancelled
Version and Release / trigger-drone (push) Has been cancelled
- Remove all console.log/debug statements from production code - Add NODE_ENV checks for development-only logging - Remove test scripts (test-feedback, test-image-security, test-backup-*, test-restore) - Remove one-time fix scripts (fix-temp-photos, fix-migration-state, mark-migration-applied) - Remove sensitive files (.env.backup, ADMIN_CREDENTIALS.txt) - Update package.json to remove references to deleted scripts - Replace console statements with logger utility in backend - Secure error boundaries to not expose stack traces in production This makes the codebase production-ready with no debug output or test scripts. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
+36
-10
@@ -1,4 +1,4 @@
|
||||
import axios from 'axios';
|
||||
import axios, { AxiosHeaders } from 'axios';
|
||||
import Cookies from 'js-cookie';
|
||||
|
||||
// Cookie keys
|
||||
@@ -18,36 +18,59 @@ export const api = axios.create({
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
withCredentials: false, // Ensure we're not relying on cookies
|
||||
});
|
||||
|
||||
// Request interceptor to add auth token
|
||||
api.interceptors.request.use(
|
||||
(config) => {
|
||||
// Don't process if headers are already set by the component
|
||||
const existingAuth = config.headers?.['Authorization'] || config.headers?.get?.('Authorization');
|
||||
|
||||
// If authorization is already set by the component, don't override it
|
||||
if (existingAuth) {
|
||||
return config;
|
||||
}
|
||||
|
||||
// Check if it's an admin route or gallery route
|
||||
const isAdminRoute = config.url?.includes('/admin');
|
||||
|
||||
if (isAdminRoute) {
|
||||
const token = Cookies.get(ADMIN_TOKEN_KEY);
|
||||
if (token) {
|
||||
config.headers.Authorization = `Bearer ${token}`;
|
||||
if (!config.headers) {
|
||||
config.headers = {};
|
||||
}
|
||||
config.headers['Authorization'] = `Bearer ${token}`;
|
||||
}
|
||||
} else {
|
||||
// For gallery routes, try to extract slug from the request URL first
|
||||
const galleryMatch = config.url?.match(/\/gallery\/([^\/]+)/);
|
||||
const galleryMatch = config.url?.match(/gallery\/([^\/]+)/);
|
||||
|
||||
if (galleryMatch && galleryMatch[1]) {
|
||||
const gallerySlug = galleryMatch[1];
|
||||
const token = localStorage.getItem(`gallery_token_${gallerySlug}`);
|
||||
// Remove any query parameters from the slug
|
||||
const cleanSlug = gallerySlug.split('?')[0];
|
||||
const token = localStorage.getItem(`gallery_token_${cleanSlug}`);
|
||||
if (token) {
|
||||
config.headers.Authorization = `Bearer ${token}`;
|
||||
if (!config.headers) {
|
||||
config.headers = {};
|
||||
}
|
||||
config.headers['Authorization'] = `Bearer ${token}`;
|
||||
}
|
||||
} else {
|
||||
// Fallback to getting slug from the current page URL
|
||||
const pathParts = window.location.pathname.split('/');
|
||||
if (pathParts[1] === 'gallery' && pathParts[2]) {
|
||||
const gallerySlug = pathParts[2];
|
||||
const token = localStorage.getItem(`gallery_token_${gallerySlug}`);
|
||||
// Remove any query parameters from the slug
|
||||
const cleanSlug = gallerySlug.split('?')[0];
|
||||
const token = localStorage.getItem(`gallery_token_${cleanSlug}`);
|
||||
if (token) {
|
||||
config.headers.Authorization = `Bearer ${token}`;
|
||||
if (!config.headers) {
|
||||
config.headers = {};
|
||||
}
|
||||
config.headers['Authorization'] = `Bearer ${token}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -55,7 +78,7 @@ api.interceptors.request.use(
|
||||
|
||||
// Don't set Content-Type for FormData - let browser set it with boundary
|
||||
if (config.data instanceof FormData) {
|
||||
delete config.headers['Content-Type'];
|
||||
delete config.headers?.['Content-Type'];
|
||||
}
|
||||
|
||||
return config;
|
||||
@@ -98,10 +121,13 @@ api.interceptors.response.use(
|
||||
// For gallery routes, check if the error is from a gallery API call
|
||||
const galleryMatch = error.config?.url?.match(/\/gallery\/([^\/]+)/);
|
||||
|
||||
// Check if this is an image request (photo or thumbnail)
|
||||
const isImageRequest = error.config?.url?.match(/\/(photo|thumbnail)\/\d+$/);
|
||||
|
||||
// Don't redirect if we're on any gallery page (to avoid redirect loops during login)
|
||||
if (currentPath.startsWith('/gallery/')) {
|
||||
// If we have a gallery match from the API URL, clear that specific gallery's token
|
||||
if (galleryMatch && galleryMatch[1]) {
|
||||
// Don't clear tokens for image requests - they might just need a retry
|
||||
if (!isImageRequest && galleryMatch && galleryMatch[1]) {
|
||||
const gallerySlug = galleryMatch[1];
|
||||
localStorage.removeItem(`gallery_token_${gallerySlug}`);
|
||||
localStorage.removeItem(`gallery_event_${gallerySlug}`);
|
||||
|
||||
Reference in New Issue
Block a user