How to use a proxy with the instagram-private-api for Node.js - node.js

Using a proxy with instagram-private-api.
Hi all, I spent a decent amount of time trying to figure this out and there is probably a really simple answer but I was seriously confused. When creating a session needed for the Instagram nodeJS API (private) you need a proxyUrl. I was wondering how to do / configure this? Do you need to create your own proxy server that you host?
Here is my code so far.
var Upload = require('instagram-private-api').V1;
var Client = require('instagram-private-api').V1;
var device = new Client.Device('test');
var storage = new Client.CookieFileStorage(__dirname +
'/cookies/test.json');
var photo = require('instagram-private-api').V1;
var username = 'testusername'
var password = 'testpassword'
var proxyUrl = '???'
Client.Session.create(device, storage, username, password, proxyUrl)
var Upload = require('./node_modules/instagram-private-api/client/v1/Upload.js')
var session = new Client.Session(device, storage, 'test', 'test')
Upload.photo(session, 'aaaa.jpg')
.then(function(upload) {
console.log(upload.params.uploadId);
return Media.configurePhoto(session, upload.params.uploadId, 'henlo world');
})
.then(function(medium) {
console.log(medium.params)
})
I know my code is probably seriously flawed as well, criticism is appreciated! Here's the link to the GitHub of the Node.JS wrapper mentioned. Here.

e
Hi there Benjamin,
I'm really looking forward to helping you.
As already stated, this library won't be upkept and maintained and could become irrelevant in updates to the official API.
I believe one has to set up a proxy url on their phone.

Related

How to rewrite NodeJS CryptoJS functions so they work in ReactJS web?

I have some code that was created for me by a past contractor that provided a working implementation of CryptoJS between a Unity3D client and NodeJS server app (as in encryption of client-server messages).
I am working on an implementation that needs to call the same server endpoints from a React web app. Basically, I need to be able to ensure that the React app provides the same results when encrypting and decrypting messages as the server (and hence the Unity3D implementation) does.
The existing encrypt/decrypt functions in the NodeJS app are shown below. They are somewhat more advanced than the standard CryptoJS examples and when I attempt to use them as-is in React, I get this error:
TypeError: cryptoJS.createHash is not a function. (In 'cryptoJS.createHash('md5')', 'cryptoJS.createHash' is undefined)
After some researching, I understand that potentially the 'use as-is' approach will fail because it's using a server side library on the client side, but I have been able to find anything that would explain how I would recreate the same code to work client-side.
encrypt(text, key, iv) {
const keyBuffer = Buffer.from(cryptoJS.createHash('md5').update(key).digest('hex'), "hex")
const ivBuffer = Buffer.from(cryptoJS.createHash('md5').update(iv).digest('hex'), "hex")
const textBuffer = Buffer.from(text, 'utf8')
let cipher = cryptoJS.createCipheriv(algorithm, keyBuffer, ivBuffer)
let encryptedText = Buffer.concat([cipher.update(textBuffer), cipher.final()])
return encryptedText.toString("base64")
}
decrypt(text, key, iv) {
const keyBuffer = Buffer.from(cryptoJS.createHash('md5').update(key).digest('hex'), "hex")
const ivBuffer = Buffer.from(cryptoJS.createHash('md5').update(iv).digest('hex'), "hex")
let decipher = cryptoJS.createDecipheriv(algorithm, keyBuffer, ivBuffer)
const textBuffer = Buffer.from(text, 'base64')
var decipheredContent = Buffer.concat([decipher.update(textBuffer), decipher.final()])
return decipheredContent.toString("utf8")
}
So, I need to figure out how to replace these encrypt/decrypt functions with ones that compile and function in client side in React web. Any help in steering me in the right direction or assisting with the code would be greatly appreciated. Thanks for taking the time to read my question.

Authentication proxy - req.user.sub persistent?

Situation
I used the node.js quickstart project from auth0 to build an authentication-proxy. Reason for this is that I cannot merge my spring backend with the Quickstart spring example.
In order to let the spring backend identify the user, I pass the user's sub as shown below.
var authenticate = jwt({
secret: new Buffer(process.env.AUTH0_CLIENT_SECRET, 'base64'),
audience: process.env.AUTH0_CLIENT_ID
});
...
app.get('/secured/*', function (req, res) {
var url = apiUrl + req.url;
var userId = req.user.sub; // 'auth0|muchoCrypto123'
url += "?userId=" + userId;
req.pipe(request(url)).pipe(res);
});
I am currently also investigating the usage of HttpRequestServlet in spring to retrieve user details.
Question
Is req.user.sub a value that I can use to identify the user without worrying that this value might change? So far I couldn't detect changes.
In the user management console I found the following:
user_id auth0|muchoCrypto123
Thus I assume that the user_id won't change. Can anyone confirm?

Using node.js to display helpscout metrics

I am hoping someone can point me in the right direction.
I would like to use metrics-helpscout to bring back data that I can use for a dashboard. I am not having any luck. This is also my first time using node.js so I apologize in advance.
Here is what I have tried so far.
Following the instructions on github I used npm to install segmentio/metrics, metrics-helpscout and metrics-express.
I created a file called metrics.js and added this...
var Metrics = require('metrics');
var expressMetrics = require('metrics-express');
var helpscout = require('metrics-helpscout');
var express = require('metrics-express/node_modules/express');
var app = express();
console.log('start' );
var zzz = Metrics()
.every('1m', helpscout('myapi-key', ['my-mailbox-id']))
.on('helpscout active tickets', function (metric) {
console.log('helpscout update:' + metric.latest() );
});
var xxx = Metrics()
.every('1m', helpscout('myapi-key', ['my-mailbox-id']));
var date = new Date();
var val = 3;
var key = 'test';
var ddd = Metrics().set(key, val, date);
app.use('/', expressMetrics(xxx))
.listen(7002);
I then started the file by running node metrics.js
I opened a browser and hit the url and port and I just got back
[]
On the metrics express page example i used the var xxx. I thought I would get back a list of all the supported metrics. I then tested just using my var ddd and it did return my value. I am sure I am missing something or a lot.
Any help is appreciated.
Just in case it matters I am using ArchLinux.
Welp I figured it out. I generated a new API key and it worked.

HttpClient fails to authenticate via NTLM on the second request when using the Sharepoint REST API on Windows Phone 8.1

Sorry for the long title, but it seems to be the best summary based on what I know so far.
We’re currently working on a Universal App that needs to access some documents on a Sharepoint server via the REST API using NTLM Authentication, which proves to be more difficult than it should be. While we were able to find workarounds for all problems (see below), I don’t really understand what is happening and why they are even necessary.
Somehow the HttpClient class seems to behave differently on the phone and on the PC. Here’s what I figured out so far.
I started with this code:
var credentials = new NetworkCredential(userName, password);
var handler = new HttpClientHandler()
{
Credentials = credentials
};
var client = new HttpClient(handler);
var response = await client.GetAsync(url);
This works fine in the Windows app, but it fails in the Windows Phone app. The server just returns a 401 Unauthorized status code.
Some research revealed that you need to provide a domain to the NetworkCredential class.
var credentials = new NetworkCredential(userName, password, domain);
This works on both platforms. But why is the domain not required on Windows?
The next problem appears when you try to do multiple requests:
var response1 = await client.GetAsync(url);
var response2 = await client.GetAsync(url);
Again, this works just fine in the Windows app. Both requests return successfully:
And again, it fails on the phone. The first request returns without problems:
Strangely any consecutive requests to the same resource fail, again with status code 401.
This problem has been encountered before, but there doesn’t seem to be a solution yet.
An answer in the second thread suggests that there’s something wrong with the NTLM handshake. But why only the second time?
Also, it seems to be a problem of the HttpClient class, because the following code works without problems on both platforms:
var request3 = WebRequest.CreateHttp(url);
request3.Credentials = credentials;
var response3 = await request3.GetResponseAsync();
var request4 = WebRequest.CreateHttp(url);
request4.Credentials = credentials;
var response4 = await request4.GetResponseAsync();
So the problem only appears:
on Windows Phone. The same code in a Windows App works.
when connecting to Sharepoint. Accessing another site with NTLM authentication works on both platforms.
when using HttpClient. Using WebRequest, it works.
So while I'm glad that I at least found some way to make it work, I’d really like to know what’s so special about this combination and what could be done to make it work?
Hi Daniel at the same problem when I do my sync, because windows phone had a lot of problems with cache, finallt I could solve with add headers.
Also I think so it's good idea that you use the timeout because it's a loooong response you can wait a lot of time... And the other good way to work it's use "using", it's similar that use ".Dispose()". Now I show you the code:
var request3 = WebRequest.CreateHttp(url);
request3.Credentials = credentials;
request.ContinueTimeout = 4000; //4 seconds
//For solve cache problems
request.Headers["Cache-Control"] = "no-cache";
request.Headers["Pragma"] = "no-cache";
using(httpWebResponse response3 = (httpWebResponse) await request3.GetResponseAsync()){
if (response3.StatusCode == HttpStatusCode.OK)
{
//Your code...
}
}
var request4 = WebRequest.CreateHttp(url);
request4.Credentials = credentials;
request.ContinueTimeout = 4000; //4 seconds
//For solve cache problems
request.Headers["Cache-Control"] = "no-cache";
request.Headers["Pragma"] = "no-cache";
using(httpWebResponse response4 = (httpWebResponse) await request4.GetResponseAsync()){
if (response4.StatusCode == HttpStatusCode.OK)
{
//Your code...
}
}
I wait that my code can help you. Thanks and good luck!

Properly enabling security for filepicker.io in Meteor

Filepicker by default allows pretty much everybody to add files to your S3 bucket who was clever enough to copy your API key out of the client code and luckily also offers a security option with expiring policies.
But I have no idea how to implement this in Meteor.js. Tried back and forth, installing meteor-crypto-base package, trying to generate the hashes on the server, tried RGBboy's urlsafe-base64 algorithm on https://github.com/RGBboy/urlsafe-base64. But I just do not get any further. Maybe someone can help! Thank you in advance.
This is an example of how to do filepicker signed URLs in meteor, based on the documentation here:
var crypto = Npm.require('crypto');
var FILEPICKER_KEY = 'Z3IYZSH2UJA7VN3QYFVSVCF7PI';
var BASE_URL = 'https://www.filepicker.io/api/file';
Meteor.methods({
signedUrl: function(handle) {
var expiry = Math.floor(new Date().getTime() / 1000 + 60 * 60);
var policy = new Buffer(JSON.stringify({
handle: handle,
expiry: expiry
})).toString('base64');
var signature = crypto
.createHmac('sha256', FILEPICKER_KEY)
.update(policy)
.digest('hex');
return BASE_URL + "/" + handle +
"?signature=" + signature + "&policy=" + policy;
}
});
Note this will need to exist somewhere inside of your server directory so you don't ship the key to the client. To demonstrate that it works, on the client side you can call it like so:
Meteor.call('signedUrl', 'KW9EJhYtS6y48Whm2S6D', function(err, url){console.log(url)});
If everything worked, you should see a photo when you visit the returned URL.

Resources