Auth0 lock - failed to load resource - javascript

I'm trying to integrate Auth0 into React like it is shown here.
This is how my Auth class looks like:
class Auth {
constructor() {
if (typeof window === 'undefined') return;
this.lock0 = new Auth0Lock(clientID, domain, {
container: 'login-container',
theme: {
primaryColor: '#FFC107',
},
languageDictionary: {
emailInputPlaceholder: 'your_email#here.com',
title: 'Authorize',
},
auth: {
audience,
redirectUrl: redirectUri,
responseType,
params: { scope },
},
});
this.auth0 = new auth0.WebAuth({
domain,
clientID,
redirectUri,
audience,
responseType,
scope,
});
this.show = this.show.bind(this);
this.login = this.login.bind(this);
this.logout = this.logout.bind(this);
this.handleAuthentication = this.handleAuthentication.bind(this);
this.isAuthenticated = this.isAuthenticated.bind(this);
console.log('Auth class initialized');
}
show() {
this.lock0.show();
}
login() {
this.auth0.authorize();
}
logout(history) {
// Clear Access Token and ID Token from local storage
localStorage.removeItem('access_token');
localStorage.removeItem('id_token');
localStorage.removeItem('expires_at');
// navigate to the home route
history.replace(HOME_ROUTE);
}
handleAuthentication(history) {
this.auth0.parseHash((err, authResult) => {
console.log('#handleAuthentication', { err, authResult });
if (authResult && authResult.accessToken && authResult.idToken) {
this.setSession(authResult, history);
history.replace(HOME_ROUTE);
} else if (err) {
history.replace(HOME_ROUTE);
console.error(err);
}
});
}
setSession(authResult, history) {
// Set the time that the Access Token will expire at
const expiresAt = JSON.stringify((authResult.expiresIn * 1000) + new Date().getTime());
localStorage.setItem('access_token', authResult.accessToken);
localStorage.setItem('id_token', authResult.idToken);
localStorage.setItem('expires_at', expiresAt);
// navigate to the home route
history.replace(HOME_ROUTE);
}
isAuthenticated() {
// Check whether the current time is past the
// Access Token's expiry time
const expiresAt = JSON.parse(localStorage.getItem('expires_at'));
return new Date().getTime() < expiresAt;
}
}
const auth = new Auth();
export default auth;
What I'm getting in the console is like 20 errors looking like this:
Failed to load resource: the server responded with a status of 400 ()
As soon as I comment out the this.lock0 = Auth0Lock... part - they are gone.
What am I doing wrong?

Related

NextAuth credentials login creates session collection in the db but not returning to the client side

i am using using mongobd adapter for nextauth, i want to persist session in the db if the user chose to login with credentials the adapter create the session in the db but the entire session async function block seems to be skipped there by not returning session to the client dont know ho to wrap around it.
"https://branche.online/next-auth-credentials-provider-with-the-database-session-strategy/" i got the inspiration from here.
import NextAuth from "next-auth"
import { MongoDBAdapter } from "#next-auth/mongodb-adapter"
import clientPromise from "../auth/lib/mongodb"
import { MongoClient } from 'mongodb';
import bcrypt from 'bcrypt'
import GoogleProvider from "next-auth/providers/google";
import FacebookProvider from "next-auth/providers/facebook";
import CredentialsProvider from "next-auth/providers/credentials";
// Modules needed to support key generation, token encryption, and HTTP cookie manipulation
import { randomUUID } from 'crypto'
// import Cookies from 'cookies'
import { setCookie, getCookie } from 'cookies-next';
import { encode, decode } from 'next-auth/jwt'
const MONGODB_URI = process.env.MONGODB_URI
// next auth starts here
export default async function handler(req, res) {
const adapter = MongoDBAdapter(clientPromise)
let userAccount = null
// Do whatever you want here, before the request is passed down to `NextAuth`
const generate = {}
generate.uuid = function () {
return uuidv4()
}
generate.uuidv4 = function () {
return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
)
}
// Helper functions to generate unique keys and calculate the expiry dates for session cookies
const generateSessionToken = () => {
// Use `randomUUID` if available. (Node 15.6++)
return randomUUID?.() ?? generate.uuid()
}
const fromDate = (time, date = Date.now()) => {
return new Date(date + time * 1000)
}
// callbacks for the sessions
const callbacks = {
async redirect({ url, baseUrl }) {
// Allows relative callback URLs
if (url.startsWith("/")) return `${baseUrl}${url}`
// Allows callback URLs on the same origin
else if (new URL(url).origin === baseUrl) return url
return baseUrl
},
async signIn({ user, account, profile, email, credentials }) {
console.log("User Signin Start: ", user)
// Check if this sign in callback is being called in the credentials authentication flow. If so, use the next-auth adapter to create a session entry in the database (SignIn is called after authorize so we can safely assume the user is valid and already authenticated).
if (req.query.nextauth.includes('callback') && req.query.nextauth.includes('credentials') && req.method === 'POST') {
if (user) {
const sessionToken = generateSessionToken()
const sessionMaxAge = 60 * 60 * 24 * 7; //7Days
const sessionExpiry = fromDate(sessionMaxAge)
console.log("Session token is: ", sessionToken)
console.log("sessionExpiry: ", sessionExpiry);
await adapter.createSession({
sessionToken: sessionToken,
userId: user.username,
expires: sessionExpiry
})
setCookie("next-auth.session-token", sessionToken, {
expires: sessionExpiry,
req: req,
res: res,
})
console.log("user Session: ", user)
}
}
return true
},
async jwt({ token, user, account, profile, isNewUser }) {
console.log("JWT callback. Got User: ", user)
if (typeof user !== typeof undefined) {
token.user = user;
}
return token
},
async session({ session, token}) {
console.log("Session. Got User: ", session, token)
if (userAccount !== null) {
console.log("UserAccount Session Generation: ", user)
session.user = {
name: userAccount.name,
email: userAccount.email,
};
console.log("Session.user: ", session.user)
// return session
}
if (
token && typeof token.user !== typeof undefined && (typeof session.user === typeof undefined ||
(typeof session.user !== typeof undefined && typeof session.user.id === typeof undefined))
) {
session.user = token.user
}
if (typeof token !== typeof undefined) {
session.token = token
}
console.log("Session: ", session)
return session
},
}
const options = {
session: {
strategy: "database",
maxAge: 7 * 24 * 60 * 60,
updateAge: 24 * 60 * 60,
// generateSessionToken: () => {
// return randomUUID?.() ?? randomBytes(32).toString("hex")
// }
},
jwt: {
// Customize the JWT encode and decode functions to overwrite the default behaviour of storing the JWT token in the session cookie when using credentials providers. Instead we will store the session token reference to the session in the database.
encode: async (token, secret, maxAge) => {
if (req.query.nextauth.includes('callback') && req.query.nextauth.includes('credentials') && req.method === 'POST') {
// const cookies = new Cookies(req,res)
// const cookie = cookies.get('next-auth.session-token')
const cookie = getCookie("next-auth.session-token", { req: req });
console.log("pure Cookie: ", cookie);
if(cookie) return cookie
else return ''
}
// Revert to default behaviour when not in the credentials provider callback flow
return encode(token, secret, maxAge)
},
decode: async (token, secret) => {
if (req.query.nextauth.includes('callback') && req.query.nextauth.includes('credentials') && req.method === 'POST') {
return null
}
// Revert to default behaviour when not in the credentials provider callback flow
return decode(token, secret)
}
},
debug: process.env.NODE_ENV === "development",
adapter,
secret: process.env.NEXTAUTH_SECRET,
providers: [
CredentialsProvider({
name: 'Credentials',
async authorize(credentials, req) {
const client = new MongoClient(MONGODB_URI, {},)
try {
await client.connect()
} catch (e) {
console.error(e)
}
const email = credentials.email
const password = credentials.password
//Get all the users
const users = client.db().collection('users')
//Find user with the email
const user = await users.findOne(
{
$or: [
{ email: email }, { username: email }
]
}
)
// //Not found - send error res
if (!user) {
client.close();
throw new Error('No user found with this credential')
}
console.log("Authorize User Credentials: ", user)
//Check hased password with DB password
const checkPassword = bcrypt.compareSync(password, user.password)
//Incorrect password - send response
if (!checkPassword) {
client.close();
throw new Error('Password doesnt match')
}
//Incorrect password - send response
if (!checkPassword) {
client.close();
throw new Error('Password doesnt match')
}
//Else send success response
userAccount = {
id: user._id,
name: user.name,
email: user.email,
};
client.close();
return userAccount;
},
}),
GoogleProvider({
clientId: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
allowDangerousEmailAccountLinking: true,
}),
FacebookProvider({
clientId: process.env.FACEBOOK_CLIENT_ID,
clientSecret: process.env.FACEBOOK_CLIENT_SECRET
}),
// ...add more providers here
],
callbacks: callbacks,
pages: {
signIn: '/signin',
signOut: '/signout',
error: '/auth/error', // Error code passed in query string as ?error=
verifyRequest: '/auth/verify-request', // (used for check email message)
// newUser: '/auth/new-user' // New users will be directed here on first sign in (leave the property out if not of interest)
},
}
return await NextAuth(req, res, options)
}

Auth0 callback returning null for token

I have a Vue.js application that uses Auth0 for the accounts. I have it so that you can register and log in currently. I have a callback URL that catches the requests and it is meant to store some data from Auth0 that my app needs. However, on the first load, it fails to store the data - seems to be picking up the default values - however on the 3rd load it will load everything perfectly fine( after 2 page refreshes).
I do not have any error messages in my Chrome console to provide just that my console.log output Vue {_uid: 2, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: Vue, …}, null and {} respectively for the console.log in the callback created method.
What am I doing wrong here to cause the default values to show on load 1 but not load 3?
Callback created
created() {
setTimeout(() => {
console.log(this.$auth)
console.log(this.$auth.token)
console.log(this.$auth.user)
localStorage.setItem('token', this.$auth.token)
localStorage.setItem('user_data', JSON.stringify(this.$auth.user))
if(this.$auth == null || this.$auth.id_token['https://tenanttalk.io/account_signup_type/is_new']) {
this.$router.push('/setup')
} else {
// Load user data from Auth0
// Go to chat page
// this.$router.push('/chat')
}
}, 500)
}
Auth0 plugin file whole
/**
* External Modules
*/
import Vue from 'vue';
import createAuth0Client from '#auth0/auth0-spa-js';
/**
* Vue.js Instance Definition
*/
let instance;
export const getInstance = () => instance;
/**
* Vue.js Instance Initialization
*/
export const useAuth0 = ({
onRedirectCallback = () =>
window.history.replaceState({}, document.title, window.location.pathname),
redirectUri = `${window.location.origin}/callback`,
...pluginOptions
}) => {
if (instance) return instance;
instance = new Vue({
data() {
return {
auth0Client: null,
isLoading: true,
isAuthenticated: false,
user: {},
error: null,
token: null,
id_token: null
};
},
methods: {
async handleRedirectCallback() {
this.isLoading = true;
try {
await this.auth0Client.handleRedirectCallback();
this.user = await this.auth0Client.getUser();
this.isAuthenticated = true;
} catch (error) {
this.error = error;
} finally {
this.isLoading = false;
}
},
loginWithRedirect(options) {
return this.auth0Client.loginWithRedirect(options);
},
logout(options) {
return this.auth0Client.logout(options);
},
getTokenSilently(o) {
return this.auth0Client.getTokenSilently(o);
},
getIdTokenClaims(o) {
return this.auth0Client.getIdTokenClaims(o);
}
},
async created() {
this.auth0Client = await createAuth0Client({
...pluginOptions,
// responseType: 'id_token',
domain: pluginOptions.domain,
client_id: pluginOptions.clientId,
audience: pluginOptions.audience,
redirect_uri: redirectUri,
});
try {
if (
window.location.search.includes('code=') &&
window.location.search.includes('state=')
) {
const { appState } = await this.auth0Client.handleRedirectCallback();
onRedirectCallback(appState);
}
} catch (error) {
this.error = error;
} finally {
this.isAuthenticated = await this.auth0Client.isAuthenticated();
this.user = await this.auth0Client.getUser();
this.$auth.getTokenSilently().then(token => this.token = token)
this.$auth.getIdTokenClaims().then(id_token => this.id_token = id_token)
this.isLoading = false;
}
},
});
return instance;
};
/**
* Vue.js Plugin Definition
*/
export const Auth0Plugin = {
install(Vue, options) {
Vue.prototype.$auth = useAuth0(options);
},
};
main.js where plugin is added directly after imports
import { Auth0Plugin } from '#/auth/auth0-plugin';
// Install the authentication plugin
Vue.use(Auth0Plugin, {
domain,
clientId,
audience,
onRedirectCallback: (appState) => {
router.push(
appState && appState.targetUrl
? appState.targetUrl
: window.location.pathname,
);
},
});

How to authenticate Nuxt on server side?

I have spent the night looking for solutions to this issue, it seems like a lot of people have it and the best advice is often "just switch to SPA mode", which is not an option for me.
I have JWT for authentication, using the JWTSessions gem for Rails.
On the frontend, I have Nuxt with nuxt-auth, using a custom scheme, and the following authorization middleware:
export default function ({ $auth, route, redirect }) {
const role = $auth.user && $auth.user.role
if (route.meta[0].requiredRole !== role) {
redirect('/login')
}
}
The symptom I have is as follows: if I log in and navigate around restricted pages, everything works as expected. I even have fetchOnServer: false for restricted pages, as I only need SSR for my public ones.
However, once I refresh the page or just navigate directly to a restricted URL, I get immediately redirected to the login page by the middleware. Clearly, the user that's authenticated on the client side is not being authenticated on the server side too.
I have the following relevant files.
nuxt.config.js
...
plugins: [
// ...
{ src: '~/plugins/axios' },
// ...
],
// ...
modules: [
'cookie-universal-nuxt',
'#nuxtjs/axios',
'#nuxtjs/auth'
],
// ...
axios: {
baseURL: process.env.NODE_ENV === 'production' ? 'https://api.example.com/v1' : 'http://localhost:3000/v1',
credentials: true
},
auth: {
strategies: {
jwtSessions: {
_scheme: '~/plugins/auth-jwt-scheme.js',
endpoints: {
login: { url: '/signin', method: 'post', propertyName: 'csrf' },
logout: { url: '/signin', method: 'delete' },
user: { url: '/users/active', method: 'get', propertyName: false }
},
tokenRequired: true,
tokenType: false
}
},
cookie: {
options: {
maxAge: 64800,
secure: process.env.NODE_ENV === 'production'
}
}
},
auth-jwt-scheme.js
const tokenOptions = {
tokenRequired: true,
tokenType: false,
globalToken: true,
tokenName: 'X-CSRF-TOKEN'
}
export default class LocalScheme {
constructor (auth, options) {
this.$auth = auth
this.name = options._name
this.options = Object.assign({}, tokenOptions, options)
}
_setToken (token) {
if (this.options.globalToken) {
this.$auth.ctx.app.$axios.setHeader(this.options.tokenName, token)
}
}
_clearToken () {
if (this.options.globalToken) {
this.$auth.ctx.app.$axios.setHeader(this.options.tokenName, false)
this.$auth.ctx.app.$axios.setHeader('Authorization', false)
}
}
mounted () {
if (this.options.tokenRequired) {
const token = this.$auth.syncToken(this.name)
this._setToken(token)
}
return this.$auth.fetchUserOnce()
}
async login (endpoint) {
if (!this.options.endpoints.login) {
return
}
await this._logoutLocally()
const result = await this.$auth.request(
endpoint,
this.options.endpoints.login
)
if (this.options.tokenRequired) {
const token = this.options.tokenType
? this.options.tokenType + ' ' + result
: result
this.$auth.setToken(this.name, token)
this._setToken(token)
}
return this.fetchUser()
}
async setUserToken (tokenValue) {
await this._logoutLocally()
if (this.options.tokenRequired) {
const token = this.options.tokenType
? this.options.tokenType + ' ' + tokenValue
: tokenValue
this.$auth.setToken(this.name, token)
this._setToken(token)
}
return this.fetchUser()
}
async fetchUser (endpoint) {
if (this.options.tokenRequired && !this.$auth.getToken(this.name)) {
return
}
if (!this.options.endpoints.user) {
this.$auth.setUser({})
return
}
const user = await this.$auth.requestWith(
this.name,
endpoint,
this.options.endpoints.user
)
this.$auth.setUser(user)
}
async logout (endpoint) {
if (this.options.endpoints.logout) {
await this.$auth
.requestWith(this.name, endpoint, this.options.endpoints.logout)
.catch(() => {})
}
return this._logoutLocally()
}
async _logoutLocally () {
if (this.options.tokenRequired) {
this._clearToken()
}
return await this.$auth.reset()
}
}
axios.js
export default function (context) {
const { app, $axios, redirect } = context
$axios.onResponseError(async (error) => {
const response = error.response
const originalRequest = response.config
const access = app.$cookies.get('jwt_access')
const csrf = originalRequest.headers['X-CSRF-TOKEN']
const credentialed = (process.client && csrf) || (process.server && access)
if (credentialed && response.status === 401 && !originalRequest.headers.REFRESH) {
if (process.server) {
$axios.setHeader('X-CSRF-TOKEN', csrf)
$axios.setHeader('Authorization', access)
}
const newToken = await $axios.post('/refresh', {}, { headers: { REFRESH: true } })
if (newToken.data.csrf) {
$axios.setHeader('X-CSRF-TOKEN', newToken.data.csrf)
$axios.setHeader('Authorization', newToken.data.access)
if (app.$auth) {
app.$auth.setToken('jwt_access', newToken.data.csrf)
app.$auth.syncToken('jwt_access')
}
originalRequest.headers['X-CSRF-TOKEN'] = newToken.data.csrf
originalRequest.headers.Authorization = newToken.data.access
if (process.server) {
app.$cookies.set('jwt_access', newToken.data.access, { path: '/', httpOnly: true, maxAge: 64800, secure: false, overwrite: true })
}
return $axios(originalRequest)
} else {
if (app.$auth) {
app.$auth.logout()
}
redirect(301, '/login')
}
} else {
return Promise.reject(error)
}
})
}
This solution is already heavily inspired by material available under other threads and at this point I am pretty much clueless regarding how to authenticate my users universally across Nuxt. Any help and guidance much appreciated.
In order for You not to lose Your authentication session in the system, You first need to save your JWT token to some storage on the client: localStorage or sessionStorage or as well as token data can be saved in cookies.
For to work of the application will be optimally, You also need to save the token in the store of Nuxt. (Vuex)
If You save Your token only in srore of Nuxt and use only state, then every time You refresh the page, Your token will be reset to zero, since the state will not have time to initialize. Therefore, you are redirected to the page /login.
To prevent this from happening, after you save Your token to some storage, You need to read it and reinitialize it in the special method nuxtServerInit(), in the universal mode his will be work on the server side the very first. (Nuxt2)
Then, accordingly, You use Your token when sending requests to the api server, adding to each request that requires authorization, a header of the Authorization type.
Since Your question is specific to the Nuxt2 version, for this version a working code example using cookies to store the token would be:
/store/auth.js
import jwtDecode from 'jwt-decode'
export const state = () => ({
token: null
})
export const getters = {
isAuthenticated: state => Boolean(state.token),
token: state => state.token
}
export const mutations = {
SET_TOKEN (state, token) {
state.token = token
}
}
export const actions = {
autoLogin ({ dispatch }) {
const token = this.$cookies.get('jwt-token')
if (isJWTValid(token)) {
dispatch('setToken', token)
} else {
dispatch('logout')
}
},
async login ({ commit, dispatch }, formData) {
const { token } = await this.$axios.$post('/api/auth/login', formData, { progress: false })
dispatch('setToken', token)
},
logout ({ commit }) {
this.$axios.setToken(false)
commit('SET_TOKEN', null)
this.$cookies.remove('jwt-token')
},
setToken ({ commit }, token) {
this.$axios.setToken(token, 'Bearer')
commit('SET_TOKEN', token)
this.$cookies.set('jwt-token', token, { path: '/', expires: new Date('2024') })
// <-- above use, for example, moment or add function that will computed date
}
}
/**
* Check valid JWT token.
*
* #param token
* #returns {boolean}
*/
function isJWTValid (token) {
if (!token) {
return false
}
const jwtData = jwtDecode(token) || {}
const expires = jwtData.exp || 0
return new Date().getTime() / 1000 < expires
}
/store/index.js
export const state = () => ({
// ... Your state here
})
export const getters = {
// ... Your getters here
}
export const mutations = {
// ... Your mutations here
}
export const actions = {
nuxtServerInit ({ dispatch }) { // <-- init auth
dispatch('auth/autoLogin')
}
}
/middleware/isGuest.js
export default function ({ store, redirect }) {
if (store.getters['auth/isAuthenticated']) {
redirect('/admin')
}
}
/middleware/auth.js
export default function ({ store, redirect }) {
if (!store.getters['auth/isAuthenticated']) {
redirect('/login')
}
}
/pages/login.vue
<template>
<div>
<!-- Your template here-->
</div>
</template>
<script>
export default {
name: 'Login',
layout: 'empty',
middleware: ['isGuest'], // <-- if the user is authorized, then he should not have access to the page !!!
data () {
return {
controls: {
login: '',
password: ''
},
rules: {
login: [
{ required: true, message: 'login is required', trigger: 'blur' }
],
password: [
{ required: true, message: 'password is required', trigger: 'blur' },
{ min: 6, message: 'minimum 6 length', trigger: 'blur' }
]
}
}
},
head: {
title: 'Login'
},
methods: {
onSubmit () {
this.$refs.form.validate(async (valid) => { // <-- Your validate
if (valid) {
// here for example: on loader
try {
await this.$store.dispatch('auth/login', {
login: this.controls.login,
password: this.controls.password
})
await this.$router.push('/admin')
} catch (e) {
// eslint-disable-next-line no-console
console.error(e)
} finally {
// here for example: off loader
}
}
})
}
}
}
</script>
! - You must have the following packages installed:
cookie-universal-nuxt
jsonwebtoken
jwt-decode
I think you will find my answer helpful. If something is not clear, ask!

How to avoid using loginPopup or loginRedirect and silently get the authenticated

I want to avoid using the loginPopup or loginRedirect and get authenticated directly. I am using the below code. I am try to achieve SSO by hosting my chatbot on sharepoint website. As i have already login to my sharepoint website I need to avoid login again.
Current functionality, When i click on the chatbot icon i am getting a pop-up window on the current site. i.e. sharepoint and i am login again, I need to avoid this.
For complete code click here
function onSignInClick() {
alert("Inside onSignInClick function");
let requestObj = {
scopes: ["user.read", 'openid', 'profile']
};
debugger;
clientApplication.loginPopup(requestObj)
.then(onSignin)
.catch(function (error) { console.log(error) });
}
function onSignin(idToken) {
let user = clientApplication.getAccount();
document.getElementById("userName").innerHTML = "Currently logged in as " + user.name;
let requestObj1 = {
scopes: ["user.read", 'openid', 'profile']
};
}
var clientApplication;
(function () {
var msalConfig = {
auth: {
clientId: '<client id>',
authority: 'https://login.microsoftonline.com/<directory id>'
},
cache: {
cacheLocation: 'localStorage',
storeAuthStateInCookie: false
}
};
if (!clientApplication) {
clientApplication = new Msal.UserAgentApplication(msalConfig);
//alert("Inside if clientApplication: " + JSON.parse(clientApplication));
}
}());
(async function main() {
// Add your BOT ID below
var BOT_ID = "<Bot-Id>";
var theURL = "https://powerva.microsoft.com/api/botmanagement/v1/directline/directlinetoken?botId=" + BOT_ID;
//alert("before userId async function: " + JSON.parse(clientApplication));
var userId = clientApplication.account?.accountIdentifier != null
? ("You-customized-prefix" + clientApplication.account.accountIdentifier).substr(0, 64)
: (Math.random().toString() + Date.now().toString()).substr(0, 64)
;
//debugger;
alert("after userId async function: " + JSON.parse(userId));
const { token } = await fetchJSON(theURL);
const directLine = window.WebChat.createDirectLine({ token });
const store = WebChat.createStore({}, ({ dispatch }) => next => action => {
const { type } = action;
if (action.type === 'DIRECT_LINE/CONNECT_FULFILLED') {
dispatch({
type: 'WEB_CHAT/SEND_EVENT',
payload: {
name: 'startConversation',
type: 'event',
value: { text: "hello" }
}
});
return next(action);
}
if (action.type === 'DIRECT_LINE/INCOMING_ACTIVITY') {
const activity = action.payload.activity;
let resourceUri;
if (activity.from && activity.from.role === 'bot' && (resourceUri = getOAuthCardResourceUri(activity))) {
exchangeTokenAsync(resourceUri)
.then(function (token) {
if (token) {
directLine.postActivity({
type: 'invoke',
name: 'signin/tokenExchange',
value: {
id: activity.attachments[0].content.tokenExchangeResource.id,
connectionName: activity.attachments[0].content.connectionName,
token
},
"from": {
id: userId,
name: clientApplication.account.name,
role: "user"
}
}).subscribe(
id => {
if (id === 'retry') {
// bot was not able to handle the invoke, so display the oauthCard
return next(action);
}
// else: tokenexchange successful and we do not display the oauthCard
},
error => {
// an error occurred to display the oauthCard
return next(action);
}
);
return;
}
else
return next(action);
});
}
else
return next(action);
}
else
return next(action);
});
window.WebChat.renderWebChat(
{
directLine: directLine,
store,
userID: userId,
styleOptions
},
document.getElementById('webchat')
);
})()
.catch(err => console.error("An error occurred: " + err));
By your scenario to eliminate loginPopup or loginRedirect in autentication,I understood that you don't require user involvement to login. The possible solution for your scenario is to use Client credential flow.
Client Credential Flow does not require user login and can silently Sign-in with application permissions.
Please refer this code sample which can help.

Vue - Mixin on page refresh

When I navigate using vue router, everything works. Ex: I click on button using #click=login(). Above the login method
methods: {
login () {
this.$router.push('/admin')
}
So vue redirect user to '/Admin' page and the router calls beforeEach event where I check if the page has meta attribute to validate user access
Then on my router/index.js
Vue.use(Router)
const router = new Router({
mode: 'history',
routes: [
Routes
]
})
router.beforeEach(async (to, from, next) => {
if (to.meta.requiresAdminAuth) {
let app = router.app.$data || {isAuthenticated: false}
if (app.isAuthenticated) {
// already signed in, we can navigate anywhere
next()
} else if (to.matched.some(record => record.meta.requiresAdminAuth)) {
// authentication is required. Trigger the sign in process, including the return URI
console.log(router.app.hello)
let authenticate = router.app.authenticate
authenticate(to.path).then(() => {
console.log('authenticating a protected url:' + to.path)
next()
})
} else {
// No auth required. We can navigate
next()
}
} else {
next()
}
})
To validade the user I'm usgin global method and this works. But when user navigate to '/Admin' from URL, not from my button, the global variable is undefined. So I tried to use Mixin, but the result was the same.
Here is my main.js where I specify global method and the mixin:
var myMixin = {
methods: {
hello: function () {
console.log('Bem-vindo ao mixin!')
}
}
}
const globalData = {
isAuthenticated: false,
user: '',
mgr: mgr
}
const globalMethods = {
async authenticate (returnPath) {
const user = await this.$root.getUser()
if (user) {
this.isAuthenticated = true
this.user = user
} else {
await this.$root.signIn(returnPath)
}
},
async getUser () {
try {
let user = await this.mgr.getUser()
console.log(user)
return user
} catch (err) {
console.log(err)
}
},
signIn (returnPath) {
returnPath ? this.mgr.signinRedirect({ state: returnPath })
: this.mgr.signinRedirect()
}
}
/* eslint-disable no-new */
new Vue({
mixins: [myMixin],
el: '#app',
router,
store,
template: '<App/>',
components: { App },
data: globalData,
methods: globalMethods
})
How can I do that? Execute a defined method when user navigate by URL?

Categories