diff --git a/src/app/api/users/[userId]/route.ts b/src/app/api/users/[userId]/route.ts index e642fe3c1..383f0ffac 100644 --- a/src/app/api/users/[userId]/route.ts +++ b/src/app/api/users/[userId]/route.ts @@ -24,7 +24,10 @@ export async function GET(request: Request, { params }: { params: Promise<{ user return json(user); } -export async function POST(request: Request, { params }: { params: Promise<{ userId: string }> }) { +export async function POST( + request: Request, + { params }: { params: Promise<{ userId: string }> }, +) { const schema = z.object({ username: z.string().max(255).optional(), password: z.string().min(8).max(255).optional(), @@ -63,15 +66,15 @@ export async function POST(request: Request, { params }: { params: Promise<{ use } if (username && auth.user.isAdmin) { - data.username = username; + data.username = username.toLowerCase(); } // Check when username changes if (data.username && user.username !== data.username) { - const user = await getUserByUsername(username); + const existingUser = await getUserByUsername(username); - if (user) { - return badRequest({ message: 'User already exists' }); + if (existingUser && existingUser.id !== userId) { + return badRequest({ message: "User already exists" }); } } @@ -97,7 +100,7 @@ export async function DELETE( } if (userId === auth.user.id) { - return badRequest({ message: 'You cannot delete yourself.' }); + return badRequest({ message: "You cannot delete yourself." }); } await deleteUser(userId); diff --git a/src/app/api/users/route.ts b/src/app/api/users/route.ts index 4335c33fb..d70faba06 100644 --- a/src/app/api/users/route.ts +++ b/src/app/api/users/route.ts @@ -28,15 +28,17 @@ export async function POST(request: Request) { const { id, username, password, role } = body; - const existingUser = await getUserByUsername(username, { showDeleted: true }); + const existingUser = await getUserByUsername(username, { + showDeleted: true, + }); if (existingUser) { - return badRequest({ message: 'User already exists' }); + return badRequest({ message: "User already exists" }); } const user = await createUser({ id: id || uuid(), - username, + username: username.toLowerCase(), password: hashPassword(password), role: role ?? ROLES.user, }); diff --git a/src/queries/prisma/user.ts b/src/queries/prisma/user.ts index 467ea1e02..4893bb1b3 100644 --- a/src/queries/prisma/user.ts +++ b/src/queries/prisma/user.ts @@ -1,8 +1,8 @@ -import { Prisma } from '@/generated/prisma/client'; -import { ROLES } from '@/lib/constants'; -import { getRandomChars } from '@/lib/generate'; -import prisma from '@/lib/prisma'; -import type { QueryFilters, Role } from '@/lib/types'; +import { Prisma } from "@/generated/prisma/client"; +import { ROLES } from "@/lib/constants"; +import { getRandomChars } from "@/lib/generate"; +import prisma from "@/lib/prisma"; +import type { QueryFilters, Role } from "@/lib/types"; import UserFindManyArgs = Prisma.UserFindManyArgs; @@ -11,7 +11,10 @@ export interface GetUserOptions { showDeleted?: boolean; } -async function findUser(criteria: Prisma.UserFindUniqueArgs, options: GetUserOptions = {}) { +async function findUser( + criteria: Prisma.UserFindUniqueArgs, + options: GetUserOptions = {}, +) { const { includePassword = false, showDeleted = false } = options; return prisma.client.user.findUnique({ @@ -41,27 +44,33 @@ export async function getUser(userId: string, options: GetUserOptions = {}) { ); } -export async function getUserByUsername(username: string, options: GetUserOptions = {}) { - return findUser({ where: { username } }, options); +export async function getUserByUsername( + username: string, + options: GetUserOptions = {}, +) { + return findUser({ where: { username: username.toLowerCase() } }, options); } -export async function getUsers(criteria: UserFindManyArgs, filters: QueryFilters = {}) { +export async function getUsers( + criteria: UserFindManyArgs, + filters: QueryFilters = {}, +) { const { search } = filters; const where: Prisma.UserWhereInput = { ...criteria.where, - ...prisma.getSearchParameters(search, [{ username: 'contains' }]), + ...prisma.getSearchParameters(search, [{ username: "contains" }]), deletedAt: null, }; return prisma.pagedQuery( - 'user', + "user", { ...criteria, where, }, { - orderBy: 'createdAt', + orderBy: "createdAt", sortDescending: true, ...filters, }, @@ -110,7 +119,7 @@ export async function deleteUser(userId: string) { let websiteIds = []; if (websites.length > 0) { - websiteIds = websites.map(a => a.id); + websiteIds = websites.map((a) => a.id); } const teams = await client.team.findMany({ @@ -124,7 +133,7 @@ export async function deleteUser(userId: string) { }, }); - const teamIds = teams.map(a => a.id); + const teamIds = teams.map((a) => a.id); if (cloudMode) { return transaction([