Twitter api statuses/update throws an error of authorization - javascript

I am building a bot on twitter with javascript to send a post from my own twitter account. But I am getting the following error:
{
code: 220,
message: 'Your credentials do not allow access to this resource.'
}
I am not using OAuth since I will be the only user of this bot, I just want to send a twitter post inside a certain listener that watches for some event. Here is the inside of my function to send a post on twitter:
const Twitter = require('twitter')
const client = new Twitter({
consumer_key: process.env.TWITTER_CONSUMER_KEY,
consumer_secret: process.env.TWITTER_CONSUMER_SECRET,
access_token_key: process.env.TWITTER_ACCESS_TOKEN_KEY,
access_token_secret: process.env.TWITTER_ACCESS_TOKEN_SECRET,
bearer_token: process.env.TWITTER_BEARER_TOKEN
})
async function sendTwitterPost() {
try {
const response = await client.post('statuses/update', {
status: 'Event occured!',
})
console.log(response)
console.log("Success")
}
catch(err){
console.log(err)
console.log("ERROR WHILE SENDING TWITTER POST!")
}
}

Related

Need help for cognito authentication flow with MFA to remember the device while challenging for MFA

I am using aws cognito service for authentication, followed https://github.com/aws-amplify/amplify-js/tree/master/packages/amazon-cognito-identity-js this documentation.
My login flow is something like this:
import {AuthenticationDetails,CognitoUser,CognitoUserPool} from 'amazon-cognito-identity-js';
const authenticationData = {
Username: <username>,
Password: <password>
};
const authenticationDetails = new AuthenticationDetails(
authenticationData
);
const userData = {
Username: <username>,
Pool: <userPoolId>,
};
const cognitoUser = new CognitoUser(userData);
cognitoUser.authenticateUser(authenticationDetails, {
onSuccess: (result) => {
const accessToken = result.getAccessToken().getJwtToken();
console.log('access token --> ', accessToken);
},
onFailure: (err) => {
console.log("error",err.message);
},
mfaRequired: function (codeDeliveryDetails) {
var verificationCode = prompt('Please input verification code', '');
cognitoUser.sendMFACode(verificationCode, this);
},
})
I've already created one AWS Cognito UserPool and the enabled MFA for the same.
In signin flow is working and the user is authenticated by multi-factor-authentication and I'm getting the access token.
But now I want not to verify mfa for the same device multiple times. Something like remember the device for the specific user for new 10-15 logins or next 7-15 days.
I checked the docs and seemed I can achieve this with aws amplify.
async function rememberDevice() {
try{
const result = await Auth.rememberDevice();
console.log(result)
}catch (error) {
console.log('Error remembering device', error)
}
}
But aws amplify is not working for me as it has an open issue.
https://github.com/aws-amplify/amplify-js/issues/9204
In my cognito user pool I tried to set this one, but it's not helping as well.
Is there any other option available in Cognito api to achieve my requirement?

POST request issues to Twitter API

I have been using NextJS, Twitter-lite to build an application using the twitter app, I basically am trying to implement the functionality in which users can post a tweet from the app to their twitter accounts. I have also used Next-Auth for implementing oAuth for twitter.
So after some working, I have managed to make it work and highlight my error - Access tokens. I want to fetch access tokens from the user after they have logged in,
In the below example - I run this script and a post is updated to my account indeed
Here is my code for the api/twitter/post.js
import Twitter from 'twitter-lite';
import { getSession } from 'next-auth/react'
import { getToken } from 'next-auth/jwt';
export default async (req, res) =>{
var Twit = require('twit')
const session = await getSession({ req });
const token = await getToken({
req,
secret: process.env.NEXTAUTH_SECRET
});
console.log(token.twitter.accessToken)
var T = new Twit({
consumer_key: process.env.TWITTER_CONSUMER_KEY,
consumer_secret: process.env.TWITTER_CONSUMER_SECRET,
access_token: 'process.env.TWITTER_ACCESS_TKN',
access_token_secret: 'process.env.TWITTER_ACCESS_TKN_SCRT'
});
T.post('statuses/update', { status: 'hello worldj!' }, function(err, data, response) {
console.log(data)
})
return res.status(200).json({ status: 'ok'});
}
Now this does work, when I hit my api route a new tweet is posted but only to 'my' account because I provided my access_tokens, I would like to know how I can get users access tokens, I have already signed them in using NextAuth so I'm sure I'm just missing a few things.
So I figured this one out,
In the call backs functions in the [...nextauth].js, I was just fetching the access_tokens with an outdated name and the new name is account.oauth_token
For anyone who ever encounters this issue - (Trying to fetch logged in users access tokens to access restricted twitter endpoints)
callbacks: {
async jwt({ token, user, account = {}, profile, isNewUser }) {
if (account.provider && !token [account.provider]) {
token[account.provider] = {};
}
if(account.oauth_token) {
token[account.provider].accessToken = account.oauth_token;
}
if (account.oauth_token_secret) {
token [account.provider].refreshToken = account.oauth_token_secret;
}
return token
},
This is how you get the logged in users access_token and access_token_secret

Twitter API streaming request returning 401

I am using Twitter for Node.js to make requests to the Twitter API, but I keep getting 401 Error which according to Twitter Docs means that there was an issue authenticating the request.
I am using the example from the twitter npm page:
const Twitter = require('twitter');
function twitter() {
var TwitterClient = new Twitter({
consumer_key: 'MY_KEY',
consumer_secret: 'MY_SECRET',
bearer_token: 'MY_TOKEN'
});
try {
TwitterClient.stream('statuses/filter', {
track: 'javascript'
}, function(stream) {
stream.on('data', function(event) {
console.log(event && event.text);
});
stream.on('error', function(error) {
try {
throw error;
}
catch (err) {
console.log(err);
}
});
});
} catch(e) {}
}
I get the following error in console:
Failed to load resource: the server responded with a status of 401 ()
Doing the GET request from the twitter npm page works fine:
var params = {screen_name: 'nodejs'};
TwitterClient.get('statuses/user_timeline', params, function(error, tweets, response) {
if (!error) {
console.log(tweets);
}
});
What I've tried:
Regenerated new tokens and double-checked them
Checked for updated system hour
Added access tokens and access secret to authentication
Thank you for your help

React Native Fetch Requests are not getting sent to my Node Js backend for some users

I've built a react native app that has a Node js backend. Users can sign In, sign up and view a profile page.
All my users can sign In but some of them can't view the profile page.
When I look at the request made to my backend, I get:
POST /UserRouter/SignIn 200 212.537 ms - 130342
Signing in works, it finds the user, returns the JWT token. When it's in the app no other requests are made. I get JSON Parse error: Unexpected EOF
Once you sign in, its supposed to immediately make a request to get your profile. With some accounts, this doesn't happen
My initial hypothesis of this problem is that the token for some users has expired, so they are not able to access protected routes. I use p***assport-jwt*** for my tokens. Hence, the backend not registering any requests.
Please find my code below:
_fetchData = () => {
AsyncStorage.getItem('jwt', (err, token) => {
fetch(`${backendUri }/UserRouter/Profile`, {
method: 'GET',
headers: {
Accept: 'application/json',
Authorization: token
}
})
.then((response) => response.json())
.then((json) => {
this.setState({name:json.name})
})
.catch((error) => {
console.log(error)
alert('There was an error ')
})
.done()
})
}
Here is my node JS code
app.get('/UserRouter/profile', passport.authenticate('jwt1', { session: false }), function (req, res) {
const token = req.headers.authorization
const decoded = jwt.decode(token.substring(4), config.secret)
User.findOne({
_id: decoded._id
},
function (err, user) {
if (err) throw err
res.json({ email: user.email, name: user.fName})
})
})
Thank you
This was the answer: https://stackoverflow.com/a/33617414/6542299
Turns out I was encoding my token with the users' document. the users' document was too large. so I just needed to reduce it

How do I upload files via using Google Drive API on meteor?

I'm using the Meteor framework to implement Google Drive API. I have generated clientId, clientSecret and redirectUrl.
In this method I have to get the url and when I clicked the Allow button, its redirect url which I have given in the redirect url. It's give the code in the url, I have save that code.
checkForAuthorization = function() {
return new Promise(function(resolve, reject) {
console.log("checkForAuthorization method is running......");
var clientId, clientSecret, redirectUrl, oauth2Client;
clientId = "XYZ";
clientSecret = "ABC";
redirectUrl = "http://localhost:3000/home";
oauth2Client = new google.auth.OAuth2(clientId, clientSecret,
redirectUrl);
getGoogleDriveAccessToken(oauth2Client).then(function(result) {
resolve(result);
}).catch(function(error) {
reject();
});
});
};
This code is for uploading the file. The login gives me an error saying that a login is required.
var uploadFileOnGoogleDrive = function(token) {
return new Promise(function(resolve, reject) {
var fileMetadata = {
'name': 'Claremont-Coral-Pillow-12x241.jpeg'
};
var media = {
mimeType: 'image/jpeg',
body: fs.createReadStream
('/home/administrator/Pictures/Claremont-
Coral-Pillow-12x241.jpeg')
};
drive.files.create({
auth: token,
resource: fileMetadata,
media: media,
fields: 'id'
}, function (err, file) {
if (err) {
console.log("The error is ", err);
} else {
console.log('File Id: ', file.id);
}
});
});
};
What am I doing wrong?
You are using the code that is made only for the terminal (command prompt).
As the documentation says itself on the below link
https://developers.google.com/drive/api/v3/quickstart/nodejs.
The authorization flow in this example is designed for a command line
application. For information on how to perform authorization in other
contexts, see the Authorizing and Authenticating. section of the
library's README.
For your answer, you should go through and use the code given in the below API Doc link:-
https://github.com/google/google-api-nodejs-client/#authorizing-and-authenticating
Thanks
Make sure you have followed the OAuth 2.0 general process which is applicable to all applications.
When you create your application, you register it using the Google
API Console. Google then provides information you'll need later,
such as a client ID and a client secret.
Activate the Drive API in the Google API Console. (If the API isn't
listed in the API Console, then skip this step.)
When your application needs access to user data, it asks Google for
a particular scope of access.
Google displays a consent screen to the user, asking them to
authorize your application to request some of their data.
If the user approves, then Google gives your application a
short-lived access token.
Your application requests user data, attaching the access token to
the request. If Google determines that your request and the token
are valid, it returns the requested data.
For additional reference, you can follow this SO post.
I had same problem integrating with JavaScript using googleapis due to version issues not supported greater than 25.0.0.1 but when I was passing credential like this it resolved my problem
function uploadFile(tmp_path,_folderID,file_name,contentType,cb){
var __fileData = fs.createReadStream(tmp_path);
var OAuth2 = google.auth.OAuth2;
var oauth2Client = new OAuth2(
client_id,
secretKey,
redirect_url
);
// Retrieve tokens via token exchange explained above or set them:
oauth2Client.credentials = {
access_token: body.access_token,
refresh_token: refreshToken
};
var drive = google.drive({version: 'v3', auth: oauth2Client});
drive.files.create({
resource: {
name: file_name,
parents: _folderID,
mimeType: contentType
},
media: {
mimeType: contentType,
body: __fileData
}
}, function (err, response) {
if(err) cb(err,null);
cb(null,'success');
})
};

Categories