Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/sync newsletter settings #773

Merged

Conversation

NiallJoeMaher
Copy link
Contributor

@NiallJoeMaher NiallJoeMaher commented Feb 26, 2024

✨ Codu Pull Request 💻

Codu Logo

Pull Request details

  • Newsletter settings sync with email service for eas sub/sunsub.
  • Add install to playwright test command.

Any Breaking changes

  • None

Summary by CodeRabbit

  • New Features
    • Enhanced user profile access in settings to check for newsletter subscription status. Users not subscribed to the newsletter will encounter a 404 page.
  • Refactor
    • Improved error handling and readability in managing newsletter subscriptions.

@NiallJoeMaher NiallJoeMaher requested a review from a team as a code owner February 26, 2024 14:29
Copy link

vercel bot commented Feb 26, 2024

@NiallJoeMaher is attempting to deploy a commit to the Codú Team on Vercel.

A member of the Team first needs to authorize it.

Copy link
Contributor

coderabbitai bot commented Feb 26, 2024

Warning

Rate Limit Exceeded

@NiallJoeMaher has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 22 minutes and 46 seconds before requesting another review.

How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.
Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.
Please see our FAQ for further information.

Commits Files that changed from the base of the PR and between 2008ce2 and 35af938.

Walkthrough

This update integrates a newsletter subscription check into user profile access and management, enhancing user experience and security. Users not subscribed to the newsletter are redirected to a 404 page when accessing profile settings. The backend now verifies newsletter subscription status and improves error handling and readability in managing subscriptions.

Changes

Files Change Summary
app/(app)/settings/page.tsx Introduced newsletter subscription status check before rendering the user profile.
server/api/router/profile.ts Added subscription status check before managing newsletter subscriptions.
server/lib/newsletter.ts Added isUserSubscribedToNewsletter function and refactored manageNewsletterSubscription.

🐇✨
In the land of code and byte,
Where rabbits hop and screens glow bright,
A new rule's made, with care and might,
"No newsletter? No profile sight."
🌟📜 So subscribe, and keep your access tight!

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share

Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit-tests for this file.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit tests for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository from git and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit tests.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • The JSON schema for the configuration file is available here.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/coderabbit-overrides.v2.json

CodeRabbit Discord Community

Join our Discord Community to get help, request features, and share feedback.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 5

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 68744ef and 67d4ada.
Files ignored due to path filters (1)
  • package.json is excluded by: !**/*.json
Files selected for processing (3)
  • app/(app)/settings/page.tsx (2 hunks)
  • server/api/router/profile.ts (2 hunks)
  • server/lib/newsletter.ts (1 hunks)
Additional comments: 2
app/(app)/settings/page.tsx (1)
  • 1-1: The import statement correctly adds notFound from next/navigation and isUserSubscribedToNewsletter from the server library, aligning with the PR's objectives to enhance the user settings page by checking newsletter subscription status.
server/api/router/profile.ts (1)
  • 11-14: The import statements for isUserSubscribedToNewsletter and manageNewsletterSubscription are correctly added, enabling the profile management API to utilize these functions for newsletter subscription management.

Comment on lines +59 to +61
if (!session.user.email) {
return notFound();
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logic to return a 404 not found page if the user's email is missing is a good security practice, ensuring that only users with a valid email can proceed. However, this might not directly relate to the newsletter subscription status. Consider adding a comment to clarify this choice or adjusting the logic to specifically check for newsletter subscription status.

+ // Ensure user has an email before proceeding. Consider checking for newsletter subscription explicitly if that's the intent.

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
if (!session.user.email) {
return notFound();
}
// Ensure user has an email before proceeding. Consider checking for newsletter subscription explicitly if that's the intent.
if (!session.user.email) {
return notFound();
}

Comment on lines +23 to +35
const response = await fetch(`${EMAIL_API_ENDPOINT}/${action}`, {
method: "POST",
headers: {
"Content-type": "application/x-www-form-urlencoded",
},
body: payload,
});

if (response.ok) {
return { message: `Successfully ${action}d to the newsletter.` };
} else {
throw new Error(`Failed to ${action} to the newsletter`);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The manageNewsletterSubscription function's error handling has been improved by throwing an error when the response is not OK. This is a good practice as it ensures that any issues with the subscription process are caught and can be handled appropriately. However, consider enhancing the error message with more details from the response to aid in debugging.

-    throw new Error(`Failed to ${action} to the newsletter`);
+    const errorDetail = await response.text();
+    throw new Error(`Failed to ${action} to the newsletter: ${errorDetail}`);

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
const response = await fetch(`${EMAIL_API_ENDPOINT}/${action}`, {
method: "POST",
headers: {
"Content-type": "application/x-www-form-urlencoded",
},
body: payload,
});
if (response.ok) {
return { message: `Successfully ${action}d to the newsletter.` };
} else {
throw new Error(`Failed to ${action} to the newsletter`);
}
const response = await fetch(`${EMAIL_API_ENDPOINT}/${action}`, {
method: "POST",
headers: {
"Content-type": "application/x-www-form-urlencoded",
},
body: payload,
});
if (response.ok) {
return { message: `Successfully ${action}d to the newsletter.` };
} else {
const errorDetail = await response.text();
throw new Error(`Failed to ${action} to the newsletter: ${errorDetail}`);
}

Comment on lines +38 to +68
export async function isUserSubscribedToNewsletter(email: string) {
const EMAIL_API_ENDPOINT = process.env.EMAIL_API_ENDPOINT;
const EMAIL_API_KEY = process.env.EMAIL_API_KEY;
const EMAIL_NEWSLETTER_ID = process.env.EMAIL_NEWSLETTER_ID;

if (!EMAIL_API_ENDPOINT || !EMAIL_API_KEY || !EMAIL_NEWSLETTER_ID) {
throw new Error("Email API not configured");
}

const payload = new URLSearchParams({
email,
api_key: EMAIL_API_KEY,
list_id: EMAIL_NEWSLETTER_ID,
}).toString();

const response = await fetch(
`${EMAIL_API_ENDPOINT}/api/subscribers/subscription-status.php`,
{
method: "POST",
headers: {
"Content-type": "application/x-www-form-urlencoded",
},
body: payload,
});

if (response.ok) {
return { message: `Successfully ${action}d to the newsletter.` };
} else {
throw new Error(`Failed to ${action} to the newsletter`);
}
} catch (error) {
Sentry.captureException(error);
},
);

if (response.ok) {
const status = await response.text();
return status === "Subscribed";
} else {
throw new Error("Failed to check newsletter subscription");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new function isUserSubscribedToNewsletter correctly checks a user's newsletter subscription status. It's a good addition for enhancing the newsletter management capabilities. However, returning a boolean for subscription status is a bit limiting. Consider returning more detailed information about the subscription status, such as "Not Subscribed", "Subscribed", or "Pending Confirmation", to provide more context to the caller.

-    return status === "Subscribed";
+    return status; // Adjust the return type and handle the detailed status in the caller.

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
export async function isUserSubscribedToNewsletter(email: string) {
const EMAIL_API_ENDPOINT = process.env.EMAIL_API_ENDPOINT;
const EMAIL_API_KEY = process.env.EMAIL_API_KEY;
const EMAIL_NEWSLETTER_ID = process.env.EMAIL_NEWSLETTER_ID;
if (!EMAIL_API_ENDPOINT || !EMAIL_API_KEY || !EMAIL_NEWSLETTER_ID) {
throw new Error("Email API not configured");
}
const payload = new URLSearchParams({
email,
api_key: EMAIL_API_KEY,
list_id: EMAIL_NEWSLETTER_ID,
}).toString();
const response = await fetch(
`${EMAIL_API_ENDPOINT}/api/subscribers/subscription-status.php`,
{
method: "POST",
headers: {
"Content-type": "application/x-www-form-urlencoded",
},
body: payload,
});
if (response.ok) {
return { message: `Successfully ${action}d to the newsletter.` };
} else {
throw new Error(`Failed to ${action} to the newsletter`);
}
} catch (error) {
Sentry.captureException(error);
},
);
if (response.ok) {
const status = await response.text();
return status === "Subscribed";
} else {
throw new Error("Failed to check newsletter subscription");
if (response.ok) {
const status = await response.text();
return status; // Adjust the return type and handle the detailed status in the caller.
} else {
throw new Error("Failed to check newsletter subscription");

Comment on lines 28 to 39
const { email } = ctx.session.user;

if (!email) {
throw new TRPCError({
code: "BAD_REQUEST",
message: "Email not found",
});
}

const newsletter = await isUserSubscribedToNewsletter(email);

if (newsletter !== input.newsletter) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logic added to check the user's email existence and newsletter subscription status before managing the subscription is a good security and usability enhancement. However, there's a redundant email variable declaration inside the if block. Since email is already defined outside, you can remove the redundant declaration to clean up the code.

-        const email = existingProfile?.email;

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
const { email } = ctx.session.user;
if (!email) {
throw new TRPCError({
code: "BAD_REQUEST",
message: "Email not found",
});
}
const newsletter = await isUserSubscribedToNewsletter(email);
if (newsletter !== input.newsletter) {
const { email } = ctx.session.user;
if (!email) {
throw new TRPCError({
code: "BAD_REQUEST",
message: "Email not found",
});
}
const newsletter = await isUserSubscribedToNewsletter(email);
if (newsletter !== input.newsletter) {

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 67d4ada and 2008ce2.
Files selected for processing (1)
  • app/(app)/settings/page.tsx (2 hunks)
Files skipped from review as they are similar to previous changes (1)
  • app/(app)/settings/page.tsx

Copy link

vercel bot commented Feb 26, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
codu ✅ Ready (Inspect) Visit Preview 💬 Add feedback Feb 26, 2024 2:40pm

@NiallJoeMaher NiallJoeMaher merged commit fcd2b57 into codu-code:develop Feb 26, 2024
4 checks passed
@NiallJoeMaher NiallJoeMaher deleted the feat/sync-newsletter-settings branch February 26, 2024 14:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant