diff --git a/packages/stark-rbac/package-lock.json b/packages/stark-rbac/package-lock.json index 2776c3942b..16159952b4 100644 --- a/packages/stark-rbac/package-lock.json +++ b/packages/stark-rbac/package-lock.json @@ -4,6 +4,12 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@ngrx/store": { + "version": "8.6.1", + "resolved": "https://registry.npmjs.org/@ngrx/store/-/store-8.6.1.tgz", + "integrity": "sha512-bV7X0hNywd6N5YroWdZffIEvLKdHZo/l4tCK9FC/o5OezVyPRKZ6QVHz8e2jnLvqj55XzOJNR/tsYh4iuVi2pg==", + "dev": true + }, "@types/jasmine": { "version": "3.6.9", "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-3.6.9.tgz", diff --git a/packages/stark-rbac/package.json b/packages/stark-rbac/package.json index 3303265d8e..3e9c0ea064 100644 --- a/packages/stark-rbac/package.json +++ b/packages/stark-rbac/package.json @@ -21,6 +21,7 @@ "@types/lodash-es": "^4.17.1" }, "devDependencies": { + "@ngrx/store": "^8.6.1", "@types/jasmine": "^3.5.0", "@types/node": "^10.17.13" }, diff --git a/packages/stark-rbac/src/modules/authorization/actions.ts b/packages/stark-rbac/src/modules/authorization/actions.ts index e96f07b0b8..2688e5361d 100644 --- a/packages/stark-rbac/src/modules/authorization/actions.ts +++ b/packages/stark-rbac/src/modules/authorization/actions.ts @@ -1 +1,2 @@ -export * from "./actions/authorization.actions"; +import * as StarkRBACAuthorizationActions from "./actions/authorization.actions"; +export { StarkRBACAuthorizationActions }; diff --git a/packages/stark-rbac/src/modules/authorization/actions/authorization.actions.ts b/packages/stark-rbac/src/modules/authorization/actions/authorization.actions.ts index a2e829f8c0..ab24f1e414 100644 --- a/packages/stark-rbac/src/modules/authorization/actions/authorization.actions.ts +++ b/packages/stark-rbac/src/modules/authorization/actions/authorization.actions.ts @@ -1,44 +1,27 @@ -import { Action } from "@ngrx/store"; - -/** - * Actions related to {@link StarkRBACAuthorizationService} - */ -export enum StarkRBACAuthorizationActionsTypes { - RBAC_USER_NAVIGATION_UNAUTHORIZED = "[StarkRBAC] User navigation unauthorized", - RBAC_USER_NAVIGATION_UNAUTHORIZED_REDIRECTED = "[StarkRBAC] User navigation unauthorized redirected" -} +import { createAction, props, union } from "@ngrx/store"; /** * Action to be triggered when the user has navigated to a route that he is not authorized to. + * + * Parameter: + * - targetState - The state the user is navigating to */ -export class StarkUserNavigationUnauthorized implements Action { - /** - * The type of action - */ - public readonly type: StarkRBACAuthorizationActionsTypes.RBAC_USER_NAVIGATION_UNAUTHORIZED = - StarkRBACAuthorizationActionsTypes.RBAC_USER_NAVIGATION_UNAUTHORIZED; - - /** - * Class constructor - * @param targetState - The state the user is navigating to. - */ - public constructor(public targetState: string) {} -} +export const userNavigationUnauthorized = createAction("[StarkRBAC] User navigation unauthorized", props<{ targetState: string }>()); /** * Action to be triggered when the user is redirected because he is not authorized to navigate to the original route. + * + * Parameters: + * - targetState - The state the user is navigating to + * - redirectionState - The redirection to be performed instead of the original navigation */ -export class StarkUserNavigationUnauthorizedRedirected implements Action { - /** - * The type of action - */ - public readonly type: StarkRBACAuthorizationActionsTypes.RBAC_USER_NAVIGATION_UNAUTHORIZED_REDIRECTED = - StarkRBACAuthorizationActionsTypes.RBAC_USER_NAVIGATION_UNAUTHORIZED_REDIRECTED; +export const userNavigationUnauthorizedRedirected = createAction( + "[StarkRBAC] User navigation unauthorized redirected", + props<{ targetState: string; redirectionState: string }>() +); - /** - * Class constructor - * @param targetState - The state the user is navigating to - * @param redirectionState - The redirection to be performed instead of the original navigation - */ - public constructor(public targetState: string, public redirectionState: string) {} -} +/** + * @ignore + */ +const all = union({ userNavigationUnauthorized, userNavigationUnauthorizedRedirected }); +export type Types = typeof all; diff --git a/packages/stark-rbac/src/modules/authorization/services/authorization.service.spec.ts b/packages/stark-rbac/src/modules/authorization/services/authorization.service.spec.ts index 486ed842f8..fb77e059fd 100644 --- a/packages/stark-rbac/src/modules/authorization/services/authorization.service.spec.ts +++ b/packages/stark-rbac/src/modules/authorization/services/authorization.service.spec.ts @@ -8,7 +8,7 @@ import { MockStarkLoggingService, MockStarkRoutingService, MockStarkSessionServi import { StarkRBACStatePermissions, StarkStateRedirection, StarkStateRedirectionFn } from "../entities"; import { StarkRBACAuthorizationServiceImpl, starkUnauthorizedUserError } from "./authorization.service"; -import { StarkUserNavigationUnauthorized, StarkUserNavigationUnauthorizedRedirected } from "../actions"; +import { StarkRBACAuthorizationActions } from "../actions"; import createSpyObj = jasmine.createSpyObj; import createSpy = jasmine.createSpy; import Spy = jasmine.Spy; @@ -412,7 +412,9 @@ describe("StarkRBACAuthorizationService", () => { expect(mockLogger.warn).toHaveBeenCalledTimes(1); expect(mockLogger.warn).toHaveBeenCalledWith(starkUnauthorizedUserError); expect(mockStore.dispatch).toHaveBeenCalledTimes(1); - expect(mockStore.dispatch).toHaveBeenCalledWith(new StarkUserNavigationUnauthorized(dummyUnauthorizedStateName)); + expect(mockStore.dispatch).toHaveBeenCalledWith( + StarkRBACAuthorizationActions.userNavigationUnauthorized({ targetState: dummyUnauthorizedStateName }) + ); mockPermissions = undefined; mockLogger.warn.calls.reset(); @@ -481,7 +483,10 @@ describe("StarkRBACAuthorizationService", () => { expect(mockLogger.warn.calls.argsFor(0)[0]).toContain("redirecting"); expect(mockStore.dispatch).toHaveBeenCalledTimes(1); expect(mockStore.dispatch).toHaveBeenCalledWith( - new StarkUserNavigationUnauthorizedRedirected(dummyUnauthorizedStateName, mockRedirectToObj.stateName) + StarkRBACAuthorizationActions.userNavigationUnauthorizedRedirected({ + targetState: dummyUnauthorizedStateName, + redirectionState: mockRedirectToObj.stateName + }) ); }); @@ -504,7 +509,10 @@ describe("StarkRBACAuthorizationService", () => { expect(mockLogger.warn.calls.argsFor(0)[0]).toContain("redirecting"); expect(mockStore.dispatch).toHaveBeenCalledTimes(1); expect(mockStore.dispatch).toHaveBeenCalledWith( - new StarkUserNavigationUnauthorizedRedirected(dummyUnauthorizedStateName, mockRedirectToObj.stateName) + StarkRBACAuthorizationActions.userNavigationUnauthorizedRedirected({ + targetState: dummyUnauthorizedStateName, + redirectionState: mockRedirectToObj.stateName + }) ); }); }); diff --git a/packages/stark-rbac/src/modules/authorization/services/authorization.service.ts b/packages/stark-rbac/src/modules/authorization/services/authorization.service.ts index 6474c5dec6..9d2250d28c 100644 --- a/packages/stark-rbac/src/modules/authorization/services/authorization.service.ts +++ b/packages/stark-rbac/src/modules/authorization/services/authorization.service.ts @@ -16,7 +16,7 @@ import { } from "@nationalbankbelgium/stark-core"; import { StarkRBACAuthorizationService, starkRBACAuthorizationServiceName } from "./authorization.service.intf"; import { StarkRBACStatePermissions, StarkStateRedirection, StarkStateRedirectionFn } from "../entities"; -import { StarkUserNavigationUnauthorized, StarkUserNavigationUnauthorizedRedirected } from "../actions"; +import { StarkRBACAuthorizationActions } from "../actions"; /** * @ignore @@ -143,7 +143,7 @@ export class StarkRBACAuthorizationServiceImpl implements StarkRBACAuthorization } // dispatch action so an effect can run any logic if needed - this.store.dispatch(new StarkUserNavigationUnauthorized(transition.targetState().name())); + this.store.dispatch(StarkRBACAuthorizationActions.userNavigationUnauthorized({ targetState: transition.targetState().name() })); throw new Error(starkUnauthorizedUserError); } @@ -159,7 +159,12 @@ export class StarkRBACAuthorizationServiceImpl implements StarkRBACAuthorization this.logger.warn(starkRBACAuthorizationServiceName + ": redirecting to state '" + stateRedirection.stateName + "'"); const originalTargetState: TargetState = transition.targetState(); // dispatch action so an effect can run any logic if needed - this.store.dispatch(new StarkUserNavigationUnauthorizedRedirected(originalTargetState.name(), stateRedirection.stateName)); + this.store.dispatch( + StarkRBACAuthorizationActions.userNavigationUnauthorizedRedirected({ + targetState: originalTargetState.name(), + redirectionState: stateRedirection.stateName + }) + ); // overriding the target state with that one to be redirected to return originalTargetState.withState(stateRedirection.stateName).withParams(stateRedirection.params || {}, true); } diff --git a/packages/stark-rbac/tsconfig.json b/packages/stark-rbac/tsconfig.json index 26529030c7..fc9b6265d5 100644 --- a/packages/stark-rbac/tsconfig.json +++ b/packages/stark-rbac/tsconfig.json @@ -17,6 +17,7 @@ "@nationalbankbelgium/stark-rbac/testing": ["./testing/public_api.ts"], "@ng-idle/*": ["../stark-core/node_modules/@ng-idle/*"], "@ngrx/*": ["../stark-core/node_modules/@ngrx/*"], + "@ngrx/store": ["./node_modules/@ngrx/store"], "@ngx-translate/*": ["../stark-core/node_modules/@ngx-translate/*"], "@uirouter/*": ["../stark-core/node_modules/@uirouter/*"], "cerialize": ["../stark-core/node_modules/cerialize"], diff --git a/showcase/src/app/shared/effects/stark-rbac-unauthorized-navigation.effects.ts b/showcase/src/app/shared/effects/stark-rbac-unauthorized-navigation.effects.ts index d6d7693ce1..9439004a00 100644 --- a/showcase/src/app/shared/effects/stark-rbac-unauthorized-navigation.effects.ts +++ b/showcase/src/app/shared/effects/stark-rbac-unauthorized-navigation.effects.ts @@ -1,12 +1,7 @@ import { Injectable, Injector, NgZone } from "@angular/core"; -import { Actions, Effect, ofType } from "@ngrx/effects"; -import { Observable } from "rxjs"; +import { Actions, createEffect, ofType } from "@ngrx/effects"; import { map } from "rxjs/operators"; -import { - StarkRBACAuthorizationActionsTypes, - StarkUserNavigationUnauthorized, - StarkUserNavigationUnauthorizedRedirected -} from "@nationalbankbelgium/stark-rbac"; +import { StarkRBACAuthorizationActions } from "@nationalbankbelgium/stark-rbac"; import { STARK_TOAST_NOTIFICATION_SERVICE, StarkMessageType, StarkToastNotificationService } from "@nationalbankbelgium/stark-ui"; import uniqueId from "lodash-es/uniqueId"; @@ -25,46 +20,46 @@ export class StarkRbacUnauthorizedNavigationEffects { */ public constructor(private actions$: Actions, private injector: Injector, private zone: NgZone) {} - @Effect({ dispatch: false }) - public starkRBACNavigationUnauthorized$(): Observable { - return this.actions$.pipe( - ofType(StarkRBACAuthorizationActionsTypes.RBAC_USER_NAVIGATION_UNAUTHORIZED), - map((action: StarkUserNavigationUnauthorized) => { - this.zone.run(() => { - this.toastNotificationService - .show({ - id: uniqueId(), - type: StarkMessageType.ERROR, - key: action.type, - code: "Stark-RBAC: unauthorized navigation" - }) - .subscribe(); - }); - }) - ); - } + public starkRBACNavigationUnauthorized$ = createEffect( + () => + this.actions$.pipe( + ofType(StarkRBACAuthorizationActions.userNavigationUnauthorized), + map((action) => { + this.zone.run(() => { + this.toastNotificationService + .show({ + id: uniqueId(), + type: StarkMessageType.ERROR, + key: action.type, + code: "Stark-RBAC: unauthorized navigation" + }) + .subscribe(); + }); + }) + ), + { dispatch: false } + ); - @Effect({ dispatch: false }) - public starkRBACNavigationUnauthorizedRedirected$(): Observable { - return this.actions$.pipe( - ofType( - StarkRBACAuthorizationActionsTypes.RBAC_USER_NAVIGATION_UNAUTHORIZED_REDIRECTED + public starkRBACNavigationUnauthorizedRedirected$ = createEffect( + () => + this.actions$.pipe( + ofType(StarkRBACAuthorizationActions.userNavigationUnauthorizedRedirected), + map((action) => { + this.zone.run(() => { + this.toastNotificationService + .show({ + id: uniqueId(), + type: StarkMessageType.WARNING, + key: "SHOWCASE.DEMO_RBAC.SERVICES.AUTHORIZATION.REDIRECTION_MESSAGE", + interpolateValues: { rbacActionType: action.type }, + code: "Stark-RBAC: unauthorized navigation redirected" + }) + .subscribe(); + }); + }) ), - map((action: StarkUserNavigationUnauthorizedRedirected) => { - this.zone.run(() => { - this.toastNotificationService - .show({ - id: uniqueId(), - type: StarkMessageType.WARNING, - key: "SHOWCASE.DEMO_RBAC.SERVICES.AUTHORIZATION.REDIRECTION_MESSAGE", - interpolateValues: { rbacActionType: action.type }, - code: "Stark-RBAC: unauthorized navigation redirected" - }) - .subscribe(); - }); - }) - ); - } + { dispatch: false } + ); /** * Gets the StarkToastNotificationService from the Injector.