Skip to content

Commit

Permalink
Merge pull request #118 from nklmantey/replace-variables-aws-region
Browse files Browse the repository at this point in the history
Replace variables aws region
  • Loading branch information
driaug authored Oct 29, 2024
2 parents 1ecef9f + 6196c41 commit 086f1b8
Show file tree
Hide file tree
Showing 23 changed files with 3,136 additions and 1,853 deletions.
1 change: 0 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
.env
.yarn/
.next/
.github/
dist/
Expand Down
894 changes: 894 additions & 0 deletions .yarn/releases/yarn-4.3.0.cjs

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
nodeLinker: node-modules

yarnPath: .yarn/releases/yarn-4.3.0.cjs
9 changes: 7 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,16 @@ Support can be asked in the `#contributions` channel of the [Plunk Discord serve

- Docker needs to be [installed](https://docs.docker.com/engine/install/) on your system.

### 2. Set your environment variables
### 2. Install dependencies

- Run `yarn install` to install the dependencies.

### 3. Set your environment variables

- Copy the `.env.example` files in the `api`, `dashboard` and `prisma` folder to `.env` in their respective folders.
- Set AWS credentials in the `api` `.env` file.

### 3. Start resources
### 4. Start resources

- Run `yarn services:up` to start a local database and a local redis server.
- Run `yarn migrate` to apply the migrations to the database.
Expand Down
26 changes: 21 additions & 5 deletions deployment/replace-variables.sh
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,26 @@ if [ -z "${API_URI}" ]; then
exit 1
fi

# Find and replace baked values with real values for the API_URI
find /app/packages/dashboard/public /app/packages/dashboard/.next -type f -name "*.js" |
while read file; do
sed -i "s|PLUNK_API_URI|${API_URI}|g" "$file"
if [ -z "${AWS_REGION}" ]; then
echo "AWS_REGION is not set. Exiting..."
exit 1
fi

# Process each directory that might contain JS files
for dir in "/app/packages/dashboard/public" "/app/packages/dashboard/.next"; do
if [ -d "$dir" ]; then
# Find all JS files and process them
find "$dir" -type f -name "*.js" -o -name "*.mjs" | while read -r file; do
if [ -f "$file" ]; then
# Replace environment variables
sed -i "s|PLUNK_API_URI|${API_URI}|g" "$file"
sed -i "s|PLUNK_AWS_REGION|${AWS_REGION}|g" "$file"
echo "Processed: $file"
fi
done
else
echo "Warning: Directory $dir does not exist, skipping..."
fi
done

echo "Environment Variables Baked."
echo "Environment Variables Baked."
11 changes: 7 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
{
"name": "plunk",
"version": "1.0.5",
"version": "1.0.9",
"private": true,
"license": "agpl-3.0",
"workspaces": {
"packages": ["packages/*"]
"packages": [
"packages/*"
]
},
"engines": {
"npm": ">=6.14.x",
"yarn": "1.22.x",
"yarn": "4.3.x",
"node": ">=18.x"
},
"devDependencies": {
Expand All @@ -34,5 +36,6 @@
"generate": "prisma generate",
"services:up": "docker compose -f docker-compose.dev.yml up -d",
"services:down": "docker compose -f docker-compose.dev.yml down"
}
},
"packageManager": "[email protected]"
}
2 changes: 1 addition & 1 deletion packages/api/.env.example
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# ENV
JWT_SECRET=mysupersecretJWTsecret
REDIS_URL=redis://127.0.0.1:56379
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/postgres
DATABASE_URL=postgresql://postgres:postgres@localhost:55432/postgres
DISABLE_SIGNUPS=false

# AWS
Expand Down
22 changes: 16 additions & 6 deletions packages/api/src/app/cron.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,22 @@ import { API_URI } from "./constants";

export const task = cron.schedule("* * * * *", () => {
signale.info("Running scheduled tasks");
void fetch(`${API_URI}/tasks`, {
method: "POST",
});
try {
void fetch(`${API_URI}/tasks`, {
method: "POST",
});
} catch (e) {
signale.error("Failed to run scheduled tasks. Please check the error below");
console.error(e);
}

signale.info("Updating verified identities");
void fetch(`${API_URI}/identities/update`, {
method: "POST",
});
try {
void fetch(`${API_URI}/identities/update`, {
method: "POST",
});
} catch (e) {
signale.error("Failed to update verified identities. Please check the error below");
console.error(e);
}
});
13 changes: 11 additions & 2 deletions packages/api/src/controllers/Tasks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ export class Tasks {
let subject = "";
let body = "";

let email = "";
let name = "";

if (action) {
const { template, notevents } = action;

Expand All @@ -52,6 +55,9 @@ export class Tasks {
}
}

email = project.verified && project.email ? template.email ?? project.email : "[email protected]";
name = template.from ?? project.from ?? project.name;

({ subject, body } = EmailService.format({
subject: template.subject,
body: template.body,
Expand All @@ -62,6 +68,9 @@ export class Tasks {
},
}));
} else if (campaign) {
email = project.verified && project.email ? campaign.email ?? project.email : "[email protected]";
name = campaign.from ?? project.from ?? project.name;

({ subject, body } = EmailService.format({
subject: campaign.subject,
body: campaign.body,
Expand All @@ -75,8 +84,8 @@ export class Tasks {

const { messageId } = await EmailService.send({
from: {
name: project.from ?? project.name,
email: project.verified && project.email ? project.email : "[email protected]",
name,
email,
},
to: [contact.email],
content: {
Expand Down
28 changes: 25 additions & 3 deletions packages/api/src/controllers/v1/Campaigns.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { CampaignSchemas, UtilitySchemas } from "@plunk/shared";
import dayjs from "dayjs";
import type { Request, Response } from "express";
import { prisma } from "../../database/prisma";
import { HttpException, NotFound } from "../../exceptions";
import { HttpException, NotAllowed, NotFound } from "../../exceptions";
import { type IJwt, type ISecret, isAuthenticated, isValidSecretKey } from "../../middleware/auth";
import { CampaignService } from "../../services/CampaignService";
import { ContactService } from "../../services/ContactService";
Expand Down Expand Up @@ -160,6 +160,8 @@ export class Campaigns {
subject: campaign.subject,
body: campaign.body,
style: campaign.style,
email: campaign.email,
from: campaign.from,
},
});

Expand All @@ -180,7 +182,15 @@ export class Campaigns {
throw new NotFound("project");
}

let { subject, body, recipients, style } = CampaignSchemas.create.parse(req.body);
let { subject, body, recipients, style, email, from } = CampaignSchemas.create.parse(req.body);

if (email && !project.verified) {
throw new NotAllowed("You need to attach a domain to your project to customize the sender address");
}

if (email && email.split("@")[1] !== project.email?.split("@")[1]) {
throw new NotAllowed("The sender address must be the same domain as the project's email address");
}

if (recipients.length === 1 && recipients[0] === "all") {
const projectContacts = await prisma.contact.findMany({
Expand All @@ -197,6 +207,8 @@ export class Campaigns {
subject,
body,
style,
from: from === "" ? null : from,
email: email === "" ? null : email,
},
});

Expand Down Expand Up @@ -253,7 +265,15 @@ export class Campaigns {
throw new NotFound("project");
}

let { id, subject, body, recipients, style } = CampaignSchemas.update.parse(req.body);
let { id, subject, body, recipients, style, email, from } = CampaignSchemas.update.parse(req.body);

if (email && !project.verified) {
throw new NotAllowed("You need to attach a domain to your project to customize the sender address");
}

if (email && email.split("@")[1] !== project.email?.split("@")[1]) {
throw new NotAllowed("The sender address must be the same domain as the project's email address");
}

if (recipients.length === 1 && recipients[0] === "all") {
const projectContacts = await prisma.contact.findMany({
Expand All @@ -276,6 +296,8 @@ export class Campaigns {
subject,
body,
style,
from: from === "" ? null : from,
email: email === "" ? null : email,
},
include: {
recipients: { select: { id: true } },
Expand Down
33 changes: 30 additions & 3 deletions packages/api/src/controllers/v1/Templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ export class Templates {
body: template.body,
type: template.type,
style: template.style,
email: template.email,
from: template.from,
},
});

Expand Down Expand Up @@ -101,7 +103,15 @@ export class Templates {
throw new NotFound("project");
}

const { subject, body, type, style } = TemplateSchemas.create.parse(req.body);
const { subject, body, type, style, email, from } = TemplateSchemas.create.parse(req.body);

if (email && !project.verified) {
throw new NotAllowed("You need to attach a domain to your project to customize the sender address");
}

if (email && email.split("@")[1] !== project.email?.split("@")[1]) {
throw new NotAllowed("The sender address must be the same domain as the project's email address");
}

const template = await prisma.template.create({
data: {
Expand All @@ -110,6 +120,8 @@ export class Templates {
body,
type,
style,
from: from === "" ? null : from,
email: email === "" ? null : email,
},
});

Expand Down Expand Up @@ -151,17 +163,32 @@ export class Templates {
throw new NotFound("project");
}

const { id, subject, body, type, style } = TemplateSchemas.update.parse(req.body);
const { id, subject, body, type, style, email, from } = TemplateSchemas.update.parse(req.body);

let template = await TemplateService.id(id);

if (!template || template.projectId !== project.id) {
throw new NotFound("template");
}

if (email && !project.verified) {
throw new NotAllowed("You need to attach a domain to your project to customize the sender address");
}

if (email && email.split("@")[1] !== project.email?.split("@")[1]) {
throw new NotAllowed("The sender address must be the same domain as the project's email address");
}

template = await prisma.template.update({
where: { id },
data: { subject, body, type, style },
data: {
subject,
body,
type,
style,
from: from === "" ? null : from,
email: email === "" ? null : email,
},
include: {
actions: true,
},
Expand Down
11 changes: 4 additions & 7 deletions packages/api/src/controllers/v1/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,12 @@ export class V1 {
redis.del(Keys.Contact.id(contact.id));
redis.del(Keys.Contact.email(project.id, contact.email));
} else {
if (subscribed && contact.subscribed !== subscribed) {
contact = await prisma.contact.update({
where: { id: contact.id },
data: { subscribed },
});

if (subscribed !== null && contact.subscribed !== subscribed) {
contact = await prisma.contact.update({where: {id: contact.id}, data: {subscribed}});

redis.del(Keys.Contact.id(contact.id));
redis.del(Keys.Contact.email(project.id, contact.email));
}
}
}

if (data) {
Expand Down
4 changes: 2 additions & 2 deletions packages/api/src/services/ActionService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,8 @@ export class ActionService {

const { messageId } = await EmailService.send({
from: {
name: project.from ?? project.name,
email: project.verified && project.email ? project.email : "[email protected]",
name: action.template.from ?? project.from ?? project.name,
email: project.verified && project.email ? action.template.email ?? project.email : "[email protected]",
},
to: [contact.email],
content: {
Expand Down
4 changes: 2 additions & 2 deletions packages/api/src/services/EmailService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ ${
<hr style="border: none; border-top: 1px solid #eaeaea; width: 100%; margin-top: 12px; margin-bottom: 12px;">
<p style="font-size: 12px; line-height: 24px; margin: 16px 0; text-align: center; color: rgb(64, 64, 64);">
You received this email because you agreed to receive emails from ${project.name}. If you no longer wish to receive emails like this, please
<a href="https://${APP_URI}/unsubscribe/${contact.id}">update your preferences</a>.
<a href="${APP_URI.startsWith("https://") ? APP_URI : `https://${APP_URI}`}/unsubscribe/${contact.id}">update your preferences</a>.
</p>
</td>
</tr>
Expand Down Expand Up @@ -472,7 +472,7 @@ ${
<mj-divider border-width="2px" border-color="#f5f5f5"></mj-divider>
<mj-text align="center">
<p style="color: #a3a3a3; text-decoration: none; font-size: 12px; line-height: 1.7142857;">
You received this email because you agreed to receive emails from ${project.name}. If you no longer wish to receive emails like this, please <a style="text-decoration: underline" href="${APP_URI}/unsubscribe/${contact.id}" target="_blank">update your preferences</a>.
You received this email because you agreed to receive emails from ${project.name}. If you no longer wish to receive emails like this, please <a style="text-decoration: underline" href="${APP_URI.startsWith("https://") ? APP_URI : `https://${APP_URI}`}/unsubscribe/${contact.id}" target="_blank">update your preferences</a>.
</p>
</mj-text>
`
Expand Down
Loading

0 comments on commit 086f1b8

Please sign in to comment.