Skip to content

Commit

Permalink
[okta-angular]: release 2.0.0 (#690)
Browse files Browse the repository at this point in the history
  • Loading branch information
aarongranick-okta authored Mar 7, 2020
1 parent aa3b154 commit 15b67a2
Show file tree
Hide file tree
Showing 20 changed files with 461 additions and 282 deletions.
26 changes: 26 additions & 0 deletions packages/okta-angular/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,29 @@
# 2.0.0

[#690](https://github.com/okta/okta-oidc-js/pull/690)

### Features

- `OktaCallbackComponent` will catch and display exceptions thrown from `handleAuthentication()`
- `onAuthRequired` callbacks will now receive the Angular injector as the 2nd parameter. This change allows logic using any services available within your application.

### Bug Fixes

- Saved URI is now stored in `sessionStorage` instead of `localStorage`. This fixes an issue which can occur when multiple instances of the app are loading at the same time.
- `OktaCallbackComponent` uses `window.location.replace()` to complete the login flow after `handleAuthentication` completes. This fixes an issue where the user could navigate back to the callback hander.

### Breaking Changes

- Signature for `onAuthRequired` callback functions has changed. Callbacks will receive the `OktaAuthService` as the first argument, and the Angular `Injector` as the second argument.
- Static initializer `OktaAuthModule.initAuth()` has been removed. `OKTA_CONFIG` should be provided directly by your module.
- `getFromUri` now returns an absolute URI as a string
- `setFromUri` takes a string. If it is a relative path, it will be converted to an absolute URI before being saved.
- Legacy config formats are no longer supported. See [Configuration Reference](https://github.com/okta/okta-auth-js#configuration-reference) for supported values.

### Other

- Upgrades `@okta/okta-auth-js` to version 3.0.0

# 1.4.0

### Features
Expand Down
13 changes: 8 additions & 5 deletions packages/okta-angular/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ If a user does not have a valid session, they will be redirected to the Okta Log

### `OktaCallbackComponent`

Handles the callback after the redirect. By default, it parses the tokens from the uri, stores them, then redirects to `/`. If a protected route (using [`OktaAuthGuard`](#oktaauthguard)) caused the redirect, then the callback redirects to the protected route. For more advanced cases, this component can be copied to your own source tree and modified as needed.
Handles the callback after the redirect. By default, it parses the tokens from the uri, stores them, then redirects to `/`. If a protected route (using [`OktaAuthGuard`](#oktaauthguard)) caused the redirect, then the callback will redirect back to the protected route. If an error is thrown while processing tokens, the component will display the error and not perform any redirect. This logic can be customized by copying the component to your own source tree and modified as needed. For example, you may want to capture or display errors differently or provide a helpful link for your users in case they encounter an error on the callback route. The most common error is the user does not have permission to access the application. In this case, they may be able to contact an administrator to obtain access.

You should define a route to handle the callback URL (`/implicit/callback` by default). Also add `OktaCallbackComponent` to the declarations section of in your `NgModule`.

Expand Down Expand Up @@ -220,7 +220,10 @@ import {
...
} from '@okta/okta-angular';

export function onAuthRequired(oktaAuth, router) {
export function onAuthRequired(oktaAuth, injector) {
// Use injector to access any service available within your application
const router = injector.get(Router);

// Redirect the user to your custom login page
router.navigate(['/custom-login']);
}
Expand Down Expand Up @@ -334,13 +337,13 @@ Parses the tokens returned as hash fragments in the OAuth 2.0 Redirect URI, then

Terminates the user's session in Okta and clears all stored tokens. Accepts an optional `uri` parameter to push the user to after logout.

#### `oktaAuth.setFromUri(uri, queryParams)`
#### `oktaAuth.setFromUri(uri)`

Used to capture the current URL state before a redirect occurs. Used primarily for custom [`canActivate`](https://angular.io/api/router/CanActivate) navigation guards.
Used to capture the current URL state before a redirect occurs. Used by custom [`canActivate`](https://angular.io/api/router/CanActivate) navigation guards.

#### `oktaAuth.getFromUri()`

Returns the stored URI and query parameters stored when the `OktaAuthGuard` and/or `setFromUri` was used.
Returns the URI stored when the `OktaAuthGuard` and/or `setFromUri` was used.

#### `oktaAuth.getTokenManager()`

Expand Down
4 changes: 2 additions & 2 deletions packages/okta-angular/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@okta/okta-angular",
"private": true,
"version": "1.4.0",
"version": "2.0.0",
"description": "Angular support for Okta",
"main": "./bundles/okta-angular.umd.js",
"module": "./fesm5/okta-angular.js",
Expand Down Expand Up @@ -40,7 +40,7 @@
"license": "Apache-2.0",
"dependencies": {
"@okta/configuration-validation": "^0.4.1",
"@okta/okta-auth-js": "^2.11.2",
"@okta/okta-auth-js": "^3.0.0",
"tslib": "^1.9.0"
},
"devDependencies": {
Expand Down
14 changes: 11 additions & 3 deletions packages/okta-angular/src/@types/okta__okta-auth-js/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
declare module '@okta/okta-auth-js';

declare interface TokenHash {
[key: string] : Token;
}
declare interface ParseFromUrlResponse {
tokens: TokenHash;
state: string;
}

declare interface TokenAPI {
getUserInfo(accessToken: Token): Promise;
getWithRedirect(params: object): Promise;
parseFromUrl(): Token[]
getUserInfo(accessToken?: AccessToken, idToken?: IDToken): Promise;
getWithRedirect(params?: object): Promise;
parseFromUrl(): ParseFromUrlResponse;
}

declare class OktaAuth {
Expand Down
2 changes: 1 addition & 1 deletion packages/okta-angular/src/okta-angular.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
export { OktaAuthModule } from './okta/okta.module';
export { OktaAuthGuard } from './okta/okta.guard';
export { OktaAuthService } from './okta/services/okta.service';
export { OKTA_CONFIG } from './okta/models/okta.config';
export { OktaConfig, OKTA_CONFIG } from './okta/models/okta.config';
export { UserClaims } from './okta/models/user-claims';

// Okta View Components
Expand Down
26 changes: 21 additions & 5 deletions packages/okta-angular/src/okta/components/callback.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,32 @@
* See the License for the specific language governing permissions and limitations under the License.
*/

import { Component } from '@angular/core';
import { Component, OnInit } from '@angular/core';

import { OktaAuthService } from '../services/okta.service';

@Component({template: `` })
export class OktaCallbackComponent {
constructor(private okta: OktaAuthService) {
@Component({
template: `<div>{{error}}</div>`
})
export class OktaCallbackComponent implements OnInit {
error: string;

constructor(private okta: OktaAuthService) {}

async ngOnInit() {
/**
* Handles the response from Okta and parses tokens.
*/
okta.handleAuthentication();
return this.okta.handleAuthentication()
.then(() => {
/**
* Navigate back to the saved uri, or root of application.
*/
const fromUri = this.okta.getFromUri();
window.location.replace(fromUri);
})
.catch(e => {
this.error = e.toString();
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@
* See the License for the specific language governing permissions and limitations under the License.
*/

import { Component } from '@angular/core';

import { Component, OnInit } from '@angular/core';
import { OktaAuthService } from '../services/okta.service';

@Component({ template: `` })
export class OktaLoginRedirectComponent {
constructor(private okta: OktaAuthService) {
okta.loginRedirect();
export class OktaLoginRedirectComponent implements OnInit {
constructor(private okta: OktaAuthService) {}
async ngOnInit() {
return this.okta.loginRedirect();
}
}
6 changes: 3 additions & 3 deletions packages/okta-angular/src/okta/createService.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Injector } from '@angular/core';
import { OktaConfig } from './models/okta.config';
import { Router } from '@angular/router';
import { OktaAuthService } from './services/okta.service';

export function createOktaService(config: OktaConfig, router: Router) {
return new OktaAuthService(config, router);
export function createOktaService(config: OktaConfig, injector: Injector) {
return new OktaAuthService(config, injector);
}
7 changes: 2 additions & 5 deletions packages/okta-angular/src/okta/models/okta.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,10 @@
* See the License for the specific language governing permissions and limitations under the License.
*/

import { InjectionToken } from '@angular/core';

import { Router } from '@angular/router';

import { InjectionToken, Injector } from '@angular/core';
import { OktaAuthService } from '../services/okta.service';

export type AuthRequiredFunction = (oktaAuth: OktaAuthService, router: Router) => void;
export type AuthRequiredFunction = (oktaAuth: OktaAuthService, injector: Injector) => void;
export type IsAuthenticatedFunction = () => Promise<boolean>;
export type OnSessionExpiredFunction = () => void;

Expand Down
6 changes: 4 additions & 2 deletions packages/okta-angular/src/okta/models/token-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ export interface IDToken {
claims: UserClaims;
}

export type Token = AccessToken | IDToken;

export interface TokenManager {
get(key: string): AccessToken | IDToken;
add(key: string, token: AccessToken | IDToken): void;
get(key: string): Token;
add(key: string, token: Token): void;
on(event: string, handler: Function): void;
off(event: string, handler: Function): void;
}
10 changes: 4 additions & 6 deletions packages/okta-angular/src/okta/okta.guard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,19 @@
* See the License for the specific language governing permissions and limitations under the License.
*/

import { Injectable } from '@angular/core';
import { Injectable, Injector } from '@angular/core';
import {
CanActivate,
ActivatedRouteSnapshot,
RouterStateSnapshot,
Router
} from '@angular/router';

import { OktaAuthService } from './services/okta.service';
import { AuthRequiredFunction } from './models/okta.config';

@Injectable()
export class OktaAuthGuard implements CanActivate {
constructor(private oktaAuth: OktaAuthService, private router: Router) { }
constructor(private oktaAuth: OktaAuthService, private injector: Injector) { }

/**
* Gateway for protected route. Returns true if there is a valid accessToken,
Expand All @@ -45,11 +44,10 @@ export class OktaAuthGuard implements CanActivate {
/**
* Store the current path
*/
const path = state.url.split(/[?#]/)[0];
this.oktaAuth.setFromUri(path, route.queryParams);
this.oktaAuth.setFromUri(state.url);

if (onAuthRequired) {
onAuthRequired(this.oktaAuth, this.router);
onAuthRequired(this.oktaAuth, this.injector);
} else {
this.oktaAuth.loginRedirect();
}
Expand Down
23 changes: 6 additions & 17 deletions packages/okta-angular/src/okta/okta.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,22 @@
* See the License for the specific language governing permissions and limitations under the License.
*/

import { ModuleWithProviders, NgModule } from '@angular/core';

import { NgModule, Injector } from '@angular/core';
import { OktaCallbackComponent } from './components/callback.component';
import { OktaLoginRedirectComponent } from './components/login-redirect.component';
import { OktaAuthService } from './services/okta.service';
import { OktaAuthGuard } from './okta.guard';
import { OktaConfig, OKTA_CONFIG } from './models/okta.config';
import { OKTA_CONFIG } from './models/okta.config';
import { createOktaService } from './createService';
import { Router } from '@angular/router';

@NgModule({
declarations: [
OktaCallbackComponent,
OktaLoginRedirectComponent
OktaLoginRedirectComponent,
],
exports: [
OktaCallbackComponent,
OktaLoginRedirectComponent
OktaLoginRedirectComponent,
],
providers: [
OktaAuthGuard,
Expand All @@ -36,20 +34,11 @@ import { Router } from '@angular/router';
useFactory: createOktaService,
deps: [
OKTA_CONFIG,
Router
Injector
]
}
]
})
export class OktaAuthModule {
// Deprecated. Your app should provide OKTA_CONFIG directly
static initAuth(config: OktaConfig): ModuleWithProviders {
return {
ngModule: OktaAuthModule,
providers: [
// Will NOT provide config when using AOT compiler. Your app module should provide this value statically in its providers section.
{ provide: OKTA_CONFIG, useValue: config }
]
};
}

}
Loading

0 comments on commit 15b67a2

Please sign in to comment.