Admin UI initial #47
6 changed files with 535 additions and 505 deletions
996
client/admin/package-lock.json
generated
996
client/admin/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -39,5 +39,11 @@
|
||||||
"prettier": "3.3.3",
|
"prettier": "3.3.3",
|
||||||
"tailwindcss": "^3.4.14",
|
"tailwindcss": "^3.4.14",
|
||||||
"typescript": "~5.5.2"
|
"typescript": "~5.5.2"
|
||||||
|
},
|
||||||
|
"resolutions": {
|
||||||
|
"rollup": "npm:@rollup/wasm-node"
|
||||||
|
},
|
||||||
|
"overrides": {
|
||||||
|
"rollup": "npm:@rollup/wasm-node"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ import { ImportComponent } from './talkgroups/import/import.component';
|
||||||
import { AuthGuard } from './auth.guard';
|
import { AuthGuard } from './auth.guard';
|
||||||
|
|
||||||
export const routes: Routes = [
|
export const routes: Routes = [
|
||||||
{ path: '', redirectTo: 'login', pathMatch: 'full' },
|
{ path: '', redirectTo: 'login' },
|
||||||
{ path: 'home', component: HomeComponent, canActivate: [AuthGuard] },
|
{ path: 'home', component: HomeComponent, canActivate: [AuthGuard] },
|
||||||
{ path: 'login', component: LoginComponent },
|
{ path: 'login', component: LoginComponent },
|
||||||
{ path: 'talkgroups', component: TalkgroupsComponent },
|
{ path: 'talkgroups', component: TalkgroupsComponent },
|
||||||
|
|
|
@ -4,5 +4,6 @@ import (
|
||||||
"embed"
|
"embed"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:embed calls
|
const Prefix = "admin/dist/admin/browser"
|
||||||
var Calls embed.FS
|
//go:embed admin/dist/admin/browser
|
||||||
|
var Client embed.FS
|
||||||
|
|
|
@ -76,7 +76,7 @@ func (a *Auth) PublicRoutes(r chi.Router) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Auth) PrivateRoutes(r chi.Router) {
|
func (a *Auth) PrivateRoutes(r chi.Router) {
|
||||||
r.Get("/refresh", a.routeRefresh)
|
r.Get("/api/refresh", a.routeRefresh)
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:embed login.html
|
//go:embed login.html
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"dynatron.me/x/stillbox/client"
|
"dynatron.me/x/stillbox/client"
|
||||||
|
@ -14,6 +16,7 @@ import (
|
||||||
"github.com/go-chi/chi/v5/middleware"
|
"github.com/go-chi/chi/v5/middleware"
|
||||||
"github.com/go-chi/httprate"
|
"github.com/go-chi/httprate"
|
||||||
"github.com/go-chi/render"
|
"github.com/go-chi/render"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -21,7 +24,7 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Server) setupRoutes() {
|
func (s *Server) setupRoutes() {
|
||||||
clientRoot, err := fs.Sub(client.Calls, "calls")
|
clientRoot, err := fs.Sub(client.Client, client.Prefix)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -59,6 +62,15 @@ func (s *Server) setupRoutes() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Server) notFoundRedirect(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if strings.HasPrefix(strings.TrimLeft(r.URL.Path, "/"), "api/") {
|
||||||
|
http.NotFound(w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
http.Redirect(w, r, "/index.html", http.StatusFound)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Server) rateLimit(r chi.Router) {
|
func (s *Server) rateLimit(r chi.Router) {
|
||||||
if s.conf.RateLimit.Verify() {
|
if s.conf.RateLimit.Verify() {
|
||||||
r.Use(rateLimiter(&s.conf.RateLimit))
|
r.Use(rateLimiter(&s.conf.RateLimit))
|
||||||
|
@ -70,8 +82,23 @@ func rateLimiter(cfg *config.RateLimit) func(http.Handler) http.Handler {
|
||||||
|
|
||||||
func (s *Server) clientRoute(r chi.Router, clientRoot fs.FS) {
|
func (s *Server) clientRoute(r chi.Router, clientRoot fs.FS) {
|
||||||
r.Get("/*", func(w http.ResponseWriter, r *http.Request) {
|
r.Get("/*", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
hfs := http.FS(clientRoot)
|
||||||
|
var pe *fs.PathError
|
||||||
|
|
||||||
|
pc := path.Clean(r.URL.Path)
|
||||||
|
f, err := hfs.Open(pc)
|
||||||
|
if err != nil {
|
||||||
|
if errors.As(err, &pe) {
|
||||||
|
s.notFoundRedirect(w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
f.Close()
|
||||||
|
}
|
||||||
|
|
||||||
rctx := chi.RouteContext(r.Context())
|
rctx := chi.RouteContext(r.Context())
|
||||||
pathPrefix := strings.TrimSuffix(rctx.RoutePattern(), "/*")
|
pathPrefix := strings.TrimSuffix(rctx.RoutePattern(), "/*")
|
||||||
|
log.Debug().Str("rurl", r.URL.Path).Str("prefix", pathPrefix).Msg("clir")
|
||||||
fs := http.StripPrefix(pathPrefix, http.FileServer(http.FS(clientRoot)))
|
fs := http.StripPrefix(pathPrefix, http.FileServer(http.FS(clientRoot)))
|
||||||
fs.ServeHTTP(w, r)
|
fs.ServeHTTP(w, r)
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue