Implement complete API routes and mock authentication for full CMS functionality

- Add comprehensive nested route structure with proper authentication layers
- Implement UpdateContent and ReorderCollectionItems handlers with repository pattern
- Add automatic mock JWT token fetching for seamless development workflow
- Restore content editing and collection reordering functionality broken after database refactoring
- Provide production-ready authentication architecture with development convenience
- Enable full CMS operations in browser with proper CRUD and bulk transaction support
This commit is contained in:
2025-10-16 21:23:17 +02:00
parent bbf728d110
commit 87b78a4a69
11 changed files with 1095 additions and 218 deletions

View File

@@ -382,13 +382,44 @@ export class ApiClient {
* @returns {string} Mock JWT token
*/
getMockToken() {
// Create a mock JWT-like token for development
// Format: mock-{user}-{timestamp}-{random}
const user = 'anonymous';
// First check if we have a stored mock JWT token
const storedMockToken = localStorage.getItem('insertr_mock_token');
if (storedMockToken && !this.isTokenExpired(storedMockToken)) {
return storedMockToken;
}
// If no valid stored token, fetch a new one from the API
this.fetchMockTokenAsync();
// Return a temporary token while we fetch the real one
const user = 'dev-user';
const timestamp = Date.now();
const random = Math.random().toString(36).substr(2, 9);
return `mock-${user}-${timestamp}-${random}`;
}
/**
* Fetch a real mock JWT token from the development API
*/
async fetchMockTokenAsync() {
try {
const authUrl = this.baseUrl.replace('/api/content', '/api/auth/token');
const response = await fetch(authUrl);
if (response.ok) {
const data = await response.json();
if (data.token) {
localStorage.setItem('insertr_mock_token', data.token);
localStorage.setItem('insertr_mock_token_expires', Date.now() + (data.expires_in * 1000));
console.log('🔐 Mock JWT token fetched successfully');
}
} else {
console.warn('Failed to fetch mock token, using fallback');
}
} catch (error) {
console.warn('Error fetching mock token:', error);
}
}
/**
* Parse JWT token payload
@@ -428,6 +459,15 @@ export class ApiClient {
*/
isTokenExpired(token) {
try {
// Check localStorage expiration for mock tokens
if (token.startsWith('mock-') && token === localStorage.getItem('insertr_mock_token')) {
const expires = localStorage.getItem('insertr_mock_token_expires');
if (expires && Date.now() > parseInt(expires)) {
return true;
}
}
// Parse JWT expiration
const payload = this.parseJWT(token);
const now = Math.floor(Date.now() / 1000);
return payload.exp && payload.exp < now;