Я пытаюсь получить входное значение в mongoDB, пока хешируется мой пароль.
Но мой пароль в моей схеме находится внутри объекта (localProvider). (Это только для образования, это то, что закодировал мой учитель)
{
username: {
type: String,
required: false,
},
email: {
type: String,
required: true,
trim: true,
unique: true,
match: /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/,
},
localProvider: {
password: {
type: String,
required: false,
},
},
facebookProvider: {
id: { type: String, required: false },
token: { type: String, required: false },
},
published_at: { type: Date, required: false },
deleted_at: { type: Date, required: false },
},
{
toJSON: { virtuals: true },
toObject: { virtuals: true },
},
{
timestamps: { createdAt: 'created_at', updatedAt: 'updated_at' },
},
);
UserSchema.methods.slugify = function () {
this.slug = slug(this.email);
};
UserSchema.pre('validate', function (next) {
if (!this.slug) {
this.slugify();
}
return next();
});
UserSchema.pre('save', function (next) {
const user = this;
if (!user.isModified('localProvider.password')) return next();// only hash the password if it has been modified (or is new)
try {
return bcrypt.genSalt(config.auth.bcrypt.SALT_WORK_FACTOR, (errSalt, salt) => {
if (errSalt) throw errSalt;
return bcrypt.hash(user.localProvider.password, salt, (errHash, hash) => {
if (errHash) throw errHash;
user.localProvider.password = hash;
return next();
});
});
} catch (error) {
return next(error);
}
});
UserSchema.methods.comparePassword = function (candidatePassword, cb) {
const user = this;
bcrypt.compare(candidatePassword, user.localProvider.password, (err, isMatch) => {
if (err) return cb(err, null);
return cb(null, isMatch);
});
};
UserSchema.virtual('id').get(function () { return this._id; });
UserSchema.plugin(mongoosePaginate);
export default mongoose.model('User', UserSchema);
Я попытался в register.js передать свои входные значения с помощью onChange
[event.target.name]: event.target.value
Только эта строка кода работает только для отдельных значений, а не внутри объекта.
Как вы видели на схеме, насколько я знаю, нет способа передать значение одному значению состояния и вложенному состоянию.
Так есть ли решение для исправления кода, чтобы я мог также передать имя пользователя и адрес электронной почты в состояние и отправить пароль для localProvider в 1 handleChange?
код из моего register.js
class Signup extends Component {
constructor() {
super()
this.state = {
username: '',
email: '',
redirectTo: null,
localProvider:{
password: ''
}
}
this.handleSubmit = this.handleSubmit.bind(this)
this.handleChange = this.handleChange.bind(this)
}
handleInputChange(event, value){
this.setState({
[event.target.name]: event.target.value
})
}
handleChange(el) {
let inputName = el.target.name;
let inputValue = el.target.value;
let statusCopy = Object.assign({}, this.state);
statusCopy.localProvider[inputName].value = inputValue;
this.setState(statusCopy);
}
handleSubmit(event) {
console.log('sign-up handleSubmit, username: ')
console.log(this.state.username)
event.preventDefault()
//request to server to add a new username/password
axios.post('/api/v1/users/', {
...this.state
})
.then(response => {
console.log(response)
if (!response.data.errmsg) {
console.log('successful signup')
this.props.history.push("/");
} else {
console.log('username already taken')
}
}).catch(error => {
console.log('signup error: ')
console.log(error)
})
}
render() {
const { classes } = this.props;
return (
<React.Fragment>
<CssBaseline />
<Paper className={classes.paper}>
<Avatar className={classes.avatar}>
<LockOutlinedIcon />
</Avatar>
<Typography component="h1" variant="h5">
Sign in
</Typography>
<form className={classes.form}>
<FormControl margin="normal" required fullWidth>
<InputLabel htmlFor="name">Name</InputLabel>
<Input name="username" type="text" id="username" autoComplete="username" onChange={this.handleInputChange} />
</FormControl>
<FormControl margin="normal" required fullWidth>
<InputLabel htmlFor="email">Email Address</InputLabel>
<Input id="email" name="email" autoComplete="email" onChange={this.handleInputChange} />
</FormControl>
<FormControl margin="normal" required fullWidth>
<InputLabel htmlFor="password">Password</InputLabel>
<Input type="password" id="password" autoComplete="current-password" onChange={this.handleChange} name="password"/>
</FormControl>
<FormControlLabel
control={<Checkbox value="remember" color="primary" />}
label="Remember me"
/>
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
>
Sign in
</Button>
</form>
</Paper>
</React.Fragment>
)
}
}
export default withStyles(styles)(Signup);```