payload-plugin-newsletter 0.13.2 → 0.14.0
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 +33 -0
- package/dist/index.cjs +144 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +144 -17
- package/dist/index.js.map +1 -1
- package/dist/types.d.cts +10 -0
- package/dist/types.d.ts +10 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1261,6 +1261,44 @@ var createNewsletterSettingsGlobal = (pluginConfig) => {
|
|
|
1261
1261
|
}
|
|
1262
1262
|
]
|
|
1263
1263
|
},
|
|
1264
|
+
{
|
|
1265
|
+
label: "Brand Settings",
|
|
1266
|
+
fields: [
|
|
1267
|
+
{
|
|
1268
|
+
name: "brandSettings",
|
|
1269
|
+
type: "group",
|
|
1270
|
+
label: "Brand Settings",
|
|
1271
|
+
fields: [
|
|
1272
|
+
{
|
|
1273
|
+
name: "siteName",
|
|
1274
|
+
type: "text",
|
|
1275
|
+
label: "Site Name",
|
|
1276
|
+
required: true,
|
|
1277
|
+
defaultValue: "Newsletter",
|
|
1278
|
+
admin: {
|
|
1279
|
+
description: "Your website or newsletter name"
|
|
1280
|
+
}
|
|
1281
|
+
},
|
|
1282
|
+
{
|
|
1283
|
+
name: "siteUrl",
|
|
1284
|
+
type: "text",
|
|
1285
|
+
label: "Site URL",
|
|
1286
|
+
admin: {
|
|
1287
|
+
description: "Your website URL (optional)"
|
|
1288
|
+
}
|
|
1289
|
+
},
|
|
1290
|
+
{
|
|
1291
|
+
name: "logoUrl",
|
|
1292
|
+
type: "text",
|
|
1293
|
+
label: "Logo URL",
|
|
1294
|
+
admin: {
|
|
1295
|
+
description: "URL to your logo image (optional)"
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1298
|
+
]
|
|
1299
|
+
}
|
|
1300
|
+
]
|
|
1301
|
+
},
|
|
1264
1302
|
{
|
|
1265
1303
|
label: "Email Templates",
|
|
1266
1304
|
fields: [
|
|
@@ -1944,10 +1982,13 @@ function verifySessionToken(token) {
|
|
|
1944
1982
|
throw error;
|
|
1945
1983
|
}
|
|
1946
1984
|
}
|
|
1947
|
-
function generateMagicLinkURL(token, baseURL, config) {
|
|
1985
|
+
function generateMagicLinkURL(token, baseURL, config, redirectUrl) {
|
|
1948
1986
|
const path = config.auth?.magicLinkPath || "/newsletter/verify";
|
|
1949
1987
|
const url = new URL(path, baseURL);
|
|
1950
1988
|
url.searchParams.set("token", token);
|
|
1989
|
+
if (redirectUrl) {
|
|
1990
|
+
url.searchParams.set("redirect", redirectUrl);
|
|
1991
|
+
}
|
|
1951
1992
|
return url.toString();
|
|
1952
1993
|
}
|
|
1953
1994
|
|
|
@@ -2001,20 +2042,93 @@ var createSubscribeEndpoint = (config) => {
|
|
|
2001
2042
|
if (existing.docs.length > 0) {
|
|
2002
2043
|
const subscriber2 = existing.docs[0];
|
|
2003
2044
|
if (subscriber2.subscriptionStatus === "unsubscribed") {
|
|
2045
|
+
const allowResubscribe = config.auth?.allowResubscribe ?? false;
|
|
2046
|
+
if (!allowResubscribe) {
|
|
2047
|
+
return Response.json({
|
|
2048
|
+
success: false,
|
|
2049
|
+
error: "This email has been unsubscribed. Please contact support to resubscribe."
|
|
2050
|
+
}, { status: 400 });
|
|
2051
|
+
}
|
|
2052
|
+
const updated = await req.payload.update({
|
|
2053
|
+
collection: config.subscribersSlug || "subscribers",
|
|
2054
|
+
id: subscriber2.id,
|
|
2055
|
+
data: {
|
|
2056
|
+
subscriptionStatus: "active",
|
|
2057
|
+
resubscribedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2058
|
+
// Preserve preferences but update metadata
|
|
2059
|
+
signupMetadata: {
|
|
2060
|
+
...metadata,
|
|
2061
|
+
source: source || "resubscribe",
|
|
2062
|
+
resubscribedFrom: subscriber2.signupMetadata?.source
|
|
2063
|
+
}
|
|
2064
|
+
},
|
|
2065
|
+
overrideAccess: true
|
|
2066
|
+
});
|
|
2067
|
+
if (config.hooks?.afterSubscribe) {
|
|
2068
|
+
await config.hooks.afterSubscribe({
|
|
2069
|
+
doc: updated,
|
|
2070
|
+
req
|
|
2071
|
+
});
|
|
2072
|
+
}
|
|
2073
|
+
const emailService = req.payload.newsletterEmailService;
|
|
2074
|
+
if (emailService) {
|
|
2075
|
+
const settings2 = await req.payload.findGlobal({
|
|
2076
|
+
slug: config.settingsSlug || "newsletter-settings"
|
|
2077
|
+
});
|
|
2078
|
+
const html = await renderEmail("welcome", {
|
|
2079
|
+
name: updated.name || "",
|
|
2080
|
+
email: updated.email,
|
|
2081
|
+
siteName: settings2?.brandSettings?.siteName || "Newsletter",
|
|
2082
|
+
siteUrl: req.payload.config.serverURL || ""
|
|
2083
|
+
});
|
|
2084
|
+
await emailService.send({
|
|
2085
|
+
to: updated.email,
|
|
2086
|
+
subject: `Welcome back to ${settings2?.brandSettings?.siteName || "our newsletter"}!`,
|
|
2087
|
+
html
|
|
2088
|
+
});
|
|
2089
|
+
}
|
|
2004
2090
|
return Response.json({
|
|
2005
|
-
success:
|
|
2006
|
-
|
|
2007
|
-
|
|
2091
|
+
success: true,
|
|
2092
|
+
message: "Welcome back! You have been resubscribed.",
|
|
2093
|
+
subscriber: {
|
|
2094
|
+
id: updated.id,
|
|
2095
|
+
email: updated.email,
|
|
2096
|
+
subscriptionStatus: updated.subscriptionStatus
|
|
2097
|
+
},
|
|
2098
|
+
wasResubscribed: true
|
|
2099
|
+
});
|
|
2008
2100
|
}
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2101
|
+
if (subscriber2.subscriptionStatus === "active") {
|
|
2102
|
+
const token = generateMagicLinkToken(
|
|
2103
|
+
String(subscriber2.id),
|
|
2104
|
+
subscriber2.email,
|
|
2105
|
+
config
|
|
2106
|
+
);
|
|
2107
|
+
const serverURL = req.payload.config.serverURL || process.env.PAYLOAD_PUBLIC_SERVER_URL || "";
|
|
2108
|
+
const magicLinkURL = generateMagicLinkURL(token, serverURL, config);
|
|
2109
|
+
const emailService = req.payload.newsletterEmailService;
|
|
2110
|
+
if (emailService) {
|
|
2111
|
+
const settings2 = await req.payload.findGlobal({
|
|
2112
|
+
slug: config.settingsSlug || "newsletter-settings"
|
|
2113
|
+
});
|
|
2114
|
+
const html = await renderEmail("signin", {
|
|
2115
|
+
magicLink: magicLinkURL,
|
|
2116
|
+
email: subscriber2.email,
|
|
2117
|
+
siteName: settings2?.brandSettings?.siteName || "Newsletter",
|
|
2118
|
+
expiresIn: config.auth?.tokenExpiration || "7d"
|
|
2119
|
+
});
|
|
2120
|
+
await emailService.send({
|
|
2121
|
+
to: subscriber2.email,
|
|
2122
|
+
subject: `Sign in to ${settings2?.brandSettings?.siteName || "your account"}`,
|
|
2123
|
+
html
|
|
2124
|
+
});
|
|
2016
2125
|
}
|
|
2017
|
-
|
|
2126
|
+
return Response.json({
|
|
2127
|
+
success: true,
|
|
2128
|
+
message: "You are already subscribed! Check your email for a sign-in link.",
|
|
2129
|
+
alreadySubscribed: true
|
|
2130
|
+
});
|
|
2131
|
+
}
|
|
2018
2132
|
}
|
|
2019
2133
|
const ipAddress = req.ip || req.connection?.remoteAddress;
|
|
2020
2134
|
const maxPerIP = settings?.subscriptionSettings?.maxSubscribersPerIP || 10;
|
|
@@ -2536,7 +2650,7 @@ var createSigninEndpoint = (config) => {
|
|
|
2536
2650
|
handler: async (req) => {
|
|
2537
2651
|
try {
|
|
2538
2652
|
const data = await req.json();
|
|
2539
|
-
const { email } = data;
|
|
2653
|
+
const { email, redirectUrl } = data;
|
|
2540
2654
|
const validation = validateSubscriberData({ email });
|
|
2541
2655
|
if (!validation.valid) {
|
|
2542
2656
|
return Response.json({
|
|
@@ -2555,8 +2669,7 @@ var createSigninEndpoint = (config) => {
|
|
|
2555
2669
|
const result = await req.payload.find({
|
|
2556
2670
|
collection: config.subscribersSlug || "subscribers",
|
|
2557
2671
|
where: {
|
|
2558
|
-
email: { equals: email.toLowerCase() }
|
|
2559
|
-
subscriptionStatus: { equals: "active" }
|
|
2672
|
+
email: { equals: email.toLowerCase() }
|
|
2560
2673
|
},
|
|
2561
2674
|
limit: 1,
|
|
2562
2675
|
overrideAccess: true
|
|
@@ -2565,17 +2678,31 @@ var createSigninEndpoint = (config) => {
|
|
|
2565
2678
|
if (result.docs.length === 0) {
|
|
2566
2679
|
return Response.json({
|
|
2567
2680
|
success: false,
|
|
2568
|
-
error: "Email not found. Please subscribe first."
|
|
2681
|
+
error: "Email not found. Please subscribe first.",
|
|
2682
|
+
requiresSubscribe: true
|
|
2569
2683
|
}, { status: 404 });
|
|
2570
2684
|
}
|
|
2571
2685
|
const subscriber = result.docs[0];
|
|
2686
|
+
const allowUnsubscribed = config.auth?.allowUnsubscribedSignin ?? false;
|
|
2687
|
+
if (subscriber.subscriptionStatus === "unsubscribed" && !allowUnsubscribed) {
|
|
2688
|
+
return Response.json({
|
|
2689
|
+
success: false,
|
|
2690
|
+
error: "Your subscription is inactive. Please resubscribe to sign in.",
|
|
2691
|
+
subscriber: {
|
|
2692
|
+
id: subscriber.id,
|
|
2693
|
+
email: subscriber.email,
|
|
2694
|
+
subscriptionStatus: subscriber.subscriptionStatus
|
|
2695
|
+
},
|
|
2696
|
+
requiresResubscribe: true
|
|
2697
|
+
}, { status: 403 });
|
|
2698
|
+
}
|
|
2572
2699
|
const token = generateMagicLinkToken(
|
|
2573
2700
|
String(subscriber.id),
|
|
2574
2701
|
subscriber.email,
|
|
2575
2702
|
config
|
|
2576
2703
|
);
|
|
2577
2704
|
const serverURL = req.payload.config.serverURL || process.env.PAYLOAD_PUBLIC_SERVER_URL || "";
|
|
2578
|
-
const magicLinkURL = generateMagicLinkURL(token, serverURL, config);
|
|
2705
|
+
const magicLinkURL = generateMagicLinkURL(token, serverURL, config, redirectUrl);
|
|
2579
2706
|
const emailService = req.payload.newsletterEmailService;
|
|
2580
2707
|
if (emailService) {
|
|
2581
2708
|
const settings = await req.payload.findGlobal({
|