mirror of
https://github.com/idanoo/GoScrobble
synced 2025-07-01 13:42:20 +00:00
0.0.16
- Add registration_enabled to /api/v1/serverinfo - Add config table caching on save - Fix redis TTL not being parsed correctly - Move registration enabled to backend toggle - Fixed navbar when loading /u/profile URL - Token now shows on user page + can reset - Added basic popup validation to disconnect/reset buttons
This commit is contained in:
parent
f8bd321fbc
commit
9cbb94fc56
21 changed files with 246 additions and 59 deletions
|
@ -12,7 +12,8 @@ type Config struct {
|
|||
}
|
||||
|
||||
type ServerInfo struct {
|
||||
Version string `json:"version"`
|
||||
Version string `json:"version"`
|
||||
RegistrationEnabled string `json:"registration_enabled"`
|
||||
}
|
||||
|
||||
func getAllConfigs() (Config, error) {
|
||||
|
|
|
@ -2,7 +2,6 @@ package goscrobble
|
|||
|
||||
import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
|
@ -21,10 +20,9 @@ type MultiScrobblerRequest struct {
|
|||
// ParseMultiScrobblerInput - Transform API data
|
||||
func ParseMultiScrobblerInput(userUUID string, data MultiScrobblerRequest, ip net.IP, tx *sql.Tx) error {
|
||||
// Cache key
|
||||
json, _ := json.Marshal(data)
|
||||
redisKey := getMd5(string(json) + userUUID)
|
||||
json := fmt.Sprintf("%s:%s:%s:%s", data.PlayedAt, data.Track, data.Album, userUUID)
|
||||
redisKey := getMd5(json)
|
||||
if getRedisKeyExists(redisKey) {
|
||||
fmt.Printf("Prevented duplicate entry!")
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -63,8 +61,7 @@ func ParseMultiScrobblerInput(userUUID string, data MultiScrobblerRequest, ip ne
|
|||
return errors.New("Failed to map track")
|
||||
}
|
||||
|
||||
// Add cache key for the duration of the song *2 since we're caching the start time too
|
||||
ttl := time.Duration(data.Duration*2) * time.Second
|
||||
ttl := time.Duration(30) * time.Minute
|
||||
setRedisValTtl(redisKey, "1", ttl)
|
||||
|
||||
return nil
|
||||
|
|
|
@ -58,7 +58,7 @@ func setRedisVal(key string, val string) error {
|
|||
|
||||
// setRedisTtl - Allows custom TTL
|
||||
func setRedisValTtl(key string, val string, ttl time.Duration) error {
|
||||
return redisDb.Set(ctx, redisPrefix+key, val, 0).Err()
|
||||
return redisDb.Set(ctx, redisPrefix+key, val, ttl).Err()
|
||||
}
|
||||
|
||||
// getRedisVal - Returns value if exists
|
||||
|
|
|
@ -54,16 +54,7 @@ func fetchScrobblesForUser(userUuid string, limit int, page int) (ScrobbleRespon
|
|||
|
||||
// Yeah this isn't great. But for now.. it works! Cache later
|
||||
total, err := getDbCount(
|
||||
"SELECT COUNT(*) FROM `scrobbles` "+
|
||||
"JOIN tracks ON scrobbles.track = tracks.uuid "+
|
||||
"JOIN track_artist ON track_artist.track = tracks.uuid "+
|
||||
"JOIN track_album ON track_album.track = tracks.uuid "+
|
||||
"JOIN artists ON track_artist.artist = artists.uuid "+
|
||||
"JOIN albums ON track_album.album = albums.uuid "+
|
||||
"JOIN users ON scrobbles.user = users.uuid "+
|
||||
"WHERE user = UUID_TO_BIN(?, true) "+
|
||||
"GROUP BY scrobbles.uuid",
|
||||
userUuid)
|
||||
"SELECT COUNT(*) FROM `scrobbles` WHERE `user` = UUID_TO_BIN(?, true) ", userUuid)
|
||||
|
||||
if err != nil {
|
||||
log.Printf("Failed to fetch scrobble count: %+v", err)
|
||||
|
@ -71,7 +62,7 @@ func fetchScrobblesForUser(userUuid string, limit int, page int) (ScrobbleRespon
|
|||
}
|
||||
|
||||
rows, err := db.Query(
|
||||
"SELECT BIN_TO_UUID(`scrobbles`.`uuid`, true), `scrobbles`.`created_at`, `artists`.`name`, `albums`.`name`,`tracks`.`name`, `scrobbles`.`source` FROM `scrobbles` "+
|
||||
"SELECT BIN_TO_UUID(`scrobbles`.`uuid`, true), `scrobbles`.`created_at`, GROUP_CONCAT(`artists`.`name` separator ','), `albums`.`name`, `tracks`.`name`, `scrobbles`.`source` FROM `scrobbles` "+
|
||||
"JOIN tracks ON scrobbles.track = tracks.uuid "+
|
||||
"JOIN track_artist ON track_artist.track = tracks.uuid "+
|
||||
"JOIN track_album ON track_album.track = tracks.uuid "+
|
||||
|
@ -79,8 +70,10 @@ func fetchScrobblesForUser(userUuid string, limit int, page int) (ScrobbleRespon
|
|||
"JOIN albums ON track_album.album = albums.uuid "+
|
||||
"JOIN users ON scrobbles.user = users.uuid "+
|
||||
"WHERE user = UUID_TO_BIN(?, true) "+
|
||||
"GROUP BY scrobbles.uuid, albums.uuid "+
|
||||
"ORDER BY scrobbles.created_at DESC LIMIT ?",
|
||||
userUuid, limit)
|
||||
|
||||
if err != nil {
|
||||
log.Printf("Failed to fetch scrobbles: %+v", err)
|
||||
return scrobbleReq, errors.New("Failed to fetch scrobbles")
|
||||
|
|
|
@ -321,6 +321,9 @@ func patchUser(w http.ResponseWriter, r *http.Request, jwtUser string, reqUser s
|
|||
if isValidTimezone(val) {
|
||||
userFull.updateUser("timezone", val, ip)
|
||||
}
|
||||
} else if k == "token" {
|
||||
token := generateToken(32)
|
||||
userFull.updateUser("token", token, ip)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -363,11 +366,13 @@ func postConfig(w http.ResponseWriter, r *http.Request, jwtUser string) {
|
|||
}
|
||||
|
||||
for k, v := range bodyJson {
|
||||
err = updateConfigValue(k, fmt.Sprintf("%s", v))
|
||||
val := fmt.Sprintf("%s", v)
|
||||
err = updateConfigValue(k, val)
|
||||
if err != nil {
|
||||
throwOkError(w, err.Error())
|
||||
return
|
||||
}
|
||||
setRedisVal(k, val)
|
||||
}
|
||||
|
||||
throwOkMessage(w, "Config updated successfully")
|
||||
|
@ -446,8 +451,19 @@ func deleteSpotifyLink(w http.ResponseWriter, r *http.Request, u string, v strin
|
|||
}
|
||||
|
||||
func fetchServerInfo(w http.ResponseWriter, r *http.Request) {
|
||||
cachedRegistrationEnabled := getRedisVal("REGISTRATION_ENABLED")
|
||||
if cachedRegistrationEnabled == "" {
|
||||
registrationEnabled, err := getConfigValue("REGISTRATION_ENABLED")
|
||||
if err != nil {
|
||||
throwOkError(w, "Error fetching serverinfo")
|
||||
}
|
||||
setRedisVal("REGISTRATION_ENABLED", registrationEnabled)
|
||||
cachedRegistrationEnabled = registrationEnabled
|
||||
}
|
||||
|
||||
info := ServerInfo{
|
||||
Version: "0.0.15",
|
||||
Version: "0.0.16",
|
||||
RegistrationEnabled: cachedRegistrationEnabled,
|
||||
}
|
||||
|
||||
js, _ := json.Marshal(&info)
|
||||
|
|
|
@ -29,6 +29,7 @@ type User struct {
|
|||
Active bool `json:"active"`
|
||||
Admin bool `json:"admin"`
|
||||
Timezone string `json:"timezone"`
|
||||
Token string `json:"token"`
|
||||
}
|
||||
|
||||
type UserResponse struct {
|
||||
|
@ -42,6 +43,7 @@ type UserResponse struct {
|
|||
Verified bool `json:"verified"`
|
||||
SpotifyUsername string `json:"spotify_username"`
|
||||
Timezone string `json:"timezone"`
|
||||
Token string `json:"token"`
|
||||
}
|
||||
|
||||
// RegisterRequest - Incoming JSON
|
||||
|
@ -211,8 +213,8 @@ func userAlreadyExists(req *RegisterRequest) bool {
|
|||
|
||||
func getUser(uuid string) (User, error) {
|
||||
var user User
|
||||
err := db.QueryRow("SELECT BIN_TO_UUID(`uuid`, true), `created_at`, `created_ip`, `modified_at`, `modified_ip`, `username`, `email`, `password`, `verified`, `admin`, `timezone` FROM `users` WHERE `uuid` = UUID_TO_BIN(?, true) AND `active` = 1",
|
||||
uuid).Scan(&user.UUID, &user.CreatedAt, &user.CreatedIp, &user.ModifiedAt, &user.ModifiedIP, &user.Username, &user.Email, &user.Password, &user.Verified, &user.Admin, &user.Timezone)
|
||||
err := db.QueryRow("SELECT BIN_TO_UUID(`uuid`, true), `created_at`, `created_ip`, `modified_at`, `modified_ip`, `username`, `email`, `password`, `verified`, `admin`, `timezone`, `token` FROM `users` WHERE `uuid` = UUID_TO_BIN(?, true) AND `active` = 1",
|
||||
uuid).Scan(&user.UUID, &user.CreatedAt, &user.CreatedIp, &user.ModifiedAt, &user.ModifiedIP, &user.Username, &user.Email, &user.Password, &user.Verified, &user.Admin, &user.Timezone, &user.Token)
|
||||
|
||||
if err == sql.ErrNoRows {
|
||||
return user, errors.New("Invalid JWT Token")
|
||||
|
@ -223,8 +225,8 @@ func getUser(uuid string) (User, error) {
|
|||
|
||||
func getUserByUsername(username string) (User, error) {
|
||||
var user User
|
||||
err := db.QueryRow("SELECT BIN_TO_UUID(`uuid`, true), `created_at`, `created_ip`, `modified_at`, `modified_ip`, `username`, `email`, `password`, `verified`, `admin`, `timezone` FROM `users` WHERE `username` = ? AND `active` = 1",
|
||||
username).Scan(&user.UUID, &user.CreatedAt, &user.CreatedIp, &user.ModifiedAt, &user.ModifiedIP, &user.Username, &user.Email, &user.Password, &user.Verified, &user.Admin, &user.Timezone)
|
||||
err := db.QueryRow("SELECT BIN_TO_UUID(`uuid`, true), `created_at`, `created_ip`, `modified_at`, `modified_ip`, `username`, `email`, `password`, `verified`, `admin`, `timezone`, `token` FROM `users` WHERE `username` = ? AND `active` = 1",
|
||||
username).Scan(&user.UUID, &user.CreatedAt, &user.CreatedIp, &user.ModifiedAt, &user.ModifiedIP, &user.Username, &user.Email, &user.Password, &user.Verified, &user.Admin, &user.Timezone, &user.Token)
|
||||
|
||||
if err == sql.ErrNoRows {
|
||||
return user, errors.New("Invalid Username")
|
||||
|
@ -235,8 +237,8 @@ func getUserByUsername(username string) (User, error) {
|
|||
|
||||
func getUserByEmail(email string) (User, error) {
|
||||
var user User
|
||||
err := db.QueryRow("SELECT BIN_TO_UUID(`uuid`, true), `created_at`, `created_ip`, `modified_at`, `modified_ip`, `username`, `email`, `password`, `verified`, `admin`, `timezone` FROM `users` WHERE `email` = ? AND `active` = 1",
|
||||
email).Scan(&user.UUID, &user.CreatedAt, &user.CreatedIp, &user.ModifiedAt, &user.ModifiedIP, &user.Username, &user.Email, &user.Password, &user.Verified, &user.Admin, &user.Timezone)
|
||||
err := db.QueryRow("SELECT BIN_TO_UUID(`uuid`, true), `created_at`, `created_ip`, `modified_at`, `modified_ip`, `username`, `email`, `password`, `verified`, `admin`, `timezone`, `token` FROM `users` WHERE `email` = ? AND `active` = 1",
|
||||
email).Scan(&user.UUID, &user.CreatedAt, &user.CreatedIp, &user.ModifiedAt, &user.ModifiedIP, &user.Username, &user.Email, &user.Password, &user.Verified, &user.Admin, &user.Timezone, &user.Token)
|
||||
|
||||
if err == sql.ErrNoRows {
|
||||
return user, errors.New("Invalid Email")
|
||||
|
@ -247,9 +249,9 @@ func getUserByEmail(email string) (User, error) {
|
|||
|
||||
func getUserByResetToken(token string) (User, error) {
|
||||
var user User
|
||||
err := db.QueryRow("SELECT BIN_TO_UUID(`users`.`uuid`, true), `created_at`, `created_ip`, `modified_at`, `modified_ip`, `username`, `email`, `password`, `verified`, `admin`, timezone FROM `users` "+
|
||||
err := db.QueryRow("SELECT BIN_TO_UUID(`users`.`uuid`, true), `created_at`, `created_ip`, `modified_at`, `modified_ip`, `username`, `email`, `password`, `verified`, `admin`, `timezone`, `token` FROM `users` "+
|
||||
"JOIN `resettoken` ON `resettoken`.`user` = `users`.`uuid` WHERE `resettoken`.`token` = ? AND `active` = 1",
|
||||
token).Scan(&user.UUID, &user.CreatedAt, &user.CreatedIp, &user.ModifiedAt, &user.ModifiedIP, &user.Username, &user.Email, &user.Password, &user.Verified, &user.Admin, &user.Timezone)
|
||||
token).Scan(&user.UUID, &user.CreatedAt, &user.CreatedIp, &user.ModifiedAt, &user.ModifiedIP, &user.Username, &user.Email, &user.Password, &user.Verified, &user.Admin, &user.Timezone, &user.Token)
|
||||
|
||||
if err == sql.ErrNoRows {
|
||||
return user, errors.New("Invalid Token")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue