some adjustments to how locking and verification work
This commit is contained in:
@@ -40,13 +40,14 @@ async function login(args) {
|
||||
}
|
||||
const authResult = await userDoc.authenticate(password);
|
||||
|
||||
if (authResult.user) {
|
||||
await authResult.user.resetLoginAttempts();
|
||||
} else {
|
||||
await userDoc.incLoginAttempts();
|
||||
const maxLoginAttemptsEnabled = args.collection.config.auth.maxLoginAttempts > 0;
|
||||
if (!authResult.user) {
|
||||
if (maxLoginAttemptsEnabled) await userDoc.incLoginAttempts();
|
||||
throw new AuthenticationError();
|
||||
}
|
||||
|
||||
if (maxLoginAttemptsEnabled) await authResult.user.resetLoginAttempts();
|
||||
|
||||
const userQuery = await operations.collections.find({
|
||||
where: {
|
||||
email: {
|
||||
|
||||
@@ -13,7 +13,7 @@ import './index.scss';
|
||||
const baseClass = 'auth-fields';
|
||||
|
||||
const Auth = (props) => {
|
||||
const { useAPIKey, requirePassword } = props;
|
||||
const { useAPIKey, requirePassword, emailVerification } = props;
|
||||
const [changingPassword, setChangingPassword] = useState(requirePassword);
|
||||
const { getField } = useFormFields();
|
||||
const modified = useFormModified();
|
||||
@@ -74,6 +74,13 @@ const Auth = (props) => {
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{emailVerification && (
|
||||
<Checkbox
|
||||
label="Verified"
|
||||
name="_verified"
|
||||
readOnly
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -81,11 +88,13 @@ const Auth = (props) => {
|
||||
Auth.defaultProps = {
|
||||
useAPIKey: false,
|
||||
requirePassword: false,
|
||||
emailVerification: false,
|
||||
};
|
||||
|
||||
Auth.propTypes = {
|
||||
useAPIKey: PropTypes.bool,
|
||||
requirePassword: PropTypes.bool,
|
||||
emailVerification: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default Auth;
|
||||
|
||||
@@ -91,6 +91,7 @@ const DefaultEditView = (props) => {
|
||||
<Auth
|
||||
useAPIKey={auth.useAPIKey}
|
||||
requirePassword={!isEditing}
|
||||
emailVerification={auth.emailVerification}
|
||||
/>
|
||||
)}
|
||||
{upload && (
|
||||
@@ -233,6 +234,7 @@ DefaultEditView.propTypes = {
|
||||
timestamps: PropTypes.bool,
|
||||
auth: PropTypes.shape({
|
||||
useAPIKey: PropTypes.bool,
|
||||
emailVerification: PropTypes.bool,
|
||||
}),
|
||||
upload: PropTypes.shape({}),
|
||||
}).isRequired,
|
||||
|
||||
@@ -24,15 +24,14 @@ function registerCollections() {
|
||||
usernameField: 'email',
|
||||
});
|
||||
|
||||
// Check if collection is the admin user set in config
|
||||
if (collection.slug === this.config.admin.user) {
|
||||
|
||||
const { maxLoginAttempts, lockTime } = collection.auth;
|
||||
|
||||
if (maxLoginAttempts > 0) {
|
||||
schema.add({ loginAttempts: { type: Number, hide: true, default: 0 } });
|
||||
schema.add({ lockUntil: { type: Date, hide: true } });
|
||||
|
||||
schema.virtual('isLocked').get(() => !!(this.lockUntil && this.lockUntil > Date.now()));
|
||||
|
||||
const { maxLoginAttempts, lockTime } = this.config.admin;
|
||||
|
||||
// eslint-disable-next-line func-names
|
||||
schema.methods.incLoginAttempts = function (cb) {
|
||||
// Expired lock, restart count at 1
|
||||
|
||||
@@ -241,13 +241,19 @@ const sanitizeCollection = (collections, collection) => {
|
||||
authFields.push({
|
||||
name: '_verified',
|
||||
type: 'checkbox',
|
||||
hidden: true,
|
||||
access: {
|
||||
create: () => false,
|
||||
update: () => false,
|
||||
},
|
||||
admin: {
|
||||
disabled: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
sanitized.auth.maxLoginAttempts = typeof sanitized.auth.maxLoginAttempts === 'undefined' ? 5 : sanitized.auth.maxLoginAttempts;
|
||||
sanitized.auth.lockTime = sanitized.auth.lockTime || 600000; // 10 minutes
|
||||
|
||||
if (!sanitized.auth.tokenExpiration) sanitized.auth.tokenExpiration = 7200;
|
||||
|
||||
if (!sanitized.auth.cookies) sanitized.auth.cookies = {};
|
||||
|
||||
@@ -5,11 +5,16 @@ const bodyParser = require('body-parser');
|
||||
const methodOverride = require('method-override');
|
||||
const qsMiddleware = require('qs-middleware');
|
||||
const fileUpload = require('express-fileupload');
|
||||
const rateLimit = require('express-rate-limit');
|
||||
const localizationMiddleware = require('../../localization/middleware');
|
||||
const authenticate = require('./authenticate');
|
||||
const identifyAPI = require('./identifyAPI');
|
||||
|
||||
const middleware = (payload) => [
|
||||
rateLimit({
|
||||
windowMs: payload.config.rateLimit.window,
|
||||
max: payload.config.rateLimit.max,
|
||||
}),
|
||||
passport.initialize(),
|
||||
identifyAPI('REST'),
|
||||
authenticate(payload.config),
|
||||
|
||||
@@ -3,7 +3,6 @@ require('isomorphic-fetch');
|
||||
|
||||
const express = require('express');
|
||||
const graphQLPlayground = require('graphql-playground-middleware-express').default;
|
||||
const rateLimit = require('express-rate-limit');
|
||||
const logger = require('./utilities/logger')();
|
||||
const bindOperations = require('./init/bindOperations');
|
||||
const bindRequestHandlers = require('./init/bindRequestHandlers');
|
||||
@@ -99,12 +98,8 @@ class Payload {
|
||||
},
|
||||
}));
|
||||
|
||||
const apiLimiter = rateLimit({
|
||||
windowMs: this.config.rateLimit.window,
|
||||
max: this.config.rateLimit.max,
|
||||
});
|
||||
// Bind router to API and add rate limiter
|
||||
this.express.use(this.config.routes.api, apiLimiter, this.router);
|
||||
// Bind router to API
|
||||
this.express.use(this.config.routes.api, this.router);
|
||||
|
||||
// Enable static routes for all collections permitting upload
|
||||
this.initStatic();
|
||||
|
||||
@@ -29,9 +29,6 @@ const sanitizeConfig = (config) => {
|
||||
sanitizedConfig.collections.push(defaultUser);
|
||||
}
|
||||
|
||||
sanitizedConfig.maxLoginAttempts = sanitizedConfig.maxLoginAttempts || 3;
|
||||
sanitizedConfig.lockTime = sanitizedConfig.lockTime || 600000; // 10 minutes
|
||||
|
||||
sanitizedConfig.email = config.email || {};
|
||||
sanitizedConfig.email.fromName = sanitizedConfig.email.fromName || 'Payload';
|
||||
sanitizedConfig.email.fromAddress = sanitizedConfig.email.fromName || 'hello@payloadcms.com';
|
||||
|
||||
Reference in New Issue
Block a user