How can I restrict app pages until a user has been authenticated using my PolymerFire authentication system?

590 Views Asked by At

I currently have a working PolymerFire authentication system where I can login and create users with an email and password. My login and sign up pages are currently just another page within my app.

I would like to take these pages and have them be the only pages accessible to a user who is not logged in. Once logged in, I would like to hide these authentication pages and allow them to use the rest of my app's pages.

Here is some relevant code:

my-app.html

<app-location route="{{route}}"></app-location>
<app-route
    route="{{route}}"
    pattern="/:page"
    data="{{routeData}}"
    tail="{{subroute}}"></app-route>

<app-drawer-layout fullbleed force-narrow>
  <!-- Drawer content -->
  <app-drawer align="end" id="drawer" >
    <app-toolbar>Menu</app-toolbar>
    <iron-selector selected="[[page]]" attr-for-selected="name" class="drawer-list" role="navigation">
      <a name="home" href="/home" hidden$="{{computeLogoutHidden(statusKnown, user)}}">Home</a>
      <a name="video-gate-builder" href="/video-gate-builder">Video Gate Builder</a>
      <a name="video-survey-builder" href="/video-survey-builder">Video Survey Builder</a>
      <a name="login" href="/login">Login</a>
      <a name="sign-up" href="/sign-up">Sign Up</a>
      More Features Coming Soon!
    </iron-selector>
  </app-drawer>

  <!-- Main content -->
  <app-header-layout has-scrolling-region>

    <app-header condenses reveals effects="waterfall">
      <app-toolbar>
        <img id="logo" src="../images/vidvision-icon-white.png">
        <div main-title>Vidvision</div>
        <span style="flex: 1;"></span>
        <p>{{computeLoginStatus(statusKnown, user)}}</p>
        <paper-icon-button icon="my-icons:menu" drawer-toggle></paper-icon-button>
      </app-toolbar>
    </app-header>

    <iron-pages
        selected="[[page]]"
        attr-for-selected="name"
        fallback-selection="view404"
        role="main">
      <my-home name="home" hidden$="{{computeLogoutHidden(statusKnown, user)}}"></my-home>
      <my-video-gate-builder name="video-gate-builder"></my-video-gate-builder>
      <my-video-survey-builder name="video-survey-builder"></my-video-survey-builder>
      <my-login name="login"></my-login>
      <my-sign-up name="sign-up"></my-sign-up>
      <my-view404 name="view404"></my-view404>
    </iron-pages>
  </app-header-layout>
</app-drawer-layout>

my-app.js

Polymer({
  is: 'my-app',

  properties: {
    page: {
      type: String,
      reflectToAttribute: true,
      observer: '_pageChanged',
    },
  },

  observers: [
    '_routePageChanged(routeData.page)',
  ],

  _routePageChanged: function(page) {
    this.page = page || 'home';

    if (!this.$.drawer.persistent) {
      this.$.drawer.close();
    }
  },

  _pageChanged: function(page) {
    // Load page import on demand. Show 404 page if fails
    var resolvedPageUrl = this.resolveUrl('my-' + page + '.html');
    this.importHref(resolvedPageUrl, null, this._showPage404, true);
  },

  _showPage404: function() {
    this.page = 'view404';
  },

my-login.html

<firebase-auth id="auth" user="{{user}}" status-known="{{statusKnown}}" location="https://vidvission.firebaseio.com" provider="{{provider}}" on-error="errorHandler" on-user-created="userSuccessHandler" on-password-changed="userSuccessHandler" on-password-reset="userSuccessHandler" on-user-removed="userSuccessHandler"></firebase-auth>

<app-location route="{{route}}"></app-location>
<div id="background">
<img id="logo" src="../images/vidvision-icon-white.png">
<div class="card">
  <div id="paddingCont">
    <label class="labels" for="email">Email</label>
    <input class="inputStyles" value="{{email::input}}">
    <label class="labels" for="password">Password</label>
    <input class="inputStyles" type="password" value="{{password::input}}">
    <div class="buttonCont">
      <div class="col-left">
        <button class="login" on-tap="login" hidden$="{{computeLoginHidden(statusKnown, user)}}">LOG IN</button>
        <button class="login" on-tap="logout" hidden$="{{computeLogoutHidden(statusKnown, user)}}">LOG OUT</button>
      </div>
      <div class="col-right">
        <a id="signUp" href="/sign-up">SIGN UP</a>
      </div>
    </div>
  </div>
</div>
<a id="forgotPassword"><p>Forgot Password?</p></a>


<div id="message">[[message]]</div>
<br>
<h3>Login status:</h3>
<p>{{computeLoginStatus(statusKnown, user)}}</p>

<h3>User ID:</h3>
<pre>{{user.uid}}</pre>
</div>

my-login.js

Polymer({
is: 'my-login',
properties: {
  provider: {
    type: String,
    value: 'anonymous'
  },
  message: {
    type: String,
    value: ''
  },
  email: {
    type: String,
    value: ''
  },
  password: {
    type: String,
    value: ''
  },
  user: {
    type: Object,
    value: null
  },
  statusKnown: {
    type: Boolean
  },
},
login: function() {
  this.$.auth.signInWithEmailAndPassword(this.email, this.password);
},
logout: function() {
  this.$.auth.signOut();
},
errorHandler: function(e) {
  this.message = 'Error: ' + e.detail.message;
},
userSuccessHandler: function(e) {
  this.message = e.type + ' success!';
},
computeLoginHidden: function(statusKnown, user) {
  return !statusKnown || !!user;
},
computeLogoutHidden: function(statusKnown, user) {
  return !statusKnown || !user;
},
computeLoginStatus: function(statusKnown, user) {
  if (statusKnown && user) {
    this.set('route.path', '/home');
    return 'Logged in';
  }
  if (statusKnown) {
    return 'Logged out';
  }
  return 'Unknown (checking status...)';
},

I am very new to authentication systems so any advice or resource suggestions are welcome. I have found that there is not too much information on PolymerFire just yet. Thank you.

1

There are 1 best solutions below

0
On

Inside the element: <firebase-auth>
Add the property: signedIn=""
Bind it to a value: signedIn="{{isSignedIn}}"

<firebase-auth id="auth" user="{{user}}" provider="google" on-
error="handleError" signedIn="{{isSignedIn}}"></firebase-auth>

Add an observer

observers: [
    '_routePageChanged(routeData.page)',
    '_userNotSignedIn(isSignedIn)
  ],

Add a Function

_userNotSignedIn: function (isSignedIn) {
 if (isSignedIn === false) {
   this.page = 'view404'; // redirect the user to another page
                          // import an element that cover the view
 }
}