Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added changes to flask-server to configure admin panel #498

Closed
wants to merge 13 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 24 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,20 @@ Run npm install in fact-bounty-client folder.
export ELASTIC_SEARCH_URL=""
export ELASTIC_SEARCH_USERNAME=""
export ELASTIC_SEARCH_PASSWORD=""

export TZ="Asia/Colombo"

export MAIL_USERNAME=""
export MAIL_PASSWORD=""
export FACTBOUNTY_ADMIN=""
export MAIL_PORT="587"
export MAIL_USE_TLS="true"
export MAIL_SERVER="smtp.gmail.com"

export ADMIN_USERNAME = "admin"
export ADMIN_PASSWORD = "password"
export ADMIN_EMAIL = "[email protected]"


export TZ=“Asia/Colombo”
```
Expand Down Expand Up @@ -107,12 +121,12 @@ Run npm install in fact-bounty-client folder.

### How to install Elasticsearch and start elasticsearch server

* #### Elasticsearch v6.7.0 can be installed as follows:
* #### Elasticsearch v7.6.0 can be installed as follows:
```
(venv)$ wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.7.0.deb
(venv)$ wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.7.0.deb.sha512
(venv)$ shasum -a 512 -c elasticsearch-6.7.0.deb.sha512
(venv)$ sudo dpkg -i elasticsearch-6.7.0.deb
(venv)$ wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.6.0.deb
(venv)$ wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.6.0.deb.sha512
(venv)$ shasum -a 512 -c elasticsearch-7.6.0.deb.sha512
(venv)$ sudo dpkg -i elasticsearch-7.6.0.deb

```

Expand Down Expand Up @@ -202,6 +216,10 @@ And use [localhost:3000](https://) to browse.

* #### Once build completes, run `docker-compose up`

## Setting up an OAuth Daemon

[How to setup OAuth Daemon](OAuthdSetup.md)

# How to Contribute

- First fork the repository and clone it.
Expand All @@ -211,3 +229,4 @@ And use [localhost:3000](https://) to browse.

## License
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fscorelab%2Ffact-Bounty.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fscorelab%2Ffact-Bounty?ref=badge_large)

9 changes: 8 additions & 1 deletion fact-bounty-client/src/AppRouter.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import Dashboard from './pages/Dashboard'
import Posts from './pages/Posts'
import PostDetailView from './pages/PostDetailView'
import Tweets from './pages/Tweets'

import ForgotPassword from './pages/ForgotPassword'
import ResetPassword from './pages/ResetPassword'
class AppRouter extends Component {
render() {
return (
Expand All @@ -23,6 +24,12 @@ class AppRouter extends Component {
<Route exact path="/" component={Landing} />
<Route exact path="/register" component={Register} />
<Route exact path="/login" component={Login} />
<Route exact path="/forgotpassword" component={ForgotPassword} />
<Route
exact
path="/resetpassword/:verificationToken"
component={ResetPassword}
/>
<Route path="/dashboard" component={Dashboard} />
<Route exact path="/posts" component={Posts} />
<Route exact path="/tweets" component={Tweets} />
Expand Down
255 changes: 255 additions & 0 deletions fact-bounty-client/src/pages/ForgotPassword/ForgotPassword.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import classnames from 'classnames'
import compose from 'recompose/compose'
import Avatar from '@material-ui/core/Avatar'
import Button from '@material-ui/core/Button'
import CssBaseline from '@material-ui/core/CssBaseline'
import FormControl from '@material-ui/core/FormControl'
import Input from '@material-ui/core/Input'
import InputLabel from '@material-ui/core/InputLabel'
import LockOutlinedIcon from '@material-ui/icons/LockOutlined'
import Paper from '@material-ui/core/Paper'
import Typography from '@material-ui/core/Typography'
import withStyles from '@material-ui/core/styles/withStyles'
import Toast from '../../components/Toast'
import { updateError } from '../../redux/actions/errorActions'
import { updateSuccess } from '../../redux/actions/successActions'
import {
forgotPassword,
authVerificationToken
} from '../../redux/actions/authActions'
import styles from './ForgotPassword.style'

class ForgotPassword extends Component {
constructor() {
super()
this.state = {
email: '',
verificationToken: '',
errors: {},
success: {},
emailValid: false,
verificationTokenValid: false,
formValid: false,
openToast: false
}
}

componentDidMount() {
// If logged in and user navigates to Register page, should redirect them to dashboard
this.props.updateError({})
this.props.updateSuccess({})
if (this.props.auth.isAuthenticated) {
this.props.history.push('/dashboard')
}
}

static getDerivedStateFromProps(props, state) {
if (props.errors) {
const errors = props.errors
let openToast = false
if (errors.fetch) {
openToast = true
}
return { errors, openToast }
}
if (props.success) {
const success = props.success
let openToast = false
if (success.fetch) {
openToast = true
}
return { success, openToast }
}
return null
}

onChange = e => {
let { id, value } = e.target
this.setState({ [id]: value }, () => {
this.validateField(id, value)
})
}

validateField = (fieldname, value) => {
let { emailValid, verificationTokenValid, errors } = this.state

emailValid = value.match(/^([\w.%+-]+)@([\w-]+\.)+([\w]{2,})$/i)
verificationTokenValid = !!this.state.verificationToken
switch (fieldname) {
case 'email':
errors.email = emailValid ? '' : 'Invalid E-mail'
break
default:
break
}
this.setState(
{
errors,
emailValid,
verificationTokenValid
},
this.validateForm
)
}

validateForm = () => {
this.setState({
formValid: this.state.emailValid || this.state.verificationToken !== ''
})
}
closeToast = () => {
// Remove error from store
this.props.updateError({})
this.props.updateSuccess({})
this.setState({ openToast: false })
}

onSubmit = e => {
e.preventDefault()
// Remove error from store
this.props.updateSuccess({})
this.props.updateError({})

const { email } = this.state
if (!this.props.success.message) {
this.props.forgotPassword({ email: email })
} else {
this.props.authVerificationToken(
{
verification_token: this.state.verificationToken
},
this.props.history
)
}
}

render() {
const { errors, openToast } = this.state
var formInput, buttonName
if (!this.props.success.message) {
formInput = (
<FormControl margin="normal" required fullWidth>
<InputLabel htmlFor="email">Email Address</InputLabel>
<Input
autoComplete="on"
onChange={this.onChange}
validate
value={this.state.email}
error={!!errors.email}
id="email"
type="email"
className={classnames('', {
invalid: errors.email
})}
/>
<Typography component="span" variant="caption" color="error">
{errors.email}
</Typography>
</FormControl>
)
buttonName = 'Send verification code'
} else {
formInput = (
<FormControl margin="normal" required fullWidth>
<InputLabel htmlFor="verificationToken">
Verification token
</InputLabel>
<Input
autoComplete="on"
onChange={this.onChange}
value={this.state.verificationToken}
id="verificationToken"
/>
</FormControl>
)
buttonName = 'Verify token'
}
return (
<main className={this.props.classes.main}>
<CssBaseline />
<Paper className={this.props.classes.paper}>
{errors.fetch ? (
<Toast
open={openToast}
onClose={this.closeToast}
message="Something went wrong, Try again later"
variant="error"
/>
) : null}
<Avatar className={this.props.classes.avatar}>
<LockOutlinedIcon />
</Avatar>
<Typography component="h1" variant="h5">
Forgot Password
</Typography>

<form
noValidate
onSubmit={this.onSubmit}
className={this.props.classes.form}
>
<Typography component="span" variant="caption" color="error">
{typeof this.props.errors === 'object'
? this.props.errors.message
: null}
</Typography>
<Typography
component="span"
variant="caption"
color="primary"
align="center"
>
{typeof this.props.success === 'object'
? this.props.success.message
: null}
</Typography>
{formInput}
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
className={this.props.classes.submit}
disabled={!this.state.formValid}
>
{buttonName}
</Button>
</form>
</Paper>
</main>
)
}
}

ForgotPassword.propTypes = {
forgotPassword: PropTypes.func.isRequired,
authVerificationToken: PropTypes.func.isRequired,
auth: PropTypes.object.isRequired,
errors: PropTypes.object.isRequired,
success: PropTypes.object.isRequired,
history: PropTypes.object,
classes: PropTypes.object,
updateError: PropTypes.func.isRequired,
updateSuccess: PropTypes.func.isRequired
}

const mapStateToProps = state => ({
auth: state.auth,
errors: state.errors,
success: state.success
})

export default compose(
withStyles(styles, {
name: 'ForgotPassword'
}),
connect(mapStateToProps, {
forgotPassword,
authVerificationToken,
updateError,
updateSuccess
})
)(ForgotPassword)
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
export default theme => ({
main: {
width: 'auto',
display: 'block', // Fix IE 11 issue.
marginLeft: theme.spacing.unit * 3,
marginRight: theme.spacing.unit * 3,
[theme.breakpoints.up(400 + theme.spacing.unit * 3 * 2)]: {
width: 400,
marginLeft: 'auto',
marginRight: 'auto'
}
},
paper: {
marginTop: theme.spacing.unit * 12,
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
padding: `${theme.spacing.unit * 2}px ${theme.spacing.unit * 3}px ${theme
.spacing.unit * 3}px`
},
avatar: {
margin: theme.spacing.unit,
backgroundColor: theme.palette.secondary.main
},
form: {
width: '100%', // Fix IE 11 issue.
marginTop: theme.spacing.unit
},
submit: {
marginTop: theme.spacing.unit * 3
}
})
2 changes: 2 additions & 0 deletions fact-bounty-client/src/pages/ForgotPassword/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import ForgotPassword from './ForgotPassword'
export default ForgotPassword
8 changes: 7 additions & 1 deletion fact-bounty-client/src/pages/Login/Login.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,13 @@ class Login extends Component {
>
Login
</Button>

<p style={{ textAlign: 'center' }}>
{' '}
<br />
<Link component={RouterLink} to="/forgotpassword">
Forgot password ?
</Link>
</p>
<div
style={{
width: '100%',
Expand Down
Loading