LP#626157 Ang2 experiments
authorBill Erickson <berickxx@gmail.com>
Thu, 23 Nov 2017 21:37:25 +0000 (16:37 -0500)
committerBill Erickson <berickxx@gmail.com>
Mon, 11 Dec 2017 17:39:51 +0000 (12:39 -0500)
Signed-off-by: Bill Erickson <berickxx@gmail.com>
Open-ILS/webby-src/src/app/staff/auth-guard.service.ts [deleted file]
Open-ILS/webby-src/src/app/staff/data-resolver.service.ts [deleted file]
Open-ILS/webby-src/src/app/staff/login.component.html
Open-ILS/webby-src/src/app/staff/login.component.ts
Open-ILS/webby-src/src/app/staff/resolver.service.ts
Open-ILS/webby-src/src/app/staff/routing.module.ts
Open-ILS/webby-src/src/app/staff/staff.component.ts

diff --git a/Open-ILS/webby-src/src/app/staff/auth-guard.service.ts b/Open-ILS/webby-src/src/app/staff/auth-guard.service.ts
deleted file mode 100644 (file)
index 4d8d7c0..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-import { Injectable } from '@angular/core';
-import { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot,
-    CanActivateChild } from '@angular/router';
-import { EgStoreService } from '@eg/core/store.service';
-import { EgAuthService } from '@eg/core/auth.service';
-
-/**
- * Confirm we have a valid auth token before allowing access
- * any staff pages (except for login).
- */
-
-@Injectable()
-export class EgStaffAuthGuard implements CanActivate, CanActivateChild {
-
-    readonly WS_ADMIN_PATH = '/staff/admin/workstation/workstations';
-
-    constructor(
-        private router: Router,
-        private egStore: EgStoreService,
-        private egAuth: EgAuthService 
-    ) {}
-
-    canActivate(
-        route: ActivatedRouteSnapshot, 
-        state: RouterStateSnapshot): Promise<boolean> {
-
-        console.debug(`EgStaffAuthGuard:canActivate() path ${state.url}`);
-
-        // Staff cookies stay in /$base/staff/
-        // TODO dynamic
-        this.egStore.loginSessionBasePath = '/webby/staff'; 
-
-        // Any and all are allowed access to the login page.
-        if (state.url == '/staff/login') return Promise.resolve(true);
-
-        // canActivate() always resolves to true, but may redirect
-        // the caller to the appropriate auth pages along the way.
-        return new Promise((resolve, error) => {
-            this.egAuth.testAuthToken().then(
-                ok  => { 
-                    if (ok.invalidWorkstation
-                        && state.url != this.WS_ADMIN_PATH
-                    ) {
-                        // Login is valid, but workstation is unknown
-                        // to this browser.  Send the caller to the
-                        // workstation admin page.
-                        this.router.navigate([this.WS_ADMIN_PATH]);
-                    } 
-                    resolve(true); 
-                },
-                notOk => {
-                    console.debug('No valid auth token, sending to login.');
-                    this.egAuth.redirectUrl = state.url;
-                    this.router.navigate(['/staff/login']);
-                    resolve(true); 
-                }
-            );
-        });
-    }
-
-    canActivateChild(
-        route: ActivatedRouteSnapshot, 
-        state: RouterStateSnapshot): Promise<boolean> {
-        console.log('canActivateChild()');
-        return this.canActivate(route, state);
-    }
-}
-
diff --git a/Open-ILS/webby-src/src/app/staff/data-resolver.service.ts b/Open-ILS/webby-src/src/app/staff/data-resolver.service.ts
deleted file mode 100644 (file)
index 474ff8e..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-import { Injectable } from '@angular/core';
-import { Router, Resolve, RouterStateSnapshot,
-         ActivatedRouteSnapshot } from '@angular/router';
-import { Observable, Observer } from 'rxjs/Rx';
-import { EgAuthService } from '@eg/core/auth.service';
-import { EgNetService } from '@eg/core/net.service';
-
-/**
- * Verify authentication info and load common startup data.
- */
-@Injectable()
-export class EgStaffDataResolver implements Resolve<Observable<any>> {
-
-    private WS_ADMIN_URL = '/staff/admin/workstation/workstations';
-
-    constructor(
-        private router: Router, 
-        private egNet: EgNetService,
-        private egAuth: EgAuthService
-    ) {}
-
-    resolve(
-        route: ActivatedRouteSnapshot, 
-        state: RouterStateSnapshot): Observable<any> {
-
-        console.debug('EgStaffDataResolver:resolve()');
-
-        // Listen for auth timeout failures
-        this.egNet.authExpired$.subscribe(
-            uhOh => {
-                console.log('Auth session has expired.  Send to login');
-                this.egAuth.redirectUrl = this.router.url;
-                this.router.navigate(['/staff/login']);
-            }
-        );
-
-        return Observable.create(observer => {
-            console.debug('auth token => ' + this.egAuth.token());
-
-            this.checkAuth().then(
-                ok => {
-                    this.loadStartupData(observer);
-                    // route resolvers require at least one observable event.
-                    // until we emit other data, just return true.
-                    observer.next(true);
-                    observer.complete();
-                }, 
-                notOk => {
-                    // Auth-related re-routing occurs within checkAuth.
-                    observer.next(true);
-                    observer.complete();
-                }
-            );
-        });
-    }
-
-    // Resolves if the caller should continue, rejects otherwise.
-    checkAuth(): Promise<void> {
-        console.log('checkAuth()');
-        return new Promise((resolve, reject) => {
-            console.log('checkAuth(2');
-            this.egAuth.testAuthToken().then(
-                ok => {return this.egAuth.verifyWorkstation()},
-                notOk => {
-                    // No valid authtoken, redirect to login page
-                    this.egAuth.redirectUrl = this.router.url;
-                    this.router.navigate(['/staff/login']);
-                    reject();
-                }
-            ).then(
-                ok => {
-                    // workstation verified.
-                    resolve();
-                },
-                notOk => {
-                    console.log('checkAuth(3)');
-                    // Login was valid, but we don't know about the
-                    // workstation used.
-                    if (this.router.url != this.WS_ADMIN_URL) {
-                    console.log('checkAuth(4) ' + this.router.url);
-                        this.router.navigate([this.WS_ADMIN_URL]);
-                    }
-                    reject();
-                }
-            );
-        });
-    }
-
-    loadStartupData(observer: Observer<any>): Promise<void> {
-        return Promise.resolve();
-    }
-}
-
index 705eede..73a6b38 100644 (file)
@@ -1,40 +1,38 @@
-<div class="container">
-  <div class="row">
-    <div class="col-md-6 offset-md-3">
-      <fieldset>
-        <legend i18n>Sign In</legend>
-        <hr/>
-        <form (ngSubmit)="handleSubmit()" #loginForm="ngForm">
+<div class="row" style="margin-top: 60px;"><!-- why margin needed? -->
+  <div class="col-md-6 offset-md-3">
+    <fieldset>
+      <legend i18n>Sign In</legend>
+      <hr/>
+      <form (ngSubmit)="handleSubmit()" #loginForm="ngForm">
 
-          <div class="form-group">
-            <label for="username" i18n>Username</label>
-            <input 
-              type="text" 
-                class="form-control" 
-                id="username" 
-                name="username"
-                required
-                i18n-placeholder
-                placeholder="Username" 
-                [(ngModel)]="args.username"/>
-          </div>
-
-          <div class="form-group">
-            <label for="password" i18n>Password</label>
-            <input 
-              type="password" 
-              class="form-control"
-              id="password" 
-              name="password"
+        <div class="form-group">
+          <label for="username" i18n>Username</label>
+          <input 
+            type="text" 
+              class="form-control" 
+              id="username" 
+              name="username"
               required
               i18n-placeholder
-              placeholder="Password" 
-              [(ngModel)]="args.password"/>
-          </div>
+              placeholder="Username" 
+              [(ngModel)]="args.username"/>
+        </div>
+
+        <div class="form-group">
+          <label for="password" i18n>Password</label>
+          <input 
+            type="password" 
+            class="form-control"
+            id="password" 
+            name="password"
+            required
+            i18n-placeholder
+            placeholder="Password" 
+            [(ngModel)]="args.password"/>
+        </div>
 
-          <button type="submit" class="btn btn-primary" i18n>Sign in</button>
-        </form>
-      </fieldset>
-    </div>
+        <button type="submit" class="btn btn-primary" i18n>Sign in</button>
+      </form>
+    </fieldset>
   </div>
 </div>
index ca2b2f8..7886575 100644 (file)
@@ -1,4 +1,5 @@
 import { Component, OnInit, Renderer } from '@angular/core';
+import { Location } from '@angular/common';
 import { Router } from '@angular/router';
 import { EgAuthService, EgAuthWsState } from '@eg/core/auth.service';
 
@@ -12,14 +13,15 @@ export class EgStaffLoginComponent implements OnInit {
       username : '',
       password : '',
       type : 'staff',
-      workstation : ''
-      //workstation :  'BR1-skiddoo' // testing
+      //workstation : ''
+      workstation :  'BR1-skiddoo' // testing
     };
 
     workstations = [];
 
     constructor(
       private router: Router,
+      private ngLocation: Location,
       private renderer: Renderer,
       private egAuth: EgAuthService
     ) {}
@@ -46,9 +48,14 @@ export class EgStaffLoginComponent implements OnInit {
                 if (this.egAuth.workstationState == EgAuthWsState.NOT_FOUND_SERVER) {
                     // User is logged in without a workstation.
                     // Redirect them to the WS admin page.
-                    url = '/staff/admin/workstation/workstations';
+                    this.router.navigate(
+                        ['/staff/admin/workstation/workstations']);
+                } else {
+                    // Force reload of the app after a successful login.
+                    // This allows the route resolver to re-run with a 
+                    // valid auth token and workstation.
+                    window.location.href = this.ngLocation.prepareExternalUrl(url);
                 }
-                this.router.navigate([url]);
             },
             notOk => {
                 // indicate failure in the UI.
index e8f975e..ac7841e 100644 (file)
@@ -1,4 +1,5 @@
 import { Injectable } from '@angular/core';
+import { Location } from '@angular/common';
 import { Observable, Observer } from 'rxjs/Rx';
 import { Router, Resolve, RouterStateSnapshot,
          ActivatedRouteSnapshot } from '@angular/router';
@@ -19,6 +20,7 @@ export class EgStaffResolver implements Resolve<Observable<any>> {
 
     constructor(
         private router: Router, 
+        private ngLocation: Location,
         private egStore: EgStoreService,
         private egNet: EgNetService,
         private egAuth: EgAuthService
@@ -31,39 +33,30 @@ export class EgStaffResolver implements Resolve<Observable<any>> {
         console.debug('EgStaffResolver:resolve()');
 
         // Staff cookies stay in /$base/staff/
-        this.egStore.loginSessionBasePath = '/webby/staff'; // TODO dynamic
+        this.egStore.loginSessionBasePath = 
+            this.ngLocation.prepareExternalUrl('/staff');
 
-        // Login resets everything.  No need to load any data.
+        // Login resets everything.  No need to load data.
         if (state.url == '/staff/login') return Observable.of(true);
 
-console.log('1');
-
         return Observable.create(observer => {
-console.log('2');
             this.egAuth.testAuthToken().then(
-                ok => {
-console.log('3');
-                    // Authtoken is OK.
+                tokenOk => {
                     this.egAuth.verifyWorkstation().then(
-                        ok => {
-console.log('4');
-                            // Workstation is OK.
+                        wsOk => {
                             this.loadStartupData(observer).then(
                                 ok => observer.complete()
                             );
                         },
-                        notOk => {
-console.log('5');
-                            // Workstation is not OK.
-                            if (state.url != this.wsAdminPath] {
+                        wsNotOk => {
+                            if (state.url != this.wsAdminPath) {
                                 this.router.navigate([this.wsAdminPath]);
                             }
                             observer.complete();
                         }
                     );
                 }, 
-                notOk => {
-console.log('6');
+                tokenNotOk => {
                     // Authtoken is not OK.
                     this.egAuth.redirectUrl = this.router.url;
                     this.router.navigate([this.loginPath]);
@@ -74,6 +67,7 @@ console.log('6');
     }
 
     loadStartupData(observer: Observer<any>): Promise<void> {
+        console.log('EgStaffResolver:loadStartupData()');
         return Promise.resolve();
     }
 }
index 83d86f2..31a42c3 100644 (file)
@@ -1,7 +1,6 @@
 import { NgModule } from '@angular/core';
 import { RouterModule, Routes } from '@angular/router';
 import { EgStaffResolver } from './resolver.service';
-//import { EgStaffDataResolver } from './data-resolver.service';
 import { EgStaffComponent } from './staff.component';
 import { EgStaffLoginComponent } from './login.component';
 import { EgStaffSplashComponent } from './splash.component';
@@ -15,7 +14,7 @@ const routes: Routes = [{
   resolve: {staffResolver : EgStaffResolver},
   children: [{
     path: '',
-    redirectTo: 'splash', // must be to sibling path
+    redirectTo: 'splash',
     pathMatch: 'full',
   }, {
     path: 'login',
@@ -36,8 +35,7 @@ const routes: Routes = [{
   imports: [ RouterModule.forChild(routes) ],
   exports: [ RouterModule ],
   providers: [ 
-    EgStaffResolver,
-//    EgStaffDataResolver
+    EgStaffResolver
   ]
 })
 
index e04aa29..5bfc81e 100644 (file)
@@ -50,15 +50,19 @@ export class EgStaffComponent implements OnInit {
      * have done their jobs.
      */
     basicAuthChecks(routeEvent: NavigationEnd): void {
-        if (!this.egAuth.token()) {
-            if (routeEvent.url != this.loginPath) {
-                this.router.navigate([this.loginPath]);
-            }
-        } else if (this.egAuth.workstationState != EgAuthWsState.VALID) {
-            if (routeEvent.url != this.wsAdminPath) {
-                this.router.navigate([this.wsAdminPath]);
-            }
-        }
+
+        // Access to login page is always granted
+        if (routeEvent.url == this.loginPath) return;
+
+        if (!this.egAuth.token()) 
+            this.router.navigate([this.loginPath]);
+
+        // Access to workstation admin page is granted regardless
+        // of workstation validity.
+        if (routeEvent.url == this.wsAdminPath) return;
+
+        if (this.egAuth.workstationState != EgAuthWsState.VALID)
+            this.router.navigate([this.wsAdminPath]);
     }
 }