Skip to content
Merged
20 changes: 18 additions & 2 deletions apps/backend/src/lib/risk-scores.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,17 @@ export type SignUpRiskAssessment = {
export type SignUpRiskRecentStatsRequest = {
signedUpAt: Date,
signUpIp: string | null,
signUpEmailNormalized: string | null,
signUpEmailBase: string | null,
recentWindowHours: number,
sameIpLimit: number,
sameEmailLimit: number,
similarEmailLimit: number,
};

export type SignUpRiskRecentStats = {
sameIpCount: number,
sameEmailCount: number,
similarEmailCount: number,
};

Expand All @@ -64,7 +67,7 @@ async function loadRecentSignUpStats(
const schema = await getPrismaSchemaForTenancy(tenancy);
const windowStart = new Date(request.signedUpAt.getTime() - request.recentWindowHours * 60 * 60 * 1000);

const [sameIpRows, similarEmailRows] = await Promise.all([
const [sameIpRows, sameEmailRows, similarEmailRows] = await Promise.all([
request.signUpIp == null || request.sameIpLimit === 0
? []
: prisma.$replica().$queryRaw<{ matched: number }[]>`
Expand All @@ -77,6 +80,18 @@ async function loadRecentSignUpStats(
LIMIT ${request.sameIpLimit}
`,

request.signUpEmailNormalized == null || request.sameEmailLimit === 0
? []
: prisma.$replica().$queryRaw<{ matched: number }[]>`
SELECT 1 AS "matched"
FROM ${sqlQuoteIdent(schema)}."ProjectUser"
WHERE "tenancyId" = ${tenancy.id}::UUID
AND "isAnonymous" = false
AND "signedUpAt" >= ${windowStart}
AND "signUpEmailNormalized" = ${request.signUpEmailNormalized}
LIMIT ${request.sameEmailLimit}
Comment thread
mantrakp04 marked this conversation as resolved.
`,
Comment thread
mantrakp04 marked this conversation as resolved.

request.signUpEmailBase == null || request.similarEmailLimit === 0
? []
: prisma.$replica().$queryRaw<{ matched: number }[]>`
Expand All @@ -92,6 +107,7 @@ async function loadRecentSignUpStats(

return {
sameIpCount: sameIpRows.length,
sameEmailCount: sameEmailRows.length,
similarEmailCount: similarEmailRows.length,
};
}
Expand Down Expand Up @@ -144,7 +160,7 @@ import.meta.vitest?.test("loaded private sign-up risk engine can calculate score
turnstileAssessment: { status: "ok" },
}, {
checkPrimaryEmailRisk: async () => ({ emailableScore: null }),
loadRecentSignUpStats: async () => ({ sameIpCount: 0, similarEmailCount: 0 }),
loadRecentSignUpStats: async () => ({ sameIpCount: 0, sameEmailCount: 0, similarEmailCount: 0 }),
});

expect(assessment).toMatchInlineSnapshot(`
Expand Down
2 changes: 1 addition & 1 deletion apps/backend/src/private/implementation
19 changes: 7 additions & 12 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading