diff --git a/cypress/e2e/login.cy.ts b/cypress/e2e/login.cy.ts index 507b1b580..506c436b7 100644 --- a/cypress/e2e/login.cy.ts +++ b/cypress/e2e/login.cy.ts @@ -9,9 +9,9 @@ describe('Login tests', () => { defaultCommandTimeout: 10000, }, () => { - cy.getDataTest('input-username').find('input').as('inputUsername').click(); - cy.get('@inputUsername').type(Cypress.env('umami_user'), { delay: 0 }); - cy.get('@inputUsername').click(); + cy.getDataTest('input-username').find('input').as('inputEmail').click(); + cy.get('@inputEmail').type(Cypress.env('umami_email'), { delay: 0 }); + cy.get('@inputEmail').click(); cy.getDataTest('input-password') .find('input') .type(Cypress.env('umami_password'), { delay: 0 }); @@ -25,12 +25,12 @@ describe('Login tests', () => { cy.getDataTest('button-submit').click(); cy.contains(/Required/i).should('be.visible'); - cy.getDataTest('input-username').find('input').as('inputUsername'); - cy.get('@inputUsername').click(); - cy.get('@inputUsername').type(Cypress.env('umami_user'), { delay: 0 }); - cy.get('@inputUsername').click(); + cy.getDataTest('input-username').find('input').as('inputEmail'); + cy.get('@inputEmail').click(); + cy.get('@inputEmail').type(Cypress.env('umami_email'), { delay: 0 }); + cy.get('@inputEmail').click(); cy.getDataTest('input-password').find('input').type('wrongpassword', { delay: 0 }); cy.getDataTest('button-submit').click(); - cy.contains(/Incorrect username and\/or password./i).should('be.visible'); + cy.contains(/Incorrect username and\/or password\./i).should('be.visible'); }); }); diff --git a/db/mysql/schema.prisma b/db/mysql/schema.prisma index 67bd24d22..53479549a 100644 --- a/db/mysql/schema.prisma +++ b/db/mysql/schema.prisma @@ -11,6 +11,8 @@ datasource db { model User { id String @id @unique @map("user_id") @db.VarChar(36) username String @unique @db.VarChar(255) + email String? @unique @db.VarChar(255) + emailVerified DateTime? @map("email_verified") @db.Timestamp(0) password String @db.VarChar(60) role String @map("role") @db.VarChar(50) logoUrl String? @map("logo_url") @db.VarChar(2183) diff --git a/db/postgresql/schema.prisma b/db/postgresql/schema.prisma index 2535f4963..9d7c1ed58 100644 --- a/db/postgresql/schema.prisma +++ b/db/postgresql/schema.prisma @@ -11,6 +11,8 @@ datasource db { model User { id String @id @unique @map("user_id") @db.Uuid username String @unique @db.VarChar(255) + email String? @unique @db.VarChar(255) + emailVerified DateTime? @map("email_verified") @db.Timestamptz(6) password String @db.VarChar(60) role String @map("role") @db.VarChar(50) logoUrl String? @map("logo_url") @db.VarChar(2183) diff --git a/src/app/api/auth/login/route.ts b/src/app/api/auth/login/route.ts index bfac55489..2404d6446 100644 --- a/src/app/api/auth/login/route.ts +++ b/src/app/api/auth/login/route.ts @@ -2,7 +2,7 @@ import { z } from 'zod'; import { checkPassword } from '@/lib/auth'; import { createSecureToken } from '@/lib/jwt'; import redis from '@/lib/redis'; -import { getUserByUsername } from '@/queries'; +import { getUserByEmail } from '@/queries'; import { json, unauthorized } from '@/lib/response'; import { parseRequest } from '@/lib/request'; import { saveAuth } from '@/lib/auth'; @@ -11,7 +11,7 @@ import { ROLES } from '@/lib/constants'; export async function POST(request: Request) { const schema = z.object({ - username: z.string(), + email: z.string().email(), password: z.string(), }); @@ -21,9 +21,9 @@ export async function POST(request: Request) { return error(); } - const { username, password } = body; + const { email, password } = body; - const user = await getUserByUsername(username, { includePassword: true }); + const user = await getUserByEmail(email, { includePassword: true }); if (!user || !checkPassword(password, user.password)) { return unauthorized('message.incorrect-username-password'); @@ -41,6 +41,6 @@ export async function POST(request: Request) { return json({ token, - user: { id, username, role, createdAt, isAdmin: role === ROLES.admin }, + user: { id, username: user.username, role, createdAt, isAdmin: role === ROLES.admin }, }); } diff --git a/src/app/login/LoginForm.tsx b/src/app/login/LoginForm.tsx index 9bc9dfd22..5784f87bb 100644 --- a/src/app/login/LoginForm.tsx +++ b/src/app/login/LoginForm.tsx @@ -20,7 +20,7 @@ export function LoginForm() { const handleSubmit = async (data: any) => { const res = await signIn('credentials', { - username: data.username, + email: data.email, password: data.password, redirect: false, }); @@ -39,13 +39,13 @@ export function LoginForm() {