Я работаю над приложением, которое использует 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;