How to get uploaded file using koa2? - multipartform-data

I posted a formData to my koa project. I got the following when I printed ctx.request
'content-type': 'multipart/form-data; boundary=----WebKitFormBoundary5AThNwq75QDUwSIA','content-length': '517840'
However, why did I get {}' when I printed ctx.request.body?

You will need to use some middleware, for example koa-body (but there is a lot of alternatives).
See the example in official repository

Related

CSRF Validation Failed in Drupal 7

I've been searching and searching, including the many topics here, for a solution to my problem. I've had no luck thus far.
A bit of a backstory: I'm writing an AngularJS app with Drupal 7 as a backend. I'm able to login without problem, save Session Name and Session ID, and put them together for a Cookie header (I had to use this "hack"). Further, if I made a login call in the Postman app, then tried to update the node, it'd work. It makes me think that there's a problem with session authentication, but I still can't figure it out.
That being said, I'm at a roadblock. Whenever I try to PUT to update a node, I get the following error:
401 (Unauthorized : CSRF validation failed)
Now, my ajax call looks like this:
$http({
method: 'PUT',
url: CONSTANTS.SITE_URL+"/update/node/"+target_nid,
headers:{
'Content-Type': CONSTANTS.CONTENT_TYPE,
'Authentication': CONSTANTS.SESS_NAME +"="+CONSTANTS.SESS_ID,
'X-CSRF-Token' : CONSTANTS.TOKEN
},
data: {
(JSON stuff)
}
})
The CONTENT_TYPE is "application/json", the "Authentication" is the band-aid for the Cookie header problem, and the "X-CSRF-Token" is what is (presumably) giving me the problem. SESS_NAME, SESS_ID, and TOKEN are all gathered from the response at Login. I can pull lists made by users on the website, I can pull the list of all of the nodes of a certain type on the website as well. I only run into a problem when I attempt to PUT to update the node.
If I missed any information, let me know and I'll add it!
EDIT: I'm using AngularJS version 1.5.3.
After trying everything else, I followed one of the comments in the thread I linked at the beginning of my original post. They had to comment out a line in Services.module :
if ($non_safe_method_called && !drupal_valid_token($csrf_token, 'services')) {
//return t('CSRF validation failed');
}
It's around line 590, plus or minus a few depending on how much you've messed with the file. I don't like doing it this way, but I can't for the life of me figure out why the token's not working right. It's a temporary fix, for sure, but if someone runs across this with the same problem in the future it'll hopefully help you out!
Instead of removing the line you could also add a true to drupal_valid_token
if ($non_safe_method_called && !drupal_valid_token($csrf_token, 'services',true)) {
return t('CSRF validation failed');
}

Saved image cannot be opened using eligrey's filesaver

I am using react to create front-end.
I have a download button which will trigger an action.
The action will use axios.post to call the server which will return a file.
The axios.response is something like this
resopnse.data: 'binary data of image file'
response.headers: {
cache-control:"public, max-age=0"
content-disposition:"attachment; filename="test.jpg""
content-type:"image/jpeg"
last-modified:"Mon, 22 Jan 2018 18:49:27 GMT"
}
response.data is tested using postman which converts the response to the correct image.
Now I am going to use eligrey's filesaver to save it.
This is what I have.
let fileName = getFileNameFromContentDisposition(response.headers);
let blob = new Blob([response.data], {type: response.headers["content-type"]});
fileSaver.saveAs(blob, fileName, true);
The code is tested using Chrome. The code will create a jpeg file, but it cannot be opened.
I played around with solutions provided for similar questions in GitHub and this website. But none of it is working.
I believe I am missing trivial setting to make this work.
The problem is not the library.
axios is the cause. The response from axios is already converted to json. So the binary data lost some information.
Even when the blob string fromaxios's reply is converted back to blob. It is a corrupted blob.
The workaround is to use fetch, and convert the response to response.blob().

"Failed to parse UUID" error message on attempting to login via TrueVault api

On attempting to login via the truvault api using angular js, I am getting this error message: Failed to parse UUID. I am passing the username, password and account_id as params. I am successful using the curl command and get the success response.
The 400 error is not described in the api docs for authorization. I am not sure about if this UUID is linked to the schema_id. Would anyone (truevault guys!!) know what I am doing wrong?
I contacted truevault support on this one. Dan helped me get through it.
I was passing the username/password/account_id as url string query parameters. I had to make two changes to the code:
1. Pass the above as form data parameters
2. add the angular-post-fix.js to my project.
(Note: I am not adding the link as there are editors who will disallow the post with links to elsewhere. It has happened in the past!)
When using Node.js, the querystring API is really useful. Just pass an object to the querystring.stringify() function, and the resulting output is ready to be sent to TrueVault for login.
Additionally, I found that adding the header 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8' might be necessary (which is one of the things the Angular post-fix library does).
#orthodoc is right, but is kind of tricky how to actually build the request. Lets say we are using fetch with formData params, I'd like to add an example of a successful request:
...
var formData = new FormData();
formData.append('username', username);
formData.append('password', password);
formData.append('account_id', accountId);
return fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
},
body: formData
});
...

Is it possible to upload files to S3 from browser in IE8?

Now I have this code in javascript.
var file_object = $('#PHOTO').get(0).files[0];
the_form = new FormData();
the_form.append("AWSAccessKeyId", "TESTING");
the_form.append("acl", "authenticated-read");
the_form.append("policy", policy);
the_form.append("signature", signature);
the_form.append("Content-Type", "image/jpeg");
the_form.append("key", "test.jpg");
the_form.append("file", file_object);
$.ajax({
url: "http://S3BUCKET.s3.amazonaws.com",
type: "POST",
data: the_form,
processData: false,
contentType: false
})
It works sweetly, in Chrome, Firefox, except IE6,7,8,9.
The reason is that file object is not supported until IE10!
https://developer.mozilla.org/en-US/docs/Web/API/File
Is there any work-around solution for browsers before IE10?
PS: Code example would be nice!!
Without Flash many things are definitely a no-go. I believe the lib you reference has some Flash fallbacks, but I'm unclear as to whether they can handle all the issues involved. This is something I'm currently dealing with myself, and here are the issues in brief:
Content-Type header in response. IE (without Flash intermediary) will try to download a JSON content type, no way around this that I know without a proxy middleman to fudge headers.
hostname mapping. If you don't map to origin hostname, IE iframe (which is the non-Flash fallback) will not allow you to read the contents of it from the containing window. Fire and forget may be possible, but consuming the response/detecting errors from s3 may not.
I will update this answer as I uncover more in the coming days. This is a large project so we have some pretty significant requirements and I imagine I'll learn a lot in the next week or so.
This is covered in a lot more detail here (not my company/project/post): http://blog.fineuploader.com/2013/08/16/fine-uploader-s3-upload-directly-to-amazon-s3-from-your-browser/

Recaptcha angularjs verify user's answer

I am using the following plugin https://github.com/VividCortex/angular-recaptcha in order to use recaptcha at a login form.
I am using the following code for verification
$http({
url: 'https://www.google.com/recaptcha/api/verify',
method: 'POST',
params: {privatekey: "key", remoteip: "userip", challenge: "challenge", response: "user_answer" },
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).success(function(data) {
console.log(data);
if (valid) {
console.log('Success');
alert('Success');
} else {
console.log('Failed validation');
alert('Fail');
// In case of a failed validation you need to reload the captcha because each challenge can be checked just once
//vcRecaptchaService.reload();
}
});
But google server is not returning anything.
I updated the code but no luck.
I think you have a typo in your code:
post: 'GET'
Change that to method: 'GET' or method: 'POST'.
You can check out angular documentation on http to make sure you've written all the params right.
If this wasn't the source of your problems, you should post more details about your issue (what do you see in your networkl console for example).
Keep in mind that recaptcha validation must be done at server-side. I'm not 100% sure that you are doing that in the browser, but your code looks like it.
As Miguel Trias stated, you shall not validate directly from angularjs/javascript client, instead you should send the challenge and response field to your server and validate then.
Therefore you can use the uri you used (https://www.google.com/recaptcha/api/verify) or a plugin, e.g. if you use php see https://developers.google.com/recaptcha/docs/php. I'd prefer a plugin because it will save work.
Furthermore keep in mind that your private key should not be used in the client, this is why it is called private. It is only used to communicate between your server and the reCaptcha servers. The public key is used to communicate between your client and the reCaptcha servers.
For more info read the Overview

Resources