+++ /dev/null
-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);
- }
-}
-
+++ /dev/null
-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();
- }
-}
-
-<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>
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';
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
) {}
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.
import { Injectable } from '@angular/core';
+import { Location } from '@angular/common';
import { Observable, Observer } from 'rxjs/Rx';
import { Router, Resolve, RouterStateSnapshot,
ActivatedRouteSnapshot } from '@angular/router';
constructor(
private router: Router,
+ private ngLocation: Location,
private egStore: EgStoreService,
private egNet: EgNetService,
private egAuth: EgAuthService
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]);
}
loadStartupData(observer: Observer<any>): Promise<void> {
+ console.log('EgStaffResolver:loadStartupData()');
return Promise.resolve();
}
}
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';
resolve: {staffResolver : EgStaffResolver},
children: [{
path: '',
- redirectTo: 'splash', // must be to sibling path
+ redirectTo: 'splash',
pathMatch: 'full',
}, {
path: 'login',
imports: [ RouterModule.forChild(routes) ],
exports: [ RouterModule ],
providers: [
- EgStaffResolver,
-// EgStaffDataResolver
+ EgStaffResolver
]
})
* 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]);
}
}