@asgardeo/auth-react 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,180 @@
1
+ /**
2
+ * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
3
+ *
4
+ * WSO2 Inc. licenses this file to you under the Apache License,
5
+ * Version 2.0 (the "License"); you may not use this file except
6
+ * in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing,
12
+ * software distributed under the License is distributed on an
13
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ * KIND, either express or implied. See the License for the
15
+ * specific language governing permissions and limitations
16
+ * under the License.
17
+ */
18
+
19
+ import {
20
+ AuthClientConfig,
21
+ BasicUserInfo,
22
+ CustomGrantConfig,
23
+ Hooks,
24
+ HttpRequestConfig,
25
+ HttpResponse,
26
+ SignInConfig,
27
+ SPAUtils
28
+ } from "@asgardeo/auth-spa";
29
+ import React, {
30
+ FunctionComponent,
31
+ PropsWithChildren,
32
+ createContext,
33
+ useContext,
34
+ useEffect,
35
+ useState
36
+ } from "react";
37
+ import AuthAPI from "./api";
38
+ import { AuthContextInterface, AuthReactConfig, AuthStateInterface } from "./models";
39
+
40
+ const AuthClient = new AuthAPI();
41
+
42
+ /**
43
+ * Authentication Context to hold global states in react components.
44
+ */
45
+ const AuthContext = createContext<AuthContextInterface>(null);
46
+
47
+ interface AuthProviderPropsInterface {
48
+ config: AuthClientConfig<AuthReactConfig>;
49
+ }
50
+
51
+ const AuthProvider: FunctionComponent<PropsWithChildren<AuthProviderPropsInterface>> = (
52
+ props: PropsWithChildren<AuthProviderPropsInterface>
53
+ ) => {
54
+ const [ state, dispatch ] = useState<AuthStateInterface>(AuthClient.getState());
55
+ const [ configState, setConfigState ] = useState(null);
56
+
57
+ const { children, config } = props;
58
+
59
+ const signIn = async(
60
+ config?: SignInConfig,
61
+ authorizationCode?: string,
62
+ sessionState?: string,
63
+ callback?: (response: BasicUserInfo) => void
64
+ ) => {
65
+ await AuthClient.signIn(dispatch, state, config, authorizationCode, sessionState, callback);
66
+ };
67
+ const signOut = (callback?) => {
68
+ AuthClient.signOut(dispatch, state, callback);
69
+ };
70
+ const getBasicUserInfo = () => AuthClient.getBasicUserInfo();
71
+ const httpRequest = (config: HttpRequestConfig) => AuthClient.httpRequest(config);
72
+ const httpRequestAll = (configs: HttpRequestConfig[]) => AuthClient.httpRequestAll(configs);
73
+ const requestCustomGrant = (
74
+ config: CustomGrantConfig,
75
+ callback?: (response: BasicUserInfo | HttpResponse<any>) => void
76
+ ) => AuthClient.requestCustomGrant(config, callback, dispatch);
77
+ const revokeAccessToken = () => AuthClient.revokeAccessToken(dispatch);
78
+ const getOIDCServiceEndpoints = () => AuthClient.getOIDCServiceEndpoints();
79
+ const getHttpClient = () => AuthClient.getHttpClient();
80
+ const getDecodedIDToken = () => AuthClient.getDecodedIDToken();
81
+ const getAccessToken = () => AuthClient.getAccessToken();
82
+ const refreshAccessToken = () => AuthClient.refreshAccessToken();
83
+ const isAuthenticated = () => AuthClient.isAuthenticated();
84
+ const enableHttpHandler = () => AuthClient.enableHttpHandler();
85
+ const disableHttpHandler = () => AuthClient.disableHttpHandler();
86
+ const getIDToken = () => AuthClient.getIDToken();
87
+ const updateConfig = (config: Partial<AuthClientConfig<AuthReactConfig>>) => AuthClient.updateConfig(config);
88
+ const on = (hook: Hooks, callback: (response?: any) => void, id?: string): Promise<void> => {
89
+ if (hook === Hooks.CustomGrant) {
90
+ return AuthClient.on(hook, callback, id);
91
+ }
92
+
93
+ return AuthClient.on(hook, callback);
94
+ };
95
+ const trySignInSilently = () => AuthClient.trySignInSilently(state, dispatch);
96
+
97
+ useEffect(() => {
98
+ if (state.isAuthenticated) {
99
+ return;
100
+ }
101
+
102
+ AuthClient.init(config);
103
+ setConfigState(config);
104
+ }, [ config ]);
105
+
106
+ /**
107
+ * Try signing in when the component is mounted.
108
+ */
109
+ useEffect(() => {
110
+
111
+ // User is already authenticated. Skip...
112
+ if (state.isAuthenticated) {
113
+ return;
114
+ }
115
+
116
+ // If `skipRedirectCallback` is not true, check if the URL has `code` and `session_state` params.
117
+ // If so, initiate the sign in. If not, try to login silently.
118
+ if (!config.skipRedirectCallback && SPAUtils.hasAuthSearchParamsInURL()) {
119
+ signIn({ callOnlyOnRedirect: true })
120
+ .then(() => {
121
+ // TODO: Add logs when a logger is available.
122
+ // Tracked here https://github.com/asgardeo/asgardeo-auth-js-sdk/issues/151.
123
+ })
124
+ .catch(() => {
125
+ // TODO: Add logs when a logger is available.
126
+ // Tracked here https://github.com/asgardeo/asgardeo-auth-js-sdk/issues/151.
127
+ })
128
+ } else {
129
+ // This uses the RP iframe to get the session. Hence, will not work if 3rd party cookies are disabled.
130
+ // If the browser has these cookies disabled, we'll not be able to retrieve the session on refreshes.
131
+ trySignInSilently()
132
+ .then((_: BasicUserInfo | boolean) => {
133
+ // TODO: Add logs when a logger is available.
134
+ // Tracked here https://github.com/asgardeo/asgardeo-auth-js-sdk/issues/151.
135
+ })
136
+ .catch(() => {
137
+ // TODO: Add logs when a logger is available.
138
+ // Tracked here https://github.com/asgardeo/asgardeo-auth-js-sdk/issues/151.
139
+ });
140
+ }
141
+ }, []);
142
+
143
+ /**
144
+ * Render state and special case actions
145
+ */
146
+ return (
147
+ <AuthContext.Provider
148
+ value={ {
149
+ disableHttpHandler,
150
+ enableHttpHandler,
151
+ getAccessToken,
152
+ getBasicUserInfo,
153
+ getDecodedIDToken,
154
+ getHttpClient,
155
+ getIDToken,
156
+ getOIDCServiceEndpoints,
157
+ httpRequest,
158
+ httpRequestAll,
159
+ isAuthenticated,
160
+ on,
161
+ refreshAccessToken,
162
+ requestCustomGrant,
163
+ revokeAccessToken,
164
+ signIn,
165
+ signOut,
166
+ state,
167
+ trySignInSilently,
168
+ updateConfig
169
+ } }
170
+ >
171
+ { configState && children }
172
+ </AuthContext.Provider>
173
+ );
174
+ };
175
+
176
+ const useAuthContext = (): AuthContextInterface => {
177
+ return useContext(AuthContext);
178
+ };
179
+
180
+ export { AuthClient, AuthProvider, useAuthContext };
package/src/index.ts ADDED
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
3
+ *
4
+ * WSO2 Inc. licenses this file to you under the Apache License,
5
+ * Version 2.0 (the "License"); you may not use this file except
6
+ * in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing,
12
+ * software distributed under the License is distributed on an
13
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ * KIND, either express or implied. See the License for the
15
+ * specific language governing permissions and limitations
16
+ * under the License.
17
+ */
18
+
19
+ import "core-js";
20
+ import "regenerator-runtime/runtime";
21
+
22
+ export * from "@asgardeo/auth-spa";
23
+ export * from "./public-api";
package/src/models.ts ADDED
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
3
+ *
4
+ * WSO2 Inc. licenses this file to you under the Apache License,
5
+ * Version 2.0 (the "License"); you may not use this file except
6
+ * in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing,
12
+ * software distributed under the License is distributed on an
13
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ * KIND, either express or implied. See the License for the
15
+ * specific language governing permissions and limitations
16
+ * under the License.
17
+ */
18
+
19
+ import {
20
+ AuthClientConfig,
21
+ BasicUserInfo,
22
+ Config,
23
+ CustomGrantConfig,
24
+ DecodedIDTokenPayload,
25
+ Hooks,
26
+ HttpClientInstance,
27
+ HttpRequestConfig,
28
+ HttpResponse,
29
+ OIDCEndpoints,
30
+ SPAConfig
31
+ } from "@asgardeo/auth-spa";
32
+
33
+ export interface AuthReactConfig extends SPAConfig {
34
+ /**
35
+ * The SDK's `AuthProvider` by default is listening to the URL changes to see
36
+ * if `code` & `session_state` search params are available so that it could perform
37
+ * token exchange. This option could be used to override that behaviour.
38
+ */
39
+ skipRedirectCallback?: boolean;
40
+ }
41
+
42
+ export interface AuthStateInterface {
43
+ allowedScopes: string;
44
+ displayName?: string;
45
+ email?: string;
46
+ isAuthenticated: boolean;
47
+ /**
48
+ * Are the Auth requests loading.
49
+ */
50
+ isLoading: boolean;
51
+ username: string;
52
+ }
53
+
54
+ export interface AuthContextInterface {
55
+ signIn: (callback?) => Promise<void>;
56
+ signOut: () => void;
57
+ getBasicUserInfo(): Promise<BasicUserInfo>;
58
+ httpRequest(config: HttpRequestConfig): Promise<HttpResponse<any>>;
59
+ httpRequestAll(configs: HttpRequestConfig[]): Promise<HttpResponse<any>[]>;
60
+ requestCustomGrant(
61
+ config: CustomGrantConfig,
62
+ callback?: (response: BasicUserInfo | HttpResponse<any>) => void
63
+ ): void;
64
+ revokeAccessToken(): Promise<boolean>;
65
+ getOIDCServiceEndpoints(): Promise<OIDCEndpoints>;
66
+ getHttpClient(): Promise<HttpClientInstance>;
67
+ getDecodedIDToken(): Promise<DecodedIDTokenPayload>;
68
+ getIDToken(): Promise<string>;
69
+ getAccessToken(): Promise<string>;
70
+ refreshAccessToken(): Promise<BasicUserInfo>;
71
+ isAuthenticated(): Promise<boolean>;
72
+ enableHttpHandler(): Promise<boolean>;
73
+ disableHttpHandler(): Promise<boolean>;
74
+ updateConfig(config: Partial<AuthClientConfig<Config>>): Promise<void>;
75
+ trySignInSilently: () => Promise<boolean | BasicUserInfo>;
76
+ on(hook: Hooks.CustomGrant, callback: (response?: any) => void, id: string): void;
77
+ on(
78
+ hook:
79
+ | Hooks.RevokeAccessToken
80
+ | Hooks.HttpRequestError
81
+ | Hooks.HttpRequestFinish
82
+ | Hooks.HttpRequestStart
83
+ | Hooks.HttpRequestSuccess
84
+ | Hooks.Initialize
85
+ | Hooks.SignIn
86
+ | Hooks.SignOut,
87
+ callback: (response?: any) => void
88
+ ): void;
89
+ on(hook: Hooks, callback: (response?: any) => void, id?: string): void;
90
+ state: AuthStateInterface;
91
+ }
92
+
93
+ export interface SecureRouteInterface {
94
+ callback: () => void;
95
+ component: any;
96
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Copyright (c) 2021, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
3
+ *
4
+ * WSO2 Inc. licenses this file to you under the Apache License,
5
+ * Version 2.0 (the "License"); you may not use this file except
6
+ * in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing,
12
+ * software distributed under the License is distributed on an
13
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ * KIND, either express or implied. See the License for the
15
+ * specific language governing permissions and limitations
16
+ * under the License.
17
+ */
18
+
19
+ export * from "./authenticate";
20
+ export * from "./models";
21
+ export * from "./secure-route";
package/src/reducer.ts ADDED
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
3
+ *
4
+ * WSO2 Inc. licenses this file to you under the Apache License,
5
+ * Version 2.0 (the "License"); you may not use this file except
6
+ * in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing,
12
+ * software distributed under the License is distributed on an
13
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ * KIND, either express or implied. See the License for the
15
+ * specific language governing permissions and limitations
16
+ * under the License.
17
+ */
18
+
19
+ import { AuthContextReducerActionTypes } from "./actions";
20
+ import { AuthStateInterface } from "./models";
21
+
22
+ /**
23
+ * Initial authenticate state.
24
+ */
25
+ const authenticateInitialState: AuthStateInterface = {
26
+ allowedScopes: "",
27
+ displayName: "",
28
+ email: "",
29
+ isAuthenticated: false,
30
+ isLoading: true,
31
+ username: ""
32
+ };
33
+
34
+ /**
35
+ * Reducer to handle the state of authentication related actions.
36
+ *
37
+ * @param state - Previous state
38
+ * @param action - Action type
39
+ * @returns The new state
40
+ */
41
+ const authenticateReducer = (state, action) => {
42
+ switch (action.type) {
43
+ case AuthContextReducerActionTypes.SET_SIGN_IN:
44
+ return {
45
+ ...state,
46
+ allowedScopes: action.payload.allowedScopes,
47
+ displayName: action.payload.displayName,
48
+ email: action.payload.email,
49
+ isAuthenticated: true,
50
+ isLoading: false,
51
+ username: action.payload.username
52
+ };
53
+ case AuthContextReducerActionTypes.SET_SIGN_OUT:
54
+ return {
55
+ ...state,
56
+ authenticateInitialState,
57
+ isLoading: false
58
+ };
59
+ case AuthContextReducerActionTypes.SET_PROFILE_INFO:
60
+ return state
61
+ default:
62
+ return state;
63
+ }
64
+ };
65
+
66
+ export { authenticateInitialState, authenticateReducer };
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
3
+ *
4
+ * WSO2 Inc. licenses this file to you under the Apache License,
5
+ * Version 2.0 (the "License"); you may not use this file except
6
+ * in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing,
12
+ * software distributed under the License is distributed on an
13
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ * KIND, either express or implied. See the License for the
15
+ * specific language governing permissions and limitations
16
+ * under the License.
17
+ */
18
+
19
+ import React, { FunctionComponent, ReactElement, useEffect } from "react";
20
+ import { Route, RouteProps } from "react-router-dom";
21
+ import { useAuthContext } from "./authenticate";
22
+ import { SecureRouteInterface } from "./models";
23
+
24
+ /**
25
+ * Protected route component.
26
+ *
27
+ * @param {SecureRouteInterface} props - Props injected in to the component.
28
+ *
29
+ * @return {React.ReactElement}
30
+ */
31
+ const SecureRoute: FunctionComponent<SecureRouteInterface & RouteProps> = (props: SecureRouteInterface & RouteProps
32
+ ): ReactElement => {
33
+ const { state } = useAuthContext();
34
+
35
+ const { component: Component, callback, ...rest } = props;
36
+
37
+ useEffect(() => {
38
+ if (!state.isAuthenticated) {
39
+ callback && callback();
40
+ }
41
+
42
+ }, [ state.isAuthenticated ]);
43
+
44
+ if (!state.isAuthenticated) {
45
+ return null;
46
+ }
47
+
48
+ return (
49
+ <Route
50
+ { ...rest }
51
+ render={ (props) =>
52
+ <Component { ...props } />
53
+ }
54
+ />
55
+ );
56
+ };
57
+
58
+ export { SecureRoute };