More CSRF in forms.

This commit is contained in:
gaba
2016-12-22 14:17:09 -08:00
parent 075fe7f6b4
commit 54d0096dd1
10 changed files with 44 additions and 20 deletions
+10 -3
View File
@@ -10,13 +10,20 @@ const checkLoginFailure = error => ({type: actions.CHECK_LOGIN_FAILURE, error});
export const checkLogin = () => dispatch => {
dispatch(checkLoginRequest());
coralApi('/auth')
.then(user => {
const isAdmin = !!user.roles.filter(i => i === 'admin').length;
dispatch(checkLoginSuccess(user, isAdmin));
.then(result => {
if (result.csrfToken !== null) {
dispatch(checkCSRFToken(result.csrfToken));
}
const isAdmin = !!result.user.roles.filter(i => i === 'admin').length;
dispatch(checkLoginSuccess(result.user, isAdmin));
})
.catch(error => dispatch(checkLoginFailure(error)));
};
// Set CSRF Token
export const checkCSRFToken = (csrfToken) => ({type: actions.CHECK_CSRF_TOKEN, csrfToken});
// LogOut Actions
const logOutRequest = () => ({type: actions.LOGOUT_REQUEST});
+2 -2
View File
@@ -31,9 +31,9 @@ export const fetchModerationQueueComments = () => {
};
// Create a new comment
export const createComment = (name, body) => {
export const createComment = (name, body, _csrf) => {
return dispatch => {
const comment = {body, name};
const comment = {body, name, _csrf};
return coralApi('/comments', {method: 'POST', comment})
.then(res => dispatch({type: commentActions.COMMENT_CREATE_SUCCESS, comment: res}))
.catch(error => dispatch({type: commentActions.COMMENT_CREATE_FAILED, error}));
@@ -7,13 +7,13 @@ import {Button} from 'react-mdl';
export default class CommentBox extends React.Component {
constructor (props) {
super(props);
this.state = {name: '', body: ''};
this.state = {name: '', body: '', csrfToken: props.csrfToken};
this.onSubmit = this.onSubmit.bind(this);
}
onSubmit () {
const {name, body} = this.state;
this.props.onSubmit({name, body});
const {name, body, csrfToken} = this.state;
this.props.onSubmit({name, body, csrfToken});
this.setState({body: '', name: ''});
}
+2
View File
@@ -2,6 +2,8 @@ export const CHECK_LOGIN_REQUEST = 'CHECK_LOGIN_REQUEST';
export const CHECK_LOGIN_SUCCESS = 'CHECK_LOGIN_SUCCESS';
export const CHECK_LOGIN_FAILURE = 'CHECK_LOGIN_FAILURE';
export const CHECK_CSRF_TOKEN = 'CHECK_CSRF_TOKEN';
export const LOGOUT_REQUEST = 'LOGOUT_REQUEST';
export const LOGOUT_SUCCESS = 'LOGOUT_SUCCESS';
export const LOGOUT_FAILURE = 'LOGOUT_FAILURE';
@@ -14,7 +14,8 @@ import CommentBox from 'components/CommentBox';
class CommentStream extends React.Component {
constructor (props) {
super(props);
this.state = {snackbar: false, snackbarMsg: ''};
console.log('PROPS IN COMMENTSTREAM ', props);
this.state = {snackbar: false, snackbarMsg: '', csrfToken: props.csrfToken};
this.onSubmit = this.onSubmit.bind(this);
this.onClickAction = this.onClickAction.bind(this);
}
@@ -25,8 +26,8 @@ class CommentStream extends React.Component {
}
// Submit the new comment
onSubmit (comment) {
this.props.dispatch(createComment(comment.name, comment.body));
onSubmit (comment, csrfToken) {
this.props.dispatch(createComment(comment.name, comment.body, csrfToken));
}
// The only action for now is flagging
@@ -43,7 +44,7 @@ class CommentStream extends React.Component {
render ({comments, users}, {snackbar, snackbarMsg}) {
return (
<div className={styles.container}>
<CommentBox onSubmit={this.onSubmit} />
<CommentBox onSubmit={this.onSubmit} csrfToken={this.state.csrfToken}/>
<CommentList isActive hideActive
singleView={false}
commentIds={comments.ids}
+5 -1
View File
@@ -4,7 +4,8 @@ import * as actions from '../constants/auth';
const initialState = Map({
loggedIn: false,
user: null,
isAdmin: false
isAdmin: false,
csrfToken: ''
});
export default function auth (state = initialState, action) {
@@ -25,6 +26,9 @@ export default function auth (state = initialState, action) {
.set('user', action.user);
case actions.LOGOUT_SUCCESS:
return initialState;
case actions.CHECK_CSRF_TOKEN:
return state
.set('csrfToken', action.csrfToken);
default :
return state;
}
@@ -133,7 +133,8 @@ class CommentStream extends Component {
currentUser={this.props.auth.user}
banned={banned}
author={user}
charCount={charCountEnable && charCount}/>
charCount={charCountEnable && charCount}
csrfToken={csrfToken}/>
</RestrictedContent>
</div>
: <p>{closedMessage}</p>
@@ -204,6 +205,7 @@ class CommentStream extends Component {
premod={moderation}
currentUser={user}
charCount={charCountEnable && charCount}
csrfToken={csrfToken}
showReply={comment.showReply}/>
{
comment.children &&
@@ -264,6 +266,7 @@ class CommentStream extends Component {
banned={banned}
currentUser={user}
charCount={charCountEnable && charCount}
csrfToken={csrfToken}
showReply={reply.showReply}/>
</div>;
})
@@ -316,7 +319,7 @@ const mapStateToProps = state => ({
const mapDispatchToProps = (dispatch) => ({
addItem: (item, item_id) => dispatch(addItem(item, item_id)),
updateItem: (id, property, value, itemType) => dispatch(updateItem(id, property, value, itemType)),
postItem: (data, type, id) => dispatch(postItem(data, type, id)),
postItem: (data, type, id, csrfToken) => dispatch(postItem(data, type, id, csrfToken)),
getStream: (rootId) => dispatch(getStream(rootId)),
addNotification: (type, text) => dispatch(addNotification(type, text)),
clearNotification: () => dispatch(clearNotification()),
+3 -1
View File
@@ -24,10 +24,10 @@ const signInSuccess = (user, isAdmin) => ({type: actions.FETCH_SIGNIN_SUCCESS, u
const signInFailure = error => ({type: actions.FETCH_SIGNIN_FAILURE, error});
export const fetchSignIn = (formData) => dispatch => {
console.log('DEBUG FORMDATA', formData);
dispatch(signInRequest());
coralApi('/auth/local', {method: 'POST', body: formData})
.then(({user}) => {
console.log('DEBUG FORMDATA ', formData);
const isAdmin = !!user.roles.filter(i => i === 'admin').length;
dispatch(signInSuccess(user, isAdmin));
dispatch(hideSignInDialog());
@@ -127,7 +127,9 @@ export const checkLogin = () => dispatch => {
dispatch(checkLoginRequest());
coralApi('/auth')
.then((result) => {
console.log('debug 1 result ', result);
if (result.csrfToken !== null) {
console.log('DEBUG 2 TOKEN', result.csrfToken);
dispatch(checkCSRFToken(result.csrfToken));
}
+5 -3
View File
@@ -14,7 +14,8 @@ class CommentBox extends Component {
comments: PropTypes.array,
reply: PropTypes.bool,
canPost: PropTypes.bool,
currentUser: PropTypes.object
currentUser: PropTypes.object,
csrfToken: PropTypes.string
}
state = {
@@ -32,7 +33,8 @@ class CommentBox extends Component {
addNotification,
appendItemArray,
premod,
author
author,
csrfToken
} = this.props;
let comment = {
@@ -57,7 +59,7 @@ class CommentBox extends Component {
if (this.props.charCount && this.state.body.length > this.props.charCount) {
return;
}
postItem(comment, 'comments')
postItem(comment, 'comments', csrfToken)
.then((postedComment) => {
const commentId = postedComment.id;
if (postedComment.status === 'rejected') {
+4 -1
View File
@@ -16,9 +16,12 @@ const parseForm = bodyParser.urlencoded({extended: false});
* This returns the user if they are logged in.
*/
router.get('/', csrfProtection, (req, res, next) => {
console.log('DEBUT WHAT IS GOING ?', req.user);
if (req.user) {
return next();
}
console.log('it has the user but what the hek?');
// When there is no user on the request, then just send back the CSRF token.
res.json({csrfToken: req.csrfToken()});
@@ -87,7 +90,7 @@ const HandleAuthPopupCallback = (req, res, next) => (err, user) => {
* Local auth endpoint, will recieve a email and password
*/
router.post('/local', parseForm, csrfProtection, (req, res, next) => {
// Perform the local authentication.
passport.authenticate('local', HandleAuthCallback(req, res, next))(req, res, next);
});