Twitter OAuth Ionic 2 - authentication

Its possible generate a Twitter token and secret token in Nodejs and after use it to open the browser for authenticate with "https://api.twitter.com/oauth/authenticate"?
I use this way to get the token:
app.get('/auth/twitter/token', function (req, res) {
var requestTokenUrl = 'https://api.twitter.com/oauth/request_token';
var requestTokenOauth = {
consumer_key: "2z8MTR8KAZuFafPHsEQ0ZBgo1",
consumer_secret: "ksPiaQz7ihCrOh3m4iRCsXZzQuSkkmcv4CLGiJQwREWeaQl7St"
};
request.post({
url: requestTokenUrl,
oauth: requestTokenOauth
}, function (err, response, body) {
var oauthToken = qs.parse(body);
res.send(oauthToken);
});
});
When I get this token in the client "https://api.twitter.com/oauth/authenticate?oauth_token=TOKEN" I got this problem: "This page is no longer valid. It's looks like someone already used the token information your provider, blabla.."
The problem is due to the way that I get the Token?
I'm using ng2-cordova-auth but this lib dont have twitter auth, I'm just trying to implement
This is my implementation:
"use strict";
var utility_1 = require("../utility");
var PROVIDER_NAME = "Twitter";
var Twitter = (function () {
function Twitter(options) {
this.twitterOptions = options;
this.flowUrl = ""
}
Twitter.prototype.login = function (token, tokenSecret) {
var _this = this;
return new Promise(function (resolve, reject) {
_ this.flowUrl = "https://api.twitter.com/oauth/authenticate?oauth_token="+token;
var browserRef = window.cordova.InAppBrowser.open(_this.flowUrl);
browserRef.addEventListener("loadstart", function (event) {
if ((event.url).indexOf(_this.twitterOptions.redirectUri) === 0) {
browserRef.removeEventListener("exit", function (event) { });
browserRef.close();
var parsedResponse = event.url.split("?")[1].split("&");
if (parsedResponse) {
resolve(parsedResponse);
}
else {
reject("Problem authenticating with " + PROVIDER_NAME);
}
}
});
browserRef.addEventListener("exit", function (event) {
reject("The " + PROVIDER_NAME + " sign in flow was canceled");
});
});
};
return Twitter;
}());
exports.Twitter = Twitter;
In my component/controller I make this:
//With twitterToken I get the token from NodeJs
this.API.twitterToken().subscribe(
data => {
this.twitterOAuth.login(data.oauth_token, data.oauth_token_secret).then((success) => {
alert(JSON.stringify(success))
}, (error) => {
alert(JSON.stringify(error));
});
},
err => alert(JSON.stringify(err))
);

Have you tried the Twitter Connect plugin? Does this help?
Plugin to use Twitter Single Sign On Uses Twitter's Fabric SDK
An example of use is
import {TwitterConnect} from 'ionic-native';
function onSuccess(response) {
console.log(response);
// Will console log something like:
// {
// userName: 'myuser',
// userId: '12358102',
// secret: 'tokenSecret'
// token: 'accessTokenHere'
// }
}
TwitterConnect.login().then(onSuccess, onError);

Related

Migrate ADAL.js to MSAL.js

I have a SPA which uses the solution provided here to authenticate with Azure AD and everything works as expected. Now I want to migrate this to use MSAL.js.
I use below for login:
import * as MSAL from 'msal'
...
const config = {
auth: {
tenantId: '<mytenant>.com',
clientId: '<myclientid>',
redirectUri: <redirecturi>,
},
cache: {
cacheLocation: 'localStorage',
}
};
const tokenRequest = {
scopes: ["User.Read"]
};
export default {
userAgentApplication: null,
/**
* #return {Promise}
*/
initialize() {
let redirectUri = config.auth.redirectUri;
// create UserAgentApplication instance
this.userAgentApplication = new MSAL.UserAgentApplication(
config.auth.clientId,
'',
() => {
// callback for login redirect
},
{
redirectUri
}
);
// return promise
return new Promise((resolve, reject) => {
if (this.userAgentApplication.isCallback(window.location.hash) || window.self !== window.top) {
// redirect to the location specified in the url params.
}
else {
// try pull the user out of local storage
let user = this.userAgentApplication.getUser();
if (user) {
resolve();
}
else {
// no user at all - go sign in.
this.signIn();
}
}
});
},
signIn() {
this.userAgentApplication.loginRedirect(tokenRequest.scopes);
},
And then I use below to get the token:
getCachedToken() {
var token = this.userAgentApplication.acquireTokenSilent(tokenRequest.scopes);
return token;
}
isAuthenticated() {
// getCachedToken will only return a valid, non-expired token.
var user = this.userAgentApplication.getUser();
if (user) {
// get token
this.getCachedToken()
.then(token => {
axios.defaults.headers.common["Authorization"] = "Bearer " + token;
// get current user email
axios
.get('<azureapi-endpoint>' + '/GetCurrentUserEmail')
.then(response => { })
.catch(err => { })
.finally(() => {
});
})
.catch(err => { })
.finally(() => { });
return true;
}
else {
return false;
}
},
}
but after login I get below error:
Access to XMLHttpRequest at 'https://login.windows.net/common/oauth2/authorize?response_type=code+id_token&redirect_uri=<encoded-stuff>' (redirected from '<my-azure-api-endpoint>') from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Also the token that I get seems to be invalid as I get 401 errors trying to call api using the token. Upon checking the token against https://jwt.io/ I get an invalid signature.
I really appreciate anyone's input as I've already spent good few days and haven't got anywhere yet.
I'm not sure if this is your issue. however, for msal.js, in the config, there is no tenantId parameter, it's supposed to be authority. Here is a sample for graph api using msal.js
https://github.com/Azure-Samples/active-directory-javascript-graphapi-v2
specifically: the config is here: https://github.com/Azure-Samples/active-directory-javascript-graphapi-v2/blob/quickstart/JavaScriptSPA/authConfig.js
as per here, https://learn.microsoft.com/en-us/azure/active-directory/develop/msal-js-initializing-client-applications it is supposed to be hitting login.microsoftonline.com not login.windows.net

IBM IAM IamAuthenticator getToken is not a function

I'm trying to get a token to use IBM Watson Speech-to-Text in my app. Here's my code:
const { IamAuthenticator } = require('ibm-cloud-sdk-core');
const authenticator = new IamAuthenticator({
apikey: 'myApiKey',
});
authenticator.getToken(function (err, token) {
if (!token) {
console.log('error: ', err);
} else {
// use token
}
});
The error message is authenticator.getToken is not a function.
The documentation says:
string IBM.Cloud.SDK.Core.Authentication.Iam.IamAuthenticator.GetToken ( )
I've tried both getToken and GetToken. Same error message. The code isn't complicated, what am I doing wrong?
This is what worked for me with the latest ibm-watson node-sdk,
Install node-sdk with this command
npm install --save ibm-watson
Then, use this code snippet in your app.js or server.js node file to receive the IAM access token
const watson = require('ibm-watson/sdk');
const { IamAuthenticator } = require('ibm-watson/auth');
// to get an IAM Access Token
const authorization = new watson.AuthorizationV1({
authenticator: new IamAuthenticator({ apikey: '<apikey>' }),
url: ''
});
authorization.getToken(function (err, token) {
if (!token) {
console.log('error: ', err);
} else {
console.log('token: ', token);
}
});
You can also directly use the IamAuthenticator with Speech to Text
const fs = require('fs');
const SpeechToTextV1 = require('ibm-watson/speech-to-text/v1');
const { IamAuthenticator } = require('ibm-watson/auth');
const speechToText = new SpeechToTextV1({
authenticator: new IamAuthenticator({ apikey: '<apikey>' }),
url: 'https://stream.watsonplatform.net/speech-to-text/api/'
});
const params = {
// From file
audio: fs.createReadStream('./resources/speech.wav'),
contentType: 'audio/l16; rate=44100'
};
speechToText.recognize(params)
.then(response => {
console.log(JSON.stringify(response.result, null, 2));
})
.catch(err => {
console.log(err);
});
// or streaming
fs.createReadStream('./resources/speech.wav')
.pipe(speechToText.recognizeUsingWebSocket({ contentType: 'audio/l16; rate=44100' }))
.pipe(fs.createWriteStream('./transcription.txt'));
See my answer in your other post that might help. You use BearerTokenAuthenticator if you want to manage the token authentication process yourself.

OpenId issue for authentication

I have an embarassing issue with cognito.
My authentication strategy works with current usage but when I try to run tests that sign up a new user and then log it in for an access to other APIs in my website
const authenticationData = {
Username: req.body.email,
Password: req.body.password,
};
const authenticationDetails = new AmazonCognitoIdentity.AuthenticationDetails(authenticationData);
const poolData = {
UserPoolId: config.development.UserPoolId,
ClientId: config.development.ClientId,
TokenScopesArray : config.development.TokenScopesArray
};
const userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);
const userData = {
Username: req.body.email,
Pool: userPool,
TokenScopesArray : config.development.TokenScopesArray
};
const cognitoUser = new AmazonCognitoIdentity.CognitoUser(userData);
cognitoUser.authenticateUser(authenticationDetails, {
onSuccess: function (result) {
console.log('success')
token = result.getAccessToken().jwtToken;
const idToken = result.idToken.jwtToken;
console.log(token)
res.cookie("accessToken",token)
res.status(200).send(token);
},
onFailure: function (err) {
console.log(err)
res.status(404).send(err)
},`
Then when I try to authenticate with the following code :
app.use(function (req, res, next) {
var token = req.body.token || req.query.token || req.cookies.accessToken || req.headers['x-access-token'];
try {
if (token) {
let promise = new Promise((resolve, reject) => {
const data = null;
const xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
console.log('response', this.responseText);
}
})
xhr.open("GET", "https://gridmanager.auth.us-east-1.amazoncognito.com/oauth2/userInfo");
xhr.setRequestHeader("Authorization", "Bearer " + token);
xhr.setRequestHeader("cache-control", "no-cache");
xhr.setRequestHeader("TokenScopesArray", config.development.TokenScopesArray)
xhr.send(data);
resolve(xhr.responseText)
})
.then(function (response) {
if (response != null) {
res.decoded = response
next();
}
else {
return res.status(404).send('User not authenticated')
}
})
}
else {
console.log('No token')
return res.status(403).send('No token')
}
} catch (error) {
// if there is no token
// return an error
console.log('error')
return res.status(403).send({
success: false,
message: error.message
});
}
I get the following error in xhr.responseText :
{"error":"invalid_token","error_description":"Access token does not contain openid scope"}
And when I log the accessToken I get in the login function, it only has 'aws.cognito.signin.user.admin'
I already tried to change the settings in my appclient but nothing works
Thanks for your help
Unfortunately, only access tokens issued by the Cognito hosted UI can include scopes other than aws.cognito.signin.user.admin. Cognito hosted UI supports OpenId Connect and Cognito API doesn't. It's a big gap in terms of functionality provided by those two. The /oauth2/userInfo endpoint is part of the Hosted UI and it also follows the OpenID Connect spec.
Why do you want to call the /oauth2/userInfo endpoint when you have access to the id_token? The id_token payload has all the information about the user that /oauth2/userInfo would return.

stateless session api request

I am building a simple app that uses JWT for authentication. But I keeps on getting the error saying the route I GET to require a call back function.
What do I expect?
I should be getting the current user's data back.
What do I actually get?
Error: Route.get() requires a callback function but got a [object Object]
Route:
const authenticate = require("../middlewares/authenticate");
const usersController = require("../controllers").users;
app.get("/users/me", authenticate, usersController.getMe);
Model:
"use strict";
const jwt = require("jsonwebtoken");
module.exports = (sequelize, DataTypes) => {
var User = sequelize.define(
"User",
{
email: DataTypes.STRING,
password: DataTypes.STRING
},
{
classMethods: {
associate: function(models) {
// associations can be defined here
},
findByToken: function(token) {
const User = this;
let decoded;
try {
decoded = jwt.verify(token, "leogoesger");
} catch (e) {
console.log(e);
}
return User.find({ where: { email: decoded.email } });
}
}
}
);
return User;
};
Middleware:
const { User } = require("../models/user");
const authenticate = (req, res, next) => {
console.log("called here");
const token = req.header("x-auth");
User.findByToken(token)
.then(user => {
if (!user) {
}
req.user = user;
req.token = token;
next();
})
.catch(e => {
res.status(401).send(e);
});
};
module.exports = { authenticate };
Controller:
module.exports = {
getMe(req, res) {
res.status(200).send({ message: "hello" });
}
};
Your authenticate module exports an object, yet you do this:
const authenticate = require("../middlewares/authenticate");
which means your const authenticate is an object, not your function. Change that to this:
const authenticate = require("../middlewares/authenticate").authenticate;
Or, change the module to export the function directly instead of exporting an object with the function in it.

Anonymous meeting join - Skype UCWA for online

I am trying to join a meeting anonymously through a meeting URI and this does not seem to work. I went to the SKYPE UCWA site and went to the interactive SDK - and tried to join a meeting anonymously from there but the page does not do anything.
https://ucwa.skype.com/websdk
Below is the code that I am trying to join a meeting anonymously, but the call to client.signInManager.signIn never completes and neither any exception is thrown.
Looking for suggestions to resolve this issue. Also, if someone has working code of joining a meeting anonymously using SKYPE web sdk (UCWA), please share the same. Thanks.
function InitialiseSkype() {
Skype.initialize({ apiKey: config.apiKey }, function (api) {
window.skypeWebAppCtor = api.application;
window.skypeWebApp = new api.application();
client = new window.skypeWebAppCtor;
//once intialised, sign in
alert("Skype SDK Initialized");
JoinAnonymous();
}, function (err) {
console.log(err);
alert('Cannot load the SDK.');
});
}
function JoinAnonymous(){
client.signInManager.signIn({
version: config.Version,
name: $('#name').val(),
meeting: $('#meetingUri').val()
}).then(function () {
alert('Signed In, Anonymously');
var conversation = application.conversationsManager.getConversationByUri(uri);
}, function (error) {
alert(error);
});
}
Actually I did sign in anonymously using that code :
//Init
var config = {apiKey: 'a42fcebd-5b43-4b89-a065-74450fb91255', // SDK
apiKeyCC: '9c967f6b-a846-4df2-b43d-5167e47d81e1' // SDK+UI
};
Skype.initialize({ apiKey: config.apiKey }, function (api) {
window.skypeWebApp = new api.application;
}, function (err) {
console.log("cannot load the sdk package", err);
});
//Actual code
var uri ="sip:xxxxxxxx;gruu;opaque=app:conf:focus:id:xxxxxxxx";
window.skypeWebApp.signInManager.signIn({
name: "pseudo",
meeting:uri
}).then(function () {
alert('Signed In, Anonymously');
}, function (error) {
alert(error);
});
I did connect with the uri given in the ucwa.skype interactive web sdk page.
But I did not manage to join the conversation after that, probably because the interactive sample does not really create the room.
I can join a meeting from a office365 account while logged in with a sample account. However I can not join anonymously my meeting room.
Do you try with an on-premise account or with a office365 account ?
Looks like Anonymous join for a meeting is not yet available for Skype For Business online.
New update of WebSDK now support anonymous meeting join for SfB Online
(function () {
'use strict';
// this will be populated when the auth token is fetched
// it is later needed to sign into Skype for Business
var authDetails = {};
// A reference to the Skype SDK application object
// set during initialization
var app;
displayStep(0);
registerUIListeners();
// Initializing the Skype application
Skype.initialize({
apiKey: '9c967f6b-a846-4df2-b43d-5167e47d81e1'
}, function (api) {
console.log('Skype SDK initialization successful');
app = api.UIApplicationInstance;
// Once it is initialized, display a UI prompt for a meeting URL
displayStep(1);
}, function (err) {
console.error('Skype SDK initialization error:', err);
});
// After the user submits the meeting URL the next step is to
// fetch an auth token
function getToken(evt) {
var input = evt.target.querySelector('input'),
meetingUrl = input.value,
request = new XMLHttpRequest(),
data;
evt.preventDefault();
console.log('Fetching auth token from meeting url:', meetingUrl);
function guid() {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
s4() + '-' + s4() + s4() + s4();
}
var sessionId = guid();
data = 'ApplicationSessionId=' + sessionId +
'&AllowedOrigins=' + encodeURIComponent(window.location.href) +
'&MeetingUrl=' + encodeURIComponent(meetingUrl);
request.onreadystatechange = function () {
if (request.readyState === XMLHttpRequest.DONE) {
if (request.status === 200) {
var response = JSON.parse(request.response);
authDetails.discoverUrl = response.DiscoverUri;
authDetails.authToken = "Bearer " + response.Token;
console.log('Successfully fetched the anonymous auth token and discoverUrl', authDetails);
displayStep(2);
}
else {
console.error('An error occured, fetching the anonymous auth token', request.responseText);
}
}
};
request.open('post', 'http://webrtctest.cloudapp.net/getAnonTokenJob');
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
request.send(data);
}
// This uses the auth token and discovery URL to sign into Skype
// and join the meeting
function joinAVMeeting(evt) {
var input = evt.target.querySelector('input'),
name = input.value;
evt.preventDefault();
console.log('Joinig meeting as:', name);
app.signInManager.signIn({
name: name,
cors: true,
root: { user: authDetails.discoverUrl },
auth: function (req, send) {
// Send token with all requests except for the GET /discover
if (req.url != authDetails.discoverUrl)
req.headers['Authorization'] = authDetails.authToken;
return send(req);
}
}).then(function () {
// When joining a conference anonymously, the SDK automatically creates
// a conversation object to represent the conference being joined
var conversation = app.conversationsManager.conversations(0);
console.log('Successfully signed in with anonymous online meeting token');
registerAppListeners(conversation);
// This turns on local video and joins the meeting
startVideoService(conversation);
}).catch(function (error) {
console.error('Unable to join conference anonymously:', error);
});
function registerAppListeners(conversation) {
conversation.selfParticipant.video.state.when('Connected', function () {
console.log('Showing self video');
document.querySelector('.self').style.display = 'inline-block';
setupContainer(conversation.selfParticipant.video.channels(0), document.querySelector('.self .video'));
displayName(document.querySelector('.self'), conversation.selfParticipant);
console.log('The video mode of the application is:', conversation.videoService.videoMode());
if (conversation.videoService.videoMode() === 'MultiView') {
// Loading the sample in any other browser than Google Chrome means that
// the videoMode is set to 'MultiView'
// Please refer to https://msdn.microsoft.com/en-us/skype/websdk/docs/ptvideogroup
// on an example on how to implement group video.
}
// When in active speaker mode only one remote channel is available.
// To display videos of multiple remote parties the video in this one channel
// is switched out automatically, depending on who is currently speaking
if (conversation.videoService.videoMode() === 'ActiveSpeaker') {
var activeSpeaker = conversation.videoService.activeSpeaker;
setupContainer(activeSpeaker.channel, document.querySelector('.remote .video'));
activeSpeaker.channel.isVideoOn.when(true, function () {
document.querySelector('.remote').style.display = 'inline-block';
activeSpeaker.channel.isStarted(true);
console.log('ActiveSpeaker video is available and has been turned on.');
});
activeSpeaker.channel.isVideoOn.when(false, function () {
document.querySelector('.remote').style.display = 'none';
activeSpeaker.channel.isStarted(false);
console.log('ActiveSpeaker video is not available anymore and has been turned off.');
});
// the .participant object changes when the active speaker changes
activeSpeaker.participant.changed(function (newValue, reason, oldValue) {
console.log('The ActiveSpeaker has changed. Old ActiveSpeaker:', oldValue && oldValue.displayName(), 'New ActiveSpeaker:', newValue && newValue.displayName());
if (newValue) {
displayName(document.querySelector('.remote'), newValue);
}
});
}
});
conversation.state.changed(function (newValue, reason, oldValue) {
if (newValue === 'Disconnected' && (oldValue === 'Connected' || oldValue === 'Connecting')) {
console.log('The conversation has ended.');
reset();
}
});
}
function setupContainer(videoChannel, videoDiv) {
videoChannel.stream.source.sink.format('Stretch');
videoChannel.stream.source.sink.container(videoDiv);
}
function displayName(container, person) {
container.querySelector('.displayName .detail').innerHTML = person.displayName();
}
function startVideoService(conversation) {
conversation.videoService.start().then(null, function (error) {
console.error('An error occured joining the conversation:', error);
});
displayStep(3);
}
}
function endConversation(evt) {
var conversation = app.conversationsManager.conversations(0);
evt.preventDefault();
conversation.leave().then(function () {
console.log('The conversation has ended.');
reset();
}, function (error) {
console.error('An error occured ending the conversation:', error);
}).then(function () {
reset();
});
}
//-----------------------------------------------------------------------
//UI helper functions
function displayStep(step) {
var nodes = document.querySelectorAll('.step');
for (var i = 0; i < nodes.length; ++i) {
var node = nodes[i];
node.style.display = 'none';
if (i === step) {
node.style.display = 'block';
}
}
}
function registerUIListeners() {
document.querySelector('.step1').onsubmit = getToken;
document.querySelector('.step2').onsubmit = joinAVMeeting;
document.querySelector('.step3').onsubmit = endConversation;
}
function reset() {
window.location = window.location.href;
}
})();
https://github.com/OfficeDev/skype-docs/blob/master/Skype/WebSDK/samples/Meetings/Anonymous%20Online/standalone/index.js