Skip to content

Commit d8d0b4b

Browse files
Merge pull request #8 from flatlogic/user-management-integration
User management integration
2 parents 61170d1 + 992f0c6 commit d8d0b4b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+4564
-359
lines changed

.env

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
NODE_PATH=src/
2+
BROWSER=false
3+
GENERATE_SOURCEMAP=false

package.json

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
"version": "5.0.0",
44
"private": true,
55
"scripts": {
6-
"build": "REACT_APP_BACKEND=true PUBLIC_URL='/sing-app-react' node scripts/build.js",
6+
"build": "cross-env REACT_APP_BACKEND=true cross-env PUBLIC_URL='/sing-app-react' node scripts/build.js",
77
"start": "node scripts/start.js",
8-
"start:backend": "REACT_APP_BACKEND=true node scripts/start.js",
8+
"start:backend": "cross-env REACT_APP_BACKEND=true node scripts/start.js",
99
"test": "node scripts/test.js"
1010
},
1111
"browserslist": [
@@ -70,22 +70,31 @@
7070
"bootstrap_calendar": "https://github.com/xero/bootstrap_calendar.git#1.0.1",
7171
"chroma-js": "^2.1.0",
7272
"classnames": "^2.2.6",
73+
"connected-react-router": "6.3.1",
74+
"cross-env": "^7.0.2",
7375
"draft-js": "^0.10.5",
7476
"echarts": "^4.4.0",
7577
"echarts-for-react": "^2.0.15-beta.1",
78+
"file-saver": "^2.0.2",
79+
"filesize": "^6.1.0",
7680
"flot": "^0.8.0-alpha",
7781
"flot.dashes": "https://github.com/cquartier/flot.dashes.git",
7882
"font-awesome": "4.7.0",
83+
"formik": "1.5.1",
7984
"formsy-react": "0.19.5",
8085
"glyphicons-halflings": "^1.9.1",
8186
"highcharts": "^7.2.0",
8287
"highcharts-react-official": "^2.2.2",
88+
"history": "^4.10.1",
8389
"jasny-bootstrap": "^3.1.3",
8490
"jsonwebtoken": "^8.5.1",
8591
"line-awesome": "github:icons8/line-awesome",
92+
"md5": "^2.2.1",
8693
"messenger": "git+https://github.com/HubSpot/messenger.git#v1.4.2",
8794
"moment": "^2.22.2",
8895
"nvd3": "1.8.6",
96+
"qs": "^6.9.4",
97+
"query-string": "^6.12.1",
8998
"rc-color-picker": "^1.2.6",
9099
"rc-hammerjs": "0.6.9",
91100
"rc-slider": "^8.7.1",
@@ -107,9 +116,9 @@
107116
"react-joyride": "^2.1.1",
108117
"react-maskedinput": "^4.0.1",
109118
"react-mde": "2.3.4",
110-
"react-redux": "^5.0.7",
111-
"react-router": "^4.3.1",
112-
"react-router-dom": "^4.3.1",
119+
"react-redux": "^7.2.0",
120+
"react-router": "5.2.0",
121+
"react-router-dom": "5.2.0",
113122
"react-router-hash-link": "^1.2.1",
114123
"react-scrollspy": "^3.3.5",
115124
"react-select": "^3.0.8",
@@ -128,11 +137,16 @@
128137
"reactstrap": "7.1.0",
129138
"redux": "^4.0.1",
130139
"redux-thunk": "^2.3.0",
140+
"reselect": "^4.0.0",
131141
"rickshaw": "1.6.6",
132142
"showdown": "1.8.6",
133143
"skycons": "^1.0.0",
134144
"sortablejs": "1.10.0",
135-
"uuid": "^3.3.3"
145+
"styled-components": "^5.1.0",
146+
"toastr": "^2.1.4",
147+
"uuid": "^3.3.3",
148+
"xlsx": "^0.16.0",
149+
"yup": "^0.28.5"
136150
},
137151
"devDependencies": {
138152
"@babel/core": "7.4.4",

src/actions/auth.js

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
import axios from 'axios';
2+
import config from '../config';
3+
import jwt from "jsonwebtoken";
4+
import { toast } from 'react-toastify';
5+
import { push } from 'connected-react-router';
6+
import Errors from '../components/FormItems/error/errors';
7+
import { mockUser } from './mock';
8+
9+
export const AUTH_FAILURE = 'AUTH_FAILURE';
10+
export const LOGIN_REQUEST = 'LOGIN_REQUEST';
11+
export const LOGIN_SUCCESS = 'LOGIN_SUCCESS';
12+
export const LOGOUT_REQUEST = 'LOGOUT_REQUEST';
13+
export const LOGOUT_SUCCESS = 'LOGOUT_SUCCESS';
14+
export const RESET_REQUEST = 'RESET_REQUEST';
15+
export const RESET_SUCCESS = 'RESET_SUCCESS';
16+
export const PASSWORD_RESET_EMAIL_REQUEST = 'PASSWORD_RESET_EMAIL_REQUEST';
17+
export const PASSWORD_RESET_EMAIL_SUCCESS = 'PASSWORD_RESET_EMAIL_SUCCESS';
18+
export const AUTH_INIT_SUCCESS = 'AUTH_INIT_SUCCESS';
19+
export const AUTH_INIT_ERROR = 'AUTH_INIT_ERROR';
20+
export const REGISTER_REQUEST = 'REGISTER_REQUEST';
21+
export const REGISTER_SUCCESS = 'REGISTER_SUCCESS';
22+
23+
async function findMe() {
24+
if (config.isBackend) {
25+
const response = await axios.get('/auth/me');
26+
return response.data;
27+
} else {
28+
return mockUser;
29+
}
30+
}
31+
32+
export function authError(payload) {
33+
return {
34+
type: AUTH_FAILURE,
35+
payload,
36+
};
37+
}
38+
39+
export function doInit() {
40+
return async (dispatch) => {
41+
let currentUser = null;
42+
if (!config.isBackend) {
43+
currentUser = mockUser;
44+
dispatch({
45+
type: AUTH_INIT_SUCCESS,
46+
payload: {
47+
currentUser,
48+
},
49+
});
50+
} else {
51+
try {
52+
let token = localStorage.getItem('token');
53+
if (token) {
54+
currentUser = await findMe();
55+
}
56+
dispatch({
57+
type: AUTH_INIT_SUCCESS,
58+
payload: {
59+
currentUser,
60+
},
61+
});
62+
} catch (error) {
63+
Errors.handle(error);
64+
65+
dispatch({
66+
type: AUTH_INIT_ERROR,
67+
payload: error,
68+
});
69+
}
70+
}
71+
}
72+
}
73+
74+
export function logoutUser() {
75+
return (dispatch) => {
76+
dispatch({
77+
type: LOGOUT_REQUEST,
78+
});
79+
localStorage.removeItem('token');
80+
localStorage.removeItem('user');
81+
axios.defaults.headers.common['Authorization'] = "";
82+
dispatch({
83+
type: LOGOUT_SUCCESS,
84+
});
85+
dispatch(push('/login'));
86+
};
87+
}
88+
89+
export function receiveToken(token) {
90+
return (dispatch) => {
91+
let user;
92+
93+
if (config.isBackend) {
94+
user = jwt.decode(token)
95+
} else {
96+
user = {
97+
email: config.auth.email,
98+
user: {
99+
id: 'default_no_connection_id_444'
100+
}
101+
}
102+
}
103+
104+
localStorage.setItem('token', token);
105+
localStorage.setItem('user', JSON.stringify(user));
106+
axios.defaults.headers.common['Authorization'] = "Bearer " + token;
107+
dispatch({
108+
type: LOGIN_SUCCESS
109+
});
110+
dispatch(push('/app'));
111+
}
112+
}
113+
114+
export function loginUser(creds) {
115+
return (dispatch) => {
116+
if (!config.isBackend) {
117+
dispatch(receiveToken('token'));
118+
dispatch(doInit());
119+
dispatch(push('/app'));
120+
} else {
121+
dispatch({
122+
type: LOGIN_REQUEST,
123+
});
124+
if (creds.social) {
125+
window.location.href = config.baseURLApi + "/auth/signin/" + creds.social + '?app=' + config.redirectUrl;
126+
} else if (creds.email.length > 0 && creds.password.length > 0) {
127+
axios.post("/auth/signin/local", creds).then(res => {
128+
const token = res.data;
129+
dispatch(receiveToken(token));
130+
dispatch(doInit());
131+
dispatch(push('/app'));
132+
}).catch(err => {
133+
dispatch(authError(err.response.data));
134+
})
135+
} else {
136+
dispatch(authError('Something was wrong. Try again'));
137+
}
138+
}
139+
};
140+
}
141+
142+
export function verifyEmail(token) {
143+
return(dispatch) => {
144+
if (!config.isBackend) {
145+
dispatch(push('/login'));
146+
} else {
147+
axios.put("/auth/verify-email", {token}).then(verified => {
148+
if (verified) {
149+
toast.success("Your email was verified");
150+
}
151+
}).catch(err => {
152+
toast.error(err.response.data);
153+
}).finally(() => {
154+
dispatch(push('/login'));
155+
})
156+
}
157+
}
158+
}
159+
160+
export function resetPassword(token, password) {
161+
return (dispatch) => {
162+
if (!config.isBackend) {
163+
dispatch(push('/login'));
164+
} else {
165+
dispatch({
166+
type: RESET_REQUEST,
167+
});
168+
axios.put("/auth/password-reset", {token, password}).then(res => {
169+
dispatch({
170+
type: RESET_SUCCESS,
171+
});
172+
toast.success("Password has been updated");
173+
dispatch(push('/login'));
174+
}).catch(err => {
175+
dispatch(authError(err.response.data));
176+
})
177+
}
178+
}
179+
}
180+
181+
export function sendPasswordResetEmail(email) {
182+
return (dispatch) => {
183+
if (!config.isBackend) {
184+
dispatch(push('/login'));
185+
} else {
186+
dispatch({
187+
type: PASSWORD_RESET_EMAIL_REQUEST,
188+
});
189+
axios.post("/auth/send-password-reset-email", {email}).then(res => {
190+
dispatch({
191+
type: PASSWORD_RESET_EMAIL_SUCCESS,
192+
});
193+
toast.success("Email with resetting instructions has been sent");
194+
dispatch(push('/login'));
195+
}).catch(err => {
196+
dispatch(authError(err.response.data));
197+
})
198+
}
199+
}
200+
}
201+
202+
export function registerUser(creds) {
203+
return (dispatch) => {
204+
if (!config.isBackend) {
205+
dispatch(push('/login'));
206+
} else {
207+
dispatch({
208+
type: REGISTER_REQUEST,
209+
});
210+
211+
if (creds.email.length > 0 && creds.password.length > 0) {
212+
axios.post("/auth/signup", creds).then(res => {
213+
dispatch({
214+
type: REGISTER_SUCCESS
215+
});
216+
toast.success("You've been registered successfully. Please check your email for verification link");
217+
dispatch(push('/login'));
218+
}).catch(err => {
219+
dispatch(authError(err.response.data));
220+
})
221+
222+
} else {
223+
dispatch(authError('Something was wrong. Try again'));
224+
}
225+
}
226+
};
227+
}

src/actions/mock.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
export const mockUser = {
2+
id: "98cea92c-84e5-4c0d-ac21-9998f4b23883",
3+
firstName: "Admin",
4+
authenticationUid: null,
5+
avatar: null,
6+
createdAt: "2020-05-12T11:04:00.864Z",
7+
createdById: null,
8+
deletedAt: null,
9+
disabled: false,
10+
email: "admin@flatlogic.com",
11+
emailVerificationToken: null,
12+
emailVerificationTokenExpiresAt: null,
13+
emailVerified: true,
14+
importHash: null,
15+
lastName: null,
16+
password: "$2b$12$EFuj2XoxivlGr.oiIvnvDulsE5iIBTngrLlrXMM/PkO//iInslWNW",
17+
passwordResetToken: null,
18+
passwordResetTokenExpiresAt: null,
19+
phoneNumber: null,
20+
provider: "local",
21+
role: "admin",
22+
updatedAt: "2020-05-12T11:04:00.864Z",
23+
updatedById: null,
24+
}

src/actions/register.js

Lines changed: 0 additions & 53 deletions
This file was deleted.

0 commit comments

Comments
 (0)