f25987e553
Root cause: localStorage keys 'oxicloud_recent_files' and
'oxicloud_favorites' were global — shared across all users on the same
browser. When user A logged out and user B logged in, user B could see
(and access) user A's recent files and favorites.
Fixes applied:
recent.js:
- Storage key now user-specific: 'oxicloud_recent_files_{username}'
- getStorageKey() derives key from current user in localStorage
- migrateFromLegacyKey() moves data from old global key on init
- Legacy global key is always removed after migration
favorites.js:
- Same pattern: 'oxicloud_favorites_{username}'
- getStorageKey() + migrateFromLegacyKey() added
auth.js (logout):
- Clears user-specific recent and favorites keys before removing
user data, plus removes any legacy global keys
Bumps service worker cache to v13.
101 lines
3.0 KiB
JavaScript
101 lines
3.0 KiB
JavaScript
// OxiCloud Service Worker
|
|
const CACHE_NAME = 'oxicloud-cache-v13';
|
|
const ASSETS_TO_CACHE = [
|
|
'/',
|
|
'/index.html',
|
|
'/js/i18n.js',
|
|
'/js/languageSelector.js',
|
|
'/js/notifications.js',
|
|
'/locales/en.json',
|
|
'/locales/es.json',
|
|
'/locales/fa.json',
|
|
'/locales/de.json',
|
|
'/favicon.ico',
|
|
'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css',
|
|
'https://cdn.jsdelivr.net/npm/alpinejs@3.12.3/dist/cdn.min.js'
|
|
];
|
|
|
|
// Install event - cache assets
|
|
self.addEventListener('install', event => {
|
|
event.waitUntil(
|
|
caches.open(CACHE_NAME)
|
|
.then(cache => {
|
|
console.log('Cache opened');
|
|
return cache.addAll(ASSETS_TO_CACHE);
|
|
})
|
|
.then(() => self.skipWaiting()) // Activate immediately
|
|
);
|
|
});
|
|
|
|
// Activate event - clean old caches
|
|
self.addEventListener('activate', event => {
|
|
event.waitUntil(
|
|
caches.keys().then(cacheNames => {
|
|
return Promise.all(
|
|
cacheNames.filter(cacheName => {
|
|
return cacheName !== CACHE_NAME;
|
|
}).map(cacheName => {
|
|
return caches.delete(cacheName);
|
|
})
|
|
);
|
|
}).then(() => self.clients.claim()) // Take control of clients
|
|
);
|
|
});
|
|
|
|
// Fetch event - serve from cache, update cache from network
|
|
self.addEventListener('fetch', event => {
|
|
// Don't intercept API requests - let them go straight to the network
|
|
if (event.request.url.includes('/api/')) {
|
|
return;
|
|
}
|
|
|
|
event.respondWith(
|
|
caches.match(event.request)
|
|
.then(response => {
|
|
// Cache hit - return the response from the cached version
|
|
if (response) {
|
|
// For non-core assets, still fetch from network for updates
|
|
if (!ASSETS_TO_CACHE.includes(new URL(event.request.url).pathname)) {
|
|
fetch(event.request).then(networkResponse => {
|
|
if (networkResponse && networkResponse.status === 200) {
|
|
const clonedResponse = networkResponse.clone();
|
|
caches.open(CACHE_NAME).then(cache => {
|
|
cache.put(event.request, clonedResponse);
|
|
});
|
|
}
|
|
}).catch(() => {
|
|
// Ignore network fetch errors - we already have a cached version
|
|
});
|
|
}
|
|
return response;
|
|
}
|
|
|
|
// Not in cache - get from network and add to cache
|
|
return fetch(event.request).then(response => {
|
|
if (!response || response.status !== 200 || response.type !== 'basic') {
|
|
return response;
|
|
}
|
|
|
|
// Clone the response as it's a stream and can only be consumed once
|
|
const responseToCache = response.clone();
|
|
|
|
caches.open(CACHE_NAME).then(cache => {
|
|
cache.put(event.request, responseToCache);
|
|
});
|
|
|
|
return response;
|
|
});
|
|
})
|
|
);
|
|
});
|
|
|
|
// Background sync for failed requests
|
|
self.addEventListener('sync', event => {
|
|
if (event.tag === 'oxicloud-sync') {
|
|
event.waitUntil(
|
|
// Implement background sync for pending file operations
|
|
Promise.resolve() // Placeholder for actual implementation
|
|
);
|
|
}
|
|
});
|