Web Push Notification with Encrypted Payload in Python - django

Can someone please explain how to send notification with Payload for Chrome using Python/Django
I am doing so-
fcm_url = "https://fcm.googleapis.com/fcm/send"
encoded = WebPusher(subscription_info).encode(json.dumps(data))
crypto_key = "dh=" + encoded["crypto_key"]
salt = "salt=" + encoded['salt']
headers = {'Authorization': 'key=' + gcm_key, 'Content-Type': 'application/json', }
headers.update({'crypto-key': crypto_key, 'content-encoding': 'aesgcm', 'encryption': salt})
fcm_data = {"raw_data":base64.b64encode(encoded.get('body')), "registration_ids": ['eYXdX1V94XY:APA91bHPQdnlQiVwe5HmWnRQrtpOnHzAJ4kEHNgB8GrEZ_YxSgtwz-0gvcpUFBAb3_eVXOVcJAjvVotGfKl9jLGM_X6nZb76YzFBZazMu1auIDAXhXjUgFDHm7E2ffRpBD70rpD1qC1r']}
resp = requests.post(fcm_url,data=json.dumps(fcm_data),headers=headers)
Output:-
{"multicast_id":6483153199368608385,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1481362362576359%958b01adf9fd7ecd"}]}
but the notification doesn't contain the above specified Data.

It looks like you are mixing the Web Push Protocol and the Firebase Cloud Messaging API.
Are you trying to send a request to a normal open web PushSubscription, or are you trying to send to a Firebase token?
If you are using the Firebase Messaging SDK for web, then you don't need to encrypt the payload (It's one of the main reasons for using the firebase messaging SDK).
If you are using just the normal open web API's and not touching the Firebase Messaging SDK, I'd check out: https://github.com/web-push-libs/pywebpush

Related

How to receive Decrypted path variable using AWS Rest API Gate way in java

I am new to AWS Lambda,
I have created one AWS Rest API gateway and connected to my AWS Lambda, I am able send request and receive response, But the Issue is while am sending request with space
,ie, am sending a path variable with space "Contact Information"
URL Before encode :
/tcn/10005/file-list/Contact Information/1-xxx-222-yyy
/* Using the below java code to give request to AWS API Gate way , It is encode my path variable like below */
String restApi = restUrl +"/tcn/10005/file-list/Contact Information/1-xxx-222-yyy";
UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(restApi);
HttpEntity<String> request = new HttpEntity<>(headers);
ResponseEntity<List> response = restTemplate.exchange(builder.buildAndExpand().toUri(),
HttpMethod.GET, request, List.class);
URL After encode :
/tcn/10005/file-list/Contact%20Information/1-xxx-222-yyy
While receiving this request from lambda am get path variable as "Contact%20Information" but it has to be a decoded value "Contact Information"
Is there any way I can archive this using AWS API Gate ? Please guide me.

Using generated on the server AccessToken to connect to GCP Text to Speech

I would like to be able to connect to GCP Text to Speech from a react.js front-end using an access token generated on the server. I adapted the code from the linked reply to produce an access token. However, I was not able to find in the docs how to use that token to connect from the front-end to GCP.
For simplicity, I would like to begin with modifying the linked working node.js example from the docs to use the hardcoded access token instead of the Default Credentials File to connect with the service.
Here is my attempt (compared to the example, only the construction of client is modified):
'use strict';
function main() {
// [START tts_quickstart]
// Imports the Google Cloud client library
const textToSpeech = require('#google-cloud/text-to-speech');
// Import other required libraries
const fs = require('fs');
const util = require('util');
// Creates a client
const client = new textToSpeech({tk: 'ya29.c.Kp8BCQj<etc.>'}).TextToSpeechClient();
async function quickStart() {
// The text to synthesize
const text = 'hello, world!';
// Construct the request
const request = {
input: {text: text},
// Select the language and SSML voice gender (optional)
voice: {languageCode: 'en-US', ssmlGender: 'NEUTRAL'},
// select the type of audio encoding
audioConfig: {audioEncoding: 'MP3'},
};
// Performs the text-to-speech request
const [response] = await client.synthesizeSpeech(request);
// Write the binary audio content to a local file
const writeFile = util.promisify(fs.writeFile);
await writeFile('output.mp3', response.audioContent, 'binary');
console.log('Audio content written to file: output.mp3');
}
quickStart();
// [END tts_quickstart]
}
main(...process.argv.slice(2));
I get an error that textToSpeech is not a constructor. How can I fix this example to connect to GCP Text to Speech using the access token?
Unfortunately it is not possible to authenticate via access token using the Text-To-Speech Nodejs Client Library. The TextToSpeechClient in Node runtime only accepts credentials objects which can be found from service accounts.
Based from the SO example you included in your question, it generates the access token and uses it in Android. It makes sense since there are no client libraries for Android as of now, so the OP is using the Text-To-Speech REST API to create an HTTP request. Using HTTP request requires the access token to authenticate, thus the solution of the SO example.
My suggestions are the following:
Adapt the solution similar to the SO example which is sending request via HTTP so you can use access token for authentication.
Use a different programming language like Python (seems unlikely since you are using React). It is possible in Python Client Library to use access token for authentication since it accepts credentials object.
Also just to add you are passing parameters incorrectly on your client object. It should be const client = new textToSpeech.TextToSpeechClient(object);

Cannot get AWS API Gateway to override response codes - FitBit endpoint verification

I am integrating FitBit with my company's platform and we are switching over from syncing with our own server to sending the data to an AWS Kinesis stream. This requires us to also set up an AWS API Gateway with a POST method to write the data to the stream. I've also set up a GET method on the same resource for the verification process.
Here's the problem I'm facing:
Once I have the API Endpoint properly set up, FitBit provides a verification code and requires a verification process in which it sends a GET request to the endpoint with a ?verify={correctVerificaitonCode} query param and wants a 204 response, and one with a ?verify={incorrectVericationCode} param and wants a 404 response. This would obviously be easy for me to accomplish in our Rails backend, where I'm in control of the code, but on AWS it's a tangled mess with little control.
I have read endless documentation on AWS about Mapping Templates and Integration Response, but no matter what I do, I cannot get the API to respond with anything other than a 200 (when the request is clean and has any ?verify param) or 500 (when I purposefully make a bad request). There is no straightforward answer in the AWS docs about this.
This is the closest I have come to a setup that the docs promise should work, yet it does not:
Using the Integration Response HTTP Status Regex
And with this mapping template
I'm two days in on this and frustrated to my wits' end. Help!
Just in case anyone find this thread in the future and is struggling with the same issue - here is how you verify a FitBit Developer API app with an Amazon Kinesis stream being fed by an AWS API Gateway:
First, set up the POST method of your API - there are AWS guides to this. Select AWS service as the integration type and kinesis as the service, then set up a mapping template for 'application/json' to look like this:
#set($event = $input.body)
#set($data = '{"action":' + $event +', "authorization": "' + $input.params('Authorization') + '", "stage":"' + $context.stage + '"}')
#set($body = $util.base64Encode($data))
{
"Data": "$body",
"PartitionKey": "shard-1",
"StreamName": "gm-fitbit"
}
Once you've done that, create a GET method on the same resource. Set MOCK as the integration type and create the endpoint. Now click on the GET method and visit Method Request. Expand URL Query String Parameters and add verify as a query param. Now, go back to the method and visit Integration Response.
Under the already existing 200 response method, expand it and add an HTTP status regex of 2\d{2} and passthrough handling.
Expand Mapping Templates, and for 'application/json' create this mapping template:
{
#if( $input.params('verify') == "theVerificationCodeProvidedToYouByFitbit" )
#set($context.responseOverride.status = 204)
#else
#set($context.responseOverride.status = 404)
#end
}
That's it! Deploy the API again, head back to Fitbit, and click verify!
There. Now there is officially a guide online to integrating Fitbit with an AWS Kinesis stream, the one I wish I had when struggling with this for 3 days.
Cheers!

I want to create my first Red App for sabre with eclipse

I'm new in this environment and I want to create my first red app, But I need some help to connect the web services for sabre , Can you help me with a example for starting in this? I have instaled the Eclipse RCP that sabre has in their page and configured it, but dont have an idea of how to start.
Thank You very much.
I would suggest the com.sabre.redapp.example.cf.sws RedApp that comes bundled on the RedApp SDK samples folder.
Mainly, for consuming Sabre WebServices, you'll be using Communication Framework classes from RedApp SDK, which allows u to consume the services without being worried with low level communications, that is, most of your development efforts will be to create and parse the XML payloads, consuming the services using java is very straightforward :
// Set actionName to the correct Sabre Web Services action name
String actionName = "OTA_AirAvailLLSRQ***";
// Retrieve a reference to ISRWCommunication
ISRWCommunication com = Activator.getDefault().getServiceReference(ISRWCommunication.class);
// Create the request
SWSRequest request = new SWSRequest();
request.setAction(actionName);
request.setPayload(payload);
// Send the request
SWSServiceClient client = new SWSServiceClient(com);
ClientResponse <SWSResponse> rsp = client.send(request);
// Retrieve the response
if (rsp.isSuccess()) {
SWSResponse response = rsp.getPayload();
// Response for the sent request
Document responsePayload = response.getResponse();
}
*** don't forget to Authorize the service usage on redapp.xml file :
<Authorization name="com.sabre.edge.cf.sws.SWS" metric="tpm">
<Action name="OTA_AirAvailLLSRQ" threshold="3" />
</Authorization>

Angular REST API security

I have issue with my app when I use Angular to consuming REST API request
The Web Service URLs store in the Angular service or controller js file
so if I have Login web service to check usename and password like:
http://mylocal.com/api/service.json?api_user=Username&api_key=Password
The end users or developers can get this url and build a software to try finding the username and password, so how to hide the web services urls in angular js if that possible?
Example:
$scope.submit = function(request) {
$scope.contactUsSuccess = false;
$http.post('/_/contactUs' +
"?firstName=" + encodeURIComponent(request.first) +
"&lastName=" + encodeURIComponent(request.last) +
"&email=" + encodeURIComponent(request.email) +
"&phone=" + encodeURIComponent(request.phone) +
"&company=" + encodeURIComponent(request.company) +
"&message=" + encodeURIComponent(request.message)
) // Contact us
.success(function(reply){
console.log(reply);
$scope.contactUsSuccess = true;
$scope.contactUs = "";
})
.error(function(){
alert('There seemed to be a problem with your submission. Please refresh the page and try again.')
});
};
You can get the contact url web service and use it, so how can i solve this issue?
First off this is really bad if you're doing this over HTTP and not HTTPS. Sending this over HTTP sends your credentials in text/plain for anyone to sniff and grab on the network.
I'm assuming they are not using specific firewall rules either.
Because of the REST endpoint you're dealing with, you could initiate the REST call in a few different ways:
Setup an HTTP(S) proxy that has that pre-defined username/password pair in it. That way instead of calling https://someremoteapp.com/user=joe&pass=test you could call /rest
Probably the better option is to setup a back-end forwarder service to work with this API and hide the credentials on the back-end. You can do this using something like PHP, Ruby, Python, Node.JS...
Best option is to ask if they support other security mechanism.