nodebb-plugin-ezoic-infinite 1.7.36 → 1.7.38
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.
- package/library.js +71 -48
- package/package.json +1 -1
- package/plugin.json +5 -1
package/library.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const meta
|
|
3
|
+
const meta = require.main.require('./src/meta');
|
|
4
4
|
const groups = require.main.require('./src/groups');
|
|
5
|
-
const db
|
|
5
|
+
const db = require.main.require('./src/database');
|
|
6
6
|
|
|
7
7
|
const SETTINGS_KEY = 'ezoic-infinite';
|
|
8
8
|
const plugin = {};
|
|
9
9
|
|
|
10
|
+
// ── Helpers ────────────────────────────────────────────────────────────────
|
|
11
|
+
|
|
10
12
|
function normalizeExcludedGroups(value) {
|
|
11
13
|
if (!value) return [];
|
|
12
14
|
if (Array.isArray(value)) return value;
|
|
@@ -27,14 +29,16 @@ async function getAllGroups() {
|
|
|
27
29
|
}
|
|
28
30
|
const filtered = names.filter(name => !groups.isPrivilegeGroup(name));
|
|
29
31
|
const data = await groups.getGroupsData(filtered);
|
|
30
|
-
// Filter out nulls (groups deleted between the sorted-set read and getGroupsData)
|
|
31
32
|
const valid = data.filter(g => g && g.name);
|
|
32
33
|
valid.sort((a, b) => String(a.name).localeCompare(String(b.name), undefined, { sensitivity: 'base' }));
|
|
33
34
|
return valid;
|
|
34
35
|
}
|
|
35
|
-
|
|
36
|
+
|
|
37
|
+
// ── Settings cache (30s TTL) ────────────────────────────────────────────────
|
|
38
|
+
|
|
39
|
+
let _settingsCache = null;
|
|
36
40
|
let _settingsCacheAt = 0;
|
|
37
|
-
const SETTINGS_TTL
|
|
41
|
+
const SETTINGS_TTL = 30_000;
|
|
38
42
|
|
|
39
43
|
async function getSettings() {
|
|
40
44
|
const now = Date.now();
|
|
@@ -42,25 +46,19 @@ async function getSettings() {
|
|
|
42
46
|
const s = await meta.settings.get(SETTINGS_KEY);
|
|
43
47
|
_settingsCacheAt = Date.now();
|
|
44
48
|
_settingsCache = {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
// Home/categories list ads (between categories on / or /categories)
|
|
52
|
-
enableCategoryAds: parseBool(s.enableCategoryAds, false),
|
|
53
|
-
showFirstCategoryAd: parseBool(s.showFirstCategoryAd, false),
|
|
49
|
+
enableBetweenAds: parseBool(s.enableBetweenAds, true),
|
|
50
|
+
showFirstTopicAd: parseBool(s.showFirstTopicAd, false),
|
|
51
|
+
placeholderIds: (s.placeholderIds || '').trim(),
|
|
52
|
+
intervalPosts: Math.max(1, parseInt(s.intervalPosts, 10) || 6),
|
|
53
|
+
enableCategoryAds: parseBool(s.enableCategoryAds, false),
|
|
54
|
+
showFirstCategoryAd: parseBool(s.showFirstCategoryAd, false),
|
|
54
55
|
categoryPlaceholderIds: (s.categoryPlaceholderIds || '').trim(),
|
|
55
|
-
intervalCategories:
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
messageIntervalPosts: Math.max(1, parseInt(s.messageIntervalPosts, 10) || 3),
|
|
62
|
-
|
|
63
|
-
excludedGroups: normalizeExcludedGroups(s.excludedGroups),
|
|
56
|
+
intervalCategories: Math.max(1, parseInt(s.intervalCategories, 10) || 4),
|
|
57
|
+
enableMessageAds: parseBool(s.enableMessageAds, false),
|
|
58
|
+
showFirstMessageAd: parseBool(s.showFirstMessageAd, false),
|
|
59
|
+
messagePlaceholderIds: (s.messagePlaceholderIds || '').trim(),
|
|
60
|
+
messageIntervalPosts: Math.max(1, parseInt(s.messageIntervalPosts, 10) || 3),
|
|
61
|
+
excludedGroups: normalizeExcludedGroups(s.excludedGroups),
|
|
64
62
|
};
|
|
65
63
|
return _settingsCache;
|
|
66
64
|
}
|
|
@@ -71,58 +69,83 @@ async function isUserExcluded(uid, excludedGroups) {
|
|
|
71
69
|
return (userGroups[0] || []).some(g => excludedGroups.includes(g.name));
|
|
72
70
|
}
|
|
73
71
|
|
|
72
|
+
// ── Scripts Ezoic ──────────────────────────────────────────────────────────
|
|
73
|
+
|
|
74
|
+
const EZOIC_SCRIPTS = `<script data-cfasync="false" src="https://cmp.gatekeeperconsent.com/min.js"></script>
|
|
75
|
+
<script data-cfasync="false" src="https://the.gatekeeperconsent.com/cmp.min.js"></script>
|
|
76
|
+
<script async src="//www.ezojs.com/ezoic/sa.min.js"></script>
|
|
77
|
+
<script>
|
|
78
|
+
window.ezstandalone = window.ezstandalone || {};
|
|
79
|
+
ezstandalone.cmd = ezstandalone.cmd || [];
|
|
80
|
+
</script>`;
|
|
81
|
+
|
|
82
|
+
// ── Hooks ──────────────────────────────────────────────────────────────────
|
|
83
|
+
|
|
74
84
|
plugin.onSettingsSet = function (data) {
|
|
75
|
-
|
|
76
|
-
if (data && data.hash === SETTINGS_KEY) {
|
|
77
|
-
_settingsCache = null;
|
|
78
|
-
}
|
|
85
|
+
if (data && data.hash === SETTINGS_KEY) _settingsCache = null;
|
|
79
86
|
};
|
|
80
87
|
|
|
81
88
|
plugin.addAdminNavigation = async (header) => {
|
|
82
89
|
header.plugins = header.plugins || [];
|
|
83
|
-
header.plugins.push({
|
|
84
|
-
route: '/plugins/ezoic-infinite',
|
|
85
|
-
icon: 'fa-ad',
|
|
86
|
-
name: 'Ezoic Infinite Ads'
|
|
87
|
-
});
|
|
90
|
+
header.plugins.push({ route: '/plugins/ezoic-infinite', icon: 'fa-ad', name: 'Ezoic Infinite Ads' });
|
|
88
91
|
return header;
|
|
89
92
|
};
|
|
90
93
|
|
|
94
|
+
/**
|
|
95
|
+
* Injecte les scripts Ezoic via res.locals.postHeader.
|
|
96
|
+
*
|
|
97
|
+
* NodeBB v4 insère res.locals.postHeader directement après le header rendu
|
|
98
|
+
* (src/middleware/render.js) : `results.header + (res.locals.postHeader || '')`
|
|
99
|
+
* C'est le point d'injection natif pour du HTML arbitraire post-<head>.
|
|
100
|
+
*
|
|
101
|
+
* Le hook filter:middleware.buildHeader expose data.locals = res.locals,
|
|
102
|
+
* et est appelé avant le rendu de chaque page non-API.
|
|
103
|
+
*/
|
|
104
|
+
plugin.injectEzoicScripts = async (data) => {
|
|
105
|
+
try {
|
|
106
|
+
const settings = await getSettings();
|
|
107
|
+
const uid = data.req?.uid ?? 0;
|
|
108
|
+
const excluded = await isUserExcluded(uid, settings.excludedGroups);
|
|
109
|
+
if (!excluded) {
|
|
110
|
+
data.locals.postHeader = (data.locals.postHeader || '') + EZOIC_SCRIPTS;
|
|
111
|
+
}
|
|
112
|
+
} catch (_) {}
|
|
113
|
+
return data;
|
|
114
|
+
};
|
|
115
|
+
|
|
91
116
|
plugin.init = async ({ router, middleware }) => {
|
|
92
117
|
async function render(req, res) {
|
|
93
|
-
const settings
|
|
118
|
+
const settings = await getSettings();
|
|
94
119
|
const allGroups = await getAllGroups();
|
|
95
|
-
|
|
96
120
|
res.render('admin/plugins/ezoic-infinite', {
|
|
97
121
|
title: 'Ezoic Infinite Ads',
|
|
98
122
|
...settings,
|
|
99
123
|
enableBetweenAds_checked: settings.enableBetweenAds ? 'checked' : '',
|
|
100
|
-
enableMessageAds_checked:
|
|
124
|
+
enableMessageAds_checked: settings.enableMessageAds ? 'checked' : '',
|
|
101
125
|
allGroups,
|
|
102
126
|
});
|
|
103
127
|
}
|
|
104
128
|
|
|
105
|
-
router.get('/admin/plugins/ezoic-infinite',
|
|
129
|
+
router.get('/admin/plugins/ezoic-infinite', middleware.admin.buildHeader, render);
|
|
106
130
|
router.get('/api/admin/plugins/ezoic-infinite', render);
|
|
107
131
|
|
|
108
132
|
router.get('/api/plugins/ezoic-infinite/config', async (req, res) => {
|
|
109
133
|
const settings = await getSettings();
|
|
110
134
|
const excluded = await isUserExcluded(req.uid, settings.excludedGroups);
|
|
111
|
-
|
|
112
135
|
res.json({
|
|
113
136
|
excluded,
|
|
114
|
-
enableBetweenAds:
|
|
115
|
-
showFirstTopicAd:
|
|
116
|
-
placeholderIds:
|
|
117
|
-
intervalPosts:
|
|
118
|
-
enableCategoryAds:
|
|
119
|
-
showFirstCategoryAd:
|
|
137
|
+
enableBetweenAds: settings.enableBetweenAds,
|
|
138
|
+
showFirstTopicAd: settings.showFirstTopicAd,
|
|
139
|
+
placeholderIds: settings.placeholderIds,
|
|
140
|
+
intervalPosts: settings.intervalPosts,
|
|
141
|
+
enableCategoryAds: settings.enableCategoryAds,
|
|
142
|
+
showFirstCategoryAd: settings.showFirstCategoryAd,
|
|
120
143
|
categoryPlaceholderIds: settings.categoryPlaceholderIds,
|
|
121
|
-
intervalCategories:
|
|
122
|
-
enableMessageAds:
|
|
123
|
-
showFirstMessageAd:
|
|
124
|
-
messagePlaceholderIds:
|
|
125
|
-
messageIntervalPosts:
|
|
144
|
+
intervalCategories: settings.intervalCategories,
|
|
145
|
+
enableMessageAds: settings.enableMessageAds,
|
|
146
|
+
showFirstMessageAd: settings.showFirstMessageAd,
|
|
147
|
+
messagePlaceholderIds: settings.messagePlaceholderIds,
|
|
148
|
+
messageIntervalPosts: settings.messageIntervalPosts,
|
|
126
149
|
});
|
|
127
150
|
});
|
|
128
151
|
};
|
package/package.json
CHANGED
package/plugin.json
CHANGED
|
@@ -15,6 +15,10 @@
|
|
|
15
15
|
{
|
|
16
16
|
"hook": "action:settings.set",
|
|
17
17
|
"method": "onSettingsSet"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"hook": "filter:middleware.buildHeader",
|
|
21
|
+
"method": "injectEzoicScripts"
|
|
18
22
|
}
|
|
19
23
|
],
|
|
20
24
|
"staticDirs": {
|
|
@@ -30,4 +34,4 @@
|
|
|
30
34
|
"css": [
|
|
31
35
|
"public/style.css"
|
|
32
36
|
]
|
|
33
|
-
}
|
|
37
|
+
}
|