How to use the SalesForce API? - salesforce

I'm trying to use an express/node application to make an api call to the salesforce api and return me data according to the records I have with the account.
But it is returning this:
[{"errorCode":"NOT_FOUND","message":"The requested resource does not exist"}]
Currently my code looks like this
const express = require('express')
const app = express();
var request = require('request');
app.get('/',(req,res, next) =>{
request({
url: 'https://nav4.lightning.force.com/services/data"',
}).pipe(res);
});
})
const port = process.env.PORT || 3000; app.listen(3000, ()=>
console.log(`listening on port ${port}`))
I think my URL is wrong and might need authentication also.

You do need to authenticate first to https://login.salesforce.com. I would suggest reading and following the documentation at their documentation. The username password flow is only recommended for testing purposes though, so once you get it working you might want to look into a different oauth flow if you are building a real application depending on your use case.

For consume the Salesforce API below are the Details to notes.
Find which api to consume REST OR SOAP
Needs :
Base URL
Endpoint URL
Consumer Key and secret key
This are the Point To archive
Below are for Your Reference
https://developer.salesforce.com/page/Consuming_Force.com_SOAP_and_REST_Web_Services_from_.NET_Applications
https://trailhead.salesforce.com/content/learn/modules/apex_integration_services

Related

Bypassing Firestore Security Rules in jest tests

Currently working on a React/Typescript/Firebase Firestore project. When writing Jest-tests for some actions/functions that are called from the UI, I ran into the following problem:
In the test file I'm able to setup the firestore client using the v9 api and make it talk to emulator
const app = initializeApp(config.firebase);
const firestore = getFirestore(app);
connectFirestoreEmulator(firestore, "localhost", 8080);
In addition I also found out how to setup the admin client and make it talk to emulator
process.env.FIRESTORE_EMULATOR_HOST = "localhost:8080";
const serviceAccount = require("../../../my-key.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
...config.firebase
});
The test itself looks something like this:
describe("createCompanyAndRating action", () => {
test("call createCompanyAndRating and make sure it creates a proper rating entity", async () => {
// omitted: set testRatingFormState and other test data that are passed as args and
// pass in the firestore db client
const {
ratingId,
companyId,
} = await createCompanyAndRating({
ratingFormState: testRatingFormState,
visitorId: testVisitorId,
firestore,
});
// verify result by fetching the rating entity from the emulator db using the admin client
const ratingPath = `companies/${companyId}/ratings/${ratingId}`;
const ratingSnap = await admin.firestore().doc(ratingPath).withConverter(ratingConverter).get();
const rating: Rating | undefined = ratingSnap.data();
// omitted: verify result with some Jest expect-statetments...
});
})
My problem is now that the Firestore security rules apply and only authenticated users can write docs in the collections used in the createCompanyAndRating function, so the test already throws an error when calling that function.
In this scenario I'm not interested in testing the security rules per se.
Is there a way to bypass the security rules for the test?
If yes, how do I have to setup the firestore client?
Is there even the possibility to somehow impersonate a user in the test?
In addition, please note that I can't to pass the admin client into the createCompanyAndRating function as the admin client API is different from the v9 firebase API that I'm relying on in the createCompanyAndRating function implementation (tried and it didn't work and not only because some type errors in the way).
Maybe my whole approach is a little misguided and I should rather concentrate on testing the internals of the createCompanyAndRating function where I do a lot of factory stuff that could be tested without db interaction.
Anyway, any help/guidance is much appreciated.
Thanks for confirming that I was looking in the right place (i.e. #firebase/rules-unit-testing). Finally figured out what the problem was, missed an "await" in createCompanyAndRating, so the firestore admin instance wasn't getting the data (and I though it was a admin config issue...) Thanks!

Access SSM Parameter store value in an aws amplify react js application

I have an amplify application built using React JS, I have a scenario for which I am manually storing API keys in my SSM parameter store in my AWS account. However, I want to retrieve/get those values(JSON object) based on a key from my React JS app (client side). So, I have installed the aws-sdk, the AWS JavaScript sdk, and using the below code snipped I am trying to access the ssms parameter store
const AWS = require('aws-sdk');
AWS.config.update({region:'us-east-1'});
const ssm = new AWS.SSM();
const getSecret = async (secretName) => {
console.log(`Getting secret for ${secretName}`);
const params = {
Name: secretName,
WithDecryption: true
};
const result = await ssm.getParameter(params).promise();
return result.Parameter.Value;
};
module.exports = {getSecret};
I am receiving this error on running my application and while accessing the store using the getSecret function.
Unhandled Rejection (CredentialsError): Missing credentials in config,
if using AWS_CONFIG_FILE, set AWS_SDK_LOAD_CONFIG=1
I believe that amplify configures the environment implicitly but since, the SSM Secrets manager is not supported yet by Amplify hence, I have to use the JS AWS SDK for this purpose. Can anyone help me spot the issue while configuring the service using AWS SDK? Or is there another or a better way to access parameter store from the client side?
Also, after surfing I have found a package named dotenv
Is it okay to store aws credentials in such a way?
Your code to fetch parameter store keys/values shouldn't be at client side considering security implications. It should be done at server-side and functionality can be exposed over endpoint for client-side.
You can read the credentials programmatically something like below:
var AWS = require("aws-sdk");
var credentials = new AWS.SharedIniFileCredentials({profile: 'profile name'});
AWS.config.credentials = credentials;
Refrence:
loading-node-credentials-shared
global-config-object

GCP Server to Server Authentication with Service Account

I'm trying to authenticate a request from my Google Cloud Function to my API on App Engine (Standard environment).
I have something working, but I'm new to OAuth2 and am looking for a sanity check.
In my Cloud Function, I send an authenticated request to my API doing the following:
import { GoogleAuth } from 'google-auth-library';
// Send Request Code:
const auth = new GoogleAuth();
const tokenClient = await auth.getIdTokenClient(`/protectedEndpoint`);
await tokenClient.request({
url: `https://${process.env.GCLOUD_PROJECT}.appspot.com/protectedEndpoint`,
method: 'POST',
});
In the API (on App Engine), I do the following:
import { GoogleAuth } from 'google-auth-library';
// Handle Request Code:
const token = <Bearer token parsed from request headers>
const googleAuth = new GoogleAuth();
const tokenClient = await googleAuth.getIdTokenClient('');
const loginTicket = await tokenClient.verifyIdToken({
idToken: token,
audience: '/protectedEndpoint',
});
if (loginTicket.getUserId() !== process.env.SERVICE_ACCOUNT_ID)) {
throw new Error('Unauthenticated Service Account');
}
return 'Successful Authentication'
Note: In both cases, I'm using Google's default application credentials to initialize the GoogleAuth client. (my Default App Engine service account)
This all works. My function sends a request to my API, and my API is able to parse the bearer token and tell me that it came from my approved service account... but I'm not 100% confident that this is actually secure. Is it possible for someone to spoof my service account without having its credentials?
Thanks in advance!
Is it possible for someone to spoof my service account without having
its credentials?
A precise answer requires the specification of time. Given enough time and processing power, any authentication/authorization/encryption/hashing/signing method can be broken.
A Google service account contains an RSA 2048-bit private key. Current guesstimates are 300 trillion years to break RSA 2048 bit encryption. With the rapid advances in computers, let's assume your data will probably not be of any use/value by the time RSA is broken.
The private key is used to sign a JWT. The Signed JWT is used to request OAuth Access/Identity Tokens.
Spoofing would require signing with the same private key. Therefore, spoofing is not possible with today's technology.
Stealing/leaking the private key or the generated OAuth tokens is the only realistic method today.

Protect a single api resource with multiple IDServers

So I have a .Net Core web api, lets call it "CMS" and its currently protected by an IdentityServer4 server as an api resource. I have configured the ID4 server to have the IDP Claim of MyIDP.
For business reasons, I need to give a client their own IdentityServer but they would also like to have their users access the same api "CMS" .
Is this possible?
In the StartUp.cs of my CMS api it currently looks like this
services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(options =>
{
options.Authority = "http://www.idserver1.com";
options.RequireHttpsMetadata = true;
options.ApiName = "cmsapi";
});
so to add protection for another id server I assume i could just duplicate the AddAuthentication but change the scheme name from Bearer to something else but that seems wrong?
The reason I think this should be possible because I have been able to add multiple external providers to my Web Application in this manner . But this is for s sign in flow and not for an api.
If this is possible how do I go about this?
This can be achieved quite simply. Suppose you want to issue a separate subdomain for each of your clients: auth0.yourdomain.com, auth1.yourdomain.com and you want an api resource to respect the token from either of those identity providers.
Assuming that the signing key is the same, you can configure a shared issuer uri on the identity server side in Startup.cs->ConfigureServices(...):
var builder = services.AddIdentityServer(options => {
options.IssuerUri = "auth.yourdomain.com";
})
...
And then on the api side you can respect the single issuer uri without having to duplicate authentication schemes:
services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(options =>
{
options.Authority = "auth.yourdomain.com";
options.RequireHttpsMetadata = true;
options.ApiName = "cmsapi";
});
One thing I can't remember is if the request scheme (http/https) is inferred for the issuer uri or not so you might need to specify that as well (https:\\auth.yourdomain.com). Other than that, this sort of implementation should be quite seamless as far as your clients are concerned.
i think i may have figured out the solution, based off another problem that was happening to me over here
Using Client Credentials flow on identityserver4 and custom AuthorizationHandler User.Identity.isAuthenticated = false
turns out you can use multiple authenticationschemes to protect an api and choose which things to protect with what using the authenticationSchemes property of the Authorize Attribute.
so you would just need a way to map the incoming bearer token to the correct authentication scheme

Make an API endpoint private

I'm developing a little webApp with AngularJS, express, nodejs and Passportjs. I have been creating endpoints on my API on demand but now I have a problem.
I have an endpoint which cannot be called by the users when they want. This API call is made when a user make an specific action in the app, so they earn points.
The endpoint is something like /api/users/updatePoints and I don't want the users with the developers tools resending the call and earning points they don't deserve.
How could I accomplish this? I have been thinking for a day but I can't think of anything reasonable.
Thank you in advance :)
--EDIT--
At last I have just deleted that ENDPOINT and write directly in the database in server-side. Not the solution I wanted but good enough. Thank you!!
It's already too late to answer but I think this could help someone.
To Privatize an endpoint, Allow only your whitelisted Origins by setting the respective response headers and for all other users send a 403 status code (Which implies forbidden, 401 says try again).
Here is an example of middleware that privatizes endpoints.
module.exports = function (allowedOrigins) {
const whitelistedOrigins = Array.isArray(allowedOrigins) ? allowedOrigins : [allowedOrigins];
return function (req, res, next) {
const origin = req.headers.origin;
if (whitelistedOrigins.indexOf(origin) > -1) {
res.setHeader("Access-Control-Allow-Origin", origin);
next();
} else {
res.status(403).json({
msg: "This is a private Endpoint, Please contact the Admin",
});
}
};
};
Here is an example of usage.
const privatizeEndpoint = require("../customMiddlewares/privatizeEndpoint");
router.post("/someEndpoint", privatizeEndpoint(["http://myprivate.domain.com"]), (req, res) => {
console.log("Inside Private Endpoint");
});
However, your endpoint will be still exposed but at least it will be served only to your whitelisted domains.
Notice that even requests without origin will be blocked (curl commands or through POSTMAN).

Resources