Browser back button redirecting to home page in angular 8 - angular8

Browser back button is not working. It redirects me to the home page instead of going to the previous page.
e.g
http://localhost:4200/#/component1/1
http://localhost:4200/#/component2/1
http://localhost:4200/#/component3/1
When I click back button when I am in component3 it has goes to component2 instead its going to the home page. Can anyone tell me the solution to this problem?
routing.ts
{
path: 'component1/:id',
component: Component1,
canActivate: [OAuthCallbackHandlerGuard],
data: { isId: true },
},
{
path: 'component2/:id',
component: Component2,
canActivate: [OAuthCallbackHandlerGuard],
data: { isId: true },
},
{
path: 'component3/:id',
component: Component3,
canActivate: [OAuthCallbackHandlerGuard],
data: { isId: true },
},
oauthcallbackhandlerguard.service.ts
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> {
this.adalService.handleWindowCallback();
let engId: number = 0;
let engagementDetailId: number = 0;
if(route.data.isEngagementDetailId == true)
{
let engDetailData =this.engagementService.$engagementDetailId.subscribe((data) => {
if (data !== undefined && data !== null) {
engagementDetailId = data;
}
});
}
else
{
let engData =this.engagementService.$engagementId.subscribe((data) => {
if (data !== undefined && data !== null) {
engId = data;
}
});
}
let groupIds = JSON.parse(sessionStorage.getItem('groupids'));
return this.validateUserAccess(engId, engagementDetailId, state,groupIds);
}
private validateUserAccess(engId: number, engagementDetailId: number, state: RouterStateSnapshot,groupIds:number[]): Observable<boolean | UrlTree> {
if (engId > 0 || engagementDetailId>0) {
return this.authGuardService.validateUserAccess(engagementDetailId, engId,groupIds).map(response => {
console.log(response);
return response ? true : this.router.parseUrl('/unauthorized');
if (response) {
this.router.navigate([state.url]);
}
else {
this.redictToUnAutherized();
}
},
(error) => {
console.log('auth failed. Error ', error);
// this.redictToUnAutherized();
return false;
});
}
else {
return Observable.of(true);
}
}
private redictToUnAutherized() {
this.router.navigate(['/unauthorized']);
}

1- Run your app in diffrent browser
2- Add default routes
const routes: Routes = [
{ path: '', pathMatch: 'full', component: HomeComponent },
{
path: 'component1/:id',
component: Component1,
canActivate: [OAuthCallbackHandlerGuard],
data: { isId: true },
},
{
path: 'component2/:id',
component: Component2,
canActivate: [OAuthCallbackHandlerGuard],
data: { isId: true },
},
{
path: 'component3/:id',
component: Component3,
canActivate: [OAuthCallbackHandlerGuard],
data: { isId: true },
},
{ path: '**', component: HomeComponent }
];
3- Try to check in OAuthCallbackHandlerGuard if it is going to navigate page back and allow it with Auth
constructor (private _location: Location)
this._location.back();

Related

TypeError: a.then is not a function while compiling in production

I'm trying to compile my vue app in production with npm run build (which is vite build).
After that I try to serve my app on my server with the /dist folder and everything seems to be working perfectly, I'm able to send fetch request, click on various links etc.
Unfortunately, after logging in and when I should be redirected, I'm getting the error
TypeError: a.then is not a function while compiling in production
and
Uncaught (in promise) TypeError: a.then is not a function"
Everything just works perfectly fine while I'm in dev mode, it's just not working in production.
It seems to be linked to the router
This is the code for my Router :
const state = reactive({
token: localStorage.getItem("token"),
userAdmin: false,
userRestaurateur: false,
userDeliverer: false
});
if (state.token) {
const user = JSON.parse(atob(state.token.split('.')[1]))
state.userAdmin = Object.values(user.roles).includes('ROLE_ADMIN');
state.userRestaurateur = Object.values(user.roles).includes('ROLE_RESTAURANT');
state.userDeliverer = Object.values(user.roles).includes('ROLE_DELIVERER');
}
const router = createRouter({
history: createWebHistory('/'),
routes: [
{
path: '/',
name: 'home',
component: function () {
if (state.token && state.userAdmin) {
return Users
} else if (state.token && state.userRestaurateur) {
return HomeRestaurateur
}else if (state.token && state.userDeliverer) {
return Commands
}else {
return Home
}
}
},
{
path: "/login",
name: "login",
component: Login,
},
{
path: "/forgot-password",
name: "forgot_password",
component: ForgotPassword,
},
{
path: "/reset-password/:token",
name: "reset_password_token",
component: ResetPassword,
},
{
path: "/register",
name: "register",
component: Register,
},
{
path: "/profile",
name: "editProfile",
component: editProfile,
},
{
path: "/Restaurant/:id/Menu",
name: "Meals",
component: Meals,
},
{
path: "/admin/users",
name: "admin_users",
component: function () {
if (state.userAdmin) {
return Users
} else {
return Error403
}
}
},
{
path: "/admin/restaurants",
name: "admin_restaurants",
component: function () {
if (state.userAdmin) {
return Restaurants
} else {
return Error403
}
}
},
{
path: "/admin/restaurants_request",
name: "admin_restaurants_request",
component: function () {
if (state.userAdmin) {
return RestaurantsRequest
} else {
return Error403
}
}
},
{
path: "/restaurants/new",
name: "create_restaurants",
component: CreateRestaurant,
},
{
path: "/admin/reports",
name: "admin_reports",
component: function () {
if (state.userAdmin) {
return Reports
} else {
return Error403
}
}
},
{
path: "/orders",
name: "orders",
component: Commands,
},
{
path: "/:pathMatch(.*)*",
name: "not_found",
component: Error404,
}
],
});
I tried checking if other methods were working correctly, tried to change server, nothing just seems to work.

VUE nested route gives the empty page

My routine returns an empty page for the children's route. Checked on the web, but can't find anything useful. I have the following setup.
Vue routes in the same index.js file
{
path: "/admin",
name: "Admin",
component: Admin,
children:[
{
path: "/scheduler",
name: "Scheduler",
component: Scheduler,
meta: {
role: "user",
middleware: [auth],
requiresAuth: true,
},
},
],
meta: {
role: "user",
middleware: [auth],
requiresAuth: true,
},
},
my beforeEach :
router.beforeEach((to, from, next) => {
if (to.matched.some((record) => record.meta.requiresAuth)) {
if (window.localStorage.getItem("token") == null) {
next({
path: "/login",
query: {
redirect: to.fullPath,
},
});
} else {
const localData = JSON.parse(window.localStorage.getItem("user")).role;
const middleware = to.meta.middleware;
const context = { to, from, next };
//If there is no error from Auth, Unauthorized
if (store.getters.errorDetails == null) {
middleware[0]({ ...context }).then(() => {
if (localData == "user" && to.meta.role == "user") {
if (to.meta.role == "admin") {
next("/user");
}
next("/user");
} else if (localData == "admin" && to.meta.role == "admin") {
if (to.meta.role == "user") {
next("/admin");
} else {
next("/admin");
}
} else {
next("/login");
}
});
}
}
} else {
next();
}
});
and I can see the following screen. Not sure what I am doing wrong. Any help is appreciated.
enter image description here

vue-router : Navigation not routing to correct path

I am using vuex and vue-router. I have a client's zone, when you try to loggin, you should go to the profil. But it's not happend.
routes: [
{
path: "/area-do-cliente",
name: "customerZone",
redirect: "/area-do-cliente/profile",
component: () =>
import(
/* webpackChunkName: "ClientZone" */ "#/scenes/ClientZone/views/ClientZone.vue"
),
children: [
{
path: "login",
name: "login",
component: () => import("#/scenes/ClientZone/components/LogIn.vue"),
props: true,
meta: { clientZoneLogin: true }
},
{
path: "profile",
name: "profile",
component: () => import("#/scenes/ClientZone/components/Profile.vue"),
meta: { clientZoneAuthRequired: true, clientZoneLogin: true },
props: true
},
]
}
]
router.beforeEach((to, from, next) => {
if (to.matched.some(_to => _to.meta.clientZoneLogin))
if (store.getters.personData.status == "1") {
console.log("01");
router({ name: "profile" });
} else {
console.log("2");
next();
}
} else {
console.log("3");
next();
}
}
});
So I still have in console => 2. It is mean that I pass the first condition, but I shouldnt. I have status 1, and the response of this data is when you click the login button (there is a event).
methods: {
doLogin: function() {
this.error = "";
let loginData = {
login: this.login,
password: this.password
};
this.isLoading = true;
this.errorMessage = "";
co.postLogin(loginData)
.then(data => {
this.$store.commit("personData", data.data); // here I push data to store
)}
}
}
Any ideas where is mistake?

Computed property depends on vuex store. How to update the cached value?

The value of this.$store.state.Auth.loginToken is modified by one of its child components. The initial value of this.$store.state.Auth.loginToken is undefined. But still, the update in its value has no effect in the cached value of navItems thus it always returns the second value.
computed: {
navItems () {
return this.$store.state.Auth.loginToken != undefined ?
this.items.concat([
{ icon: 'add', title: 'Add new journal entry', to: '/' },
{ icon: 'power_settings_new', title: 'Logout', to: '/logout'}
]) :
this.items.concat([
{ icon: 'play_arrow', title: 'Login', to: '/login' }
])
}
}
Is there a better way to keep a watch on this.$store.state.Auth.loginToken so that it can be used same as navItems?
I created a basic example of how you can use vuex getters and Auth token (codepen):
const mapGetters = Vuex.mapGetters;
var store = new Vuex.Store({
state: {
Auth: {
loginToken: ''
},
menuItems: [
{ icon: 'home', title: 'Home', to: '/' },
{ icon: 'about', title: 'About', to: '/about' },
{ icon: 'contact', title: 'Contact', to: '/contact' }
]
},
mutations: {
SET_LOGIN_TOKEN(state, data) {
state.Auth.loginToken = 1
}
},
getters: {
menuItems(state, getters) {
if(state.Auth.loginToken !== '') {
return state.menuItems.concat([{
icon: 'profile', title: 'Profile', to: '/profile'
}])
}
return state.menuItems
},
loggedIn(state) {
return state.Auth.loginToken !== ''
}
},
actions: {
doLogin({commit}) {
commit('SET_LOGIN_TOKEN', 1)
}
}
});
new Vue({
el: '#app',
store,
data: function() {
return {
newTodoText: "",
doneFilter: false
}
},
methods: {
login() {
this.$store.dispatch('doLogin')
}
},
computed: {
...mapGetters(['menuItems', 'loggedIn'])
}
})
This is just an example so you can ignore the actual login action. Also, the store should be a directory, the getters, mutations and actions should have their own files which are then imported in the index.js in the store like in this example

aurelia redirect line gives error "ERROR [app-router] Error: Unable to find module with ID: not-found"

I have been implementing an authorization step which I modeled on THIS question's answer by fragsalat.
Everything works until it reaches the line
return new Redirect('login');
upon which I get the error:
aurelia-logging-console.js:47 ERROR [app-router] Error: Expected router pipeline to return a navigation result, but got [{"url":"login","options":{"trigger":true,"replace":true},"shouldContinueProcessing":false}] instead.
at processResult (aurelia-router.js:1761)
at aurelia-router.js:1725
at <anonymous>
I am not sure why this has not just redirected?
This is the full app.ts file so you might see the context:
import { Aurelia, PLATFORM, autoinject } from "aurelia-framework";
import {
Redirect,
NavigationInstruction,
Router,
RouterConfiguration,
Next
} from "aurelia-router";
import { AuthService } from "../../auth/auth-service";
//import { Clients } from '../../public/components/login/login'
#autoinject
export class App {
public router: Router;
private TOKEN_KEY = "session";
configureRouter(config: RouterConfiguration, router: Router): void {
this.router = router;
config.title = "Aurelia";
config.addAuthorizeStep(AuthorizeStep);
config.map([
{
route: ["", "scheduler"],
name: "scheduler",
settings: {
icon: "scheduler",
auth: true,
roles: ["Employee", "Admin"]
},
moduleId: PLATFORM.moduleName("../components/scheduler/scheduler"),
nav: true,
title: "scheduler"
},
{
route: "clients",
name: "clients",
moduleId: PLATFORM.moduleName(
"../components/clients/clientList/clientList"
),
title: "Clients",
nav: true,
settings: {
nav: [
{ href: "#clients/clientsList", title: "Client List" },
{ href: "#clients/Create", title: "Create Client" }
],
auth: true,
roles: ["Employee", "Admin"],
pos: "left"
}
},
{
route: "clients/ClientsList",
name: "clientList",
moduleId: PLATFORM.moduleName(
"../components/clients/clientList/clientList"
),
settings: {
auth: true,
roles: ["Employee", "Admin"]
}
},
{
route: "clients/create",
name: "aboutTeam",
moduleId: PLATFORM.moduleName(
"../components/clients/clientCreate/clientCreate"
),
settings: {
auth: true,
roles: ["Employee", "Admin"]
}
},
{
route: "logout",
name: "logout",
settings: {
icon: "user",
auth: true,
roles: ["Employee", "Admin"],
pos: "right"
},
moduleId: PLATFORM.moduleName("../components/auth/logout/logout"),
nav: true,
title: "Logout"
},
{
route: "not-found",
name: "not-found",
settings: {
auth: true,
roles: ["Employee", "Admin"]
},
moduleId: PLATFORM.moduleName("../components/notFound/notFound"),
nav: false,
title: "Not Found"
},
{
route: "login",
name: "login",
settings: {
icon: "user",
auth: true,
roles: ["Employee", "Admin"],
pos: "right"
},
moduleId: PLATFORM.moduleName("../../public/components/login/login"),
nav: true,
title: "login"
}
]);
config.mapUnknownRoutes("not-found");
}
}
#autoinject
class AuthorizeStep {
private endDate: any;
static loginFragment = '../../public/components/login/login';
constructor(
private authService: AuthService,
private router: Router,
private aurelia: Aurelia
) { }
run(navigationInstruction: NavigationInstruction, next: Next): Promise<any> {
return Promise.resolve()
.then(() => this.checkAuthentication(navigationInstruction, next))
.then(result => result || this.checkAuthorization(navigationInstruction, next))
.then(result => result || this.checkOrigin(navigationInstruction, next))
.then(result => result || next());
}
checkAuthentication(navigationInstruction, next) {
// Do we have a JWT?
const session = this.authService.getIdentity();
if (!session) {
this.forceReturnToPublic(next); // No JWT - back to the public root.
}
console.log("CHECKaUTHENTICATION: ", navigationInstruction.getAllInstructions().some(i => i.config.settings.auth) )
if (navigationInstruction.getAllInstructions().some(i => i.config.settings.auth)) {
// Is the token valid?
if (this.authService.hasTokenExpired(session)) {
const currentUrl = navigationInstruction.fragment + (navigationInstruction.queryString ? `?${navigationInstruction.queryString}` : '');
console.log("FRAGMENT: ", navigationInstruction.fragment);
console.log("NAVIGATE INSTRUCTION: ", navigationInstruction)
console.log('currentURL: ', currentUrl);
localStorage.setItem('origin', currentUrl);
console.log("AuthorizeStep.loginFragment", AuthorizeStep.loginFragment)
next.cancel();
console.log("and it gets here!");
return new Redirect('login');
}
}
}
checkAuthorization(navigationInstruction, next) {
var usersRole = this.authService.getUserRole();
let requiredRoles = navigationInstruction.getAllInstructions()
.map(i => i.config.settings.roles)[0];
console.log("route Roles: ", requiredRoles);
let isUserPermited = requiredRoles ? requiredRoles.some(r => r === usersRole) : true;
console.log("isUserPermited: ", isUserPermited);
if (!isUserPermited) {
this.forceReturnToPublic(next);
}
}
checkOrigin(instruction, next) {
const origin = localStorage.getItem('origin');
// Check if we were not redirected to login page and have an origin
if (instruction.fragment !== AuthorizeStep.loginFragment && origin) {
localStorage.removeItem('origin');
return next.cancel(new Redirect(origin));
}
}
forceReturnToPublic(next) {
if (localStorage.getItem('origin')) {
localStorage.removeItem('origin') // Just in case we had origin set.
}
next.cancel();
this.authService.clearIdentity();
this.router.navigate("/", { replace: true, trigger: false });
this.router.reset();
this.aurelia.setRoot("public/public/public");
}
}
In all other pipeline steps you're using return next.cancel(new Redirect()), it should be the same case, as the pipeline step expects a Next as a return value, but you return a Redirect here.
Try changing it to
return next.cancel(new Redirect('login'));