diff --git a/apps/api/src/common/user.ts b/apps/api/src/common/user.ts index 9dec9dbc..db257364 100644 --- a/apps/api/src/common/user.ts +++ b/apps/api/src/common/user.ts @@ -21,7 +21,7 @@ export async function createUser( const user = await prisma.user.create({ data: { id: dto.id, - email: dto.email, + email: dto.email.toLowerCase(), name: dto.name, profilePictureUrl: dto.profilePictureUrl, isActive: dto.isActive ?? true, @@ -69,7 +69,7 @@ export async function getUserByEmailOrId( const user = (await prisma.user.findUnique({ where: { - email: input + email: input.toLowerCase() } })) ?? (await prisma.user.findUnique({ diff --git a/apps/api/src/common/util.ts b/apps/api/src/common/util.ts index d3a72e54..26413fb2 100644 --- a/apps/api/src/common/util.ts +++ b/apps/api/src/common/util.ts @@ -68,7 +68,7 @@ export const generateOtp = async ( expiresAt: new Date(new Date().getTime() + OTP_EXPIRY), user: { connect: { - email + email: email.toLowerCase() } } } diff --git a/apps/api/src/prisma/migrations/20250207132819_update_user_email_lowercase/migration.sql b/apps/api/src/prisma/migrations/20250207132819_update_user_email_lowercase/migration.sql new file mode 100644 index 00000000..282cde9d --- /dev/null +++ b/apps/api/src/prisma/migrations/20250207132819_update_user_email_lowercase/migration.sql @@ -0,0 +1,3 @@ +-- Update table +UPDATE public."User" +SET "email" = LOWER("email"); \ No newline at end of file diff --git a/apps/api/src/project/project.e2e.spec.ts b/apps/api/src/project/project.e2e.spec.ts index a5fbc5ef..30f4a075 100644 --- a/apps/api/src/project/project.e2e.spec.ts +++ b/apps/api/src/project/project.e2e.spec.ts @@ -269,7 +269,7 @@ describe('Project Controller Tests', () => { expect(adminRole).toBeDefined() expect(adminRole.projects).toHaveLength(2) - expect(adminRole.projects[0].projectId).toBe(project1.id) + expect(adminRole.projects).toContainEqual({ projectId: project1.id }) }) it('should not let non-member create a project', async () => { diff --git a/apps/api/src/user/service/user.service.ts b/apps/api/src/user/service/user.service.ts index 74425baa..b0b90681 100644 --- a/apps/api/src/user/service/user.service.ts +++ b/apps/api/src/user/service/user.service.ts @@ -46,7 +46,7 @@ export class UserService { const userExists = (await this.prisma.user.count({ where: { - email: dto.email + email: dto.email.toLowerCase() } })) > 0 @@ -61,10 +61,10 @@ export class UserService { otpId: otp.id }, update: { - newEmail: dto.email + newEmail: dto.email.toLowerCase() }, create: { - newEmail: dto.email, + newEmail: dto.email.toLowerCase(), otpId: otp.id } }) @@ -101,7 +101,7 @@ export class UserService { const userExists = (await this.prisma.user.count({ where: { - email: dto.email + email: dto.email.toLowerCase() } })) > 0 @@ -115,7 +115,7 @@ export class UserService { id: userId }, data: { - email: dto.email, + email: dto.email.toLowerCase(), authProvider: AuthProvider.EMAIL_OTP } }) @@ -169,7 +169,7 @@ export class UserService { id: user.id }, data: { - email: userEmailChange.newEmail, + email: userEmailChange.newEmail.toLowerCase(), authProvider: AuthProvider.EMAIL_OTP } }) @@ -240,7 +240,7 @@ export class UserService { }, { email: { - contains: search + contains: search.toLowerCase() } } ] @@ -277,14 +277,14 @@ export class UserService { this.log.log(`Deleted user ${userId}`) } - async createUser(user: CreateUserDto) { - this.log.log(`Creating user with email ${user.email}`) + async createUser(dto: CreateUserDto) { + this.log.log(`Creating user with email ${dto.email}`) // Check for duplicate user const checkDuplicateUser = (await this.prisma.user.count({ where: { - email: user.email + email: dto.email.toLowerCase() } })) > 0 if (checkDuplicateUser) { @@ -292,16 +292,16 @@ export class UserService { } // Create the user's default workspace along with user - const userWithWorkspace = await createUser( - { authProvider: AuthProvider.EMAIL_OTP, ...user }, + const createdUser = await createUser( + { authProvider: AuthProvider.EMAIL_OTP, ...dto }, this.prisma ) - this.log.log(`Created user with email ${user.email}`) + this.log.log(`Created user with email ${createdUser.email}`) - await this.mailService.accountLoginEmail(userWithWorkspace.email) - this.log.log(`Sent login email to ${user.email}`) + await this.mailService.accountLoginEmail(createdUser.email) + this.log.log(`Sent login email to ${createdUser.email}`) - return userWithWorkspace + return createdUser } private async createDummyUser() { diff --git a/apps/api/src/user/user.e2e.spec.ts b/apps/api/src/user/user.e2e.spec.ts index 2beb48a5..83111d61 100644 --- a/apps/api/src/user/user.e2e.spec.ts +++ b/apps/api/src/user/user.e2e.spec.ts @@ -46,7 +46,7 @@ describe('User Controller Tests', () => { }) regularUser = await userService.createUser({ - email: 'john@keyshade.xyz', + email: 'John@keyshade.xyz', name: 'John', isActive: true, isAdmin: false, @@ -259,8 +259,8 @@ describe('User Controller Tests', () => { 'x-e2e-user-email': adminUser.email }, payload: { - email: adminUser.email, - name: 'Admin', + email: regularUser.email.toUpperCase(), + name: regularUser.name, isAdmin: false, isActive: true, isOnboardingFinished: true @@ -375,7 +375,7 @@ describe('User Controller Tests', () => { userId: regularUser.id, AND: { emailChange: { - newEmail: 'newEmail@keyshade.xyz' + newEmail: 'newemail@keyshade.xyz' } } } @@ -399,7 +399,7 @@ describe('User Controller Tests', () => { expect(result.statusCode).toEqual(200) expect(JSON.parse(result.body)).toEqual({ ...regularUser, - email: 'newEmail@keyshade.xyz' + email: 'newemail@keyshade.xyz' }) const updatedUser = await prisma.user.findUnique({ @@ -408,7 +408,7 @@ describe('User Controller Tests', () => { } }) - expect(updatedUser.email).toEqual('newEmail@keyshade.xyz') + expect(updatedUser.email).toEqual('newemail@keyshade.xyz') }) it('should give error when new email is used by an existing user', async () => { diff --git a/apps/api/src/workspace-membership/service/workspace-membership.service.ts b/apps/api/src/workspace-membership/service/workspace-membership.service.ts index d0e6f57a..9823b71d 100644 --- a/apps/api/src/workspace-membership/service/workspace-membership.service.ts +++ b/apps/api/src/workspace-membership/service/workspace-membership.service.ts @@ -264,7 +264,7 @@ export class WorkspaceMembershipService { .findMany({ where: { email: { - in: userEmails + in: userEmails.map((email) => email.toLowerCase()) } }, select: { @@ -489,7 +489,7 @@ export class WorkspaceMembershipService { }, { email: { - contains: search + contains: search.toLowerCase() } } ] @@ -534,7 +534,7 @@ export class WorkspaceMembershipService { }, { email: { - contains: search + contains: search.toLowerCase() } } ] @@ -841,7 +841,7 @@ export class WorkspaceMembershipService { const memberUser: User | null = await this.prisma.user.findUnique({ where: { - email: member.email + email: member.email.toLowerCase() } }) diff --git a/apps/platform/src/app/(main)/project/[project]/@variable/page.tsx b/apps/platform/src/app/(main)/project/[project]/@variable/page.tsx index 855faa1f..89e52d8a 100644 --- a/apps/platform/src/app/(main)/project/[project]/@variable/page.tsx +++ b/apps/platform/src/app/(main)/project/[project]/@variable/page.tsx @@ -122,9 +122,7 @@ function VariablePage(): React.JSX.Element { ) : null} {/* Edit variable sheet */} - {isEditVariableOpen && selectedVariable ? ( - - ) : null} + {isEditVariableOpen && selectedVariable ? : null} )} diff --git a/apps/platform/src/components/dashboard/project/editProjectSheet/index.tsx b/apps/platform/src/components/dashboard/project/editProjectSheet/index.tsx index 31954aa7..d26ef928 100644 --- a/apps/platform/src/components/dashboard/project/editProjectSheet/index.tsx +++ b/apps/platform/src/components/dashboard/project/editProjectSheet/index.tsx @@ -15,20 +15,23 @@ import { Button } from '@/components/ui/button' import { Label } from '@/components/ui/label' import { Input } from '@/components/ui/input' import { Switch } from '@/components/ui/switch' -import { - editProjectOpenAtom, +import { + editProjectOpenAtom, selectedProjectAtom, - projectsOfWorkspaceAtom + projectsOfWorkspaceAtom } from '@/store' import ControllerInstance from '@/lib/controller-instance' export default function EditProjectSheet(): JSX.Element { - const [isEditProjectSheetOpen, setIsEditProjectSheetOpen] = useAtom(editProjectOpenAtom) - const [selectedProject , setSelectedProject] = useAtom(selectedProjectAtom) + const [isEditProjectSheetOpen, setIsEditProjectSheetOpen] = + useAtom(editProjectOpenAtom) + const [selectedProject, setSelectedProject] = useAtom(selectedProjectAtom) const [projects, setProjects] = useAtom(projectsOfWorkspaceAtom) const [isLoading, setIsLoading] = useState(false) - const [formData, setFormData] = useState>({ + const [formData, setFormData] = useState< + Omit + >({ name: '', description: '', storePrivateKey: false @@ -64,11 +67,14 @@ export default function EditProjectSheet(): JSX.Element { const changes: Partial> = {} - if (formData.name !== undefined && formData.name !== selectedProject.name) { - changes.name = formData.name.trim() + if (formData.name !== undefined && formData.name !== selectedProject.name) { + changes.name = formData.name.trim() } - - if (formData.description !== undefined && formData.description!== selectedProject.description) { + + if ( + formData.description !== undefined && + formData.description !== selectedProject.description + ) { changes.description = formData.description.trim() } if (formData.storePrivateKey !== selectedProject.storePrivateKey) { @@ -97,22 +103,26 @@ export default function EditProjectSheet(): JSX.Element { } setIsLoading(true) - + const updateRequest: UpdateProjectRequest = { projectSlug: selectedProject.slug, ...changes } - const { data, error, success } = await ControllerInstance.getInstance() - .projectController.updateProject(updateRequest) + const { data, error, success } = + await ControllerInstance.getInstance().projectController.updateProject( + updateRequest + ) if (success && data) { - setProjects(projects.map(project => - project.slug === selectedProject.slug - ? { ...project, ...data } - : project - )) - + setProjects( + projects.map((project) => + project.slug === selectedProject.slug + ? { ...project, ...data } + : project + ) + ) + toast.success('Project updated successfully') setIsEditProjectSheetOpen(false) setSelectedProject(null) @@ -195,4 +205,4 @@ export default function EditProjectSheet(): JSX.Element { ) -} \ No newline at end of file +} diff --git a/apps/platform/src/components/dashboard/project/projectCard/index.tsx b/apps/platform/src/components/dashboard/project/projectCard/index.tsx index 3d38d3a0..1a847f8b 100644 --- a/apps/platform/src/components/dashboard/project/projectCard/index.tsx +++ b/apps/platform/src/components/dashboard/project/projectCard/index.tsx @@ -167,4 +167,4 @@ export default function ProjectCard({ ) -} \ No newline at end of file +} diff --git a/apps/web/src/instrumentation.ts b/apps/web/src/instrumentation.ts index 8aff09f0..af853730 100644 --- a/apps/web/src/instrumentation.ts +++ b/apps/web/src/instrumentation.ts @@ -1,13 +1,13 @@ -import * as Sentry from '@sentry/nextjs'; +import * as Sentry from '@sentry/nextjs' export async function register() { if (process.env.NEXT_RUNTIME === 'nodejs') { - await import('../sentry.server.config'); + await import('../sentry.server.config') } if (process.env.NEXT_RUNTIME === 'edge') { - await import('../sentry.edge.config'); + await import('../sentry.edge.config') } } -export const onRequestError = Sentry.captureRequestError; +export const onRequestError = Sentry.captureRequestError