Skip to content

Add playbook persistence, nudges, and dashboard#4

Open
ecatuogno1 wants to merge 1 commit intomainfrom
codex/define-prisma-models-and-seed-scripts
Open

Add playbook persistence, nudges, and dashboard#4
ecatuogno1 wants to merge 1 commit intomainfrom
codex/define-prisma-models-and-seed-scripts

Conversation

@ecatuogno1
Copy link
Copy Markdown
Owner

Summary

  • define Prisma schema for playbook articles, tags, user preferences, and nudge queue with seed data
  • add MDX content management utilities, metric evaluation rules, and delivery queue integrations
  • surface tailored playbook recommendations with filters and opt-in controls on the new dashboard route

Testing

  • npm run lint

https://chatgpt.com/codex/tasks/task_e_690bf5719b10832dad6051a056afa5a2

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +23 to +32
export default async function PlaybookPage({
searchParams
}: {
searchParams?: { userId?: string };
}) {
const userId = searchParams?.userId ?? fallbackUserId;

const preference = await prisma.userPreference.findUnique({
where: { userId },
include: {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Derive playbook userId from session instead of query string

The page pulls userId straight from searchParams and uses it to load preferences and saved articles. Because there is no authentication or verification, any visitor can hit /playbook?userId=<someone> and retrieve another user’s saved items and opt‑in state, and the value is forwarded to client components where it is later used for mutations. The user identifier should come from the authenticated session (or the query string should be ignored) to avoid leaking account data.

Useful? React with 👍 / 👎.

Comment on lines +12 to +16
export const updateDeliveryOptIns = async (userId: string, payload: OptInPayload) => {
await prisma.userPreference.update({
where: { userId },
data: payload
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Server actions allow updating any user by supplying a forged userId

Both server actions accept a userId argument from the client and use it directly in Prisma updates. A malicious caller can invoke these actions with someone else’s ID (e.g. via ?userId= on the dashboard) and change their delivery opt‑ins or saved articles without any ownership check. Instead, derive the user ID from the authenticated request context before running the mutation, or validate that the supplied ID belongs to the current user.

Useful? React with 👍 / 👎.

Comment on lines +35 to +49
export async function GET(request: Request) {
const { searchParams } = new URL(request.url);
const userId = searchParams.get('userId');

const nudges = await prisma.nudge.findMany({
where: userId
? {
preference: {
userId
}
}
: undefined,
orderBy: { createdAt: 'desc' },
take: 25
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge GET /api/nudges leaks all users’ nudges when userId is omitted

The GET handler executes prisma.nudge.findMany with where: undefined whenever no userId query parameter is provided, returning the latest 25 nudges across every user. Because the route has no authentication, any caller can enumerate other users’ notifications. The handler should reject requests without a user identifier and ensure the identifier belongs to the authenticated user before returning data.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant