init: add fuse-react v8.3.5 skeleton

This commit is contained in:
evgeniywas
2023-05-30 21:07:44 +01:00
commit 3a760d2646
543 changed files with 102541 additions and 0 deletions

View 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;
}

View 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
View 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

File diff suppressed because one or more lines are too long

5
src/@mock-api/mock.js Normal file
View 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;