diff --git a/build.sh b/build.sh
index 3fee9a1..5633fcc 100644
--- a/build.sh
+++ b/build.sh
@@ -5,6 +5,7 @@ if [ $? -ne 0 ]; then
fi
cp -r static build/
cp -r GeoLite2-Country.mmdb build/
+cp -r Logo.png build/static/
mkdir build/images
cp client/src/assets/images/icons/cosmos_gray.png build/cosmos_gray.png
cp client/src/assets/images/icons/cosmos_gray.png cosmos_gray.png
diff --git a/changelog.md b/changelog.md
index e9d4d02..b4a8a3b 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,15 @@
+## Version 0.3.0
+ - Set Max nb simulatneous connections per user
+ - Set Global Max nb simulatneous connections
+ - Display nickname on invite page
+ - Reset self-signed certificates when hostnames changes
+ - Block based on geo-locations
+ - Block common bots
+ - DNS challenge for letsencrypt
+ - Implement 2 FA
+ - Implement SMTP to Send Email (password reset / invites)
+ - Show loading on user rows on actions
+
## Version 0.2.0
- URL UI completely redone from scratch
- Add new "Smart Shield" feature for easier protection without manual adjustments required
diff --git a/client/src/api/users.jsx b/client/src/api/users.jsx
index 1975ef2..46a2998 100644
--- a/client/src/api/users.jsx
+++ b/client/src/api/users.jsx
@@ -100,6 +100,16 @@ function reset2FA(values) {
}))
}
+function resetPassword(values) {
+ return wrap(fetch('/cosmos/api/password-reset', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify(values),
+ }))
+}
+
export {
list,
create,
@@ -110,5 +120,6 @@ export {
deleteUser,
new2FA,
check2FA,
- reset2FA
+ reset2FA,
+ resetPassword,
};
\ No newline at end of file
diff --git a/client/src/components/countrySelect.jsx b/client/src/components/countrySelect.jsx
new file mode 100644
index 0000000..0450fa4
--- /dev/null
+++ b/client/src/components/countrySelect.jsx
@@ -0,0 +1,493 @@
+import * as React from 'react';
+import Box from '@mui/material/Box';
+import TextField from '@mui/material/TextField';
+import Autocomplete from '@mui/material/Autocomplete';
+import { Grid } from '@mui/material';
+
+// From https://bitbucket.org/atlassian/atlaskit-mk-2/raw/4ad0e56649c3e6c973e226b7efaeb28cb240ccb0/packages/core/select/src/data/countries.js
+const _countries = [
+ { code: 'AD', label: 'Andorra', phone: '376' },
+ {
+ code: 'AE',
+ label: 'United Arab Emirates',
+ phone: '971',
+ },
+ { code: 'AF', label: 'Afghanistan', phone: '93' },
+ {
+ code: 'AG',
+ label: 'Antigua and Barbuda',
+ phone: '1-268',
+ },
+ { code: 'AI', label: 'Anguilla', phone: '1-264' },
+ { code: 'AL', label: 'Albania', phone: '355' },
+ { code: 'AM', label: 'Armenia', phone: '374' },
+ { code: 'AO', label: 'Angola', phone: '244' },
+ { code: 'AQ', label: 'Antarctica', phone: '672' },
+ { code: 'AR', label: 'Argentina', phone: '54' },
+ { code: 'AS', label: 'American Samoa', phone: '1-684' },
+ { code: 'AT', label: 'Austria', phone: '43' },
+ {
+ code: 'AU',
+ label: 'Australia',
+ phone: '61',
+ suggested: true,
+ },
+ { code: 'AW', label: 'Aruba', phone: '297' },
+ { code: 'AX', label: 'Alland Islands', phone: '358' },
+ { code: 'AZ', label: 'Azerbaijan', phone: '994' },
+ {
+ code: 'BA',
+ label: 'Bosnia and Herzegovina',
+ phone: '387',
+ },
+ { code: 'BB', label: 'Barbados', phone: '1-246' },
+ { code: 'BD', label: 'Bangladesh', phone: '880' },
+ { code: 'BE', label: 'Belgium', phone: '32' },
+ { code: 'BF', label: 'Burkina Faso', phone: '226' },
+ { code: 'BG', label: 'Bulgaria', phone: '359' },
+ { code: 'BH', label: 'Bahrain', phone: '973' },
+ { code: 'BI', label: 'Burundi', phone: '257' },
+ { code: 'BJ', label: 'Benin', phone: '229' },
+ { code: 'BL', label: 'Saint Barthelemy', phone: '590' },
+ { code: 'BM', label: 'Bermuda', phone: '1-441' },
+ { code: 'BN', label: 'Brunei Darussalam', phone: '673' },
+ { code: 'BO', label: 'Bolivia', phone: '591' },
+ { code: 'BR', label: 'Brazil', phone: '55' },
+ { code: 'BS', label: 'Bahamas', phone: '1-242' },
+ { code: 'BT', label: 'Bhutan', phone: '975' },
+ { code: 'BV', label: 'Bouvet Island', phone: '47' },
+ { code: 'BW', label: 'Botswana', phone: '267' },
+ { code: 'BY', label: 'Belarus', phone: '375' },
+ { code: 'BZ', label: 'Belize', phone: '501' },
+ {
+ code: 'CA',
+ label: 'Canada',
+ phone: '1',
+ suggested: true,
+ },
+ {
+ code: 'CC',
+ label: 'Cocos (Keeling) Islands',
+ phone: '61',
+ },
+ {
+ code: 'CD',
+ label: 'Congo, Democratic Republic of the',
+ phone: '243',
+ },
+ {
+ code: 'CF',
+ label: 'Central African Republic',
+ phone: '236',
+ },
+ {
+ code: 'CG',
+ label: 'Congo, Republic of the',
+ phone: '242',
+ },
+ { code: 'CH', label: 'Switzerland', phone: '41' },
+ { code: 'CI', label: "Cote d'Ivoire", phone: '225' },
+ { code: 'CK', label: 'Cook Islands', phone: '682' },
+ { code: 'CL', label: 'Chile', phone: '56' },
+ { code: 'CM', label: 'Cameroon', phone: '237' },
+ { code: 'CN', label: 'China', phone: '86' },
+ { code: 'CO', label: 'Colombia', phone: '57' },
+ { code: 'CR', label: 'Costa Rica', phone: '506' },
+ { code: 'CU', label: 'Cuba', phone: '53' },
+ { code: 'CV', label: 'Cape Verde', phone: '238' },
+ { code: 'CW', label: 'Curacao', phone: '599' },
+ { code: 'CX', label: 'Christmas Island', phone: '61' },
+ { code: 'CY', label: 'Cyprus', phone: '357' },
+ { code: 'CZ', label: 'Czech Republic', phone: '420' },
+ {
+ code: 'DE',
+ label: 'Germany',
+ phone: '49',
+ suggested: true,
+ },
+ { code: 'DJ', label: 'Djibouti', phone: '253' },
+ { code: 'DK', label: 'Denmark', phone: '45' },
+ { code: 'DM', label: 'Dominica', phone: '1-767' },
+ {
+ code: 'DO',
+ label: 'Dominican Republic',
+ phone: '1-809',
+ },
+ { code: 'DZ', label: 'Algeria', phone: '213' },
+ { code: 'EC', label: 'Ecuador', phone: '593' },
+ { code: 'EE', label: 'Estonia', phone: '372' },
+ { code: 'EG', label: 'Egypt', phone: '20' },
+ { code: 'EH', label: 'Western Sahara', phone: '212' },
+ { code: 'ER', label: 'Eritrea', phone: '291' },
+ { code: 'ES', label: 'Spain', phone: '34' },
+ { code: 'ET', label: 'Ethiopia', phone: '251' },
+ { code: 'FI', label: 'Finland', phone: '358' },
+ { code: 'FJ', label: 'Fiji', phone: '679' },
+ {
+ code: 'FK',
+ label: 'Falkland Islands (Malvinas)',
+ phone: '500',
+ },
+ {
+ code: 'FM',
+ label: 'Micronesia, Federated States of',
+ phone: '691',
+ },
+ { code: 'FO', label: 'Faroe Islands', phone: '298' },
+ {
+ code: 'FR',
+ label: 'France',
+ phone: '33',
+ suggested: true,
+ },
+ { code: 'GA', label: 'Gabon', phone: '241' },
+ { code: 'GB', label: 'United Kingdom', phone: '44' },
+ { code: 'GD', label: 'Grenada', phone: '1-473' },
+ { code: 'GE', label: 'Georgia', phone: '995' },
+ { code: 'GF', label: 'French Guiana', phone: '594' },
+ { code: 'GG', label: 'Guernsey', phone: '44' },
+ { code: 'GH', label: 'Ghana', phone: '233' },
+ { code: 'GI', label: 'Gibraltar', phone: '350' },
+ { code: 'GL', label: 'Greenland', phone: '299' },
+ { code: 'GM', label: 'Gambia', phone: '220' },
+ { code: 'GN', label: 'Guinea', phone: '224' },
+ { code: 'GP', label: 'Guadeloupe', phone: '590' },
+ { code: 'GQ', label: 'Equatorial Guinea', phone: '240' },
+ { code: 'GR', label: 'Greece', phone: '30' },
+ {
+ code: 'GS',
+ label: 'South Georgia and the South Sandwich Islands',
+ phone: '500',
+ },
+ { code: 'GT', label: 'Guatemala', phone: '502' },
+ { code: 'GU', label: 'Guam', phone: '1-671' },
+ { code: 'GW', label: 'Guinea-Bissau', phone: '245' },
+ { code: 'GY', label: 'Guyana', phone: '592' },
+ { code: 'HK', label: 'Hong Kong', phone: '852' },
+ {
+ code: 'HM',
+ label: 'Heard Island and McDonald Islands',
+ phone: '672',
+ },
+ { code: 'HN', label: 'Honduras', phone: '504' },
+ { code: 'HR', label: 'Croatia', phone: '385' },
+ { code: 'HT', label: 'Haiti', phone: '509' },
+ { code: 'HU', label: 'Hungary', phone: '36' },
+ { code: 'ID', label: 'Indonesia', phone: '62' },
+ { code: 'IE', label: 'Ireland', phone: '353' },
+ { code: 'IL', label: 'Israel', phone: '972' },
+ { code: 'IM', label: 'Isle of Man', phone: '44' },
+ { code: 'IN', label: 'India', phone: '91' },
+ {
+ code: 'IO',
+ label: 'British Indian Ocean Territory',
+ phone: '246',
+ },
+ { code: 'IQ', label: 'Iraq', phone: '964' },
+ {
+ code: 'IR',
+ label: 'Iran, Islamic Republic of',
+ phone: '98',
+ },
+ { code: 'IS', label: 'Iceland', phone: '354' },
+ { code: 'IT', label: 'Italy', phone: '39' },
+ { code: 'JE', label: 'Jersey', phone: '44' },
+ { code: 'JM', label: 'Jamaica', phone: '1-876' },
+ { code: 'JO', label: 'Jordan', phone: '962' },
+ {
+ code: 'JP',
+ label: 'Japan',
+ phone: '81',
+ suggested: true,
+ },
+ { code: 'KE', label: 'Kenya', phone: '254' },
+ { code: 'KG', label: 'Kyrgyzstan', phone: '996' },
+ { code: 'KH', label: 'Cambodia', phone: '855' },
+ { code: 'KI', label: 'Kiribati', phone: '686' },
+ { code: 'KM', label: 'Comoros', phone: '269' },
+ {
+ code: 'KN',
+ label: 'Saint Kitts and Nevis',
+ phone: '1-869',
+ },
+ {
+ code: 'KP',
+ label: "Korea, Democratic People's Republic of",
+ phone: '850',
+ },
+ { code: 'KR', label: 'Korea, Republic of', phone: '82' },
+ { code: 'KW', label: 'Kuwait', phone: '965' },
+ { code: 'KY', label: 'Cayman Islands', phone: '1-345' },
+ { code: 'KZ', label: 'Kazakhstan', phone: '7' },
+ {
+ code: 'LA',
+ label: "Lao People's Democratic Republic",
+ phone: '856',
+ },
+ { code: 'LB', label: 'Lebanon', phone: '961' },
+ { code: 'LC', label: 'Saint Lucia', phone: '1-758' },
+ { code: 'LI', label: 'Liechtenstein', phone: '423' },
+ { code: 'LK', label: 'Sri Lanka', phone: '94' },
+ { code: 'LR', label: 'Liberia', phone: '231' },
+ { code: 'LS', label: 'Lesotho', phone: '266' },
+ { code: 'LT', label: 'Lithuania', phone: '370' },
+ { code: 'LU', label: 'Luxembourg', phone: '352' },
+ { code: 'LV', label: 'Latvia', phone: '371' },
+ { code: 'LY', label: 'Libya', phone: '218' },
+ { code: 'MA', label: 'Morocco', phone: '212' },
+ { code: 'MC', label: 'Monaco', phone: '377' },
+ {
+ code: 'MD',
+ label: 'Moldova, Republic of',
+ phone: '373',
+ },
+ { code: 'ME', label: 'Montenegro', phone: '382' },
+ {
+ code: 'MF',
+ label: 'Saint Martin (French part)',
+ phone: '590',
+ },
+ { code: 'MG', label: 'Madagascar', phone: '261' },
+ { code: 'MH', label: 'Marshall Islands', phone: '692' },
+ {
+ code: 'MK',
+ label: 'Macedonia, the Former Yugoslav Republic of',
+ phone: '389',
+ },
+ { code: 'ML', label: 'Mali', phone: '223' },
+ { code: 'MM', label: 'Myanmar', phone: '95' },
+ { code: 'MN', label: 'Mongolia', phone: '976' },
+ { code: 'MO', label: 'Macao', phone: '853' },
+ {
+ code: 'MP',
+ label: 'Northern Mariana Islands',
+ phone: '1-670',
+ },
+ { code: 'MQ', label: 'Martinique', phone: '596' },
+ { code: 'MR', label: 'Mauritania', phone: '222' },
+ { code: 'MS', label: 'Montserrat', phone: '1-664' },
+ { code: 'MT', label: 'Malta', phone: '356' },
+ { code: 'MU', label: 'Mauritius', phone: '230' },
+ { code: 'MV', label: 'Maldives', phone: '960' },
+ { code: 'MW', label: 'Malawi', phone: '265' },
+ { code: 'MX', label: 'Mexico', phone: '52' },
+ { code: 'MY', label: 'Malaysia', phone: '60' },
+ { code: 'MZ', label: 'Mozambique', phone: '258' },
+ { code: 'NA', label: 'Namibia', phone: '264' },
+ { code: 'NC', label: 'New Caledonia', phone: '687' },
+ { code: 'NE', label: 'Niger', phone: '227' },
+ { code: 'NF', label: 'Norfolk Island', phone: '672' },
+ { code: 'NG', label: 'Nigeria', phone: '234' },
+ { code: 'NI', label: 'Nicaragua', phone: '505' },
+ { code: 'NL', label: 'Netherlands', phone: '31' },
+ { code: 'NO', label: 'Norway', phone: '47' },
+ { code: 'NP', label: 'Nepal', phone: '977' },
+ { code: 'NR', label: 'Nauru', phone: '674' },
+ { code: 'NU', label: 'Niue', phone: '683' },
+ { code: 'NZ', label: 'New Zealand', phone: '64' },
+ { code: 'OM', label: 'Oman', phone: '968' },
+ { code: 'PA', label: 'Panama', phone: '507' },
+ { code: 'PE', label: 'Peru', phone: '51' },
+ { code: 'PF', label: 'French Polynesia', phone: '689' },
+ { code: 'PG', label: 'Papua New Guinea', phone: '675' },
+ { code: 'PH', label: 'Philippines', phone: '63' },
+ { code: 'PK', label: 'Pakistan', phone: '92' },
+ { code: 'PL', label: 'Poland', phone: '48' },
+ {
+ code: 'PM',
+ label: 'Saint Pierre and Miquelon',
+ phone: '508',
+ },
+ { code: 'PN', label: 'Pitcairn', phone: '870' },
+ { code: 'PR', label: 'Puerto Rico', phone: '1' },
+ {
+ code: 'PS',
+ label: 'Palestine, State of',
+ phone: '970',
+ },
+ { code: 'PT', label: 'Portugal', phone: '351' },
+ { code: 'PW', label: 'Palau', phone: '680' },
+ { code: 'PY', label: 'Paraguay', phone: '595' },
+ { code: 'QA', label: 'Qatar', phone: '974' },
+ { code: 'RE', label: 'Reunion', phone: '262' },
+ { code: 'RO', label: 'Romania', phone: '40' },
+ { code: 'RS', label: 'Serbia', phone: '381' },
+ { code: 'RU', label: 'Russian Federation', phone: '7' },
+ { code: 'RW', label: 'Rwanda', phone: '250' },
+ { code: 'SA', label: 'Saudi Arabia', phone: '966' },
+ { code: 'SB', label: 'Solomon Islands', phone: '677' },
+ { code: 'SC', label: 'Seychelles', phone: '248' },
+ { code: 'SD', label: 'Sudan', phone: '249' },
+ { code: 'SE', label: 'Sweden', phone: '46' },
+ { code: 'SG', label: 'Singapore', phone: '65' },
+ { code: 'SH', label: 'Saint Helena', phone: '290' },
+ { code: 'SI', label: 'Slovenia', phone: '386' },
+ {
+ code: 'SJ',
+ label: 'Svalbard and Jan Mayen',
+ phone: '47',
+ },
+ { code: 'SK', label: 'Slovakia', phone: '421' },
+ { code: 'SL', label: 'Sierra Leone', phone: '232' },
+ { code: 'SM', label: 'San Marino', phone: '378' },
+ { code: 'SN', label: 'Senegal', phone: '221' },
+ { code: 'SO', label: 'Somalia', phone: '252' },
+ { code: 'SR', label: 'Suriname', phone: '597' },
+ { code: 'SS', label: 'South Sudan', phone: '211' },
+ {
+ code: 'ST',
+ label: 'Sao Tome and Principe',
+ phone: '239',
+ },
+ { code: 'SV', label: 'El Salvador', phone: '503' },
+ {
+ code: 'SX',
+ label: 'Sint Maarten (Dutch part)',
+ phone: '1-721',
+ },
+ {
+ code: 'SY',
+ label: 'Syrian Arab Republic',
+ phone: '963',
+ },
+ { code: 'SZ', label: 'Swaziland', phone: '268' },
+ {
+ code: 'TC',
+ label: 'Turks and Caicos Islands',
+ phone: '1-649',
+ },
+ { code: 'TD', label: 'Chad', phone: '235' },
+ {
+ code: 'TF',
+ label: 'French Southern Territories',
+ phone: '262',
+ },
+ { code: 'TG', label: 'Togo', phone: '228' },
+ { code: 'TH', label: 'Thailand', phone: '66' },
+ { code: 'TJ', label: 'Tajikistan', phone: '992' },
+ { code: 'TK', label: 'Tokelau', phone: '690' },
+ { code: 'TL', label: 'Timor-Leste', phone: '670' },
+ { code: 'TM', label: 'Turkmenistan', phone: '993' },
+ { code: 'TN', label: 'Tunisia', phone: '216' },
+ { code: 'TO', label: 'Tonga', phone: '676' },
+ { code: 'TR', label: 'Turkey', phone: '90' },
+ {
+ code: 'TT',
+ label: 'Trinidad and Tobago',
+ phone: '1-868',
+ },
+ { code: 'TV', label: 'Tuvalu', phone: '688' },
+ {
+ code: 'TW',
+ label: 'Taiwan, Republic of China',
+ phone: '886',
+ },
+ {
+ code: 'TZ',
+ label: 'United Republic of Tanzania',
+ phone: '255',
+ },
+ { code: 'UA', label: 'Ukraine', phone: '380' },
+ { code: 'UG', label: 'Uganda', phone: '256' },
+ {
+ code: 'US',
+ label: 'United States',
+ phone: '1',
+ suggested: true,
+ },
+ { code: 'UY', label: 'Uruguay', phone: '598' },
+ { code: 'UZ', label: 'Uzbekistan', phone: '998' },
+ {
+ code: 'VA',
+ label: 'Holy See (Vatican City State)',
+ phone: '379',
+ },
+ {
+ code: 'VC',
+ label: 'Saint Vincent and the Grenadines',
+ phone: '1-784',
+ },
+ { code: 'VE', label: 'Venezuela', phone: '58' },
+ {
+ code: 'VG',
+ label: 'British Virgin Islands',
+ phone: '1-284',
+ },
+ {
+ code: 'VI',
+ label: 'US Virgin Islands',
+ phone: '1-340',
+ },
+ { code: 'VN', label: 'Vietnam', phone: '84' },
+ { code: 'VU', label: 'Vanuatu', phone: '678' },
+ { code: 'WF', label: 'Wallis and Futuna', phone: '681' },
+ { code: 'WS', label: 'Samoa', phone: '685' },
+ { code: 'XK', label: 'Kosovo', phone: '383' },
+ { code: 'YE', label: 'Yemen', phone: '967' },
+ { code: 'YT', label: 'Mayotte', phone: '262' },
+ { code: 'ZA', label: 'South Africa', phone: '27' },
+ { code: 'ZM', label: 'Zambia', phone: '260' },
+ { code: 'ZW', label: 'Zimbabwe', phone: '263' },
+];
+
+const countries = {};
+const countriesOptions = [];
+_countries.forEach((country) => {
+ countries[country.code] = country;
+ countriesOptions.push(country.code);
+});
+
+export default function CountrySelect({name, label, formik}) {
+ return (
+
+ {
+ formik.setFieldValue(name, value)
+ }}
+ error={Boolean(formik.touched[name] && formik.errors[name])}
+ getOptionLabel={(option) => {countries[option].label}
}
+ renderOption={(props, option) => (
+ img': { mr: 2, flexShrink: 0 } }} {...props}>
+
+ {countries[option].label} ({option.code}) +{countries[option].phone}
+
+ )}
+ renderInput={(params) => (
+
+ )}
+ />
+
+ );
+}
+
+export {
+ countries
+};
\ No newline at end of file
diff --git a/client/src/isLoggedIn.jsx b/client/src/isLoggedIn.jsx
index aca47fb..830517e 100644
--- a/client/src/isLoggedIn.jsx
+++ b/client/src/isLoggedIn.jsx
@@ -16,7 +16,7 @@ const IsLoggedIn = () => useEffect(() => {
window.location.href = '/ui/newmfa';
}
}
- });
+ })
}, []);
export default IsLoggedIn;
\ No newline at end of file
diff --git a/client/src/pages/authentication/auth-forms/AuthLogin.jsx b/client/src/pages/authentication/auth-forms/AuthLogin.jsx
index 1823436..a27ee1c 100644
--- a/client/src/pages/authentication/auth-forms/AuthLogin.jsx
+++ b/client/src/pages/authentication/auth-forms/AuthLogin.jsx
@@ -1,5 +1,5 @@
import React, { useEffect } from 'react';
-import { Link as RouterLink } from 'react-router-dom';
+import { Link, Link as RouterLink } from 'react-router-dom';
// material-ui
import {
@@ -30,6 +30,7 @@ import AnimateButton from '../../../components/@extended/AnimateButton';
// assets
import { EyeOutlined, EyeInvisibleOutlined } from '@ant-design/icons';
+import { LoadingButton } from '@mui/lab';
// ============================|| FIREBASE - LOGIN ||============================ //
@@ -182,10 +183,10 @@ const AuthLogin = () => {
/>
}
label={Keep me sign in}
- />
-
+ />*/}
+
Forgot Password?
- */}
+
{errors.submit && (
@@ -194,10 +195,9 @@ const AuthLogin = () => {
)}
-
-
-
+
{/*
diff --git a/client/src/pages/authentication/auth-forms/AuthRegister.jsx b/client/src/pages/authentication/auth-forms/AuthRegister.jsx
index 71a2dfc..a7dbf21 100644
--- a/client/src/pages/authentication/auth-forms/AuthRegister.jsx
+++ b/client/src/pages/authentication/auth-forms/AuthRegister.jsx
@@ -32,6 +32,7 @@ import { strengthColor, strengthIndicator } from '../../../utils/password-streng
// assets
import { EyeOutlined, EyeInvisibleOutlined } from '@ant-design/icons';
+import { LoadingButton } from '@mui/lab';
// ============================|| FIREBASE - REGISTER ||============================ //
@@ -178,10 +179,9 @@ const AuthRegister = ({nickname, isRegister, isInviteLink, regkey}) => {
)}
-
-
-
+
diff --git a/client/src/pages/authentication/forgotPassword.jsx b/client/src/pages/authentication/forgotPassword.jsx
new file mode 100644
index 0000000..984850b
--- /dev/null
+++ b/client/src/pages/authentication/forgotPassword.jsx
@@ -0,0 +1,122 @@
+import { Link } from 'react-router-dom';
+
+// material-ui
+import { Button, FormHelperText, Grid, InputLabel, OutlinedInput, Stack, Typography } from '@mui/material';
+
+// project import
+import AuthWrapper from './AuthWrapper';
+import { Formik } from 'formik';
+
+// third-party
+import * as Yup from 'yup';
+import * as API from '../../api';
+import { CosmosInputText } from '../config/users/formShortcuts';
+import { useState } from 'react';
+
+// ================================|| LOGIN ||================================ //
+
+const ForgotPassword = () => {
+ const [isSuccess, setIsSuccess] = useState(false);
+
+ return (
+
+
+
+ Password Reset
+ {/*
+ Don't have an account?
+ */}
+
+
+
+ {!isSuccess && {
+ try {
+ API.users.resetPassword(values).then((data) => {
+ if (data.status == 'error') {
+ setStatus({ success: false });
+ setErrors({ submit: 'Unexpected error. Check your infos or try again later.' });
+ setSubmitting(false);
+ return;
+ } else {
+ setStatus({ success: true });
+ setSubmitting(false);
+ setIsSuccess(true);
+ }
+ })
+ } catch (err) {
+ setStatus({ success: false });
+ setErrors({ submit: err.message });
+ setSubmitting(false);
+ }
+ }}
+ >
+ {(formik) => (
+
+ )}
+ }
+ {isSuccess &&
+ Check your email for a link to reset your password. If it doesn’t appear within a few minutes, check your spam folder.
+
+
+
}
+
+
+
+)};
+
+export default ForgotPassword;
diff --git a/client/src/pages/config/users/configman.jsx b/client/src/pages/config/users/configman.jsx
index c6bad43..0410b4a 100644
--- a/client/src/pages/config/users/configman.jsx
+++ b/client/src/pages/config/users/configman.jsx
@@ -28,7 +28,8 @@ import { EyeOutlined, EyeInvisibleOutlined } from '@ant-design/icons';
import AnimateButton from '../../../components/@extended/AnimateButton';
import RestartModal from './restart';
import { WarningOutlined, PlusCircleOutlined, CopyOutlined, ExclamationCircleOutlined , SyncOutlined, UserOutlined, KeyOutlined } from '@ant-design/icons';
-import { CosmosCheckbox, CosmosInputText, CosmosSelect } from './formShortcuts';
+import { CosmosCheckbox, CosmosFormDivider, CosmosInputPassword, CosmosInputText, CosmosSelect } from './formShortcuts';
+import CountrySelect, { countries } from '../../../components/countrySelect';
const ConfigManagement = () => {
@@ -57,6 +58,7 @@ const ConfigManagement = () => {
MongoDB: config.MongoDB,
LoggingLevel: config.LoggingLevel,
RequireMFA: config.RequireMFA,
+ GeoBlocking: config.BlockedCountries,
Hostname: config.HTTPConfig.Hostname,
GenerateMissingTLSCert: config.HTTPConfig.GenerateMissingTLSCert,
@@ -66,6 +68,14 @@ const ConfigManagement = () => {
SSLEmail: config.HTTPConfig.SSLEmail,
HTTPSCertificateMode: config.HTTPConfig.HTTPSCertificateMode,
DNSChallengeProvider: config.HTTPConfig.DNSChallengeProvider,
+
+ Email_Enabled: config.EmailConfig.Enabled,
+ Email_Host: config.EmailConfig.Host,
+ Email_Port: config.EmailConfig.Port,
+ Email_Username: config.EmailConfig.Username,
+ Email_Password: config.EmailConfig.Password,
+ Email_From: config.EmailConfig.From,
+ Email_UseTLS : config.EmailConfig.UseTLS,
}}
validationSchema={Yup.object().shape({
Hostname: Yup.string().max(255).required('Hostname is required'),
@@ -79,6 +89,7 @@ const ConfigManagement = () => {
MongoDB: values.MongoDB,
LoggingLevel: values.LoggingLevel,
RequireMFA: values.RequireMFA,
+ BlockedCountries: values.GeoBlocking,
HTTPConfig: {
...config.HTTPConfig,
Hostname: values.Hostname,
@@ -88,6 +99,16 @@ const ConfigManagement = () => {
SSLEmail: values.SSLEmail,
HTTPSCertificateMode: values.HTTPSCertificateMode,
DNSChallengeProvider: values.DNSChallengeProvider,
+ },
+ EmailConfig: {
+ ...config.EmailConfig,
+ Enabled: values.Email_Enabled,
+ Host: values.Email_Host,
+ Port: values.Email_Port,
+ Username: values.Email_Username,
+ Password: values.Email_Password,
+ From: values.Email_From,
+ UseTLS: values.Email_UseTLS,
}
}
@@ -116,245 +137,316 @@ const ConfigManagement = () => {
>
{(formik) => (
)}
diff --git a/client/src/pages/config/users/formShortcuts.jsx b/client/src/pages/config/users/formShortcuts.jsx
index 6a1ed9a..11c8370 100644
--- a/client/src/pages/config/users/formShortcuts.jsx
+++ b/client/src/pages/config/users/formShortcuts.jsx
@@ -52,7 +52,7 @@ export const CosmosInputText = ({ name, style, multiline, type, placeholder, onC
}
-export const CosmosInputPassword = ({ name, type, placeholder, onChange, label, formik }) => {
+export const CosmosInputPassword = ({ name, noStrength, type, placeholder, onChange, label, formik }) => {
const [level, setLevel] = React.useState();
const [showPassword, setShowPassword] = React.useState(false);
const handleClickShowPassword = () => {
@@ -108,7 +108,7 @@ export const CosmosInputPassword = ({ name, type, placeholder, onChange, label,
)}
-
+ {!noStrength &&
@@ -119,7 +119,7 @@ export const CosmosInputPassword = ({ name, type, placeholder, onChange, label,
-
+ }
}
diff --git a/client/src/pages/config/users/usermanagement.jsx b/client/src/pages/config/users/usermanagement.jsx
index 93524a0..f1129c4 100644
--- a/client/src/pages/config/users/usermanagement.jsx
+++ b/client/src/pages/config/users/usermanagement.jsx
@@ -30,6 +30,7 @@ const UserManagement = () => {
const [openDeleteForm, setOpenDeleteForm] = React.useState(false);
const [openInviteForm, setOpenInviteForm] = React.useState(false);
const [toAction, setToAction] = React.useState(null);
+ const [loadingRow, setLoadingRow] = React.useState(null);
const roles = ['Guest', 'User', 'Admin']
@@ -39,6 +40,7 @@ const UserManagement = () => {
setIsLoading(true);
API.users.list()
.then(data => {
+ setLoadingRow(null);
setRows(data.data);
setIsLoading(false);
})
@@ -50,30 +52,45 @@ const UserManagement = () => {
function sendlink(nickname, formType) {
API.users.invite({
- nickname
+ nickname,
+ formType: ""+formType,
})
.then((values) => {
let sendLink = window.location.origin + '/ui/register?t='+formType+'&nickname='+nickname+'&key=' + values.data.registerKey;
- setToAction({...values.data, nickname, sendLink, formType});
+ setToAction({...values.data, nickname, sendLink, formType, formAction: formType === 2 ? 'invite them to the server' : 'let them reset their password'});
setOpenInviteForm(true);
});
}
return <>
+
{openInviteForm ?