Как сохранить JSON из Microsoft Graph API в MongoDB - PullRequest
0 голосов
/ 11 марта 2019

Я работаю над приложением, которое использует Microsoft Graph API для получения пользовательских данных inbox. Я хотел бы затем сохранить JSON в Mongodb. Моя проблема связана с непониманием того, как обращаться к JSON для манипулирования. Любые пункты или советы будут очень полезны. Я опубликую код ниже.

Edit7: Узнав, что я получаю accessToken и username только после перенаправления на Microsoft Outlook и входа в систему, я хочу получить эти два поля даже после входа. Я знаю, что я Я сохраняю значения в cookies и должен иметь доступ к ним. Я сейчас пытаюсь понять, как это сделать. Я вставлю код для auth.js, который обрабатывает аутентификацию для token, который я получаю, и создает токен доступа.

Причина, по которой я хочу получить эти значения, заключается в том, что я знаю, что пользователь прошел аутентификацию, и что у меня есть правильная информация о людях. Затем я хочу сохранить значения, которые я возвращаю из result.value в mongodb.

mail.js

var express = require('express');
var router = express.Router();
var authHelper = require('../helpers/auth');
var graph = require('@microsoft/microsoft-graph-client');

// Creating report object from report.js
SERA = require('../helpers/report_Schema')

var app = express()

/* GET /mail */
router.get('/', async function (req, res, next) {
  let parms = {
    title: 'Inbox',
    active: {
      inbox: true
    }
  };
  // get token and username from input of email
  const accessToken = await authHelper.getAccessToken(req.cookies, res);
  const userName = req.cookies.graph_user_name;

  if (accessToken && userName) {
    parms.user = userName;

    // Initialize Graph client
    const client = graph.Client.init({
      authProvider: (done) => {
        done(null, accessToken);
      }
    });

    try {
      // Get the 10 newest messages from inbox
      const result = await client
        .api('/me/mailfolders/inbox/messages?$search= "from:@gmail.com"')
        .top(5)
        .select('subject,from,receivedDateTime,isRead,sentDateTime')
        // .orderby('receivedDateTime DESC')
        .count(true)
        .get();


          //console.log(result)



      parms.messages = result.value;
      res.render('mail', parms);





    } catch (err) {
      parms.message = 'Error retrieving messages';
      parms.error = {
        status: `${err.code}: ${err.message}`
      };
      parms.debug = JSON.stringify(err.body, null, 2);
      res.render('error', parms);
    }

  } else {
    // Redirect to home
    res.redirect('/');
  }
});




// Posting Email
router.post('/saveReport', async function (req, res) {

  // get token and username from input of email
  const accessToken = await authHelper.getAccessToken(req.cookies, res);
  const userName = req.cookies.graph_user_name;

  if (accessToken && userName) {
    parms.user = userName;

    // Initialize Graph client
    const client = graph.Client.init({
      authProvider: (done) => {
        done(null, accessToken);
      }
    });

    try {
      // Get the 10 newest messages from inbox
      const result = await client
        .api('/me/mailfolders/inbox/messages?$search= "from:@gmail.com"')
        .top(5)
        .select('subject,from,receivedDateTime,isRead,sentDateTime')
        // .orderby('receivedDateTime DESC')
        .count(true)
        .get();


    } catch (err) {
      parms.message = 'Error retrieving messages';
      parms.error = {
        status: `${err.code}: ${err.message}`
      };
      parms.debug = JSON.stringify(err.body, null, 2);
      res.render('error', parms);
    }

    const report = new SERA({
      _id: result.value[0].id,
      receivedDateTime: result.value[0].receivedDateTime,
      sentDateTime: result.value[1].sentDateTime
    });
    // save stores into database
    report.save().then(result => {
        console.log(result)
      })
      // error checking
      .catch(err => console.log(err))

    res.status(201).json({
      message: "Handling post request to /api/report",
      createdReport: report
    });


  } else {
    // Redirect to home
    res.redirect('/');
  }
});

module.exports = router;

reportSchema

var mongoose = require('mongoose')

var sera = mongoose.Schema({
    // id generated by mongo
    _id: String,
    receivedDateTime: String,
    sentDateTime: String
});

module.exports = mongoose.model("SERA", sera)
//module.exports.reportSchema = reportSchema;
// mongoose.model("Report", reportSchema)

auth.js

// This file is where we authenticate the token we get back from the api
const credentials = {
  client: {
    // this is the app_id that we get when we register our app on microsoft
    id: process.env.APP_ID,
    // this is the password. stored in our .env file. Client password
    secret: process.env.APP_PASSWORD,
  },
  auth: {
    //  String used to set the host to request the tokens to. Required.
    tokenHost: 'https://login.microsoftonline.com',
    // String path to request an authorization code
    authorizePath: 'common/oauth2/v2.0/authorize',
    //String path to request an access token. 
    tokenPath: 'common/oauth2/v2.0/token'
  }
};
// here we require simple-oauth2
const oauth2 = require('simple-oauth2').create(credentials);
// require a jsonwebtoken
const jwt = require('jsonwebtoken');

// this function will get the scopes and redirect_uri 
// and authorize it.
function getAuthUrl() {
  const returnVal = oauth2.authorizationCode.authorizeURL({
    // this is where we are redirected after authorization
    redirect_uri: process.env.REDIRECT_URI,
    // this is the scopes of the app
    scope: process.env.APP_SCOPES
  });
  console.log(`Generated auth url: ${returnVal}`);
  return returnVal;
}

// this function gets the token to be authorized
async function getTokenFromCode(auth_code, res) {
  // gets the access token object
  let result = await oauth2.authorizationCode.getToken({
    code: auth_code,
    redirect_uri: process.env.REDIRECT_URI,
    scope: process.env.APP_SCOPES
  });

  // creates the access token
  const token = oauth2.accessToken.create(result);
  console.log('Token created: ', token.token);

  saveValuesToCookie(token, res);

  return token.token.access_token;
}

async function getAccessToken(cookies, res) {
  // Do we have an access token cached?
  let token = cookies.graph_access_token;

  if (token) {
    // We have a token, but is it expired?
    // Expire 5 minutes early to account for clock differences
    const FIVE_MINUTES = 300000;
    const expiration = new Date(parseFloat(cookies.graph_token_expires - FIVE_MINUTES));
    if (expiration > new Date()) {
      // Token is still good, just return it
      return token;
    }
  }

  // Either no token or it's expired, do we have a 
  // refresh token?
  // If we do, create set the refresh_token and then refresh it
  // after that we save it and return it
  const refresh_token = cookies.graph_refresh_token;
  if (refresh_token) {
    const newToken = await oauth2.accessToken.create({
      refresh_token: refresh_token
    }).refresh();
    saveValuesToCookie(newToken, res);
    return newToken.token.access_token;
  }

  // Nothing in the cookies that helps, return empty
  return null;
}

//JSON Web Token (JWT) is a compact, URL-safe means of representing
// claims to be transferred between two parties.
function saveValuesToCookie(token, res) {
  // Parse the identity token
  const user = jwt.decode(token.token.id_token);

  // Save the access token in a cookie
  res.cookie('graph_access_token', token.token.access_token, {
    maxAge: 3600000,
    httpOnly: true
  });
  // Save the user's name in a cookie
  res.cookie('graph_user_name', user.name, {
    maxAge: 3600000,
    httpOnly: true
  });
  // Save the refresh token in a cookie
  res.cookie('graph_refresh_token', token.token.refresh_token, {
    maxAge: 7200000,
    httpOnly: true
  });
  // Save the token expiration tiem in a cookie
  res.cookie('graph_token_expires', token.token.expires_at.getTime(), {
    maxAge: 3600000,
    httpOnly: true
  });
}

// this function will clear the cookies for the graph variables
// When the user signs out, all of the cookies will be cleared.
function clearCookies(res) {
  // Clear cookies
  res.clearCookie('graph_access_token', {
    maxAge: 3600000,
    httpOnly: true
  });
  res.clearCookie('graph_user_name', {
    maxAge: 3600000,
    httpOnly: true
  });
  res.clearCookie('graph_refresh_token', {
    maxAge: 7200000,
    httpOnly: true
  });
  res.clearCookie('graph_token_expires', {
    maxAge: 3600000,
    httpOnly: true
  });
}

exports.getAuthUrl = getAuthUrl;
exports.getTokenFromCode = getTokenFromCode;
exports.getAccessToken = getAccessToken;
exports.clearCookies = clearCookies;
...