Hosna Qasmei
Hosna Qasmei
CCConvex Community
Created by Hosna Qasmei on 9/17/2024 in #support-community
Resources for Implementing User Roles
I'm looking to implement user roles for access control. Does anyone know if there are any specific resources, documentation, or best practices for setting up user roles with next.js, clerk and convex? How to intercept requests and check user roles Best practices for redirecting to role-appropriate routes Handling unauthorized access attempts
6 replies
CCConvex Community
Created by Hosna Qasmei on 7/17/2024 in #support-community
Trying to add rate limiting to newsletter sign up
I have this code, I'm trying to implement rate limiting so I don't get DDOS and to learn how to use it. If a user isn't logged in, and I want to limit based on IP address how would i do that? Also with the convex-helpers @ian , how does it know to increment? Does it just find the item with the same key? How do I get the key to be the IP address? Thank you
import { defineRateLimits } from 'convex-helpers/server/rateLimit';
import { ConvexError, v } from 'convex/values';

import { mutation } from './_generated/server';

const SECOND = 1000; // ms
const MINUTE = 60 * SECOND;
const HOUR = 60 * MINUTE;

const { rateLimit, checkRateLimit, resetRateLimit } = defineRateLimits({
newsletterSignUpRateLimit: { kind: 'fixed window', rate: 3, period: HOUR },
});

export const addEmail = mutation({
args: {
email: v.string(),
subscriptionDate: v.string(),
isActive: v.boolean(),
},
handler: async (ctx, args) => {
// Make sure the rate limit is not exceeded
// const { ok, retryAt } = await rateLimit(ctx, {
// name: 'newsletterSignUpRateLimit',
// });
// if (!ok) return { retryAt };

// Check if email already exists, if so, return error, else insert
const existingEmail = await ctx.db
.query('newsletters')
.withIndex('by_email', (q) => q.eq('email', args.email))
.first();

if (existingEmail) {
throw new ConvexError('Email already exists');
}

return await ctx.db.insert('newsletters', {
email: args.email,
subscriptionDate: args.subscriptionDate,
isActive: args.isActive,
});
},
});
import { defineRateLimits } from 'convex-helpers/server/rateLimit';
import { ConvexError, v } from 'convex/values';

import { mutation } from './_generated/server';

const SECOND = 1000; // ms
const MINUTE = 60 * SECOND;
const HOUR = 60 * MINUTE;

const { rateLimit, checkRateLimit, resetRateLimit } = defineRateLimits({
newsletterSignUpRateLimit: { kind: 'fixed window', rate: 3, period: HOUR },
});

export const addEmail = mutation({
args: {
email: v.string(),
subscriptionDate: v.string(),
isActive: v.boolean(),
},
handler: async (ctx, args) => {
// Make sure the rate limit is not exceeded
// const { ok, retryAt } = await rateLimit(ctx, {
// name: 'newsletterSignUpRateLimit',
// });
// if (!ok) return { retryAt };

// Check if email already exists, if so, return error, else insert
const existingEmail = await ctx.db
.query('newsletters')
.withIndex('by_email', (q) => q.eq('email', args.email))
.first();

if (existingEmail) {
throw new ConvexError('Email already exists');
}

return await ctx.db.insert('newsletters', {
email: args.email,
subscriptionDate: args.subscriptionDate,
isActive: args.isActive,
});
},
});
4 replies
CCConvex Community
Created by Hosna Qasmei on 7/1/2024 in #support-community
What is the best way to implement infinite scrolling with Convex
I have this function to call all the items in a table
export const getPortfolios = query({
handler: async (ctx) => {
return await ctx.db.query('portfolios').collect();
},
});
export const getPortfolios = query({
handler: async (ctx) => {
return await ctx.db.query('portfolios').collect();
},
});
I want to implement infinite scrolling, so rather than overloading the app only show more items when scrolling wanted to know if there is a way I can do this server side rather than client side.
64 replies
CCConvex Community
Created by Hosna Qasmei on 6/20/2024 in #support-community
Download Table data as a CSV from Convex Dashboard
No description
9 replies
CCConvex Community
Created by Hosna Qasmei on 6/14/2024 in #support-community
How do you call a function from a sub file in python
No description
12 replies
CCConvex Community
Created by Hosna Qasmei on 5/1/2024 in #support-community
Querying Data in the Server to Show in Metadata
import React, { ReactNode } from 'react';

import type { Metadata } from 'next';

import { Id } from '@/convex/_generated/dataModel';
import { fetchQuery } from 'convex/nextjs';

import { api } from '../../../../../convex/_generated/api';
import ProjectWrapper from './project-wrapper';

type Props = {
params: { planId: string };
};

export async function generateMetadata({ params }: Props): Promise<Metadata> {
// read route params
const id = params.planId;
const plan = await fetchQuery(api.plans.queries.getUserPlan, {
planId: id as Id<'plans'>,
});

const projectName = plan?.projectName;
console.log(plan);

return {
title: projectName,
};
}

export default function PlanLayout({ children }: { children: ReactNode }) {
return <ProjectWrapper>{children}</ProjectWrapper>;
}
import React, { ReactNode } from 'react';

import type { Metadata } from 'next';

import { Id } from '@/convex/_generated/dataModel';
import { fetchQuery } from 'convex/nextjs';

import { api } from '../../../../../convex/_generated/api';
import ProjectWrapper from './project-wrapper';

type Props = {
params: { planId: string };
};

export async function generateMetadata({ params }: Props): Promise<Metadata> {
// read route params
const id = params.planId;
const plan = await fetchQuery(api.plans.queries.getUserPlan, {
planId: id as Id<'plans'>,
});

const projectName = plan?.projectName;
console.log(plan);

return {
title: projectName,
};
}

export default function PlanLayout({ children }: { children: ReactNode }) {
return <ProjectWrapper>{children}</ProjectWrapper>;
}
8 replies
CCConvex Community
Created by Hosna Qasmei on 4/22/2024 in #support-community
is it possible to query .order based on a variable?
No description
5 replies
CCConvex Community
Created by Hosna Qasmei on 3/28/2024 in #support-community
Can’t delete Log Stream Integration
No description
4 replies
CCConvex Community
Created by Hosna Qasmei on 3/2/2024 in #support-community
Is it possible to call a mutation in a Next.js API route?
I am trying to implement Stripe Oauth into my Next.js app. I get the users user id and access tokens from an api route, /api/stripe/verify. When I get those values I wanted to create a row in my convex table, but the only way it work is with use client. Wanted to know what the best approach for this is. Here is the code I'm referring too

import { NextResponse } from 'next/server';

import { stripe } from '@/lib/stripe';
import { useMutation, useQuery } from 'convex/react';

import { api } from '../../../../../convex/_generated/api';
import { Id } from '../../../../../convex/_generated/dataModel';

// Main POST handler
export async function POST(req: Request): Promise<NextResponse> {
const addIntegration = useMutation(api.integrations.addIntegrationByUser);
try {
const body = await req.json();
const code = body.codeId;

const result = await stripe.oauth
.token({
grant_type: 'authorization_code',
code: code,
})
.catch((err: unknown) => {
console.log(err);
});
if (result) {
await addIntegration({
planId: '' as Id<'plans'>,
userId: '',
integration: '',
value: [
{
stripeUserId: result.stripe_user_id,
accessToken: result.access_token,
refreshToken: result.refresh_token,
},
],
});
}

console.log(result);
return NextResponse.json({ test: '' });
} catch (error) {
console.error('[PROJECT_POST]', error);
return new NextResponse('Internal Server Error', { status: 500 });
}
}

import { NextResponse } from 'next/server';

import { stripe } from '@/lib/stripe';
import { useMutation, useQuery } from 'convex/react';

import { api } from '../../../../../convex/_generated/api';
import { Id } from '../../../../../convex/_generated/dataModel';

// Main POST handler
export async function POST(req: Request): Promise<NextResponse> {
const addIntegration = useMutation(api.integrations.addIntegrationByUser);
try {
const body = await req.json();
const code = body.codeId;

const result = await stripe.oauth
.token({
grant_type: 'authorization_code',
code: code,
})
.catch((err: unknown) => {
console.log(err);
});
if (result) {
await addIntegration({
planId: '' as Id<'plans'>,
userId: '',
integration: '',
value: [
{
stripeUserId: result.stripe_user_id,
accessToken: result.access_token,
refreshToken: result.refresh_token,
},
],
});
}

console.log(result);
return NextResponse.json({ test: '' });
} catch (error) {
console.error('[PROJECT_POST]', error);
return new NextResponse('Internal Server Error', { status: 500 });
}
}
3 replies
CCConvex Community
Created by Hosna Qasmei on 2/28/2024 in #support-community
_creationTime schema setup
No description
51 replies
CCConvex Community
Created by Hosna Qasmei on 2/23/2024 in #support-community
Jupyter Notebook + Convex
Wanted to know if it's possible to use convex to upload a value into a table from values calculated using python in Jupyter Notebook? It seems like there isn't because you have to be running the convex server, just wanted to double check.
26 replies
CCConvex Community
Created by Hosna Qasmei on 1/19/2024 in #support-community
Any good resources for Convex + Resend?
Hi, I'm looking if there are any docs on using resend with convex
6 replies