Skip to content

Commit ce6b53b

Browse files
committed
feat: add validatePassword method to throw error when password is invalid
1 parent 399dca1 commit ce6b53b

File tree

2 files changed

+109
-0
lines changed

2 files changed

+109
-0
lines changed

src/mixins/lucid.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { E_INVALID_CREDENTIALS } from '../errors.ts'
1515

1616
type UserWithUserFinderRow = {
1717
verifyPassword(plainPassword: string): Promise<boolean>
18+
validatePassword(plainPassword: string, passwordFieldName?: string): Promise<void>
1819
}
1920

2021
type UserWithUserFinderClass<
@@ -175,6 +176,28 @@ export function withAuthFinder(
175176
}
176177
return hashFactory().verify(passwordHash, plainPassword)
177178
}
179+
180+
async validatePassword(plainPassword: string, passwordFieldName?: string): Promise<void> {
181+
if (!(await this.verifyPassword(plainPassword))) {
182+
const error = new Error('Validation Error')
183+
Object.defineProperty(error, 'code', {
184+
value: 'E_VALIDATION_ERROR',
185+
})
186+
Object.defineProperty(error, 'status', {
187+
value: 422,
188+
})
189+
Object.defineProperty(error, 'messages', {
190+
value: [
191+
{
192+
field: passwordFieldName ?? 'currentPassword',
193+
message: 'The current password is incorrect',
194+
rule: 'current_password',
195+
},
196+
],
197+
})
198+
throw error
199+
}
200+
}
178201
}
179202

180203
return UserWithUserFinder

tests/auth/mixins/with_auth_finder.spec.ts

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,3 +315,89 @@ test.group('withAuthFinder | verify', () => {
315315
)
316316
})
317317
})
318+
319+
test.group('withAuthFinder | verifyPassword', () => {
320+
test('verify if password is valid or invalid', async ({ assert }) => {
321+
const db = await createDatabase()
322+
await createTables(db)
323+
324+
const hash = getHasher()
325+
326+
class User extends compose(
327+
BaseModel,
328+
withAuthFinder(() => hash, {
329+
uids: ['email', 'username'],
330+
passwordColumnName: 'password',
331+
})
332+
) {
333+
@column({ isPrimary: true })
334+
declare id: number
335+
336+
@column()
337+
declare username: string
338+
339+
@column()
340+
declare email: string
341+
342+
@column()
343+
declare password: string
344+
}
345+
346+
const user = await User.create({
347+
username: 'virk',
348+
email: 'virk@adonisjs.com',
349+
password: 'secret',
350+
})
351+
352+
assert.isTrue(await user.verifyPassword('secret'))
353+
assert.isFalse(await user.verifyPassword('foo'))
354+
})
355+
356+
test('throw validation like error when password is invalid', async ({ assert }) => {
357+
assert.plan(3)
358+
const db = await createDatabase()
359+
await createTables(db)
360+
361+
const hash = getHasher()
362+
363+
class User extends compose(
364+
BaseModel,
365+
withAuthFinder(() => hash, {
366+
uids: ['email', 'username'],
367+
passwordColumnName: 'password',
368+
})
369+
) {
370+
@column({ isPrimary: true })
371+
declare id: number
372+
373+
@column()
374+
declare username: string
375+
376+
@column()
377+
declare email: string
378+
379+
@column()
380+
declare password: string
381+
}
382+
383+
const user = await User.create({
384+
username: 'virk',
385+
email: 'virk@adonisjs.com',
386+
password: 'secret',
387+
})
388+
389+
try {
390+
await user.validatePassword('foo')
391+
} catch (error) {
392+
assert.equal(error.code, 'E_VALIDATION_ERROR')
393+
assert.equal(error.status, 422)
394+
assert.deepEqual(error.messages, [
395+
{
396+
field: 'currentPassword',
397+
message: 'The current password is incorrect',
398+
rule: 'current_password',
399+
},
400+
])
401+
}
402+
})
403+
})

0 commit comments

Comments
 (0)