### What? Prevents decrypted apiKey from being saved back to database on the auth refresh operation. ### Why? References issue #13063: refreshing a token for a logged-in user decrypted `apiKey` and wrote it back in plaintext, corrupting the user record. ### How? The user is now fetched with `db.findOne` instead of `findByID`, preserving the encryption of the key when saved back to the database using `db.updateOne`. The user record is then re-fetched using `findByID`, allowing for the decrypted key to be provided in the response. ### Tests * ✅ keeps apiKey encrypted in DB after refresh * ✅ returns user with decrypted apiKey after refresh Fixes #13063
This commit is contained in:
@@ -262,6 +262,42 @@ describe('Auth', () => {
|
||||
expect(data.user.custom).toBe('Goodbye, world!')
|
||||
})
|
||||
|
||||
it('keeps apiKey encrypted in DB after refresh operation', async () => {
|
||||
const apiKey = '987e6543-e21b-12d3-a456-426614174999'
|
||||
const user = await payload.create({
|
||||
collection: slug,
|
||||
data: { email: 'user@example.com', password: 'Password123', apiKey, enableAPIKey: true },
|
||||
})
|
||||
const { token } = await payload.login({
|
||||
collection: 'users',
|
||||
data: { email: 'user@example.com', password: 'Password123' },
|
||||
})
|
||||
await restClient.POST('/users/refresh-token', {
|
||||
headers: { Authorization: `JWT ${token}` },
|
||||
})
|
||||
const raw = await payload.db.findOne<any>({
|
||||
collection: 'users',
|
||||
req: { locale: 'en' } as any,
|
||||
where: { id: { equals: user.id } },
|
||||
})
|
||||
expect(raw?.apiKey).not.toContain('-') // still ciphertext
|
||||
})
|
||||
|
||||
it('returns a user with decrypted apiKey after refresh', async () => {
|
||||
const { token } = await payload.login({
|
||||
collection: 'users',
|
||||
data: { email: 'user@example.com', password: 'Password123' },
|
||||
})
|
||||
|
||||
const res = await restClient
|
||||
.POST('/users/refresh-token', {
|
||||
headers: { Authorization: `JWT ${token}` },
|
||||
})
|
||||
.then((r) => r.json())
|
||||
|
||||
expect(res.user.apiKey).toMatch(/[0-9a-f-]{36}/) // UUID string
|
||||
})
|
||||
|
||||
it('should allow a user to be created', async () => {
|
||||
const response = await restClient.POST(`/${slug}`, {
|
||||
body: JSON.stringify({
|
||||
|
||||
Reference in New Issue
Block a user