@@ -3,8 +3,10 @@ import { DocumentNode } from 'graphql';
3
3
import { QueryRef , Apollo , MutationResult } from 'apollo-angular' ;
4
4
import { Observable , throwError } from 'rxjs' ;
5
5
import { ApolloQueryResult } from '@apollo/client' ;
6
- import { catchError } from 'rxjs/operators' ;
6
+ import { catchError , switchMap } from 'rxjs/operators' ;
7
7
import { MsalService } from '@azure/msal-angular' ;
8
+ import { AuthenticationResult , InteractionRequiredAuthError } from '@azure/msal-browser' ;
9
+ import { environment } from '../../environments/environment' ;
8
10
9
11
@Injectable ( {
10
12
providedIn : 'root' ,
@@ -15,8 +17,37 @@ export class GraphqlService {
15
17
private authService : MsalService ,
16
18
) { }
17
19
18
- private getToken ( ) : string | null {
19
- return sessionStorage . getItem ( 'accessToken' ) ;
20
+ private getToken ( ) : Observable < string > {
21
+ const account =
22
+ this . authService . instance . getActiveAccount ( ) || this . authService . instance . getAllAccounts ( ) [ 0 ] ;
23
+
24
+ if ( ! account ) {
25
+ // eslint-disable-next-line prefer-promise-reject-errors
26
+ return throwError ( 'No active account found' ) ;
27
+ }
28
+
29
+ const request = {
30
+ scopes : [ environment . apiScope ] ,
31
+ account,
32
+ } ;
33
+ const token = this . authService . acquireTokenSilent ( request ) . pipe (
34
+ switchMap ( ( response : AuthenticationResult ) => {
35
+ if ( response && response . accessToken ) {
36
+ return [ response . accessToken ] ;
37
+ }
38
+
39
+ return throwError ( 'Failed to acquire token' ) ;
40
+ } ) ,
41
+ catchError ( ( error ) => {
42
+ if ( error instanceof InteractionRequiredAuthError ) {
43
+ // fallback to interaction when silent call fails
44
+ this . authService . acquireTokenRedirect ( request ) ;
45
+ }
46
+
47
+ return throwError ( error ) ;
48
+ } ) ,
49
+ ) ;
50
+ return token ;
20
51
}
21
52
22
53
private handleUnauthorizedError ( ) : void {
@@ -26,19 +57,21 @@ export class GraphqlService {
26
57
}
27
58
28
59
query < T > ( query : DocumentNode ) : Observable < ApolloQueryResult < T > > {
29
- const token = this . getToken ( ) ;
30
- const queryRef : QueryRef < T > = this . apollo . use ( 'default' ) . watchQuery ( {
31
- query,
32
- errorPolicy : 'all' ,
33
- fetchPolicy : 'network-only' ,
34
- context : {
35
- headers : {
36
- Authorization : `Bearer ${ token } ` ,
37
- } ,
38
- } ,
39
- } ) ;
60
+ return this . getToken ( ) . pipe (
61
+ switchMap ( ( token : string ) => {
62
+ const queryRef : QueryRef < T > = this . apollo . use ( 'default' ) . watchQuery ( {
63
+ query,
64
+ errorPolicy : 'all' ,
65
+ fetchPolicy : 'network-only' ,
66
+ context : {
67
+ headers : {
68
+ Authorization : `Bearer ${ token } ` ,
69
+ } ,
70
+ } ,
71
+ } ) ;
40
72
41
- return queryRef . valueChanges . pipe (
73
+ return queryRef . valueChanges ;
74
+ } ) ,
42
75
catchError ( ( error ) => {
43
76
if ( this . isUnauthorizedError ( error ) ) {
44
77
this . handleUnauthorizedError ( ) ;
@@ -51,32 +84,32 @@ export class GraphqlService {
51
84
52
85
// eslint-disable-next-line @typescript-eslint/no-explicit-any
53
86
mutate < T > ( mutation : DocumentNode , variables : any ) : Observable < MutationResult < T > > {
54
- const token = this . getToken ( ) ;
55
- return this . apollo
56
- . mutate < T > ( {
57
- mutation,
58
- variables : { file : variables . inputFile } ,
59
- context : {
60
- hasUpload : true ,
61
- useMultipart : true ,
62
- headers : {
63
- 'content-type' : 'application/json' ,
64
- 'x-apollo-operation-name' : 'createSummary' ,
65
- Authorization : `Bearer ${ token } ` ,
87
+ return this . getToken ( ) . pipe (
88
+ switchMap ( ( token : string ) =>
89
+ this . apollo . mutate < T > ( {
90
+ mutation,
91
+ variables : { file : variables . inputFile } ,
92
+ context : {
93
+ hasUpload : true ,
94
+ useMultipart : true ,
95
+ headers : {
96
+ 'content-type' : 'application/json' ,
97
+ 'x-apollo-operation-name' : 'createSummary' ,
98
+ Authorization : `Bearer ${ token } ` ,
99
+ } ,
66
100
} ,
67
- } ,
68
- errorPolicy : 'all' ,
69
- fetchPolicy : 'network-only' ,
70
- } )
71
- . pipe (
72
- catchError ( ( error ) => {
73
- if ( this . isUnauthorizedError ( error ) ) {
74
- this . handleUnauthorizedError ( ) ;
75
- }
76
-
77
- return throwError ( error ) ;
101
+ errorPolicy : 'all' ,
102
+ fetchPolicy : 'network-only' ,
78
103
} ) ,
79
- ) ;
104
+ ) ,
105
+ catchError ( ( error ) => {
106
+ if ( this . isUnauthorizedError ( error ) ) {
107
+ this . handleUnauthorizedError ( ) ;
108
+ }
109
+
110
+ return throwError ( error ) ;
111
+ } ) ,
112
+ ) ;
80
113
}
81
114
82
115
// eslint-disable-next-line @typescript-eslint/no-explicit-any
0 commit comments