1
- import { Component , OnInit } from '@angular/core' ;
1
+ import { AfterViewInit , Component , OnInit , ViewChild } from '@angular/core' ;
2
2
import { MatDialog } from '@angular/material/dialog' ;
3
3
import { getDefaultDialogConfig } from '@perun-web-apps/perun/utils' ;
4
4
import { AddAuthImgDialogComponent } from '../../../components/dialogs/add-auth-img-dialog/add-auth-img-dialog.component' ;
5
5
import { Attribute , AttributesManagerService } from '@perun-web-apps/perun/openapi' ;
6
- import { StoreService } from '@perun-web-apps/perun/services' ;
6
+ import { AuthService , StoreService } from '@perun-web-apps/perun/services' ;
7
7
import { RemoveStringValueDialogComponent } from '../../../components/dialogs/remove-string-value-dialog/remove-string-value-dialog.component' ;
8
8
import { TranslateService } from '@ngx-translate/core' ;
9
+ import { OAuthService } from 'angular-oauth2-oidc' ;
10
+ import { MatSlideToggle } from '@angular/material/slide-toggle' ;
9
11
10
12
@Component ( {
11
13
selector : 'perun-web-apps-settings-authentication' ,
12
14
templateUrl : './settings-authentication.component.html' ,
13
15
styleUrls : [ './settings-authentication.component.scss' ] ,
14
16
} )
15
- export class SettingsAuthenticationComponent implements OnInit {
17
+ export class SettingsAuthenticationComponent implements OnInit , AfterViewInit {
18
+ @ViewChild ( 'toggle' ) toggle : MatSlideToggle ;
19
+
16
20
removeDialogTitle : string ;
17
21
imgAtt : Attribute ;
18
22
imageSrc = '' ;
19
23
removeDialogDescription : string ;
20
24
mfaUrl = '' ;
21
25
displayImageBlock : boolean ;
26
+ mfaAvailable = false ;
27
+ mfaApiUrl = '' ;
28
+ loadingMfa = false ;
29
+ loadingImg = false ;
22
30
23
31
constructor (
24
32
private dialog : MatDialog ,
25
33
private attributesManagerService : AttributesManagerService ,
26
34
private store : StoreService ,
27
- private translate : TranslateService
35
+ private translate : TranslateService ,
36
+ private oauthService : OAuthService ,
37
+ private authService : AuthService
28
38
) {
29
39
translate
30
40
. get ( 'AUTHENTICATION.DELETE_IMG_DIALOG_TITLE' )
@@ -34,7 +44,15 @@ export class SettingsAuthenticationComponent implements OnInit {
34
44
. subscribe ( ( res ) => ( this . removeDialogDescription = res ) ) ;
35
45
}
36
46
47
+ ngAfterViewInit ( ) : void {
48
+ this . toggle . change . subscribe ( ( change ) => {
49
+ this . reAuthenticate ( change . checked ) ;
50
+ } ) ;
51
+ }
52
+
37
53
ngOnInit ( ) : void {
54
+ this . loadingMfa = true ;
55
+ this . loadingImg = true ;
38
56
this . translate . onLangChange . subscribe ( ( ) => {
39
57
this . translate
40
58
. get ( 'AUTHENTICATION.DELETE_IMG_DIALOG_TITLE' )
@@ -45,9 +63,58 @@ export class SettingsAuthenticationComponent implements OnInit {
45
63
this . mfaUrl = this . store . get ( 'mfa' , 'url_' + this . translate . currentLang ) ;
46
64
} ) ;
47
65
this . mfaUrl = this . store . get ( 'mfa' , 'url_' + this . translate . currentLang ) ;
66
+ this . mfaApiUrl = this . store . get ( 'mfa' , 'api_url' ) ;
67
+ fetch ( this . mfaApiUrl + 'mfaAvailable' , {
68
+ method : 'GET' ,
69
+ headers : { Authorization : 'Bearer ' + this . oauthService . getIdToken ( ) } ,
70
+ } )
71
+ . then ( ( response ) => response . text ( ) )
72
+ . then ( ( responseText ) => {
73
+ this . mfaAvailable = responseText === 'true' ;
74
+ if ( this . mfaAvailable ) {
75
+ this . loadMfa ( ) ;
76
+ }
77
+ } )
78
+ . catch ( ( e ) => {
79
+ console . error ( e ) ;
80
+ this . loadingMfa = false ;
81
+ } ) ;
82
+
48
83
this . loadImage ( ) ;
49
84
}
50
85
86
+ private loadMfa ( ) : void {
87
+ const mfaRoute = sessionStorage . getItem ( 'mfa_route' ) ;
88
+ if ( mfaRoute ) {
89
+ const enforceMfa = sessionStorage . getItem ( 'enforce_mfa' ) ;
90
+ this . enableMfa ( enforceMfa === 'true' )
91
+ . then ( ( res ) => {
92
+ if ( res . ok && enforceMfa === 'true' ) {
93
+ this . toggle . toggle ( ) ;
94
+ }
95
+ this . loadingMfa = false ;
96
+ } )
97
+ . catch ( ( e ) => {
98
+ console . error ( e ) ;
99
+ this . loadingMfa = false ;
100
+ } ) ;
101
+ } else {
102
+ const enforceMfaAttributeName = this . store . get ( 'mfa' , 'enforce_mfa_attribute' ) ;
103
+ this . attributesManagerService
104
+ . getUserAttributeByName ( this . store . getPerunPrincipal ( ) . userId , enforceMfaAttributeName )
105
+ . subscribe ( ( attr ) => {
106
+ if ( attr . value ) {
107
+ this . toggle . toggle ( ) ;
108
+ }
109
+ this . loadingMfa = false ;
110
+ } ) ;
111
+ }
112
+ if ( sessionStorage . getItem ( 'mfa_route' ) ) {
113
+ sessionStorage . removeItem ( 'enforce_mfa' ) ;
114
+ sessionStorage . removeItem ( 'mfa_route' ) ;
115
+ }
116
+ }
117
+
51
118
onAddImg ( ) {
52
119
const config = getDefaultDialogConfig ( ) ;
53
120
config . width = '500px' ;
@@ -62,13 +129,29 @@ export class SettingsAuthenticationComponent implements OnInit {
62
129
} ) ;
63
130
}
64
131
65
- // private transformTextToImg(text: string) {
66
- // const canvas = document.createElement('canvas');
67
- // const context = canvas.getContext('2d');
68
- // context.font = "100px Calibri";
69
- // context.fillText(text, 1, 70);
70
- // return canvas.toDataURL('image/png');
71
- // }
132
+ reAuthenticate ( enforceMfa : boolean ) : void {
133
+ sessionStorage . setItem ( 'enforce_mfa' , enforceMfa . toString ( ) ) ;
134
+ sessionStorage . setItem ( 'mfa_route' , '/profile/settings/auth' ) ;
135
+ localStorage . removeItem ( 'refresh_token' ) ;
136
+ this . oauthService . logOut ( true ) ;
137
+ sessionStorage . setItem ( 'auth:redirect' , location . pathname ) ;
138
+ sessionStorage . setItem ( 'auth:queryParams' , location . search . substring ( 1 ) ) ;
139
+ this . authService . loadConfigData ( ) ;
140
+ this . oauthService . loadDiscoveryDocumentAndLogin ( ) ;
141
+ }
142
+
143
+ enableMfa ( value : boolean ) : Promise < Response > {
144
+ const idToken = this . oauthService . getIdToken ( ) ;
145
+ const path = `mfaEnforced` ;
146
+ const url = `${ this . mfaApiUrl } ${ path } ` ;
147
+ const body = `value=${ value } ` ;
148
+
149
+ return fetch ( url , {
150
+ method : 'PUT' ,
151
+ body : body ,
152
+ headers : { Authorization : `Bearer ${ idToken } ` } ,
153
+ } ) ;
154
+ }
72
155
73
156
onDeleteImg ( ) {
74
157
const config = getDefaultDialogConfig ( ) ;
@@ -95,17 +178,28 @@ export class SettingsAuthenticationComponent implements OnInit {
95
178
this . displayImageBlock = this . store . get ( 'mfa' , 'enable_security_image' ) ;
96
179
this . attributesManagerService
97
180
. getUserAttributeByName ( this . store . getPerunPrincipal ( ) . userId , imgAttributeName )
98
- . subscribe ( ( attr ) => {
99
- if ( ! attr ) {
100
- this . attributesManagerService
101
- . getAttributeDefinitionByName ( imgAttributeName )
102
- . subscribe ( ( att ) => {
103
- this . imgAtt = att as Attribute ;
104
- } ) ;
105
- } else {
106
- this . imgAtt = attr ;
107
- this . imageSrc = this . imgAtt . value as unknown as string ;
181
+ . subscribe (
182
+ ( attr ) => {
183
+ if ( ! attr ) {
184
+ this . attributesManagerService
185
+ . getAttributeDefinitionByName ( imgAttributeName )
186
+ . subscribe ( ( att ) => {
187
+ this . imgAtt = att as Attribute ;
188
+ } ) ;
189
+ } else {
190
+ this . imgAtt = attr ;
191
+ this . imageSrc = this . imgAtt . value as unknown as string ;
192
+ }
193
+ this . loadingImg = false ;
194
+ } ,
195
+ ( e ) => {
196
+ console . error ( e ) ;
197
+ this . loadingImg = false ;
108
198
}
109
- } ) ;
199
+ ) ;
200
+ }
201
+
202
+ redirectToMfa ( ) : void {
203
+ window . open ( this . mfaUrl , '_blank' ) ;
110
204
}
111
205
}
0 commit comments