Git Product home page Git Product logo

asgardeo-auth-react-sdk's Introduction

Asgardeo Auth React SDK

Builder Stackoverflow Join the chat at https://discord.gg/wso2 License Twitter


Table of Content

Introduction

Asgardeo Auth React SDK allows React applications to use OpenID Connect - OIDC authentication with Asgardeo as the Consumer Identity and Access Management(CIAM) Provider. The SDK supports following capabilities

Prerequisite - Register your application in Asgardeo

  1. Register to Asgardeo and create an organization if you don't already have one. The organization name you choose will be referred to as <org_name> throughout this document.
  2. Register a Single Page Application in Asgardeo to obtain necessary keys to integrate your application with Asgardeo. You will obtain a client_ID from Asgardeo for your application which will need to embed later in your application for the integration.

Getting Started

Follow this guide to integrate Asgardeo to your own React Application. To try out the sample apps, use this guide.

1. Installing the Package

Run the following command to install @asgardeo/auth-react from the npm registry.

npm install @asgardeo/auth-react --save

Asgardeo React SDK exposes the AuthProvider component, which helps you easily integrate Asgardeo to your application.

First, import the AuthProvider component from @asgardeo/auth-react. where you applications root component is defined.

Note Typically the root component of a react app is defined in the index.* file.

import { AuthProvider } from "@asgardeo/auth-react";

Then, wrap your root component with the AuthProvider.

import React from "react";
import { AuthProvider } from "@asgardeo/auth-react";

const config = {
     signInRedirectURL: "https://localhost:3000/sign-in",
     signOutRedirectURL: "https://localhost:3000/dashboard",
     clientID: "<client_ID>",
     baseUrl: "https://api.asgardeo.io/t/<org_name>",
     scope: [ "openid","profile" ]
};

export const MyApp = (): ReactElement => {
    return (
        <AuthProvider config={ config }>
            <App />
        </AuthProvider>
    )
}

Note You can refer to the details of AuthProvider config here

Once the root component is wrapped with AuthProvider, useAuthContext() hook can be used anywhere within the application to implement user authentication capabilities in the application.

Using APIs

Best practices when using APIs

Asgardeo Auth React SDK is built on top of Asgardeo Auth SPA SDK, a base library. Hence, almost all the usable APIs from Auth SPA SDK are re-exported from Asgardeo Auth React SDK and you don't need to import dependencies from the base library to your application.

  • The only SDK that should be listed in the app dependencies is @asgardeo/auth-react.
  • Always import APIs from @asgardeo/auth-react.

Warning IDE or Editor auto import may sometimes import certain APIs from @asgardeo/auth-spa, change them back manually.

Click here for Tips: Do's When importing a component from Asgardeo React SDK

DO ✅

import { AsgardeoSPAClient } from "@asgardeo/auth-react";

When including React SDK as a dependency:

DO ✅
// In package.json

dependencies: {
    "@asgardeo/auth-react": "^2.0.0"
}


useAuthContext() hook

The useAuthContext() hook provided by the SDK could be used to implement the necessary authentication functionalities and access the session state that contains information such as a unique identifier for the authenticated user.

Import the useAuthContext() hook from @asgardeo/auth-react.

import { useAuthContext } from "@asgardeo/auth-react";

And then inside your components, you can access the context as follows

const { state, signIn, signOut } = useAuthContext();

Few common methods that you will require when implementing authentication capabilities in your application.

  • signIn - Initiate a login request to Asgardeo, process the response to obtain authentication response.
  • signOut - Logout the user from Asgardeo and clear any authentication data from the SDK storage.
  • isAuthenticated - Check whether there is an authenticated user session. Based on the result you can decide to change the application view/behaviour.
  • getBasicUserInfo - Get authenticated user's basic information from the authentication response.
  • getDecodedIDToken - Get the decoded id_token obtained in the authentication response. From there you can derive more information such as additional user-attributes.
  • getIDToken - Get the id_token (JWT) obtained in the authentication response.
  • getAccessToken - Get the access_token obtained in the authentication response.
  • refreshAccessToken - Get the refresh_token obtained in the authentication response.
  • getHttpClient - Get an HttpClient instance so that the you can make RESTful calls to the backend, where the client will attach the necessary Authorization headers to the request.

The state object will contain attributes such as whether a user is currently logged in, the username of the currently logged-in user etc.

Note You can refer to the detailed API documentation here


Add a Login/Logout Button

You can use the signIn() method from useAuthContext() to easily implement a login button.

<button onClick={ () => signIn() }>Login</button>

Similarly to the above step, we can use the signOut() method from useAuthContext() to implement a logout button.

<button onClick={() => signOut()}>Logout</button>

Clicking on Login button will take the user to Asgardeo login page. Upon successful signIn(), the user will be redirected to the app (based on the specified signInRedirectURL) and the state.isAuthenticated will be set to true.

Clicking on Logout button will sign out the user and will be redirected to signOutRedirectURL and the state.isAuthenticated will be set to false.

Note Instead of buttons you can use the signIn() & signOut() methods from the SDK to implement any preffered user-experience in your application

You can use the state.isAuthenticated attribute to check the authenticated status of the user.


Show Authenticated User's Information

The following code snippet demonstrates the usage of the state object, together with signIn() and signOut() methods from the context.

import React from "react";
import { useAuthContext } from "@asgardeo/auth-react";

function App() {

  const { state, signIn, signOut } = useAuthContext();

  return (
    <div className="App">
      {
        state.isAuthenticated
          ? (
            <div>
              <ul>
                <li>{state.username}</li>
              </ul>

              <button onClick={() => signOut()}>Logout</button>
            </div>
          )
          : <button onClick={() => signIn()}>Login</button>
      }
    </div>
  );
}

export default App;

Add Routing

If your application needs routing, the SDK provides a multiple approaches to secure routes in your application. You can read more about routing capabilities in Asgardeo here.


API Documentation

Additionally to above, Asgardeo offers a wide range of APIs that you can use to integrate and make use of Asgardeo within your React Application. You can refer to a detailed API documentation here.

Sample Apps

Sample React Apps offered by Asgardeo will allow you to take Asgardeo for a spin without having to setup your own application. You can see how to setup sample apps here.

Develop

Prerequisites

  • Node.js (version 10 or above).
  • yarn package manager.

Installing Dependencies

The repository is a mono repository. The SDK repository is found in the lib directory. You can install the dependencies by running the following command at the root.

yarn build

Contribute

Please read Contributing to the Code Base for details on our code of conduct, and the process for submitting pull requests to us.

Reporting issues

We encourage you to report issues, improvements, and feature requests creating Github Issues.

Important: And please be advised that security issues must be reported to security@wso2com, not as GitHub issues, in order to reach the proper audience. We strongly advise following the WSO2 Security Vulnerability Reporting Guidelines when reporting the security issues.

License

This project is licensed under the Apache License 2.0. See the LICENSE file for details.

asgardeo-auth-react-sdk's People

Contributors

achintha444 avatar afrahussaindeen avatar anuradhask avatar ashans avatar ayshsandu avatar brionmario avatar chaminjay avatar chanikaruchini avatar darshanasbg avatar dhaura avatar dimalchandrasiri avatar donomalvindula avatar ims94 avatar janithgan avatar jeradrutnam avatar kayathiri4 avatar maheshika avatar migara-pramod avatar nipunsampath avatar pandukakarunasena avatar pavindulakshan avatar savindi7 avatar thanujalk avatar thivi avatar tmkasun avatar vihanga-liyanage avatar wso2-jenkins-bot avatar yasasr1 avatar yasinmiran avatar yathindrak avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

asgardeo-auth-react-sdk's Issues

Token overriding issue when multiple applications hosted in same subdomain

Describe the issue:
When two applications are hosted on the same domain, the tokens in the session storage does not refresh when switching between applications. It will use the same token from the previous application

How to reproduce:

  1. Host 2 applications under same domain (Ex: example.com/app1 and example.com/app2)
  2. Open one application (example.com/app1) in a tab and log into the application
  3. You should see session storage of the tab with following artifacts
    Screenshot 2023-02-14 at 17 09 17
  4. Switch to the other application while being in the same tab
  5. You should see that the access_token does not refresh in session storage and is being used from the previous application.

Expected behavior:

  • The 2 applications should have their own artifacts in the session storage. One method of preserving these artifacts is to append the clientID of each application to the key of the artifacts.

Optional Fields

Related issues:
Parent Issue - https://github.com/wso2-enterprise/iam-engineering/issues/409

Token Request is Failing in asgardeo-react-app

Describe the issue:
I tried the sample react app asgardeo-react-app with the following config
{
"clientID": "8L0rX62AXUSDLguffhwtLlqdJrwa",
"clientHost": "https://localhost:5000",
"signInRedirectURL": "https://localhost:5000",
"signOutRedirectURL": "https://localhost:5000",
"serverOrigin": "https://localhost:10443",
"baseUrls": ["https://localhost:10443"]
}

After login callback, when requesting the token its failing. I have received the token but on console its throwing error as Token request failed. Following that i tried 'state?.isAuthenticated' and 'on("sign-in")' and both of them returned false value. Due to this my login process is not getting completed.

Environment information (Please complete the following information; remove any unnecessary fields) :

  • Product Version: IS 5.10.0
  • OS: Mac
  • Userstore: JDBC

Add support for Node 17+ versions

Describe the issue:
We are getting the following error when we try to start our react sample in Node 17+ versions and the newest LTS 18.12.0.

image

The major reason is that in node 17, they've changed the implementation of SSL handling, which came as a breaking change for older code bases [1]. We might need to bump our packages accordingly or configure webpack to support this.

How to reproduce:

  1. Install or switch to Node >17
  2. Try to start the sample app
  3. You'll see an error mentioned above

Expected behavior:
Sample app should start without any issues

Environment information (Please complete the following information; remove any unnecessary fields) :

  • OS: [e.g., Windows, Linux, Mac] - Mac
  • Node - >17

Optional Fields

Using WebWorker - Uncaught (in promise) TypeError: document.getElementById(...) is null

Authorization code flow is working as expected, my users are authenticated thanks the webworkers as expected.
But the following error is displayed in the browser console :

Uncaught (in promise) TypeError: document.getElementById(...) is null
    i http://localhost:8082/build.js line 869 > eval line 407 > eval:1
    node_modules asgardeo/auth-react/dist/main.js?:407
    node_modules asgardeo/auth-react/dist/main.js?:407
    node_modules asgardeo/auth-react/dist/main.js?:407
    node_modules asgardeo/auth-react/dist/main.js?:16

Everything seems to work as expected, but this error looks quite confusing.
When I click on the error on my browser, it shows me that the element the code is trying to find has the ID "opIFrame". In my DOM, I can actually find an iframe with the ID "rpIFrame", but I can't find any with the ID "opIFrame"

How to reproduce:
The error happens in the sample apps you provide and in the app I created using your package.
I've pulled the code, edited the config.json to set storage as "webWorker" and other required fields, then started the app with "npm run start" command.

Expected behavior:
The error message should not appear in the browser console.

Custom grant request is failing

Describe the issue:
Related use case: choreo-apim-devportal [1]
I am trying to call the requestCustomGrant [2] API and obtain a new token. The custom grant request is done in the sign-in hook and the code looks like this.

        authClient?.signIn();

        authClient?.on(Hooks.SignIn, async (response: any) => {
            const config = {
                tokenEndpoint: "https://<apim-host>/oauth2/token",
                attachToken: false,
                data: {
                    client_id: "choreodevportal",
                    grant_type: "urn:ietf:params:oauth:grant-type:token-exchange",
                    subject_token_type: "urn:ietf:params:oauth:token-type:jwt",
                    requested_token_type: "urn:ietf:params:oauth:token-type:jwt",
                    scope: "{{scope}}",
                    subject_token: "{{token}}",
                },
                id: "apim-token-exchange",
                returnResponse: true,
                returnsSession: true,
                signInRequired: true
            }

            dispatch(userLoginSuccess(response));
            authClient?.getDecodedIDToken().then((idToken) => {
                dispatch(fetchUserInfoSuccess(idToken));
            }).catch((error) => {
                dispatch(setErrorNotification('Error while retrieving user information'));
                dispatch(fetchUserInfoFailure(error));
            });

            // Custom grant request
            authClient.requestCustomGrant(config).catch(error=>console.log(error));
        });

The requestCustomGrant is failing and the error log looks like,

fl: The custom grant request failed.

Please note that the custom grant request is sending the network call correctly and the response is received correctly.

Response:

{
   "access_token":"eyJ4NXQiOiJNbUV5WlRSaFpH....<clipped>",
   "issued_token_type":"urn:ietf:params:oauth:token-type:jwt",
   "scope":"urn:choreo:0d3780bb-6f09-4020-8cfa-a17d3e46cf22:apim:subscribe urn:choreo:7068fbc7-fa80-4e27-befa-98d8897b7fb9:apim:subscribe",
   "token_type":"Bearer",
   "expires_in":10800
}

Info: I have tried this with session storage and the web worker

Expected behavior:
Custom grant request should pass and the new token should be set as the auth client's token which will be setting in the auth header in subsequent http calls.

Environment information

  • Product Version: react sdk v0.1.4
  • OS: ubuntu 20.04

Allow the sign-in redirect to go back to the page the sign-in was initiated from

Describe the issue:

Currently, the Redirect URL is static. The URL can't be changed to dynamically set the redirect URL. This means that it would always take the user back to the home page after a successful login, even if the user triggers the Asgardeo sign-in from a sub-route.

How to reproduce:

  1. In an app that has Asgardeo sign-in integrated, click-on sign-in inside a sub-route.
  2. Complete the sign-in process
    Asgardeo will redirect the user to the home page (the pre-set redirect URL)

Expected behavior:
Redirect the user to the URL that the user clicked on the sign-in button.

Suggestion:
The SDK could save this redirect URL in session storage. In the SDK, when attempting to redirect, if there is a redirect URL saved in session storage, that could be used. If not, the Redirect URL that was set from the deployment env variables can be used.

Environment information (Please complete the following information; remove any unnecessary fields) :

  • Product Version: 1.1.18

Optional Fields

Related issues:

LSFLK/MedicinesforLK#527

@nipunsampath @anjula-sack

Add fullstack token exchange sample app

Is your suggestion related to an experience ? Please describe.

Currently, in order to use choreo API with Asgardeo as the IDP, we need to perform the token exchange. In this case, if we need to make the exchange in the client side, we can use the @asgardeo/token-exchange-plugin.

However, if the requiremnt is to handle the the exchange in the server side, but the authentication should be handled in the client side, it would be nice to have a sample with the steps required.

Additionally, this task would be related to the serverside sample of the discussed flow - asgardeo/asgardeo-auth-express-sdk#24.

Describe the improvement

Additional context

Support unauthenticated requests to pass through the AsgardeoSPAClient

Is your suggestion related to an experience? Please describe.

We have a requirement, Where some APIs support both Authenticated and unauthenticated access, So that users should be able to call these APIs without sign-in or having an access token.

Describe the improvement

in the current implementation of AsgardeoSPAClient.getInstance().httpRequest() we can invoke an API without sign-in or prior login. This limits the AsgardeoSPAClient usage to use only for authenticated APIs but for unauthenticated/anonymous requests has to use another client.

So it's really helpful if we can allow unauthenticated requests to pass through the client without appending the Authorization header.

Carrot sign (^) is not allowed for passwords

If we try to sign up for Asgardeo using Email and then try to enter a password which includes ^, it redirects to the page shown below.
404

Here according to the given instruction, ^ is considered a valid symbol.
signUP

After that, if we try to add a new customer, and choose to set a temporary password for the user (2nd method) then also we are not allowed to use ^. But here the validation message(prompt) is correct. (it does not include ^ as a special character)
errorDescribed

If we try the first method to add a new customer ( invite the user to set their own password) the issue remains the same.
misLeading

Furthermore, when we enter a password that includes ^, it does not fail any test cases initially.
tryPswWith^

I observed this behaviour for different OS s (Windows & Linux) as well. Hence, we can resolve this issue by allowing the Carrot sign (^) as a valid symbol.

Accommodate custom params through config json.

Is your suggestion related to an experience ? Please describe.
Some sample apps might have the necessity to send custom parameters. Since, these sample apps are used in e2e, though it might be feasible to edit signin method, adding a config for custom parameter in config.json itself and adding this to url if it is not null, will be great in POV of e2e.

Ex:
Adding this to config.json

{
    ...,
    "signInParams": {
        "fidp": "abc",
        "username": "email",
    }
}

And after null check
signIn(authConfig.signInParams, ...);

Additional context
This was actually required in enterprise login flow e2e automation where we have to send custom parameters.

Can't create two auth client instances

Describe the issue:
The getInstance API doesn't create multiple instances.

How to reproduce:

const authClient = AsgardeoSPAClient.getInstance();
const fooAuthClient = AsgardeoSPAClient.getInstance("foo");
// initialize both clients (set configs to use session storage)
// sign in to both clients

on session storage, only one auth client instance can be seen.

Expected behavior:
Both auth client instances should be available on the stoarage (in this case, the session storage)

Environment information (Please complete the following information; remove any unnecessary fields) :

  • Product Version: react sdk 1.0.4
  • OS: ubutnu 20.02
  • Browser: chrome

When try to check whether user had login to the system when website load State updates infinitely

Describe the issue:
When trying to check whether the user had a login to the system when the website State updates infinitely till we get a response back as far as I understood.

Code sample:
https://github.com/LSFLK/MedicinesforLK/blob/development/admin-portal/src/App.tsx#L26

This happens when we have selected workers as our storage option. This works fine for other two storage options (localstorage, session storage)

How to reproduce:

Expected behavior:
If the user logged in update the state to have authenticated true and loading false.
If the user is not logged in redirect the user to the login page.

Environment information (Please complete the following information; remove any unnecessary fields) :

  • Product Version: Latest
  • OS: Mac

Readme contains SPA SDK samples instead of React SDK samples

Is your suggestion related to a missing or misleading document? Please describe.
Here https://github.com/asgardeo/asgardeo-auth-react-sdk#signOut,

It contains examples for signout as,

auth.signOut();

But for react SDK, the sample should be as,


    // Function for handling signin.
    function handleSignIn(){
            signIn();
    }
      
    // Function for handling signout.
    function handleSignOut() {
        signOut()
}
    

Describe the improvement
The examples given in the readme should be updated with React SDK. Now it contains examples from SPA SDK https://github.com/asgardeo/asgardeo-auth-spa-sdk#signout. This issue exists for other examples as well


`react-router-dom` dependency needs to be updated

Describe the issue:

npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR!
npm ERR! While resolving: [email protected]
npm ERR! Found: [email protected]
npm ERR! node_modules/react-router-dom
npm ERR! react-router-dom@"^6.4.3" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer react-router-dom@"^5.2.0" from @asgardeo/[email protected]
npm ERR! node_modules/@asgardeo/auth-react
npm ERR! @asgardeo/auth-react@"^1.1.18" from the root project
npm ERR!
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR!
npm ERR!
npm ERR! For a full report see:
npm ERR! /Users/nuwantissera/.npm/_logs/2022-11-19T16_29_00_480Z-eresolve-report.txt

npm ERR! A complete log of this run can be found in:
npm ERR! /Users/nuwantissera/.npm/_logs/2022-11-19T16_29_00_480Z-debug-0.log

How to reproduce:

Try to npm install and start this project https://github.com/indikasampath2000/cnappdev-e2e-usecase-react-app/pull/1/files

Expected behavior:

Environment information (Please complete the following information; remove any unnecessary fields) :

  • Product Version: [e.g., IS 5.10.0, IS 5.9.0]
  • OS: [e.g., Windows, Linux, Mac]
  • Database: [e.g., MySQL, H2]
  • Userstore: [e.g., LDAP, JDBC]

Optional Fields

Related issues:

Suggested labels:

Configuring endpoints of extenal identity provider is not working

Describe the issue:
Configuring OAuth2.0 endpoints of external identity providers is not getting reflected. Seems like it is always reading the hardcoded endpoints.

How to reproduce

<AuthProvider
        config={ {
            resourceServerURLs: [],
            storage: Storage.SessionStorage,
            signInRedirectURL: "http://localhost:3000",
            signOutRedirectURL: "http://localhost:3000",
            clientID: "<clientid>",
            overrideWellEndpointConfig: true,
            serverOrigin: "<server_origin>",
            endpoints:{
                    authorizationEndpoint:"/authorize",
                    tokenEndpoint:"/oauth/token",
                    userinfoEndpoint:"/userinfo",
                    jwksUri: "/.well-known/jwks"
            }
         
        } }
    >
      { /* Use your own component tree here instead of HomePage.  */ }
      <LandingPage />
    </AuthProvider>

Even though I configured endpoints externally, it is taking the hardcoded endpoints in the class.

This was the authorization request that I could see in the network trace. (I configured /authorize only)

https://<idp_domain>/oauth2/authorize?response_type=code&client_id=<client_id>&scope=openid&redirect_uri=https%3A%2F%2Flocalhost%3A4200&response_mode=query&code_challenge_method=S256&code_challenge=ky83tKxV2DHV3GE984HCGOiF0KZSwqPRab1uk1JfAKc

Screenshot 2021-07-19 at 18 14 38

similar to this wso2-attic/asgardeo-auth-angular-sdk#81

SDK not compatible with react 17.x

Describe the issue:
When tried to install react sdk with reactjs 17.0.2, following error occurred.

npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR! 
npm ERR! While resolving: [email protected]
npm ERR! Found: [email protected]
npm ERR! node_modules/react
npm ERR!   react@"^17.0.2" from the root project
npm ERR! 
npm ERR! Could not resolve dependency:
npm ERR! peer react@"^16.14.0" from @asgardeo/[email protected]
npm ERR! node_modules/@asgardeo/auth-react
npm ERR!   @asgardeo/auth-react@"^0.1.4" from the root project
npm ERR! 
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.

This is because my project is using reactjs 17.x while this SDK depends on reactjs 16.14.x. I can proceed using --force (but not sure about the consequences). But in future, it will be better if we can support reactjs 17.x out of the box.

How to reproduce:
Try installing this SDK on a react 17.x project (a newly created reactjs project using create-react-app)

Expected behavior:
Developers should be able to use this SDK with both 16.x and 17.x reactjs versions.

Environment information (Please complete the following information; remove any unnecessary fields) :

  • Product Version: 0.1.4
  • OS: Linux
  • Database: N/A
  • Userstore:N/A

Optional Fields

Related issues:

Suggested labels:

Need a new API to sign in with a custom grant

Is your feature request related to a problem? Please describe.
When Choreo apim devportal's custom grant request is enabled, it is unable to perform a token refresh. Therefore, a new API is needed to store the token obtained from the orginal idp (choreo idp), use it to exchange the token (custom grant request) and use it to refresh the token.

Use case, current implementation, issues in current implementation and details on the suggested API are documented in [1]

Describe the solution you would prefer
A new API is needed to solve the shortcomings of using the current APIs in sdk. details are documented in [1].

Getting `TextEcoder is not defined` error for NextJs multi-page Application

Describe the issue:
I have been trying to integrate the Asgardeo for NextJs multi-page application. It compiled without any errors. Getting the following error when loading the application.

TextEcoder is not defined

How to reproduce:

Expected behavior:

Environment information (Please complete the following information; remove any unnecessary fields) :

  • Product Version: [e.g., IS 5.10.0, IS 5.9.0]
  • OS: [e.g., Windows, Linux, Mac]
  • Database: [e.g., MySQL, H2]
  • Userstore: [e.g., LDAP, JDBC]

Optional Fields

Related issues:

Suggested labels:

Using httpRequest in SDK cannot send multipart data like file when storage type is Worker

Describe the issue:
When trying to send a formData that has a file with the httpRequest() function available in the React SDK, it fails to upload with the error
failed-to-execute-postmessage-on-worker-formdata-object-could-not-be-cloned

This works fine if changed the storage type in the AuthContext to local storage or session storage.

How to reproduce:

  • Get an example React app.
  • Create a FormData typed object.
  • Append some data ( in this case File object that we received from an upload controller) to FormData object.
  • Attach this as data to the RequestConfig for httpRequest()
  • Do a post call.

Expected behavior:

  • File data to be uploaded to the service.

Environment information (Please complete the following information; remove any unnecessary fields) :

  • Product Version: latest
  • OS: Mac

Change the sub and username resolution in the SDK.

SDK returns the value of the sub as the result for state.username . When the value of the sub is a pseudo identifier, it cannot be qualified as a username.
Hence we need to introduce sub as a different attribute in the state object. And another field for username if it is available in the id_token.

  • introduce state.sub
  • change the resolution of state.username to read username , if not present prefered_name from the SDK. If there is no value for both in the id_token, then leave it empty.

Reference code: https://github.com/asgardeo/asgardeo-auth-js-sdk/blob/f81d533d99a0933d0b83f849aae9699a54ef7a0a/lib/src/utils/authentication-utils.ts#L29

Need to change the references as well.

Replace axios with fetch

Is your suggestion related to an experience ? Please describe.

Using fetch over axios will reduce the bundle size of the sdk. This would improve the cold starts in serverless environments as well.

Here, we should consider providing browser polyfills as well.

Describe the improvement

Additional context

`httpRequest` function in React SDK throws `undefined` (no error object) for some unknow errors

Describe the issue:

We are using httpRequest function as below,

const auth = AsgardeoSPAClient.getInstance();

const response = auth.httpRequest(
{
....
}
)

Following is a sample client configuration

image

How to reproduce:

Expected behavior:

Environment information (Please complete the following information; remove any unnecessary fields) :

  • Product Version: [e.g., IS 5.10.0, IS 5.9.0]
  • OS: [e.g., Windows, Linux, Mac]
  • Database: [e.g., MySQL, H2]
  • Userstore: [e.g., LDAP, JDBC]

Optional Fields

Related issues:

Suggested labels:

Requesting access token failed when login in with a seperate tenant

Describe the issue:
I was trying the sample react ts app, but when trying to login with a separate tenant, access token request fails after the IS login screen.

How to reproduce:

  • Login to IS carbon console https://localhost:9443/carbon
  • Create a new tenant
  • Create a new service provider and configure
  • Update config.json file of the react app with OAuth Client Key and callback url
  • Run sample react app
  • Click login
  • Give tenant admin credentials and login

Screenshot:
Screenshot from 2021-06-14 00-15-34s

Expected behavior:
Redirected to https://localhost:5000/home with access token

Environment information (Please complete the following information; remove any unnecessary fields) :

  • Product Version: IS 5.10.0
  • OS: Ubuntu 18.04.5 LTS
  • Node Version: v12.17.0
  • NPM Version: 6.14.4

Issue while using FormData in httpRequest method

Describe the issue:

An error gets thrown when we try to use the FormData() object to attach the data in Form Data format to a PUT request in the httpRequest method.

How to reproduce:

Asgardeo React SDK version : "@asgardeo/auth-react": "^0.2.6",

Sample code:

  const { httpRequest } = useAuthContext();
  const formData = new FormData();
  formData.append('name', 'john');
  httpRequest({
    url: 'https://red-dream-592.getsandbox.com:443/putuser',
    method: 'PUT',
    data: formData,
  })
    .then((response) => {
      console.log({ response });
    })
    .catch((err) => {
      console.log({ err });
    });

Error:

err: DOMException: Failed to execute 'postMessage' on 'Worker': FormData object could not be cloned. at d (https://localhost:3000/static/js/vendors~main.chunk.js:7962:28) at Object.httpRequest (https://localhost:3000/static/js/vendors~main.chunk.js:8033:37) at _l.<anonymous> (https://localhost:3000/static/js/vendors~main.chunk.js:8367:107) at Generator.next (<anonymous>) at o (https://localhost:3000/static/js/vendors~main.chunk.js:2426:19)
code: 25
message: "Failed to execute 'postMessage' on 'Worker': FormData object could not be cloned."
name: "DataCloneError"

Expected behavior:

Environment information (Please complete the following information; remove any unnecessary fields) :

  • Product Version: [e.g., IS 5.10.0, IS 5.9.0]
  • OS: [e.g., Windows, Linux, Mac]
  • Database: [e.g., MySQL, H2]
  • Userstore: [e.g., LDAP, JDBC]

Optional Fields

Related issues:

Suggested labels:

Code Snippet in Getting Started Section Does Not Compile

Description

The code snippet in the Getting Started section does not compile because the number of arguments does not match in the signIn() method.

Error Message:

ERROR in src/App.tsx:29:16
TS2345: Argument of type '() => void' is not assignable to parameter of type 'SignInConfig'.
  Type '() => void' is not assignable to type 'Record<string, string | boolean>'.
    Index signature for type 'string' is missing in type '() => void'.
    27 |
    28 |     const handleClick = (): void => {
  > 29 |         signIn(() => {
       |                ^^^^^^^
    30 |             setSignedIn(true);
    31 |         });
    32 |     }

Describe the improvement

  • Fix the code snippet by removing the callback function from the signIn() method.

Exchanged token not getting refreshed during token refresh in requestCustomGrant

Describe the issue:
When an application is using a custom grant to do a token exchange, the first token is obtained from a particular IDP and then it is exchanged for another token from another IDP using a token service.

As of now, the SDK initiates a refresh token call whenever a 401 response is received to a network call and gets a new token from the first IDP.
The issue is that although the token from the first IDP is obtained from the refresh token grant, the token exchange with the second IDP doesn't happen and hence, the access token stored in the worker is the token from the first IDP and all other network calls to the backend REST APIs fail since they are expecting a new token from the second IDP.

How to reproduce:

Expected behavior:
When the SDK refreshes a token, it would be expected to see if a custom grant has been configured and if so, initiates the custom grant as well.

Environment information (Please complete the following information; remove any unnecessary fields) :

  • Product Version: [e.g., IS 5.10.0, IS 5.9.0]
  • OS: [e.g., Windows, Linux, Mac]
  • Database: [e.g., MySQL, H2]
  • Userstore: [e.g., LDAP, JDBC]

Optional Fields

Related issues:

Suggested labels:

`isAuthenticated` Returns false even when Signed In Already

Describe the issue:
state.isAuthenticated returns false even after signed into the application successfully. It returns true only if signIn() method invoked manually. i.e. clicking the "Login" button again

How to reproduce:

  1. Setup a ReactJs SPA with Asgardeo configs
  2. Sign into the app
  3. Observe the value of isAuthenticated

Expected behavior:
isAuthenticated should return true if the user has successfully signed in.

Environment information (Please complete the following information; remove any unnecessary fields) :

  • Node Version: 14.20.0
  • OS: macOs
  • npm Version: 6.14.17

Samples running on port `5000` has issues in the new MacOS `Monterey`

Describe the issue:
Mac OS Monterey uses port 5000 for AirPlay Receiver functionality. Hence, the samples should change the running port from 5000 to a safer port and if possible add functionality to give the user ability to offset the port if it's in use.

How to reproduce:

  1. On your Mac with Monterey update (AirPlay-enabled)
  2. Startup any of the samples.

Expected behavior:
Samples should work fine.

Environment information (Please complete the following information; remove any unnecessary fields) :

  • Product Version: -
  • OS: Mac Monterey
  • Database: -
  • Userstore: -

Write unit tests for the SDK and integrate with Github actions

Is your suggestion related to an experience ? Please describe.

The SDK can simply become nonfunctional due to a single commit. Currently there is no automated way of verifying a pr. So it would be great to have unit tests and add a test execution job under github actions PR builder.

Describe the improvement

Additional context

[REACT 18] Race condition in applications when `Strict Mode` is turned on.

Describe the issue:

When @asgardeo/auth-react is used in a React 18 application with strict mode, it goes in to an infinite loop.

loop

How to reproduce:

  1. Create a react app with CRA
  2. Integrate Asgardeo Auth React. (Guide https://wso2.com/asgardeo/docs/get-started/try-your-own-app/react/#prerequisites)

Expected behavior:
The application shouldn't loop.

Additional Context:
This seems to happening due to the ensuring-reusable-state feature in Strict Mode in React 18.

The use effect inside Auth Provider is called twice causing a race condition. (https://github.com/asgardeo/asgardeo-auth-react-sdk/blob/v1.1.15/lib/src/authenticate.tsx#L149)

Logout fails in token exchange flow with "openid" scope

Describe the issue:
The SDK provides a custom grant and that can be used for a token exchange from an STS after the initial login token is obtained.
However, if the user requests the "openid" scope in the custom grant as well, the id_token from the initial login flow would get replaced from the new id_token received from the STS.

The impact of this happens when the user tries to logout. When the logout request is initiated, the id_token that will be sent to the Identity Provider would be the id_token from the STS and hence the logout would fail.

How to reproduce:

  • Login from the IDP
  • Once the token is obtained, perform a token exchange with "openid" scope included.
  • Perform a logout request.

Expected behavior:

Environment information (Please complete the following information; remove any unnecessary fields) :

  • Product Version: [e.g., IS 5.10.0, IS 5.9.0]
  • OS: [e.g., Windows, Linux, Mac]
  • Database: [e.g., MySQL, H2]
  • Userstore: [e.g., LDAP, JDBC]

Optional Fields

Related issues:

Suggested labels:
Priority/High, Bug

App doesn't work when Block third-party cookies enabled

As latest browsers are blocking third party cookies, its good to create the single page app to compatible with that. If not when a person try this app for the first time in an incognito without knowing this will frustrate as the sample is not working

image

Need to be able to retrieve sub from the state

When fixing #58, it seems sub is not added to the state of the SDK.

Since, sub is a 1st class attribute to relate the user in the Issuer by the client, I think we need to be able to retrieve it in the `state.

Session Not Cleared After Logout

Describe the issue:

When login into an application created using asgardeo-auth-react-sdk, a key-value pair session (session_data-instance_0) is created after a successful login. However when the user logout using signout() method provided by sdk, the session_data-instance_0 sill remains in the session storage.

Expected behavior:

User session data in session storage should be removed after a logout.

Environment information (Please complete the following information; remove any unnecessary fields) :

  • Product Version: v1.1.12
  • OS: Mac OS Monterey v12.4
  • Browser: Chrome v103.0.5060.53

Related issues:
wso2-attic/asgardeo-auth-angular-sdk#115

Could not initiate token request when configuring wellknown endpoint for an external identity provider

Describe the issue:

const App = () => (
    <AuthProvider
        config={ {
          signInRedirectURL: "http://localhost:3000",
          signOutRedirectURL: "http://localhost:3000/",
            clientID: "qxVkdTUc50leBKZFj1HnEOGOMbhEtzqx",
            serverOrigin: "https://<idp_domain_name>",
            wellKnownEndpoint: "/.well-known/openid-configuration",
        } }
    >
      { /* Use your own component tree here instead of HomePage.  */ }
      <LandingPage />
    </AuthProvider>
);

Similar to this wso2-attic/asgardeo-auth-angular-sdk#80

Authorization code flow is working as expected. But token flow is not working. there is call to token endpoint in the network trace as well.

AuthorizationRequest:
https://<idp_issuer_value>/authorize?response_type=code&client_id=<clientId>&scope=openid&redirect_uri=https%3A%2F%2Flocalhost%3A3000&response_mode=query&code_challenge_method=S256&code_challenge=-BAT5kFeMw6Mx9ZLZQf5xaW7W320eaiJqWbFJJHm9L0

Response:
https://localhost:3000/?code=5LjrbgCq8rce41wg

Causes an error with Node LTS 18.12.1 - Error: error:0308010C:digital envelope routines::unsupported

Describe the issue:
Running the sample project with Node LTS 18.12.1 the below error will be triggered.

node:internal/crypto/hash:71
  this[kHandle] = new _Hash(algorithm, xofLen);
                  ^

Error: error:0308010C:digital envelope routines::unsupported
    at new Hash (node:internal/crypto/hash:71:19)
    at Object.createHash (node:crypto:133:10)
    at module.exports (/Users/../asgardeo-react-app/node_modules/webpack/lib/util/createHash.js:135:53)
    at NormalModule._initBuildHash (/Users/../asgardeo-react-app/node_modules/webpack/lib/NormalModule.js:417:16)
    at handleParseError (/Users/../asgardeo-react-app/node_modules/webpack/lib/NormalModule.js:471:10)
    at /Users/../asgardeo-react-app/node_modules/webpack/lib/NormalModule.js:503:5
    at /Users/../asgardeo-react-app/node_modules/webpack/lib/NormalModule.js:358:12
    at /Users/../asgardeo-react-app/node_modules/loader-runner/lib/LoaderRunner.js:373:3
    at iterateNormalLoaders (/Users/../asgardeo-react-app/node_modules/loader-runner/lib/LoaderRunner.js:214:10)
    at iterateNormalLoaders (/Users/../asgardeo-react-app/node_modules/loader-runner/lib/LoaderRunner.js:221:10) {
  opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ],
  library: 'digital envelope routines',
  reason: 'unsupported',
  code: 'ERR_OSSL_EVP_UNSUPPORTED'
}

How to reproduce:
Use the Node LTS 18.12.1 and run 'npm install && npm start' in the root folder

Was able to fix the error by exporting 'openssl-legacy-provider'

export NODE_OPTIONS=--openssl-legacy-provider

This error will not occur if the Node.js version is downgraded. Ex - Tried with V16.18.1 and did not face an error

Reason for the issue seems to be that In Node.js v17, a security hole was closed in the SSL provider. This fix was a breaking change that corresponded with similar breaking changes in the SSL packages in NPM. When you attempt to use SSL in Node.js v17 or later without also upgrading those SSL packages in your package.json, then you will see this error.

Uncaught (in promise) Hl: Requesting access token failed at http://localhost:3000/static/js/vendors~main.chunk.js

Describe the issue:

//////////////////////////////////////////////////////////////////////////////////////////////////////
const redirectUrl = http://localhost:3000;

const config = {
signInRedirectURL: redirectUrl,
signOutRedirectURL: redirectUrl,
clientID: CLIENT_ID,
clientSecret: CLIENT_SECRET,
serverOrigin: SERVER_URL,
scope: ['openid'],
prompt: 'login',
};

<AuthProvider config={config} fallback={

Initializing...
}>{children}

//////////////////////////////////////////////////////////////////////////////////////////////////////
const { signIn, state } = useAuthContext();

const authentication = async () => {
try {
await signIn({ disableTrySignInSilently: true });
console.log('signed in');
} catch (e) {
console.log('error', e);
}
};

Request on getting Token was successfully fired (can check it in Network tab into Chrome) but "signIn" line was frozen and console.log didn't call. Also we have got next error in console:

main.js:30 Uncaught (in promise) Hl: Requesting access token failed
at http://localhost:3000/static/js/vendors~main.chunk.js:4801:37

Expected behavior:
I need to get token and trigger when login was successfull

Considerable time takes to resolve user state

Describe the issue:

When the user navigates between routes defined by react-router, the SDK sends a silent sign-in request and followed by a /token request. This process slows down, setting up state variable defined in the AuthContext.

Screenshot 2022-10-15 at 12 48 20

How to reproduce:

  1. Setup a create react app with react router module.
  2. setup the Asgardeo react sdk.
  3. When routing between different routes, it can notice that it takes long to set the values provided by the state parameter.

Expected behavior:

The state values should be loaded as soon as possible without sending API calls.

Environment information (Please complete the following information; remove any unnecessary fields) :

  • OS: Mac
  • react-router-dom: ^6.4.2`
  • React: ^18.2.0

Optional Fields

Related issues:

Suggested labels:

Trailing `/` on `signOutRedirectURL` breaks the application

Describe the issue:

I configured Asgardeo IDP to a react application. I wanted to redirect back to http://localhost:3000 after the user logs out. I mistakenly put http://localhost:3000/ as the signOutRedirectURL and it results in a page like below when the user logs out.
Screenshot 2022-11-15 at 22 35 13

When I remove the /, it worked fine. But ideally (IMO) this shouldn't be validated.

How to reproduce:

Expected behavior:

Environment information (Please complete the following information; remove any unnecessary fields) :

  • Product Version: [e.g., IS 5.10.0, IS 5.9.0]
  • OS: [e.g., Windows, Linux, Mac]
  • Database: [e.g., MySQL, H2]
  • Userstore: [e.g., LDAP, JDBC]

Optional Fields

Related issues:

Suggested labels:

Doesn't give an expected result with response type array-buffer

Describe the issue:
Used SDK to fetch data for Apollo client custom fetch, and used the following configurations for request.

  • Request type: POST
  • Response type: ArrayBuffer

responseType: 'arraybuffer'

Noticed that the array buffer response type doesn't work properly with SDK, instead of an array buffer object it gives an empty object.

How to reproduce:

  1. Make a request with response type array-buffer

Expected behavior:

with Same configuration Axios and Asgardio
image
in asgardio, instead of array buffer object it gives empty object

Environment information (Please complete the following information; remove any unnecessary fields) :

  • Product Version: [e.g., IS 5.10.0, IS 5.9.0]
  • OS: Linux

Document the best practice for passing an obtained id_token to an external service

Is your suggestion related to a missing or misleading document? Please describe.
$subject

Once a user is successfully logged in, what's the best practice to use the retrieved id_token when calling external services? i.e, what's the recommended way to pass the id_token as the Autrhorization header in a request to another service.

Describe the improvement

Update the samples or add some documentation explaining the above.

bundle size too big for React-SDK

Is your suggestion related to an experience? Please describe.

When we did a bundle analysis in our React app which we use @asgardeo/auth-react for auth purposes, It outputs the following result.

image

@asgardeo/auth-react is consuming +500KB which is bigger than the next biggest chunk in our app.
For the comparison, MUI core is under 100KB, React + React-DOM is ~126KB

So IMO +500KB for auth library is an unusually large bundle size.

Describe the improvement

IMHO, We might be packing the resources that @asgardeo/auth-react probably not used in the runtime, So if we can do proper Tree shaking we might able to reduce the bundle size by large amount.

React Router version defined is too harsh

Is your suggestion related to an experience ? Please describe.

ATM, react-router-dom version is set to an exact version, which is not ideal since the router version should be decided by the consuming application.

"react-router-dom": "^5.2.0"

Also, our current Secure Router implementation should support React router v4 & v5 since the API didn't have any breaking changes unlike v6.

Describe the improvement

Change the version to support both v4 & v5.

"react-router-dom": ">=4.x <=5.x"

Unable to call public APIs with httpRequest method in the SDK

Describe the issue:
Getting an error when trying to use httpRequest method from the SDK to call an API which doesn't require any authentication.

How to reproduce:
Call a public API endpoint with the above method
https://github.com/ayshsandu/readers-guild/blob/main/src/components/BookList.js#L35-L38

Expected behavior:
SDK should be able to invoke public APIs as well as secured ones.

Environment information (Please complete the following information; remove any unnecessary fields) :

  • Product Version: [e.g., IS 5.10.0, IS 5.9.0]
  • OS: [e.g., Windows, Linux, Mac]
  • Database: [e.g., MySQL, H2]
  • Userstore: [e.g., LDAP, JDBC]

Optional Fields

Related issues:

Suggested labels:

Add httpRequest functionality to sample apps

Is your suggestion related to an experience ? Please describe.

The sample apps can be improved to have the httpRequest functionality.

Describe the improvement

Currently, SDK docs contain the steps to perform HTTP request. Nevertheless, the sample apps can be further improved to have the httpRequest to showcase the flow of accessing a protected resource.
Ex: calling the basic user info endpoint

Additional context

Not automatic token in production mode

Hello,
I'm trying to use the library to authenticate a wso2 custom service provider.
To achieve this goal I've started following the official documentation so I've created an application in Asgardeo console and so more.
My problem is this one:

  • In development mode I can correctly finish the authentication flow both with asgardeo application or with our custom wso2 provider and have a valid access token;
  • In production mode (deploy on a server), with wso2 or asgardeo app there is no difference, when I complete the auth flow and get back to my callback url I have to click on login button once more to call the /token api and obtain a valid access token but obviusly the source code is the same.
    I like to specify that if I'll run my app with serve library all works correctly. It's only when the webapp is hosted by the server.

What could be the problem?
Here my auth json

{
"clientID": my client id,
"serverOrigin": wso2 or asgardeo,
"signInRedirectURL": my webapp,
"signOutRedirectURL": my webapp,
"storage":"webWorker",
"resourceServerURLs": [backend wso2 api],
"validateIDToken": false
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.