How to submit the simple log with AWS CloudWatch Logs from frontend? - javascript

After about 1 hour of searching, I didn't find anything about 'how to submit a simple log to AWS CloudWatch Logs' from the frontend side. Almost all examples are for Node.js, but I need to submit the errors from the frontend, not form backend. I even did not found which package which I should use for the frontend.
To save, your time, I prepared the template of solution.
import { AWSCloudWatch } from "?????";
AWSCloudWatch.config({
// minimal config
});
if (__IS_DEVELOPMENT_BUILDING_MODE__ || __IS_TESTING_BUILDING_MODE__) {
console.error(errorMessage);
return;
}
if (__IS_PRODUCTION_BUILDING_MODE__) {
// Submit 'errorMessage' to AWS CloudWatch
// It would be something like
// AWSCloudWatch.submit(errorMessage)
}

You can use AWS SDK for JavaScript directly from your browser. Visit https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/ for the guide.
Then you can call the putLogEvents method of AWS CloudWatchLogs API, assuming you already created log group and log stream. For guide visit https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/CloudWatchLogs.html#putLogEvents-property

We're not supposed to be dumping browser-side error logs directly from the browser to CloudWatch. This presents an issue because posting logs to CloudWatch using SDK outside the AWS ecosystem requires API secret key and secret IDs, which means that it could be exposed to bad elements that could run MITM attacks and intercept our AWS credentials.
You will have two options to proceed with what you desire to do with less risk:
Use client-side libraries (Sentry) that were specifically designed to log errors and debugging information.
You can implement the sending of logs via an API that then forwards/proxies the logs towards CloudWatch.

Related

Error: Credential is missing for AssociateSoftwareTokenCommand with AWS CognitoIdentityProviderClient Javascript SDK

BLUF: I would like to set up software token association in AWS Cognito in a user-facing JavaScript application (using AWS SDK) and am struggling with 'Credential is missing' errors.
I am trying to create an application using AWS Cognito using the Javascript SDK and the CognitoIdentityProviderClient that requires the user to use a software token MFA.
I can sign up and confirm the user using the SignUpCommand and I can generate a successful response for the user with InitiateAuthCommand using username/password login (first time logging in). At that point I then need to process an MFA_SETUP challenge which requires the use of a separate AssociateSoftwareTokenCommand flow to generate the secrets and responses.
I would expect to be able to let the end user, while logging in through their browser, issue the command to associate the software token themselves after successfully entering their username/password for the first time.
The problem I run in to is that I get the following error when issuing the AssociateSoftwareTokenCommand:
Error: Credential is missing
at SignatureV4.credentialProvider (runtimeConfig.browser.js:16)
at SignatureV4.<anonymous> (SignatureV4.js:169)
at step (tslib.es6.js:102)
at Object.next (tslib.es6.js:83)
at tslib.es6.js:76
at new Promise (<anonymous>)
at __awaiter (tslib.es6.js:72)
at SignatureV4.signRequest (SignatureV4.js:165)
at SignatureV4.<anonymous> (SignatureV4.js:85)
at step (tslib.es6.js:102)
Some vigorous Googling and looking through StackOverflow this method requires a credential object in the Client configuration, however this credential, as far as I can tell from Google/SO/AWS SDK docs, requires me to create an IAM object and generate keys / a secret key.
My application (built with React) is mostly single-app/browser based and I am trying to avoid additional server-side logic to act as a middleman if possible - and obviously don't want to go dropping secret keys into user-facing interfaces.
My questions then are:
Am I able to do this directly in my React App without action exposing credentials?
Is a server side middleman/proxy the only way for me to safely associate a software token?
Or is there perhaps some aspect of these credentials I am overlooking?
The offensive lines of code are simple (I can get the valid session key, no problem):
const client = new CognitoIdentityProviderClient({ region: AWS_REGION });
const command = new AssociateSoftwareTokenCommand({Session: session });
const response = await client.send(command)
Other searches have shown me that the credentials: {} object would then go in the client configuration object, which part I understand, I just don't want to put that on the client side with secret keys, etc.
Thank you for any assistance.

Writing data in Service Worker to Cloud Firestore

I'm working on a Firebase project and I want to receive firebase cloud messages (send from a Node.js server) in my service worker in my javascript project. This works fine, but now I want to save some data in my firebase cloud firestore from my service worker after receiving the notification. And there is the problem, I'm running in the error listed below:
Uncaught ReferenceError: XMLHttpRequest is not defined at Ln.<anonymous> (xmlhttp.js:167) at Me (channelrequest.js:512) at Ce (webchannelbase.js:1249) at Kn.xa (webchannelbase.js:1251) at re (run.js:124)
Since a few days I'm trying to find the error, but could not find a solution until now. Therefore I hope that you can help me now. I've tried to save the data in the firebase realtime database which works, but because I need to have offline persistence, I had to switch to cloud firestore which runs in the error above.
Here is the code from my node.js server for sending the notification (userID and registrationToken is defined before):
payload = {
data: {
"title": "This is a Notification",
"body": "This is the body of the notification message."
},
};
options = {
priority: "high",
timeToLive: 7200
};
// send message to the registration token
admin.messaging().sendToDevice(registrationToken, payload, options).then(function(response) {
admin.firestore().collection("Logging").doc(userID).set({active: "true"});
}).catch(function(error) {
console.log("Error sending message:", error);
});
And here is the code for receiving the notification in my firebase-messagins service worker file (userID is defined before):
self.addEventListener('notificationclick', function(event) {
event.notification.close();
const keepAlive = async() => {
firebase.firestore().collection("Logging").doc(userID).update({"open": "true"});
}
event.waitUntil(keepAlive());
});
Can anyone help me, please? I have no more ideas for solving my problem :/
You can't use XMLHttpRequest inside of a service worker. Instead, you need to use the Fetch API.
Based on your code, it's the Firebase client library that's using XMLHttpRequest under the hood. I don't think that you have any control over that (at least not based on what I see in the current JavaScript documentation for Firebase).
Instead of using the Firebase client library in your service worker, you could try using the REST API directly, using fetch() to send your HTTP requests. You'll be responsible for things like authentication and setting whatever user ids, etc. that the client library would otherwise handle for you, but I think that's your best bet inside of a service worker.
Since version 9 the Firebase Web SDK uses fetch instead of XMLHttpRequest. So it works inside a service worker.

How to use trello webhook callbackURL pointing to localhost in php codeigniter?

I have created a web-based system in codeigniter and some trello integration using its API services. I wanted to achieve something like if there is a new card created in a particular board it will also send a notification in my system that a new card is created. I started reading some documentation in trello webhooks but I just can't figure it out. Am I heading in the right way? Would it be valid if I provide a callbackURL pointing in localhost callbackURL: "localhost/main_controller/trelloCallback" ? However the code below returns a 400 status. Please help me. Thank you.
Javascript
$.post("https://api.trello.com/1/tokens/5db4c9fbb5b2kaf8420771072b203616f3874fa92a4c57f0c796cf90819fa05c/webhooks?key=a2a93deccc7064dek5f4011c2e9810d6", {
description: "My first webhook",
callbackURL: "localhost/dti_infosys/main_controller/trelloCallback",
idModel: "5a73c33ad9a2dk1b473612eb",
});
main_controller/trelloCallback
function trelloCallback() {
$json = file_get_contents('php://input');
$action = json_decode($json,true);
var_dump($action);
}
I know it's an old question, but this use case of having an external tool access our localhost for development is quite common.
So for anyone (OP included) that would like a cloud based service to be able to call a local endpoint, you can use tools like ngrok.
Basically, it sets up a URL accessible via internet that forwards all calls to one of your local ports.
Let's say that your local webserver running your PHP listens on the port 8000 on your machine.
With ngrok installed, you could execute the following command:
$> ngrok http 8000
That would set up the forwarding session:
ngrok by #inconshreveable
Session Status online
Session Expires 6 hours, 21 minutes
Version 2.3.35
Region United States (us)
Web Interface http://127.0.0.1:4040
Forwarding http://b5d44737.ngrok.io -> http://localhost:8000
Forwarding https://b5d44737.ngrok.io -> http://localhost:8000
You can then use any of the Forwarding addresses pointing to ngrok.io to access your local webserver through internet, meaning that if you were to provide an URL using any of these addresses instead of localhost to an external tool, it would be able to indirectly call your local endpoint.
In your case, your javascript call to create a Trello webhook would be:
$.post("https://api.trello.com/1/tokens/<YOUR_ACCESS_TOKEN>/webhooks?key=<YOUR_API_KEY>", {
description: "My first webhook",
callbackURL: "https://b5d44737.ngrok.io/dti_infosys/main_controller/trelloCallback",
idModel: "<YOUR_MODEL_ID>",
});
A bit of warning though: In the case of ngrok, the Forwarding URLs are randomized at each session startup, meaning that the webhooks you created on one session would not work an another session because there callbacksUrl wouldn't be valid anymore.
Note that you can subscribe to a paid plan to "reserve" ngrok subdomains and have URL consistency between sessions. Or you could manually update your webhooks callbackUrls with the new forarding URLs.
Anyway, I hope this will help!
P.S.: When the forwarding session runs, you can access localhost:4040 to inspect calls made on the forwarding URLs and retry some of them.

facebook graph api node.js invalid appsecret_proof

this is my first post so please go easy on me!
I am a beginning developer working with javascript and node.js. I am trying to make a basic request from a node js file to facebook's graph API. I have signed up for their developer service using my facebook account, and I have installed the node package for FB found here (https://www.npmjs.com/package/fb). It looks official enough.
Everything seems to be working, except I am getting a response to my GET request with a message saying my appsecret_proof is invalid.
Here is the code I am using (be advised the sensitive info is just keyboard mashing).
let https = require("https");
var FB = require('fb');
FB.options({
version: 'v2.11',
appId: 484592542348233,
appSecret: '389fa3ha3fukzf83a3r8a3f3aa3a3'
});
FB.setAccessToken('f8af89a3f98a3f89a3f87af8afnafmdasfasedfaskjefzev8zv9z390fz39fznabacbkcbalanaa3fla398fa3lfa3flka3flina3fk3anflka3fnalifn3laifnka3fnaelfafi3eifafnaifla3nfia3nfa3ifla');
console.log(FB.options());
FB.api('/me',
'GET',
{
"fields": "id,name"
},
function (res) {
if(!res || res.error) {
console.log(!res ? 'error occurred' : res.error);
return;
}
console.log(res);
console.log(res.id);
console.log(res.name);
}
);
The error I am getting reads:
{ message: 'Invalid appsecret_proof provided in the API argument',
type: 'GraphMethodException',
code: 100,
fbtrace_id: 'H3pDC0OPZdK' }
I have reset my appSecret and accessToken on the developer page and tried them immediately after resetting them. I get the same error, so I don't think that stale credentials are the issue. My
console.log(FB.options())
returns an appropriate looking object that also contains a long hash for appSecretProof as expected. I have also tried this code with a number of version numbers in the options (v2.4, v2.5, v2.11, and without any version key). Facebook's documentation on this strikes me as somewhat unclear. I think I should be using v2.5 of the SDK (which the node package is meant to mimic) and making requests to v2.11 of the graph API, but ??? In any case, that wouldn't seem to explain the issue I'm having. I get a perfectly good response that says my appSecretProof is invalid when I don't specify any version number at all.
The node package for fb should be generating this appSecretProof for me, and it looks like it is doing that. My other info and syntax all seem correct according to the package documentation. What am I missing here? Thank you all so much in advance.
looks like you have required the appsecret_proof for 2 factor authorization in the advance setting in your app.
Access tokens are portable. It's possible to take an access token generated on a client by Facebook's SDK, send it to a server and then make calls from that server on behalf of the client. An access token can also be stolen by malicious software on a person's computer or a man in the middle attack. Then that access token can be used from an entirely different system that's not the client and not your server, generating spam or stealing data.
You can prevent this by adding the appsecret_proof parameter to every API call from a server and enabling the setting to require proof on all calls. This prevents bad guys from making API calls with your access tokens from their servers. If you're using the official PHP SDK, the appsecret_proof parameter is automatically added.
Please refer the below url to generate the valid appsecret_proof,and add it to each api call
https://developers.facebook.com/docs/graph-api/securing-requests
I had to deal with the same issue while working with passport-facebook-token,
I finally released that the problem had nothing to have with the logic of my codebase or the app configuration.
I had this error just because I was adding intentionally an authorization Header to the request. so if you are using postman or some other http client just make sure that the request does not contain any authorization Header.

Best way to check if Twilio authentication is successful with JS SDK

What is the best way to check if Twilio auht_token, account_sid are correct and sms can be sent, number checked? Some call which doesn't cost extra credits?
E.g. I see https://www.twilio.com/docs/api/rest/usage-records on RESTfull documentation but can't find how to get the same thing with JS SDK. Can't see dedicated endpoint for config checking so looking for anything else.
Environment: NodeJS 8.9
Twilio developer evangelist here.
Most API calls to the Twilio REST API don't cost, particularly those where you retrieve a resource or list resources. Since you mentioned SMS you could, for example, list your latest messages like this:
const client = require('twilio')(accountSid, authToken);
client.messages.list({ limit: 10 })
.then(function(messages) {
console.log("Everything is good!");
})
.catch(function(err) {
console.error("Something went wrong: ", err)
})
Take a look through the API reference and pick one that takes your fancy.
Using JS SDK might be insecure here. Because of that I think they didn't include a method in the JS API which may present the user the account_sid and the auth_token, which may be exploited. I assume you can use a server bridge between your client JS and Twilio API. Like this:
Client makes a JS AJAX request to http://my.domain.tld/checkstatus
Server connects to the Twilio API with C#, PHP, NodeJS or whatever tech it uses
Twilio returns that the credentials and tokens are still valid or expired
Server prepares the client response as true/false or 0/1
Client reads the status and continues or redirects somewhere else.
Edit There's a GET method here which you can also use with JS AJAX call:
https://www.twilio.com/docs/api/rest/usage-records#list-get
which is requested by this format:
/2010-04-01/Accounts/{AccountSid}/Usage/Records/{Subresource}

Categories