mirror of
https://github.com/navidrome/navidrome.git
synced 2025-04-15 11:40:36 +03:00
feat: better way to detect initial account creation
This commit is contained in:
parent
730722cfe3
commit
10ead1f5f2
@ -49,6 +49,7 @@ func (app *Router) routes() http.Handler {
|
||||
})
|
||||
|
||||
// Serve UI app assets
|
||||
r.Handle("/", ServeIndex(app.ds))
|
||||
r.Handle("/*", http.StripPrefix(app.path, http.FileServer(assets.AssetFile())))
|
||||
|
||||
return r
|
||||
|
43
server/app/serve_index.go
Normal file
43
server/app/serve_index.go
Normal file
@ -0,0 +1,43 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"html/template"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
"github.com/deluan/navidrome/assets"
|
||||
"github.com/deluan/navidrome/log"
|
||||
"github.com/deluan/navidrome/model"
|
||||
)
|
||||
|
||||
// Injects the `firstTime` config in the `index.html` template
|
||||
func ServeIndex(ds model.DataStore) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
c, err := ds.User(r.Context()).CountAll()
|
||||
firstTime := c == 0 && err == nil
|
||||
|
||||
t := template.New("initial state")
|
||||
fs := assets.AssetFile()
|
||||
indexHtml, err := fs.Open("index.html")
|
||||
if err != nil {
|
||||
log.Error(r, "Could not find `index.html` template", err)
|
||||
}
|
||||
indexStr, err := ioutil.ReadAll(indexHtml)
|
||||
if err != nil {
|
||||
log.Error(r, "Could not read from `index.html`", err)
|
||||
}
|
||||
t, _ = t.Parse(string(indexStr))
|
||||
appConfig := map[string]interface{}{
|
||||
"firstTime": firstTime,
|
||||
}
|
||||
j, _ := json.Marshal(appConfig)
|
||||
data := map[string]interface{}{
|
||||
"AppConfig": string(j),
|
||||
}
|
||||
err = t.Execute(w, data)
|
||||
if err != nil {
|
||||
log.Error(r, "Could not execute `index.html` template", err)
|
||||
}
|
||||
}
|
||||
}
|
@ -25,6 +25,9 @@
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
<title>Navidrome</title>
|
||||
<script>
|
||||
window.__APP_CONFIG__ = "{{.AppConfig}}"
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useState } from 'react'
|
||||
import React from 'react'
|
||||
import { Admin, resolveBrowserLocale, Resource } from 'react-admin'
|
||||
import dataProvider from './dataProvider'
|
||||
import authProvider from './authProvider'
|
||||
@ -19,48 +19,35 @@ const i18nProvider = polyglotI18nProvider(
|
||||
resolveBrowserLocale()
|
||||
)
|
||||
|
||||
const App = () => (
|
||||
<Admin
|
||||
theme={theme}
|
||||
customReducers={{ queue: playQueueReducer }}
|
||||
dataProvider={dataProvider}
|
||||
authProvider={authProvider}
|
||||
i18nProvider={i18nProvider}
|
||||
layout={Layout}
|
||||
loginPage={Login}
|
||||
>
|
||||
{(permissions) => [
|
||||
<Resource name="artist" {...artist} options={{ subMenu: 'library' }} />,
|
||||
<Resource name="album" {...album} options={{ subMenu: 'library' }} />,
|
||||
<Resource name="song" {...song} options={{ subMenu: 'library' }} />,
|
||||
permissions === 'admin' ? <Resource name="user" {...user} /> : null,
|
||||
<Player />
|
||||
]}
|
||||
</Admin>
|
||||
)
|
||||
const App = () => {
|
||||
try {
|
||||
const appConfig = JSON.parse(window.__APP_CONFIG__)
|
||||
|
||||
// TODO: This is a complicated way to force a first check for initial setup. A better way would be to send this info
|
||||
// set in the `window` object in the index.html
|
||||
const AppWrapper = () => {
|
||||
const [checked, setChecked] = useState(false)
|
||||
// This flags to the login process that it should create the first account instead
|
||||
if (appConfig.firstTime) {
|
||||
localStorage.setItem('initialAccountCreation', 'true')
|
||||
}
|
||||
} catch (e) {}
|
||||
|
||||
if (!checked) {
|
||||
dataProvider
|
||||
.getOne('keepalive', { id: new Date().getTime() })
|
||||
.then(() => setChecked(true))
|
||||
.catch((err) => {
|
||||
authProvider
|
||||
.checkError(err)
|
||||
.then(() => {
|
||||
setChecked(true)
|
||||
})
|
||||
.catch(() => {
|
||||
setChecked(true)
|
||||
})
|
||||
})
|
||||
return null
|
||||
}
|
||||
return <App />
|
||||
return (
|
||||
<Admin
|
||||
theme={theme}
|
||||
customReducers={{ queue: playQueueReducer }}
|
||||
dataProvider={dataProvider}
|
||||
authProvider={authProvider}
|
||||
i18nProvider={i18nProvider}
|
||||
layout={Layout}
|
||||
loginPage={Login}
|
||||
>
|
||||
{(permissions) => [
|
||||
<Resource name="artist" {...artist} options={{ subMenu: 'library' }} />,
|
||||
<Resource name="album" {...album} options={{ subMenu: 'library' }} />,
|
||||
<Resource name="song" {...song} options={{ subMenu: 'library' }} />,
|
||||
permissions === 'admin' ? <Resource name="user" {...user} /> : null,
|
||||
<Player />
|
||||
]}
|
||||
</Admin>
|
||||
)
|
||||
}
|
||||
|
||||
export default AppWrapper
|
||||
export default App
|
||||
|
@ -56,11 +56,7 @@ const authProvider = {
|
||||
checkAuth: () =>
|
||||
localStorage.getItem('token') ? Promise.resolve() : Promise.reject(),
|
||||
|
||||
checkError: (error) => {
|
||||
const { status, message } = error
|
||||
if (message === 'no users created') {
|
||||
localStorage.setItem('initialAccountCreation', 'true')
|
||||
}
|
||||
checkError: ({ status }) => {
|
||||
if (status === 401 || status === 403) {
|
||||
removeItems()
|
||||
return Promise.reject()
|
||||
|
Loading…
x
Reference in New Issue
Block a user