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
Related
I have a webservice which validates user/pwd and returns true/false (valid/invalid). I am trying to leverage Custom Authentication Workflow of AWS Cognito to integrate with the webservice.
I read through the docs and came across the define, create and verify lambda triggers and I tried those as follows:
Define trigger:
exports.handler = async (event) => {
if (!event.request.session || event.request.session.length === 0) {
event.response.challengeName = "CUSTOM_CHALLENGE";
event.response.failAuthentication = false;
event.response.issueTokens = false;
} else if (event.request.session.length === 1) {
// If we passed the CUSTOM_CHALLENGE then issue token
event.response.failAuthentication = false;
event.response.issueTokens = true;
} else {
// Something is wrong. Fail authentication
event.response.failAuthentication = true;
event.response.issueTokens = false;
}
return event;
};;
Create Trigger:
exports.handler = async (event) => {
if (event.request.challengeName == 'CUSTOM_CHALLENGE') {
event.response.publicChallengeParameters = {};
event.response.privateChallengeParameters = {};
}
return event;
}
Verify Trigger:
exports.handler = async (event, context) => {
//call webservice using "event.userName" and "event.request.challengeAnswer" (password)
var result = <bool-result-received-from-webservice>
event.response.answerCorrect = result;
return event;
};
The JS client looks like this:
Amplify.configure({
Auth: {
region: 'dd',
userPoolId: 'eeee',
userPoolWebClientId: 'ffff',
authenticationFlowType: 'CUSTOM_AUTH'
}
})
let user = await Auth.signIn(username)
.then(u => {
console.log(u); //(1) TOKENS ARE ALREADY CREATED HERE WITHOUT VERIFYING PASSWORD. NOT SURE.
if (u.challengeName === 'CUSTOM_CHALLENGE') {
console.log("responding to challenge..");
// to send the answer of the custom challenge
Auth.sendCustomChallengeAnswer(u, password)
.then(u2 => {
console.log("after responding to challenge...");
console.log(u2); //(2) NEW TOKENS ARE CREATED HERE. NOT SURE.
return u2;
})
.catch(err => {
console.log("ERROR with Challenge:");
console.log(err);
});
} else {
console.log("no challenge needed..");
return u;
}
})
.catch(err => {
console.log("ERROR with sign-in:..");
console.log(err);
});
I mentioned 1 and 2 in the comments above. Not sure if it's behaving correctly.
If the username is not in the "users" list of "user pool", it throws it as invalid login. Is it possible to validate username/password only through webservice having no "users" in the "user pool"?
we are using peer js webrtc for video call. Everything is working fine just the problem is i am not able to switch camera during call. I have done some work where i can switch camera in local during call but its doesnt effect on remote area.
here is my code
$('select').on('change', function (e) {
navigator.mediaDevices.enumerateDevices().then(function (devices) {
var valueSelected = $("#myselect option:selected").val();
alert(valueSelected);
//var myselect = 0;
if (valueSelected == "0") {
var cameras = [];
devices.forEach(function (device) {
'videoinput' === device.kind && cameras.push(device.deviceId);
});
var constraints = { video: { deviceId: { exact: cameras[0] } } };
navigator.mediaDevices.getUserMedia(constraints).then(function (stream) {
window.localStream = stream;
myapp.setMyVideo(window.localStream)
//if (callback)
// callback();
}, function (err) {
console.log("The following error occurred: " + err.name);
alert('Unable to call ' + err.name)
});
}
else {
var cameras = [];
devices.forEach(function (device) {
'videoinput' === device.kind && cameras.push(device.deviceId);
});
var constraints = { video: { deviceId: { exact: cameras[1] } } };
navigator.mediaDevices.getUserMedia(constraints).then(function (stream) {
window.localStream = stream;
myapp.setMyVideo(window.localStream)
//if (callback)
// callback();
}, function (err) {
console.log("The following error occurred: " + err.name);
alert('Unable to call ' + err.name)
});
}
//var myselect = $("#myselect option:selected").val();
});
});
The recommended way to change stream when a peer-to-peer connection is established is to use replaceTrack function that does not require ICE renegotiation:
RTCRtpSender.replaceTrack
The documentation says:
Among the use cases for replaceTrack() is the common need to switch between the rear- and front-facing cameras on a phone. With replaceTrack(), you can simply have a track object for each camera and switch between the two as needed. See the example...
I am using Mobilefirst Platform 8.0 for my app development.
How can we use HTTP basic authentication method to authenticate the mobile client through datapower. Please help me out with challnegHandler sample code.
I tried the below code in challengeHandler but Datapower always returning 401.
var DataPowerChallengeHandler = function() {
var dataPowerChallengeHandler = WL.Client.createGatewayChallengeHandler("LtpaBasedSSO");
dataPowerChallengeHandler.canHandleResponse = function(response) {
if (!response || response.responseText === null) {
return false;
}
if (response.status=="401") {{
return true;
}
return false;
};
dataPowerChallengeHandler.handleChallenge = function(response) {
document.getElementById('result').style.display = 'none';
document.getElementById('auth').style.display = 'block';
};
dataPowerChallengeHandler.submitLoginFormCallback = function(response) {
var isLoginFormResponse = dataPowerChallengeHandler.canHandleResponse(response);
if (isLoginFormResponse) {
dataPowerChallengeHandler.handleChallenge(response);
} else {
document.getElementById('result').style.display = 'block';
document.getElementById('auth').style.display = 'none';
dataPowerChallengeHandler.submitSuccess();
}
};
document.getElementById("AuthSubmitButton").addEventListener("click", function() {
var username = document.getElementById('txtusername').value;
var password = document.getElementById('txtpassword').value;
var mystring = convertBase64(username+":"+password);
var headerString = "Basic "+ mystring;
WL.Client.addGlobalHeader("Authorization",headerString);
dataPowerChallengeHandler.submitSuccess();
});
document.getElementById("logout").addEventListener("click", function() {
WLAuthorizationManager.logout("LtpaBasedSSO").then(
function() {
WL.Logger.debug("logout onSuccess");
alert("Success logout");
},
function(response) {
WL.Logger.debug("logout onFailure: " + JSON.stringify(response));
});
});
document.getElementById('AuthCancelButton').addEventListener("click",function(){
document.getElementById('result').style.display = 'block';
document.getElementById('auth').style.display = 'none';
dataPowerChallengeHandler.cancel();
});
return dataPowerChallengeHandler;
};
Your gateway challenge handler code is improper and causing all these issues.
canHandleResponse method is used to determine whether it is a challenge thrown by datapower or not. Your client code is returning true whenever there is a 401 challenge. This will return true even though for non-datapower challenges which should be corrected.
and handleChallenge is explicitly getting called in submitLoginFormCallback method which is wrong. handleChallenge will get called by SDK only when canHandleResponse method returns true.
Kindly go through this tutorial for more information on how to use gateway challenge handler in your client application.
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);
I've created an application using google drive API to list and manage all my drive files.
Everything goes fine, except the log out part. I've searched for two days for a solution without a result.
The following is code related to login and works fine:
function checkAuth() {
gapi.auth.authorize(
{
'client_id': CLIENT_ID,
'scope': SCOPES.join(' '),
'immediate': true,
'authuser': '-1'
}, handleAuthResult);
}
function handleAuthResult(authResult) {
var authorizeDiv = document.getElementById('authorize-div');
if (authResult && !authResult.error) {
// Hide auth UI, then load client library.
authorizeDiv.style.display = 'none';
loadDriveApi();
} else {
authorizeDiv.style.display = 'inline';
}
}
function handleAuthClick(event) {
gapi.auth.authorize(
{client_id: CLIENT_ID, scope: SCOPES, immediate: false},
handleAuthResult);
return false;
}
function loadDriveApi() {
gapi.client.load('drive', 'v2', listFiles);
}
I'm able to login and work with files, but when I try to logout with following I get No 'Access-Control-Allow-Origin' error
$(document).on('click', '.logout', function(){
var token = gapi.auth.getToken();
if (token) {
var accessToken = gapi.auth.getToken().access_token;
if (accessToken) {
var revokeToken = 'https://accounts.google.com/o/oauth2/revoke?token=' + accessToken;
jQuery.getJSON(revokeToken).success(function(data) {
console.log(data);
}).error(function(message) {
console.error('error' + message);
}).complete(function() {
console.log('completed!');
});
}
}
gapi.auth.setToken(null);
gapi.auth.signOut();
});
In Google Developers Console I've regitred my website to Authorized JavaScript origins.
Thanks