whatadewitt / yahoo-fantasy-sports-api

NodeJS wrapper for the Yahoo! Fantasy Sports API
https://yahoo-fantasy-node-docs.vercel.app/
MIT License
205 stars 54 forks source link

feature: add support for scope in request parameter to api.login.yahoo.com/oauth2/request_auth #117

Open HappyZombies opened 4 months ago

HappyZombies commented 4 months ago

As per the docs here, I added the option in the auth() method to take in a third argument for scope, it works the same way as state, where it's only set if it's present.

This option allows the auth method to return a id_token which contains a JWT that is digitally signed by Yahoo, in which contains identity information about the user. This information can help create accounts and have data about the user being authetnicated, like their email, first name, etc. This information will be mention on the Yahoo Login when they are redirected to the login page.

In addition, I updated the callback method to include the entire response body instead of just the auth token and refresh, since we don't want to limit the response here and just return all the possible properties there are.

If you need anything else in this PR please let me know ! :)

whatadewitt commented 4 months ago

Very interesting. Can you just point me to where you have this implemented? I just want to make sure I'm visualizing it right as I've only ever set the scopes at the application level when creating the app...

HappyZombies commented 4 months ago

Sure thing! So first we create an app on Yahoo with the OpenID radio button check, and with check box the e-mail since, this is what I want in my case.

Screenshot 2024-07-19 at 7 28 46 PM

Now if I call the .auth() method without these changes, I will be redirect to the Yahoo permission page and notice that we have the "profile" option with email showing.

Screenshot 2024-07-19 at 7 41 02 PM

However since I can't pass in the scope of "openid", I won't ever get the id_token property back and as such, I can't get the e-mail to create the user account or log them into their account.

With this change, I can add a scope based on anything the docs state (which can just be comma separated strings), and also return the entire callback response body back to me for me to use however I like.

This is how it looks in my code now:

    route.get("/yahoo", async (req, res) => {
        YahooService.yf.auth(res, null, "openid"); // this will redirect them to Yahoo, which will redirect to my callback
    });

    route.get("/yahoo/callback", async (req, res) => {
        YahooService.yf.authCallback(req, async (err, data) => {
           // data contains property id_token, which is a JWT that contains their e-mail
            if (err) {
                return res.redirect('/error')
            }
            const user = await AuthService.authenticate(data);
            if (!user) {
                return res.redirect('/create-account')
            }
            return res.redirect("/api")
        });
    });
whatadewitt commented 4 months ago

Apologies, I've been sick! I will look at this as soon as I can. I really feel like I had this handled, but I see what you're explaining and it makes a lot of sense. I will look at it ASAP!