mirror of
https://github.com/hrfee/jfa-go.git
synced 2024-12-22 09:00:10 +00:00
userpage: initial page
login, lang, and theme work. Currently only makes a request to a hello-world type endpoint to verify auth works. Accessible at /my/account.
This commit is contained in:
parent
54fde33a20
commit
726acb9c29
1
Makefile
1
Makefile
@ -104,6 +104,7 @@ typescript:
|
|||||||
$(info compiling typescript)
|
$(info compiling typescript)
|
||||||
mkdir -p $(DATA)/web/js
|
mkdir -p $(DATA)/web/js
|
||||||
$(ESBUILD) --target=es6 --bundle tempts/admin.ts $(SOURCEMAP) --outfile=./$(DATA)/web/js/admin.js --minify
|
$(ESBUILD) --target=es6 --bundle tempts/admin.ts $(SOURCEMAP) --outfile=./$(DATA)/web/js/admin.js --minify
|
||||||
|
$(ESBUILD) --target=es6 --bundle tempts/user.ts $(SOURCEMAP) --outfile=./$(DATA)/web/js/user.js --minify
|
||||||
$(ESBUILD) --target=es6 --bundle tempts/pwr.ts $(SOURCEMAP) --outfile=./$(DATA)/web/js/pwr.js --minify
|
$(ESBUILD) --target=es6 --bundle tempts/pwr.ts $(SOURCEMAP) --outfile=./$(DATA)/web/js/pwr.js --minify
|
||||||
$(ESBUILD) --target=es6 --bundle tempts/form.ts $(SOURCEMAP) --outfile=./$(DATA)/web/js/form.js --minify
|
$(ESBUILD) --target=es6 --bundle tempts/form.ts $(SOURCEMAP) --outfile=./$(DATA)/web/js/form.js --minify
|
||||||
$(ESBUILD) --target=es6 --bundle tempts/setup.ts $(SOURCEMAP) --outfile=./$(DATA)/web/js/setup.js --minify
|
$(ESBUILD) --target=es6 --bundle tempts/setup.ts $(SOURCEMAP) --outfile=./$(DATA)/web/js/setup.js --minify
|
||||||
|
7
api-userpage.go
Normal file
7
api-userpage.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "github.com/gin-gonic/gin"
|
||||||
|
|
||||||
|
func (app *appContext) HelloWorld(gc *gin.Context) {
|
||||||
|
gc.JSON(200, stringResponse{"It worked!", "none"})
|
||||||
|
}
|
10
api.go
10
api.go
@ -214,7 +214,7 @@ func (app *appContext) GetConfig(gc *gin.Context) {
|
|||||||
app.info.Println("Config requested")
|
app.info.Println("Config requested")
|
||||||
resp := app.configBase
|
resp := app.configBase
|
||||||
// Load language options
|
// Load language options
|
||||||
formOptions := app.storage.lang.Form.getOptions()
|
formOptions := app.storage.lang.User.getOptions()
|
||||||
fl := resp.Sections["ui"].Settings["language-form"]
|
fl := resp.Sections["ui"].Settings["language-form"]
|
||||||
fl.Options = formOptions
|
fl.Options = formOptions
|
||||||
fl.Value = app.config.Section("ui").Key("language-form").MustString("en-us")
|
fl.Value = app.config.Section("ui").Key("language-form").MustString("en-us")
|
||||||
@ -452,8 +452,8 @@ func (app *appContext) GetLanguages(gc *gin.Context) {
|
|||||||
page := gc.Param("page")
|
page := gc.Param("page")
|
||||||
resp := langDTO{}
|
resp := langDTO{}
|
||||||
switch page {
|
switch page {
|
||||||
case "form":
|
case "form", "user":
|
||||||
for key, lang := range app.storage.lang.Form {
|
for key, lang := range app.storage.lang.User {
|
||||||
resp[key] = lang.Meta.Name
|
resp[key] = lang.Meta.Name
|
||||||
}
|
}
|
||||||
case "admin":
|
case "admin":
|
||||||
@ -494,8 +494,8 @@ func (app *appContext) ServeLang(gc *gin.Context) {
|
|||||||
if page == "admin" {
|
if page == "admin" {
|
||||||
gc.JSON(200, app.storage.lang.Admin[lang])
|
gc.JSON(200, app.storage.lang.Admin[lang])
|
||||||
return
|
return
|
||||||
} else if page == "form" {
|
} else if page == "form" || page == "user" {
|
||||||
gc.JSON(200, app.storage.lang.Form[lang])
|
gc.JSON(200, app.storage.lang.User[lang])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
respondBool(400, false, gc)
|
respondBool(400, false, gc)
|
||||||
|
@ -169,11 +169,11 @@ func (app *appContext) loadConfig() error {
|
|||||||
|
|
||||||
oldFormLang := app.config.Section("ui").Key("language").MustString("")
|
oldFormLang := app.config.Section("ui").Key("language").MustString("")
|
||||||
if oldFormLang != "" {
|
if oldFormLang != "" {
|
||||||
app.storage.lang.chosenFormLang = oldFormLang
|
app.storage.lang.chosenUserLang = oldFormLang
|
||||||
}
|
}
|
||||||
newFormLang := app.config.Section("ui").Key("language-form").MustString("")
|
newFormLang := app.config.Section("ui").Key("language-form").MustString("")
|
||||||
if newFormLang != "" {
|
if newFormLang != "" {
|
||||||
app.storage.lang.chosenFormLang = newFormLang
|
app.storage.lang.chosenUserLang = newFormLang
|
||||||
}
|
}
|
||||||
app.storage.lang.chosenAdminLang = app.config.Section("ui").Key("language-admin").MustString("en-us")
|
app.storage.lang.chosenAdminLang = app.config.Section("ui").Key("language-admin").MustString("en-us")
|
||||||
app.storage.lang.chosenEmailLang = app.config.Section("email").Key("language").MustString("en-us")
|
app.storage.lang.chosenEmailLang = app.config.Section("email").Key("language").MustString("en-us")
|
||||||
|
@ -373,6 +373,23 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"user_page": {
|
||||||
|
"order": [],
|
||||||
|
"meta": {
|
||||||
|
"name": "User Page",
|
||||||
|
"description": "Settings for the user page, which provides useful info and tools to users directly. NOTE: Jellyfin Login must be enabled to use this feature.",
|
||||||
|
"depends_true": "ui|jellyfin_login"
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"enabled": {
|
||||||
|
"name": "Enabled",
|
||||||
|
"required": false,
|
||||||
|
"requires_restart": false,
|
||||||
|
"type": "bool",
|
||||||
|
"value": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"password_validation": {
|
"password_validation": {
|
||||||
"order": [],
|
"order": [],
|
||||||
"meta": {
|
"meta": {
|
||||||
|
53
html/user.html
Normal file
53
html/user.html
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
<html lang="en" class="light">
|
||||||
|
<head>
|
||||||
|
<link rel="stylesheet" type="text/css" href="{{ .urlBase }}/css/{{ .cssVersion }}bundle.css">
|
||||||
|
<script>
|
||||||
|
window.URLBase = "{{ .urlBase }}";
|
||||||
|
window.notificationsEnabled = {{ .notifications }};
|
||||||
|
window.emailEnabled = {{ .emailEnabled }};
|
||||||
|
window.telegramEnabled = {{ .telegramEnabled }};
|
||||||
|
window.discordEnabled = {{ .discordEnabled }};
|
||||||
|
window.matrixEnabled = {{ .matrixEnabled }};
|
||||||
|
window.ombiEnabled = {{ .ombiEnabled }};
|
||||||
|
window.langFile = JSON.parse({{ .language }});
|
||||||
|
window.linkResetEnabled = {{ .linkResetEnabled }};
|
||||||
|
window.language = "{{ .langName }}";
|
||||||
|
</script>
|
||||||
|
{{ template "header.html" . }}
|
||||||
|
<title>{{ .lang.Strings.pageTitle }}</title>
|
||||||
|
</head>
|
||||||
|
<body class="max-w-full overflow-x-hidden section">
|
||||||
|
<div id="notification-box"></div>
|
||||||
|
<div class="top-4 left-4 absolute">
|
||||||
|
<span class="dropdown" tabindex="0" id="lang-dropdown">
|
||||||
|
<span class="button ~urge dropdown-button">
|
||||||
|
<i class="ri-global-line"></i>
|
||||||
|
<span class="ml-2 chev"></span>
|
||||||
|
</span>
|
||||||
|
<div class="dropdown-display">
|
||||||
|
<div class="card ~neutral @low">
|
||||||
|
<label class="switch pb-4">
|
||||||
|
<input type="radio" name="lang-time" id="lang-12h">
|
||||||
|
<span>{{ .strings.time12h }}</span>
|
||||||
|
</label>
|
||||||
|
<label class="switch pb-4">
|
||||||
|
<input type="radio" name="lang-time" id="lang-24h">
|
||||||
|
<span>{{ .strings.time24h }}</span>
|
||||||
|
</label>
|
||||||
|
<div id="lang-list"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
<span class="button ~warning" alt="{{ .strings.theme }}" id="button-theme"><i class="ri-sun-line"></i></span>
|
||||||
|
<span class="button ~critical @low mb-4 unfocused" id="logout-button">{{ .strings.logout }}</span>
|
||||||
|
</div>
|
||||||
|
{{ template "login-modal.html" . }}
|
||||||
|
<div class="page-container">
|
||||||
|
<div class="card @low dark:~d_neutral mb-4" id="card-user">
|
||||||
|
Not logged in.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script src="{{ .urlBase }}/js/user.js" type="module"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
6
lang.go
6
lang.go
@ -38,9 +38,9 @@ type adminLang struct {
|
|||||||
JSON string
|
JSON string
|
||||||
}
|
}
|
||||||
|
|
||||||
type formLangs map[string]formLang
|
type userLangs map[string]userLang
|
||||||
|
|
||||||
func (ls *formLangs) getOptions() [][2]string {
|
func (ls *userLangs) getOptions() [][2]string {
|
||||||
opts := make([][2]string, len(*ls))
|
opts := make([][2]string, len(*ls))
|
||||||
i := 0
|
i := 0
|
||||||
for key, lang := range *ls {
|
for key, lang := range *ls {
|
||||||
@ -50,7 +50,7 @@ func (ls *formLangs) getOptions() [][2]string {
|
|||||||
return opts
|
return opts
|
||||||
}
|
}
|
||||||
|
|
||||||
type formLang struct {
|
type userLang struct {
|
||||||
Meta langMeta `json:"meta"`
|
Meta langMeta `json:"meta"`
|
||||||
Strings langSection `json:"strings"`
|
Strings langSection `json:"strings"`
|
||||||
Notifications langSection `json:"notifications"`
|
Notifications langSection `json:"notifications"`
|
||||||
|
2
main.go
2
main.go
@ -284,7 +284,7 @@ func start(asDaemon, firstCall bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
app.storage.lang.CommonPath = "common"
|
app.storage.lang.CommonPath = "common"
|
||||||
app.storage.lang.FormPath = "form"
|
app.storage.lang.UserPath = "form"
|
||||||
app.storage.lang.AdminPath = "admin"
|
app.storage.lang.AdminPath = "admin"
|
||||||
app.storage.lang.EmailPath = "email"
|
app.storage.lang.EmailPath = "email"
|
||||||
app.storage.lang.TelegramPath = "telegram"
|
app.storage.lang.TelegramPath = "telegram"
|
||||||
|
18
router.go
18
router.go
@ -101,6 +101,9 @@ func (app *appContext) loadRoutes(router *gin.Engine) {
|
|||||||
if app.URLBase != "" {
|
if app.URLBase != "" {
|
||||||
routePrefixes = append(routePrefixes, "")
|
routePrefixes = append(routePrefixes, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
userPageEnabled := app.config.Section("user_page").Key("enabled").MustBool(true) && app.config.Section("ui").Key("jellyfin_login").MustBool(true)
|
||||||
|
|
||||||
for _, p := range routePrefixes {
|
for _, p := range routePrefixes {
|
||||||
router.GET(p+"/lang/:page", app.GetLanguages)
|
router.GET(p+"/lang/:page", app.GetLanguages)
|
||||||
router.Use(static.Serve(p+"/", app.webFS))
|
router.Use(static.Serve(p+"/", app.webFS))
|
||||||
@ -140,6 +143,11 @@ func (app *appContext) loadRoutes(router *gin.Engine) {
|
|||||||
router.POST(p+"/invite/:invCode/matrix/user", app.MatrixSendPIN)
|
router.POST(p+"/invite/:invCode/matrix/user", app.MatrixSendPIN)
|
||||||
router.POST(p+"/users/matrix", app.MatrixConnect)
|
router.POST(p+"/users/matrix", app.MatrixConnect)
|
||||||
}
|
}
|
||||||
|
if userPageEnabled {
|
||||||
|
router.GET(p+"/my/account", app.MyUserPage)
|
||||||
|
router.GET(p+"/my/token/login", app.getUserTokenLogin)
|
||||||
|
router.GET(p+"/my/token/refresh", app.getUserTokenRefresh)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if *SWAGGER {
|
if *SWAGGER {
|
||||||
app.info.Print(warning("\n\nWARNING: Swagger should not be used on a public instance.\n\n"))
|
app.info.Print(warning("\n\nWARNING: Swagger should not be used on a public instance.\n\n"))
|
||||||
@ -147,7 +155,14 @@ func (app *appContext) loadRoutes(router *gin.Engine) {
|
|||||||
router.GET(p+"/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
|
router.GET(p+"/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
api := router.Group("/", app.webAuth())
|
api := router.Group("/", app.webAuth())
|
||||||
|
|
||||||
|
var user *gin.RouterGroup
|
||||||
|
if userPageEnabled {
|
||||||
|
user = router.Group("/my", app.userAuth())
|
||||||
|
}
|
||||||
|
|
||||||
for _, p := range routePrefixes {
|
for _, p := range routePrefixes {
|
||||||
router.POST(p+"/logout", app.Logout)
|
router.POST(p+"/logout", app.Logout)
|
||||||
api.DELETE(p+"/users", app.DeleteUsers)
|
api.DELETE(p+"/users", app.DeleteUsers)
|
||||||
@ -210,6 +225,9 @@ func (app *appContext) loadRoutes(router *gin.Engine) {
|
|||||||
}
|
}
|
||||||
api.POST(p+"/matrix/login", app.MatrixLogin)
|
api.POST(p+"/matrix/login", app.MatrixLogin)
|
||||||
|
|
||||||
|
if userPageEnabled {
|
||||||
|
user.GET(p+"/hello", app.HelloWorld)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
40
storage.go
40
storage.go
@ -116,9 +116,9 @@ type Lang struct {
|
|||||||
chosenAdminLang string
|
chosenAdminLang string
|
||||||
Admin adminLangs
|
Admin adminLangs
|
||||||
AdminJSON map[string]string
|
AdminJSON map[string]string
|
||||||
FormPath string
|
UserPath string
|
||||||
chosenFormLang string
|
chosenUserLang string
|
||||||
Form formLangs
|
User userLangs
|
||||||
PasswordResetPath string
|
PasswordResetPath string
|
||||||
chosenPWRLang string
|
chosenPWRLang string
|
||||||
PasswordReset pwrLangs
|
PasswordReset pwrLangs
|
||||||
@ -144,7 +144,7 @@ func (st *Storage) loadLang(filesystems ...fs.FS) (err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = st.loadLangForm(filesystems...)
|
err = st.loadLangUser(filesystems...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -395,16 +395,16 @@ func (st *Storage) loadLangAdmin(filesystems ...fs.FS) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (st *Storage) loadLangForm(filesystems ...fs.FS) error {
|
func (st *Storage) loadLangUser(filesystems ...fs.FS) error {
|
||||||
st.lang.Form = map[string]formLang{}
|
st.lang.User = map[string]userLang{}
|
||||||
var english formLang
|
var english userLang
|
||||||
loadedLangs := make([]map[string]bool, len(filesystems))
|
loadedLangs := make([]map[string]bool, len(filesystems))
|
||||||
var load loadLangFunc
|
var load loadLangFunc
|
||||||
load = func(fsIndex int, fname string) error {
|
load = func(fsIndex int, fname string) error {
|
||||||
filesystem := filesystems[fsIndex]
|
filesystem := filesystems[fsIndex]
|
||||||
index := strings.TrimSuffix(fname, filepath.Ext(fname))
|
index := strings.TrimSuffix(fname, filepath.Ext(fname))
|
||||||
lang := formLang{}
|
lang := userLang{}
|
||||||
f, err := fs.ReadFile(filesystem, FSJoin(st.lang.FormPath, fname))
|
f, err := fs.ReadFile(filesystem, FSJoin(st.lang.UserPath, fname))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -418,11 +418,11 @@ func (st *Storage) loadLangForm(filesystems ...fs.FS) error {
|
|||||||
st.lang.Common.patchCommon(&lang.Strings, index)
|
st.lang.Common.patchCommon(&lang.Strings, index)
|
||||||
if fname != "en-us.json" {
|
if fname != "en-us.json" {
|
||||||
if lang.Meta.Fallback != "" {
|
if lang.Meta.Fallback != "" {
|
||||||
fallback, ok := st.lang.Form[lang.Meta.Fallback]
|
fallback, ok := st.lang.User[lang.Meta.Fallback]
|
||||||
err = nil
|
err = nil
|
||||||
if !ok {
|
if !ok {
|
||||||
err = load(fsIndex, lang.Meta.Fallback+".json")
|
err = load(fsIndex, lang.Meta.Fallback+".json")
|
||||||
fallback = st.lang.Form[lang.Meta.Fallback]
|
fallback = st.lang.User[lang.Meta.Fallback]
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
loadedLangs[fsIndex][lang.Meta.Fallback+".json"] = true
|
loadedLangs[fsIndex][lang.Meta.Fallback+".json"] = true
|
||||||
@ -447,7 +447,7 @@ func (st *Storage) loadLangForm(filesystems ...fs.FS) error {
|
|||||||
}
|
}
|
||||||
lang.notificationsJSON = string(notifications)
|
lang.notificationsJSON = string(notifications)
|
||||||
lang.validationStringsJSON = string(validationStrings)
|
lang.validationStringsJSON = string(validationStrings)
|
||||||
st.lang.Form[index] = lang
|
st.lang.User[index] = lang
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
engFound := false
|
engFound := false
|
||||||
@ -463,10 +463,10 @@ func (st *Storage) loadLangForm(filesystems ...fs.FS) error {
|
|||||||
if !engFound {
|
if !engFound {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
english = st.lang.Form["en-us"]
|
english = st.lang.User["en-us"]
|
||||||
formLoaded := false
|
userLoaded := false
|
||||||
for i := range filesystems {
|
for i := range filesystems {
|
||||||
files, err := fs.ReadDir(filesystems[i], st.lang.FormPath)
|
files, err := fs.ReadDir(filesystems[i], st.lang.UserPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -474,13 +474,13 @@ func (st *Storage) loadLangForm(filesystems ...fs.FS) error {
|
|||||||
if !loadedLangs[i][f.Name()] {
|
if !loadedLangs[i][f.Name()] {
|
||||||
err = load(i, f.Name())
|
err = load(i, f.Name())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
formLoaded = true
|
userLoaded = true
|
||||||
loadedLangs[i][f.Name()] = true
|
loadedLangs[i][f.Name()] = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !formLoaded {
|
if !userLoaded {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -540,7 +540,7 @@ func (st *Storage) loadLangPWR(filesystems ...fs.FS) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
english = st.lang.PasswordReset["en-us"]
|
english = st.lang.PasswordReset["en-us"]
|
||||||
formLoaded := false
|
userLoaded := false
|
||||||
for i := range filesystems {
|
for i := range filesystems {
|
||||||
files, err := fs.ReadDir(filesystems[i], st.lang.PasswordResetPath)
|
files, err := fs.ReadDir(filesystems[i], st.lang.PasswordResetPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -550,13 +550,13 @@ func (st *Storage) loadLangPWR(filesystems ...fs.FS) error {
|
|||||||
if !loadedLangs[i][f.Name()] {
|
if !loadedLangs[i][f.Name()] {
|
||||||
err = load(i, f.Name())
|
err = load(i, f.Name())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
formLoaded = true
|
userLoaded = true
|
||||||
loadedLangs[i][f.Name()] = true
|
loadedLangs[i][f.Name()] = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !formLoaded {
|
if !userLoaded {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -160,6 +160,7 @@ window.onpopstate = (event: PopStateEvent) => {
|
|||||||
|
|
||||||
const login = new Login(window.modals.login as Modal, "/");
|
const login = new Login(window.modals.login as Modal, "/");
|
||||||
login.onLogin = () => {
|
login.onLogin = () => {
|
||||||
|
console.log("Logged in.");
|
||||||
window.updater = new Updater();
|
window.updater = new Updater();
|
||||||
setInterval(() => { window.invites.reload(); accounts.reload(); }, 30*1000);
|
setInterval(() => { window.invites.reload(); accounts.reload(); }, 30*1000);
|
||||||
const currentTab = window.tabs.current;
|
const currentTab = window.tabs.current;
|
||||||
|
37
ts/user.ts
Normal file
37
ts/user.ts
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import { ThemeManager } from "./modules/theme.js";
|
||||||
|
import { lang, LangFile, loadLangSelector } from "./modules/lang.js";
|
||||||
|
import { Modal } from "./modules/modal.js";
|
||||||
|
import { _get, _post, notificationBox, whichAnimationEvent } from "./modules/common.js";
|
||||||
|
import { Login } from "./modules/login.js";
|
||||||
|
|
||||||
|
const theme = new ThemeManager(document.getElementById("button-theme"));
|
||||||
|
|
||||||
|
window.lang = new lang(window.langFile as LangFile);
|
||||||
|
|
||||||
|
loadLangSelector("user");
|
||||||
|
|
||||||
|
window.animationEvent = whichAnimationEvent();
|
||||||
|
|
||||||
|
window.token = "";
|
||||||
|
|
||||||
|
window.modals = {} as Modals;
|
||||||
|
|
||||||
|
(() => {
|
||||||
|
window.modals.login = new Modal(document.getElementById("modal-login"), true);
|
||||||
|
})();
|
||||||
|
|
||||||
|
window.notifications = new notificationBox(document.getElementById('notification-box') as HTMLDivElement, 5);
|
||||||
|
|
||||||
|
const login = new Login(window.modals.login as Modal, "/my/");
|
||||||
|
login.onLogin = () => {
|
||||||
|
console.log("Logged in.");
|
||||||
|
document.getElementById("card-user").textContent = "Logged In!";
|
||||||
|
_get("/my/hello", null, (req: XMLHttpRequest) => {
|
||||||
|
if (req.readyState == 4) {
|
||||||
|
const card = document.getElementById("card-user");
|
||||||
|
card.textContent = card.textContent + " got response " + req.response["response"];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
login.login("", "");
|
84
views.go
84
views.go
@ -44,15 +44,23 @@ func gcHTML(gc *gin.Context, code int, file string, templ gin.H) {
|
|||||||
gc.HTML(code, file, templ)
|
gc.HTML(code, file, templ)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *appContext) pushResources(gc *gin.Context, admin bool) {
|
func (app *appContext) pushResources(gc *gin.Context, page Page) {
|
||||||
|
var toPush []string
|
||||||
|
switch page {
|
||||||
|
case AdminPage:
|
||||||
|
toPush = []string{"/js/admin.js", "/js/theme.js", "/js/lang.js", "/js/modal.js", "/js/tabs.js", "/js/invites.js", "/js/accounts.js", "/js/settings.js", "/js/profiles.js", "/js/common.js"}
|
||||||
|
break
|
||||||
|
case UserPage:
|
||||||
|
toPush = []string{"/js/user.js", "/js/theme.js", "/js/lang.js", "/js/modal.js", "/js/common.js"}
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
toPush = []string{}
|
||||||
|
}
|
||||||
if pusher := gc.Writer.Pusher(); pusher != nil {
|
if pusher := gc.Writer.Pusher(); pusher != nil {
|
||||||
app.debug.Println("Using HTTP2 Server push")
|
app.debug.Println("Using HTTP2 Server push")
|
||||||
if admin {
|
for _, f := range toPush {
|
||||||
toPush := []string{"/js/admin.js", "/js/theme.js", "/js/lang.js", "/js/modal.js", "/js/tabs.js", "/js/invites.js", "/js/accounts.js", "/js/settings.js", "/js/profiles.js", "/js/common.js"}
|
if err := pusher.Push(app.URLBase+f, nil); err != nil {
|
||||||
for _, f := range toPush {
|
app.debug.Printf("Failed HTTP2 ServerPush of \"%s\": %+v", f, err)
|
||||||
if err := pusher.Push(app.URLBase+f, nil); err != nil {
|
|
||||||
app.debug.Printf("Failed HTTP2 ServerPush of \"%s\": %+v", f, err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -65,6 +73,8 @@ const (
|
|||||||
AdminPage Page = iota + 1
|
AdminPage Page = iota + 1
|
||||||
FormPage
|
FormPage
|
||||||
PWRPage
|
PWRPage
|
||||||
|
UserPage
|
||||||
|
OtherPage
|
||||||
)
|
)
|
||||||
|
|
||||||
func (app *appContext) getLang(gc *gin.Context, page Page, chosen string) string {
|
func (app *appContext) getLang(gc *gin.Context, page Page, chosen string) string {
|
||||||
@ -77,8 +87,8 @@ func (app *appContext) getLang(gc *gin.Context, page Page, chosen string) string
|
|||||||
gc.SetCookie("lang", lang, (365 * 3600), "/", gc.Request.URL.Hostname(), true, true)
|
gc.SetCookie("lang", lang, (365 * 3600), "/", gc.Request.URL.Hostname(), true, true)
|
||||||
return lang
|
return lang
|
||||||
}
|
}
|
||||||
case FormPage:
|
case FormPage, UserPage:
|
||||||
if _, ok := app.storage.lang.Form[lang]; ok {
|
if _, ok := app.storage.lang.User[lang]; ok {
|
||||||
gc.SetCookie("lang", lang, (365 * 3600), "/", gc.Request.URL.Hostname(), true, true)
|
gc.SetCookie("lang", lang, (365 * 3600), "/", gc.Request.URL.Hostname(), true, true)
|
||||||
return lang
|
return lang
|
||||||
}
|
}
|
||||||
@ -95,8 +105,8 @@ func (app *appContext) getLang(gc *gin.Context, page Page, chosen string) string
|
|||||||
if _, ok := app.storage.lang.Admin[cookie]; ok {
|
if _, ok := app.storage.lang.Admin[cookie]; ok {
|
||||||
return cookie
|
return cookie
|
||||||
}
|
}
|
||||||
case FormPage:
|
case FormPage, UserPage:
|
||||||
if _, ok := app.storage.lang.Form[cookie]; ok {
|
if _, ok := app.storage.lang.User[cookie]; ok {
|
||||||
return cookie
|
return cookie
|
||||||
}
|
}
|
||||||
case PWRPage:
|
case PWRPage:
|
||||||
@ -109,7 +119,7 @@ func (app *appContext) getLang(gc *gin.Context, page Page, chosen string) string
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (app *appContext) AdminPage(gc *gin.Context) {
|
func (app *appContext) AdminPage(gc *gin.Context) {
|
||||||
app.pushResources(gc, true)
|
app.pushResources(gc, AdminPage)
|
||||||
lang := app.getLang(gc, AdminPage, app.storage.lang.chosenAdminLang)
|
lang := app.getLang(gc, AdminPage, app.storage.lang.chosenAdminLang)
|
||||||
emailEnabled, _ := app.config.Section("invite_emails").Key("enabled").Bool()
|
emailEnabled, _ := app.config.Section("invite_emails").Key("enabled").Bool()
|
||||||
notificationsEnabled, _ := app.config.Section("notifications").Key("enabled").Bool()
|
notificationsEnabled, _ := app.config.Section("notifications").Key("enabled").Bool()
|
||||||
@ -149,6 +159,32 @@ func (app *appContext) AdminPage(gc *gin.Context) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (app *appContext) MyUserPage(gc *gin.Context) {
|
||||||
|
app.pushResources(gc, UserPage)
|
||||||
|
lang := app.getLang(gc, UserPage, app.storage.lang.chosenUserLang)
|
||||||
|
emailEnabled, _ := app.config.Section("invite_emails").Key("enabled").Bool()
|
||||||
|
notificationsEnabled, _ := app.config.Section("notifications").Key("enabled").Bool()
|
||||||
|
ombiEnabled := app.config.Section("ombi").Key("enabled").MustBool(false)
|
||||||
|
gcHTML(gc, http.StatusOK, "user.html", gin.H{
|
||||||
|
"urlBase": app.getURLBase(gc),
|
||||||
|
"cssClass": app.cssClass,
|
||||||
|
"cssVersion": cssVersion,
|
||||||
|
"contactMessage": app.config.Section("ui").Key("contact_message").String(),
|
||||||
|
"emailEnabled": emailEnabled,
|
||||||
|
"telegramEnabled": telegramEnabled,
|
||||||
|
"discordEnabled": discordEnabled,
|
||||||
|
"matrixEnabled": matrixEnabled,
|
||||||
|
"ombiEnabled": ombiEnabled,
|
||||||
|
"linkResetEnabled": app.config.Section("password_resets").Key("link_reset").MustBool(false),
|
||||||
|
"notifications": notificationsEnabled,
|
||||||
|
"username": !app.config.Section("email").Key("no_username").MustBool(false),
|
||||||
|
"strings": app.storage.lang.Admin[lang].Strings,
|
||||||
|
"quantityStrings": app.storage.lang.Admin[lang].QuantityStrings,
|
||||||
|
"language": app.storage.lang.Admin[lang].JSON,
|
||||||
|
"langName": lang,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (app *appContext) ResetPassword(gc *gin.Context) {
|
func (app *appContext) ResetPassword(gc *gin.Context) {
|
||||||
isBot := strings.Contains(gc.Request.Header.Get("User-Agent"), "Bot")
|
isBot := strings.Contains(gc.Request.Header.Get("User-Agent"), "Bot")
|
||||||
setPassword := app.config.Section("password_resets").Key("set_password").MustBool(false)
|
setPassword := app.config.Section("password_resets").Key("set_password").MustBool(false)
|
||||||
@ -157,7 +193,7 @@ func (app *appContext) ResetPassword(gc *gin.Context) {
|
|||||||
app.NoRouteHandler(gc)
|
app.NoRouteHandler(gc)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
app.pushResources(gc, false)
|
app.pushResources(gc, PWRPage)
|
||||||
lang := app.getLang(gc, PWRPage, app.storage.lang.chosenPWRLang)
|
lang := app.getLang(gc, PWRPage, app.storage.lang.chosenPWRLang)
|
||||||
data := gin.H{
|
data := gin.H{
|
||||||
"urlBase": app.getURLBase(gc),
|
"urlBase": app.getURLBase(gc),
|
||||||
@ -177,8 +213,8 @@ func (app *appContext) ResetPassword(gc *gin.Context) {
|
|||||||
data["validate"] = app.config.Section("password_validation").Key("enabled").MustBool(false)
|
data["validate"] = app.config.Section("password_validation").Key("enabled").MustBool(false)
|
||||||
data["requirements"] = app.validator.getCriteria()
|
data["requirements"] = app.validator.getCriteria()
|
||||||
data["strings"] = app.storage.lang.PasswordReset[lang].Strings
|
data["strings"] = app.storage.lang.PasswordReset[lang].Strings
|
||||||
data["validationStrings"] = app.storage.lang.Form[lang].validationStringsJSON
|
data["validationStrings"] = app.storage.lang.User[lang].validationStringsJSON
|
||||||
data["notifications"] = app.storage.lang.Form[lang].notificationsJSON
|
data["notifications"] = app.storage.lang.User[lang].notificationsJSON
|
||||||
data["langName"] = lang
|
data["langName"] = lang
|
||||||
data["passwordReset"] = true
|
data["passwordReset"] = true
|
||||||
data["telegramEnabled"] = false
|
data["telegramEnabled"] = false
|
||||||
@ -422,9 +458,9 @@ func (app *appContext) VerifyCaptcha(gc *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (app *appContext) InviteProxy(gc *gin.Context) {
|
func (app *appContext) InviteProxy(gc *gin.Context) {
|
||||||
app.pushResources(gc, false)
|
app.pushResources(gc, FormPage)
|
||||||
code := gc.Param("invCode")
|
code := gc.Param("invCode")
|
||||||
lang := app.getLang(gc, FormPage, app.storage.lang.chosenFormLang)
|
lang := app.getLang(gc, FormPage, app.storage.lang.chosenUserLang)
|
||||||
/* Don't actually check if the invite is valid, just if it exists, just so the page loads quicker. Invite is actually checked on submit anyway. */
|
/* Don't actually check if the invite is valid, just if it exists, just so the page loads quicker. Invite is actually checked on submit anyway. */
|
||||||
// if app.checkInvite(code, false, "") {
|
// if app.checkInvite(code, false, "") {
|
||||||
inv, ok := app.storage.invites[code]
|
inv, ok := app.storage.invites[code]
|
||||||
@ -493,7 +529,7 @@ func (app *appContext) InviteProxy(gc *gin.Context) {
|
|||||||
} else {
|
} else {
|
||||||
gcHTML(gc, http.StatusOK, "create-success.html", gin.H{
|
gcHTML(gc, http.StatusOK, "create-success.html", gin.H{
|
||||||
"cssClass": app.cssClass,
|
"cssClass": app.cssClass,
|
||||||
"strings": app.storage.lang.Form[lang].Strings,
|
"strings": app.storage.lang.User[lang].Strings,
|
||||||
"successMessage": app.config.Section("ui").Key("success_message").String(),
|
"successMessage": app.config.Section("ui").Key("success_message").String(),
|
||||||
"contactMessage": app.config.Section("ui").Key("contact_message").String(),
|
"contactMessage": app.config.Section("ui").Key("contact_message").String(),
|
||||||
"jfLink": jfLink,
|
"jfLink": jfLink,
|
||||||
@ -528,9 +564,9 @@ func (app *appContext) InviteProxy(gc *gin.Context) {
|
|||||||
"requirements": app.validator.getCriteria(),
|
"requirements": app.validator.getCriteria(),
|
||||||
"email": email,
|
"email": email,
|
||||||
"username": !app.config.Section("email").Key("no_username").MustBool(false),
|
"username": !app.config.Section("email").Key("no_username").MustBool(false),
|
||||||
"strings": app.storage.lang.Form[lang].Strings,
|
"strings": app.storage.lang.User[lang].Strings,
|
||||||
"validationStrings": app.storage.lang.Form[lang].validationStringsJSON,
|
"validationStrings": app.storage.lang.User[lang].validationStringsJSON,
|
||||||
"notifications": app.storage.lang.Form[lang].notificationsJSON,
|
"notifications": app.storage.lang.User[lang].notificationsJSON,
|
||||||
"code": code,
|
"code": code,
|
||||||
"confirmation": app.config.Section("email_confirmation").Key("enabled").MustBool(false),
|
"confirmation": app.config.Section("email_confirmation").Key("enabled").MustBool(false),
|
||||||
"userExpiry": inv.UserExpiry,
|
"userExpiry": inv.UserExpiry,
|
||||||
@ -538,7 +574,7 @@ func (app *appContext) InviteProxy(gc *gin.Context) {
|
|||||||
"userExpiryDays": inv.UserDays,
|
"userExpiryDays": inv.UserDays,
|
||||||
"userExpiryHours": inv.UserHours,
|
"userExpiryHours": inv.UserHours,
|
||||||
"userExpiryMinutes": inv.UserMinutes,
|
"userExpiryMinutes": inv.UserMinutes,
|
||||||
"userExpiryMessage": app.storage.lang.Form[lang].Strings.get("yourAccountIsValidUntil"),
|
"userExpiryMessage": app.storage.lang.User[lang].Strings.get("yourAccountIsValidUntil"),
|
||||||
"langName": lang,
|
"langName": lang,
|
||||||
"passwordReset": false,
|
"passwordReset": false,
|
||||||
"telegramEnabled": telegram,
|
"telegramEnabled": telegram,
|
||||||
@ -563,7 +599,7 @@ func (app *appContext) InviteProxy(gc *gin.Context) {
|
|||||||
data["discordPIN"] = app.discord.NewAuthToken()
|
data["discordPIN"] = app.discord.NewAuthToken()
|
||||||
data["discordUsername"] = app.discord.username
|
data["discordUsername"] = app.discord.username
|
||||||
data["discordRequired"] = app.config.Section("discord").Key("required").MustBool(false)
|
data["discordRequired"] = app.config.Section("discord").Key("required").MustBool(false)
|
||||||
data["discordSendPINMessage"] = template.HTML(app.storage.lang.Form[lang].Strings.template("sendPINDiscord", tmpl{
|
data["discordSendPINMessage"] = template.HTML(app.storage.lang.User[lang].Strings.template("sendPINDiscord", tmpl{
|
||||||
"command": `<span class="text-black dark:text-white font-mono">/` + app.config.Section("discord").Key("start_command").MustString("start") + `</span>`,
|
"command": `<span class="text-black dark:text-white font-mono">/` + app.config.Section("discord").Key("start_command").MustString("start") + `</span>`,
|
||||||
"server_channel": app.discord.serverChannelName,
|
"server_channel": app.discord.serverChannelName,
|
||||||
}))
|
}))
|
||||||
@ -579,7 +615,7 @@ func (app *appContext) InviteProxy(gc *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (app *appContext) NoRouteHandler(gc *gin.Context) {
|
func (app *appContext) NoRouteHandler(gc *gin.Context) {
|
||||||
app.pushResources(gc, false)
|
app.pushResources(gc, OtherPage)
|
||||||
gcHTML(gc, 404, "404.html", gin.H{
|
gcHTML(gc, 404, "404.html", gin.H{
|
||||||
"cssClass": app.cssClass,
|
"cssClass": app.cssClass,
|
||||||
"cssVersion": cssVersion,
|
"cssVersion": cssVersion,
|
||||||
|
Loading…
Reference in New Issue
Block a user