adonisjs / auth

Official Authentication package for AdonisJS
https://docs.adonisjs.com/guides/auth/introduction
MIT License
193 stars 65 forks source link

Web Guard with Database Provider and RememberMe causes error: "Auth database provider expects "users.id" to always exist" #217

Closed kylanhurt closed 1 year ago

kylanhurt commented 1 year ago

Package version

8.2.3

Node.js and npm version

0.39.3

Repo: https://github.com/telos-crew/telos-comment-indexer/tree/26b2c2f6446d36515c4b2596eb994ebcf639b070

Relevant files: AuthController.ts

  public async validateNonce({ auth, request, response }: HttpContextContract) {
    const { account_name, serializedTransaction, signatures } = request.body()
    const [user] = await Database.query().from('users').where('account_name', account_name)
    const nonce = await Redis.get(`nonce:${account_name}`)
    try {
    // some custom validation
      await auth.use('web').loginViaId(user.id, true)
    } catch (err) {
      return response.status(400).json({ error: err.message })
    }
  }

config/auth.ts

const authConfig: AuthConfig = {
  guard: 'web',
  guards: {
    web: {
      driver: 'session',
      provider: {
        driver: 'database',
        identifierKey: 'id',
        usersTable: 'users',
        connection: 'pg',
        hashDriver: 'argon',
        uids: ['id', 'account_name'],
      },
    },
  },
}

contracts/auth.ts

declare module '@ioc:Adonis/Addons/Auth' {
  interface ProvidersList {
    user: {
      implementation: DatabaseProviderContract<DatabaseProviderRow>
      config: DatabaseProviderConfig
    }
  }

  interface GuardsList {
    web: {
      implementation: SessionGuardContract<'user', 'web'>
      config: SessionGuardConfig<'user'>
      client: SessionClientContract<'user'>
    }
  }
}

The AuthController line await auth.use('web').loginViaId(user.id, true) always seems to cause the Auth database provider expects "users.id" to always exist error message. The one exception is if I set the second param to false / null, then no error is thrown. Specifically, the error seems to be coming from the ensureUserHasId routine, specifically here:

        if (!user[this.config.identifierKey]) {
            throw new utils_1.Exception(`Auth database provider expects "${this.config.usersTable}.${this.config.identifierKey}" to always exist`);
        }

The user variable passed in has the following values:

DatabaseUser {
  user: {
    id: 1,
    account_name: 'captaincrypt',
    remember_me_token: 'ePSYlXesdjJKOlwaJ6lA'
  },
  config: {
...
  },
  hash: Hash {
...
  }
}

As you can see there is no user[this.config.identifierKey] as the ID is nested beneath a user property / object which is inside the user variable that is passed in.

Please let me know if there is anything else that I can do to clarify this issue. Thank you!

Update: Update: it specifically seems like updateRememberMeToken or ensureUserHasId might not know whether it's supposed to be receiving a regular user or ProviderUser

stale[bot] commented 1 year ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.