I am using Auth0 for authentication and have the navbar changing state based on being authenticated or not, as well as checking if the user is the proper role.
Disclaimer: This was tossed together quickly and could probably be done better, but it is working for me at this point and is just one way of doing it.
In app.ts I have setup the router map with two additional properties called auth and roles.
auth is a boolean with true meaning the user must be authenticated to see it.
roles is a string[] containing the user required roles to view the nav item
Here are a couple of examples of what I am using there
{
route: ['edit-member/:id'],
name: 'edit-member',
moduleId: PLATFORM.moduleName('./pages/edit-member'),
nav: false,
title: 'Edit Member',
auth: true,
},
{
route: ['manage-members/:id?'],
name: 'manage-members',
moduleId: PLATFORM.moduleName('./pages/manage-members'),
nav: true,
title: 'Members',
auth: true,
roles: ["instructor", "manager", "admin"],
href: 'manage-members/0'
},
In my auth service I send events on login successful, and logoff that will change the navbar items displayed.
Here is the code for nav-bar.ts
import { inject } from 'aurelia-framework';
import * as log from 'toastr';
import { Router } from 'aurelia-router';
import { AuthService } from 'services/auth-service';
import { EventAggregator } from 'aurelia-event-aggregator';
@inject(Router, EventAggregator, BindingSignaler, AuthService)
export class NavBar
{
subLoginComplete: any;
subLogoffComplete: any;
routes = [];
isAuthenticated: boolean = false;
constructor(public router: Router, private ea: EventAggregator, private authService: AuthService)
{
console.log("NavBar Constructor");
this.subLoginComplete = this.ea.subscribe("LoginComplete", () =>
{
console.log("NavBar LoginComplete signal");
this.isAuthenticated = this.authService.isAuthenticated();
this.changeRoutes();
});
this.subLogoffComplete = this.ea.subscribe("LogoffComplete", () =>
{
console.log("NavBar LogoffComplete signal");
this.isAuthenticated = this.authService.isAuthenticated();
this.changeRoutes();
});
}
attached()
{
this.routes = this.router.navigation;
this.changeRoutes();
}
dispose()
{
this.subLoginComplete.dispose();
this.subLogoffComplete.dispose();
}
private changeRoutes()
{
this.routes = [];
this.routes = this.router.navigation;
}
showNav(navItem)
{
console.log("showNav: " + navItem.config.name);
if (!navItem.config.roles)
{
console.log("no roles define, return true");
return true;
}
let enable: boolean = this.authService.isAuthorized(navItem.config.roles);
console.log(navItem.config.name + " " + (enable ? "enabled" : "disabled"));
return enable;
}
login()
{
this.authService.login();
}
logout()
{
this.authService.logout();
}
}
Next is the html for the navbar, and the magic happens in the authFilter value convertor
<template>
<require from="../value-converters/auth-filter"></require>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<a class="navbar-brand" href="#">The Flight Hangar</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li repeat.for="row of routes | authFilter" class="nav-item ${row.isActive ? 'active' : ''}">
<a class="nav-link" href.bind="row.href">${row.title}</a>
</li>
</ul>
<ul class="navbar-nav pull-right">
<li class="nav-item" click.delegate="login()" show.bind="!isAuthenticated">
<a class="nav-link">Log In</a>
</li>
<li class="nav-item" href="#" click.delegate="logout()" show.bind="isAuthenticated">
<a class="nav-link" href="#">${authService.currentUser.name} - Log Out</a>
</li>
</ul>
</div>
</nav>
</template>
Finally here is the authfilter code that determines if the item should be displayed or not.
import { Router } from "aurelia-router";
import { AuthService } from "services/auth-service";
import { inject } from "aurelia-framework";
@inject(Router, AuthService)
export class AuthFilterValueConverter
{
constructor(public router: Router, private authService: AuthService)
{
console.log("NavBar Constructor");
}
showNav(navItem) : boolean
{
console.log("showNav: " + navItem.config.name);
if (!navItem.config.roles)
{
console.log("no roles define, return true");
return true;
}
let enable: boolean = this.authService.isAuthorized(navItem.config.roles);
console.log(navItem.config.name + " " + (enable ? "enabled" : "disabled"));
return enable;
}
toView(routes)
{
return routes.filter(r => this.showNav(r));
}
}
Hopefully this might get you started.