1
- import type { InteractionMode } from '@logto/browser ' ;
1
+ import { type Optional } from '@silverhand/essentials ' ;
2
2
3
3
import type { Context } from './context.js' ;
4
4
import { throwContextError } from './context.js' ;
5
5
6
6
export const createPluginMethods = ( context : Context ) => {
7
7
const { logtoClient, setLoading, setError, setIsAuthenticated } = context ;
8
8
9
- const signIn = async ( redirectUri : string , interactionMode ?: InteractionMode ) => {
10
- if ( ! logtoClient . value ) {
11
- return throwContextError ( ) ;
12
- }
13
-
14
- try {
15
- setLoading ( true ) ;
16
-
17
- await logtoClient . value . signIn ( redirectUri , interactionMode ) ;
18
- } catch ( error : unknown ) {
19
- setError ( error , 'Unexpected error occurred while signing in.' ) ;
20
- }
21
- } ;
22
-
23
- const signOut = async ( postLogoutRedirectUri ?: string ) => {
24
- if ( ! logtoClient . value ) {
25
- return throwContextError ( ) ;
26
- }
27
-
28
- try {
29
- setLoading ( true ) ;
30
-
31
- await logtoClient . value . signOut ( postLogoutRedirectUri ) ;
32
-
33
- // We deliberately do NOT set isAuthenticated to false here, because the app state may change immediately
34
- // even before navigating to the oidc end session endpoint, which might cause rendering problems.
35
- // Moreover, since the location will be redirected, the isAuthenticated state will not matter any more.
36
- } catch ( error : unknown ) {
37
- setError ( error , 'Unexpected error occurred while signing out.' ) ;
38
- } finally {
39
- setLoading ( false ) ;
40
- }
41
- } ;
42
-
43
- const fetchUserInfo = async ( ) => {
44
- if ( ! logtoClient . value ) {
45
- return throwContextError ( ) ;
46
- }
47
-
48
- try {
49
- setLoading ( true ) ;
50
-
51
- return await logtoClient . value . fetchUserInfo ( ) ;
52
- } catch ( error : unknown ) {
53
- setError ( error , 'Unexpected error occurred while fetching user info.' ) ;
54
- } finally {
55
- setLoading ( false ) ;
56
- }
57
- } ;
58
-
59
- const getAccessToken = async ( resource ?: string ) => {
60
- if ( ! logtoClient . value ) {
61
- return throwContextError ( ) ;
62
- }
63
-
64
- try {
65
- setLoading ( true ) ;
66
-
67
- return await logtoClient . value . getAccessToken ( resource ) ;
68
- } catch ( error : unknown ) {
69
- setError ( error , 'Unexpected error occurred while getting access token.' ) ;
70
- } finally {
71
- setLoading ( false ) ;
72
- }
9
+ const client = logtoClient . value ?? throwContextError ( ) ;
10
+
11
+ const proxy = < R , T extends unknown [ ] > (
12
+ run : ( ...args : T ) => Promise < R > ,
13
+ resetLoadingState = true
14
+ ) => {
15
+ return async ( ...args : T ) : Promise < Optional < R > > => {
16
+ try {
17
+ setLoading ( true ) ;
18
+ return await run ( ...args ) ;
19
+ } catch ( error : unknown ) {
20
+ setError ( error , `Unexpected error occurred while calling ${ run . name } .` ) ;
21
+ } finally {
22
+ if ( resetLoadingState ) {
23
+ setLoading ( false ) ;
24
+ }
25
+ }
26
+ } ;
73
27
} ;
74
28
75
- const getIdTokenClaims = async ( ) => {
76
- if ( ! logtoClient . value ) {
77
- return throwContextError ( ) ;
78
- }
79
-
80
- try {
81
- return await logtoClient . value . getIdTokenClaims ( ) ;
82
- } catch ( error : unknown ) {
83
- setError ( error , 'Unexpected error occurred while getting id token claims.' ) ;
84
- }
29
+ const methods = {
30
+ getRefreshToken : proxy ( client . getRefreshToken . bind ( client ) ) ,
31
+ getAccessToken : proxy ( client . getAccessToken . bind ( client ) ) ,
32
+ getAccessTokenClaims : proxy ( client . getAccessTokenClaims . bind ( client ) ) ,
33
+ getOrganizationToken : proxy ( client . getOrganizationToken . bind ( client ) ) ,
34
+ getOrganizationTokenClaims : proxy ( client . getOrganizationTokenClaims . bind ( client ) ) ,
35
+ getIdToken : proxy ( client . getIdToken . bind ( client ) ) ,
36
+ getIdTokenClaims : proxy ( client . getIdTokenClaims . bind ( client ) ) ,
37
+ signIn : proxy ( client . signIn . bind ( client ) , false ) ,
38
+ // We deliberately do NOT set isAuthenticated to false in the function below, because the app state
39
+ // may change immediately even before navigating to the oidc end session endpoint, which might cause
40
+ // rendering problems.
41
+ // Moreover, since the location will be redirected, the isAuthenticated state will not matter any more.
42
+ signOut : proxy ( client . signOut . bind ( client ) ) ,
43
+ fetchUserInfo : proxy ( client . fetchUserInfo . bind ( client ) ) ,
85
44
} ;
86
45
87
46
const handleSignInCallback = async ( callbackUri : string , callbackFunction ?: ( ) => void ) => {
@@ -102,11 +61,7 @@ export const createPluginMethods = (context: Context) => {
102
61
} ;
103
62
104
63
return {
105
- signIn,
106
- signOut,
107
- fetchUserInfo,
108
- getAccessToken,
109
- getIdTokenClaims,
64
+ ...methods ,
110
65
handleSignInCallback,
111
66
} ;
112
67
} ;
0 commit comments