payload-plugin-newsletter 0.17.1 → 0.17.3
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/CHANGELOG.md +25 -0
- package/dist/collections.cjs +432 -62
- package/dist/collections.cjs.map +1 -1
- package/dist/collections.js +432 -62
- package/dist/collections.js.map +1 -1
- package/dist/index.cjs +1017 -1019
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1057 -1059
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/collections.js
CHANGED
|
@@ -9,9 +9,19 @@ var __export = (target, all) => {
|
|
|
9
9
|
};
|
|
10
10
|
|
|
11
11
|
// src/types/newsletter.ts
|
|
12
|
+
var NewsletterProviderError;
|
|
12
13
|
var init_newsletter = __esm({
|
|
13
14
|
"src/types/newsletter.ts"() {
|
|
14
15
|
"use strict";
|
|
16
|
+
NewsletterProviderError = class extends Error {
|
|
17
|
+
constructor(message, code, provider, details) {
|
|
18
|
+
super(message);
|
|
19
|
+
this.code = code;
|
|
20
|
+
this.provider = provider;
|
|
21
|
+
this.details = details;
|
|
22
|
+
this.name = "NewsletterProviderError";
|
|
23
|
+
}
|
|
24
|
+
};
|
|
15
25
|
}
|
|
16
26
|
});
|
|
17
27
|
|
|
@@ -1228,12 +1238,427 @@ async function getBroadcastConfig(req, pluginConfig) {
|
|
|
1228
1238
|
}
|
|
1229
1239
|
}
|
|
1230
1240
|
|
|
1241
|
+
// src/endpoints/broadcasts/send.ts
|
|
1242
|
+
init_types();
|
|
1243
|
+
|
|
1244
|
+
// src/utils/access.ts
|
|
1245
|
+
var isAdmin = (user, config) => {
|
|
1246
|
+
if (!user || user.collection !== "users") {
|
|
1247
|
+
return false;
|
|
1248
|
+
}
|
|
1249
|
+
if (config?.access?.isAdmin) {
|
|
1250
|
+
return config.access.isAdmin(user);
|
|
1251
|
+
}
|
|
1252
|
+
if (user.roles?.includes("admin")) {
|
|
1253
|
+
return true;
|
|
1254
|
+
}
|
|
1255
|
+
if (user.isAdmin === true) {
|
|
1256
|
+
return true;
|
|
1257
|
+
}
|
|
1258
|
+
if (user.role === "admin") {
|
|
1259
|
+
return true;
|
|
1260
|
+
}
|
|
1261
|
+
if (user.admin === true) {
|
|
1262
|
+
return true;
|
|
1263
|
+
}
|
|
1264
|
+
return false;
|
|
1265
|
+
};
|
|
1266
|
+
var adminOnly = (config) => ({ req }) => {
|
|
1267
|
+
const user = req.user;
|
|
1268
|
+
return isAdmin(user, config);
|
|
1269
|
+
};
|
|
1270
|
+
var adminOrSelf = (config) => ({ req, id }) => {
|
|
1271
|
+
const user = req.user;
|
|
1272
|
+
if (!user) {
|
|
1273
|
+
if (!id) {
|
|
1274
|
+
return {
|
|
1275
|
+
id: {
|
|
1276
|
+
equals: "unauthorized-no-access"
|
|
1277
|
+
}
|
|
1278
|
+
};
|
|
1279
|
+
}
|
|
1280
|
+
return false;
|
|
1281
|
+
}
|
|
1282
|
+
if (isAdmin(user, config)) {
|
|
1283
|
+
return true;
|
|
1284
|
+
}
|
|
1285
|
+
if (user.collection === "subscribers") {
|
|
1286
|
+
if (!id) {
|
|
1287
|
+
return {
|
|
1288
|
+
id: {
|
|
1289
|
+
equals: user.id
|
|
1290
|
+
}
|
|
1291
|
+
};
|
|
1292
|
+
}
|
|
1293
|
+
return id === user.id;
|
|
1294
|
+
}
|
|
1295
|
+
if (!id) {
|
|
1296
|
+
return {
|
|
1297
|
+
id: {
|
|
1298
|
+
equals: "unauthorized-no-access"
|
|
1299
|
+
}
|
|
1300
|
+
};
|
|
1301
|
+
}
|
|
1302
|
+
return false;
|
|
1303
|
+
};
|
|
1304
|
+
|
|
1305
|
+
// src/utils/auth.ts
|
|
1306
|
+
async function getAuthenticatedUser(req) {
|
|
1307
|
+
try {
|
|
1308
|
+
const me = await req.payload.find({
|
|
1309
|
+
collection: "users",
|
|
1310
|
+
where: {
|
|
1311
|
+
id: {
|
|
1312
|
+
equals: "me"
|
|
1313
|
+
// Special value in Payload to get current user
|
|
1314
|
+
}
|
|
1315
|
+
},
|
|
1316
|
+
limit: 1,
|
|
1317
|
+
depth: 0
|
|
1318
|
+
});
|
|
1319
|
+
return me.docs[0] || null;
|
|
1320
|
+
} catch {
|
|
1321
|
+
return null;
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
async function requireAdmin(req, config) {
|
|
1325
|
+
const user = await getAuthenticatedUser(req);
|
|
1326
|
+
if (!user) {
|
|
1327
|
+
return {
|
|
1328
|
+
authorized: false,
|
|
1329
|
+
error: "Authentication required"
|
|
1330
|
+
};
|
|
1331
|
+
}
|
|
1332
|
+
if (!isAdmin(user, config)) {
|
|
1333
|
+
return {
|
|
1334
|
+
authorized: false,
|
|
1335
|
+
error: "Admin access required"
|
|
1336
|
+
};
|
|
1337
|
+
}
|
|
1338
|
+
return {
|
|
1339
|
+
authorized: true,
|
|
1340
|
+
user
|
|
1341
|
+
};
|
|
1342
|
+
}
|
|
1343
|
+
|
|
1344
|
+
// src/endpoints/broadcasts/send.ts
|
|
1345
|
+
var createSendBroadcastEndpoint = (config, collectionSlug) => {
|
|
1346
|
+
return {
|
|
1347
|
+
path: "/:id/send",
|
|
1348
|
+
method: "post",
|
|
1349
|
+
handler: async (req) => {
|
|
1350
|
+
try {
|
|
1351
|
+
const auth = await requireAdmin(req, config);
|
|
1352
|
+
if (!auth.authorized) {
|
|
1353
|
+
return Response.json({
|
|
1354
|
+
success: false,
|
|
1355
|
+
error: auth.error
|
|
1356
|
+
}, { status: 401 });
|
|
1357
|
+
}
|
|
1358
|
+
if (!config.features?.newsletterManagement?.enabled) {
|
|
1359
|
+
return Response.json({
|
|
1360
|
+
success: false,
|
|
1361
|
+
error: "Broadcast management is not enabled"
|
|
1362
|
+
}, { status: 400 });
|
|
1363
|
+
}
|
|
1364
|
+
const url = new URL(req.url || "", `http://localhost`);
|
|
1365
|
+
const pathParts = url.pathname.split("/");
|
|
1366
|
+
const id = pathParts[pathParts.length - 2];
|
|
1367
|
+
if (!id) {
|
|
1368
|
+
return Response.json({
|
|
1369
|
+
success: false,
|
|
1370
|
+
error: "Broadcast ID is required"
|
|
1371
|
+
}, { status: 400 });
|
|
1372
|
+
}
|
|
1373
|
+
const data = await (req.json?.() || Promise.resolve({}));
|
|
1374
|
+
const broadcastDoc = await req.payload.findByID({
|
|
1375
|
+
collection: collectionSlug,
|
|
1376
|
+
id,
|
|
1377
|
+
user: auth.user
|
|
1378
|
+
});
|
|
1379
|
+
if (!broadcastDoc || !broadcastDoc.providerId) {
|
|
1380
|
+
return Response.json({
|
|
1381
|
+
success: false,
|
|
1382
|
+
error: "Broadcast not found or not synced with provider"
|
|
1383
|
+
}, { status: 404 });
|
|
1384
|
+
}
|
|
1385
|
+
const providerConfig = await getBroadcastConfig(req, config);
|
|
1386
|
+
if (!providerConfig || !providerConfig.token) {
|
|
1387
|
+
return Response.json({
|
|
1388
|
+
success: false,
|
|
1389
|
+
error: "Broadcast provider not configured in Newsletter Settings or environment variables"
|
|
1390
|
+
}, { status: 500 });
|
|
1391
|
+
}
|
|
1392
|
+
const { BroadcastApiProvider: BroadcastApiProvider2 } = await Promise.resolve().then(() => (init_broadcast2(), broadcast_exports));
|
|
1393
|
+
const provider = new BroadcastApiProvider2(providerConfig);
|
|
1394
|
+
const broadcast = await provider.send(broadcastDoc.providerId, data);
|
|
1395
|
+
await req.payload.update({
|
|
1396
|
+
collection: collectionSlug,
|
|
1397
|
+
id,
|
|
1398
|
+
data: {
|
|
1399
|
+
sendStatus: "sending" /* SENDING */,
|
|
1400
|
+
sentAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1401
|
+
},
|
|
1402
|
+
user: auth.user
|
|
1403
|
+
});
|
|
1404
|
+
return Response.json({
|
|
1405
|
+
success: true,
|
|
1406
|
+
message: "Broadcast sent successfully",
|
|
1407
|
+
broadcast
|
|
1408
|
+
});
|
|
1409
|
+
} catch (error) {
|
|
1410
|
+
console.error("Failed to send broadcast:", error);
|
|
1411
|
+
if (error instanceof NewsletterProviderError) {
|
|
1412
|
+
return Response.json({
|
|
1413
|
+
success: false,
|
|
1414
|
+
error: error.message,
|
|
1415
|
+
code: error.code
|
|
1416
|
+
}, { status: error.code === "NOT_SUPPORTED" ? 501 : 500 });
|
|
1417
|
+
}
|
|
1418
|
+
return Response.json({
|
|
1419
|
+
success: false,
|
|
1420
|
+
error: "Failed to send broadcast"
|
|
1421
|
+
}, { status: 500 });
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
};
|
|
1425
|
+
};
|
|
1426
|
+
|
|
1427
|
+
// src/endpoints/broadcasts/schedule.ts
|
|
1428
|
+
init_types();
|
|
1429
|
+
var createScheduleBroadcastEndpoint = (config, collectionSlug) => {
|
|
1430
|
+
return {
|
|
1431
|
+
path: "/:id/schedule",
|
|
1432
|
+
method: "post",
|
|
1433
|
+
handler: async (req) => {
|
|
1434
|
+
try {
|
|
1435
|
+
const auth = await requireAdmin(req, config);
|
|
1436
|
+
if (!auth.authorized) {
|
|
1437
|
+
return Response.json({
|
|
1438
|
+
success: false,
|
|
1439
|
+
error: auth.error
|
|
1440
|
+
}, { status: 401 });
|
|
1441
|
+
}
|
|
1442
|
+
if (!config.features?.newsletterManagement?.enabled) {
|
|
1443
|
+
return Response.json({
|
|
1444
|
+
success: false,
|
|
1445
|
+
error: "Broadcast management is not enabled"
|
|
1446
|
+
}, { status: 400 });
|
|
1447
|
+
}
|
|
1448
|
+
const url = new URL(req.url || "", `http://localhost`);
|
|
1449
|
+
const pathParts = url.pathname.split("/");
|
|
1450
|
+
const id = pathParts[pathParts.length - 2];
|
|
1451
|
+
if (!id) {
|
|
1452
|
+
return Response.json({
|
|
1453
|
+
success: false,
|
|
1454
|
+
error: "Broadcast ID is required"
|
|
1455
|
+
}, { status: 400 });
|
|
1456
|
+
}
|
|
1457
|
+
const data = await (req.json?.() || Promise.resolve({}));
|
|
1458
|
+
const { scheduledAt } = data;
|
|
1459
|
+
if (!scheduledAt) {
|
|
1460
|
+
return Response.json({
|
|
1461
|
+
success: false,
|
|
1462
|
+
error: "scheduledAt is required"
|
|
1463
|
+
}, { status: 400 });
|
|
1464
|
+
}
|
|
1465
|
+
const scheduledDate = new Date(scheduledAt);
|
|
1466
|
+
if (isNaN(scheduledDate.getTime())) {
|
|
1467
|
+
return Response.json({
|
|
1468
|
+
success: false,
|
|
1469
|
+
error: "Invalid scheduledAt date"
|
|
1470
|
+
}, { status: 400 });
|
|
1471
|
+
}
|
|
1472
|
+
if (scheduledDate <= /* @__PURE__ */ new Date()) {
|
|
1473
|
+
return Response.json({
|
|
1474
|
+
success: false,
|
|
1475
|
+
error: "scheduledAt must be in the future"
|
|
1476
|
+
}, { status: 400 });
|
|
1477
|
+
}
|
|
1478
|
+
const broadcastDoc = await req.payload.findByID({
|
|
1479
|
+
collection: collectionSlug,
|
|
1480
|
+
id,
|
|
1481
|
+
user: auth.user
|
|
1482
|
+
});
|
|
1483
|
+
if (!broadcastDoc || !broadcastDoc.providerId) {
|
|
1484
|
+
return Response.json({
|
|
1485
|
+
success: false,
|
|
1486
|
+
error: "Broadcast not found or not synced with provider"
|
|
1487
|
+
}, { status: 404 });
|
|
1488
|
+
}
|
|
1489
|
+
const providerConfig = config.providers?.broadcast;
|
|
1490
|
+
if (!providerConfig) {
|
|
1491
|
+
return Response.json({
|
|
1492
|
+
success: false,
|
|
1493
|
+
error: "Broadcast provider not configured"
|
|
1494
|
+
}, { status: 500 });
|
|
1495
|
+
}
|
|
1496
|
+
const { BroadcastApiProvider: BroadcastApiProvider2 } = await Promise.resolve().then(() => (init_broadcast2(), broadcast_exports));
|
|
1497
|
+
const provider = new BroadcastApiProvider2(providerConfig);
|
|
1498
|
+
const broadcast = await provider.schedule(broadcastDoc.providerId, scheduledDate);
|
|
1499
|
+
await req.payload.update({
|
|
1500
|
+
collection: collectionSlug,
|
|
1501
|
+
id,
|
|
1502
|
+
data: {
|
|
1503
|
+
sendStatus: "scheduled" /* SCHEDULED */,
|
|
1504
|
+
scheduledAt: scheduledDate.toISOString()
|
|
1505
|
+
},
|
|
1506
|
+
user: auth.user
|
|
1507
|
+
});
|
|
1508
|
+
return Response.json({
|
|
1509
|
+
success: true,
|
|
1510
|
+
message: `Broadcast scheduled for ${scheduledDate.toISOString()}`,
|
|
1511
|
+
broadcast
|
|
1512
|
+
});
|
|
1513
|
+
} catch (error) {
|
|
1514
|
+
console.error("Failed to schedule broadcast:", error);
|
|
1515
|
+
if (error instanceof NewsletterProviderError) {
|
|
1516
|
+
return Response.json({
|
|
1517
|
+
success: false,
|
|
1518
|
+
error: error.message,
|
|
1519
|
+
code: error.code
|
|
1520
|
+
}, { status: error.code === "NOT_SUPPORTED" ? 501 : 500 });
|
|
1521
|
+
}
|
|
1522
|
+
return Response.json({
|
|
1523
|
+
success: false,
|
|
1524
|
+
error: "Failed to schedule broadcast"
|
|
1525
|
+
}, { status: 500 });
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1528
|
+
};
|
|
1529
|
+
};
|
|
1530
|
+
|
|
1531
|
+
// src/endpoints/broadcasts/test.ts
|
|
1532
|
+
var createTestBroadcastEndpoint = (config, collectionSlug) => {
|
|
1533
|
+
return {
|
|
1534
|
+
path: "/:id/test",
|
|
1535
|
+
method: "post",
|
|
1536
|
+
handler: async (req) => {
|
|
1537
|
+
try {
|
|
1538
|
+
const auth = await requireAdmin(req, config);
|
|
1539
|
+
if (!auth.authorized) {
|
|
1540
|
+
return Response.json({
|
|
1541
|
+
success: false,
|
|
1542
|
+
error: auth.error
|
|
1543
|
+
}, { status: 401 });
|
|
1544
|
+
}
|
|
1545
|
+
const url = new URL(req.url || "", `http://localhost`);
|
|
1546
|
+
const pathParts = url.pathname.split("/");
|
|
1547
|
+
const id = pathParts[pathParts.length - 2];
|
|
1548
|
+
if (!id) {
|
|
1549
|
+
return Response.json({
|
|
1550
|
+
success: false,
|
|
1551
|
+
error: "Broadcast ID is required"
|
|
1552
|
+
}, { status: 400 });
|
|
1553
|
+
}
|
|
1554
|
+
const data = await (req.json?.() || Promise.resolve({}));
|
|
1555
|
+
const testEmail = data.email || auth.user.email;
|
|
1556
|
+
if (!testEmail) {
|
|
1557
|
+
return Response.json({
|
|
1558
|
+
success: false,
|
|
1559
|
+
error: "No email address available for test send"
|
|
1560
|
+
}, { status: 400 });
|
|
1561
|
+
}
|
|
1562
|
+
const broadcast = await req.payload.findByID({
|
|
1563
|
+
collection: collectionSlug,
|
|
1564
|
+
id,
|
|
1565
|
+
user: auth.user
|
|
1566
|
+
});
|
|
1567
|
+
if (!broadcast) {
|
|
1568
|
+
return Response.json({
|
|
1569
|
+
success: false,
|
|
1570
|
+
error: "Broadcast not found"
|
|
1571
|
+
}, { status: 404 });
|
|
1572
|
+
}
|
|
1573
|
+
const htmlContent = await convertToEmailSafeHtml(broadcast.content, {
|
|
1574
|
+
wrapInTemplate: true,
|
|
1575
|
+
preheader: broadcast.preheader,
|
|
1576
|
+
customBlockConverter: config.customizations?.broadcasts?.customBlockConverter
|
|
1577
|
+
});
|
|
1578
|
+
const emailService = req.payload.newsletterEmailService;
|
|
1579
|
+
if (!emailService) {
|
|
1580
|
+
return Response.json({
|
|
1581
|
+
success: false,
|
|
1582
|
+
error: "Email service is not configured"
|
|
1583
|
+
}, { status: 500 });
|
|
1584
|
+
}
|
|
1585
|
+
const providerConfig = config.providers.default === "resend" ? config.providers.resend : config.providers.broadcast;
|
|
1586
|
+
const fromEmail = providerConfig?.fromAddress || providerConfig?.fromEmail || "noreply@example.com";
|
|
1587
|
+
const fromName = providerConfig?.fromName || "Newsletter";
|
|
1588
|
+
const replyTo = broadcast.settings?.replyTo || providerConfig?.replyTo;
|
|
1589
|
+
await emailService.send({
|
|
1590
|
+
to: testEmail,
|
|
1591
|
+
from: fromEmail,
|
|
1592
|
+
fromName,
|
|
1593
|
+
replyTo,
|
|
1594
|
+
subject: `[TEST] ${broadcast.subject}`,
|
|
1595
|
+
html: htmlContent,
|
|
1596
|
+
trackOpens: false,
|
|
1597
|
+
trackClicks: false
|
|
1598
|
+
});
|
|
1599
|
+
return Response.json({
|
|
1600
|
+
success: true,
|
|
1601
|
+
message: `Test email sent to ${testEmail}`
|
|
1602
|
+
});
|
|
1603
|
+
} catch (error) {
|
|
1604
|
+
console.error("Failed to send test broadcast:", error);
|
|
1605
|
+
return Response.json({
|
|
1606
|
+
success: false,
|
|
1607
|
+
error: "Failed to send test email"
|
|
1608
|
+
}, { status: 500 });
|
|
1609
|
+
}
|
|
1610
|
+
}
|
|
1611
|
+
};
|
|
1612
|
+
};
|
|
1613
|
+
|
|
1614
|
+
// src/endpoints/broadcasts/preview.ts
|
|
1615
|
+
var createBroadcastPreviewEndpoint = (config, collectionSlug) => {
|
|
1616
|
+
return {
|
|
1617
|
+
path: "/preview",
|
|
1618
|
+
method: "post",
|
|
1619
|
+
handler: async (req) => {
|
|
1620
|
+
try {
|
|
1621
|
+
const data = await (req.json?.() || Promise.resolve({}));
|
|
1622
|
+
const { content, preheader, subject } = data;
|
|
1623
|
+
if (!content) {
|
|
1624
|
+
return Response.json({
|
|
1625
|
+
success: false,
|
|
1626
|
+
error: "Content is required for preview"
|
|
1627
|
+
}, { status: 400 });
|
|
1628
|
+
}
|
|
1629
|
+
const mediaUrl = req.payload.config.serverURL ? `${req.payload.config.serverURL}/api/media` : "/api/media";
|
|
1630
|
+
const htmlContent = await convertToEmailSafeHtml(content, {
|
|
1631
|
+
wrapInTemplate: true,
|
|
1632
|
+
preheader,
|
|
1633
|
+
mediaUrl,
|
|
1634
|
+
customBlockConverter: config.customizations?.broadcasts?.customBlockConverter
|
|
1635
|
+
});
|
|
1636
|
+
return Response.json({
|
|
1637
|
+
success: true,
|
|
1638
|
+
preview: {
|
|
1639
|
+
subject: subject || "Preview",
|
|
1640
|
+
preheader: preheader || "",
|
|
1641
|
+
html: htmlContent
|
|
1642
|
+
}
|
|
1643
|
+
});
|
|
1644
|
+
} catch (error) {
|
|
1645
|
+
console.error("Failed to generate email preview:", error);
|
|
1646
|
+
return Response.json({
|
|
1647
|
+
success: false,
|
|
1648
|
+
error: "Failed to generate email preview"
|
|
1649
|
+
}, { status: 500 });
|
|
1650
|
+
}
|
|
1651
|
+
}
|
|
1652
|
+
};
|
|
1653
|
+
};
|
|
1654
|
+
|
|
1231
1655
|
// src/collections/Broadcasts.ts
|
|
1232
1656
|
var createBroadcastsCollection = (pluginConfig) => {
|
|
1233
1657
|
const hasProviders = !!(pluginConfig.providers?.broadcast || pluginConfig.providers?.resend);
|
|
1234
1658
|
const customizations = pluginConfig.customizations?.broadcasts;
|
|
1659
|
+
const collectionSlug = "broadcasts";
|
|
1235
1660
|
return {
|
|
1236
|
-
slug:
|
|
1661
|
+
slug: collectionSlug,
|
|
1237
1662
|
access: {
|
|
1238
1663
|
read: () => true,
|
|
1239
1664
|
// Public read access
|
|
@@ -1262,6 +1687,12 @@ var createBroadcastsCollection = (pluginConfig) => {
|
|
|
1262
1687
|
description: "Individual email campaigns sent to subscribers",
|
|
1263
1688
|
defaultColumns: ["subject", "_status", "sendStatus", "sentAt", "recipientCount"]
|
|
1264
1689
|
},
|
|
1690
|
+
endpoints: [
|
|
1691
|
+
createSendBroadcastEndpoint(pluginConfig, collectionSlug),
|
|
1692
|
+
createScheduleBroadcastEndpoint(pluginConfig, collectionSlug),
|
|
1693
|
+
createTestBroadcastEndpoint(pluginConfig, collectionSlug),
|
|
1694
|
+
createBroadcastPreviewEndpoint(pluginConfig, collectionSlug)
|
|
1695
|
+
],
|
|
1265
1696
|
fields: [
|
|
1266
1697
|
{
|
|
1267
1698
|
name: "subject",
|
|
@@ -1807,67 +2238,6 @@ var createBroadcastsCollection = (pluginConfig) => {
|
|
|
1807
2238
|
};
|
|
1808
2239
|
};
|
|
1809
2240
|
|
|
1810
|
-
// src/utils/access.ts
|
|
1811
|
-
var isAdmin = (user, config) => {
|
|
1812
|
-
if (!user || user.collection !== "users") {
|
|
1813
|
-
return false;
|
|
1814
|
-
}
|
|
1815
|
-
if (config?.access?.isAdmin) {
|
|
1816
|
-
return config.access.isAdmin(user);
|
|
1817
|
-
}
|
|
1818
|
-
if (user.roles?.includes("admin")) {
|
|
1819
|
-
return true;
|
|
1820
|
-
}
|
|
1821
|
-
if (user.isAdmin === true) {
|
|
1822
|
-
return true;
|
|
1823
|
-
}
|
|
1824
|
-
if (user.role === "admin") {
|
|
1825
|
-
return true;
|
|
1826
|
-
}
|
|
1827
|
-
if (user.admin === true) {
|
|
1828
|
-
return true;
|
|
1829
|
-
}
|
|
1830
|
-
return false;
|
|
1831
|
-
};
|
|
1832
|
-
var adminOnly = (config) => ({ req }) => {
|
|
1833
|
-
const user = req.user;
|
|
1834
|
-
return isAdmin(user, config);
|
|
1835
|
-
};
|
|
1836
|
-
var adminOrSelf = (config) => ({ req, id }) => {
|
|
1837
|
-
const user = req.user;
|
|
1838
|
-
if (!user) {
|
|
1839
|
-
if (!id) {
|
|
1840
|
-
return {
|
|
1841
|
-
id: {
|
|
1842
|
-
equals: "unauthorized-no-access"
|
|
1843
|
-
}
|
|
1844
|
-
};
|
|
1845
|
-
}
|
|
1846
|
-
return false;
|
|
1847
|
-
}
|
|
1848
|
-
if (isAdmin(user, config)) {
|
|
1849
|
-
return true;
|
|
1850
|
-
}
|
|
1851
|
-
if (user.collection === "subscribers") {
|
|
1852
|
-
if (!id) {
|
|
1853
|
-
return {
|
|
1854
|
-
id: {
|
|
1855
|
-
equals: user.id
|
|
1856
|
-
}
|
|
1857
|
-
};
|
|
1858
|
-
}
|
|
1859
|
-
return id === user.id;
|
|
1860
|
-
}
|
|
1861
|
-
if (!id) {
|
|
1862
|
-
return {
|
|
1863
|
-
id: {
|
|
1864
|
-
equals: "unauthorized-no-access"
|
|
1865
|
-
}
|
|
1866
|
-
};
|
|
1867
|
-
}
|
|
1868
|
-
return false;
|
|
1869
|
-
};
|
|
1870
|
-
|
|
1871
2241
|
// src/emails/render.tsx
|
|
1872
2242
|
import { render } from "@react-email/render";
|
|
1873
2243
|
|