init: add fuse-react v8.3.5 skeleton
This commit is contained in:
206
src/@mock-api/api/auth-api.js
Normal file
206
src/@mock-api/api/auth-api.js
Normal file
@@ -0,0 +1,206 @@
|
||||
import FuseUtils from '@fuse/utils';
|
||||
import _ from '@lodash';
|
||||
import Base64 from 'crypto-js/enc-base64';
|
||||
import HmacSHA256 from 'crypto-js/hmac-sha256';
|
||||
import Utf8 from 'crypto-js/enc-utf8';
|
||||
import jwtDecode from 'jwt-decode';
|
||||
import mock from '../mock';
|
||||
import mockApi from '../mock-api.json';
|
||||
|
||||
let usersApi = mockApi.components.examples.auth_users.value;
|
||||
|
||||
/* eslint-disable camelcase */
|
||||
|
||||
mock.onGet('/api/auth/sign-in').reply(async (config) => {
|
||||
const data = JSON.parse(config.data);
|
||||
const { email, password } = data;
|
||||
const user = _.cloneDeep(usersApi.find((_user) => _user.data.email === email));
|
||||
|
||||
const error = [];
|
||||
|
||||
if (!user) {
|
||||
error.push({
|
||||
type: 'email',
|
||||
message: 'Check your email address',
|
||||
});
|
||||
}
|
||||
|
||||
if (user && user.password !== password) {
|
||||
error.push({
|
||||
type: 'password',
|
||||
message: 'Check your password',
|
||||
});
|
||||
}
|
||||
|
||||
if (error.length === 0) {
|
||||
delete user.password;
|
||||
|
||||
const access_token = generateJWTToken({ id: user.uuid });
|
||||
|
||||
const response = {
|
||||
user,
|
||||
access_token,
|
||||
};
|
||||
|
||||
return [200, response];
|
||||
}
|
||||
|
||||
return [200, { error }];
|
||||
});
|
||||
|
||||
mock.onGet('/api/auth/access-token').reply((config) => {
|
||||
const data = JSON.parse(config.data);
|
||||
const { access_token } = data;
|
||||
|
||||
if (verifyJWTToken(access_token)) {
|
||||
const { id } = jwtDecode(access_token);
|
||||
|
||||
const user = _.cloneDeep(usersApi.find((_user) => _user.uuid === id));
|
||||
|
||||
delete user.password;
|
||||
|
||||
const updatedAccessToken = generateJWTToken({ id: user.uuid });
|
||||
|
||||
const response = {
|
||||
user,
|
||||
access_token: updatedAccessToken,
|
||||
};
|
||||
|
||||
return [200, response];
|
||||
}
|
||||
const error = 'Invalid access token detected';
|
||||
return [401, { error }];
|
||||
});
|
||||
|
||||
mock.onPost('/api/auth/sign-up').reply((request) => {
|
||||
const data = JSON.parse(request.data);
|
||||
const { displayName, password, email } = data;
|
||||
const isEmailExists = usersApi.find((_user) => _user.data.email === email);
|
||||
const error = [];
|
||||
|
||||
if (isEmailExists) {
|
||||
error.push({
|
||||
type: 'email',
|
||||
message: 'The email address is already in use',
|
||||
});
|
||||
}
|
||||
|
||||
if (error.length === 0) {
|
||||
const newUser = {
|
||||
uuid: FuseUtils.generateGUID(),
|
||||
from: 'custom-db',
|
||||
password,
|
||||
role: 'admin',
|
||||
data: {
|
||||
displayName,
|
||||
photoURL: 'assets/images/avatars/Abbott.jpg',
|
||||
email,
|
||||
settings: {},
|
||||
shortcuts: [],
|
||||
},
|
||||
};
|
||||
|
||||
usersApi = [...usersApi, newUser];
|
||||
|
||||
const user = _.cloneDeep(newUser);
|
||||
|
||||
delete user.password;
|
||||
|
||||
const access_token = generateJWTToken({ id: user.uuid });
|
||||
|
||||
const response = {
|
||||
user,
|
||||
access_token,
|
||||
};
|
||||
|
||||
return [200, response];
|
||||
}
|
||||
return [200, { error }];
|
||||
});
|
||||
|
||||
mock.onPost('/api/auth/user/update').reply((config) => {
|
||||
const data = JSON.parse(config.data);
|
||||
const { user } = data;
|
||||
|
||||
usersApi = usersApi.map((_user) => {
|
||||
if (user.uuid === user.id) {
|
||||
return _.merge(_user, user);
|
||||
}
|
||||
return _user;
|
||||
});
|
||||
|
||||
return [200, user];
|
||||
});
|
||||
|
||||
/**
|
||||
* JWT Token Generator/Verifier Helpers
|
||||
* !! Created for Demonstration Purposes, cannot be used for PRODUCTION
|
||||
*/
|
||||
|
||||
const jwtSecret = 'some-secret-code-goes-here';
|
||||
|
||||
function base64url(source) {
|
||||
// Encode in classical base64
|
||||
let encodedSource = Base64.stringify(source);
|
||||
|
||||
// Remove padding equal characters
|
||||
encodedSource = encodedSource.replace(/=+$/, '');
|
||||
|
||||
// Replace characters according to base64url specifications
|
||||
encodedSource = encodedSource.replace(/\+/g, '-');
|
||||
encodedSource = encodedSource.replace(/\//g, '_');
|
||||
|
||||
// Return the base64 encoded string
|
||||
return encodedSource;
|
||||
}
|
||||
|
||||
function generateJWTToken(tokenPayload) {
|
||||
// Define token header
|
||||
const header = {
|
||||
alg: 'HS256',
|
||||
typ: 'JWT',
|
||||
};
|
||||
|
||||
// Calculate the issued at and expiration dates
|
||||
const date = new Date();
|
||||
const iat = Math.floor(date.getTime() / 1000);
|
||||
const exp = Math.floor(date.setDate(date.getDate() + 7) / 1000);
|
||||
|
||||
// Define token payload
|
||||
const payload = {
|
||||
iat,
|
||||
iss: 'Fuse',
|
||||
exp,
|
||||
...tokenPayload,
|
||||
};
|
||||
|
||||
// Stringify and encode the header
|
||||
const stringifiedHeader = Utf8.parse(JSON.stringify(header));
|
||||
const encodedHeader = base64url(stringifiedHeader);
|
||||
|
||||
// Stringify and encode the payload
|
||||
const stringifiedPayload = Utf8.parse(JSON.stringify(payload));
|
||||
const encodedPayload = base64url(stringifiedPayload);
|
||||
|
||||
// Sign the encoded header and mock-api
|
||||
let signature = `${encodedHeader}.${encodedPayload}`;
|
||||
signature = HmacSHA256(signature, jwtSecret);
|
||||
signature = base64url(signature);
|
||||
|
||||
// Build and return the token
|
||||
return `${encodedHeader}.${encodedPayload}.${signature}`;
|
||||
}
|
||||
|
||||
function verifyJWTToken(token) {
|
||||
// Split the token into parts
|
||||
const parts = token.split('.');
|
||||
const header = parts[0];
|
||||
const payload = parts[1];
|
||||
const signature = parts[2];
|
||||
|
||||
// Re-sign and encode the header and payload using the secret
|
||||
const signatureCheck = base64url(HmacSHA256(`${header}.${payload}`, jwtSecret));
|
||||
|
||||
// Verify that the resulting signature is valid
|
||||
return signature === signatureCheck;
|
||||
}
|
||||
31
src/@mock-api/api/notifications-api.js
Normal file
31
src/@mock-api/api/notifications-api.js
Normal file
@@ -0,0 +1,31 @@
|
||||
import _ from '@lodash';
|
||||
import FuseUtils from '@fuse/utils';
|
||||
import mockApi from '../mock-api.json';
|
||||
import mock from '../mock';
|
||||
|
||||
let notificationsDB = mockApi.components.examples.notifications.value;
|
||||
|
||||
mock.onGet('/api/notifications').reply((config) => {
|
||||
return [200, notificationsDB];
|
||||
});
|
||||
|
||||
mock.onDelete('/api/notifications').reply((config) => {
|
||||
notificationsDB = [];
|
||||
return [200];
|
||||
});
|
||||
|
||||
mock.onPost('/api/notifications').reply(({ data }) => {
|
||||
const newNotification = { id: FuseUtils.generateGUID(), ...JSON.parse(data) };
|
||||
|
||||
notificationsDB.push(newNotification);
|
||||
|
||||
return [200, newNotification];
|
||||
});
|
||||
|
||||
mock.onDelete(/\/api\/notifications\/[^/]+/).reply((config) => {
|
||||
const { id } = config.url.match(/\/api\/notifications\/(?<id>[^/]+)/).groups;
|
||||
|
||||
_.remove(notificationsDB, { id });
|
||||
|
||||
return [200, id];
|
||||
});
|
||||
12
src/@mock-api/index.js
Normal file
12
src/@mock-api/index.js
Normal file
@@ -0,0 +1,12 @@
|
||||
import './api/auth-api';
|
||||
import './api/notifications-api';
|
||||
import history from '@history';
|
||||
import mock from './mock';
|
||||
|
||||
mock.onAny().passThrough();
|
||||
|
||||
if (module?.hot?.status() === 'apply') {
|
||||
const { pathname } = history.location;
|
||||
history.push('/loading');
|
||||
history.push({ pathname });
|
||||
}
|
||||
32873
src/@mock-api/mock-api.json
Normal file
32873
src/@mock-api/mock-api.json
Normal file
File diff suppressed because one or more lines are too long
5
src/@mock-api/mock.js
Normal file
5
src/@mock-api/mock.js
Normal file
@@ -0,0 +1,5 @@
|
||||
import MockAdapter from 'axios-mock-adapter';
|
||||
import axios from 'axios';
|
||||
|
||||
const mock = new MockAdapter(axios, { delayResponse: 0, onNoMatch: 'passthrough' });
|
||||
export default mock;
|
||||
Reference in New Issue
Block a user