Download a file from AWS S3 with Angular 2+ - asp.net

I have an ASP.NET Core web app and I'm using Angular 4. There are a lot of resources showing how to upload a file to S3, which I've done. But there doesn't seem to be anything about reading the file.
I want to give users the ability to upload a JSON file, save it to S3, then on a different view show the user all of the files they've uploaded as well as display the content of the file.
Are there any resources for showing how to do this?

If its publicaly available items, you can use the S3 JavaScript SDKs 'getObject' method to download a file.
/* The following example retrieves an object for an S3 bucket. */
var params = {
Bucket: "examplebucket",
Key: "HappyFace.jpg"
};
s3.getObject(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
/*
data = {
AcceptRanges: "bytes",
ContentLength: 3191,
ContentType: "image/jpeg",
ETag: "\"6805f2cfc46c0f04559748bb039d69ae\"",
LastModified: <Date Representation>,
Metadata: {
},
TagCount: 2,
VersionId: "null"
}
*/
});
If the files are private, use S3 Signed Urls or CloudFront Signed Urls( or Cookies) to generate a download Url from your backend after authorizing the user. Using this download url, download the file from S3 directly in angular app.
Examples:
Using CloudFront signed urls.
Using S3 Signed Url using the S3 SDKs getSignedUrl method.
Another option is to generate S3 temporary access credentials from AWS STS directly from your backend and send back to the Angular app or using a authentication service such as AWS Cognito so that Angular app can use it to invoke the S3 SDK.

Related

Download images to users local machines via Firebase Functions

Is it possible to download images to users local machines directly via Firebase functions? How to do it in case that:
Images are stored in Firebase storage.
Images are stored on other cloud storage providers (I can access them with url).
I don't want to download those images via url links so that I don't reveal the url the image is located on.
Is it possible to download images to users local machines directly via Firebase functions?
No, it's not possible. The client must reach out to the server in order to download content. The content can't be "pushed" to the client without its authorization. That would be a huge security hole for the client.
This is why download URLs exist - to give the client something to download via a normal HTTP request.
You can create a presigned URL using the Google APIs library. The Firebase bucket is just a regular GCS bucket. Something like this:
const admin = getFirebaseAdmin();
let bucket = admin.storage().bucket(firebaseConfig.storageBucket);
const f = bucket.file(location);
if (!(await f.exists())) {
throw logError(`No file found at specified location: ${location}`, functionName)
}
const url1 = await f.getSignedUrl({
action: 'read',
expires: new Date((new Date).getTime() + (24 * 60) * 60000) // expires in 24 hours
});
const url = url1[0];
return url;

Flutter - Uploading Image to Firebase Storage

I am trying to create an admin application that can select and upload an image to the Firebase storage and after that, I want the image URL to automatically reflect in the document that is sending data to the client-side application.
The only problem with this is that I only know how to upload an image to Firebase storage from the admin application. I haven't figured a way, as to how can I get the image URL into my document in Cloud Firestore.
Any suggestions or direction regarding this will be helpful.
I am using the flutter framework.
Database structure :
SkinTreatment :
"SkinTreatment": {
"someDocumentName": {
"title": "Threading",
"packageDetails":"This package will provide you with normal upper EyeBrow Threading",
"price" : "200"
"duration": "75mins"
},
"someDocumentName2": { ... },
"someDocumentName3": { ... }
}
You can certainly write code to write the path and/or URL of a file in Cloud Storage to any database. If you have a StorageReference object representing a file that was uploaded, you can use its getPath() method to get a path to the file in storage, and you can use getDownloadUrl() to asynchronously get a download URL as well.
For help writing data to Firestore, there is plenty of documentation.

How to upload file in firebase cloud function into firebase storage from url?

I'm using some API, that can give me file with 2 ways:
- I can get FILE in response
- I can get direct URL to the file to download
I decided to make request with first method, get FILE in response. I'm trying to save the file in firebase storage, from firebase cloud function:
exports.test = functions.region('europe-west1').https.onRequest(async (req, res) => {
const axios = require('axios').default
axios({
method: 'get',
url: `https://cloudpbx.beeline.ru/apis/portal/v2/records/06365a27-f8d1-4c51-bba3-a08802429964/9052948777%40mpbx.sip.beeline.ru/download`
}).then((resp) => {
console.log('resp', resp.data)
const bucket = admin.storage().bucket('cardbox-1.appspot.com/mcun/calls')
bucket.upload(resp.data)
})
})
In resp.data i have something like that:
��H�Xing��h $&)+-.179:>ACEGINRTW[_acegjmoqtwz|����������������������������������������������������PLAME3.100(,�$!��h�6���H��V]#mdE�E��"#���}�8kwT��&���>:P�2��>?�����8 ����������*���Z��XVC�(b�k�
D�G��
As i can see its file by itself, but how to handle it, and how upload it into firebase storage? Also, i'm not sure, that i'm correct creating a bucket and using storage api.
Please feel free to make request, you can get response without auth. That file must be mp3 type
Here is the logs with headers about what i'm getting from response:
HTTP/1.1 200 OK
Server: nginx/1.6.2
Date: Tue, 24 Mar 2020 16:19:55 GMT
Content-Type: application/octet-stream;charset=utf-8
Content-Length: 48744
Connection: close
Content-Disposition: attachment; filename=file.mp3
��H�Xing��h $&)+-.179:>ACEGINRTW[_acegjmoqtwz|����������������������������������������������������PLAME3.100(,�$!��h�6���H��V]#mdE�E��"#���}�8kwT��&���>:P�2��>?�����8 ����������*���Z��XVC�(b�k�
D�G��
C���al�ꝰ�z�KY�Q�]ЪF�8�^���W;,�LUteA�%�u�&��.���
0�q��Cڟ#���6��#�K�h��Itᠠ|[�q�{j'�+ �ʤS<F� Y�5D]?�����nlƦBC�S�Zx'�e�D�Fi_��Vl��4����H��E�z���SMVПQ�P� AT<���(�x�+3�ТB����e�ZC}t��Ї�#֗����2���Kve���.�ԏ�UH���u����ʘfbC��C� ��C�+ġ��̺��R#��|x5hq`Х3�?�N(���.5��� c+��`�Y�F8�d�B&53��¥�L�cx4��3��q�JHԓJ�43Ώ�(к�4r ��a �D
Dɍ0�
Well, it seems that there are a couple of tasks to do here :)
According to the definition of the upload method and their examples, using node js as client library (that makes total sense). You will be able to Upload a file to the bucket. But to be honest, I am not very clear about the usage of the pathString parameter since it points to a local path. Maybe the URL option that you mentioned would be great to test as a feature.
Just pasting the example from docs:
// Imports the Google Cloud client library
const {Storage} = require('#google-cloud/storage');
// Creates a client
const storage = new Storage();
async function uploadFile() {
// Uploads a local file to the bucket
await storage.bucket(bucketName).upload(filename, {
gzip: true,
metadata: {
Content-Type: 'audio/mpeg'
},
});
console.log(`${filename} uploaded to ${bucketName}.`);
}
uploadFile().catch(console.error);
Another way to accomplish this, is to make a POST request with the JSON API to the upload method of Cloud Storage. As I understand, the objects are saved as "RAW" in Cloud Storage.
If you are concerned about the conversion to MP3 file, I think this answer explains very well. Basically, if you want to perform the conversion in the Firebase Function, maybe is not the best scenario according to the size/time of the files.
Good Luck!

How to upload files or images on hasura graphql engine

Example:
upload file to server and save resulting path to the database, only authenticated users should be able to upload files
How to implement this?
to summarize we have 3 ways:
client uploads to s3 (or similar service), get's file url, then makes insert/update mutation to the right table
custom uploader - write application/server that uploads files and mutates db and use nginx routing to redirect some requests to it
custom resolver using schema stitching (example)
If you are uploading files to AWS S3, there is a simple way that you don't have to launch another server to process file upload or create a handler for hasura action.
Basically, when you upload files to S3, it's better to get signed url from backend and upload to s3 directly. BTW, for multiple image sizes hosting, this approach is easy and painless.
The critical point is how to get s3 signed url to upload.
In node.js, you can do
const AWS = require("aws-sdk");
const s3 = new AWS.S3({ apiVersion: "2006-03-01" });
const signedUrl = s3.getSignedUrl("putObject", {
Bucket: "my-bucket",
Key: "path/to/file.jpg",
Expires: 600,
});
console.log("signedUrl", signedUrl);
A signedUrl example is like https://my-bucket.s3.amazonaws.com/path/to/file.jpg?AWSAccessKeyId=AKISE362FGWH263SG&Expires=1621134177&Signature=oa%2FeRF36DSfgYwFdC%2BRVrs3sAnGA%3D.
Normally, you will put the above code to a handler hosted in AWS Lambda or glitch, and add some logic for authorization and even add a row to table.
You can see that the most important part is Signature=oa%2FeRF36DSfgYwFdC%2BRVrs3sAnGA%3D. How can we make it easier to get Signature?
After digging into AWS JS SDK, we can find signature is computed here.
return util.crypto.lib.createHmac(fn, key).update(string).digest(digest);
fn = 'sha1'
string = 'PUT\n\n\n1621135558\b/my-bucket/path/to/file.jpg'
digest = 'base64'
It's just sha1 a certain format of string. This means we can just use hasura computed fields and Postgres crypto function to achieve the same results.
So if you have a table "files"
CREATE TABLE files (
id SERIAL,
created_at timestamps,
filename text,
user_id integer
);
you can create a SQL function
CREATE OR REPLACE FUNCTION public.file_signed_url(file_row files)
RETURNS text
LANGUAGE sql
STABLE
AS $function$
SELECT ENCODE( HMAC(
'PUT' ||E'\n'||E'\n'||E'\n'||
(cast(extract(epoch from file_row.created_at) as integer) + 600)
||E'\n'|| '/my-bucket/' || file_row.filename
, 'AWS_SECRET', 'SHA1'), 'BASE64')
$function$
Finally, follow this to expose this computed field to Hasura.
This way allows you to be able to not add any backend stuff and handle permission all in Hasura.

Upload TLS client certificate to Firebase cloud functions

I'm trying to figure out if it is possible to upload a TLS client certificate to be used for my cloud functions in firebase. The TLS client certificate is required by a third-party payment solution called Swish.
This is my first firebase project and it seems silly that a small issue like this will render the platform unusable for me..
After some headache and trying I found a quite easy way to solve swish-payments through cloud functions:
Using request-js instead of the built in libraries, I only need to build the options object to use in the request.post() method as following:
const swishOptions = {
url: 'LINK TO SWISH SERVER',
json: true,
pfx: fs.readFileSync('cert.p12'),
passphrase: 'swish',
body: swishRequestBody
}
The cert.p12-file should be placed in the same folder as index.js and will be uploaded together with the functions.
rq.post(swishOptions, (err, res) => {
if (err){
console.log('payment creation error: ' + JSON.stringify(err))
reject(err)
}
if (res){
console.log('Payment-token: ' + res.headers.paymentrequesttoken)
}
});
The body-object should contain all fields specified in the Swish API, use console.log() to read the error-messages from the Swish-server.

Resources