Skip to content

Commit

Permalink
redwoodjs#7787 - Added new usernameMatch to SignupFlowOptions for cas…
Browse files Browse the repository at this point in the history
…e insensitive check on db
  • Loading branch information
ageddesi committed Apr 6, 2023
1 parent 504110d commit b5958f5
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 1 deletion.
22 changes: 21 additions & 1 deletion packages/auth-providers/dbAuth/api/src/DbAuthHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ interface SignupFlowOptions {
usernameTaken?: string
flowNotEnabled?: string
}

/**
* Allows the user to define if the UserCheck for their selected db provider should use case insensitive
*/
usernameMatch?: string
}

interface ForgotPasswordFlowOptions<TUser = Record<string | number, any>> {
Expand Down Expand Up @@ -1282,8 +1287,23 @@ export class DbAuthHandler<
this._validateField('username', username) &&
this._validateField('password', password)
) {

// Each db provider has it owns rules for case insensitive comparison.
// We are checking if you have defined one for your db choice here
// https://www.prisma.io/docs/concepts/components/prisma-client/case-sensitivity
const usernameMatchFlowOption = (this.options.signup as SignupFlowOptions)?.usernameMatch;
const findUniqueUserMatchCriteriaOptions = !usernameMatchFlowOption ?
{ [this.options.authFields.username]: username }
:
{
[this.options.authFields.username]: {
equals: username,
mode: usernameMatchFlowOption
}
}

const user = await this.dbAccessor.findUnique({
where: { [this.options.authFields.username]: username },
where: findUniqueUserMatchCriteriaOptions,
})
if (user) {
throw new DbAuthError.DuplicateUsernameError(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2340,6 +2340,41 @@ describe('dbAuth', () => {
expect.assertions(2)
})

it('createUser db check is called with insensitive string when user has provided one in SignupFlowOptions', async () => {
const spy = jest.spyOn(db.user, 'findUnique');
options.signup.usernameMatch = "insensitive"

const dbUser = await createDbUser()
event.body = JSON.stringify({
username: dbUser.email,
password: 'password',
})
const dbAuth = new DbAuthHandler(event, context, options)

dbAuth._createUser();
expect(spy).toHaveBeenCalled()
expect(spy).toHaveBeenCalledWith({ 'where' : {
'email' : expect.objectContaining({ mode: 'insensitive'})
} })
})

it('createUser db check is not called with insensitive string when user has not provided one in SignupFlowOptions', async () => {
const spy = jest.spyOn(db.user, 'findUnique');
delete options.signup.usernameMatch

const dbUser = await createDbUser()
event.body = JSON.stringify({
username: dbUser.email,
password: 'password',
})
const dbAuth = new DbAuthHandler(event, context, options)

dbAuth._createUser().catch((e) => {})
expect(spy).not.toHaveBeenCalledWith({ 'where' : {
'email' : expect.objectContaining({ mode: 'insensitive'})
} })
})

it('throws a default error message if username is missing', async () => {
const defaultMessage = options.signup.errors.fieldMissing
delete options.signup.errors.fieldMissing
Expand Down

0 comments on commit b5958f5

Please sign in to comment.