OPEN-ISP v0.5 (pickle-lime) — rilis open-source perdana

Aplikasi billing & manajemen ISP (fiber optic) — PWA pelanggan, portal teknisi & kolektor,
admin panel lengkap, multi-vendor OLT, RADIUS, WhatsApp/Telegram, pembayaran QRIS.

Kredit & lisensi (ISC):
- Base kode & repo: alijayanet/billing-rtrw oleh Alijaya Net — terima kasih banyak
  atas base kode dan repo yang bermanfaat.
- Add-on: GoWA, LibreSpeed/OpenSpeedTest, Uptime Kuma, notification-forwarder.
- Dikembangkan menjadi OPEN-ISP oleh oxpoe — https://github.com/oxpoe/open-isp
This commit is contained in:
oxpoe committed 2026-10-09 05:51:21 +07:00
commit eaf05f2811
280 files changed
+123975

No files matched your search

+123
View File
@@ -0,0 +1,123 @@
/* Service Worker — Portal Pelanggan OPEN-ISP
Strategi: HTML & CSS/JS = network-first (selalu ambil terbaru saat online),
gambar & manifest & font = cache-first (jarang berubah).
Naikkan CACHE_NAME bila perlu purge (v4 → v5 → ...). */
const CACHE_NAME = 'customer-pwa-v7';
const PRECACHE_URLS = [
// Aset inti (network-first tapi disimpan untuk offline)
'/css/auth.css',
'/css/landing.css',
'/css/dashboard.css',
'/css/pages.css',
'/css/theme-toggle.css',
'/js/theme-toggle.js',
// Ikon & manifest PWA
'/img/icons/icon-192.png',
'/img/icons/icon-512.png',
'/img/icons/icon-maskable-192.png',
'/img/icons/icon-maskable-512.png',
'/img/icons/apple-touch-icon.png',
'/manifest.webmanifest',
'/manifest-landing.webmanifest',
// Halaman shell untuk fallback offline
'/offline.html',
'/customer/login',
'/customer/register'
];
self.addEventListener('install', (event) => {
self.skipWaiting();
event.waitUntil(
caches.open(CACHE_NAME).then((cache) =>
// Tambah satu-per-satu agar satu URL gagal tidak membatalkan semuanya
Promise.all(
PRECACHE_URLS.map((url) =>
cache.add(url).catch(() => null)
)
)
).catch(() => {})
);
});
self.addEventListener('activate', (event) => {
event.waitUntil(
Promise.all([
caches.keys().then((keys) =>
Promise.all(keys.map((k) => (k === CACHE_NAME ? null : caches.delete(k))))
),
self.clients.claim()
])
);
});
async function cacheFirst(request) {
const cached = await caches.match(request);
if (cached) return cached;
const res = await fetch(request);
const cache = await caches.open(CACHE_NAME);
if (res && res.ok) cache.put(request, res.clone()).catch(() => {});
return res;
}
async function networkFirst(request, fallbackUrl) {
try {
const res = await fetch(request, { cache: 'no-cache' });
const cache = await caches.open(CACHE_NAME);
if (res && res.ok) cache.put(request, res.clone()).catch(() => {});
return res;
} catch (e) {
const cached = await caches.match(request);
if (cached) return cached;
if (fallbackUrl) {
const fallback = await caches.match(fallbackUrl);
if (fallback) return fallback;
}
return new Response('Offline', {
status: 200,
headers: { 'Content-Type': 'text/plain; charset=utf-8' }
});
}
}
self.addEventListener('fetch', (event) => {
const req = event.request;
if (req.method !== 'GET') return;
const url = new URL(req.url);
if (url.origin !== self.location.origin) return;
const path = url.pathname;
// version.txt → selalu network (mekanisme deteksi update)
if (path === '/version.txt') return;
// Navigasi halaman pelanggan → network-first
if (req.mode === 'navigate') {
if (path.startsWith('/customer/')) event.respondWith(networkFirst(req, '/customer/login'));
else event.respondWith(networkFirst(req));
return;
}
// CSS & JS → network-first agar perubahan desain langsung terlihat
if (path.startsWith('/css/') || path.startsWith('/js/')) {
event.respondWith(networkFirst(req));
return;
}
// Gambar, ikon, manifest, font → cache-first
if (
path.startsWith('/img/') ||
path.startsWith('/fonts/') ||
path === '/manifest.webmanifest' ||
path === '/manifest-landing.webmanifest'
) {
event.respondWith(cacheFirst(req));
return;
}
event.respondWith(networkFirst(req));
});
self.addEventListener('message', (event) => {
if (event.data === 'SKIP_WAITING') self.skipWaiting();
});