faustjs icon indicating copy to clipboard operation
faustjs copied to clipboard

Provide error code for generateAuthorizationCode

Open DDeis opened this issue 1 year ago • 3 comments

When trying to log in (with onLogin from @faustwp/experimental-app-router or generateAuthorizationCode GraphQL mutation) with an inexistant username/email, or wrong password we get a specific error message for each case:

// Not registered user
"generateAuthorizationCode": {
    "code": null,
    "error": "<strong>Error:</strong> The username <strong>test</strong> is not registered on this site. If you are unsure of your username, try your email address instead."
}
// Wrong password
"generateAuthorizationCode": {
    "code": null,
    "error": "<strong>Error:</strong> The password you entered for the username <strong>admin</strong> is incorrect. <a href=\"https://********/wp-login.php?action=lostpassword\">Lost your password?</a>"
}

These message may not be what we want to display as user feedback and could give too much information to intruders. We could use login_errors filter in our Wordpress installation to override messages, or parse the existing message, but it would be nice if the error code was also provided to let developers handle it as they want without adding a Wordpress filter.

Proposed output

// Preferred
"generateAuthorizationCode": {
    "code": null,
    "error": {
         "code": "invalid_username",
         "message": "<strong>Error:</strong> The username <strong>test</strong> is not registered on this site. If you are unsure of your username, try your email address instead."
    }
}

or

// Simpler (and non breaking ?)
"generateAuthorizationCode": {
    "code": null,
    "error": "<strong>Error:</strong> The username <strong>test</strong> is not registered on this site. If you are unsure of your username, try your email address instead.",
    "errorCode": "invalid_username"
    }
}

I don't know what would be the impacts but I'm willing to make a PR if needed

Related code

Use $authenticate->get_error_code() or $authenticate->get_error_codes() in:

https://github.com/wpengine/faustjs/blob/main/plugins/faustwp/includes/graphql/callbacks.php#L366C1-L371C6

function register_generate_ac_mutation() {
	register_graphql_mutation(
		'generateAuthorizationCode',

                        // Omitted code ...

			'outputFields'        => array(
				'code'  => array(
					'type'        => 'String',
					'description' => __( 'Authorization code used for requesting refresh/access tokens', 'faustwp' ),
				),
				'error' => array(
					'type'        => 'String',
					'description' => __( 'Error encountered during user authentication, if any', 'faustwp' ),
				),
			),

                                // Omitted code ...

				if ( is_wp_error( $authenticate ) ) {
					return array(
						'code'  => null,
						'error' => $authenticate->get_error_message(),
					);
				}

                                // Omitted code ...

			},
		)
	);
}

Versions

Wordpress Plugin Faust.js: 1.2.1 @faustwp/experimental-app-router: 0.2.2 @faustwp/core: 2.1.2 next: 14.1.0

DDeis avatar Feb 05 '24 08:02 DDeis

Hey @DDeis, thanks for the issue!

Have you considered checking the response from generateAuthorizationCode to see if there is an error property, and if so, rendering your own error message?

For example, in your logic, you can check to see if there is an error in the response, and if so, you know that the user was not logged in. You could then render your own custom error message that is more generic, maybe like "Login was not successful. Please make sure your username and password is correct."

blakewilson avatar Feb 05 '24 15:02 blakewilson

Hi @blakewilson, thanks for the response!

Yes that's exactly what I am doing and I'm fine with it for my current use case.

Though I would find useful to be able to handle error codes directly and handle them separately (or not) in Next.js.

The workaround would to override the default message by sending the error code as the message with a WordPress filter (https://developer.wordpress.org/reference/hooks/login_errors/), but I would prefer to avoid that.

DDeis avatar Feb 05 '24 19:02 DDeis

I like the idea of replacing 'code' => null with something like 'code' => $authenticate->get_error_code(). If we have a code, we should probably return it, unless there was a reason for not doing so.

mindctrl avatar Feb 06 '24 14:02 mindctrl