Hosna QasmeiH
Convex Community2y ago
3 replies
Hosna Qasmei

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,
    });
  },
});
Was this page helpful?