Skip to content

Commit 68c62f8

Browse files
committed
fix: address copilot review suggestions for byok validation and worker init edge-cases
1 parent 2d9b53c commit 68c62f8

6 files changed

Lines changed: 31 additions & 15 deletions

File tree

‎apps/dashboard-api/src/controllers/project.controller.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1160,7 +1160,7 @@ module.exports.updateProject = async (req, res) => {
11601160
{ $set: updateFields },
11611161
{
11621162
new: true,
1163-
select:
1163+
projection:
11641164
"+resendApiKey.encrypted +resendApiKey.iv +resendApiKey.tag",
11651165
},
11661166
);

‎apps/public-api/src/app.js‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@ const { capture } = require('@kiroo/sdk');
2222
const {emailQueue} = require('@urbackend/common');
2323
const {authEmailQueue} = require('@urbackend/common');
2424
const {initWebhookWorker} = require('@urbackend/common');
25+
const {initAuthEmailWorker} = require('@urbackend/common');
2526

2627
// Initialize webhook worker
2728
if (process.env.NODE_ENV !== 'test') {
2829
initWebhookWorker();
30+
initAuthEmailWorker();
2931
}
3032

3133
app.use(express.json());

‎apps/public-api/src/controllers/mail.controller.js‎

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const getMailCountKey = (projectId, monthKey) =>
1414

1515
const loadProjectMailConfig = async (projectId) => {
1616
return Project.findById(projectId)
17-
.select("+resendApiKey.encrypted +resendApiKey.iv +resendApiKey.tag")
17+
.select("+resendApiKey.encrypted +resendApiKey.iv +resendApiKey.tag resendFromEmail")
1818
.lean();
1919
};
2020

@@ -62,16 +62,17 @@ module.exports.sendMail = async (req, res) => {
6262
return res.status(401).json({ error: "Project context missing." });
6363
}
6464

65-
const limit = getMonthlyMailLimit(req.project);
66-
const { count, key } = await reserveMonthlyMailSlot(projectId, limit);
67-
consumedQuotaKey = key;
68-
6965
const project = await loadProjectMailConfig(projectId);
7066
if (!project) {
7167
return res.status(404).json({ error: "Project not found." });
7268
}
7369

74-
const decryptedByokKey = decrypt(project.resendApiKey);
70+
const encryptedByokKey =
71+
project.resendApiKey && typeof project.resendApiKey === "object" && Object.keys(project.resendApiKey).length > 0
72+
? project.resendApiKey
73+
: null;
74+
const decryptedByokKey = encryptedByokKey ? decrypt(encryptedByokKey) : null;
75+
7576
const usingByok = typeof decryptedByokKey === "string" && decryptedByokKey.trim().length > 0;
7677
const clientKey = usingByok
7778
? decryptedByokKey.trim()
@@ -81,6 +82,10 @@ module.exports.sendMail = async (req, res) => {
8182
return res.status(500).json({ error: "Resend API key is not configured." });
8283
}
8384

85+
const limit = getMonthlyMailLimit(req.project);
86+
const { count, key } = await reserveMonthlyMailSlot(projectId, limit);
87+
consumedQuotaKey = key;
88+
8489
const resend = new Resend(clientKey);
8590

8691
let fromAddress = DEFAULT_FROM;

‎apps/web-dashboard/src/pages/ProjectSettings.jsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ export default function ProjectSettings() {
304304
Default Sent-From Address
305305
</label>
306306
<input
307-
type="email"
307+
type="text"
308308
className="input-field"
309309
placeholder="e.g. Acme <info@acme.com>"
310310
value={resendFromEmailValue}

‎packages/common/src/index.js‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ const Webhook = require("./models/Webhook");
2222
const WebhookDelivery = require("./models/WebhookDelivery");
2323

2424
// Queues
25-
const { authEmailQueue } = require("./queues/authEmailQueue");
25+
const { authEmailQueue,
26+
initAuthEmailWorker, initAuthEmailWorker } = require("./queues/authEmailQueue");
2627
const { emailQueue } = require("./queues/emailQueue");
2728
const {
2829
webhookQueue,

‎packages/common/src/queues/authEmailQueue.js‎

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,13 @@ const { decrypt } = require('../utils/encryption');
77
// Create the email queue specifically for fast OTPs
88
const authEmailQueue = new Queue('auth-email-queue', { connection });
99

10-
// Initialize Worker with Rate Limiting
11-
const worker = new Worker('auth-email-queue', async (job) => {
10+
let worker = null;
11+
12+
const initAuthEmailWorker = () => {
13+
if (worker) return worker;
14+
15+
// Initialize Worker with Rate Limiting
16+
worker = new Worker('auth-email-queue', async (job) => {
1217
const { email, otp, type, pname, projectId } = job.data;
1318
const redact = (e) => e.replace(/(.{2})(.*)(?=@)/, (gp1, gp2, gp3) => gp2 + "*".repeat(gp3.length));
1419
const maskedEmail = redact(email);
@@ -51,8 +56,11 @@ worker.on('completed', (job) => {
5156
console.log(`[Queue] Job ${job.id} completed successfully`);
5257
});
5358

54-
worker.on('failed', (job, err) => {
55-
console.error(`[Queue] Job ${job.id} failed:`, err);
56-
});
59+
worker.on('failed', (job, err) => {
60+
console.error(`[Queue] Job ${job.id} failed:`, err);
61+
});
62+
63+
return worker;
64+
};
5765

58-
module.exports = { authEmailQueue };
66+
module.exports = { authEmailQueue, initAuthEmailWorker };

0 commit comments

Comments
 (0)