mirror of
https://github.com/ivanpaulovich/clean-architecture-manga.git
synced 2025-01-07 03:17:10 +08:00
React (#247) @Franpastoragusti
Thanks to @Franpastoragusti for the amazing app https://github.com/Franpastoragusti/oidc-react-app
This commit is contained in:
parent
381fd74c9d
commit
3f7021e775
11
.vscode/launch.json
vendored
11
.vscode/launch.json
vendored
@ -5,8 +5,8 @@
|
||||
"version": "0.2.0",
|
||||
"compounds": [
|
||||
{
|
||||
"name": "Identity Server & Accounts API & SPA",
|
||||
"configurations": ["Accounts API", "Identity Server", "SPA"]
|
||||
"name": "Solution",
|
||||
"configurations": ["Accounts API", "Identity Server", "Start SPA", "Debug SPA"]
|
||||
}
|
||||
],
|
||||
"configurations": [
|
||||
@ -30,7 +30,7 @@
|
||||
"ASPNETCORE_URLS": "https://localhost:5000",
|
||||
"ASPNETCORE_HTTPS_PORT": "5000",
|
||||
"IDENTITY_SERVER_ORIGIN": "https://localhost:5000",
|
||||
"RedirectUris": "https://localhost:5002/callback",
|
||||
"RedirectUris": "https://localhost:5002/signin-oidc",
|
||||
"PostLogoutRedirectUris": "https://localhost:5002",
|
||||
"AllowedCorsOrigins": "https://localhost:5002"
|
||||
},
|
||||
@ -65,7 +65,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "SPA",
|
||||
"name": "Start SPA",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"cwd": "${workspaceFolder}/wallet-spa",
|
||||
@ -77,7 +77,8 @@
|
||||
"request": "launch",
|
||||
"name": "Debug SPA",
|
||||
"url": "https://localhost:5002",
|
||||
"webRoot": "${workspaceFolder}/wallet-spa"
|
||||
"webRoot": "${workspaceFolder}/wallet-spa",
|
||||
"runtimeExecutable": "canary"
|
||||
},
|
||||
{
|
||||
"name": "Accounts API (Docker)",
|
||||
|
@ -1,6 +1,14 @@
|
||||
REACT_APP_AUTHORITY=https://localhost:5000
|
||||
REACT_APP_REDIRECT_URI=https://localhost:5002/callback
|
||||
REACT_APP_POST_LOGOUT_REDIRECT_URI=https://localhost:5002
|
||||
REACT_APP_ACCOUNTS_API=https://localhost:5001
|
||||
HTTPS=true
|
||||
PORT=5002
|
||||
REACT_APP_ACCOUNTS_API=https://localhost:5001
|
||||
REACT_APP_AUDIENCE=https://localhost:5000
|
||||
REACT_APP_AUTH_URL=https://localhost:5000
|
||||
REACT_APP_AUTHORITY=https://localhost:5000
|
||||
REACT_APP_IDENTITY_CLIENT_ID=spa
|
||||
REACT_APP_ISSUER=https://localhost:5000
|
||||
REACT_APP_LOGOFF_REDIRECT_URL=https://localhost:5002/logout
|
||||
REACT_APP_POST_LOGOUT_REDIRECT_URI=https://localhost:5002/logout/callback
|
||||
REACT_APP_REDIRECT_URI=https://localhost:5002/signin-oidc
|
||||
REACT_APP_REDIRECT_URL=https://localhost:5002/signin-oidc
|
||||
REACT_APP_SCOPE=openid profile api1.full_access
|
||||
REACT_APP_SILENT_REDIRECT_URL=https://localhost:5002/silentrenew
|
||||
|
@ -1,18 +1,14 @@
|
||||
import "./App.css";
|
||||
import React from "react";
|
||||
import { Component } from "react";
|
||||
import Layout from "./components/Layout";
|
||||
import React, { Component } from "react";
|
||||
import { AuthProvider } from "./providers/authProvider";
|
||||
import { BrowserRouter } from "react-router-dom";
|
||||
import { Routes } from "./routes/routes";
|
||||
|
||||
export default class App extends Component {
|
||||
static displayName = App.name;
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Layout openIdManager={this.props.openIdManager}/>
|
||||
<AuthProvider>
|
||||
<BrowserRouter children={Routes} basename={"/"} />
|
||||
</AuthProvider>
|
||||
)
|
||||
};
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import App from './App';
|
||||
|
||||
test('renders learn react link', () => {
|
||||
const { getByText } = render(<App />);
|
||||
const linkElement = getByText(/learn react/i);
|
||||
expect(linkElement).toBeInTheDocument();
|
||||
});
|
@ -95,10 +95,6 @@ const styles = (theme) => ({
|
||||
|
||||
class Header extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
const { handleChangeNavDrawer, navDrawerOpen, classes } = this.props
|
||||
|
@ -6,7 +6,7 @@ import SideMenu from "../components/SideMenu";
|
||||
import Footer from "../components/Footer";
|
||||
import MainContent from "../components/MainContent";
|
||||
import { ThemeProvider } from "@material-ui/core/styles";
|
||||
import defaultTheme, { customTheme } from "../theme";
|
||||
import defaultTheme from "../theme";
|
||||
import classNames from "classnames";
|
||||
|
||||
const styles = () => ({
|
||||
@ -69,10 +69,9 @@ class Layout extends React.Component {
|
||||
return (
|
||||
<ThemeProvider theme={theme}>
|
||||
<Header handleChangeNavDrawer={this.handleChangeNavDrawer} navDrawerOpen={navDrawerOpen} />
|
||||
<SideMenu openIdManager={this.props.openIdManager} navDrawerOpen={navDrawerOpen}
|
||||
handleChangeNavDrawer={this.handleChangeNavDrawer} />
|
||||
<SideMenu navDrawerOpen={navDrawerOpen} handleChangeNavDrawer={this.handleChangeNavDrawer} />
|
||||
<div className={classNames(classes.container, !navDrawerOpen && classes.containerFull)}>
|
||||
<MainContent openIdManager={this.props.openIdManager} />
|
||||
<MainContent />
|
||||
</div>
|
||||
<Footer />
|
||||
</ThemeProvider>
|
||||
|
@ -6,7 +6,6 @@ import {
|
||||
import { Container } from 'reactstrap';
|
||||
import Accounts from "../pages/Accounts";
|
||||
import Account from "../pages/Account";
|
||||
import { AuthCallback } from "../pages/AuthCallback";
|
||||
import OpenAccount from "../pages/OpenAccount";
|
||||
import Deposit from "../pages/Deposit";
|
||||
import Withdraw from "../pages/Withdraw";
|
||||
@ -41,68 +40,17 @@ const styles = theme => ({
|
||||
});
|
||||
|
||||
class MainContent extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Container>
|
||||
<Route
|
||||
exact
|
||||
path="/OpenAccount"
|
||||
render={() => {
|
||||
return <OpenAccount openIdManager={this.props.openIdManager} />;
|
||||
}}
|
||||
/>
|
||||
<Route
|
||||
exact
|
||||
path="/"
|
||||
render={() => {
|
||||
return <Accounts openIdManager={this.props.openIdManager} />;
|
||||
}}
|
||||
/>
|
||||
<Route
|
||||
exact
|
||||
path="/accounts/:accountId/close"
|
||||
render={() => {
|
||||
return <CloseAccount openIdManager={this.props.openIdManager} />;
|
||||
}}
|
||||
/>
|
||||
<Route
|
||||
exact
|
||||
path="/accounts/:accountId/transfer"
|
||||
render={() => {
|
||||
return <Transfer openIdManager={this.props.openIdManager} />;
|
||||
}}
|
||||
/>
|
||||
<Route
|
||||
exact
|
||||
path="/accounts/:accountId/deposit"
|
||||
render={() => {
|
||||
return <Deposit openIdManager={this.props.openIdManager} />;
|
||||
}}
|
||||
/>
|
||||
<Route
|
||||
exact
|
||||
path="/accounts/:accountId/withdraw"
|
||||
render={() => {
|
||||
return <Withdraw openIdManager={this.props.openIdManager} />;
|
||||
}}
|
||||
/>
|
||||
<Route
|
||||
exact
|
||||
path="/accounts/:accountId"
|
||||
render={() => {
|
||||
return <Account openIdManager={this.props.openIdManager} />;
|
||||
}}
|
||||
/>
|
||||
<Route
|
||||
path="/callback"
|
||||
render={() => {
|
||||
return <AuthCallback />;
|
||||
}}
|
||||
/>
|
||||
<Route exact={true} path="/dashboard/openaccount" component={OpenAccount} />
|
||||
<Route exact={true} path="/dashboard/accounts/:accountId/close" component={CloseAccount} />
|
||||
<Route exact={true} path="/dashboard/accounts/:accountId/transfer" component={Transfer} />
|
||||
<Route exact={true} path="/dashboard/accounts/:accountId/deposit" component={Deposit} />
|
||||
<Route exact={true} path="/dashboard/accounts/:accountId/withdraw" component={Withdraw} />
|
||||
<Route exact={true} path="/dashboard/accounts/:accountId" component={Account} />
|
||||
<Route exact={true} path="/dashboard" component={Accounts} />
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
|
@ -4,16 +4,15 @@ import List from "@material-ui/core/List";
|
||||
import ListItem from "@material-ui/core/ListItem";
|
||||
import ListItemIcon from "@material-ui/core/ListItemIcon";
|
||||
import ListItemText from "@material-ui/core/ListItemText";
|
||||
import AccountCircle from "@material-ui/icons/AccountCircle";
|
||||
import HomeIcon from '@material-ui/icons/Home';
|
||||
import AccountBalanceIcon from '@material-ui/icons/AccountBalance';
|
||||
import ExitToApp from "@material-ui/icons/ExitToApp";
|
||||
import AddIcon from '@material-ui/icons/Add';
|
||||
import { Avatar } from "@material-ui/core";
|
||||
import { Grid } from "@material-ui/core";
|
||||
import { withStyles } from "@material-ui/core/styles";
|
||||
import classNames from "classnames";
|
||||
import { fade } from "@material-ui/core/styles/colorManipulator";
|
||||
import { AuthConsumer } from "../providers/authProvider"
|
||||
import AuthService from "../store/authService";
|
||||
|
||||
const drawStyles = theme => {
|
||||
return {
|
||||
@ -80,17 +79,6 @@ const drawStyles = theme => {
|
||||
color: "white",
|
||||
boxShadow: "rgba(0, 0, 0, 0.16) 0px 3px 10px, rgba(0, 0, 0, 0.23) 0px 3px 10px"
|
||||
},
|
||||
menuItem: {
|
||||
padding: "10px 16px",
|
||||
color: "white",
|
||||
fontSize: 14,
|
||||
"&:focus": {
|
||||
backgroundColor: theme.palette.primary.main,
|
||||
"& .MuiListItemIcon-root, & .MuiListItemText-primary": {
|
||||
color: theme.palette.common.white
|
||||
}
|
||||
}
|
||||
},
|
||||
miniMenuItem: {
|
||||
color: "white",
|
||||
margin: "10px 0",
|
||||
@ -114,31 +102,33 @@ const drawStyles = theme => {
|
||||
};
|
||||
|
||||
class SideMenu extends Component {
|
||||
|
||||
authService;
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
isLoggedIn: false,
|
||||
user: null
|
||||
user: {
|
||||
profile: {
|
||||
name: ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.performLogin = this.performLogin.bind(this);
|
||||
this.performLogout = this.performLogout.bind(this);
|
||||
this.authService = new AuthService();
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.props.openIdManager.getUser().then((user) => {
|
||||
if (user) {
|
||||
this.setState({ isLoggedIn: true, user: user });
|
||||
} else {
|
||||
this.setState({ isLoggedIn: false, user: null });
|
||||
}
|
||||
});
|
||||
this.authService
|
||||
.getUser()
|
||||
.then((user) => {
|
||||
this.setState({ user: user });
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const { user } = this.state;
|
||||
const { classes, navDrawerOpen, handleChangeNavDrawer } = this.props;
|
||||
const { classes, navDrawerOpen } = this.props;
|
||||
return (
|
||||
<div>
|
||||
<Drawer
|
||||
@ -146,17 +136,38 @@ class SideMenu extends Component {
|
||||
variant="permanent"
|
||||
classes={{
|
||||
paper: classNames(classes.drawerPaper, !navDrawerOpen && classes.drawerPaperClose)
|
||||
}}
|
||||
>
|
||||
|
||||
}} >
|
||||
<div>
|
||||
<div className={classes.logo}>My Wallet</div>
|
||||
{this.state.isLoggedIn && <div className={classNames(classes.avatarRoot, !navDrawerOpen && classes.avatarRootMini)}>
|
||||
<div className={classNames(classes.avatarRoot, !navDrawerOpen && classes.avatarRootMini)}>
|
||||
<Avatar size={navDrawerOpen ? 48 : 32} classes={{ root: classes.avatarIcon }} />
|
||||
<span className={classes.avatarSpan}>{user.profile.name}</span>
|
||||
</div>}
|
||||
<span className={classes.avatarSpan}>{this.state.user.profile.name}</span>
|
||||
</div>
|
||||
<List>
|
||||
{this.state.isLoggedIn ? this.renderWhenTrue() : this.renderWhenFalse()}
|
||||
<ListItem button component="a" href="/Dashboard">
|
||||
<ListItemIcon style={{ color: "white" }}>
|
||||
<AccountBalanceIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary="My Accounts" />
|
||||
</ListItem>
|
||||
<ListItem button component="a" href="/Dashboard/OpenAccount">
|
||||
<ListItemIcon style={{ color: "white" }}>
|
||||
<AddIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary="Open an Account" />
|
||||
</ListItem>
|
||||
<ListItem button>
|
||||
<ListItemIcon style={{ color: "white" }}>
|
||||
<ExitToApp />
|
||||
</ListItemIcon>
|
||||
<AuthConsumer>
|
||||
{({ logout }) => {
|
||||
return (
|
||||
<ListItemText primary="Sign Out" onClick={logout} />
|
||||
);
|
||||
}}
|
||||
</AuthConsumer>
|
||||
</ListItem>
|
||||
</List>
|
||||
</div>
|
||||
|
||||
@ -164,52 +175,6 @@ class SideMenu extends Component {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderWhenTrue() {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<ListItem button component="a" href="/">
|
||||
<ListItemIcon style={{ color: "white" }}>
|
||||
<AccountBalanceIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary="My Accounts" />
|
||||
</ListItem>
|
||||
<ListItem button component="a" href="/OpenAccount">
|
||||
<ListItemIcon style={{ color: "white" }}>
|
||||
<AddIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary="Open an Account" />
|
||||
</ListItem>
|
||||
<ListItem button>
|
||||
<ListItemIcon style={{ color: "white" }}>
|
||||
<ExitToApp />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary="Sign Out" onClick={this.performLogout} />
|
||||
</ListItem>
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
renderWhenFalse() {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<ListItem button>
|
||||
<ListItemIcon style={{ color: "white" }}>
|
||||
<AccountCircle />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary="Sign In" onClick={this.performLogin} />
|
||||
</ListItem>
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
performLogin() {
|
||||
this.props.openIdManager.signinRedirect();
|
||||
}
|
||||
|
||||
performLogout() {
|
||||
this.props.openIdManager.signoutRedirect();
|
||||
}
|
||||
}
|
||||
|
||||
export default withStyles(drawStyles, { withTheme: true })(SideMenu);
|
12
wallet-spa/src/components/auth/callback.jsx
Normal file
12
wallet-spa/src/components/auth/callback.jsx
Normal file
@ -0,0 +1,12 @@
|
||||
import * as React from "react";
|
||||
|
||||
import { AuthConsumer } from "../../providers/authProvider";
|
||||
|
||||
export const Callback = () => (
|
||||
<AuthConsumer>
|
||||
{({ signinRedirectCallback }) => {
|
||||
signinRedirectCallback();
|
||||
return <span>loading</span>;
|
||||
}}
|
||||
</AuthConsumer>
|
||||
);
|
11
wallet-spa/src/components/auth/logout.jsx
Normal file
11
wallet-spa/src/components/auth/logout.jsx
Normal file
@ -0,0 +1,11 @@
|
||||
import * as React from "react";
|
||||
import { AuthConsumer } from "../../providers/authProvider";
|
||||
|
||||
export const Logout = () => (
|
||||
<AuthConsumer>
|
||||
{({ logout }) => {
|
||||
logout();
|
||||
return <span>loading</span>;
|
||||
}}
|
||||
</AuthConsumer>
|
||||
);
|
11
wallet-spa/src/components/auth/logoutCallback.jsx
Normal file
11
wallet-spa/src/components/auth/logoutCallback.jsx
Normal file
@ -0,0 +1,11 @@
|
||||
import React from "react";
|
||||
import { AuthConsumer } from "../../providers/authProvider";
|
||||
|
||||
export const LogoutCallback = () => (
|
||||
<AuthConsumer>
|
||||
{({ signoutRedirectCallback }) => {
|
||||
signoutRedirectCallback();
|
||||
return <span>loading</span>;
|
||||
}}
|
||||
</AuthConsumer>
|
||||
);
|
9
wallet-spa/src/components/auth/register.jsx
Normal file
9
wallet-spa/src/components/auth/register.jsx
Normal file
@ -0,0 +1,9 @@
|
||||
import React from 'react';
|
||||
|
||||
export const Register = () => {
|
||||
return (
|
||||
<div>
|
||||
register
|
||||
</div>
|
||||
);
|
||||
};
|
12
wallet-spa/src/components/auth/silentRenew.jsx
Normal file
12
wallet-spa/src/components/auth/silentRenew.jsx
Normal file
@ -0,0 +1,12 @@
|
||||
import React from "react";
|
||||
|
||||
import { AuthConsumer } from "../../providers/authProvider";
|
||||
|
||||
export const SilentRenew = () => (
|
||||
<AuthConsumer>
|
||||
{({ signinSilentCallback }) => {
|
||||
signinSilentCallback();
|
||||
return <span>loading</span>;
|
||||
}}
|
||||
</AuthConsumer>
|
||||
);
|
8
wallet-spa/src/components/privatePage.jsx
Normal file
8
wallet-spa/src/components/privatePage.jsx
Normal file
@ -0,0 +1,8 @@
|
||||
import React from 'react';
|
||||
import Layout from './Layout'
|
||||
|
||||
export const PrivatePage = () => {
|
||||
return (
|
||||
<Layout />
|
||||
);
|
||||
};
|
54
wallet-spa/src/components/publicPage.jsx
Normal file
54
wallet-spa/src/components/publicPage.jsx
Normal file
@ -0,0 +1,54 @@
|
||||
|
||||
import React from "react";
|
||||
import {
|
||||
Button,
|
||||
Grid,
|
||||
Paper,
|
||||
AppBar,
|
||||
Typography,
|
||||
Toolbar,
|
||||
} from "@material-ui/core";
|
||||
import { AuthConsumer } from "../providers/authProvider"
|
||||
|
||||
export const PublicPage = () => (
|
||||
<div>
|
||||
<AppBar position="static" alignitems="center" color="primary">
|
||||
<Toolbar>
|
||||
<Grid container justify="center" wrap="wrap">
|
||||
<Grid item>
|
||||
<Typography variant="h6">Clean Architecture Manga</Typography>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Toolbar>
|
||||
</AppBar>
|
||||
<Grid container spacing={0} justify="center" direction="row">
|
||||
<Grid item>
|
||||
<Grid
|
||||
container
|
||||
direction="column"
|
||||
justify="center"
|
||||
spacing={2}
|
||||
className="login-form"
|
||||
>
|
||||
<Paper
|
||||
variant="elevation"
|
||||
elevation={2}
|
||||
className="login-background"
|
||||
>
|
||||
<Grid item>
|
||||
<AuthConsumer>
|
||||
{({ signinRedirect }) => {
|
||||
return <Button variant="contained" color="primary" type="submit" className="button-block" onClick={signinRedirect}>Sign In</Button>;
|
||||
}}
|
||||
</AuthConsumer>
|
||||
</Grid>
|
||||
</Paper>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</div>
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
@ -1,31 +1,11 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
import App from './App';
|
||||
import * as serviceWorker from './serviceWorker';
|
||||
import * as Oidc from "oidc-client";
|
||||
import "./styles.scss";
|
||||
import "font-awesome/css/font-awesome.css";
|
||||
|
||||
const baseUrl = document.getElementsByTagName('base')[0].getAttribute('href');
|
||||
const rootElement = document.getElementById('root');
|
||||
|
||||
const config = {
|
||||
authority: process.env.REACT_APP_AUTHORITY,
|
||||
client_id: "spa",
|
||||
redirect_uri: process.env.REACT_APP_REDIRECT_URI,
|
||||
response_type: "code",
|
||||
scope: "openid profile api1.full_access",
|
||||
post_logout_redirect_uri: process.env.REACT_APP_POST_LOGOUT_REDIRECT_URI,
|
||||
};
|
||||
|
||||
const openIdManager = new Oidc.UserManager(config);
|
||||
|
||||
ReactDOM.render(
|
||||
<BrowserRouter basename={baseUrl}>
|
||||
<App openIdManager={openIdManager} />
|
||||
</BrowserRouter>,
|
||||
rootElement);
|
||||
ReactDOM.render(<App />, document.getElementById('root'));
|
||||
|
||||
// If you want your app to work offline and load faster, you can change
|
||||
// unregister() to register() below. Note this comes with some pitfalls.
|
||||
|
@ -33,19 +33,15 @@ class Account extends React.Component {
|
||||
}
|
||||
|
||||
fetchData = id => {
|
||||
this.props.openIdManager.getUser().then((user) => {
|
||||
if (user) {
|
||||
accountsService
|
||||
.getAccount(user, id)
|
||||
.then((response) => {
|
||||
this.setState(response.data);
|
||||
console.log(response.data);
|
||||
})
|
||||
.catch((e) => {
|
||||
console.log(e);
|
||||
});
|
||||
}
|
||||
});
|
||||
accountsService
|
||||
.getAccount(id)
|
||||
.then((response) => {
|
||||
this.setState(response.data);
|
||||
console.log(response.data);
|
||||
})
|
||||
.catch((e) => {
|
||||
console.log(e);
|
||||
});
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
@ -166,19 +162,19 @@ class Account extends React.Component {
|
||||
|
||||
<div style={styles.buttons}>
|
||||
|
||||
<Button component={Link} to={`/accounts/${this.state.accountId}/Deposit`} variant="contained" color="primary">
|
||||
<Button component={Link} to={`/dashboard/accounts/${this.state.accountId}/Deposit`} variant="contained" color="primary">
|
||||
Deposit
|
||||
</Button>
|
||||
|
||||
<Button component={Link} to={`/accounts/${this.state.accountId}/Withdraw`} variant="contained" color="primary">
|
||||
<Button component={Link} to={`/dashboard/accounts/${this.state.accountId}/Withdraw`} variant="contained" color="primary">
|
||||
Withdraw
|
||||
</Button>
|
||||
|
||||
<Button component={Link} to={`/accounts/${this.state.accountId}/Transfer`} variant="contained" color="primary">
|
||||
<Button component={Link} to={`/dashboard/accounts/${this.state.accountId}/Transfer`} variant="contained" color="primary">
|
||||
Transfer
|
||||
</Button>
|
||||
|
||||
<Button component={Link} to={`/accounts/${this.state.accountId}/Close`} variant="contained" color="secondary">
|
||||
<Button component={Link} to={`/dashboard/accounts/${this.state.accountId}/Close`} variant="contained" color="secondary">
|
||||
Close
|
||||
</Button>
|
||||
|
||||
|
@ -20,22 +20,18 @@ class Accounts extends React.Component {
|
||||
this.state = {
|
||||
accounts: []
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.props.openIdManager.getUser().then((user) => {
|
||||
if (user) {
|
||||
accountsService
|
||||
.getAccounts(user)
|
||||
.then((response) => {
|
||||
this.setState(response.data);
|
||||
console.log(response.data);
|
||||
})
|
||||
.catch((e) => {
|
||||
console.log(e);
|
||||
});
|
||||
}
|
||||
});
|
||||
accountsService
|
||||
.getAccounts()
|
||||
.then((response) => {
|
||||
this.setState(response.data);
|
||||
console.log(response.data);
|
||||
})
|
||||
.catch((e) => {
|
||||
console.log(e);
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
@ -60,7 +56,7 @@ class Accounts extends React.Component {
|
||||
this.state.accounts.map((account) => {
|
||||
return (
|
||||
<TableRow key={account.accountId}>
|
||||
<TableCell><a className="text-dark" href={`/accounts/${account.accountId}`}>{account.accountId}</a></TableCell>
|
||||
<TableCell><a className="text-dark" href={`/dashboard/accounts/${account.accountId}`}>{account.accountId}</a></TableCell>
|
||||
<TableCell>{account.currentBalance}</TableCell>
|
||||
<TableCell>{account.currency}</TableCell>
|
||||
</TableRow>
|
||||
|
@ -1,31 +0,0 @@
|
||||
import React, { PureComponent } from "react";
|
||||
import * as Oidc from "oidc-client";
|
||||
import { Redirect } from "react-router-dom";
|
||||
|
||||
export class AuthCallback extends PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
redirect: false,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
new Oidc.UserManager({ response_mode: "query" })
|
||||
.signinRedirectCallback()
|
||||
.then(() => {
|
||||
this.setState({ redirect: true });
|
||||
})
|
||||
.catch(function (e) {
|
||||
console.error(e);
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.state.redirect) {
|
||||
return <Redirect to="/" push />;
|
||||
}
|
||||
|
||||
return <div>Redirecting...</div>;
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ import PageBase from "../components/PageBase";
|
||||
import { Link } from "react-router-dom";
|
||||
import Button from "@material-ui/core/Button";
|
||||
import { grey } from "@material-ui/core/colors";
|
||||
import {Redirect} from "react-router-dom";
|
||||
|
||||
class CloseAccount extends React.Component {
|
||||
|
||||
@ -34,21 +35,17 @@ class CloseAccount extends React.Component {
|
||||
};
|
||||
|
||||
saveCloseAccount = () => {
|
||||
this.props.openIdManager.getUser().then((user) => {
|
||||
if (user) {
|
||||
accountsService
|
||||
.closeAccount(user, this.state.accountId)
|
||||
.then(response => {
|
||||
this.setState({
|
||||
accountId: response.data.accountId,
|
||||
submitted: true
|
||||
});
|
||||
})
|
||||
.catch(e => {
|
||||
console.log(e);
|
||||
});
|
||||
}
|
||||
})
|
||||
accountsService
|
||||
.closeAccount(this.state.accountId)
|
||||
.then(response => {
|
||||
this.setState({
|
||||
accountId: response.data.accountId,
|
||||
submitted: true
|
||||
});
|
||||
})
|
||||
.catch(e => {
|
||||
console.log(e);
|
||||
});
|
||||
};
|
||||
|
||||
newCloseAccount = () => {
|
||||
@ -83,20 +80,8 @@ class CloseAccount extends React.Component {
|
||||
<PageBase title="Close Account" navigation="My Accounts / Close Account">
|
||||
|
||||
{this.state.submitted ? (
|
||||
<div>
|
||||
<div style={styles.buttons}>
|
||||
<Button
|
||||
style={styles.saveButton}
|
||||
variant="contained"
|
||||
type="submit"
|
||||
color="primary"
|
||||
onClick={this.newCloseAccount}
|
||||
>
|
||||
Another one
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<Redirect to={`/dashboard`} push />
|
||||
) : (
|
||||
<div style={styles.buttons}>
|
||||
<Link to="/">
|
||||
<Button variant="contained">Cancel</Button>
|
||||
|
@ -10,6 +10,7 @@ import Select from "@material-ui/core/Select";
|
||||
import { grey } from "@material-ui/core/colors";
|
||||
import FormControl from "@material-ui/core/FormControl";
|
||||
import InputLabel from "@material-ui/core/InputLabel";
|
||||
import {Redirect} from "react-router-dom";
|
||||
|
||||
class Deposit extends React.Component {
|
||||
|
||||
@ -43,27 +44,23 @@ class Deposit extends React.Component {
|
||||
};
|
||||
|
||||
saveDeposit = () => {
|
||||
this.props.openIdManager.getUser().then((user) => {
|
||||
if (user) {
|
||||
var bodyFormData = new FormData();
|
||||
bodyFormData.append('amount', this.state.amount);
|
||||
bodyFormData.append('currency', this.state.currency);
|
||||
var bodyFormData = new FormData();
|
||||
bodyFormData.append('amount', this.state.amount);
|
||||
bodyFormData.append('currency', this.state.currency);
|
||||
|
||||
transactionService
|
||||
.deposit(user, this.state.accountId, bodyFormData)
|
||||
.then(response => {
|
||||
this.setState({
|
||||
transactionId: response.data.transaction.transactionId,
|
||||
transactionDate: response.data.transaction.transactionDate,
|
||||
submitted: true
|
||||
});
|
||||
console.log(response.data);
|
||||
})
|
||||
.catch(e => {
|
||||
console.log(e);
|
||||
});
|
||||
}
|
||||
})
|
||||
transactionService
|
||||
.deposit(this.state.accountId, bodyFormData)
|
||||
.then(response => {
|
||||
this.setState({
|
||||
transactionId: response.data.transaction.transactionId,
|
||||
transactionDate: response.data.transaction.transactionDate,
|
||||
submitted: true
|
||||
});
|
||||
console.log(response.data);
|
||||
})
|
||||
.catch(e => {
|
||||
console.log(e);
|
||||
});
|
||||
};
|
||||
|
||||
newDeposit = () => {
|
||||
@ -78,7 +75,6 @@ class Deposit extends React.Component {
|
||||
};
|
||||
|
||||
render() {
|
||||
|
||||
const styles = {
|
||||
toggleDiv: {
|
||||
marginTop: 20,
|
||||
@ -102,19 +98,7 @@ class Deposit extends React.Component {
|
||||
<PageBase title="Deposit" navigation="My Accounts / Deposit">
|
||||
|
||||
{this.state.submitted ? (
|
||||
<div>
|
||||
<div style={styles.buttons}>
|
||||
<Button
|
||||
style={styles.saveButton}
|
||||
variant="contained"
|
||||
type="submit"
|
||||
color="primary"
|
||||
onClick={this.newDeposit}
|
||||
>
|
||||
Another one
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<Redirect to={`/dashboard/accounts/${this.state.accountId}`} push />
|
||||
) : (
|
||||
<div>
|
||||
|
||||
|
@ -10,6 +10,7 @@ import Select from "@material-ui/core/Select";
|
||||
import { grey } from "@material-ui/core/colors";
|
||||
import FormControl from "@material-ui/core/FormControl";
|
||||
import InputLabel from "@material-ui/core/InputLabel";
|
||||
import {Redirect} from "react-router-dom";
|
||||
|
||||
class OpenAccount extends React.Component {
|
||||
|
||||
@ -41,27 +42,23 @@ class OpenAccount extends React.Component {
|
||||
};
|
||||
|
||||
saveAccount = () => {
|
||||
this.props.openIdManager.getUser().then((user) => {
|
||||
if (user) {
|
||||
var bodyFormData = new FormData();
|
||||
bodyFormData.append('amount', this.state.amount);
|
||||
bodyFormData.append('currency', this.state.currency);
|
||||
var bodyFormData = new FormData();
|
||||
bodyFormData.append('amount', this.state.amount);
|
||||
bodyFormData.append('currency', this.state.currency);
|
||||
|
||||
accountsService
|
||||
.openAccount(user, bodyFormData)
|
||||
.then(response => {
|
||||
this.setState({
|
||||
id: response.data.account.accountId,
|
||||
title: response.data.account.accountId,
|
||||
description: response.data.account.accountId,
|
||||
submitted: true
|
||||
});
|
||||
})
|
||||
.catch(e => {
|
||||
console.log(e);
|
||||
});
|
||||
}
|
||||
})
|
||||
accountsService
|
||||
.openAccount(bodyFormData)
|
||||
.then(response => {
|
||||
this.setState({
|
||||
id: response.data.account.accountId,
|
||||
title: response.data.account.accountId,
|
||||
description: response.data.account.accountId,
|
||||
submitted: true
|
||||
});
|
||||
})
|
||||
.catch(e => {
|
||||
console.log(e);
|
||||
});
|
||||
};
|
||||
|
||||
newAccount = () => {
|
||||
@ -98,20 +95,8 @@ class OpenAccount extends React.Component {
|
||||
<PageBase title="Open a New Account" navigation="My Accounts / Open a New Account">
|
||||
|
||||
{this.state.submitted ? (
|
||||
<div>
|
||||
<div style={styles.buttons}>
|
||||
<Button
|
||||
style={styles.saveButton}
|
||||
variant="contained"
|
||||
type="submit"
|
||||
color="primary"
|
||||
onClick={this.newAccount}
|
||||
>
|
||||
Another one
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<Redirect to={`/dashboard`} push />
|
||||
) : (
|
||||
<div>
|
||||
|
||||
<TextField
|
||||
|
@ -10,6 +10,7 @@ import Select from "@material-ui/core/Select";
|
||||
import { grey } from "@material-ui/core/colors";
|
||||
import FormControl from "@material-ui/core/FormControl";
|
||||
import InputLabel from "@material-ui/core/InputLabel";
|
||||
import {Redirect} from "react-router-dom";
|
||||
|
||||
class Transfer extends React.Component {
|
||||
|
||||
@ -44,26 +45,22 @@ class Transfer extends React.Component {
|
||||
};
|
||||
|
||||
saveTransfer = () => {
|
||||
this.props.openIdManager.getUser().then((user) => {
|
||||
if (user) {
|
||||
var bodyFormData = new FormData();
|
||||
bodyFormData.append('amount', this.state.amount);
|
||||
bodyFormData.append('currency', this.state.currency);
|
||||
var bodyFormData = new FormData();
|
||||
bodyFormData.append('amount', this.state.amount);
|
||||
bodyFormData.append('currency', this.state.currency);
|
||||
|
||||
transactionService
|
||||
.transfer(user, this.state.accountId, this.state.destinationAccountId, bodyFormData)
|
||||
.then(response => {
|
||||
this.setState({
|
||||
transactionId: response.data.transaction.transactionId,
|
||||
transactionDate: response.data.transaction.transactionDate,
|
||||
submitted: true
|
||||
});
|
||||
})
|
||||
.catch(e => {
|
||||
console.log(e);
|
||||
});
|
||||
}
|
||||
})
|
||||
transactionService
|
||||
.transfer(this.state.accountId, this.state.destinationAccountId, bodyFormData)
|
||||
.then(response => {
|
||||
this.setState({
|
||||
transactionId: response.data.transaction.transactionId,
|
||||
transactionDate: response.data.transaction.transactionDate,
|
||||
submitted: true
|
||||
});
|
||||
})
|
||||
.catch(e => {
|
||||
console.log(e);
|
||||
});
|
||||
};
|
||||
|
||||
newTransfer = () => {
|
||||
@ -103,20 +100,8 @@ class Transfer extends React.Component {
|
||||
<PageBase title="Transfer" navigation="My Accounts / Transfer">
|
||||
|
||||
{this.state.submitted ? (
|
||||
<div>
|
||||
<div style={styles.buttons}>
|
||||
<Button
|
||||
style={styles.saveButton}
|
||||
variant="contained"
|
||||
type="submit"
|
||||
color="primary"
|
||||
onClick={this.newTransfer}
|
||||
>
|
||||
Another one
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<Redirect to={`/dashboard/accounts/${this.state.accountId}`} push />
|
||||
) : (
|
||||
<div>
|
||||
|
||||
<TextField
|
||||
|
@ -10,6 +10,7 @@ import Select from "@material-ui/core/Select";
|
||||
import { grey } from "@material-ui/core/colors";
|
||||
import FormControl from "@material-ui/core/FormControl";
|
||||
import InputLabel from "@material-ui/core/InputLabel";
|
||||
import {Redirect} from "react-router-dom";
|
||||
|
||||
class Withdraw extends React.Component {
|
||||
|
||||
@ -43,27 +44,23 @@ class Withdraw extends React.Component {
|
||||
};
|
||||
|
||||
saveWithdraw = () => {
|
||||
this.props.openIdManager.getUser().then((user) => {
|
||||
if (user) {
|
||||
var bodyFormData = new FormData();
|
||||
bodyFormData.append('amount', this.state.amount);
|
||||
bodyFormData.append('currency', this.state.currency);
|
||||
var bodyFormData = new FormData();
|
||||
bodyFormData.append('amount', this.state.amount);
|
||||
bodyFormData.append('currency', this.state.currency);
|
||||
|
||||
transactionService
|
||||
.withdraw(user, this.state.accountId, bodyFormData)
|
||||
.then(response => {
|
||||
this.setState({
|
||||
transactionId: response.data.transaction.transactionId,
|
||||
transactionDate: response.data.transaction.transactionDate,
|
||||
submitted: true
|
||||
});
|
||||
console.log(response.data);
|
||||
})
|
||||
.catch(e => {
|
||||
console.log(e);
|
||||
});
|
||||
}
|
||||
})
|
||||
transactionService
|
||||
.withdraw(this.state.accountId, bodyFormData)
|
||||
.then(response => {
|
||||
this.setState({
|
||||
transactionId: response.data.transaction.transactionId,
|
||||
transactionDate: response.data.transaction.transactionDate,
|
||||
submitted: true
|
||||
});
|
||||
console.log(response.data);
|
||||
})
|
||||
.catch(e => {
|
||||
console.log(e);
|
||||
});
|
||||
};
|
||||
|
||||
newWithdraw = () => {
|
||||
@ -102,20 +99,8 @@ class Withdraw extends React.Component {
|
||||
<PageBase title="Withdraw" navigation="My Accounts / Withdraw">
|
||||
|
||||
{this.state.submitted ? (
|
||||
<div>
|
||||
<div style={styles.buttons}>
|
||||
<Button
|
||||
style={styles.saveButton}
|
||||
variant="contained"
|
||||
type="submit"
|
||||
color="primary"
|
||||
onClick={this.newWithdraw}
|
||||
>
|
||||
Another one
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<Redirect to={`/dashboard/accounts/${this.state.accountId}`} push />
|
||||
) : (
|
||||
<div>
|
||||
|
||||
<TextField
|
||||
|
25
wallet-spa/src/providers/authProvider.js
Normal file
25
wallet-spa/src/providers/authProvider.js
Normal file
@ -0,0 +1,25 @@
|
||||
import React, { Component } from "react";
|
||||
import AuthService from "../store/authService";
|
||||
|
||||
const AuthContext = React.createContext({
|
||||
signinRedirectCallback: () => ({}),
|
||||
logout: () => ({}),
|
||||
signoutRedirectCallback: () => ({}),
|
||||
isAuthenticated: () => ({}),
|
||||
signinRedirect: () => ({}),
|
||||
signinSilentCallback: () => ({}),
|
||||
createSigninRequest: () => ({})
|
||||
});
|
||||
|
||||
export const AuthConsumer = AuthContext.Consumer;
|
||||
|
||||
export class AuthProvider extends Component {
|
||||
authService;
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.authService = new AuthService();
|
||||
}
|
||||
render() {
|
||||
return <AuthContext.Provider value={this.authService}>{this.props.children}</AuthContext.Provider>;
|
||||
}
|
||||
}
|
20
wallet-spa/src/routes/privateRoute.js
Normal file
20
wallet-spa/src/routes/privateRoute.js
Normal file
@ -0,0 +1,20 @@
|
||||
import React from "react";
|
||||
import { Route } from "react-router-dom";
|
||||
import { AuthConsumer } from "../providers/authProvider";
|
||||
|
||||
export const PrivateRoute = ({ component, ...rest }) => {
|
||||
const renderFn = Component => props => (
|
||||
<AuthConsumer>
|
||||
{({ isAuthenticated, signinRedirect }) => {
|
||||
if (!!Component && isAuthenticated()) {
|
||||
return <Component {...props} />;
|
||||
} else {
|
||||
signinRedirect();
|
||||
return <span>loading</span>;
|
||||
}
|
||||
}}
|
||||
</AuthConsumer>
|
||||
);
|
||||
|
||||
return <Route {...rest} render={renderFn(component)} />;
|
||||
};
|
22
wallet-spa/src/routes/routes.js
Normal file
22
wallet-spa/src/routes/routes.js
Normal file
@ -0,0 +1,22 @@
|
||||
import * as React from "react";
|
||||
import { Route, Switch } from "react-router-dom";
|
||||
import { Callback } from "../components/auth/callback";
|
||||
import { Logout } from "../components/auth/logout";
|
||||
import { LogoutCallback } from "../components/auth/logoutCallback";
|
||||
import { PrivateRoute } from "./privateRoute";
|
||||
import { Register } from "../components/auth/register";
|
||||
import { SilentRenew } from "../components/auth/silentRenew";
|
||||
import { PublicPage } from "../components/publicPage";
|
||||
import { PrivatePage } from "../components/privatePage";
|
||||
|
||||
export const Routes = (
|
||||
<Switch>
|
||||
<Route exact={true} path="/signin-oidc" component={Callback} />
|
||||
<Route exact={true} path="/logout" component={Logout} />
|
||||
<Route exact={true} path="/logout/callback" component={LogoutCallback} />
|
||||
<Route exact={true} path="/register" component={Register} />
|
||||
<Route exact={true} path="/silentrenew" component={SilentRenew} />
|
||||
<PrivateRoute path="/dashboard" component={PrivatePage} />
|
||||
<Route path="/" component={PublicPage} />
|
||||
</Switch>
|
||||
);
|
@ -1,5 +0,0 @@
|
||||
// jest-dom adds custom jest matchers for asserting on DOM nodes.
|
||||
// allows you to do things like:
|
||||
// expect(element).toHaveTextContent(/react/i)
|
||||
// learn more: https://github.com/testing-library/jest-dom
|
||||
import '@testing-library/jest-dom/extend-expect';
|
@ -1,26 +1,22 @@
|
||||
import http from "./http-common"
|
||||
import api from "./oauth"
|
||||
|
||||
const getAccounts = (user) => {
|
||||
return http
|
||||
.createAxios(user)
|
||||
const getAccounts = () => {
|
||||
return api
|
||||
.get("/api/v1/accounts");
|
||||
};
|
||||
|
||||
const getAccount = (user, id) => {
|
||||
return http
|
||||
.createAxios(user)
|
||||
const getAccount = (id) => {
|
||||
return api
|
||||
.get(`/api/v1/accounts/${id}`);
|
||||
};
|
||||
|
||||
const openAccount = (user, data) => {
|
||||
return http
|
||||
.createAxios(user)
|
||||
const openAccount = (data) => {
|
||||
return api
|
||||
.post("/api/v1/accounts", data);
|
||||
};
|
||||
|
||||
const closeAccount = (user, id) => {
|
||||
return http
|
||||
.createAxios(user)
|
||||
const closeAccount = (id) => {
|
||||
return api
|
||||
.delete(`/api/v1/accounts/${id}`);
|
||||
};
|
||||
|
||||
|
106
wallet-spa/src/store/authService.js
Normal file
106
wallet-spa/src/store/authService.js
Normal file
@ -0,0 +1,106 @@
|
||||
import { IDENTITY_CONFIG, METADATA_OIDC } from "../utils/authConst";
|
||||
import { UserManager, WebStorageStateStore, Log } from "oidc-client";
|
||||
|
||||
export default class AuthService {
|
||||
UserManager;
|
||||
|
||||
constructor() {
|
||||
this.UserManager = new UserManager({
|
||||
...IDENTITY_CONFIG,
|
||||
userStore: new WebStorageStateStore({ store: window.sessionStorage }),
|
||||
metadata: {
|
||||
...METADATA_OIDC,
|
||||
},
|
||||
});
|
||||
// Logger
|
||||
Log.logger = console;
|
||||
Log.level = Log.DEBUG;
|
||||
this.UserManager.events.addUserLoaded((user) => {
|
||||
if (window.location.href.indexOf("signin-oidc") !== -1) {
|
||||
this.navigateToScreen();
|
||||
}
|
||||
});
|
||||
this.UserManager.events.addSilentRenewError((e) => {
|
||||
console.log("silent renew error", e.message);
|
||||
});
|
||||
|
||||
this.UserManager.events.addAccessTokenExpired(() => {
|
||||
console.log("token expired");
|
||||
this.logout();
|
||||
});
|
||||
}
|
||||
|
||||
signinRedirectCallback = () => {
|
||||
this.UserManager.signinRedirectCallback()
|
||||
.then((user) => {
|
||||
})
|
||||
.catch(function (e) {
|
||||
console.error(e);
|
||||
});
|
||||
};
|
||||
|
||||
getUser = async () => {
|
||||
const user = await this.UserManager.getUser();
|
||||
if (!user) {
|
||||
return await this.UserManager.signinRedirectCallback();
|
||||
}
|
||||
return user;
|
||||
};
|
||||
|
||||
parseJwt = (token) => {
|
||||
const base64Url = token.split(".")[1];
|
||||
const base64 = base64Url.replace("-", "+").replace("_", "/");
|
||||
return JSON.parse(window.atob(base64));
|
||||
};
|
||||
|
||||
signinRedirect = () => {
|
||||
localStorage.setItem("redirectUri", window.location.pathname);
|
||||
this.UserManager.signinRedirect({});
|
||||
};
|
||||
|
||||
navigateToScreen = () => {
|
||||
window.location.replace("/dashboard");
|
||||
};
|
||||
|
||||
isAuthenticated = () => {
|
||||
const oidcStorage = JSON.parse(
|
||||
sessionStorage.getItem(
|
||||
`oidc.user:${process.env.REACT_APP_AUTH_URL}:${process.env.REACT_APP_IDENTITY_CLIENT_ID}`
|
||||
)
|
||||
);
|
||||
|
||||
return !!oidcStorage && !!oidcStorage.access_token;
|
||||
};
|
||||
|
||||
signinSilent = () => {
|
||||
this.UserManager.signinSilent()
|
||||
.then((user) => {
|
||||
console.log("signed in", user);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
};
|
||||
signinSilentCallback = () => {
|
||||
this.UserManager.signinSilentCallback();
|
||||
};
|
||||
|
||||
createSigninRequest = () => {
|
||||
return this.UserManager.createSigninRequest();
|
||||
};
|
||||
|
||||
logout = () => {
|
||||
this.UserManager.signoutRedirect({
|
||||
id_token_hint: localStorage.getItem("id_token"),
|
||||
});
|
||||
this.UserManager.clearStaleState();
|
||||
};
|
||||
|
||||
signoutRedirectCallback = () => {
|
||||
this.UserManager.signoutRedirectCallback().then(() => {
|
||||
localStorage.clear();
|
||||
window.location.replace(process.env.REACT_APP_PUBLIC_URL);
|
||||
});
|
||||
this.UserManager.clearStaleState();
|
||||
};
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
import axios from "axios";
|
||||
|
||||
const createAxios = user => {
|
||||
return axios.create({
|
||||
baseURL: process.env.REACT_APP_ACCOUNTS_API,
|
||||
headers: {
|
||||
'Authorization': 'Bearer ' + user.access_token,
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
export default {
|
||||
createAxios
|
||||
};
|
29
wallet-spa/src/store/oauth.js
Normal file
29
wallet-spa/src/store/oauth.js
Normal file
@ -0,0 +1,29 @@
|
||||
import axios from "axios";
|
||||
|
||||
const api = axios.create({
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
baseURL: "https://localhost:5001/"
|
||||
});
|
||||
|
||||
api.interceptors.request.use(
|
||||
function (config) {
|
||||
const oidcStorage = JSON.parse(
|
||||
window.sessionStorage.getItem(
|
||||
`oidc.user:${process.env.REACT_APP_AUTH_URL}:${process.env.REACT_APP_IDENTITY_CLIENT_ID}`
|
||||
)
|
||||
);
|
||||
|
||||
if (!!oidcStorage && !!oidcStorage.access_token) {
|
||||
config.headers.Authorization = `Bearer ${oidcStorage.access_token}`;
|
||||
}
|
||||
|
||||
return config;
|
||||
},
|
||||
function (err) {
|
||||
return Promise.reject(err);
|
||||
}
|
||||
);
|
||||
|
||||
export default api;
|
@ -1,20 +1,17 @@
|
||||
import http from "./http-common"
|
||||
import api from "./oauth"
|
||||
|
||||
const deposit = (user, accountId, data) => {
|
||||
return http
|
||||
.createAxios(user)
|
||||
const deposit = (accountId, data) => {
|
||||
return api
|
||||
.patch(`/api/v1/transactions/${accountId}/deposit`, data);
|
||||
};
|
||||
|
||||
const withdraw = (user, accountId, data) => {
|
||||
return http
|
||||
.createAxios(user)
|
||||
const withdraw = (accountId, data) => {
|
||||
return api
|
||||
.patch(`/api/v1/transactions/${accountId}/withdraw`, data);
|
||||
};
|
||||
|
||||
const transfer = (user, originAccountId, destinationAccountId, data) => {
|
||||
return http
|
||||
.createAxios(user)
|
||||
const transfer = (originAccountId, destinationAccountId, data) => {
|
||||
return api
|
||||
.patch(`/api/v1/transactions/${originAccountId}/${destinationAccountId}`, data);
|
||||
};
|
||||
|
||||
|
105
wallet-spa/src/utils/authConst.js
Normal file
105
wallet-spa/src/utils/authConst.js
Normal file
@ -0,0 +1,105 @@
|
||||
export const IDENTITY_CONFIG = {
|
||||
authority: process.env.REACT_APP_AUTH_URL,
|
||||
client_id: process.env.REACT_APP_IDENTITY_CLIENT_ID,
|
||||
redirect_uri: process.env.REACT_APP_REDIRECT_URL,
|
||||
silent_redirect_uri: process.env.REACT_APP_SILENT_REDIRECT_URL,
|
||||
post_logout_redirect_uri: process.env.REACT_APP_LOGOFF_REDIRECT_URL,
|
||||
audience: process.env.REACT_APP_AUDIENCE,
|
||||
response_type: "code",
|
||||
response_mode: "query",
|
||||
automaticSilentRenew: false,
|
||||
loadUserInfo: true,
|
||||
scope: "openid profile api1.full_access",
|
||||
};
|
||||
|
||||
export const METADATA_OIDC = {
|
||||
issuer: process.env.REACT_APP_ISSUER,
|
||||
jwks_uri: process.env.REACT_APP_AUTH_URL + "/.well-known/openid-configuration/jwks",
|
||||
authorization_endpoint: process.env.REACT_APP_AUTH_URL + "/connect/authorize",
|
||||
token_endpoint: process.env.REACT_APP_AUTH_URL + "/connect/token",
|
||||
userinfo_endpoint: process.env.REACT_APP_AUTH_URL + "/connect/userinfo",
|
||||
end_session_endpoint: process.env.REACT_APP_AUTH_URL + "/connect/endsession",
|
||||
check_session_iframe: process.env.REACT_APP_AUTH_URL + "/connect/checksession",
|
||||
revocation_endpoint: process.env.REACT_APP_AUTH_URL + "/connect/revocation",
|
||||
introspection_endpoint: process.env.REACT_APP_AUTH_URL + "/connect/introspect",
|
||||
};
|
||||
|
||||
|
||||
|
||||
// {
|
||||
// "issuer":"https://localhost:5000",
|
||||
// "jwks_uri":"https://localhost:5000/.well-known/openid-configuration/jwks",
|
||||
// "authorization_endpoint":"https://localhost:5000/connect/authorize",
|
||||
// "token_endpoint":"https://localhost:5000/connect/token",
|
||||
// "userinfo_endpoint":"https://localhost:5000/connect/userinfo",
|
||||
// "end_session_endpoint":"https://localhost:5000/connect/endsession",
|
||||
// "check_session_iframe":"https://localhost:5000/connect/checksession",
|
||||
// "revocation_endpoint":"https://localhost:5000/connect/revocation",
|
||||
// "introspection_endpoint":"https://localhost:5000/connect/introspect",
|
||||
// "device_authorization_endpoint":"https://localhost:5000/connect/deviceauthorization",
|
||||
// "frontchannel_logout_supported":true,
|
||||
// "frontchannel_logout_session_supported":true,
|
||||
// "backchannel_logout_supported":true,
|
||||
// "backchannel_logout_session_supported":true,
|
||||
// "scopes_supported":[
|
||||
// "openid",
|
||||
// "profile",
|
||||
// "api1.read_only",
|
||||
// "api1.full_access",
|
||||
// "offline_access"
|
||||
// ],
|
||||
// "claims_supported":[
|
||||
// "sub",
|
||||
// "name",
|
||||
// "family_name",
|
||||
// "given_name",
|
||||
// "middle_name",
|
||||
// "nickname",
|
||||
// "preferred_username",
|
||||
// "profile",
|
||||
// "picture",
|
||||
// "website",
|
||||
// "gender",
|
||||
// "birthdate",
|
||||
// "zoneinfo",
|
||||
// "locale",
|
||||
// "updated_at"
|
||||
// ],
|
||||
// "grant_types_supported":[
|
||||
// "authorization_code",
|
||||
// "client_credentials",
|
||||
// "refresh_token",
|
||||
// "implicit",
|
||||
// "password",
|
||||
// "urn:ietf:params:oauth:grant-type:device_code"
|
||||
// ],
|
||||
// "response_types_supported":[
|
||||
// "code",
|
||||
// "token",
|
||||
// "id_token",
|
||||
// "id_token token",
|
||||
// "code id_token",
|
||||
// "code token",
|
||||
// "code id_token token"
|
||||
// ],
|
||||
// "response_modes_supported":[
|
||||
// "form_post",
|
||||
// "query",
|
||||
// "fragment"
|
||||
// ],
|
||||
// "token_endpoint_auth_methods_supported":[
|
||||
// "client_secret_basic",
|
||||
// "client_secret_post"
|
||||
// ],
|
||||
// "id_token_signing_alg_values_supported":[
|
||||
// "RS256"
|
||||
// ],
|
||||
// "subject_types_supported":[
|
||||
// "public"
|
||||
// ],
|
||||
// "code_challenge_methods_supported":[
|
||||
// "plain",
|
||||
// "S256"
|
||||
// ],
|
||||
// "request_parameter_supported":true
|
||||
// }
|
Loading…
Reference in New Issue
Block a user