Trying to use JavaScript Interop using Blazor client side.
The widget doesn't render.
I was hoping to setup an employee portal in Blazor, but wanted to use the Okta widget of course. Initially I just couldn't get the widget to render and now more problems. Will have to back track a little, but has anyone a clue how to render a javascript UI component within Blazor?
Also, I replaced the Okta config info with my own Okta developer instance info - not shown below...
#inject IJSRuntime JSRuntime
<h3>Employee Login</h3>
<div id="okta-signin-widget"></div>
#code {
protected override void OnAfterRender(bool firstRender)
{
if (firstRender)
{
JSRuntime.InvokeAsync<object>("RenderLogin", "OnAfterRender was Triggered");
}
}
}
RenderLogin is a tag in a JavaScript file OktaLogin.js
Inside an OktaLogin.js file (everything in the file is client side):
signInWidgetConfig = {
// Enable or disable widget functionality with the following options. Some of these features require additional configuration in your Okta admin settings. Detailed information can be found here: https://github.com/okta/okta-signin-widget#okta-sign-in-widget
// Look and feel changes:
logo: '//logo.clearbit.com/okta.com', // Try changing "okta.com" to other domains, like: "workday.com", "splunk.com", or "delmonte.com"
language: 'en', // Try: [fr, de, es, ja, zh-CN] Full list: https://github.com/okta/okta-signin-widget#language-and-text
i18n: {
//Overrides default text when using English. Override other languages by adding additional sections.
'en': {
'primaryauth.title': 'Sign In', // Changes the sign in text
'primaryauth.submit': 'Sign In' // Changes the sign in button
// More e.g. [primaryauth.username.placeholder, primaryauth.password.placeholder, needhelp, etc.].
// Full list here: https://github.com/okta/okta-signin-widget/blob/master/packages/#okta/i18n/dist/properties/login.properties
}
},
// Changes to widget functionality
features: {
registration: true, // Enable self-service registration flow
rememberMe: true, // Setting to false will remove the checkbox to save username
//multiOptionalFactorEnroll: true, // Allow users to enroll in multiple optional factors before finishing the authentication flow.
//selfServiceUnlock: true, // Will enable unlock in addition to forgotten password
//smsRecovery: true, // Enable SMS-based account recovery
//callRecovery: true, // Enable voice call-based account recovery
router: true // Leave this set to true for the API demo
},
baseUrl: 'https://live-widget.oktapreview.com',
clientId: '0oaexo9c530ZUVuOj0h7',
redirectUri: 'https://developer.okta.com/live-widget',
authParams: {
issuer: 'https://live-widget.oktapreview.com/oauth2/ausexqn31sz3HMxdf0h7',
responseType: ['id_token', 'token'],
scopes: ['openid', 'email', 'profile']
}
};
signInWidget = new OktaSignIn(signInWidgetConfig);
function widgetSuccessCallback(res) {
var key = '';
if (res[0]) {
key = Object.keys(res[0])[0];
signInWidget.tokenManager.add(key, res[0]);
}
if (res[1]) {
key = Object.keys(res[1])[0];
signInWidget.tokenManager.add(key, res[1]);
}
if (res.status === 'SUCCESS') {
var token = signInWidget.tokenManager.get(key);
console.log("Logged in to Okta and issued token:");
console.log(token);
console.log("Reload this page to start over.");
alert("Logged in! Check your developer console for details");
}
}
function widgetErrorCallback(err) {
}
RenderLogin:** signInWidget.renderEl({ el: '#widget-container' }, widgetSuccessCallback, widgetErrorCallback);
Related
So, basically I'm trying to receive a call from provider to my app. For that purpose Quickblox gives us a listener to receive the upcoming calls onCallListener. So here is my code snippet that should work but doesn't.
const calleesIds = [4104]
const sessionType = QB.webrtc.CallType.VIDEO
const additionalOptions = {}
let callSession = QB.webrtc.createNewSession(calleesIds, sessionType, null, additionalOptions)
console.log(callSession, "SESSION")
const mediaParams = {
audio: true,
video: true,
options: {
muted: true,
mirror: true,
},
elemId: "myVideoStream"
}
QB.webrtc.onCallListener = function(session: any, extension: object) {
callSession = session
console.log('asdasd')
// if you are going to take a call
session.getUserMedia(mediaParams, function (error: object, stream: object) {
if (error) {
console.error(error)
} else {
session.accept(extension)
session.attachMediaStream("videoStream", stream)
}
})
}
P.S. I also integrated chat which works perfect!
Found the solution by myself! Whenever you create a user and dialog id, search that user in the quickblox dashboard by the dialogId and change its settings: you will see that userId and providerId is the same which is wrong. So put your userId in the userId field and save that. After that you video calling listeners will work fine!)
P. S. also in the backend replace provider token with user token.
I cannot get the Firebase "Sign in with Google" button to work using flask-talisman. Here is my CSP:
I am not sure if I a missing the right items for 'script-src'. One thing I do know is that if I remove this CSP from my application completely, everything works as normal. So I believe the Firebase issue has to do with what I am putting into the csp.
app = Flask(__name__)
csp = {
'default-src': [
'\'self\'',
'\'unsafe-inline\'',
'cdnjs.cloudflare.com',
'maxcdn.bootstrapcdn.com',
'ajax.googleapis.com',
'cdn.datatables.net',
'fonts.googleapis.com',
'gstatic.com',
'https://js.stripe.com',
],
'script-src': [
'\'self\'',
'unsafe-eval',
'\'unsafe-inline\'',
'cdn.firebase.com',
'*.firebaseio.com'
],
'object-src': [
'\'self\''
]
}
talisman = Talisman(app, content_security_policy=csp)
Here is my relevant code in HTML where I use Firebase. It was taken from Google's example.
<div id="firebaseui-auth-container"></div>
<button id="sign-out" hidden=true>Sign Out</button>
<div id="login-info" hidden=true>
<script src="{{ url_for('static', filename='script.js') }}"></script>
Then file "script.js" is below:
window.addEventListener('load', function () {
document.getElementById('sign-out').onclick = function () {
firebase.auth().signOut();
};
// FirebaseUI config.
var uiConfig = {
signInSuccessUrl: '/',
signInOptions: [
// Comment out any lines corresponding to providers you did not check in
// the Firebase console.
firebase.auth.GoogleAuthProvider.PROVIDER_ID
//firebase.auth.EmailAuthProvider.PROVIDER_ID,
//firebase.auth.FacebookAuthProvider.PROVIDER_ID,
//firebase.auth.TwitterAuthProvider.PROVIDER_ID,
//firebase.auth.GithubAuthProvider.PROVIDER_ID,
//firebase.auth.PhoneAuthProvider.PROVIDER_ID
],
// Terms of service url.
// tosUrl: '/terms-of-service',
privacyPolicyUrl: '/privacy-policy'
};
firebase.auth().onAuthStateChanged(function (user) {
if (user) {
// User is signed in, so display the "sign out" button and login info.
document.getElementById('sign-out').hidden = false;
document.getElementById('login-info').hidden = false;
console.log(`Signed in as ${user.displayName} (${user.email})`);
user.getIdToken().then(function (token) {
// Add the token to the browser's cookies. The server will then be
// able to verify the token against the API.
// SECURITY NOTE: As cookies can easily be modified, only put the
// token (which is verified server-side) in a cookie; do not add other
// user information.
document.cookie = "token=" + token;
});
} else {
// User is signed out.
// Initialize the FirebaseUI Widget using Firebase.
var ui = new firebaseui.auth.AuthUI(firebase.auth());
// Show the Firebase login button.
ui.start('#firebaseui-auth-container', uiConfig);
// Update the login state indicators.
document.getElementById('sign-out').hidden = true;
document.getElementById('login-info').hidden = true;
// Clear the token cookie.
document.cookie = "token=";
}
}, function (error) {
console.log(error);
alert('Unable to log in: ' + error)
});
});
Does anyone know what I am missing?
I'm using a very basic CASL implementation. Unfortunately, the docs aren't that detailed. I have the following code (basically copy-pasted from the docs).
import { abilitiesPlugin } from '#casl/vue'
import defineAbilitiesFor from './ability'
const ability = defineAbilitiesFor({name: 'guest'})
Vue.use(abilitiesPlugin, ability )
where defineAbilitiesFor is defined as (in ./ability.js)
import { AbilityBuilder } from '#casl/ability'
function defineAbilitiesFor(user) {
return AbilityBuilder.define((can, cannot) => {
can(['read'], 'foo', { username: user.name})
})
}
I know it's possible to update the rules/conditions (i.e. ability.update([])). But how do I update the user's information after initializing CASL? (e.g. after the user has logged in
CASL has nothing to do with user. What eventually it cares is only user's permissions. So, after login you need to update rules, basically use ability.update(myRules)
In your Login component, after login request to API (or after you receive information about currently logged in user), you need to call ability.update(defineRulesFor(user)).
ability can be just an empty Ability instance. For example:
const ability = new Ability([])
function defineRulesFor(user) {
const { can, rules } = AbilityBuilder.extract()
can(['read'], 'foo', { username: user.name })
return rules
}
// Later after login request to API (or after you receive information about currently logged in user)
login() {
return http.post('/login')
.then((response) => {
ability.update(defineRulesFor(response.user))
// after that Ability instance contains rules for returned user
})
}
I'm using Direct Line 3.0 and the Microsoft Bot Framework and require the webpage to send some form fields to the bot as if the user sent them. For example when the user presses Submit, the fields email, phone etc are sent to the bot as if the user sent them like this: email, phone, etc.
This is because the bot redirects the user depending on what the values are. The bot is in C# and is hosted on Azure. The logic for submitting the information should be in JavaScript.
Bot is initiated like this:
<div id="chat" style="background-color:white;
width:250px;height:600px;"><div id="bot" />
<script src="https://cdn.botframework.com/botframework-
webchat/latest/botchat.js"></script></div></div>
and through a DirectLine script:
<script>
const botConnection = new BotChat.DirectLine({
secret: 'secret',
});
BotChat.App({
user: { id: 'You' },
bot: { id: 'myId' },
resize: 'detect',
botConnection: botConnection
}, document.getElementById("bot"));
</script>
All I need is to send one string as if the user sent it. I cannot do this with HTML manipulation it seems.
Thanks for anyone pointing me in the right direction!
Sending a message to the bot "like the user would do" is possible using the "Backchannel" functionnality of the webchat.
There is a good sample of use in the Readme file on Github webchat's page: https://github.com/Microsoft/BotFramework-WebChat#the-backchannel.
You have to use your botConnection previously created to send an activity like the following:
botConnection.postActivity({
from: { id: 'me' },
name: 'buttonClicked',
type: 'event',
value: ''
});
Then catch this on your bot code, but checking the Activity type which will be Event in this case.
You can have a look on how they throw this postActivity from a button click in the sample provided: samples here: https://github.com/Microsoft/BotFramework-WebChat/blob/master/samples/backchannel/index.html
Or in this other sample that I made (available on Github, both client web page and bot code): the bot's controller looks like the following:
[BotAuthentication]
public class MessagesController : ApiController
{
/// <summary>
/// POST: api/Messages
/// Receive a message from a user and reply to it
/// </summary>
public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{
// Process each activity
if (activity.Type == ActivityTypes.Message)
{
await Conversation.SendAsync(activity, () => new Dialogs.RootDialog());
}
// Webchat: getting an "event" activity for our js code
else if (activity.Type == ActivityTypes.Event && activity.ChannelId == "webchat")
{
var receivedEvent = activity.AsEventActivity();
if ("localeSelectionEvent".Equals(receivedEvent.Name, StringComparison.InvariantCultureIgnoreCase))
{
await EchoLocaleAsync(activity, activity.Locale);
}
}
// Sample for Skype: locale is provided in ContactRelationUpdate event
else if (activity.Type == ActivityTypes.ContactRelationUpdate && activity.ChannelId == "skype")
{
await EchoLocaleAsync(activity, activity.Entities[0].Properties["locale"].ToString());
}
var response = Request.CreateResponse(HttpStatusCode.OK);
return response;
}
private async Task EchoLocaleAsync(Activity activity, string inputLocale)
{
Activity reply = activity.CreateReply($"User locale is {inputLocale}, you should use this language for further treatment");
var connector = new ConnectorClient(new Uri(activity.ServiceUrl));
await connector.Conversations.SendToConversationAsync(reply);
}
}
I'm using Meteor and alanning:roles for user roles in my project. I'm trying to check if logged user has an admin permission.
I've tried all the ways.
That check returns false.I've made what is in README of alanning:roles, like this:
//server/init.js
var users = [
{name:"Normal User",email:"normal#ehnormal.com.br",roles:[]},
{name:"Usuario Secreto",email:"mauriciord#me.com",roles:['view-secrets']},
{name:"Usuario Gerenciador",email:"mauricioreattoduarte#gmail.com",roles:['manage-users']},
{name:"Mauricio",email:"mauricio#thcm.com.br",roles:['admin']}
];
_.each(users, function (user) {
var id;
id = Accounts.createUser({
email: user.email,
password: "apple1",
profile: { name: user.name }
});
if (user.roles.length > 0) {
// Need _id of existing user record so this call must come
// after `Accounts.createUser` or `Accounts.onCreate`
// Roles.addUsersToRoles(id, user.roles, 'default-group');
Meteor.users.update({_id: id}, {$set:{'emails.0.verified': true}});
console.log("usuario criado");
Roles.addUsersToRoles(id, user.roles, 'default-group');
//Roles.addUsersToRoles(id, user.roles);
}
});
Like said in README, too:
//server/publish.js
Meteor.publish(null, function (){
return Meteor.roles.find({})
});
But when i try to check User's permission in routes.js: see here on my repository.
// lib/routes.js
var logado = FlowRouter.group({
name: 'logadoRoutes',
// se não estiver logado vai para /login
triggersEnter: [function(context, redirect) {
console.log('logado grupo');
if(!Meteor.userId()) {
FlowRouter.go('login');
} else {
return true;
}
}]
});
var admin = logado.group({
prefix: '/admin',
name: 'adminRoutes',
triggersEnter: [function(context, redirect) {
var loggedInUser = Meteor.userId();
console.log('verificando admin ...');
if (Roles.userIsInRole(loggedInUser, ['view-secrets', 'admin'], "default-group")) {
return true;
console.log('é admin - rotas');
}
console.log('não é admin - rotas');
throw new Meteor.Error(403, "Acesso Negado");
}]
});
Here is my repository: https://github.com/mauriciord/thomasicamargo
Packages: https://github.com/mauriciord/thomasicamargo/blob/master/.meteor/packages
meteor-base # Packages every Meteor app needs to have
mobile-experience # Packages for a great mobile UX
mongo # The database Meteor supports right now
blaze-html-templates # Compile .html files into Meteor Blaze views
session # Client-side reactive dictionary for your app
jquery # Helpful client-side library
tracker # Meteor's client-side reactive programming library
standard-minifiers # JS/CSS minifiers run for production mode
es5-shim # ECMAScript 5 compatibility for older browsers.
ecmascript # Enable ECMAScript2015+ syntax in app code
kadira:flow-router
kadira:blaze-layout
erasaur:meteor-lodash
stolinski:stylus-multi
fortawesome:fontawesome
spiderable
fastclick
raix:handlebar-helpers
aldeed:collection2
aldeed:autoform
accounts-ui
accounts-password
matb33:bootstrap-glyphicons
zimme:active-route
gwendall:auth-client-callbacks
meteortoys:allthings
datariot:ganalytics
check
twbs:bootstrap
less
arillo:flow-router-helpers
alanning:roles
UPDATE: I changed in layout with isInRole (it was ifInRole), and now it's working.
I was trying to verify the condition on routes.js just pressing 'Enter' on the URL of Navigation Bar. localhost:3000/admin, but when i go this route via anchor link, the condition work 100% haha. In condition i've made this:
if (Roles.subscription.ready() && Roles.userIsInRole(loggedInUser, ['admin'], 'default-group')) {
return true;
console.log('é admin - rotas');
}
I don't know why, i'm new on MeteorJS.