-
Notifications
You must be signed in to change notification settings - Fork 61
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[SDK-1778] Add AuthGuard to protect unauthenticated users from access…
…ing certain routes (#16) * Add auth guard and spec * Add guard to auth module * Add guard to playground * Add review suggestions * Wrap navigateByUrl in a setTimeout Otherwise, the call to `navigateByUrl` appears to never complete and the redirect never happens. Co-authored-by: Steve Hobbs <[email protected]> Co-authored-by: Steve Hobbs <[email protected]>
- Loading branch information
1 parent
17790bf
commit 0c1c47f
Showing
17 changed files
with
180 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { of } from 'rxjs'; | ||
import { AuthGuard } from './auth.guard'; | ||
|
||
describe('AuthGuard', () => { | ||
let authServiceMock: any; | ||
let guard: AuthGuard; | ||
const routeMock: any = { snapshot: {} }; | ||
const routeStateMock: any = { snapshot: {}, url: '/' }; | ||
|
||
it('should return true for a logged in user', () => { | ||
authServiceMock = { | ||
isAuthenticated$: of(true), | ||
loginWithRedirect: jasmine.createSpy('loginWithRedirect'), | ||
}; | ||
guard = new AuthGuard(authServiceMock); | ||
const listener = jasmine.createSpy(); | ||
guard.canActivate(routeMock, routeStateMock).subscribe(listener); | ||
expect(authServiceMock.loginWithRedirect).not.toHaveBeenCalled(); | ||
expect(listener).toHaveBeenCalledWith(true); | ||
}); | ||
|
||
it('should redirect a logged out user', () => { | ||
authServiceMock = { | ||
isAuthenticated$: of(false), | ||
loginWithRedirect: jasmine.createSpy('loginWithRedirect'), | ||
}; | ||
guard = new AuthGuard(authServiceMock); | ||
guard.canActivate(routeMock, routeStateMock).subscribe(); | ||
expect(authServiceMock.loginWithRedirect).toHaveBeenCalledWith({ | ||
appState: { target: '/' }, | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { Injectable } from '@angular/core'; | ||
import { | ||
ActivatedRouteSnapshot, | ||
RouterStateSnapshot, | ||
CanActivate, | ||
} from '@angular/router'; | ||
import { Observable, of } from 'rxjs'; | ||
import { tap } from 'rxjs/operators'; | ||
import { AuthService } from './auth.service'; | ||
|
||
@Injectable({ | ||
providedIn: 'root', | ||
}) | ||
export class AuthGuard implements CanActivate { | ||
constructor(private auth: AuthService) {} | ||
|
||
canActivate( | ||
next: ActivatedRouteSnapshot, | ||
state: RouterStateSnapshot | ||
): Observable<boolean> { | ||
return this.auth.isAuthenticated$.pipe( | ||
tap((loggedIn) => { | ||
if (!loggedIn) { | ||
this.auth.loginWithRedirect({ appState: { target: state.url } }); | ||
} else { | ||
return of(true); | ||
} | ||
}) | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,24 @@ | ||
import { NgModule } from '@angular/core'; | ||
import { Routes, RouterModule } from '@angular/router'; | ||
import { ProtectedComponent } from './protected/protected.component'; | ||
import { AuthGuard } from 'projects/auth0-angular/src/lib/auth.guard'; | ||
import { UnprotectedComponent } from './unprotected/unprotected.component'; | ||
|
||
|
||
const routes: Routes = []; | ||
const routes: Routes = [ | ||
{ | ||
path: 'protected', | ||
component: ProtectedComponent, | ||
canActivate: [AuthGuard], | ||
}, | ||
{ | ||
path: '', | ||
component: UnprotectedComponent, | ||
pathMatch: 'full', | ||
}, | ||
]; | ||
|
||
@NgModule({ | ||
imports: [RouterModule.forRoot(routes)], | ||
exports: [RouterModule] | ||
exports: [RouterModule], | ||
}) | ||
export class AppRoutingModule { } | ||
export class AppRoutingModule {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<p>This route is protected!</p> |
24 changes: 24 additions & 0 deletions
24
projects/playground/src/app/protected/protected.component.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; | ||
|
||
import { ProtectedComponent } from './protected.component'; | ||
|
||
describe('ProtectedComponent', () => { | ||
let component: ProtectedComponent; | ||
let fixture: ComponentFixture<ProtectedComponent>; | ||
|
||
beforeEach(async(() => { | ||
TestBed.configureTestingModule({ | ||
declarations: [ProtectedComponent], | ||
}).compileComponents(); | ||
})); | ||
|
||
beforeEach(() => { | ||
fixture = TestBed.createComponent(ProtectedComponent); | ||
component = fixture.componentInstance; | ||
fixture.detectChanges(); | ||
}); | ||
|
||
it('should create', () => { | ||
expect(component).toBeTruthy(); | ||
}); | ||
}); |
12 changes: 12 additions & 0 deletions
12
projects/playground/src/app/protected/protected.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { Component, OnInit } from '@angular/core'; | ||
|
||
@Component({ | ||
selector: 'app-protected', | ||
templateUrl: './protected.component.html', | ||
styleUrls: ['./protected.component.css'], | ||
}) | ||
export class ProtectedComponent implements OnInit { | ||
constructor() {} | ||
|
||
ngOnInit(): void {} | ||
} |
Empty file.
1 change: 1 addition & 0 deletions
1
projects/playground/src/app/unprotected/unprotected.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<p>This route is unprotected!</p> |
24 changes: 24 additions & 0 deletions
24
projects/playground/src/app/unprotected/unprotected.component.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; | ||
|
||
import { UnprotectedComponent } from './unprotected.component'; | ||
|
||
describe('UnprotectedComponent', () => { | ||
let component: UnprotectedComponent; | ||
let fixture: ComponentFixture<UnprotectedComponent>; | ||
|
||
beforeEach(async(() => { | ||
TestBed.configureTestingModule({ | ||
declarations: [UnprotectedComponent], | ||
}).compileComponents(); | ||
})); | ||
|
||
beforeEach(() => { | ||
fixture = TestBed.createComponent(UnprotectedComponent); | ||
component = fixture.componentInstance; | ||
fixture.detectChanges(); | ||
}); | ||
|
||
it('should create', () => { | ||
expect(component).toBeTruthy(); | ||
}); | ||
}); |
12 changes: 12 additions & 0 deletions
12
projects/playground/src/app/unprotected/unprotected.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { Component, OnInit } from '@angular/core'; | ||
|
||
@Component({ | ||
selector: 'app-unprotected', | ||
templateUrl: './unprotected.component.html', | ||
styleUrls: ['./unprotected.component.css'], | ||
}) | ||
export class UnprotectedComponent implements OnInit { | ||
constructor() {} | ||
|
||
ngOnInit(): void {} | ||
} |