fix: corrects local strategy user lookup when using loginWithUsername (#7587)

## Description

Fixes the local strategy user lookup.

- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

- [x] Bug fix (non-breaking change which fixes an issue)

## Checklist:

- [x] I have added tests that prove my fix is effective or that my
feature works
- [ ] Existing test suite passes locally with my changes
- [ ] I have made corresponding changes to the documentation
This commit is contained in:
Jarrod Flesch
2024-08-08 19:51:12 -04:00
committed by GitHub
parent ee62ed6ebb
commit 6227276d2c
2 changed files with 86 additions and 28 deletions

View File

@@ -1,6 +1,6 @@
import type { SanitizedCollectionConfig } from '../../../collections/config/types.js'
import type { JsonObject, Payload } from '../../../index.js'
import type { PayloadRequest } from '../../../types/index.js'
import type { PayloadRequest, Where } from '../../../types/index.js'
import { ValidationError } from '../../../errors/index.js'
import { generatePasswordSaltHash } from './generatePasswordSaltHash.js'
@@ -22,23 +22,43 @@ export const registerLocalStrategy = async ({
}: Args): Promise<Record<string, unknown>> => {
const loginWithUsername = collection?.auth?.loginWithUsername
let whereConstraint: Where
if (!loginWithUsername) {
whereConstraint = {
email: {
equals: doc.email,
},
}
} else {
whereConstraint = {
or: [],
}
if (doc.email) {
whereConstraint.or.push({
email: {
equals: doc.email,
},
})
}
if (doc.username) {
whereConstraint.or.push({
username: {
equals: doc.username,
},
})
}
}
const existingUser = await payload.find({
collection: collection.slug,
depth: 0,
limit: 1,
pagination: false,
req,
where: loginWithUsername
? {
username: {
equals: doc.username,
},
}
: {
email: {
equals: doc.email,
},
},
where: whereConstraint,
})
if (existingUser.docs.length > 0) {

View File

@@ -17,22 +17,20 @@ describe('Login With Username Feature', () => {
}
})
describe('hook execution', () => {
it('should not allow creation with neither email nor username', async () => {
let errors = []
try {
await payload.create({
collection: 'login-with-either',
data: {
email: null,
username: null,
},
})
} catch (error) {
errors = error.data.errors
}
expect(errors).toHaveLength(2)
})
it('should not allow creation with neither email nor username', async () => {
let errors = []
try {
await payload.create({
collection: 'login-with-either',
data: {
email: null,
username: null,
},
})
} catch (error) {
errors = error.data.errors
}
expect(errors).toHaveLength(2)
})
it('should not allow removing both username and email fields', async () => {
@@ -115,4 +113,44 @@ describe('Login With Username Feature', () => {
})
expect(loginWithUsername).toHaveProperty('token')
})
it('should allow mutliple creates with optional email and username', async () => {
// create a user with just email
await payload.create({
collection: 'login-with-either',
data: {
email: 'email1@mail.com',
password: 'test',
},
})
// create second user with just email
const emailUser2 = await payload.create({
collection: 'login-with-either',
data: {
email: 'email2@mail.com',
password: 'test',
},
})
expect(emailUser2).toHaveProperty('id')
// create user with just username
await payload.create({
collection: 'login-with-either',
data: {
username: 'username1',
password: 'test',
},
})
// create second user with just username
const usernameUser2 = await payload.create({
collection: 'login-with-either',
data: {
username: 'username2',
password: 'test',
},
})
expect(usernameUser2).toHaveProperty('id')
})
})