11import * as ko from "knockout" ;
2- import { UserService } from "@paperbits/common/user" ;
2+ import { BuiltInRoles , UserService } from "@paperbits/common/user" ;
33import { EventManager } from "@paperbits/common/events" ;
44import { RoleBasedSecurityModel } from "@paperbits/common/security/roleBasedSecurityModel" ;
5- import { RoleBasedSecuredBehavior , RoleBasedSecuredBehaviorConfig } from "@paperbits/common/behaviors/behavior.roleBasedSecured" ;
65
76
87export class RoleBasedSecuredBindingHandler {
@@ -11,45 +10,48 @@ export class RoleBasedSecuredBindingHandler {
1110 private readonly userService : UserService
1211 ) {
1312 ko . bindingHandlers [ "secured" ] = {
14- init : ( element : HTMLElement , valueAccessor : ( ) => ko . Observable < RoleBasedSecurityModel > | RoleBasedSecurityModel ) => {
15- const securityModelObservableOrStatic = valueAccessor ( ) ;
16- const initialSecurityModel = ko . unwrap ( securityModelObservableOrStatic ) ;
17-
18- const dataRoleObservable : ko . Observable < string | null > = ko . observable ( null ) ;
13+ init : ( element : HTMLElement , valueAccessor : any ) => {
14+ const securityModel = ko . unwrap ( valueAccessor ( ) ) ;
15+ const initiallyAssignedRoles = securityModel ?. roles ;
16+ const dataRoleObservable : ko . Observable < string > = ko . observable ( initiallyAssignedRoles ) ;
1917 const hiddenObservable : ko . Observable < boolean > = ko . observable ( false ) ;
2018
21- const behaviorConfig : RoleBasedSecuredBehaviorConfig = {
22- initialSecurityModel : initialSecurityModel ,
23- userService : this . userService ,
24- eventManager : this . eventManager ,
25- onUpdate : ( roles , isHidden ) => {
26- dataRoleObservable ( roles ) ;
27- hiddenObservable ( isHidden ) ;
28- }
19+ const applyRoles = ( securityModel : RoleBasedSecurityModel ) => { // has to be synchronous to be applied during publishing
20+ const widgetRoles = securityModel ?. roles || [ BuiltInRoles . everyone . key ] ;
21+
22+ const roles = widgetRoles
23+ && widgetRoles . length === 1
24+ && widgetRoles [ 0 ] === BuiltInRoles . everyone . key
25+ ? null
26+ : widgetRoles . join ( "," ) ;
27+
28+ dataRoleObservable ( roles ) ;
29+ applyVisibility ( ) ;
30+ } ;
31+
32+ const applyVisibility = async ( ) => { // doesn't have to be synchronous, used in design- and run-time only
33+ const widgetRolesString = dataRoleObservable ( ) ;
34+ const widgetRoles = ! ! widgetRolesString ? widgetRolesString . split ( "," ) : [ BuiltInRoles . everyone . key ] ;
35+ const userRoles = await this . userService . getUserRoles ( ) ;
36+ const visibleToUser = userRoles . some ( x => widgetRoles . includes ( x ) ) || widgetRoles . includes ( BuiltInRoles . everyone . key ) ;
37+
38+ hiddenObservable ( ! visibleToUser ) ;
2939 } ;
3040
31- const behaviorHandle = RoleBasedSecuredBehavior . attach ( element , behaviorConfig ) ;
41+ this . eventManager . addEventListener ( "onUserRoleChange" , applyVisibility ) ;
3242
3343 ko . applyBindingsToNode ( element , {
3444 attr : { "data-role" : dataRoleObservable } ,
3545 css : { hidden : hiddenObservable }
3646 } , null ) ;
3747
38- let subscription : ko . Subscription | undefined ;
39- if ( ko . isObservable ( securityModelObservableOrStatic ) ) {
40- subscription = securityModelObservableOrStatic . subscribe ( ( newModel ) => {
41- behaviorHandle . update && behaviorHandle . update ( newModel ) ;
42- } ) ;
43- }
44-
4548 ko . utils . domNodeDisposal . addDisposeCallback ( element , ( ) => {
46- if ( subscription ) {
47- subscription . dispose ( ) ;
48- }
49- if ( behaviorHandle && behaviorHandle . detach ) {
50- behaviorHandle . detach ( ) ;
51- }
49+ this . eventManager . removeEventListener ( "onUserRoleChange" , applyVisibility ) ;
5250 } ) ;
51+
52+ const assignedRolesObsevable : ko . Observable < RoleBasedSecurityModel > = valueAccessor ( ) ;
53+ assignedRolesObsevable . subscribe ( applyRoles ) ;
54+ applyRoles ( securityModel ) ;
5355 }
5456 } ;
5557 }
0 commit comments