Nuxt JS route validation doesn't redirect to error page - vue.js

I have an app with Nuxt JS, and there is a route called posts that accepts parameters like so: .../posts/_id. When someone goes to /posts/put_news, they get post with name "Put News" and so on.
So, I wrote a validation method like so:
async validate({ params }) {
// await operations
const response = await axios.get('http://localhost:5000/listings_names')
var response_data = response.data
var str = (params.id).split('_').join(' ')
const arr2 = str.split(" ");
for (var i = 0; i < arr2.length; i++) {
arr2[i] = arr2[i].charAt(0).toUpperCase() + arr2[i].slice(1);
}
const str2 = arr2.join(" ");
var id_fix = str2
const obj = response_data.find(o => o.name == id_fix);
console.log(obj)
if (obj == undefined){
console.log('undefied, false')
return false
}
else{
return true;
}
},
The code does return false, but does nothing else. Once it returns "false" I expect nuxt to redirect the user to the error page, but it just stays on that page. I looked on the documentation, and it seems like the user should be automatically redirected to an error page, however nothing happens here. Also, my nuxt version is 2.15.8.
Thank you for the help

I fixed the issue, so all I had to do, was add redirect to validate function, and redirect to the error page, like so:
async validate({ params, redirect }) { //run-functions
if (obj == undefined) {
redirect('/not_found')
return false
} else {
return true
}
}

Related

Navigation guard keeps looping

I have a guard for my routes which does work in all aspects apart from when I wish to check a permissions object related to that page prior to continuing onto the url.
I have separated out the logic for the permissions check into a function and console logging it out all elements are working, in that it finds the right object in the array, finds the right key and value, and allows or blocks accordingly.
My problem though is that when I go through this route hitting this function it loops endlessly and crashes the browser. I think my overarching logic is fine but have I screwed up its implementation somewhere?
function guard (to, from, next) {
var loggedin_state = store.state.user.auth.loggedin // Boolean
var user = store.state.user.user // Array
var token = store.state.user.auth.token // String
var entryUrl // String
if(entryUrl == null || entryUrl == undefined){
entryUrl = to.path
}
if(loggedin_state == true) {
// Is the user profile blank
if(user == null) {
this.$store.dispatch('user/get_user_information', null)
}
// If they tried a route before logging in that would have been stored
if(entryUrl) {
// Store the url before wiping it
let url = entryUrl;
// Wipe the entry url variable
entryUrl = null;
// Carry on to permission checking function
return go_to_url(url);
} else {
// Go to stored url
return next(to.path)
}
} else {
// Is there a token assigned? If so they are approved and just need the profile information
if(token !== null) {
loggedin_state = true
this.$store.dispatch('user/get_user_information', null)
return go_to_url(to.path);
} else {
// Store entry url before redirect for use after login
entryUrl = to.path
// Re-route to login page
return next("/login");
}
}
function go_to_url(url) {
// Find matching object in user.permissions based upon url
var view_permissions = [
{ "area": "all", "read": 1, "create": 0, "edit": 0, "delete": 0 },
{ "area": "dashboard", "read": 1, "create": 0, "edit": 0, "delete": 0 }
];
// var view_permissions = store.state.user.permissions
var view_permission = view_permissions.find(view => view.area === to.name);
if(view_permission.read == 1) {
// Go to url
next(url);
} else {
// Re-route to somewhere
}
};
};
My problem was in passing a value to the next() function call. By removing that out it worked alright:
function guard (to, from, next) {
console.log('To:')
console.log(to)
console.log('From:')
console.log(from)
console.log('EntryUrl: ' + entryUrl)
// 1 - If no entry path was provided then set to
if(entryUrl == null || entryUrl == undefined){
entryUrl = to.path
console.log('EntryUrl: ' + entryUrl)
}
// 2 - Check if the user is marked as being logged in
var loggedin_state = store.state.user.auth.loggedin
if(loggedin_state == undefined) {
store.commit('user/set_delete_session', null)
return next("/login");
}
// 3 - If they are marked as logged in continue
var user = store.state.user.user
var token = store.state.user.auth.token
if(loggedin_state == true) {
// If the user isn't authorised with a token then send them to the log in page
if(token == null) {
store.commit('user/set_delete_session', null)
return next("/login");
}
// If they've got a token but no user profile data acquire it
if(user == null) {
UserApi.get_user_information(response.data.token)
.then(response => {
store.commit('user/set_user', response.data)
})
}
// If they tried a route before logging in that would have been stored
if(entryUrl) {
console.log('Go to saved URL')
// Store the url before wiping it
let url = entryUrl;
// Wipe the entry url variable
entryUrl = null;
// Go to stored url
return go_to_url(url);
} else {
console.log('Go to pointed url')
// Carry on to permission checking function
return go_to_url(to.path);
}
} else {
// The user is not logged in. Store the URL they were trying to visit and redirect them to the login page
entryUrl = to.path
console.log('EntryUrl: ' + entryUrl)
return next("/login");
}
function go_to_url(url) {
console.log(url)
// 1 - Grab the user permissions from the user profile
var permissions_array = null
if(user !== null) {
permissions_array = user.permissions
}
console.log(permissions_array)
// 2 - Check and route
if(permissions_array !== null) {
// Find the relevant permission object based upon the route name and the area key
var view_permissions = permissions_array.find(view => view.area === to.name);
console.log(view_permissions)
// If a permission object was found check its status, if no object found assume it is okay to view
if(view_permissions !== undefined) {
// If set to 1 the user can view this route, else reroute to a permissions denied page
if(view_permissions.read == 1) {
// Go to url
console.log('GUARD - PROCEED')
console.log(to.name)
next();
} else {
console.log('GUARD - BLOCKED')
return next("/permission-denied");
}
} else {
return next()
}
}
};
};

Visiting multiple urls using PhantomJS evaluating Error

I have this beautiful code, all I want to make some pause between visits, so I add a 'setinterval', but this not works:
var page = require('webpage').create();
// the urls to navigate to
var urls = [
'http://blogger.com/',
'https://github.com/',
'http://reddit.com/'
];
var i = 0;
// the recursion function
var genericCallback = setInterval(function () {
return function (status) {
console.log("URL: " + urls[i]);
console.log("Status: " + status);
// exit if there was a problem with the navigation
if (!status || status === 'fail') phantom.exit();
i++;
if (status === "success") {
//-- YOUR STUFF HERE ----------------------
// do your stuff here... I'm taking a picture of the page
page.render('example' + i + '.png');
//-----------------------------------------
if (i < urls.length) {
// navigate to the next url and the callback is this function (recursion)
page.open(urls[i], genericCallback());
} else {
// try navigate to the next url (it is undefined because it is the last element) so the callback is exit
page.open(urls[i], function () {
phantom.exit();
});
}
}
};
},2000);
// start from the first url
page.open(urls[i], genericCallback());
the screenshot with the error I get:
maybe someone could help me and heal this code? Because I'm new to JS and to PhantomJS, any help will be apreciate.
I got this code from another stackoverflow answer here - Using Multiple page.open in Single Script
but I can't comment to the author , because I don't have 50 reputation
It should rather be something like this:
var page = require('webpage').create();
var urls = ['http://blogger.com/','https://github.com/','http://reddit.com/'];
var i = 0;
function OpenPage(){
setTimeout(function(){
page.open(urls[i], function(status) {
if (status == 'success') {
page.render('example' + i + '.png');
}
i++;
if(i <= urls.length - 1){
OpenPage();
}else{
phantom.exit();
}
});
},2000);
}
OpenPage();

Adal.js not setting props in localStorage

I'm having a problem using the adal.js library without Angular. (I'm using Vue.js.)
I have an authentication context instance, which is constructed with the following options (exact values have been changed to protect the innocent):
let config = {
tenant: '<tenant id>',
clientId: '<client id>',
redirectUri: 'http://myapplication.com/index.html',
// popUp: true,
cacheLocation: 'localStorage'
}
On my login page, I call authContext.login(), which redirects me first to https://login.microsoftonline.com/, where I log into AAD. Upon successful login, another redirect takes me back to my application, at the URI I've configured above, along with an id_token parameter in the URL. However, no token or other properties are stored by the library in local storage, just a few properties that are the result of the configuration.
On successful login, All I've got in localStorage is
{
adal.access.token.key: "",
adal.error: ""
adal.error.description: ""
adal.expiration.key: "0"
adal.idtoken: ""
adal.login.error: ""
adal.login.request: "http://myapplication.com/#/login"
adal.nonce.idtoken: "<a non-empty string>"
adal.session.state: ""
adal.state.login: "<a non-empty string>"
adal.token.keys: ""
adal.username: ""
}
So, as far as AAD is concerned, I've successfully authenticated, but the library itself seems to have no notion of what user is logged in, what tokens are associated with them, when the token expires, etc. Any advice on how to proceed would be most appreciated. Thank you in advance for reading.
Active Directory Authentication Library for JavaScript (ADAL JS) helps you to use Azure AD for handling authentication in your single page applications. This library is optimized for working together with AngularJS.
It will not save the tokens into the cache unless we code it. You can check the relative code from adal-angular.js. Here is a piece of code for your reference:
The saveTokenFromHash method will also save the tokens into cache and this function will execute after the page redirect back to the Angular app.
adal.js:
AuthenticationContext.prototype.saveTokenFromHash = function (requestInfo) {
this._logstatus('State status:' + requestInfo.stateMatch);
this._saveItem(this.CONSTANTS.STORAGE.ERROR, '');
this._saveItem(this.CONSTANTS.STORAGE.ERROR_DESCRIPTION, '');
// Record error
if (requestInfo.parameters.hasOwnProperty(this.CONSTANTS.ERROR_DESCRIPTION)) {
this._logstatus('Error :' + requestInfo.parameters.error);
this._logstatus('Error description:' + requestInfo.parameters[this.CONSTANTS.ERROR_DESCRIPTION]);
this._saveItem(this.CONSTANTS.STORAGE.FAILED_RENEW, requestInfo.parameters[this.CONSTANTS.ERROR_DESCRIPTION]);
this._saveItem(this.CONSTANTS.STORAGE.ERROR, requestInfo.parameters.error);
this._saveItem(this.CONSTANTS.STORAGE.ERROR_DESCRIPTION, requestInfo.parameters[this.CONSTANTS.ERROR_DESCRIPTION]);
if (requestInfo.requestType === this.REQUEST_TYPE.LOGIN) {
this._loginInProgress = false;
this._saveItem(this.CONSTANTS.STORAGE.LOGIN_ERROR, requestInfo.parameters.errorDescription);
} else {
this._renewActive = false;
}
} else {
// It must verify the state from redirect
if (requestInfo.stateMatch) {
// record tokens to storage if exists
this._logstatus('State is right');
if (requestInfo.parameters.hasOwnProperty(this.CONSTANTS.SESSION_STATE)) {
this._saveItem(this.CONSTANTS.STORAGE.SESSION_STATE, requestInfo.parameters[this.CONSTANTS.SESSION_STATE]);
}
var keys, resource;
if (requestInfo.parameters.hasOwnProperty(this.CONSTANTS.ACCESS_TOKEN)) {
this._logstatus('Fragment has access token');
// default resource
this._renewActive = false;
resource = this.config.loginResource;
if (!this._hasResource(resource)) {
keys = this._getItem(this.CONSTANTS.STORAGE.TOKEN_KEYS) || '';
this._saveItem(this.CONSTANTS.STORAGE.TOKEN_KEYS, keys + resource + this.CONSTANTS.RESOURCE_DELIMETER);
}
if (requestInfo.requestType === this.REQUEST_TYPE.RENEW_TOKEN) {
resource = this._getResourceFromState(requestInfo.stateResponse);
}
// save token with related resource
this._saveItem(this.CONSTANTS.STORAGE.ACCESS_TOKEN_KEY + resource, requestInfo.parameters[this.CONSTANTS.ACCESS_TOKEN]);
this._saveItem(this.CONSTANTS.STORAGE.EXPIRATION_KEY + resource, this._expiresIn(requestInfo.parameters[this.CONSTANTS.EXPIRES_IN]));
}
if (requestInfo.parameters.hasOwnProperty(this.CONSTANTS.ID_TOKEN)) {
this._loginInProgress = false;
this._user = this._createUser(requestInfo.parameters[this.CONSTANTS.ID_TOKEN]);
if (this._user && this._user.profile) {
if (this._user.profile.nonce !== this._getItem(this.CONSTANTS.STORAGE.NONCE_IDTOKEN)) {
this._user = null;
this._saveItem(this.CONSTANTS.STORAGE.LOGIN_ERROR, 'Nonce is not same as ' + this._idTokenNonce);
} else {
this._saveItem(this.CONSTANTS.STORAGE.IDTOKEN, requestInfo.parameters[this.CONSTANTS.ID_TOKEN]);
// Save idtoken as access token for app itself
resource = this.config.clientId;
if (!this._hasResource(resource)) {
keys = this._getItem(this.CONSTANTS.STORAGE.TOKEN_KEYS) || '';
this._saveItem(this.CONSTANTS.STORAGE.TOKEN_KEYS, keys + resource + this.CONSTANTS.RESOURCE_DELIMETER);
}
this._saveItem(this.CONSTANTS.STORAGE.ACCESS_TOKEN_KEY + resource, requestInfo.parameters[this.CONSTANTS.ID_TOKEN]);
this._saveItem(this.CONSTANTS.STORAGE.EXPIRATION_KEY + resource, this._user.profile.exp);
}
}
}
} else {
this._saveItem(this.CONSTANTS.STORAGE.ERROR, 'Invalid_state');
this._saveItem(this.CONSTANTS.STORAGE.ERROR_DESCRIPTION, 'Invalid_state');
if (requestInfo.requestType === this.REQUEST_TYPE.LOGIN) {
this._saveItem(this.CONSTANTS.STORAGE.LOGIN_ERROR, 'State is not same as ' + requestInfo.stateResponse);
}
}
}
};
And this function will be called in this.$get like below:
// special function that exposes methods in Angular controller
// $rootScope, $window, $q, $location, $timeout are injected by Angular
this.$get = ['$rootScope', '$window', '$q', '$location', '$timeout', function ($rootScope, $window, $q, $location, $timeout) {
var locationChangeHandler = function () {
var hash = $window.location.hash;
if (_adal.isCallback(hash)) {
// callback can come from login or iframe request
var requestInfo = _adal.getRequestInfo(hash);
_adal.saveTokenFromHash(requestInfo);
$window.location.hash = '';
if (requestInfo.requestType !== _adal.REQUEST_TYPE.LOGIN) {
_adal.callback = $window.parent.AuthenticationContext().callback;
}
// Return to callback if it is send from iframe
if (requestInfo.stateMatch) {
if (typeof _adal.callback === 'function') {
// Call within the same context without full page redirect keeps the callback
if (requestInfo.requestType === _adal.REQUEST_TYPE.RENEW_TOKEN) {
// Idtoken or Accestoken can be renewed
if (requestInfo.parameters['access_token']) {
_adal.callback(_adal._getItem(_adal.CONSTANTS.STORAGE.ERROR_DESCRIPTION), requestInfo.parameters['access_token']);
return;
} else if (requestInfo.parameters['id_token']) {
_adal.callback(_adal._getItem(_adal.CONSTANTS.STORAGE.ERROR_DESCRIPTION), requestInfo.parameters['id_token']);
return;
}
}
} else {
// normal full login redirect happened on the page
updateDataFromCache(_adal.config.loginResource);
if (_oauthData.userName) {
//IDtoken is added as token for the app
$timeout(function () {
updateDataFromCache(_adal.config.loginResource);
$rootScope.userInfo = _oauthData;
// redirect to login requested page
var loginStartPage = _adal._getItem(_adal.CONSTANTS.STORAGE.START_PAGE);
if (loginStartPage) {
$location.path(loginStartPage);
}
}, 1);
$rootScope.$broadcast('adal:loginSuccess');
} else {
$rootScope.$broadcast('adal:loginFailure', _adal._getItem(_adal.CONSTANTS.STORAGE.ERROR_DESCRIPTION));
}
}
}
} else {
// No callback. App resumes after closing or moving to new page.
// Check token and username
updateDataFromCache(_adal.config.loginResource);
if (!_adal._renewActive && !_oauthData.isAuthenticated && _oauthData.userName) {
if (!_adal._getItem(_adal.CONSTANTS.STORAGE.FAILED_RENEW)) {
// Idtoken is expired or not present
_adal.acquireToken(_adal.config.loginResource, function (error, tokenOut) {
if (error) {
$rootScope.$broadcast('adal:loginFailure', 'auto renew failure');
} else {
if (tokenOut) {
_oauthData.isAuthenticated = true;
}
}
});
}
}
}
$timeout(function () {
updateDataFromCache(_adal.config.loginResource);
$rootScope.userInfo = _oauthData;
}, 1);
}
...
And here is a sample code which could save the tokens into cache for your reference:
<html>
<head>
<script src="https://unpkg.com/vue"></script>
<script src="node_modules\adal-angular\lib\adal.js"> </script>
<script src="config.js"> </script>
</head>
<body>
<div>
<button onclick="login()" >Login</button>
</div>
<script>
var authContext=new AuthenticationContext(config);
function login(){
authContext.login();
}
function init(configOptions){
if (configOptions) {
// redirect and logout_redirect are set to current location by default
var existingHash = window.location.hash;
var pathDefault = window.location.href;
if (existingHash) {
pathDefault = pathDefault.replace(existingHash, '');
}
configOptions.redirectUri = configOptions.redirectUri || pathDefault;
configOptions.postLogoutRedirectUri = configOptions.postLogoutRedirectUri || pathDefault;
// create instance with given config
} else {
throw new Error('You must set configOptions, when calling init');
}
// loginresource is used to set authenticated status
updateDataFromCache(authContext.config.loginResource);
}
var _oauthData = { isAuthenticated: false, userName: '', loginError: '', profile: '' };
var updateDataFromCache = function (resource) {
// only cache lookup here to not interrupt with events
var token = authContext.getCachedToken(resource);
_oauthData.isAuthenticated = token !== null && token.length > 0;
var user = authContext.getCachedUser() || { userName: '' };
_oauthData.userName = user.userName;
_oauthData.profile = user.profile;
_oauthData.loginError = authContext.getLoginError();
};
init(config);
function saveTokenFromHash(){
var hash = window.location.hash;
var requestInfo = authContext.getRequestInfo(hash);
if (authContext.isCallback(hash)) {
// callback can come from login or iframe request
var requestInfo = authContext.getRequestInfo(hash);
authContext.saveTokenFromHash(requestInfo);
window.location.hash = '';
if (requestInfo.requestType !== authContext.REQUEST_TYPE.LOGIN) {
authContext.callback = window.parent.AuthenticationContext().callback;
}
}
}
saveTokenFromHash();
</script>
</body>
</html>

Single page application client and server routing

I've got the following code to handle client side navigation using HTML5 pushstate (classic combination of crossroadsjs and historyjs):
History = window.History;
History.Adapter.bind(window, 'statechange', function () {
var state = History.getState();
console.log(state);
if (state.data.urlPath) {
return crossroads.parse(state.data.urlPath);
}
else
{
if (state.hash.length > 1) {
var fullHash = state.hash;
var hashPath = fullHash.slice(0, fullHash.indexOf('?'));
return crossroads.parse(hashPath);
}
}});
crossroads.normalizeFn = crossroads.NORM_AS_OBJECT;
crossroads.parse('/');
$('body').on('click', 'a', function(e) {
var title, urlPath;
urlPath = $(this).attr('href');
if (urlPath.slice(0, 1) == '#'){
return true;
}
e.preventDefault();
title = $(this).text().trim();
return History.pushState({ urlPath: urlPath }, title, urlPath);
});
It works really well. Now, to handle url bookmarking and sharing, I added and express server to handle all requests. All it does is to redirect to index.html (a sort of catchall rule):
var env = require('./env');
var fallback = require('express-history-api-fallback');
var express = require('express');
var app = express();
var config = env.config();
var root = __dirname + '/dist';
app.use(express.static(root));
app.use(fallback('index.html', { root: root }));
var port = process.env.PORT || 9090;
var server = app.listen(port, function () {
console.log('Server started at: http://localhost:' + port);
console.log(config);
});
The problem I am facing is that it successfully redirects to index.html but it doesn't load the correct route on the client side. So a request to www.mysite.com or www.mysite.com/anotherpage will always load the home page route.
I am obviously missing some code to intercept that and load the appropriate route on the client side. I just don't know what to do.
Found where the bug was:
crossroads.parse('/');
This was always redirecting to the "home" route. I just had to refactor the code a bit:
History.Adapter.bind(window, 'statechange', this.routeCrossRoads);
routeCrossRoads() {
var state = History.getState();
if (state.data.urlPath) {
return crossroads.parse(state.data.urlPath);
}
else {
if (state.hash.length > 1) {
var fullHash = state.hash;
var pos = fullHash.indexOf('?');
if (pos > 0) {
var hashPath = fullHash.slice(0, pos);
return crossroads.parse(hashPath);
}
else {
return crossroads.parse(fullHash);
}
}
else {
return crossroads.parse('/');
}
}
}

CasperJS looking for 404 error on links site

I'm beginner programmer. I found nice script
http://planzero.org/blog/2013/03/07/spidering_the_web_with_casperjs
I tried to rewrite this script with CasperJS test framework.
I would to get xunit report from this code
var startUrl = 'http://yoursite.foo';
var visitedUrls = [], pendingUrls = [];
var casper = require('casper').create({
pageSettings: {
loadImages: false,
loadPlugins: false
}});
var utils = require('utils')
var helpers = require('helpers')
// Spider from the given URL
casper.test.begin('href' , function(test) {
casper.start(startUrl, function() {
function spider(url) {
// Add the URL to the visited stack
visitedUrls.push(url);
// Open the URL
casper.open(url).then(function() {
test.assertHttpStatus(200, ":" + url);
// Find links present on this page
var links = this.evaluate(function() {
var links = [];
Array.prototype.forEach.call(__utils__.findAll('a'), function(e) {
links.push(e.getAttribute('href'));
});
return links;
});
// Add newly found URLs to the stack
var baseUrl = this.getGlobal('location').origin;
Array.prototype.forEach.call(links, function(link) {
var newUrl = helpers.absoluteUri(baseUrl, link);
if (pendingUrls.indexOf(newUrl) == -1 && visitedUrls.indexOf(newUrl) == -1 && !(link.search(startUrl) == -1)) {
pendingUrls.push(newUrl);
}
});
// If there are URLs to be processed
if (pendingUrls.length > 0) {
var nextUrl = pendingUrls.shift();
spider(nextUrl);
}
else {
console.log('links ended');
this.break;
}
});
}
spider(startUrl);
}).run(function(){
test.done();
});
});
Script is running but when he and Job I can't get report.
If you're trying to learn how to use CasperJS you need to start with a smaller example than that. That script is a mess which goes after a site named yoursite.foo (maybe you put that name in there?)
I would take small steps. I have a video which may help explain how to use CasperJS.
http://www.youtube.com/watch?v=Kefil5tCL9o