33import React , { Component } from 'react' ;
44import { BrowserRouter as Router , Route } from 'react-router-dom' ;
55import { Container } from 'reactstrap' ;
6+ import { UserAgentApplication } from 'msal' ;
67import NavBar from './NavBar' ;
78import ErrorMessage from './ErrorMessage' ;
89import Welcome from './Welcome' ;
10+ import { config } from './Config' ;
11+ import { getUserDetails } from './GraphService' ;
912import 'bootstrap/dist/css/bootstrap.css' ;
1013
1114interface AppState {
@@ -15,28 +18,51 @@ interface AppState {
1518}
1619
1720class App extends Component < any , AppState > {
21+ private userAgentApplication : UserAgentApplication ;
22+
23+ // <constructorSnippet>
1824 constructor ( props : any ) {
1925 super ( props ) ;
2026
27+ this . userAgentApplication = new UserAgentApplication ( {
28+ auth : {
29+ clientId : config . appId ,
30+ redirectUri : config . redirectUri
31+ } ,
32+ cache : {
33+ cacheLocation : "localStorage" ,
34+ storeAuthStateInCookie : true
35+ }
36+ } ) ;
37+
38+ var account = this . userAgentApplication . getAccount ( ) ;
39+
2140 this . state = {
22- isAuthenticated : false ,
41+ isAuthenticated : ( account !== null ) ,
2342 user : { } ,
2443 error : null
2544 } ;
45+
46+ if ( account ) {
47+ // Enhance user object with data from Graph
48+ this . getUserProfile ( ) ;
49+ }
2650 }
51+ // </constructorSnippet>
2752
2853 render ( ) {
2954 let error = null ;
3055 if ( this . state . error ) {
3156 error = < ErrorMessage message = { this . state . error . message } debug = { this . state . error . debug } /> ;
3257 }
3358
59+ // <renderSnippet>
3460 return (
3561 < Router >
3662 < div >
3763 < NavBar
3864 isAuthenticated = { this . state . isAuthenticated }
39- authButtonMethod = { null }
65+ authButtonMethod = { this . state . isAuthenticated ? this . logout . bind ( this ) : this . login . bind ( this ) }
4066 user = { this . state . user } />
4167 < Container >
4268 { error }
@@ -45,19 +71,106 @@ class App extends Component<any, AppState> {
4571 < Welcome { ...props }
4672 isAuthenticated = { this . state . isAuthenticated }
4773 user = { this . state . user }
48- authButtonMethod = { null } />
74+ authButtonMethod = { this . login . bind ( this ) } />
4975 } />
5076 </ Container >
5177 </ div >
5278 </ Router >
5379 ) ;
80+ // </renderSnippet>
5481 }
5582
5683 setErrorMessage ( message : string , debug : string ) {
5784 this . setState ( {
5885 error : { message : message , debug : debug }
5986 } ) ;
6087 }
88+
89+ // <loginSnippet>
90+ async login ( ) {
91+ try {
92+ await this . userAgentApplication . loginPopup (
93+ {
94+ scopes : config . scopes ,
95+ prompt : "select_account"
96+ } ) ;
97+ await this . getUserProfile ( ) ;
98+ }
99+ catch ( err ) {
100+ var error = { } ;
101+
102+ if ( typeof ( err ) === 'string' ) {
103+ var errParts = err . split ( '|' ) ;
104+ error = errParts . length > 1 ?
105+ { message : errParts [ 1 ] , debug : errParts [ 0 ] } :
106+ { message : err } ;
107+ } else {
108+ error = {
109+ message : err . message ,
110+ debug : JSON . stringify ( err )
111+ } ;
112+ }
113+
114+ this . setState ( {
115+ isAuthenticated : false ,
116+ user : { } ,
117+ error : error
118+ } ) ;
119+ }
120+ }
121+ // </loginSnippet>
122+
123+ // <logoutSnippet>
124+ logout ( ) {
125+ this . userAgentApplication . logout ( ) ;
126+ }
127+ // </logoutSnippet>
128+
129+ async getUserProfile ( ) {
130+ try {
131+ // Get the access token silently
132+ // If the cache contains a non-expired token, this function
133+ // will just return the cached token. Otherwise, it will
134+ // make a request to the Azure OAuth endpoint to get a token
135+
136+ var accessToken = await this . userAgentApplication . acquireTokenSilent ( {
137+ scopes : config . scopes
138+ } ) ;
139+
140+ if ( accessToken ) {
141+ // Get the user's profile from Graph
142+ var user = await getUserDetails ( accessToken . accessToken ) ;
143+ this . setState ( {
144+ isAuthenticated : true ,
145+ user : {
146+ displayName : user . displayName ,
147+ email : user . mail || user . userPrincipalName
148+ } ,
149+ error : null
150+ } ) ;
151+ }
152+ }
153+ catch ( err ) {
154+ var error = { } ;
155+ if ( typeof ( err ) === 'string' ) {
156+ var errParts = err . split ( '|' ) ;
157+ error = errParts . length > 1 ?
158+ { message : errParts [ 1 ] , debug : errParts [ 0 ] } :
159+ { message : err } ;
160+ } else {
161+ error = {
162+ message : err . message ,
163+ debug : JSON . stringify ( err )
164+ } ;
165+ }
166+
167+ this . setState ( {
168+ isAuthenticated : false ,
169+ user : { } ,
170+ error : error
171+ } ) ;
172+ }
173+ }
61174}
62175
63176export default App ;
0 commit comments