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:
parent
77a7583913
commit
849c0a5fa6
@ -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
18
src/js/Maths/Maths.js
Normal 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;
|
@ -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} />
|
||||||
|
@ -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
98
src/js/Settings/LastFM.js
Normal 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;
|
@ -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>
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user