how to properly configure mean.js passport to authenticate with twitter - passport.js

In my mean.js based app, I'm trying to implement passport twitter authentication.
My twitter section in development.js looks like this:
twitter: {
clientID: process.env.TWITTER_KEY || ' somekey1234',
clientSecret: process.env.TWITTER_SECRET || 'someSecret1234',
callbackURL: '/auth/twitter/callback'
}
I have signed up with twitter, added my mobile number to my profile, created an app, and got the consumer key and consumer secret.
My Website entry in twitter looks like this:
http://10.211.55.25:3000
My callback url entry looks like this:
http://10.211.55.25:3000/auth/twitter/callback
When I attempt to "Sign up using Twitter" in my app. I get this error:
Error: {"errors":[{"code":32,"message":"Could not authenticate you."}]}
at Strategy.parseErrorResponse (/home/eugene/dev/node/DataManager_0.2/node_modules/passport-twitter/lib/strategy.js:182:10)
at Strategy.OAuthStrategy._createOAuthError (/home/eugene/dev/node/DataManager_0.2/node_modules/passport-twitter/node_modules/passport-oauth1/lib/strategy.js:349:16)
at OAuthStrategy.authenticate (/home/eugene/dev/node/DataManager_0.2/node_modules/passport-twitter/node_modules/passport-oauth1/lib/strategy.js:218:41)
at exports.OAuth.getOAuthRequestToken (/home/eugene/dev/node/DataManager_0.2/node_modules/passport-twitter/node_modules/passport-oauth1/node_modules/oauth/lib/oauth.js:543:17)
at exports.OAuth._performSecureRequest.passBackControl (/home/eugene/dev/node/DataManager_0.2/node_modules/passport-twitter/node_modules/passport-oauth1/node_modules/oauth/lib/oauth.js:397:13)
at IncomingMessage.exports.OAuth._performSecureRequest.request.on.callbackCalled (/home/eugene/dev/node/DataManager_0.2/node_modules/passport-twitter/node_modules/passport-oauth1/node_modules/oauth/lib/oauth.js:409:9)
at IncomingMessage.EventEmitter.emit (events.js:117:20)
at _stream_readable.js:920:16
at process._tickCallback (node.js:415:13)
As I'm getting this error, the app url in my browser is being set to:
http://10.211.55.25:3000/auth/twitter
What can I do to fix this?

You have an error in the JSON values (An space that is present in TWITTER_KEY value):
twitter: {
clientID: process.env.TWITTER_KEY || ' somekey1234',
clientSecret: process.env.TWITTER_SECRET || 'someSecret1234',
callbackURL: '/auth/twitter/callback'
}
should be
twitter: {
clientID: process.env.TWITTER_KEY || 'somekey1234',
clientSecret: process.env.TWITTER_SECRET || 'someSecret1234',
callbackURL: '/auth/twitter/callback'
}

Related

Passport.js: Having trouble redirecting after Twitter login

I'm having trouble redirecting my users to a specified page on my website after logging in with Twitter and Passport.js.
Here's the relevant code:
let prefix = 'http://';
let callbackURL = 'localhost:3000'
// Initiate the strategy, from the Passport.js docs
passport.use(
new Strategy(
{
consumerKey,
consumerSecret,
callbackURL: `${prefix}${callbackURL}/api/auth/twitter/callback`,
},
function (token: any, tokenSecret: any, profile: any, cb: any) {
console.log('Thank you for logging in', profile.displayName)
},
),
)
// Where my users get redirected from twitter
app.get(
'/api/auth/twitter/callback',
passport.authenticate('twitter', {
successRedirect: '/api/testing',
failureRedirect: '/login',
}),
)
// Where the Twitter login process starts
app.use('/api/auth/twitter', passport.authenticate('twitter'))
At the moment /api/auth/twitter is redirecting me to Twitter and allowing me to login. Afterwards I get sent to /api/auth/twitter/callback which even triggers the Thank you for logging in console.log.
Unfortunately after that I'm not being redirected to either / or /login.
My redirect chain stops at http://localhost:3000/api/auth/twitter/callback and displays:
Error: This feature is temporarily unavailable
at Strategy.parseErrorResponse (/home/leonardo/serverless-prisma-vercel-boilerplate/node_modules/passport-twitter/lib/strategy.js:206:12)
at Strategy.OAuthStrategy._createOAuthError (/home/leonardo/serverless-prisma-vercel-boilerplate/node_modules/passport-oauth1/lib/strategy.js:393:16)
at /home/leonardo/serverless-prisma-vercel-boilerplate/node_modules/passport-oauth1/lib/strategy.js:154:43
at /home/leonardo/serverless-prisma-vercel-boilerplate/node_modules/oauth/lib/oauth.js:465:22
at passBackControl (/home/leonardo/serverless-prisma-vercel-boilerplate/node_modules/oauth/lib/oauth.js:397:13)
at IncomingMessage.<anonymous> (/home/leonardo/serverless-prisma-vercel-boilerplate/node_modules/oauth/lib/oauth.js:409:9)
at IncomingMessage.emit (events.js:327:22)
at endReadableNT (_stream_readable.js:1221:12)
at processTicksAndRejections (internal/process/task_queues.js:84:21)
Any idea what this could be about? Is there something wrong with the way my redirects are setup?
This seems what these people are experiencing but it's not of much help solving the core issue.

ValidationError: "tenantId" is not allowed when using AzureAD for hapi JS route authorization

We are trying to use #hapi/bell on our back-end routes to provide authorization. The authentication strategy uses azure as provider and the scheme is bell
This is how I register the strategy. The clientId, clientSecret, tenantId and password are hidden for obvious reasons
server.auth.strategy('azureAD', 'bell', {
provider: 'azure',
clientId: '...',
clientSecret: '...',
tenantId: '...',
password: '...',
providerParams: {
response_type: 'code'
},
scope: ['openid', 'offline_access', 'profile', 'User.Read']
})
When I run the server, I get the following error:
{ [ValidationError: "tenantId" is not allowed] ...
Now, looking into the azure portal, we definitely want to be supporting accounts only inside the organisation i.e. single-tenant.
If I remove the tenantId option and restart the server I get CORS error which essentially says that our app is not configured as a multi-tenant application and we need to use a tenant-specific endpoint or configure the application to be multi-tenant. Adding the tenantId, however, says that it is not allowed.
Any guidance as to why this is happening will be highly appreciated.
I found out that instead of registering the strategy as I have shown in the question the following could be done:
const custom = Bell.providers.azure({ tenant: '...' })
server.auth.strategy('azureAD', 'bell', {
provider: custom,
clientId: '...',
clientSecret: '...',
password: '...',
isSecure: false, // look into this, not a good idea but required if not using HTTPS
providerParams: {
response_type: 'code'
},
scope: ['openid', 'offline_access', 'profile', 'User.Read']
})
This gets rid of the "tenantId" is not allowed error, however, we now get a different error stating Authentication failed due to: Missing custom request token cookie.
Bell suggests that a common solution is to combine bell with the hapi-auth-cookie authentication scheme plugin, so now this is something to look into.
The Joi package is validating the schema and throwing errors. See config property below. It overrides options and avoids the "tenantId" or "tenant" is not allowed error you are seeing. Also, in recent versions Bell Azure Provider wants "tenant" not "tenantId" property.
server.auth.strategy('azureAD', 'bell', {
provider: 'azure',
config: {
tenant: '...',
useParamsAuth: false,
},
clientId: '...',
clientSecret: '...',
password: '...',
providerParams: {
response_type: 'code'
},
scope: ['openid', 'offline_access', 'profile', 'User.Read'],
isSecure: false,
})

Firebase admin SDK getaddrinfo ENOTFOUND metadata.google.internal. Error code: ENOTFOUND"

I'm trying to set up the admin sdk and also created a new private key. I even reverted back to an old version with only the admin sdk and it won't work. Is there anything which could be cached on my device?
Nest application successfully started NestApplication true
Credential implementation provided to initializeApp() via the "credential" property failed to fetch a valid Google OAuth2 access token with the following error: "Error fetching access token: Error while making request: getaddrinfo ENOTFOUND metadata.google.internal. Error code: ENOTFOUND". Error: Credential implementation provided to initializeApp() via the "credential" property failed to fetch a valid Google OAuth2 access token with the following error: "Error fetching access token: Error while making request: getaddrinfo ENOTFOUND metadata.google.internal. Error code: ENOTFOUND".
at FirebaseAppError.FirebaseError [as constructor] (/Users/user/Documents/Dev/project/demo/node_modules/firebase-admin/lib/utils/error.js:42:28)
at FirebaseAppError.PrefixedFirebaseError [as constructor] (/Users/user/Documents/Dev/project/demo/node_modules/firebase-admin/lib/utils/error.js:88:28)
at new FirebaseAppError (/Users/user/Documents/Dev/project/demo/node_modules/firebase-admin/lib/utils/error.js:122:28)
at /Users/user/Documents/Dev/project/demo/node_modules/firebase-admin/lib/firebase-app.js:121:23
at processTicksAndRejections (internal/process/task_queues.js:85:5)
at /Users/user/Documents/Dev/project/demo/node_modules/#nestjs/core/router/router-execution-context.js:44:28
at /Users/user/Documents/Dev/project/demo/node_modules/#nestjs/core/router/router-proxy.js:8:17 ExceptionsHandler
This is how I'm trying to use both packages:
import * as firebase from 'firebase-admin';
import * as serviceAccount from '../../firebase_credentials.json';
const config = {
type: serviceAccount.type,
projectId: serviceAccount.project_id,
privateKeyId: serviceAccount.private_key_id,
privateKey: serviceAccount.private_key,
clientEmail: serviceAccount.client_email,
clientId: serviceAccount.client_id,
authUri: serviceAccount.auth_uri,
tokenUri: serviceAccount.token_uri,
authProviderX509CertUrl: serviceAccount.auth_provider_x509_cert_url,
clientC509CertUrl: serviceAccount.client_x509_cert_url,
};
if (!firebase.apps.length) {
firebase.initializeApp(config);
}
export const firebaseAuth = firebase.auth();
export function create(email: string, password: string) {
firebaseAuth.createUser({
email: email,
emailVerified: false,
password: password,
displayName: email,
disabled: false,
})
.then( (userRecord) => {
// See the UserRecord reference doc for the contents of userRecord.
console.log('Successfully created new user:', userRecord.uid);
})
.catch((error) => {
console.log('Error creating new user:', error);
});
}
What should I try to get this resolved?
Thanks for any help
You can't use both the Admin SDK and the regular Firebase JavaScript SDK in a single application. If the app runs in a potentially untrusted environment, you should use the regular JavaScript SDK. If it runs in a trusted environment (such as your development machine, a server you control, or Cloud Functions) you can use either the JavaScript SDK or the Admin SDK for that environment (in your case for Node.js).

Error using instagram-node

This is my code run on a node.js server. I have the proper access token obtained from OAuth2.0 protocol as defined in the Instagram developer page.
function getMedia(accessToken) {
var instagram = require('instagram-node').instagram();
instagram.use({
access_token: accessToken
});
instagram.user_self_media_recent(function(err, medias, pagination, remaining, limit) {
if(err) {
console.log(err);
}
console.log(medias);
});
}
I'm getting this in my error response:
{ Error: getaddrinfo ENOTFOUND api.instagram.com api.instagram.com:443
at errnoException (dns.js:28:10)
at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:76:26)
code: 'ENOTFOUND',
errno: 'ENOTFOUND',
syscall: 'getaddrinfo',
hostname: 'api.instagram.com',
host: 'api.instagram.com',
port: 443,
retry: [Function: retry] }
Does anyone know what this error response means?
Quick follow up. I was using Google's Firebase for my backend. On the "Spark" plan you get this warning:
Billing account not configured. External network is not accessible and
quotas are severely limited. Configure billing account to remove these
restrictions
I upgraded to "Blaze" plan and now retrieve data from Instagram.
The answer posted below suggests that I need to initialize the Instagram client with a client_id and client_secret, this is not true. I am getting media posts with just the access_token.
Thanks
When you initialize the instagram client you should use your app's client Id and client secret.
instagram.use({
client_id: INSTA_CLIENT_ID,
client_secret: INSTA_CLIENT_SECRET,
});
Then use the access token you have to authenticate the specific instagram user and request medias on their behalf.
instagram.use({
access_token: accessToken
});
instagram.user_self_media_recent(function(err, medias, pagination, remaining, limit) {
if(err) {
console.log(err);
}
console.log(medias);
});
When you first initialize your instagram node client you must use the authentication credentials that you receive from instagram when you register your app here.

Nodemailer whit GMail SMTP OAuth2 autentication is getting me 'Invalid status code 401'

I'm trying to make a simple mail sender using Nodemailer 3, the GMail API whit OAuth2 autentication.
Here's my script:
var serverConfig = {
gmail: {
client_user : 'my#email.com',
client_id : '349...myClientId',
secret : 'mysecret..123jd123',
refresh_token : 'x/xxxxxxxxxxxxxx-reZuEMeSuJaSERmCVY',
access_token : 'xxxxxxxxxxxxxxxxx',
expires: '3599'
}
}
// 3LO authentication https://nodemailer.com/smtp/oauth2/#example-3
var transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
type: 'OAuth2',
user: serverConfig.gmail.client_user,
clientId: serverConfig.gmail.client_id,
clientSecret: serverConfig.gmail.secret,
refreshToken: serverConfig.gmail.refresh_token
},
});
module.exports = {
"send": function(_from,_to,_subject,_html,_text){
// setup email data with unicode symbols
var mailOptions = {
from: _from,
to: _to, // list of receivers
subject: _subject, // Subject line
html: _html, // html body
text: _text // plain text body
};
transporter.sendMail(mailOptions, function(error, info){
if (error) {
return console.log(error);
}
console.log('Message ' + info.messageId + ' sent: %s' + info.response);
})
}
}
When I force the access_token in the auth object, the email is sent without any problem. But, when I don't specify the access_token, only de refresh_token, I'm getting this error:
{ Error: Invalid status code 401
at ClientRequest.req.on.res (/myproject/node_modules/nodemailer/lib/fetch/index.js:193:23)
at emitOne (events.js:96:13)
at ClientRequest.emit (events.js:188:7)
at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:474:21)
at HTTPParser.parserOnHeadersComplete (_http_common.js:99:23)
at TLSSocket.socketOnData (_http_client.js:363:20)
at emitOne (events.js:96:13)
at TLSSocket.emit (events.js:188:7)
at readableAddChunk (_stream_readable.js:176:18)
at TLSSocket.Readable.push (_stream_readable.js:134:10)
type: 'FETCH',
sourceUrl: 'https://accounts.google.com/o/oauth2/token',
code: 'EAUTH',
command: 'AUTH XOAUTH2' }
Maybe it's too late, but just answering here incase someone comes across the same issue. My problem rectified when the refreshToken was reset. This article gives great instructions for the whole process
I was able to fix this by going to https://console.cloud.google.com/apis/credentials, selecting the correct OAuth 2.0 Client ID, and choosing "Reset Secret" at the top. This revoked my old secret and generated a new one, which I then used in the OAuth Playground to exchange for a refresh token. I put the new Client Secret and Refresh Token in the auth object for nodemailer and it started working again.

Resources