-
Notifications
You must be signed in to change notification settings - Fork 1k
Description
What's not working?
Under the current default setup of dbAuth, the forgotPasswordOptions handler in api/src/functions/auth.ts file lists an example url that incorrectly states an object to access the raw resetToken.
The default file generation looks like this:
export const handler = async (
event: APIGatewayProxyEvent,
context: Context
) => {
const forgotPasswordOptions: DbAuthHandlerOptions['forgotPassword'] = {
// handler() is invoked after verifying that a user was found with the given
// username. This is where you can send the user an email with a link to
// reset their password. With the default dbAuth routes and field names, the
// URL to reset the password will be:
//
// https://example.com/reset-password?resetToken=${user.resetToken}
//
// Whatever is returned from this function will be returned from
// the `forgotPassword()` function that is destructured from `useAuth()`
// You could use this return value to, for example, show the email
// address in a toast message so the user will know it worked and where
// to look for the email.
handler: (user) => {
return user
},
// How long the resetToken is valid for, in seconds (default is 24 hours)
expires: 60 * 60 * 24,
errors: {
// for security reasons you may want to be vague here rather than expose
// the fact that the email address wasn't found (prevents fishing for
// valid email addresses)
usernameNotFound: 'Username not found',
// if the user somehow gets around client validation
usernameRequired: 'Username is required',
},
}
The example url suggests implementing an email link by accessing user.resetToken, but this returns undefined (presumably since only allowedUserFields are returned, though I'm not sure what values are attached to the user object, and what values are simply not allowed since this is resolved internally via the DbAuthHandlerOptions). IF, allowedUserFields includes 'resetToken', this token could be exposed to the user object, and would then result in an error as this would expose the hashed token in the url (and the reset password page/ validateToken() functions expect a raw token, that is then hashed and compared to the database hashed token).
In this case, event is the User object (of type UserType), and the context is the raw resetToken before it is hashed and stored in the database. This means that the correct example URL in the commented out example should exist within the handler function as follows:
handler: (user, context) => {
// Example URL should provide context, the raw resetToken, which would be sent via email, or text, etc, THEN return the user to the client with allowedUserFields to provide a verification to client UI (message successfully sent to ${user.email}!
// https://example.com/reset-password?resetToken=${context}
return user
},
I had to dig in the node modules .d.ts files to see how this handler function works in the auth.ts file, and it is unclear that the context within the forgotPasswordOptions returns the raw token 'resetToken' before it is hashed and stored in the db. This is due in part to the handler.d.ts file showing generic 'event', and 'context', values that are used across all of the individual handler() {} helper functions for each auth use case. The individual handler params returned within each function are not specified in the node modules ts files, and also do not have sufficient comments within the code blocks (at least for forgotPassword to show that the context would be the rawToken that would be used to actually reset a password).
I am also unsure if this should be classified as a bug, specifically, as it only provides a suggested code. However, if uncommented with a valid base url, the example URL within the function would result in an error.
How do we reproduce the bug?
From a fresh redwood installation using redwood version 8.6.1, I added auth via yarn rw setup auth dbAuth
. This generated the above example within my api/src/functions/auth.ts file.
What's your environment? (If it applies)
System:
OS: macOS 15.4
Shell: 5.9 - /bin/zsh
Binaries:
Node: 20.19.0 - /private/var/folders/pp/jhdtr7112wv2mmdj6vnwgnhr0000gn/T/xfs-56146c55/node
Yarn: 4.6.0 - /private/var/folders/pp/jhdtr7112wv2mmdj6vnwgnhr0000gn/T/xfs-56146c55/yarn
Databases:
SQLite: 3.43.2 - /usr/bin/sqlite3
Browsers:
Chrome: 135.0.7049.96
Safari: 18.4
npmPackages:
@redwoodjs/auth-dbauth-setup: 8.6.1 => 8.6.1
@redwoodjs/cli-storybook-vite: 8.6.1 => 8.6.1
@redwoodjs/core: 8.6.1 => 8.6.1
@redwoodjs/project-config: 8.6.1 => 8.6.1
redwood.toml:
[web]
title = "Redwood App"
port = 8910
apiUrl = "/.redwood/functions" # You can customize graphql and dbauth urls individually too: see https://redwoodjs.com/docs/app-configuration-redwood-toml#api-paths
includeEnvironmentVariables = [
# Add any ENV vars that should be available to the web side to this array
# See https://redwoodjs.com/docs/environment-variables#web
]
[api]
port = 8911
[browser]
open = true
[notifications]
versionUpdates = ["latest"]
Are you interested in working on this?
- I'm interested in working on this