Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix DEV server startup issues & Use @asgardeo/auth-react for authentication #23

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
root = true

[*]
indent_style = space
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
max_line_length = 120
19 changes: 19 additions & 0 deletions .env.local.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Set to true if using HTTPS
HTTPS=true

# The port number to run the application on
PORT=3000

# The client ID of your Asgardeo application
REACT_APP_ASGARDEO_CLIENT_ID=<CLIENT_ID_TAKEN_FROM_ASGARDEO_CONSOLE>

# The base URL of your Asgardeo organization's services.
REACT_APP_ASGARDEO_SERVICES_URL=<BASE_URL_TAKEN_FROM_ASGARDEO_CONSOLE>

# The callback URL to redirect to after successful authentication with Asgardeo
# Ex: https://localhost:3000
REACT_APP_ASGARDEO_LOGIN_CALLBACK_URL=<CALLBACK_URL_AFTER_A_SUCCESSFUL_AUTHENTICATION>

# The callback URL to redirect to after successful logout from Asgardeo
# Ex: https://localhost:3000
REACT_APP_ASGARDEO_LOGOUT_CALLBACK_URL=<CALLBACK_URL_AFTER_A_SUCCESSFUL_LOGOUT>
29 changes: 27 additions & 2 deletions config-overrides.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,33 @@
*
*/

const { addLessLoader, override } = require("customize-cra");
const { override } = require("customize-cra");
const addLessLoader = require("customize-cra-less-loader");
const webpack = require("webpack");

module.exports = override(
addLessLoader()
addLessLoader({
lessLoaderOptions: {
lessOptions: {
javascriptEnabled: true
}
}
}),
(config) => {
config.resolve.fallback = {
...config.resolve.fallback,
stream: require.resolve("stream-browserify"),
buffer: require.resolve("buffer")
};
config.resolve.extensions = [...config.resolve.extensions, ".ts", ".js"];
config.plugins = [
...config.plugins,
new webpack.ProvidePlugin({
process: "process/browser",
Buffer: ["buffer", "Buffer"]
})
];

return config;
}
);
27,250 changes: 14,022 additions & 13,228 deletions package-lock.json

Large diffs are not rendered by default.

15 changes: 10 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"repository": "https://github.com/wso2-incubator/identity-authentication-flow-composer",
"license": "Apache-2.0",
"dependencies": {
"@asgardeo/auth-react": "^1.1.23",
"@monaco-editor/react": "^4.0.11",
"@testing-library/jest-dom": "^5.11.9",
"@testing-library/react": "^11.2.5",
Expand All @@ -22,7 +23,8 @@
"react-flow-renderer": "8.0.0",
"react-icons": "^4.2.0",
"react-redux": "^7.2.2",
"react-scripts": "4.0.2",
"react-router-dom": "^5.3.4",
"react-scripts": "5.0.1",
"redux-thunk": "^2.3.0",
"semantic-ui-css": "^2.4.1",
"semantic-ui-less": "^2.4.1",
Expand All @@ -35,7 +37,6 @@
"build": "react-app-rewired build",
"eject": "react-scripts eject",
"lint": "eslint --ext .js,.jsx,.ts,.tsx .",
"lint:ci": "eslint -c .eslintrc.js $(git diff --diff-filter=d --name-only | grep -E \"(.js$|.ts$|.jsx$|.tsx$)\")",
"start": "react-app-rewired start",
"test": "react-app-rewired test"
},
Expand All @@ -62,15 +63,19 @@
"@types/react-redux": "^7.1.16",
"@typescript-eslint/eslint-plugin": "^4.15.2",
"@typescript-eslint/parser": "^4.15.2",
"buffer": "^6.0.3",
"customize-cra": "^1.0.0",
"customize-cra-less-loader": "^2.0.0",
"eslint": "^7.20.0",
"eslint-loader": "^4.0.2",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-react": "^7.22.0",
"eslint-plugin-react-hooks": "^4.2.0",
"less": "^4.1.1",
"less-loader": "^7.3.0",
"less": "^4.1.3",
"less-loader": "^11.1.0",
"process": "^0.11.10",
"react-app-rewired": "^2.1.8",
"redux-devtools-extension": "^2.13.8"
"redux-devtools-extension": "^2.13.8",
"stream-browserify": "^3.0.0"
}
}
164 changes: 93 additions & 71 deletions src/api/application.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* Copyright (c) 2021, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
* Copyright (c) 2021-2023, WSO2 LLC. (https://www.wso2.com). All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
Expand All @@ -16,9 +16,17 @@
* under the License.
*/

import axios from "axios";
import { AsgardeoSPAClient } from "@asgardeo/auth-react";
import { getApplicationsResourceEndpoints } from "../configs";
import { AuthenticationSequenceInterface } from "../models";
import { AuthenticationSequenceInterface, HttpMethod } from "../models";

/**
* This is a wrapper function for the AsgardeoSPAClient's httpRequest function.
* @function
* @returns {function} - Returns a function that calls AsgardeoSPAClient.getInstance().httpRequest.
*/
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const httpRequest = AsgardeoSPAClient.getInstance()!.httpRequest!.bind(AsgardeoSPAClient.getInstance());

/**
* Gets the application details.
Expand All @@ -30,23 +38,26 @@ import { AuthenticationSequenceInterface } from "../models";
* TODO: Use this function to get the application details to show the existing authentication flow of the application
* from the console when the Authentication Flow Composer opens
*/
export const getApplicationDetails = (appId:string|null) : Promise<any> => {
return axios.get(
`${getApplicationsResourceEndpoints().applications}${appId}`,
{
headers: {
"Accept": "application/json",
"Authorization": "Basic YWRtaW46YWRtaW4="
export const getApplicationDetails = (appId: string | null): Promise<any> => {
const requestConfig = {
headers: {
Accept: "application/json"
},
method: HttpMethod.GET,
url: `${getApplicationsResourceEndpoints().applications}${appId}`
};

return httpRequest(requestConfig)
.then((response) => {
if (response?.status !== 200) {
return Promise.reject(new Error("Failed to update authentication sequence"));
}
}
).then((response) => {
if (response.status !== 200) {
return Promise.reject(new Error("Failed to update authentication sequence"));
}
return Promise.resolve(response);
}).catch((error) => {
return Promise.reject(error);
});

return Promise.resolve(response);
})
.catch((error) => {
return Promise.reject(error);
});
};

/**
Expand All @@ -56,25 +67,28 @@ export const getApplicationDetails = (appId:string|null) : Promise<any> => {
*
* @return {Promise<any>} A promise containing the response.
*/
export const getAuthenticators = (type?:string) : Promise<any> => {
return axios.get(
type === "idp"
export const getAuthenticators = (type?: string): Promise<any> => {
const requestConfig = {
headers: {
Accept: "application/json"
},
method: HttpMethod.GET,
url: type === "idp"
? getApplicationsResourceEndpoints().identityProviders
: getApplicationsResourceEndpoints().authenticators,
{
headers: {
"Accept": "application/json",
"Authorization": "Basic YWRtaW46YWRtaW4="
: getApplicationsResourceEndpoints().authenticators
};

return httpRequest(requestConfig)
.then((response) => {
if (response?.status !== 200) {
return Promise.reject(new Error("Failed to update authentication sequence"));
}
}
).then((response) => {
if (response.status !== 200) {
return Promise.reject(new Error("Failed to update authentication sequence"));
}
return Promise.resolve(response);
}).catch((error) => {
return Promise.reject(error);
});

return Promise.resolve(response);
})
.catch((error) => {
return Promise.reject(error);
});
};

/**
Expand All @@ -85,23 +99,27 @@ export const getAuthenticators = (type?:string) : Promise<any> => {
* Current implementation use templates from templates.json
* TODO: Use this function to get the templates from the server.
*/
export const getTemplates = () : Promise<any> => {
return axios.get(
getApplicationsResourceEndpoints().templates,
{
headers: {
"Accept": "application/json",
"Authorization": "Basic YWRtaW46YWRtaW4="
export const getTemplates = (): Promise<any> => {
const httpRequestConfig = {
headers: {
Accept: "application/json"
},
method: HttpMethod.GET,
url: getApplicationsResourceEndpoints().templates

};

return httpRequest(httpRequestConfig)
.then((response) => {
if (response?.status !== 200) {
return Promise.reject(new Error("Failed to get templates"));
}
}
).then((response) => {
if (response.status !== 200) {
return Promise.reject(new Error("Failed to get templates"));
}
return Promise.resolve(response);
}).catch((error) => {
return Promise.reject(error);
});

return Promise.resolve(response);
})
.catch((error) => {
return Promise.reject(error);
});
};

/**
Expand All @@ -113,23 +131,27 @@ export const getTemplates = () : Promise<any> => {
* @return {Promise<any>} A promise containing the response.
*/
export const updateAuthenticationSequence = (
authenticationSequence: AuthenticationSequenceInterface, appId: string|null
) : Promise<any> => {
return axios.patch(
`${getApplicationsResourceEndpoints().applications}${appId}`,
{ authenticationSequence: authenticationSequence },
{
headers: {
"Accept": "application/json",
"Authorization": "Basic YWRtaW46YWRtaW4="
authenticationSequence: AuthenticationSequenceInterface,
appId: string | null
): Promise<any> => {
const requestConfig = {
body: { authenticationSequence },
headers: {
Accept: "application/json"
},
method: HttpMethod.PATCH,
url: `${getApplicationsResourceEndpoints().applications}${appId}`
};

return httpRequest(requestConfig)
.then((response) => {
if (response?.status !== 200) {
return Promise.reject(new Error("Failed to update authentication sequence"));
}
}
).then((response) => {
if (response.status !== 200) {
return Promise.reject(new Error("Failed to update authentication sequence"));
}
return Promise.resolve(response);
}).catch((error) => {
return Promise.reject(error);
});

return Promise.resolve(response);
})
.catch((error) => {
return Promise.reject(error);
});
};
39 changes: 31 additions & 8 deletions src/app.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* Copyright (c) 2021, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
* Copyright (c) 2021-2023, WSO2 LLC. (https://www.wso2.com). All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
Expand All @@ -16,23 +16,46 @@
* under the License.
*/

import React, { FunctionComponent, ReactElement } from "react";
import { AppHeader, ScriptBasedFlow, Sidebar, VisualFlow } from "./components";
import { useAuthContext } from "@asgardeo/auth-react";
import React, { FunctionComponent, ReactElement, useEffect } from "react";
import { AppHeader, PreLoader, ScriptBasedFlow, Sidebar, VisualFlow } from "./components";

/**
* Main App component.
*
* @return {React.ReactElement}
*/
export const App: FunctionComponent = (): ReactElement => {
const { state, trySignInSilently, signIn } = useAuthContext();
const { isAuthenticated, isLoading } = state;

useEffect(() => {
if (isAuthenticated || isLoading) {
return;
}

trySignInSilently()
.then((response) => {
if (!response) {
signIn();
}
})
.catch(() => {
signIn();
});
}, [isAuthenticated, isLoading, signIn, trySignInSilently]);

if (isLoading || !isAuthenticated) {
return <PreLoader />;
}

return (
<div className="app">
<AppHeader/>
<AppHeader />
<div className="app-body">
<Sidebar/>
<VisualFlow/>
<ScriptBasedFlow/>
<Sidebar />
<VisualFlow />
<ScriptBasedFlow />
</div>
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion src/components/core/header/app-header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

import { File } from "@babel/types";
import React, { FunctionComponent, ReactElement, useEffect, useState } from "react";
import { VscDebugRestart } from "react-icons/all";
import { VscDebugRestart } from "react-icons/vsc";
import { shallowEqual, useSelector } from "react-redux";
import { getAuthenticators, updateAuthenticationSequence } from "../../../api";
import Icon from "../../../assets/asgardeo-logo.svg";
Expand Down
Loading