added frontend for last.fm username updating

fixed password updating
changed password statuses from text to toast
added maths menu item
This commit is contained in:
aj 2019-10-19 17:57:56 +01:00
parent 77a7583913
commit 849c0a5fa6
6 changed files with 146 additions and 35 deletions

View File

@ -227,7 +227,8 @@ def user(username=None):
'username': pulled_user['username'], 'username': pulled_user['username'],
'type': pulled_user['type'], 'type': pulled_user['type'],
'spotify_linked': pulled_user['spotify_linked'], 'spotify_linked': pulled_user['spotify_linked'],
'validated': pulled_user['validated'] 'validated': pulled_user['validated'],
'lastfm_username': pulled_user['lastfm_username']
} }
return jsonify(response), 200 return jsonify(response), 200
@ -239,10 +240,10 @@ def user(username=None):
request_json = request.get_json() request_json = request.get_json()
if 'username' not in request_json: if 'username' in request_json:
return jsonify({'status': 'error', 'message': 'no username provided'}), 400 username = request_json['username']
actionable_user = database.get_user_doc_ref(request_json['username']) actionable_user = database.get_user_doc_ref(username)
if actionable_user.get().exists is False: if actionable_user.get().exists is False:
return jsonify({"message": 'non-existent user', "status": "error"}), 400 return jsonify({"message": 'non-existent user', "status": "error"}), 400
@ -262,12 +263,16 @@ def user(username=None):
'spotify_linked': False 'spotify_linked': False
}) })
if 'lastfm_username' in request_json:
logger.info(f'updating lastfm username {username} -> {request_json["lastfm_username"]}')
dic['lastfm_username'] = request_json['lastfm_username']
if len(dic) == 0: if len(dic) == 0:
logger.warning(f'no updates for {request_json["username"]}') logger.warning(f'no updates for {request_json["username"]}')
return jsonify({"message": 'no changes to make', "status": "error"}), 400 return jsonify({"message": 'no changes to make', "status": "error"}), 400
actionable_user.update(dic) actionable_user.update(dic)
logger.info(f'updated {request_json["username"]}') logger.info(f'updated {username}')
return jsonify({'message': 'account updated', 'status': 'succeeded'}), 200 return jsonify({'message': 'account updated', 'status': 'succeeded'}), 200
@ -298,7 +303,7 @@ def users(username=None):
@blueprint.route('/user/password', methods=['POST']) @blueprint.route('/user/password', methods=['POST'])
@login_required @login_required
def change_password(): def change_password(username=None):
request_json = request.get_json() request_json = request.get_json()
@ -310,17 +315,17 @@ def change_password():
if len(request_json['new_password']) > 30: if len(request_json['new_password']) > 30:
return jsonify({"error": 'password too long'}), 400 return jsonify({"error": 'password too long'}), 400
current_user = database.get_user_doc_ref(session['username']) current_user = database.get_user_doc_ref(username)
if check_password_hash(current_user.get().to_dict()['password'], request_json['current_password']): if check_password_hash(current_user.get().to_dict()['password'], request_json['current_password']):
current_user.update({'password': generate_password_hash(request_json['new_password'])}) current_user.update({'password': generate_password_hash(request_json['new_password'])})
logger.info(f'password udpated {session["username"]}') logger.info(f'password udpated {username}')
return jsonify({"message": 'password changed', "status": "success"}), 200 return jsonify({"message": 'password changed', "status": "success"}), 200
else: else:
logger.warning(f"incorrect password {session['username']}") logger.warning(f"incorrect password {username}")
return jsonify({'error': 'wrong password provided'}), 401 return jsonify({'error': 'wrong password provided'}), 401
else: else:

18
src/js/Maths/Maths.js Normal file
View File

@ -0,0 +1,18 @@
import React, { Component } from "react";
import { BrowserRouter as Router, Route, Link, Switch, Redirect} from "react-router-dom";
class Maths extends Component {
render() {
return (
<div>
</div>
);
}
}
export default Maths;

View File

@ -2,6 +2,7 @@ import React, { Component } from "react";
import { BrowserRouter as Router, Route, Link, Switch, Redirect} from "react-router-dom"; import { BrowserRouter as Router, Route, Link, Switch, Redirect} from "react-router-dom";
import Index from "./Index/Index.js"; import Index from "./Index/Index.js";
import Maths from "./Maths/Maths.js";
import Playlists from "./Playlist/Playlists.js"; import Playlists from "./Playlist/Playlists.js";
import PlaylistView from "./Playlist/PlaylistView.js"; import PlaylistView from "./Playlist/PlaylistView.js";
import Settings from "./Settings/Settings.js"; import Settings from "./Settings/Settings.js";
@ -57,8 +58,9 @@ class PlaylistManager extends Component {
<tbody> <tbody>
<tr><td><span><Link to="/app">home</Link></span></td></tr> <tr><td><span><Link to="/app">home</Link></span></td></tr>
<tr><td><Link to="/app/playlists">playlists</Link></td></tr> <tr><td><Link to="/app/playlists">playlists</Link></td></tr>
<tr><td><Link to="/app/settings">settings</Link></td></tr> <tr><td><Link to="/app/maths">maths</Link></td></tr>
{ this.state.type == 'admin' && <tr><td><Link to="/app/admin">admin</Link></td></tr> } <tr><td><Link to="/app/settings/password">settings</Link></td></tr>
{ this.state.type == 'admin' && <tr><td><Link to="/app/admin/lock">admin</Link></td></tr> }
<tr><td><a href="/auth/logout">logout</a></td></tr> <tr><td><a href="/auth/logout">logout</a></td></tr>
<tr><td><a href="https://sarsoo.xyz">sarsoo.xyz</a></td></tr> <tr><td><a href="https://sarsoo.xyz">sarsoo.xyz</a></td></tr>
</tbody> </tbody>
@ -68,6 +70,7 @@ class PlaylistManager extends Component {
<Switch> <Switch>
<Route path="/app" exact component={Index} /> <Route path="/app" exact component={Index} />
<Route path="/app/playlists" component={Playlists} /> <Route path="/app/playlists" component={Playlists} />
<Route path="/app/maths" component={Maths} />
<Route path="/app/settings" component={Settings} /> <Route path="/app/settings" component={Settings} />
{ this.state.type == 'admin' && <Route path="/app/admin" component={Admin} /> } { this.state.type == 'admin' && <Route path="/app/admin" component={Admin} /> }
<Route path='/app/playlist/:name' component={PlaylistView} /> <Route path='/app/playlist/:name' component={PlaylistView} />

View File

@ -1,6 +1,8 @@
import React, { Component } from "react"; import React, { Component } from "react";
const axios = require('axios'); const axios = require('axios');
import showMessage from "../Toast.js"
class ChangePassword extends Component { class ChangePassword extends Component {
constructor(props){ constructor(props){
@ -8,9 +10,7 @@ class ChangePassword extends Component {
this.state = { this.state = {
current: "", current: "",
new1: "", new1: "",
new2: "", new2: ""
error: false,
errorValue: null
} }
this.handleCurrentChange = this.handleCurrentChange.bind(this); this.handleCurrentChange = this.handleCurrentChange.bind(this);
this.handleNewChange = this.handleNewChange.bind(this); this.handleNewChange = this.handleNewChange.bind(this);
@ -37,37 +37,21 @@ class ChangePassword extends Component {
handleSubmit(event){ handleSubmit(event){
if(this.state.current.length == 0){ if(this.state.current.length == 0){
this.setState({ showMessage("enter current password");
error: true,
errorValue: "enter current password"
});
}else{ }else{
if(this.state.new1.length == 0){ if(this.state.new1.length == 0){
this.setState({ showMessage("enter new password");
error: true,
errorValue: "enter new password"
});
}else{ }else{
if(this.state.new1 != this.state.new2){ if(this.state.new1 != this.state.new2){
this.setState({ showMessage("new password mismatch");
error: true,
errorValue: "new password mismatch"
});
}else{ }else{
axios.post('/api/user/password',{ axios.post('/api/user/password',{
current_password: this.state.current, current_password: this.state.current,
new_password: this.state.new1 new_password: this.state.new1
}).then((response) => { }).then((response) => {
this.setState({ showMessage("password changed");
error: true,
errorValue: "password changed"
});
}).catch((error) => { }).catch((error) => {
this.setState({ showMessage(`error changing password (${error.response.status})`);
error: true,
errorValue: "error changing password"
});
}); });
} }
} }

98
src/js/Settings/LastFM.js Normal file
View File

@ -0,0 +1,98 @@
import React, { Component } from "react";
const axios = require('axios');
import showMessage from "../Toast.js"
class LastFM extends Component {
constructor(props){
super(props);
this.state = {
lastfm_username: null,
isLoading: true
}
this.getUserInfo();
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
getUserInfo(){
axios.get('/api/user')
.then((response) => {
var username = response.data.lastfm_username;
if(username == null){
username = '';
}
this.setState({
lastfm_username: username,
isLoading: false
})
})
.catch((error) => {
showMessage(`error getting user info (${error.response.status})`);
});
}
handleChange(event){
this.setState({
'lastfm_username': event.target.value
});
}
handleSubmit(event){
var username = this.state.lastfm_username;
if(username == ''){
username = null
}
axios.post('/api/user',{
lastfm_username: username
}).then((response) => {
showMessage('saved');
}).catch((error) => {
showMessage(`error saving (${error.response.status})`);
});
event.preventDefault();
}
render(){
const table =
<form onSubmit={this.handleSubmit}>
<table className="app-table max-width">
<thead>
<tr>
<th colSpan="2"><h1 className="ui-text center-text text-no-select">last.fm username</h1></th>
</tr>
</thead>
<tbody>
<tr>
<td className="ui-text center-text text-no-select">username:</td>
<td><input
type="text"
name="current"
value={this.state.lastfm_username}
onChange={this.handleChange}
className="full-width" /></td>
</tr>
<tr>
<td colSpan="2"><input type="submit" style={{width: "100%"}} className="button" value="save" /></td>
</tr>
</tbody>
</table>
</form>;
const loadingMessage = <p className="center-text text-no-select">loading...</p>;
return this.state.isLoading ? loadingMessage : table;
}
}
export default LastFM;

View File

@ -3,6 +3,7 @@ import { BrowserRouter as Router, Route, Link, Switch, Redirect} from "react-rou
import ChangePassword from "./ChangePassword.js"; import ChangePassword from "./ChangePassword.js";
import SpotifyLink from "./SpotifyLink.js"; import SpotifyLink from "./SpotifyLink.js";
import LastFM from "./LastFM.js";
class Settings extends Component { class Settings extends Component {
@ -12,10 +13,12 @@ class Settings extends Component {
<ul className="navbar" style={{width: "100%"}}> <ul className="navbar" style={{width: "100%"}}>
<li><Link to={`${this.props.match.url}/password`}>password</Link></li> <li><Link to={`${this.props.match.url}/password`}>password</Link></li>
<li><Link to={`${this.props.match.url}/spotify`}>spotify</Link></li> <li><Link to={`${this.props.match.url}/spotify`}>spotify</Link></li>
<li><Link to={`${this.props.match.url}/lastfm`}>last.fm</Link></li>
</ul> </ul>
<Route path={`${this.props.match.url}/password`} component={ChangePassword} /> <Route path={`${this.props.match.url}/password`} component={ChangePassword} />
<Route path={`${this.props.match.url}/spotify`} component={SpotifyLink} /> <Route path={`${this.props.match.url}/spotify`} component={SpotifyLink} />
<Route path={`${this.props.match.url}/lastfm`} component={LastFM} />
</div> </div>
); );