How do I access JSON component only? - reactjs

I want to access only the component within a particular JSON header. The fetch code I have written is rendering a JSON output along with the variable name.
I wrote a fetch api and I am returning the response as follows:
fetchPreAuthnConfig: async (data) => {
try {
const response = await fetch(preAuthnEndpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
});
const configurations = await response.json();
console.log(configurations);
return configurations;
} catch (error) {
console.error('Error', error);
return error;
}
},
But the json is returned along with the configurations header which is breaking my functionality on the other code block. The JSON response is as follows:
configurations:
appClientId: "0oa7xxxxxxxxxxxx"
applicationId: "0oa7xxxxxxxxxxxx"
applicationLabel: "Application Name"
createAccount: false
displayName: "Application Name"
emailToken: "{}"
helpTemplateName: "help"
hideResetAccountOption: false
rewriteUrl: ""
scope: "openid profile invites"
serverTime: 1654682083399
termsOnPasswdPage: false
title: "Login"
workflow: "Authorize"
workflowHandlerEndpoint: ""
workflowType: "LOGIN"
How can I refactor the above code so that the returned JSON is:
appClientId: "0oa7xxxxxxxxxxxx"
applicationId: "0oa7xxxxxxxxxxxx"
applicationLabel: "Application Name"
createAccount: false
displayName: "Application Name"
emailToken: "{}"
helpTemplateName: "help"
hideResetAccountOption: false
rewriteUrl: ""
scope: "openid profile invites"
serverTime: 1654682083399
termsOnPasswdPage: false
title: "Login"
workflow: "Authorize"
workflowHandlerEndpoint: ""
workflowType: "LOGIN"
Basically remove the configurations header.

You need to access the key configurations in the JSON object, you can do it as follows:
const { configurations } = await response.json()

Related

Mailgun Attachment + Axios

I would like to send an attachment with Mailgun using react+axios.
Currently, I get an email with an attachment, but it is not named correctly (the name is ".") and if I rename it to a text file it contains the text "[object Object]".
Do you have any idea how to solve this problem?
const form = new FormData();
const fs = require("fs");
form.append("from", "example#gmx.ch");
form.append("to", "Bob <example#hotmail.ch>");
form.append("subject", "Test");
form.append("text", "Hello!!");
form.append("attachment", [{
filename: "example.txt",
data: fs.readFileSync(__dirname + "/text.txt", {
encoding: "utf8",
flag: "r"
})
}]);
const endpoint = "https://api.mailgun.net/v3/sandbox123.mailgun.org/messages";
await axios.post(endpoint, form, {
auth: {
username: "api",
password: process.env.MAILGUN_API_KEY
},
headers: { "Content-Type": "multipart/form-data" }
});
Two things:
As per the mailgun docs when sending attachments you must use "multipart/form-data" encoding. Try:
await axios.post(endpoint, form, {
auth: {
username: "api",
password: process.env.MAILGUN_API_KEY
},
headers: { 'Content-Type': 'multipart/form-data' }
});
Try putting your attachment object inside an array. I am not familiar with the mailgun API but I saw a couple examples where the attachments were inside an array, maybe even if there is a single attachment the API is still expecting it this way.

Update user in AD B2C using Microsoft Graph API (error 400 bad request)

I have collection of users in AD B2C and now using Graph API I want to update one of the custom attributes of user, but constantly I have error 400 Bad Request
This is my code
const test = [
{ client: 'john', status: 'confirmed' },
{ client: 'ema', status: 'rejected' },
{ client: 'melissa', status: 'pending' },
{ client: 'alice', status: 'pending' },
{ client: 'richard', status: 'pending' }
]
const options2 = {
method: 'PATCH',
headers: {
Authorization: 'Bearer ' + token,
'content-type': 'application/json'
},
body: JSON.stringify({ extension_{applicationID}_Clients: JSON.stringify(test) })
}
fetch(
'https://graph.microsoft.com/beta/users/' + decoded.oid,
options2
)
.then(
(result) => {
console.log('result update user', result)
},
(error) => {
console.log(error)
}
)
This is the response
[Symbol(Response internals)]: {
url: 'https://graph.microsoft.com/beta/users/{userID}',
status: 400,
statusText: 'Bad Request',
headers: Headers { [Symbol(map)]: [Object: null prototype] },
counter: 0
}
}
I would really appreciate any kind of help to solve this problem.
I suppose body is the problem but I'm not sure where exactly.
EDIT: I'm saving stringfied array into users object
I tried and tested updating a custom attribute in B2C for a user using Graph API and it worked for me. Let me share the steps:
Create a custom attribute in B2C under User attributes blade:
Now in order to update/patch a user with custom attribute, you need to use the following convention extension_appIdOfB2CExtensionApp_CustomAttributeName. Make sure the appId of the B2C Extension app has no hypens when when you use it with the convention extension_appIdOfB2CExtensionApp_CustomAttributeName. More details can be found here.
I used Postman and made a PATCH call and updated the user custom attribute for the B2C user.
Used the GET call and listed the user attributes and found the newly added custom attribute in the user profile:

Authorization Denied trying to access Bookings Api in Microsoft Graph

I am trying to create an app that runs from an AWS lambda that acts as a middle man for customers wanting to sign up for a booking using Microsoft Bookings. Following the documentation I am able to generate an access token for Graph, but I get an authorization denial when I try to request information from bookings through the api.
My Code:
import request from "request";
import { Callback } from "./callback";
const APP_ID = process.env.BOOKINGS_APP_ID;
const APP_SECRET = process.env.BOOKINGS_API_SECRET;
const TOKEN_ENDPOINT = `https://login.microsoftonline.com/${process.env.BOOKINGS_TENANT_NAME}.onmicrosoft.com/oauth2/token`;
const requestParams = {
client_id: APP_ID,
client_secret: APP_SECRET,
grant_type: "client_credentials",
resource: "https://graph.microsoft.com",
scope: "https://graph.microsoft.com/.default",
};
export default class Bookings {
public static async listBusinesses(callback: Callback) {
Bookings.generateAPIToken((err: string | null, data: any) => {
const options = {
// body: {},
headers: {
"Authorization": `Bearer ${data}`,
"Content-Type": "application/json",
},
method: "GET",
url: "https://graph.microsoft.com/beta/bookingBusinesses",
};
console.log(data);
return request(options, (error: string, res: any) => {
if (error) {
return callback(error, {});
}
return callback(null, JSON.parse(res.body));
});
});
}
public static async generateAPIToken(callback: Callback) {
request.post({ url: TOKEN_ENDPOINT, form: requestParams }, (err, res, body) => {
if (err) {
return callback(err, {});
}
return callback(null, JSON.parse(body).access_token);
});
}
}
The error that I get:
{
error: {
code: '',
message: 'Authorization has been denied for this request.',
innerError: {
'request-id': '695d3f90-357d-490c-b980-4a2018dd39a5',
date: '2020-06-08T03:21:59'
}
}
}
I have also tried using the microsoft-graph-client library to access bookings but that doesn't work either. What I am doing wrong? Thank you for any help.
We can see the document shows the graph api(bookingBusinesses) which you want to request requires delegated type permissions and not support application type permission.
So we can not use "client_credentials" grant flow, your code shows you use "client_credentials" as the grant type. You can use "username/password" grant flow to get the access token instead. So the param you request for the access token should be like below:
const requestParams = {
client_id: APP_ID,
client_secret: APP_SECRET,
grant_type: "password",
scope: "https://graph.microsoft.com/.default",
username: "your user name/email(like xxxxx#xxx.onmicrosoft.com)",
password: "your password"
};
By the way, I noticed the "TOKEN_ENDPOINT" in your code is https://login.microsoftonline.com/${process.env.BOOKINGS_TENANT_NAME}.onmicrosoft.com/oauth2/token and you use both params resource and scope in requestParams. If we use v1 endpoint as your code, we just need to use the param resource. If we use v2 endpoint(https://login.microsoftonline.com/${process.env.BOOKINGS_TENANT_NAME}.onmicrosoft.com/oauth2/v2.0/token), we need to use use the param scope instead of the param resource. The code I provided above use v2, so I use scope param and you also need to change the "TOKEN_ENDPOINT" to v2(just add a v2.0 between the oauth2/ and /token).
If you don't want to change the "TOKEN_ENDPOINT" to v2, just use the params like below:
const requestParams = {
client_id: APP_ID,
client_secret: APP_SECRET,
grant_type: "password",
resource: "https://graph.microsoft.com",
username: "your user name/email(like xxxxx#xxx.onmicrosoft.com)",
password: "your password"
};
Hope it helps~

axios POST request to strapi image upload [Internal Server Error]

I'm uploading an image to strapi using axios but the response is 500 error. However in Postman the request is 200
POSTMAN
AXIOS CODE
let bodyFormData = new FormData();
bodyFormData.append('files', this.state.avatar, this.state.avatar.name)
bodyFormData.append('ref', 'user')
bodyFormData.append('refId', getId())
bodyFormData.append('field', 'avatar')
bodyFormData.append('source', 'users-permmissions')
axios({
method: 'post',
url: `${strapi}/upload`,
headers: {
'Content-Type': 'multipart/form-data',
'Authorization': `Bearer ${withToken()}`,
},
data: bodyFormData,
}).then(res=>console.log(res.data)).catch(err=>{console.log(err.response.data.message)})
what's supposed to be the issue here?
Here's part of the strapi user model
{
"avatar": {
"model": "file",
"via": "related",
"plugin": "upload",
"required": false
}
}
The solution is to throw Axios in the trash. I struggled with this for a day of my life that I will never get back. There's a longish, years-old thread at https://github.com/axios/axios/issues/318 with people complaining about being unable to get multipart form uploads to work with Axios.
I switched to the request-promise module and got it to work within minutes, using the following simple code:
const fs = require("fs-extra");
const rp = require('request-promise');
let out = await rp({
method: 'POST',
uri: 'http://mystrapihost/upload',
formData: {
// Like <input type="text" name="ref">
'ref': "customer", // name of the Strapi data type, singular
'field': "attachments", // a field named "attachments" of type "Media"
'refId': "838e238949ewhd82e8938299e289e99", // strapi ID of object to attach to
// Like <input type="file" name="files">
"files": { // must be called "files" to be "seen" by Strapi Upload module
name: "myfile.pdf",
value: fs.createReadStream("/path/to/myfile.pdf"),
options: {
filename: "myfile.pdf",
contentType: 'application/pdf'
},
},
},
headers: {Authorization: 'Bearer myjwtgobbledygook123456'} // put your JWT code here
});
console.log(out);
Enjoy!!

How to fix "Type Error" axios in React JS

My issue is that i am getting a type error whenever i try parameters to this api https://scryfall.com/docs/api/cards/collection
I've tried some debugging but i can't quite seem to get the response.
https://codesandbox.io/s/r5515135zo
axios({
api: "https://api.scryfall.com/cards/collection",
method: "post",
identifiers: [{ name: "banefire" }, { set: "m19" }]
})
.then(function(response) {
// your action after success
console.log(response);
})
.catch(function(error) {
// your action on error success
console.log(error);
});
};
Trying to get a response without an error in console.
As per axios' docs, a JSON post request is done as such:
axios.post({ /* JSON data */ })
You should thus replace the code you included by the following:
axios.post('https://api.scryfall.com/cards/collection', {
identifiers: [{
name: "banefire"
}, {
set: "m19"
}]
})
.then(console.log)
.catch(console.log);
Or, if you want to save the API response in a global variable - let's say, myGlobalVar to be super original:
const myGlobalVar = null;
axios.post('https://api.scryfall.com/cards/collection', {
identifiers: [{ name: "banefire" }, { set: "m19" }]
})
.then(responseData => myGlobalVar = responseData)
Note that in your answer, you included identifiers as an axios parameter, not part of the data you'll pass to the API.

Resources