SimpleGraphClient: Invalid token received - oauth

I started developing a new MS Teams Application and I am trying to authenticate a MS Teams user on my app's backend by following the source code of
https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/app-sso
But unfortunately when I am trying to create a SimpleGraphClient with the token acquired by this function
// Get Access Token
const getAccessToken = async(req) => {
return new Promise((resolve, reject) => {
const { tenantId, token } = reqData(req);
const scopes = ['User.Read']; //['User.Read', 'email', 'offline_access', 'openid', 'profile'];
const url = `https://login.microsoftonline.com/${ tenantId }/oauth2/v2.0/token`;
const params = {
client_id: process.env.MicrosoftAppId,
client_secret: process.env.MicrosoftAppPassword,
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
assertion: token,
requested_token_use: 'on_behalf_of',
scope: scopes.join(' ')
};
// eslint-disable-next-line no-undef
fetch(url, {
method: 'POST',
body: querystring.stringify(params),
headers: {
Accept: 'application/json',
'Content-Type': 'application/x-www-form-urlencoded'
}
}).then(result => {
if (result.status !== 200) {
result.json().then(json => {
// eslint-disable-next-line prefer-promise-reject-errors
reject({ error: json.error });
});
} else {
result.json().then(async json => {
resolve(json.access_token);
});
}
});
});
};
I am taking the exception :
throw new Error('SimpleGraphClient: Invalid token received.');
What am I doing wrong?

Related

How to call a POST API from lambda function?

I am trying to integrate a POST API call from a lambda function using Node.js 12.x.
I tried like below:
var posturl = "My post api path";
var jsonData = "{'password':'abcdef','domain':'www.mydomain.com','username':'abc.def'}";
var req = require('request');
const params = {
url: posturl,
headers: { 'jsonData': jsonData }
};
req.post(params, function(err, res, body) {
if(err){
console.log('------error------', err);
} else{
console.log('------success--------', body);
}
});
But when I am execute it using state machine, I am getting the below exception:
{
"errorType": "Error",
"errorMessage": "Cannot find module 'request'\nRequire stack:\n- /var/task/index.js\n- /var/runtime/UserFunction.js\n- /var/runtime/index.js",
"trace": [
"Error: Cannot find module 'request'",
"Require stack:",
"- /var/task/index.js",
"- /var/runtime/UserFunction.js",
"- /var/runtime/index.js",
" at Function.Module._resolveFilename (internal/modules/cjs/loader.js:815:15)",
" at Function.Module._load (internal/modules/cjs/loader.js:667:27)",
" at Module.require (internal/modules/cjs/loader.js:887:19)",
" at require (internal/modules/cjs/helpers.js:74:18)",
" at Runtime.exports.handler (/var/task/index.js:8:14)",
" at Runtime.handleOnce (/var/runtime/Runtime.js:66:25)"
]
}
Here the posturl is my api path and jsondata is my key value pair data.
So How can I call a POST API from lambda function? How can I pass the entire jsondata key when call API? How can I parse the response after the service call?
Update: I have tried like below
All my details are passing with a key jsonData, where I can specify that? Without that key, it will not work.
exports.handler = (event, context, callback) => {
const http = require('http');
const data = JSON.stringify({
password: 'mypassword',
domain: 'www.mydomain.com',
username: 'myusername'
});
const options = {
hostname: 'http://abc.mydomain.com',
path: 'remaining path with ticket',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': data.length
}
};
const req = http.request(options, (res) => {
let data = '';
console.log('Status Code:', res.statusCode);
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
console.log('Body: ', JSON.parse(data));
});
}).on("error", (err) => {
console.log("Error: ", err.message);
});
req.write(data);
req.end();
};
source : How to Make an HTTP Post Request using Node.js
const https = require('https');
const data = JSON.stringify({
name: 'John Doe',
job: 'Content Writer'
});
const options = {
hostname: 'reqres.in',
path: '/api/users',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': data.length
}
};
const req = https.request(options, (res) => {
let data = '';
console.log('Status Code:', res.statusCode);
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
console.log('Body: ', JSON.parse(data));
});
}).on("error", (err) => {
console.log("Error: ", err.message);
});
req.write(data);
req.end();

How to refresh access token in electron app?google oauth2.0

I use this api to provide google login function for my electron app
https://github.com/googleapis/google-auth-library-nodejs
My access token expires after 3600 seconds
I don’t want my users to log in again after 3600 seconds
How can I make the token refresh automatically?
I try to use the document example code on the my app
But it doesn't seem to work
How can I get a new access_token
I try the code below to get a new access_token
But nothing happens
const { app, BrowserWindow, screen } = require('electron');
const fs = require('fs');
const { google } = require('googleapis'); // auth node js
googleOAuth2Login();
function googleOAuth2Login() {
const SCOPES = ['https://www.googleapis.com/auth/drive'];
const TOKEN_PATH = 'token.json';
fs.readFile('credentials.json', (err, content) => {
if (err) return console.log('Error loading client secret file:', err);
authorize(JSON.parse(content), showAccessToken);
});
function authorize(credentials, callback) {
const { client_secret, client_id, redirect_uris } = credentials.installed;
const oAuth2Client = new google.auth.OAuth2(
client_id,
client_secret,
redirect_uris[0]
);
// Check if we have previously stored a token.
fs.readFile(TOKEN_PATH, (err, content) => {
if (err) return getAccessToken(oAuth2Client, callback);
oAuth2Client.setCredentials(JSON.parse(content));
callback(JSON.parse(content))
oAuth2Client.on('tokens', (tokens) => {
//this handle not work
if (tokens.refresh_token) {
// store the refresh_token in my database!
console.log(tokens.refresh_token);
}
console.log(tokens.access_token);
});
});
}
/**
* This method opens a new window to let users log-in the OAuth provider service,
* grant permissions to OAuth client service (this application),
* and returns OAuth code which can be exchanged for the real API access keys.
*
* #param {*} interactionWindow a window in which the user will have interaction with OAuth provider service.
* #param {*} authPageURL an URL of OAuth provider service, which will ask the user grants permission to us.
* #returns {Promise<string>}
*/
function getOAuthCodeByInteraction(interactionWindow, authPageURL) {
interactionWindow.loadURL(authPageURL, { userAgent: 'Chrome' });
return new Promise((resolve, reject) => {
const onclosed = () => {
reject('Interaction ended intentionally ;(');
};
interactionWindow.on('closed', onclosed);
interactionWindow.on('page-title-updated', (ev) => {
const url = new URL(ev.sender.getURL());
// console.log(url.searchParams)
if (url.searchParams.get('approvalCode')) {
console.log('allow')
interactionWindow.removeListener('closed', onclosed);
interactionWindow.close();
return resolve(url.searchParams.get('approvalCode'));
}
if ((url.searchParams.get('response') || '').startsWith('error=')) {
console.log('reject')
interactionWindow.removeListener('closed', onclosed);
interactionWindow.close();
return reject(url.searchParams.get('response'));
}
});
});
};
function executeAuthWindow(authWindow, authUrl) {
authWindow.setMenu(null);
authWindow.show();
return new Promise((resolve, reject) => {
getOAuthCodeByInteraction(authWindow, authUrl)
.then((res) => {
if (res != 'Interaction ended intentionally ;(') {
return resolve(res);
}
if (res == 'Interaction ended intentionally ;(') {
return reject('Fail:Authorization window colose');
}
}).catch((err) => {
if (err = 'error=access_denied') {
return reject('Fail: error=access_denied');
}
});
})
}
function getAccessToken(oAuth2Client, callback) {
const authUrl = oAuth2Client.generateAuthUrl({
access_type: 'offline',
scope: SCOPES
});
const authWindow = new BrowserWindow({
width: 600,
height: 800,
show: false,
'node-integration': false,
'web-security': false
});
executeAuthWindow(authWindow, authUrl)
.then((code) => {
//access_token: and refresh_token:
oAuth2Client.getToken(code, (err, token) => {
if (err) return console.error('Error retrieving access token', err);
console.log('getToken')
console.log(token)
oAuth2Client.setCredentials(token);
console.log(oAuth2Client)
fs.writeFile(TOKEN_PATH, JSON.stringify(token), (err) => {
if (err) return console.error(err);
console.log('Token stored to', TOKEN_PATH);
});
});
}).catch((err) => {
console.log(err)
})
}
// initOAuthClient
function showAccessToken(token) {
console.log(token)
}
}
credentials file
{
"installed": {
"client_id": "*******17079-*********gjlh6g2nnndhqotn3ij509k.apps.googleusercontent.com",
"project_id": "quickstart-**********",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_secret": "*********dNz3Gceo9F",
"redirect_uris": [
"urn:ietf:wg:oauth:2.0:oob",
"http://localhost"
]
}
}

NativeScript-Angular - POST formdata to Wordpress ContactForm7 API

Hello everyone and thanks in advance ...
I'm trying to use the Contact Form7 APIs to fill in and submit a form from an Angular NativeScript App.
I have tried different solutions but I always get the same error response.
{"into":"#","status":"validation_failed","message":"Oops, there seems to be some error in the fields. Check and try again, please.","invalidFields":[{"into":"span.wpcf7-form-control-wrap.nome","message":"Attention, this field is required!","idref":null},{"into":"span.wpcf7-form-control-wrap.mail","message":"Attention, this field is required!","idref":null}]}
In the example I have entered static values ​​in the body for convenience
Help me ;(
attempt 1
onTappedInvia(): void {
fetch("http://www.example.com/wp-json/contact-form-7/v1/contact-forms/{id}/feedback", {
method: "POST",
headers: { "Content-Type": "multipart/form-data" },
body: JSON.stringify({
nome: "Test API",
mail: "test#test.test"
})
}).then((r) => r.json())
.then((response) => {
const result = response.json;
console.log(response);
}).catch((e) => {
console.log(e);
});
}
attempt 2
deliverForm() {
var formData: any = new FormData();
formData.append('nome', "Test API");
formData.append('email', "test#test.test");
formData.append('your-message', "Test API");
this.submitted=true;
console.log(formData);
this.formService.create(formData)
.subscribe(
data => {
console.log('Invoice successfully uploaded');
console.log('Error'+ JSON.stringify(data));
},
error => {
console.log('Error'+ JSON.stringify(error));
});
console.log('USCITO');
}
and formService
const HttpUploadOptions = {
headers: new HttpHeaders({ "Content-Type": "multipart/form-data;" })
}
#Injectable({
providedIn: 'root'
})
export class FormService {
constructor(
private HttpClient: HttpClient
) { }
create(formData){
return this.HttpClient.post('http://www.example.com/wp-json/contact-form-7/v1/contact-forms/{id}/feedback', formData, HttpUploadOptions)
}
}
The problem was with the Content-Type. i tried with application/x-www-form-urlencoded and it works!
fetch("http:www.aficfestival.it/wp-json/contact-form-7/v1/contact-forms/5173/feedback?", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: form
}).then((r) => r.json())
.then((response) => {
const result = response.json;
console.log(response);
}).catch((e) => {
console.log(e);
});
}

MS Graph Sample Application Integration Test not Working

I want to do what the MS Graph sample node app is doing in its integrationTests.js, but that test doesn't work. Here's what I've tried:
Followed the quick start for creating a node.js app.
Ran the app. Ensured it worked by sending an e-mail.
Modified the test Checking that the sample can send an email to use my account parameters.
Tried to run the test. It fails with 403: insufficient scope. The call to get the token returned scopes, but lacked Mail.Send.
In the post data for the call to login.microsoftonline.com, I added "scope: 'Mail.Send'"
I still receive a valid token, and the return scope includes Mail.Send, but when I try to post with that token, I get 400: cannot POST /beta/me/sendMail
I tried adding scope (Mail.Send) in the query string and as a header (thought I saw that somewhere), but it made no difference.
I added the Mail.Send permission (under "Application Permissions") for the app in the application registration portal.
I compared the token (using https://jwt.ms) from my test call to the call from the app when it works. I see no real difference. They both contain the Mail.Send scope.
Here is the code (which is only slightly different from what's in the sample):
// in graphHelper.js
function postSendMail(accessToken, message, callback) {
request
.post('https://graph.microsoft.com/beta/me/sendMail')
//.post('https://graph.microsoft.com/beta/me/sendMail?scope=Mail.Send') // nope
.send(message)
.set('Authorization', 'Bearer ' + accessToken)
.set('Content-Type', 'application/json')
.set('Content-Length', message.length)
.set('scope', 'Mail.Send') // nope
.end((err, res) => {
callback(err, res);
});
}
describe('Integration', function () { // mocha
var accessToken;
var scope;
const config = getConfig();
// My account variables in testConfig.json file
function getConfig() {
var configFilePath = path.join(__dirname, 'testConfig.json');
return JSON.parse(fs.readFileSync(configFilePath, { encoding: 'utf8' }));
}
function getAccessToken(done) {
var postData = querystring.stringify(
{
grant_type: 'password',
//grant_type: 'client_id', // not supported
//grant_type: 'authorization_code', // This assumes you've requested an auth code.
resource: 'https://graph.microsoft.com/',
scope: 'Mail.Send',
client_id: config.test_client_id_v2,
client_secret: config.test_client_secret_v2,
username: config.test_username,
password: config.test_password
}
);
var postOptions = {
host: 'login.microsoftonline.com',
port: 443,
path: '/common/oauth2/token',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(postData)
}
};
var postRequest = https.request(postOptions, function (res) {
var data = '';
res.setEncoding('utf8');
res.on('data', function (chunk) {
data += chunk;
});
res.on('end', function () {
const response = JSON.parse(data);
accessToken = response.access_token;
scope = response.scope;
done();
});
});
postRequest.on('error', function (e) {
console.log('Error: ' + e.message);
done(e);
});
postRequest.write(postData);
postRequest.end();
}
before( // eslint-disable-line no-undef
function (done) {
getAccessToken(done);
}
);
it('Checking that the sample can send an email',
function (done) {
var postBody = emailer.generateMailBody(config.test_name, config.test_username);
graphHelper.postSendMail(
accessToken, scope,
JSON.stringify(postBody),
function (error) {
assert(error === null, `The sample failed to send an email: ${error}`);
done();
});
}
);
});

How to implement OAuth2 authorization with the server in react native?

I want to implement OAuth2 authorization in react native.I implemented code the following way.
const HOST_ADRESS = "192.168.173.1"; //change with your own host
const client_id = "app";
const username = "balan#gmail.com";
const password = "12345";
fetch('https://'+HOST_ADRESS+"/oauth/token", {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Cache-Control': 'no-cache'
},
body: "client_id=app&client_secret=app1234&grant_type=pass&username="+username+"&password="+password
})
.then((response) => response.json())
.then((responseJson) => {
console.log("******* RESPONSE ********* "+ JSON.stringify(responseJson));
})
.then((response) => response.text())
.then((responseText) => {
console.log("--------------responseText"+responseText);
console.log("******* RESPONSE ********* "+ JSON.stringify(responseJson));
})
.catch((error) => {
const data = {error: "A error happened"};
//redux error.
//dispatch(actionsCreators.errorLogin(data));
console.log("+++++++++++++++++++error"+error);
console.warn(error);
});
But it always get an error like
{"error":"unauthorized","error_description":"Full authentication is required to access this resource"}

Resources