curl req into firebase functions req - node.js

Hello I am following the instructions to implement an encryption payment from from Adyen. I am using Firebase as my backend. Now the Dokumentation want that I make a backend req like this:
curl -u "ws#Company.SomeCompany":"SomePassword" \
-H "Content-Type: application/json" \
-X POST \
--data \
'{
"additionalData": {
"card.encrypted.json":"adyenjs_0_1_4p1$..."
},
"amount" : {
"value" : 10000,
"currency" : "EUR"
},
"reference" : "Your Reference Here",
"merchantAccount" : "TestMerchant" }'\
https://pal-test.adyen.com/pal/servlet/Payment/v30/authorise
Can someone please help me to convert this curl request into an firebase functions request? For example:
exports.helloWorld = (req, res) => {
if (req.body.message === undefined) {
// This is an error case, as "message" is required
res.status(400).send('No message defined!');
} else {
// Everything is ok
console.log(req.body.message);
res.status(200).end();
}
};

You need to pass your Adyen credentials as data in http post request. Add firebase user token as Bearer token in Authroization token. So now your function will be:
exports.helloWorld = (req, res) => {
// check authorization of firebase.
if (!req.headers.authorization || !req.headers.authorization.startsWith('Bearer ')) {
res.status(403).send('Unauthorized');
return;
}
const idToken = req.headers.authorization.split('Bearer ')[1];
this.admin.auth().verifyIdToken(idToken).then(decodedIdToken => {
// new read the data like below
// req.body.username , req.body.additionalData
})
};

Related

How to manage session in supertokens?

I am using the supertokens-node library to manage users in my nest.js app.
I want to protect some of the routes and for that I am using the verifySession method of the supertokens. I am using the postman to test the routes but I am getting unauthorised in the response.
This is the AuthGaurd function as per the docs:
#Injectable()
export class AuthGuard implements CanActivate {
constructor(private readonly verifyOptions?: VerifySessionOptions) {}
async canActivate(context: ExecutionContext): Promise<boolean> {
const ctx = context.switchToHttp();
let err = undefined;
const resp = ctx.getResponse();
// You can create an optional version of this by passing {sessionRequired: false} to verifySession
await verifySession(this.verifyOptions)(ctx.getRequest(), resp, (res) => {
err = res;
});
if (resp.headersSent) {
throw new STError({
message: 'RESPONSE_SENT',
type: 'RESPONSE_SENT',
});
}
if (err) {
throw err;
}
return true;
}
}
This is the endpoint that is I have applied the AuthGuard
#Post('/bulkAddUpdate')
#UseGuards(new AuthGuard())
async builkAddUpdate(
#Body() bulkData: any,
#Session() session: SessionContainer
) {
console.log(session.getUserId());
const user = await this.applicationService.bulkAction(bulkData.data);
if (user) {
return utils.sendSuccess(SUCCESS.S200.DEFAULT, user);
} else {
throw new NotFoundException();
}
}
As per the docs when I sign-in I have to set the headers rid(key) : session(value) in the signin method but when I hit the request I am getting 404 route not found error. But when I remove rid from the headers then it works perfectly fine.
And I am also setting headers as rid : session to my protected route but I am getting unauthorised in the response.
This is the cURL request:
curl --location --request POST 'http://localhost:9000/applications' \
--header 'rid: thirdpartyemailpassword' \
--header 'Content-Type: application/json' \
--header 'Cookie: pga4_session=887a38e7-589c-4faa-9bbe-139e9145b535!iTseBPH6uzAlV9Mbaap/agtBJ6GymXNDEp+4cgySEdA=; sFrontToken=eyJ1aWQiOiJkMzU0ZTJlOS1hNGVlLTQwOGYtYTQ5My0yYjQ1NjBhYWFiYzkiLCJhdGUiOjE2NzU0MjMzODc4NDAsInVwIjp7ImlzUGFzc3dvcmRsZXNzIjpmYWxzZX19; sIRTFrontend=d131494f-dbd8-4a21-a5a8-3959bb2d4fd1' \
--data-raw '{
"userID": 2,
"applicationContent": "<html><body>Anything...</body></html>",
"applicationType": 200
}'
The sign in API should not have the rid as session. The rid should be set to the recipe you are using that exposes the signin API. For example, if you are using the EmailPassword recipe, you want to set the rid to emailpassword when querying the sign in API.
Once you call the sign in API successfully, you should get back session tokens in cookies which are managed by Postman.
Then when you query your protected API, Postman should automatically add the sAccessToken cookie in the request which is verified by the supertokens-node SDK.

getting 404, firebase + node.js, using "projects.locations.instances.create"

I'm trying to make an instance of a database with node.js in firebase realtime database.
My node.js route looks like this:
const axios = require('axios');
var {google} = require("googleapis");
var serviceAccount = require("paht/to/json");
router.post('/createnewdatabase', function (req, res) {
//scopes used for the create
var scopes = [
"https://www.googleapis.com/auth/cloud-platform",
"https://www.googleapis.com/auth/firebase"
];
// Authenticate a JWT client with the service account.
var jwtClient = new google.auth.JWT(
serviceAccount.client_email,
null,
serviceAccount.private_key,
scopes
);
// Use the JWT client to generate an access token.
jwtClient.authorize(function(error, tokens) {
if (error) {
console.log("Error making request to generate access token:", error);
} else if (tokens.access_token === null) {
console.log("Provided service account does not have permission to generate access tokens");
} else {
var accessToken = tokens.access_token;
let apiKey = req.body.apiKey;
const config = {
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + accessToken
},
};
axios({
method: 'post',
url: 'https://firebasedatabase.googleapis.com/v1beta/projects/{project-id}/locations/europe-west1',
data: {
key: apiKey,
databaseId: 'segesggseg-656-sdgsdgs',
},
config
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
res.send('POST request to the homepage')
}
});
})
I'm getting a 404 when trying to call the route. I'm guessing it's something with the tokens. The documentation is here: https://firebase.google.com/docs/reference/rest/database/database-management/rest/v1beta/projects.locations.instances/create
I can't figure it out :-)
Please consider that according to the official documetation link:
"name field - Currently the only supported location is 'us-central1'."
I was able to create an instance using the api only with empty data parameter.
'https://firebasedatabase.googleapis.com/v1beta/projects/111111111111/locations/us-central1/instances?databaseId=myinstanceiddd&validateOnly=true&key=[YOUR_API_KEY]' \
--header 'Authorization: Bearer [YOUR_ACCESS_TOKEN]' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{}' \
--compressed
200
{
"name": "projects/111111111111/locations/us-central1/instances/myinstanceiddd",
"project": "projects/111111111111",
"databaseUrl": "https://myinstanceiddd.firebaseio.com",
"type": "USER_DATABASE",
"state": "ACTIVE"
}
After answer above did not work for me... I was forced to read docs (https://firebase.google.com/docs/reference/rest/database/database-management/rest/v1beta/projects.locations.instances/create) word by word...
Second paragraph says that ur project needs to be on the Blaze plan in order to be able to create instance... After this doing this, it now works for me.

Axios Basic Auth with API key Example in Node

There is a curl request like this:
curl -X GET --header 'Accept: application/json' --header 'Authorization: Basic [==APIKEYHERE==]' 'https://apipath.com/path?verbose=true'
I removed the APIKEY and the API path for privacy.
The curl request is working fine, I can't figure out how to convert this into an Axios request since it only needs an API key and not a username and password.
Here is the example I found:
axios.get('https://apipath.com/path?verbose=true', {}, {auth: {username: 'username', password: 'password'}})
.then(function(response) {
console.log(response.data, 'api response');
})
I'm not sure how to get this to work for my case?
The short answer to adding an X-Api-Key to an http request with axios can be summed up with the following example:
const url =
"https://someweirdawssubdomain.execute-api.us-east-9.amazonaws.com/prod/custom-endpoint";
const config = {
headers: {
"Content-Type": "application/json",
},
};
// Add Your Key Here!!!
axios.defaults.headers.common = {
"X-API-Key": "******this_is_a_secret_api_key**********",
};
const smsD = await axios({
method: "post",
url: url,
data: {
message: "Some message to a lonely_server",
},
config,
});
I was stuck for 8 hours trying to figure this out as the errors lined up in the queue, adding the key to the default headers was the only way I could get this to work.
Given the cURL command including --header 'Authorization: Basic [==APIKEYHERE==]', you know that the server wants a header sent using the Basic authentication scheme. That means that your API key is both the username and password joined by a : and encoded with Base64. So, you can decode what the username and password should be by decoding your API key with Base64 and seeing the values joined by the colon.
Consider the spec detailed on MDN: Authorization Header
So if your API key is Ym9iOnBhc3N3b3JkMQ==, and you decode it with Buffer.from("API_KEY", "base64").toString(), you would get the value bob:password1 meaning your username is bob and your password is password1 making your request:
const [username, password] = Buffer.from("YOUR_API_KEY", "base64").toString().split(":");
axios.get('https://apipath.com/path?verbose=true', {}, {
auth: {
username,
password
}
})
.then(function(response) {
console.log(response.data, 'api response');
})
You can define a function like this, then you can pass the token to header after login success.
import axios from "axios";
const setAuthToken = token => {
if (token) {
// Apply to every request
axios.defaults.headers.common["Authorization"] = token;
} else {
// Delete auth header
delete axios.defaults.headers.common["Authorization"];
}
};
axios.get('https://apipath.com/path?verbose=true', {}, {auth: {username: 'username', password: 'password'}})
.then(() => setAuthToken(response.token));

Passing parameters in angular4 services

I have been trying to pass two parameter from my angular frontend to node api. However I am getting error on my node console that paramter value is missing or invalid when I run my app.
Below here is node api code
app.post('/users', function(req, res) {
var username = req.body.username;
var orgName = req.body.orgName;
logger.debug('End point : /users');
logger.debug('User name : ' + username);
logger.debug('Org name : ' + orgName);
if (!username) {
res.json(getErrorMessage('\'username\''));
return;
}
if (!orgName) {
res.json(getErrorMessage('\'orgName\''));
return;
}
var token = jwt.sign({
exp: Math.floor(Date.now() / 1000) + parseInt(config.jwt_expiretime),
username: username,
orgName: orgName
}, app.get('secret'));
helper.getRegisteredUsers(username, orgName, true).then(function(response) {
if (response && typeof response !== 'string') {
response.token = token;
res.json(response);
} else {
res.json({
success: false,
message: response
});
}
});
});
Here is my angular service code . For the sake of demonstration , I am passing dummy values from angular service
getEnrollmentId(userName,org) {
let headers = new Headers({ 'Content-Type': 'x-www-form-urlencoded' });
let options = new RequestOptions({ headers: headers });
let body = "'username=Barry&orgName=org2'";
return this.http.post('http://localhost:4000/users', body, options )
.map((res: Response) => res.json())
.catch((error:any) => Observable.throw(error.json().error || 'Server error shit'));
}
When I try to acheive same thing using curl query by calling node api and passing paramters , I am successfully able to post data and return response from api. Below here is curl query
curl -s -X POST \
http://localhost:4000/users \
-H "content-type: application/x-www-form-urlencoded" \
-d 'username=Jim&orgName=org1'
What am I doing wrong in my angular services?
Pass the parameter as url search params ,
below code should help
let body = new URLSearchParams();
body.set('username', username);
body.set('orgName', orgName);

I have curl documentation for how to use a site's APIs but would like to use Node JS for the API

I'm trying to make an API for saleforeceIQ and their documentation doesn't include Node JS which is what I'm most familiar with. I'm wondering if I could make an API with Node JS from looking at their documentation. Here is their curl documentation get get an account:
DEFINITION
GET https://api.salesforceiq.com/v2/accounts/{accountId}
REQUEST
curl 'https://api.salesforceiq.com/v2/accounts/abcdef1234567890abcdef0b'
-X GET
-u [API Key]:[API Secret]
-H 'Accept: application/json'
RESPONSE
HTTP/1.1 200 OK
{
"id" : "abcdef1234567890abcdef0b",
"modifiedDate" : 1389124003573,
"name" : "Account"
}
Here is what I have come up with so far for converting this to Node JS:
var key = "[KEY]"
var secret = "[SECRET]"
var request = require('request');
var headers = {
'Accept': 'application/json'
};
var options = {
url: 'https://api.salesforceiq.com/v2/accounts/',
headers: headers
};
function callback(error, response, body) {
if (!error && response.statusCode == 200) {
console.log("body " +body);
}
else{
console.log(error)
}
}
request(options, callback)
My problem is I don't know how to incorporate the key and secret into Node JS
The -u option of curl specify the username and password. So translated for request.js became:
var options = {
// your options
'auth': {
'user': '[KEY]',
'pass': '[SECRET]',
'sendImmediately': true
}
}
You can find more info here: https://github.com/request/request#http-authentication

Resources