nodebb-plugin-anti-account-sharing 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/library.js +61 -56
  2. package/package.json +1 -1
  3. package/plugin.json +17 -18
package/library.js CHANGED
@@ -8,76 +8,81 @@ const Plugin = {};
8
8
  // --- AYARLAR ---
9
9
  const MAX_DEVICES = 1; // Kaç bilgisayara izin verilsin?
10
10
 
11
- // Cihazın Mobil olup olmadığını anlayan fonksiyon
12
11
  function isMobile(req) {
13
- const ua = req.headers['user-agent'];
14
- return /Mobile|Android|iPhone|iPad|iPod/i.test(ua);
12
+ const ua = req?.headers?.['user-agent'] || '';
13
+ return /Mobile|Android|iPhone|iPad|iPod/i.test(ua);
15
14
  }
16
15
 
17
- Plugin.init = async function (params) {
18
- console.log(`[Anti-Share] Güvenlik Aktif (Limit: ${MAX_DEVICES} Bilgisayar) 🛡️`);
16
+ Plugin.init = async function () {
17
+ console.log(`[Anti-Share] Güvenlik Aktif (Limit: ${MAX_DEVICES} Bilgisayar) 🛡️`);
19
18
  };
20
19
 
21
- // 1. GİRİŞ YAPILDIĞINDA (Listeye Ekle)
20
+ // 1) Login olunca session'ı kaydet
22
21
  Plugin.recordSession = async function (data) {
23
- // Sadece Bilgisayar girişlerini takip ediyoruz
24
- if (!isMobile(data.req)) {
25
- if (data.uid && data.req.sessionID) {
26
- const key = `antishare:sessions:${data.uid}`;
27
-
28
- // 1. Yeni oturumu listenin SONUNA ekle
29
- await db.listAppend(key, data.req.sessionID);
30
-
31
- // 2. Listeyi kırp (Sadece son 5 taneyi tut)
32
- // (Eğer 6. kişi girerse, listenin başındaki 1. kişi silinir)
33
- await db.listTrim(key, -MAX_DEVICES, -1);
34
- }
35
- }
22
+ const req = data?.req;
23
+ const uid = data?.uid;
24
+
25
+ // req yoksa sessizce çık (bazı akışlarda gelemeyebiliyor)
26
+ if (!req || !uid || !req.sessionID) return;
27
+
28
+ // Mobil girişleri takip etmiyoruz
29
+ if (isMobile(req)) return;
30
+
31
+ const key = `antishare:sessions:${uid}`;
32
+
33
+ // Yeni oturumu sona ekle, sonra sadece son MAX_DEVICES kadarını tut
34
+ await db.listAppend(key, req.sessionID);
35
+ await db.listTrim(key, -MAX_DEVICES, -1);
36
36
  };
37
37
 
38
- // 2. HER SAYFA GEZİNTİSİNDE (Kontrol Et)
38
+ // 2) Her page + api isteğinde kontrol
39
39
  Plugin.checkSession = async function (data) {
40
- const req = data.req;
41
- const res = data.res;
40
+ const req = data?.req;
41
+ const res = data?.res;
42
+
43
+ if (!req || !res) return data;
44
+
45
+ // login değilse veya mobilse karışma
46
+ if (!req.uid || req.uid <= 0 || isMobile(req)) return data;
42
47
 
43
- // Giriş yapmamışsa veya Mobilden giriyorsa KARIŞMA
44
- if (!req.uid || req.uid <= 0 || isMobile(req)) {
45
- return data;
48
+ // admin ise karışma
49
+ const isAdmin = await user.isAdministrator(req.uid);
50
+ if (isAdmin) return data;
51
+
52
+ const key = `antishare:sessions:${req.uid}`;
53
+ const validSessions = await db.getListRange(key, 0, -1);
54
+
55
+ // liste boşsa (ilk login vs.) karışma
56
+ if (!Array.isArray(validSessions) || !validSessions.length) return data;
57
+
58
+ // sessionID yoksa karışma
59
+ if (!req.sessionID) return data;
60
+
61
+ if (!validSessions.includes(req.sessionID)) {
62
+ // Oturumu öldür
63
+ try { req.logout?.(); } catch (e) {}
64
+ if (req.session) {
65
+ try { req.session.destroy(() => {}); } catch (e) {}
46
66
  }
47
67
 
48
- const isAdmin = await user.isAdministrator(req.uid);
49
- if (isAdmin) return data;
50
-
51
- // --- BİLGİSAYAR KONTROLÜ ---
52
- const key = `antishare:sessions:${req.uid}`;
53
-
54
- // Veritabanındaki "Geçerli Oturum Listesi"ni çek
55
- const validSessions = await db.getListRange(key, 0, -1);
56
-
57
- // Eğer şu anki oturum ID'si, izin verilenler listesinde YOKSA -> AT!
58
- if (validSessions && !validSessions.includes(req.sessionID)) {
59
-
60
- // Oturumu Öldür
61
- req.logout();
62
- if (req.session) req.session.destroy();
63
-
64
- if (req.xhr || (req.headers.accept && req.headers.accept.indexOf('json') > -1)) {
65
- return res.status(401).json({
66
- error: 'session_terminated',
67
- message: 'Maksimum cihaz sınırına ulaşıldı.'
68
- });
69
- } else {
70
- return res.redirect('/login?error=session-conflict');
71
- }
68
+ const wantsJson =
69
+ req.xhr ||
70
+ (req.headers.accept && req.headers.accept.includes('json')) ||
71
+ req.originalUrl?.startsWith('/api/');
72
+
73
+ if (wantsJson) {
74
+ res.status(401).json({
75
+ error: 'session_terminated',
76
+ message: 'Maksimum cihaz sınırına ulaşıldı.',
77
+ });
78
+ return; // IMPORTANT: response bitti
72
79
  }
73
80
 
74
- return data;
75
- };
81
+ res.redirect('/login?error=session-conflict');
82
+ return; // IMPORTANT: response bitti
83
+ }
76
84
 
77
- // Client scriptini ekle
78
- Plugin.addScripts = async function (scripts) {
79
- scripts.push('plugins/nodebb-plugin-anti-account-sharing/static/security.js');
80
- return scripts;
85
+ return data;
81
86
  };
82
87
 
83
- module.exports = Plugin;
88
+ module.exports = Plugin;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-anti-account-sharing",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Prevents account sharing by enforcing a single active session policy for desktop devices.",
5
5
  "main": "library.js",
6
6
  "keywords": [
package/plugin.json CHANGED
@@ -1,19 +1,18 @@
1
1
  {
2
- "id": "nodebb-plugin-niki-antishare",
3
- "name": "Niki Anti-Share Security",
4
- "description": "Bilgisayar oturumlarını tekilleştirerek hesap paylaşımını engeller (Mobil hariç).",
5
- "url": "https://forum.ieu.app",
6
- "library": "./library.js",
7
- "hooks": [
8
- { "hook": "static:app.load", "method": "init" },
9
- { "hook": "action:user.loggedIn", "method": "recordSession" },
10
- { "hook": "filter:router.page", "method": "checkSession" },
11
- { "hook": "filter:scripts.get", "method": "addScripts" }
12
- ],
13
- "scripts": [
14
- "static/security.js"
15
- ],
16
- "staticDirs": {
17
- "static": "./static"
18
- }
19
- }
2
+ "id": "nodebb-plugin-anti-account-sharing",
3
+ "name": "Anti-Share Security",
4
+ "description": "Bilgisayar oturumlarını tekilleştirerek hesap paylaşımını engeller (Mobil hariç).",
5
+ "library": "./library.js",
6
+ "hooks": [
7
+ { "hook": "static:app.load", "method": "init" },
8
+ { "hook": "action:user.loggedIn", "method": "recordSession" },
9
+ { "hook": "filter:router.page", "method": "checkSession" },
10
+ { "hook": "filter:router.api", "method": "checkSession" }
11
+ ],
12
+ "scripts": [
13
+ "static/security.js"
14
+ ],
15
+ "staticDirs": {
16
+ "static": "./static"
17
+ }
18
+ }