Data4Autos-Shopify-Backend/freeAccessStore.js
MOHAN 35b3f98d5f feat: free-access whitelist + admin panel
- freeAccessStore.js: JSON-persisted whitelist of shops with optional
  expiry dates; isShopAllowed(), addShop(), removeShop(), listShops()
- routes/adminPanel.js: password-protected single-page admin dashboard
  served at /d4a-admin; cookie-based session auth (no extra deps);
  add / remove / list shops with expiry dates and notes
- server.js: mount /d4a-admin panel; expose GET /free-access/:shop
  public API for frontend loaders; import freeAccessStore

Credentials: d4a-admin / Data4autos@2026.
Migrates racewerksengg.myshopify.com from hardcode into the JSON store.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-11 13:19:06 +05:30

71 lines
1.9 KiB
JavaScript

// freeAccessStore.js — persistent whitelist of shops granted free access
const fs = require('fs');
const path = require('path');
const dataFile = path.resolve(__dirname, 'data', 'freeAccess.json');
const dataDir = path.dirname(dataFile);
if (!fs.existsSync(dataDir)) fs.mkdirSync(dataDir, { recursive: true });
if (!fs.existsSync(dataFile)) {
// seed with the shop that was previously hardcoded
fs.writeFileSync(dataFile, JSON.stringify({
"racewerksengg.myshopify.com": {
grantedAt: new Date().toISOString(),
expiresAt: null,
note: "Internal test shop (migrated from hardcode)"
}
}, null, 2), 'utf8');
}
function readStore() {
try { return JSON.parse(fs.readFileSync(dataFile, 'utf8')); }
catch { return {}; }
}
function saveStore(store) {
fs.writeFileSync(dataFile, JSON.stringify(store, null, 2), 'utf8');
}
function isShopAllowed(shop) {
if (!shop) return false;
const store = readStore();
const entry = store[shop.toLowerCase().trim()];
if (!entry) return false;
if (!entry.expiresAt) return true; // permanent grant
return new Date(entry.expiresAt) > new Date();
}
function addShop(shop, expiresAt, note = '') {
const store = readStore();
const key = shop.toLowerCase().trim();
store[key] = {
grantedAt: new Date().toISOString(),
expiresAt: expiresAt || null,
note: note || '',
};
saveStore(store);
return store[key];
}
function removeShop(shop) {
const store = readStore();
const key = shop.toLowerCase().trim();
delete store[key];
saveStore(store);
}
function listShops() {
const store = readStore();
const now = new Date();
return Object.entries(store).map(([shop, entry]) => ({
shop,
grantedAt: entry.grantedAt,
expiresAt: entry.expiresAt,
note: entry.note || '',
expired: entry.expiresAt ? new Date(entry.expiresAt) <= now : false,
permanent: !entry.expiresAt,
}));
}
module.exports = { isShopAllowed, addShop, removeShop, listShops };