nodebb-plugin-calendar-onekite 11.2.0 → 11.2.2
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/lib/admin.js +24 -5
- package/lib/helloassoWebhook.js +22 -12
- package/library.js +11 -5
- package/package.json +1 -1
- package/public/client.js +1 -1
package/lib/admin.js
CHANGED
|
@@ -19,12 +19,33 @@ function formatFR(tsOrIso) {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
async function sendEmail(template, toEmail, subject, data) {
|
|
22
|
-
|
|
22
|
+
// Prefer sending by uid (NodeBB core expects uid in various places)
|
|
23
|
+
const uid = data && Number.isInteger(data.uid) ? data.uid : null;
|
|
24
|
+
if (!toEmail && !uid) return;
|
|
23
25
|
|
|
24
26
|
const settings = await meta.settings.get('calendar-onekite').catch(() => ({}));
|
|
25
27
|
const lang = (settings && settings.defaultLang) || (meta && meta.config && meta.config.defaultLang) || 'fr';
|
|
26
28
|
const params = Object.assign({}, data || {}, subject ? { subject } : {});
|
|
27
29
|
|
|
30
|
+
// If we have a uid, use the native uid-based sender first.
|
|
31
|
+
try {
|
|
32
|
+
if (uid && typeof emailer.send === 'function') {
|
|
33
|
+
// NodeBB: send(template, uid, params)
|
|
34
|
+
if (emailer.send.length >= 3) {
|
|
35
|
+
await emailer.send(template, uid, params);
|
|
36
|
+
} else {
|
|
37
|
+
await emailer.send(template, uid, params);
|
|
38
|
+
}
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
} catch (err) {
|
|
42
|
+
console.warn('[calendar-onekite] Failed to send email', {
|
|
43
|
+
template,
|
|
44
|
+
toEmail,
|
|
45
|
+
err: err && err.message ? err.message : String(err),
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
28
49
|
try {
|
|
29
50
|
if (typeof emailer.sendToEmail === 'function') {
|
|
30
51
|
// NodeBB: sendToEmail(template, email, language, params)
|
|
@@ -36,10 +57,6 @@ async function sendEmail(template, toEmail, subject, data) {
|
|
|
36
57
|
}
|
|
37
58
|
return;
|
|
38
59
|
}
|
|
39
|
-
if (typeof emailer.send === 'function') {
|
|
40
|
-
// Fallback: send(template, uid, params) - not usable without uid
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
60
|
} catch (err) {
|
|
44
61
|
console.warn('[calendar-onekite] Failed to send email', {
|
|
45
62
|
template,
|
|
@@ -184,6 +201,7 @@ admin.approveReservation = async function (req, res) {
|
|
|
184
201
|
? `https://www.openstreetmap.org/?mlat=${encodeURIComponent(String(latNum))}&mlon=${encodeURIComponent(String(lonNum))}#map=18/${encodeURIComponent(String(latNum))}/${encodeURIComponent(String(lonNum))}`
|
|
185
202
|
: '';
|
|
186
203
|
await sendEmail('calendar-onekite_approved', requester.email, 'Location matériel - Réservation validée', {
|
|
204
|
+
uid: parseInt(r.uid, 10),
|
|
187
205
|
username: requester.username,
|
|
188
206
|
itemName: (Array.isArray(r.itemNames) ? r.itemNames.join(', ') : (r.itemName || '')),
|
|
189
207
|
itemNames: (Array.isArray(r.itemNames) ? r.itemNames : (r.itemName ? [r.itemName] : [])),
|
|
@@ -216,6 +234,7 @@ admin.refuseReservation = async function (req, res) {
|
|
|
216
234
|
const requester = await user.getUserFields(r.uid, ['username', 'email']);
|
|
217
235
|
if (requester && requester.email) {
|
|
218
236
|
await sendEmail('calendar-onekite_refused', requester.email, 'Location matériel - Réservation refusée', {
|
|
237
|
+
uid: parseInt(r.uid, 10),
|
|
219
238
|
username: requester.username,
|
|
220
239
|
itemName: r.itemName,
|
|
221
240
|
start: formatFR(r.start),
|
package/lib/helloassoWebhook.js
CHANGED
|
@@ -24,7 +24,8 @@ const SETTINGS_KEY = 'calendar-onekite';
|
|
|
24
24
|
const PROCESSED_KEY = 'calendar-onekite:helloasso:processedPayments';
|
|
25
25
|
|
|
26
26
|
async function sendEmail(template, toEmail, subject, data) {
|
|
27
|
-
|
|
27
|
+
const uidFromData = data && Number.isInteger(data.uid) ? data.uid : null;
|
|
28
|
+
if (!toEmail && !uidFromData) return;
|
|
28
29
|
try {
|
|
29
30
|
const emailer = require.main.require('./src/emailer');
|
|
30
31
|
// NodeBB core signature is typically:
|
|
@@ -33,6 +34,23 @@ async function sendEmail(template, toEmail, subject, data) {
|
|
|
33
34
|
const language = (meta && meta.config && (meta.config.defaultLang || meta.config.defaultLanguage)) || 'fr';
|
|
34
35
|
const params = Object.assign({}, data || {}, subject ? { subject } : {});
|
|
35
36
|
|
|
37
|
+
// In NodeBB 4.x, various email flows expect a uid to be present.
|
|
38
|
+
// If we have it, always prefer the uid-based sender.
|
|
39
|
+
let uid = uidFromData;
|
|
40
|
+
if (!uid && toEmail && typeof user.getUidByEmail === 'function') {
|
|
41
|
+
try {
|
|
42
|
+
uid = await user.getUidByEmail(toEmail);
|
|
43
|
+
if (uid && typeof uid === 'string') uid = parseInt(uid, 10);
|
|
44
|
+
} catch (e) {
|
|
45
|
+
uid = null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (uid && typeof emailer.send === 'function') {
|
|
49
|
+
// NodeBB: send(template, uid, params)
|
|
50
|
+
await emailer.send(template, uid, params);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
36
54
|
if (typeof emailer.sendToEmail === 'function') {
|
|
37
55
|
// Prefer the canonical signature.
|
|
38
56
|
// If a fork uses a shorter signature, we'll still try passing params as 3rd arg.
|
|
@@ -44,17 +62,8 @@ async function sendEmail(template, toEmail, subject, data) {
|
|
|
44
62
|
return;
|
|
45
63
|
}
|
|
46
64
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
await emailer.send(template, toEmail, language, params);
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
if (emailer.send.length === 3) {
|
|
53
|
-
await emailer.send(template, toEmail, params);
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
await emailer.send(template, toEmail, language, params);
|
|
57
|
-
}
|
|
65
|
+
// Do not call emailer.send with an email address (it expects uid). If we reach here,
|
|
66
|
+
// fall back to sendToEmail only.
|
|
58
67
|
} catch (err) {
|
|
59
68
|
// eslint-disable-next-line no-console
|
|
60
69
|
console.warn('[calendar-onekite] Failed to send email (webhook)', { template, toEmail, err: String(err && err.message || err) });
|
|
@@ -345,6 +354,7 @@ async function handler(req, res, next) {
|
|
|
345
354
|
const requester = await user.getUserFields(r.uid, ['username', 'email']);
|
|
346
355
|
if (requester && requester.email) {
|
|
347
356
|
await sendEmail('calendar-onekite_paid', requester.email, 'Location matériel - Paiement reçu', {
|
|
357
|
+
uid: parseInt(r.uid, 10),
|
|
348
358
|
username: requester.username,
|
|
349
359
|
itemName: (Array.isArray(r.itemNames) ? r.itemNames.join(', ') : (r.itemName || '')),
|
|
350
360
|
itemNames: (Array.isArray(r.itemNames) ? r.itemNames : (r.itemName ? [r.itemName] : [])),
|
package/library.js
CHANGED
|
@@ -24,15 +24,18 @@ Plugin.init = async function (params) {
|
|
|
24
24
|
|
|
25
25
|
// Build middleware arrays safely and always spread them into Express route methods.
|
|
26
26
|
// Express will throw if any callback is undefined, so we filter strictly.
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
// Auth middlewares differ slightly depending on NodeBB configuration.
|
|
28
|
+
// In v4, some installs rely on middleware.authenticate rather than exposeUid.
|
|
29
|
+
const baseExpose = mw(middleware && (middleware.authenticate || middleware.exposeUid));
|
|
30
|
+
const publicExpose = baseExpose;
|
|
31
|
+
const publicAuth = mw(middleware && (middleware.authenticate || middleware.exposeUid), middleware && middleware.ensureLoggedIn);
|
|
29
32
|
|
|
30
33
|
// Robust admin guard: avoid middleware.admin.checkPrivileges() signature differences
|
|
31
34
|
// across NodeBB versions. We treat membership in the 'administrators' group as admin.
|
|
32
35
|
const Groups = require.main.require('./src/groups');
|
|
33
36
|
async function adminOnly(req, res, next) {
|
|
34
37
|
try {
|
|
35
|
-
const uid = req.uid;
|
|
38
|
+
const uid = req.uid || (req.user && req.user.uid) || (req.session && req.session.uid);
|
|
36
39
|
if (!uid) {
|
|
37
40
|
return res.status(401).json({ status: { code: 'not-authorized', message: 'Not logged in' } });
|
|
38
41
|
}
|
|
@@ -45,7 +48,11 @@ Plugin.init = async function (params) {
|
|
|
45
48
|
return next(err);
|
|
46
49
|
}
|
|
47
50
|
}
|
|
48
|
-
const adminMws = mw(
|
|
51
|
+
const adminMws = mw(
|
|
52
|
+
middleware && (middleware.authenticate || middleware.exposeUid),
|
|
53
|
+
middleware && middleware.ensureLoggedIn,
|
|
54
|
+
adminOnly
|
|
55
|
+
);
|
|
49
56
|
|
|
50
57
|
// Page routes (HTML)
|
|
51
58
|
// IMPORTANT: pass an ARRAY for middlewares (even if empty), otherwise
|
|
@@ -63,7 +70,6 @@ Plugin.init = async function (params) {
|
|
|
63
70
|
router.put('/api/v3/plugins/calendar-onekite/reservations/:rid/refuse', ...publicExpose, api.refuseReservation);
|
|
64
71
|
router.put('/api/v3/plugins/calendar-onekite/reservations/:rid/cancel', ...publicExpose, api.cancelReservation);
|
|
65
72
|
|
|
66
|
-
router.get('/api/v3/plugins/calendar-onekite/special-events', ...publicExpose, api.getSpecialEvents);
|
|
67
73
|
router.post('/api/v3/plugins/calendar-onekite/special-events', ...publicExpose, api.createSpecialEvent);
|
|
68
74
|
router.delete('/api/v3/plugins/calendar-onekite/special-events/:eid', ...publicExpose, api.deleteSpecialEvent);
|
|
69
75
|
|
package/package.json
CHANGED
package/public/client.js
CHANGED
|
@@ -849,7 +849,7 @@ function toDatetimeLocalValue(date) {
|
|
|
849
849
|
showAlert('error', 'Impossible : au moins un matériel est déjà réservé ou en attente sur cette période.');
|
|
850
850
|
} else {
|
|
851
851
|
const msg = payload && (payload.message || payload.error || payload.msg) ? String(payload.message || payload.error || payload.msg) : '';
|
|
852
|
-
showAlert('error', msg || ((e && (e.status === 401 || e.status === 403)) ? '
|
|
852
|
+
showAlert('error', msg || ((e && (e.status === 401 || e.status === 403)) ? 'Vous devez être adhérent Onekite' : 'Erreur lors de la création de la demande.'));
|
|
853
853
|
}
|
|
854
854
|
calendar.unselect();
|
|
855
855
|
isDialogOpen = false;
|