Files
cal.diy/packages/trpc/server/routers/viewer/admin/lockUserAccount.handler.ts
T
d3bbed01f6 feat: add signup watchlist review mode (#27912)
* feat: add signup watchlist review feature flag and handler logic

- Add 'signup-watchlist-review' global feature flag
- Add SIGNUP to WatchlistSource enum in Prisma schema
- When flag enabled, lock new signups and add email to watchlist
- Show 'account under review' message on signup page
- Add i18n strings for review UI
- Create seed migration for the feature flag

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* test: add isAccountUnderReview tests to fetchSignup test suite

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* fix: address Cubic AI review feedback (confidence >= 9/10)

- Remove 'import process from node:process' in signup-view.tsx (P0 bug in 'use client' component)
- Move watchlist review check before checkoutSessionId early return in calcomSignupHandler (P1 premium bypass)
- Revert selfHostedHandler to original state (out of scope per user request)
- Add test mocks for FeaturesRepository and GlobalWatchlistRepository

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* fix: remove node:process import from useFlags.ts (client-side file)

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* fix: remove !token condition from watchlist review check

Token is present in normal email-verified signups, so the !token
condition was incorrectly skipping watchlist review for verified users.

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* Apply suggestion from @cubic-dev-ai[bot]

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* refactor: move user lock to UserRepository.lockByEmail

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* refactor: use cached getFeatureRepository() instead of deprecated FeaturesRepository

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* refactor: remove user locking, keep only watchlist addition on signup review

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* feat: lock user on signup review, remove watchlist entry on unlock

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-02-12 23:14:31 +00:00

52 lines
1.2 KiB
TypeScript

import { GlobalWatchlistRepository } from "@calcom/features/watchlist/lib/repository/GlobalWatchlistRepository";
import { normalizeEmail } from "@calcom/features/watchlist/lib/utils/normalization";
import { prisma } from "@calcom/prisma";
import type { TrpcSessionUser } from "../../../types";
import type { TAdminLockUserAccountSchema } from "./lockUserAccount.schema";
type GetOptions = {
ctx: {
user: NonNullable<TrpcSessionUser>;
};
input: TAdminLockUserAccountSchema;
};
const lockUserAccountHandler = async ({ input }: GetOptions) => {
const { userId, locked } = input;
const user = await prisma.user.update({
where: {
id: userId,
},
data: {
locked,
},
select: {
id: true,
email: true,
},
});
if (!user) {
throw new Error("User not found");
}
if (!locked) {
const globalWatchlistRepo = new GlobalWatchlistRepository(prisma);
const normalizedEmail = normalizeEmail(user.email);
const watchlistEntry = await globalWatchlistRepo.findBlockedEmail(normalizedEmail);
if (watchlistEntry) {
await globalWatchlistRepo.deleteEntry(watchlistEntry.id);
}
}
return {
success: true,
userId,
locked,
};
};
export default lockUserAccountHandler;