hatchways / team-vampire

1 stars 0 forks source link

BE: Availability Controllers GET /availability #3

Open bonnieli opened 3 years ago

bonnieli commented 3 years ago

Create a route that:

Google Calendar API

Each date you select, it’ll load the appointment slots available

[ {start_time: 2323234, end_time: 234234}, {start_time: 2323234, end_time: 234234}, {start_time: 2323234, end_time: 234234}, ... ]

singhmi4 commented 3 years ago

Hi @bonnieli

Having some trouble getting calendar data to show even though I've included it in the scope in the passport.authentication

It's says that I'm missing an API Key as the error message when trying to access the calendar in the controller here: https://github.com/hatchways/team-vampire/compare/feature-be-google-calendar-freebusy-api

Surprisingly, I don't see a lot of passport related google calendar api authentication questions on stackoverflow.

bonnieli commented 3 years ago

I believe you're authenticating the user, before accessing the google endpoint to grab events but based on documentation you need to also pass in the access token again

https://stackoverflow.com/questions/46173620/authenticating-googleapi-node-library-with-passport

you're missing the auth: oauth2Client part

singhmi4 commented 3 years ago

I believe you're authenticating the user, before accessing the google endpoint to grab events but based on documentation you need to also pass in the access token again

https://stackoverflow.com/questions/46173620/authenticating-googleapi-node-library-with-passport

you're missing the auth: oauth2Client part

Hi @bonnieli, so I'm guessing I need to store the refresh_token and access_token that gets passed in the parameters in the passport google oauth2 strategy in order to set the oauth2 credentials like this:

module.exports = function(passport) {
    // console.log(process.env.GOOGLE_CLIENT_ID);
    passport.use(new GoogleStrategy({
        clientID: process.env.GOOGLE_CLIENT_ID,
        clientSecret: process.env.GOOGLE_CLIENT_SECRET,
        clientID: process.env.GOOGLE_CLIENT_ID,
        clientSecret: process.env.GOOGLE_CLIENT_SECRET,
        callbackURL: "/api/auth/google/callback"
    },
    async (accessToken, refreshToken, profile, done) => {
        const newUser = {
            accessToken: accessToken, // <---
            refreshToken: refreshToken, // <---
            googleId: profile.id,
            firstName: profile.name.givenName,
            lastName: profile.name.familyName,
            email: profile.emails[0].value,
            profilePicture: profile.photos[0].value
        };

Currently, my User schema doesn't have keys for access tokens and refresh tokens so I guess I'll add those in, delete the user, and create a new user to assign it access and refresh tokens upon authentication.

singhmi4 commented 3 years ago

hi @bonnieli , just to let you know I was able to access my google calendar following that stack overflow post with the access and refresh tokens I've added to the User model after initial authentication. Thanks, again!

Updated code pushed to the branch: https://github.com/hatchways/team-vampire/compare/feature-be-google-calendar-freebusy-api

singhmi4 commented 3 years ago

@bonnieli Was able to test the freebusy query on my calendar which returned an array of start/end times that correspond to events in my calendar. Will figure out how to get the free time slots on my calendar using this array by, I'm guessing, subtracting the "busy" end and start times and storing the "free" start and end times in a new array.

I also ran into another issue that had my stored access and refresh tokens becoming invalid which caused the oauth2 credentials to become invalid for accessing the calendar that I "fixed" by updating the tokens during the authentication process. Can you check if this method makes sense in my code?

bonnieli commented 3 years ago

hm did your access/refresh tokens change in any way when you call this new controller?

let's walk through this later today

singhmi4 commented 3 years ago

hi @bonnieli I'm getting an error after being logged in for a long amount of time when I try to access the google calendar api:

{ GaxiosError: invalid_request
    at Gaxios.<anonymous> (/home/michael/Documents/webdev/projects/team-vampire/server/node_modules/gaxios/build/src/gaxios.js:73:27)
    at Generator.next (<anonymous>)
    at fulfilled (/home/michael/Documents/webdev/projects/team-vampire/server/node_modules/gaxios/build/src/gaxios.js:16:58)
    at processTicksAndRejections (internal/process/task_queues.js:86:5)
  response:
   { config:
      { method: 'POST',
        url: 'https://oauth2.googleapis.com/token',
        data:
         'refresh_token=1%2F%2F0fCxrnJByRJNjCgYIARAAGA8SNwF-L9Irl-0_dgDK4Wq9l4fW5xbWIaDldMH4KwQfk9c66S5Ufwj6gmB4vgaA34yEiLXmR3Qy8Q4&client_id=&client_secret=cRH2vVlg-jcdto68q-Wr8Y9s&grant_type=refresh_token',
        headers: [Object],
        params: [Object: null prototype] {},
        paramsSerializer: [Function: paramsSerializer],
        body:
         'refresh_token=1%2F%2F0fCxrnJByRJNjCgYIARAAGA8SNwF-L9Irl-0_dgDK4Wq9l4fW5xbWIaDldMH4KwQfk9c66S5Ufwj6gmB4vgaA34yEiLXmR3Qy8Q4&client_id=&client_secret=cRH2vVlg-jcdto68q-Wr8Y9s&grant_type=refresh_token',
        validateStatus: [Function: validateStatus],
        responseType: 'json' },
     data:
      { error: 'invalid_request',
        error_description: 'Could not determine client ID from request.' },
     headers:
      { 'alt-svc':
         'h3-29=":443"; ma=2592000,h3-T051=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"',
        'cache-control': 'no-cache, no-store, max-age=0, must-revalidate',
        connection: 'close',
        'content-encoding': 'gzip',
        'content-type': 'application/json; charset=utf-8',
        date: 'Thu, 10 Dec 2020 00:37:50 GMT',
        expires: 'Mon, 01 Jan 1990 00:00:00 GMT',
        pragma: 'no-cache',
        server: 'scaffolding on HTTPServer2',
        'transfer-encoding': 'chunked',
        vary: 'Origin, X-Origin, Referer',
        'x-content-type-options': 'nosniff',
        'x-frame-options': 'SAMEORIGIN',
        'x-xss-protection': '0' },
     status: 400,
     statusText: 'Bad Request' },
  config:
   { method: 'POST',
     url: 'https://oauth2.googleapis.com/token',
     data:
      'refresh_token=1%2F%2F0fCxrnJByRJNjCgYIARAAGA8SNwF-L9Irl-0_dgDK4Wq9l4fW5xbWIaDldMH4KwQfk9c66S5Ufwj6gmB4vgaA34yEiLXmR3Qy8Q4&client_id=&client_secret=cRH2vVlg-jcdto68q-Wr8Y9s&grant_type=refresh_token',
     headers:
      { 'Content-Type': 'application/x-www-form-urlencoded',
        'User-Agent': 'google-api-nodejs-client/3.1.2',
        Accept: 'application/json' },
     params: [Object: null prototype] {},
     paramsSerializer: [Function: paramsSerializer],
     body:
      'refresh_token=1%2F%2F0fCxrnJByRJNjCgYIARAAGA8SNwF-L9Irl-0_dgDK4Wq9l4fW5xbWIaDldMH4KwQfk9c66S5Ufwj6gmB4vgaA34yEiLXmR3Qy8Q4&client_id=&client_secret=cRH2vVlg-jcdto68q-Wr8Y9s&grant_type=refresh_token',
     validateStatus: [Function: validateStatus],
     responseType: 'json' },
  code: '400' }

I think this is trying to get new tokens to access the api.

The only way I have right now to fix this is to do the authentication process again going through the correct controller, but I know in the office hours you mentioned the need to get new tokens because they expire which is what the google calendar api mentions as well.

bonnieli commented 3 years ago

hm did you change anything in the backend code? based off of that error message:

{ error: 'invalid_request',
  error_description: 'Could not determine client ID from request.' },

for some reason client Id isn't being passed in?

singhmi4 commented 3 years ago

@bonnieli no, I didn't change anything in the back-end. that error message didn't come up again when I accessed the auth/google controller which created exported a new google oauth2 passport strategy and set new access and refresh tokens.

bonnieli commented 3 years ago

it may be the access token has expired. perhaps the 400 error is because of that although the error message is quite confusing but may be designed that way for security purposes

https://stackoverflow.com/questions/19460379/how-to-get-a-new-google-oauth-access-token-from-refresh-token-in-passportjs

if you can detect that 400 error maybe we'll need to do a refresh of the token on check