1
0
mirror of https://github.com/hrfee/jfa-go.git synced 2024-10-18 09:00:11 +00:00

Compare commits

..

61 Commits

Author SHA1 Message Date
c3fb00a307
wrong go version container 2021-02-12 15:37:19 +00:00
988829a6db
dont build docker on go1.16 branch 2021-02-12 15:22:21 +00:00
a6a7710a79
use filepath.Join wrapper for different embed and os path styles
If using internal, "/" is used as a separator always, and with external,
filepath.Join is used.
2021-02-12 14:59:35 +00:00
873afb47cd
strip debug symbols in makefile 2021-02-12 14:59:35 +00:00
ea99966057
refactor, move route loading to router.go 2021-02-12 14:59:16 +00:00
aaed272bf2
use embed.fs wrapper on data 2021-02-12 14:35:16 +00:00
e6775cd2d1
use embed.fs wrapper for langFS so lang/ is not needed in paths
[files]lang_files is now the path to the lang directory, not path to a
directory containing it.
2021-02-12 14:35:16 +00:00
98a9e20cc0
Fix docker build, add GOBINARY flag for make
GOBINARY defaults to "go", but if you want to build on a normal system,
you'll likely set it to go1.16rc1 with "make all GOBINARY=go1.16rc1".
2021-02-12 14:35:13 +00:00
ee37588959
drone image 2021-02-12 14:32:57 +00:00
cb12c6f441
update goreleaser 2021-02-12 14:32:57 +00:00
72cf3e2240
add external/internal data options
"make all" will build with internal data, whereas "make debug"/"make
all-external" will make an external "data/" directory.
2021-02-12 14:32:48 +00:00
815bdc35ac
fully self-contained
paths are pretty janky, but it works. Also, [files]/lang_files now must
be the path to a directory CONTAINING a "lang/" directory. I'll work
around this at a later date.
2021-02-12 14:28:09 +00:00
0330540f87
Use fs for language, add lang_files option
The local app translations are loaded, and then if [files]/lang_files
is provided (a directory containing custom translations), any found
inside it are loaded over top. This makes customizing much easier.
2021-02-12 14:28:09 +00:00
fefe2d82a4
rebase 12/02, use go1.16rc1 in make, remove ioutil, start switching to io/fs for file i/o
ioutil's contents are now in io and os.
Eventually jfa-go's files will be embedded in the binary with go1.16's
new embed feature. Using io/fs will provide abstraction for accessing
these files, and allow for both embedded and non-embedded versions.
Also, internal paths to things like email templates, etc. will be
prefixed with "jfa-go:" to indicate to use the app's own Filesystem
instead of reading the file normally. This also allows for custom files
to continue to be used as they are currently.
2021-02-12 14:27:01 +00:00
1af8d1f77d
fix url in account creation success page 2021-02-12 13:38:34 +00:00
4c653fea36
fix url base on invite and broken getLanguages 2021-02-12 12:52:08 +00:00
2ee0ed55f6
forgot key agh 2021-02-12 00:35:20 +00:00
94981f4891
dont use drone manifest plugin 2021-02-11 23:52:05 +00:00
f72def0399
serve on / and URL base for easy proxying 2021-02-11 23:06:51 +00:00
81fb0fc69f
fix triggers aarch64 = arm64 2021-02-11 22:25:00 +00:00
c3af0f4380
remove tag event from unstable build 2021-02-11 21:48:57 +00:00
3a9e4950d4
run docker amd64 builds on drone, attempt multiarch 2021-02-11 21:18:32 +00:00
06dada297b
up command_timeout for slow rpi builds 2021-02-11 18:47:24 +00:00
2b55a1873c
fix css, oops 2021-02-11 18:28:25 +00:00
c2e68bdc77
add GOESBUILD option for platform without esbuild on npm 2021-02-11 18:21:21 +00:00
e1c3b312ff
split armhf and arm64, add stable build 2021-02-11 16:24:32 +00:00
e235ed9fda
fix key again 2021-02-11 16:14:39 +00:00
5cda12dd3b
separate into pipelines, add armhf 2021-02-11 16:11:07 +00:00
a9d48083fd
fix keyfile 2021-02-11 15:48:13 +00:00
e28c50401e
use key path 2021-02-11 15:37:02 +00:00
4a3b015a40
start adding automated arm builds 2021-02-11 15:29:33 +00:00
1a6727312c
dont override header on email confirmation fail 2021-02-11 14:04:15 +00:00
91d3d2596e
fix broken invite links 2021-02-11 13:49:06 +00:00
192c9a4764
account for lack of trailing slash in url 2021-02-09 20:45:35 +00:00
173c38563e
remove embed, oops 2021-02-08 15:43:20 +00:00
d061721f56
explicitly set js mimetype 2021-02-08 15:25:02 +00:00
218882b7c6
remove debug console.log 2021-02-08 11:50:58 +00:00
fed3ee4c4f
Create FUNDING.yml 2021-02-08 01:01:48 +00:00
8eed4b0127
merge language again 2021-02-05 18:25:56 +00:00
c09ffb49e7
switch emails to normal text when not editing
fixes padding on small screens.
2021-02-05 18:24:27 +00:00
ClankJake
f331f4eb92 translation from Weblate (Portuguese (Brazil))
Currently translated at 100.0% (103 of 103 strings)

Translation: jfa-go/Admin Page
Translate-URL: https://weblate.hrfee.pw/projects/jfa-go/admin/pt_BR/
2021-02-05 15:55:38 +01:00
Richard de Boer
629b669c64 translation from Weblate (Dutch)
Currently translated at 100.0% (103 of 103 strings)

Translation: jfa-go/Admin Page
Translate-URL: https://weblate.hrfee.pw/projects/jfa-go/admin/nl/
2021-02-05 15:55:38 +01:00
Cornichon420
2dab900748 translation from Weblate (French)
Currently translated at 100.0% (103 of 103 strings)

Translation: jfa-go/Admin Page
Translate-URL: https://weblate.hrfee.pw/projects/jfa-go/admin/fr/
2021-02-05 15:55:38 +01:00
hrfee
f864097f2e translation from Weblate (English)
Currently translated at 100.0% (103 of 103 strings)

Translation: jfa-go/Admin Page
Translate-URL: https://weblate.hrfee.pw/projects/jfa-go/admin/en/
2021-02-05 15:55:38 +01:00
2c8be42bbc
fix invite links with URL base 2021-02-05 13:33:34 +00:00
6691ae27f4
fix navigation with URL base set 2021-02-05 13:31:56 +00:00
23fecb16b2
merge language changes 2021-02-05 13:11:00 +00:00
b037b08152
respect URL Base in http preloads and inline html links 2021-02-05 13:10:47 +00:00
ClankJake
46fe3a7f5d Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (32 of 32 strings)

Translation: jfa-go/Emails
Translate-URL: https://weblate.hrfee.pw/projects/jfa-go/emails/pt_BR/
2021-02-03 10:04:41 +01:00
virusperfect
61bd62403f Translated using Weblate (German)
Currently translated at 100.0% (95 of 95 strings)

Translation: jfa-go/Setup
Translate-URL: https://weblate.hrfee.pw/projects/jfa-go/setup/de/
2021-02-03 10:04:41 +01:00
ClankJake
5893d4b855 translation from Weblate (Portuguese (Brazil))
Currently translated at 100.0% (27 of 27 strings)

Translation: jfa-go/Account Creation Form
Translate-URL: https://weblate.hrfee.pw/projects/jfa-go/form/pt_BR/
2021-02-03 10:04:41 +01:00
virusperfect
8016e6f211 Translated using Weblate (German)
Currently translated at 100.0% (32 of 32 strings)

Translation: jfa-go/Emails
Translate-URL: https://weblate.hrfee.pw/projects/jfa-go/emails/de/
2021-02-03 10:04:41 +01:00
virusperfect
a5560b04bd translation from Weblate (German)
Currently translated at 100.0% (27 of 27 strings)

Translation: jfa-go/Account Creation Form
Translate-URL: https://weblate.hrfee.pw/projects/jfa-go/form/de/
2021-02-03 10:04:41 +01:00
Richard de Boer
b9e171b1fd Translated using Weblate (Dutch)
Currently translated at 100.0% (32 of 32 strings)

Translation: jfa-go/Emails
Translate-URL: https://weblate.hrfee.pw/projects/jfa-go/emails/nl/
2021-02-03 10:04:41 +01:00
Cornichon420
a633425baa Translated using Weblate (French)
Currently translated at 100.0% (32 of 32 strings)

Translation: jfa-go/Emails
Translate-URL: https://weblate.hrfee.pw/projects/jfa-go/emails/fr/
2021-02-03 10:04:41 +01:00
Richard de Boer
e29e89c618 translation from Weblate (Dutch)
Currently translated at 100.0% (27 of 27 strings)

Translation: jfa-go/Account Creation Form
Translate-URL: https://weblate.hrfee.pw/projects/jfa-go/form/nl/
2021-02-03 10:04:41 +01:00
Cornichon420
62c986161c translation from Weblate (French)
Currently translated at 100.0% (27 of 27 strings)

Translation: jfa-go/Account Creation Form
Translate-URL: https://weblate.hrfee.pw/projects/jfa-go/form/fr/
2021-02-03 10:04:41 +01:00
ClankJake
6279c73402 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (32 of 32 strings)

Translation: jfa-go/Emails
Translate-URL: https://weblate.hrfee.pw/projects/jfa-go/emails/pt_BR/
2021-02-03 10:04:41 +01:00
ClankJake
22e103837f translation from Weblate (Portuguese (Brazil))
Currently translated at 100.0% (101 of 101 strings)

Translation: jfa-go/Admin Page
Translate-URL: https://weblate.hrfee.pw/projects/jfa-go/admin/pt_BR/
2021-02-03 10:04:41 +01:00
ClankJake
feba6e7bae Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (95 of 95 strings)

Translation: jfa-go/Setup
Translate-URL: https://weblate.hrfee.pw/projects/jfa-go/setup/pt_BR/
2021-02-03 10:04:41 +01:00
95a6b48c3e
add go1.16 branch do drone builds
This branch has fully self-contained binaries, so I thought it'd be a
good idea to build it alongside.
2021-02-01 18:43:30 +00:00
31 changed files with 456 additions and 102 deletions

View File

@ -9,7 +9,7 @@ steps:
commands:
- git fetch --tags
- name: release
image: golang:latest
image: golang:1.16rc1-buster
environment:
GITHUB_TOKEN:
from_secret: github_token
@ -19,11 +19,139 @@ steps:
- (curl -sL https://deb.nodesource.com/setup_14.x | bash -)
- apt install nodejs
- curl -sL https://git.io/goreleaser | bash
when:
event: tag
trigger:
event:
- tag
branch:
- main
---
name: jfa-go-1.16-git
name: amd64-docker
kind: pipeline
type: docker
steps:
- name: fetch
image: docker:git
commands:
- git fetch --tags
- name: build
image: plugins/docker
settings:
username: hrfee
password:
from_secret: docker_key
repo: hrfee/jfa-go
tags: manifest-latest-amd64
trigger:
event:
- tag
branch:
- main
---
name: arm64-docker
kind: pipeline
type: docker
steps:
- name: arm64-ssh
image: appleboy/drone-ssh
volumes:
- name: ssh_key
path: /root/drone_rsa
settings:
host:
from_secret: ssh_host
username:
from_secret: ssh_username
port:
from_secret: ssh_port
volumes:
- /root/.ssh/docker-build:/root/drone_rsa
key_path: /root/drone_rsa
command_timeout: 50m
script:
- /home/rock64/jfa-go-build/build-stable.sh
trigger:
event:
- tag
branch:
- main
volumes:
- name: ssh_key
host:
path: /root/.ssh/docker-build
---
name: armhf-docker
kind: pipeline
type: docker
steps:
- name: armhf-ssh
image: appleboy/drone-ssh
volumes:
- name: ssh_key
path: /root/drone_rsa
settings:
host:
from_secret: ssh_host
username:
from_secret: ssh_username
port:
from_secret: ssh_port
volumes:
- /root/.ssh/docker-build:/root/drone_rsa
key_path: /root/drone_rsa
command_timeout: 50m
script:
- ssh pi /home/pi/jfa-go-build/build-stable.sh
trigger:
event:
- tag
branch:
- main
volumes:
- name: ssh_key
host:
path: /root/.ssh/docker-build
---
name: docker-manifest
kind: pipeline
type: docker
steps:
- name: manifest
image: appleboy/drone-ssh
volumes:
- name: ssh_key
path: /root/drone_rsa
settings:
host:
from_secret: ssh_host
username:
from_secret: ssh_username
port:
from_secret: ssh_port
volumes:
- /root/.ssh/docker-build:/root/drone_rsa
key_path: /root/drone_rsa
command_timeout: 50m
script:
- env DOCKER_CLI_EXPERIMENTAL=enabled docker manifest create hrfee/jfa-go:latest --amend hrfee/jfa-go:manifest-latest-amd64 --amend hrfee/jfa-go:manifest-latest-arm64 --amend hrfee/jfa-go:manifest-latest-armhf
- env DOCKER_CLI_EXPERIMENTAL=enabled docker manifest push hrfee/jfa-go:latest
trigger:
event:
- tag
branch:
- main
volumes:
- name: ssh_key
host:
path: /root/.ssh/docker-build
depends_on:
- amd64-docker
- arm64-docker
- armhf-docker
---
name: jfa-go-git
kind: pipeline
type: docker
@ -54,13 +182,146 @@ trigger:
- pull_request
---
name: amd64-docker-git
kind: pipeline
type: docker
steps:
- name: build
image: plugins/docker
settings:
username: hrfee
password:
from_secret: docker_key
repo: hrfee/jfa-go
tags: manifest-unstable-amd64
trigger:
branch:
- main
event:
exclude:
- pull_request
---
name: arm64-docker-git
kind: pipeline
type: docker
steps:
- name: arm64-ssh
image: appleboy/drone-ssh
volumes:
- name: ssh_key
path: /root/drone_rsa
settings:
host:
from_secret: ssh_host
username:
from_secret: ssh_username
port:
from_secret: ssh_port
volumes:
- /root/.ssh/docker-build:/root/drone_rsa
key_path: /root/drone_rsa
command_timeout: 50m
script:
- /home/rock64/jfa-go-build/build.sh
trigger:
branch:
- main
event:
exclude:
- pull_request
volumes:
- name: ssh_key
host:
path: /root/.ssh/docker-build
---
name: armhf-docker-git
kind: pipeline
type: docker
steps:
- name: armhf-ssh
image: appleboy/drone-ssh
volumes:
- name: ssh_key
path: /root/drone_rsa
settings:
host:
from_secret: ssh_host
username:
from_secret: ssh_username
port:
from_secret: ssh_port
volumes:
- /root/.ssh/docker-build:/root/drone_rsa
key_path: /root/drone_rsa
command_timeout: 50m
script:
- ssh pi /home/pi/jfa-go-build/build.sh
trigger:
branch:
- main
event:
exclude:
- pull_request
volumes:
- name: ssh_key
host:
path: /root/.ssh/docker-build
---
name: docker-manifest-unstable
kind: pipeline
type: docker
steps:
- name: manifest
image: appleboy/drone-ssh
volumes:
- name: ssh_key
path: /root/drone_rsa
settings:
host:
from_secret: ssh_host
username:
from_secret: ssh_username
port:
from_secret: ssh_port
volumes:
- /root/.ssh/docker-build:/root/drone_rsa
key_path: /root/drone_rsa
command_timeout: 50m
script:
- env DOCKER_CLI_EXPERIMENTAL=enabled docker manifest create hrfee/jfa-go:unstable --amend hrfee/jfa-go:manifest-unstable-amd64 --amend hrfee/jfa-go:manifest-unstable-arm64 --amend hrfee/jfa-go:manifest-unstable-armhf
- env DOCKER_CLI_EXPERIMENTAL=enabled docker manifest push hrfee/jfa-go:unstable
depends_on:
- amd64-docker-git
- arm64-docker-git
- armhf-docker-git
trigger:
branch:
- main
event:
exclude:
- pull_request
volumes:
- name: ssh_key
host:
path: /root/.ssh/docker-build
---
name: jfa-go-pr
kind: pipeline
type: docker
steps:
- name: build
image: golang:latest
image: golang:1.16rc1-buster
commands:
- apt update -y
- apt install build-essential python3-pip curl software-properties-common sed upx -y
@ -74,3 +335,4 @@ trigger:
event:
include:
- pull_request

3
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,3 @@
# These are supported funding model platforms
github: hrfee

View File

@ -11,6 +11,7 @@ before:
- mkdir -p data
- cp -r static data/web
- npm install
- npm install esbuild
- mkdir -p data/web/css
- npx esbuild --bundle css/base.css --outfile=./data/web/css/bundle.css --external:remixicon.css --minify
- cp node_modules/remixicon/fonts/remixicon.css node_modules/remixicon/fonts/remixicon.woff2 data/web/css/

View File

@ -6,7 +6,7 @@ RUN apt update -y \
&& apt install build-essential python3-pip curl software-properties-common sed upx -y \
&& (curl -sL https://deb.nodesource.com/setup_14.x | bash -) \
&& apt install nodejs \
&& (cd /opt/build; make all-external; make compress) \
&& (cd /opt/build; make all-external GOESBUILD=on; make compress) \
&& sed -i 's#id="password_resets-watch_directory" placeholder="/config/jellyfin"#id="password_resets-watch_directory" value="/jf" disabled#g' /opt/build/build/data/html/setup.html
FROM golang:1.16rc1-buster

View File

@ -1,8 +1,19 @@
GOESBUILD ?= off
ifeq ($(GOESBUILD), on)
ESBUILD := esbuild
else
ESBUILD := npx esbuild
endif
GOBINARY ?= go
npm:
$(info installing npm dependencies)
npm install
@if [ "$(GOESBUILD)" = "off" ]; then\
npm install esbuild;\
else\
go get -u github.com/evanw/esbuild/cmd/esbuild;\
fi
configuration:
$(info Fixing config-base)
@ -18,16 +29,16 @@ email:
typescript:
$(info compiling typescript)
-mkdir -p data/web/js
-npx esbuild --bundle ts/admin.ts --outfile=./data/web/js/admin.js --minify
-npx esbuild --bundle ts/form.ts --outfile=./data/web/js/form.js --minify
-npx esbuild --bundle ts/setup.ts --outfile=./data/web/js/setup.js --minify
-$(ESBUILD) --bundle ts/admin.ts --outfile=./data/web/js/admin.js --minify
-$(ESBUILD) --bundle ts/form.ts --outfile=./data/web/js/form.js --minify
-$(ESBUILD) --bundle ts/setup.ts --outfile=./data/web/js/setup.js --minify
ts-debug:
$(info compiling typescript w/ sourcemaps)
-mkdir -p data/web/js
-npx esbuild --bundle ts/admin.ts --sourcemap --outfile=./data/web/js/admin.js
-npx esbuild --bundle ts/form.ts --sourcemap --outfile=./data/web/js/form.js
-npx esbuild --bundle ts/setup.ts --sourcemap --outfile=./data/web/js/setup.js
-$(ESBUILD) --bundle ts/admin.ts --sourcemap --outfile=./data/web/js/admin.js
-$(ESBUILD) --bundle ts/form.ts --sourcemap --outfile=./data/web/js/form.js
-$(ESBUILD) --bundle ts/setup.ts --sourcemap --outfile=./data/web/js/setup.js
-rm -r data/web/js/ts
$(info copying typescript)
cp -r ts data/web/js
@ -59,7 +70,7 @@ compress:
bundle-css:
-mkdir -p data/web/css
$(info bundling css)
npx esbuild --bundle css/base.css --outfile=data/web/css/bundle.css --external:remixicon.css --minify
$(ESBUILD) --bundle css/base.css --outfile=data/web/css/bundle.css --external:remixicon.css --minify
copy:
$(info copying fonts)

1
go.mod
View File

@ -13,6 +13,7 @@ replace github.com/hrfee/jfa-go/ombi => ./ombi
require (
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/evanw/esbuild v0.8.44 // indirect
github.com/fsnotify/fsnotify v1.4.9
github.com/gin-contrib/pprof v1.3.0
github.com/gin-contrib/static v0.0.0-20200916080430-d45d9a37d28e

3
go.sum
View File

@ -34,6 +34,8 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473 h1:4
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/evanw/esbuild v0.8.44 h1:9svHk3MxC3T8ThKkUJ71GcPXYGMhxhO5iCfg2hrU0PU=
github.com/evanw/esbuild v0.8.44/go.mod h1:y2AFBAGVelPqPodpdtxWWqe6n2jYf5FrsJbligmRmuw=
github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51 h1:0JZ+dUmQeA8IIVUMzysrX4/AKuQwWhV2dYQuPZdvdSQ=
github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64=
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A=
@ -420,6 +422,7 @@ golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200501145240-bc7a7d42d5c3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1 h1:sIky/MyNRSHTrdxfsiUSS4WIAMvInbeXljJz+jDjeYE=
golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed h1:J22ig1FUekjjkmZUM7pTKixYm8DvrYsvrBZdunYeIuQ=

View File

@ -1,7 +1,7 @@
<!DOCTYPE html>
<html lang="en" class="{{ .cssClass }}">
<head>
<link rel="stylesheet" type="text/css" href="css/bundle.css">
<link rel="stylesheet" type="text/css" href="{{ .urlBase }}/css/bundle.css">
<script>
window.URLBase = "{{ .urlBase }}";
window.notificationsEnabled = {{ .notifications }};
@ -40,7 +40,7 @@
<div id="modal-about" class="modal">
<div class="modal-content content card">
<span class="heading">{{ .strings.aboutProgram }} <span class="modal-close">&times;</span></span>
<img src="/banner.svg" class="mt-1" alt="jfa-go banner">
<img src="{{ .urlBase }}/banner.svg" class="mt-1" alt="jfa-go banner">
<p><i class="icon ri-github-fill"></i><a href="https://github.com/hrfee/jfa-go">jfa-go</a></p>
<p>{{ .strings.version }} <span class="code monospace">{{ .version }}</span></p>
<p>{{ .strings.commitNoun }} <span class="code monospace">{{ .commit }}</span></p>
@ -292,6 +292,6 @@
</div>
</div>
</div>
<script src="js/admin.js" type="module"></script>
<script src="{{ .urlBase }}/js/admin.js" type="module"></script>
</body>
</html>

View File

@ -36,7 +36,7 @@
"sendDeleteNotificationEmail": "Send notification email",
"sendDeleteNotifiationExample": "Your account has been deleted.",
"settingsRestart": "Restart",
"settingsRestarting": "Restarting...",
"settingsRestarting": "Restarting",
"settingsRestartRequired": "Restart needed",
"settingsRestartRequiredDescription": "A restart is necessary to apply some settings you changed. Restart now or later?",
"settingsApplyRestartLater": "Apply, restart later",
@ -55,7 +55,6 @@
"addProfileDescription": "Create a Jellyfin user and configure it, then select it below. When this profile is applied to an invite, new users will be created with the settings.",
"addProfileNameOf": "Profile Name",
"addProfileStoreHomescreenLayout": "Store homescreen layout",
"inviteNoUsersCreated": "None yet!",
"inviteUsersCreated": "Created users",
"inviteNoProfile": "No Profile",
@ -64,7 +63,6 @@
"inviteRemainingUses": "Remaining uses",
"inviteNoInvites": "None",
"inviteExpiresInTime": "Expires in {n}",
"notifyEvent": "Notify on:",
"notifyInviteExpiry": "On expiry",
"notifyUserCreation": "On user creation"
@ -98,7 +96,6 @@
"errorUserCreated": "Failed to create user {n}.",
"errorSendWelcomeEmail": "Failed to send welcome email (check console/logs)"
},
"quantityStrings": {
"modifySettingsFor": {
"singular": "Modify Settings for {n} user",

View File

@ -40,7 +40,7 @@
"settingsApplyRestartLater": "Appliquer, redémarrer plus tard",
"settingsApplyRestartNow": "Appliquer et redémarrer",
"settingsApplied": "Paramètres appliqués.",
"settingsRefreshPage": "Actualisez la page dans quelques secondes",
"settingsRefreshPage": "Actualisez la page dans quelques secondes.",
"settingsRequiredOrRestartMessage": "Remarque: {n} indique un champ obligatoire, {n} indique que les modifications nécessitent un redémarrage.",
"settingsSave": "Sauver",
"ombiUserDefaults": "Paramètres par défaut de l'utilisateur Ombi",
@ -64,7 +64,9 @@
"notifyEvent": "Notifier sur :",
"notifyInviteExpiry": "À l'expiration",
"notifyUserCreation": "à la création de l'utilisateur",
"label": "Etiquette"
"label": "Etiquette",
"settingsRestarting": "Redémarrage…",
"settingsRestart": "Redémarrer"
},
"notifications": {
"changedEmailAddress": "Adresse e-mail modifiée de {n}.",

View File

@ -39,7 +39,7 @@
"settingsApplyRestartLater": "Sla op, herstart later",
"settingsApplyRestartNow": "Sla op & herstart",
"settingsApplied": "Wijzigingen doorgevoerd.",
"settingsRefreshPage": "Ververs de pagina over enkele seconden",
"settingsRefreshPage": "Ververs de pagina over enkele seconden.",
"settingsRequiredOrRestartMessage": "Opmerking: {n} is een verplicht veld, {n} geeft aan dat na wijzigen een herstart nodig is.",
"settingsSave": "Opslaan",
"ombiUserDefaults": "Ombi gebruiker standaardinstellingen",
@ -63,7 +63,9 @@
"notifyEvent": "Meldingen:",
"notifyInviteExpiry": "Bij verloop",
"notifyUserCreation": "Bij aanmaken gebruiker",
"label": "Label"
"label": "Label",
"settingsRestart": "Herstart",
"settingsRestarting": "Aan het herstarten…"
},
"notifications": {
"changedEmailAddress": "E-mailadres van {n} gewijzigd.",

View File

@ -29,7 +29,7 @@
"newUser": "Novo Usuário",
"profile": "Perfil",
"unknown": "Desconhecido",
"label": "",
"label": "Rótulo",
"modifySettings": "Modificar configurações",
"modifySettingsDescription": "Aplique as configurações de um perfil existente ou obtenha-as diretamente de um usuário.",
"applyHomescreenLayout": "Aplicar layout na tela inicial",
@ -40,7 +40,7 @@
"settingsApplyRestartLater": "Aplicar, reiniciar mais tarde",
"settingsApplyRestartNow": "Aplicar e reiniciar",
"settingsApplied": "Configurações aplicada.",
"settingsRefreshPage": "Atualize a página em alguns segundos",
"settingsRefreshPage": "Atualize a página em alguns segundos.",
"settingsRequiredOrRestartMessage": "Nota: {n} indica campo obrigatório, {n} indica que as alterações requer um reinício.",
"settingsSave": "Salve",
"ombiUserDefaults": "Padrões do usuário Ombi",
@ -63,7 +63,9 @@
"inviteExpiresInTime": "Expira em {n}",
"notifyEvent": "Notificar em:",
"notifyInviteExpiry": "No vencimento",
"notifyUserCreation": "Na criação do usuário"
"notifyUserCreation": "Na criação do usuário",
"settingsRestart": "Reiniciar",
"settingsRestarting": "Reiniciando…"
},
"notifications": {
"changedEmailAddress": "Endereço de e-mail alterado de {n}.",
@ -86,7 +88,7 @@
"errorLoadUsers": "Falha ao carregar usuários.",
"errorSaveSettings": "Não foi possível salvar as configurações.",
"errorLoadSettings": "Falha ao carregar as configurações.",
"errorSetOmbiDefaults": "Falha ao armazenar padrões de ombi.",
"errorSetOmbiDefaults": "Falha em armazenar os padrões ombi.",
"errorLoadOmbiUsers": "Falha ao carregar usuários ombi.",
"errorChangedEmailAddress": "Não foi possível alterar o endereço de e-mail de {n}.",
"errorFailureCheckLogs": "Falha (verificar console/logs)",

View File

@ -43,5 +43,10 @@
"welcome": "Willkommen bei Jellyfin!",
"youCanLoginWith": "Du kannst dich mit den mit den untenstehenden Zugangsdaten anmelden",
"jellyfinURL": "URL"
},
"emailConfirmation": {
"title": "Bestätige deine E-Mail - Jellyfin",
"clickBelow": "Klicke den untenstehenden Link, um deine E-Mail-Adresse zu bestätigen, und fange an, Jellyfin zu benutzen.",
"confirmEmail": "E-Mail bestätigen"
}
}

View File

@ -44,5 +44,10 @@
"title": "Bienvenue sur Jellyfin",
"welcome": "Bienvenue sur Jellyfin !",
"jellyfinURL": "URL"
},
"emailConfirmation": {
"title": "Confirmez votre adresse e-mail - Jellyfin",
"clickBelow": "Clique sur le lien ci-dessous pour confirmer ton adresse e-mail et commencer à utiliser Jellyfin.",
"confirmEmail": "Confirmer l'adresse e-mail"
}
}

View File

@ -43,5 +43,10 @@
"welcome": "Welkom bij Jellyfin!",
"youCanLoginWith": "Je kunt inloggen met onderstaande gegevens",
"jellyfinURL": "URL"
},
"emailConfirmation": {
"title": "Bevestig je e-mailadres - Jellyfin",
"clickBelow": "Klik op onderstaande link om je e-mailadres te bevestigen en te beginnen met Jellyfin.",
"confirmEmail": "Bevestig e-mailadres"
}
}

View File

@ -33,7 +33,7 @@
"inviteEmail": {
"title": "Convite - Jellyfin",
"hello": "Ola",
"youHaveBeenInvited": "Você um convite para o Jellyfin.",
"youHaveBeenInvited": "Você recebeu um convite para o Jellyfin.",
"toJoin": "Para participar, clique no link abaixo.",
"inviteExpiry": "Este convite expira em {n} às {n}, que é em {n}, então seja rápido.",
"linkButton": "Crie sua conta"
@ -43,5 +43,10 @@
"welcome": "Bem vindo ao Jellyfin!",
"youCanLoginWith": "Você pode fazer o login com os detalhes abaixo",
"jellyfinURL": "URL"
},
"emailConfirmation": {
"title": "Confirme seu email - Jellyfin",
"clickBelow": "Clique no link abaixo para confirmar seu endereço de e-mail e começar a usar o Jellyfin.",
"confirmEmail": "Confirmar Email"
}
}

View File

@ -14,7 +14,9 @@
"createAccountButton": "Konto erstellen",
"passwordRequirementsHeader": "Passwortanforderungen",
"successHeader": "Erfolg!",
"successContinueButton": "Weiter"
"successContinueButton": "Weiter",
"confirmationRequired": "E-Mail-Bestätigung erforderlich",
"confirmationRequiredMessage": "Bitte überprüfe dein Posteingang und bestätige deine E-Mail-Adresse."
},
"validationStrings": {
"length": {

View File

@ -15,7 +15,9 @@
"createAccountButton": "Créer le compte",
"passwordRequirementsHeader": "Mot de passe requis",
"successHeader": "Succes!",
"successContinueButton": "Continuer"
"successContinueButton": "Continuer",
"confirmationRequired": "Confirmation de l'adresse e-mail requise",
"confirmationRequiredMessage": "Veuillez vérifier votre boite de réception pour confirmer votre adresse e-mail."
},
"validationStrings": {
"length": {

View File

@ -14,7 +14,9 @@
"createAccountButton": "Maak account aan",
"passwordRequirementsHeader": "Wachtwoordvereisten",
"successHeader": "Succes!",
"successContinueButton": "Doorgaan"
"successContinueButton": "Doorgaan",
"confirmationRequired": "Bevestiging van e-mailadres verplicht",
"confirmationRequiredMessage": "Controleer je e-mail inbox om je adres te bevestigen."
},
"validationStrings": {
"length": {

View File

@ -14,7 +14,9 @@
"createAccountButton": "Criar Conta",
"passwordRequirementsHeader": "Requisitos da Senha",
"successHeader": "Sucesso!",
"successContinueButton": "Continuar"
"successContinueButton": "Continuar",
"confirmationRequired": "Necessária confirmação de e-mail",
"confirmationRequiredMessage": "Verifique sua caixa de entrada no e-mail para verificar seu endereço."
},
"notifications": {
"errorUserExists": "Esse usuário já existe.",

View File

@ -25,7 +25,7 @@
},
"endPage": {
"finished": "Fertig!",
"restartMessage": "Es gibt weitere Einstellungen, die du auf der Admin-Seite konfigurieren kannst. Drücke unten, um neu zu starten, dann aktualisiere die Seite.",
"restartMessage": "Es gibt weitere Einstellungen, die du auf der Admin-Seite konfigurieren kannst. Klicke unten, um neu zu starten, dann aktualisiere die Seite.",
"refreshPage": "Aktualisieren"
},
"language": {
@ -42,7 +42,7 @@
"urlBaseNotice": "Nur erforderlich, wenn ein Reverse-Proxy auf einer Subdomain verwendet wird (z. B. 'jellyf.in/accounts').",
"lightTheme": "Hell",
"darkTheme": "Dunkel",
"useHTTPS": "Verwende HTTPS",
"useHTTPS": "HTTPS verwenden",
"httpsPort": "HTTPS Port",
"useHTTPSNotice": "Nur empfohlen, wenn du keinen Reverse-Proxy verwendest.",
"pathToCertificate": "Pfad zum Zertifikat",
@ -51,10 +51,10 @@
"login": {
"title": "Anmelden",
"description": "Um auf die Admin-Seite zuzugreifen, musst du dich mit einer untenstehenden Methode anmelden:",
"authorizeWithJellyfin": "Autorisiere mit Jellyfin/Emby: Anmeldedaten werden mit Jellyfin geteilt, was mehrere Benutzer ermöglicht.",
"authorizeWithJellyfin": "Mit Jellyfin/Emby autorisieren: Anmeldedaten werden mit Jellyfin geteilt, was mehrere Benutzer ermöglicht.",
"authorizeManual": "Benutzername und Passwort: Lege Benutzername und Passwort manuell fest.",
"adminOnly": "Nur Admin-Benutzer (empfohlen)",
"emailNotice": "Eine E-Mail-Adresse kann verwendet werden, um Benachrichtigungen zu erhalten."
"emailNotice": "Deine E-Mail-Adresse kann verwendet werden, um Benachrichtigungen zu erhalten."
},
"jellyfinEmby": {
"title": "Jellyfin/Emby",
@ -69,8 +69,8 @@
},
"ombi": {
"title": "Ombi",
"description": "Durch den Anschluss an Ombi wird sowohl ein Jellyfin-Konto als auch ein Ombi-Konto erstellt, wenn ein Benutzer durch jfa-go beitritt. Nachdem das Setup abgeschlossen ist, gehe zu den Einstellungen um ein Standardprofil für neue Ombi-Benutzer festzulegen.",
"apiKeyNotice": "Finde das in der ersten Registerkarte der Ombi-Einstellungen."
"description": "Durch den Anschluss an Ombi wird sowohl ein Jellyfin-Konto als auch ein Ombi-Konto erstellt, wenn ein Benutzer durch jfa-go beitritt. Nachdem das Setup abgeschlossen ist, gehe zu den Einstellungen, um ein Standardprofil für neue Ombi-Benutzer festzulegen.",
"apiKeyNotice": "Finde dies in der ersten Registerkarte der Ombi-Einstellungen."
},
"email": {
"title": "E-Mail",
@ -89,7 +89,7 @@
},
"notifications": {
"title": "Benachrichtigungen",
"description": "Wenn aktiviert, kannst du (per Invite) wählen, eine E-Mail zu erhalten, wenn ein Invite abläuft oder ein Benutzer erstellt wird. Wenn du nicht die Jellyfin-Login-Methode gewählt hast, stelle sicher, dass du deine E-Mail-Adresse angegeben hast."
"description": "Wenn aktiviert, kannst du (pro Invite) wählen, eine E-Mail zu erhalten, wenn ein Invite abläuft oder ein Benutzer erstellt wird. Wenn du nicht die Jellyfin-Login-Methode gewählt hast, stelle sicher, dass du deine E-Mail-Adresse angegeben hast."
},
"welcomeEmails": {
"title": "Willkommens-E-Mails",

View File

@ -37,7 +37,7 @@
},
"general": {
"title": "Geral",
"listenAddress": "",
"listenAddress": "Endereço de Escuta",
"urlBase": "URL Base",
"urlBaseNotice": "Necessário apenas se estiver usando um proxy reverso em um subdomínio (por exemplo, 'jellyf.in/accounts').",
"lightTheme": "Claro",

View File

@ -10,6 +10,7 @@ import (
"io"
"io/fs"
"log"
"mime"
"net"
"net/http"
"os"
@ -521,13 +522,15 @@ func start(asDaemon, firstCall bool) {
app.info.Fatalf("Failed to load language files: %+v\n", err)
}
}
cssHeader = app.loadCSSHeader()
// workaround for potentially broken windows mime types
mime.AddExtensionType(".js", "application/javascript")
app.info.Println("Initializing router")
router := app.loadRouter(address, debugMode)
app.info.Println("Loading routes")
router.GET("/lang/:page", app.GetLanguages)
if !firstRun {
app.loadRoutes(router)
app.info.Printf("Starting router @ %s", address)
} else {
app.loadSetup(router)
app.info.Printf("Loading setup @ %s", address)

6
package-lock.json generated
View File

@ -228,9 +228,9 @@
"integrity": "sha1-vfpzUplmTfr9NFKe1PhSKidf6lY="
},
"esbuild": {
"version": "0.7.22",
"resolved": "https://registry.npm.taobao.org/esbuild/download/esbuild-0.7.22.tgz",
"integrity": "sha1-kUm5A/gSi3xFp1QEbCQZnXa74I4="
"version": "0.8.44",
"resolved": "https://registry.npm.taobao.org/esbuild/download/esbuild-0.8.44.tgz",
"integrity": "sha1-KnT0j+IFeQgcnY/pm+b7jShIyIc="
},
"escalade": {
"version": "3.1.1",

View File

@ -18,7 +18,7 @@
"homepage": "https://github.com/hrfee/jfa-go#readme",
"dependencies": {
"a17t": "^0.4.0",
"esbuild": "^0.7.8",
"esbuild": "^0.8.44",
"lodash": "^4.17.19",
"mjml": "^4.8.0",
"remixicon": "^2.5.0",

View File

@ -97,45 +97,59 @@ func (app *appContext) loadRouter(address string, debug bool) *gin.Engine {
}
func (app *appContext) loadRoutes(router *gin.Engine) {
router.GET("/", app.AdminPage)
router.GET("/accounts", app.AdminPage)
router.GET("/settings", app.AdminPage)
router.GET("/lang/:page/:file", app.ServeLang)
router.GET("/token/login", app.getTokenLogin)
router.GET("/token/refresh", app.getTokenRefresh)
router.POST("/newUser", app.NewUser)
router.Use(static.Serve("/invite/", app.webFS))
router.GET("/invite/:invCode", app.InviteProxy)
routePrefixes := []string{app.URLBase}
if app.URLBase != "" {
routePrefixes = append(routePrefixes, "")
}
for _, p := range routePrefixes {
router.GET(p+"/lang/:page", app.GetLanguages)
router.Use(static.Serve(p+"/", app.webFS))
router.GET(p+"/", app.AdminPage)
router.GET(p+"/accounts", app.AdminPage)
router.GET(p+"/settings", app.AdminPage)
router.GET(p+"/lang/:page/:file", app.ServeLang)
router.GET(p+"/token/login", app.getTokenLogin)
router.GET(p+"/token/refresh", app.getTokenRefresh)
router.POST(p+"/newUser", app.NewUser)
router.Use(static.Serve(p+"/invite/", app.webFS))
router.GET(p+"/invite/:invCode", app.InviteProxy)
}
if *SWAGGER {
app.info.Print(aurora.Magenta("\n\nWARNING: Swagger should not be used on a public instance.\n\n"))
router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
for _, p := range routePrefixes {
router.GET(p+"/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
}
}
api := router.Group("/", app.webAuth())
router.POST("/logout", app.Logout)
api.DELETE("/users", app.DeleteUser)
api.GET("/users", app.GetUsers)
api.POST("/users", app.NewUserAdmin)
api.POST("/invites", app.GenerateInvite)
api.GET("/invites", app.GetInvites)
api.DELETE("/invites", app.DeleteInvite)
api.POST("/invites/profile", app.SetProfile)
api.GET("/profiles", app.GetProfiles)
api.POST("/profiles/default", app.SetDefaultProfile)
api.POST("/profiles", app.CreateProfile)
api.DELETE("/profiles", app.DeleteProfile)
api.POST("/invites/notify", app.SetNotify)
api.POST("/users/emails", app.ModifyEmails)
api.POST("/users/settings", app.ApplySettings)
api.GET("/config", app.GetConfig)
api.POST("/config", app.ModifyConfig)
api.POST("/restart", app.restart)
if app.config.Section("ombi").Key("enabled").MustBool(false) {
api.GET("/ombi/users", app.OmbiUsers)
api.POST("/ombi/defaults", app.SetOmbiDefaults)
for _, p := range routePrefixes {
router.POST(p+"/logout", app.Logout)
api.DELETE(p+"/users", app.DeleteUser)
api.GET(p+"/users", app.GetUsers)
api.POST(p+"/users", app.NewUserAdmin)
api.POST(p+"/invites", app.GenerateInvite)
api.GET(p+"/invites", app.GetInvites)
api.DELETE(p+"/invites", app.DeleteInvite)
api.POST(p+"/invites/profile", app.SetProfile)
api.GET(p+"/profiles", app.GetProfiles)
api.POST(p+"/profiles/default", app.SetDefaultProfile)
api.POST(p+"/profiles", app.CreateProfile)
api.DELETE(p+"/profiles", app.DeleteProfile)
api.POST(p+"/invites/notify", app.SetNotify)
api.POST(p+"/users/emails", app.ModifyEmails)
// api.POST(p + "/setDefaults", app.SetDefaults)
api.POST(p+"/users/settings", app.ApplySettings)
api.GET(p+"/config", app.GetConfig)
api.POST(p+"/config", app.ModifyConfig)
api.POST(p+"/restart", app.restart)
if app.config.Section("ombi").Key("enabled").MustBool(false) {
api.GET(p+"/ombi/users", app.OmbiUsers)
api.POST(p+"/ombi/defaults", app.SetOmbiDefaults)
}
}
}
func (app *appContext) loadSetup(router *gin.Engine) {
router.GET("/lang/:page", app.GetLanguages)
router.GET("/", app.ServeSetup)
router.POST("/jellyfin/test", app.TestJF)
router.POST("/config", app.ModifyConfig)

View File

@ -84,23 +84,24 @@ window.tabs.addTab("accounts", null, accounts.reload);
window.tabs.addTab("settings", null, settings.reload);
for (let tab of ["invites", "accounts", "settings"]) {
if (window.location.pathname == "/" + tab) {
if (window.location.pathname == window.URLBase + "/" + tab) {
window.tabs.switch(tab, true);
}
}
if (window.location.pathname == "/") {
if ((window.URLBase + "/").includes(window.location.pathname)) {
window.tabs.switch("invites", true);
}
document.addEventListener("tab-change", (event: CustomEvent) => {
const urlParams = new URLSearchParams(window.location.search);
const lang = urlParams.get('lang');
let tab = "/" + event.detail;
if (tab == "/invites") {
if (window.location.pathname == "/") {
tab = "/";
} else { tab = "../"; }
let tab = window.URLBase + "/" + event.detail;
if (tab == window.URLBase + "/invites") {
if (window.location.pathname == window.URLBase + "/") {
tab = window.URLBase + "/";
} else if (window.URLBase) { tab = window.URLBase; }
else { tab = "../"; }
}
if (lang) {
tab += "?lang=" + lang

View File

@ -42,7 +42,15 @@ class user implements User {
}
get email(): string { return this._emailAddress; }
set email(value: string) { this._email.value = value; this._emailAddress = value; }
set email(value: string) {
this._emailAddress = value;
const input = this._email.querySelector("input");
if (input) {
input.value = value;
} else {
this._email.textContent = value;
}
}
get last_active(): string { return this._lastActive.textContent; }
set last_active(value: string) { this._lastActive.textContent = value; }
@ -55,20 +63,27 @@ class user implements User {
this._row.innerHTML = `
<td><input type="checkbox" value=""></td>
<td><span class="accounts-username"></span> <span class="accounts-admin"></span></td>
<td><i class="icon ri-edit-line accounts-email-edit"></i><input type="email" class="input ~neutral !normal stealth-input stealth-input-hidden accounts-email" readonly></td>
<td><i class="icon ri-edit-line accounts-email-edit"></i><span class="accounts-email-container ml-half"></span></td>
<td class="accounts-last-active"></td>
`;
const emailEditor = `<input type="email" class="input ~neutral !normal stealth-input">`;
this._check = this._row.querySelector("input[type=checkbox]") as HTMLInputElement;
this._username = this._row.querySelector(".accounts-username") as HTMLSpanElement;
this._admin = this._row.querySelector(".accounts-admin") as HTMLSpanElement;
this._email = this._row.querySelector(".accounts-email") as HTMLInputElement;
this._email = this._row.querySelector(".accounts-email-container") as HTMLInputElement;
this._emailEditButton = this._row.querySelector(".accounts-email-edit") as HTMLElement;
this._lastActive = this._row.querySelector(".accounts-last-active") as HTMLTableDataCellElement;
this._check.onchange = () => { this.selected = this._check.checked; }
const toggleStealthInput = () => {
this._email.classList.toggle("stealth-input-hidden");
this._email.readOnly = !this._email.readOnly;
if (this._emailEditButton.classList.contains("ri-edit-line")) {
this._email.innerHTML = emailEditor;
this._email.querySelector("input").value = this._emailAddress;
this._email.classList.remove("ml-half");
} else {
this._email.textContent = this._emailAddress;
this._email.classList.add("ml-half");
}
this._emailEditButton.classList.toggle("ri-check-line");
this._emailEditButton.classList.toggle("ri-edit-line");
};
@ -80,7 +95,7 @@ class user implements User {
}
};
this._emailEditButton.onclick = () => {
if (this._email.classList.contains("stealth-input-hidden")) {
if (this._emailEditButton.classList.contains("ri-edit-line")) {
document.addEventListener('click', outerClickListener);
} else {
this._updateEmail();
@ -94,7 +109,7 @@ class user implements User {
private _updateEmail = () => {
let oldEmail = this.email;
this.email = this._email.value;
this.email = this._email.querySelector("input").value;
let send = {};
send[this.id] = this.email;
_post("/users/emails", send, (req: XMLHttpRequest) => {

View File

@ -45,6 +45,7 @@ export class DOMInvite implements Invite {
for (let split of ["#", "?"]) {
codeLink = codeLink.split(split)[0];
}
if (codeLink.slice(-1) != "/") { codeLink += "/"; }
this._codeLink = codeLink + "invite/" + code;
const linkEl = this._codeArea.querySelector("a") as HTMLAnchorElement;
if (this.label == "") {

View File

@ -400,7 +400,6 @@ window.onpopstate = (event: PopStateEvent) => {
const card = cards[i];
const back = card.getElementsByClassName("back")[0] as HTMLSpanElement;
const next = card.getElementsByClassName("next")[0] as HTMLSpanElement;
console.log(cards[i]);
const titleEl = cards[i].querySelector("span.heading") as HTMLElement;
let title = titleEl.textContent.replace("/", "_").replace(" ", "-");
if (titleEl.classList.contains("welcome")) {

View File

@ -11,17 +11,26 @@ import (
)
var css = []string{"bundle.css", "remixicon.css"}
var cssHeader = func() string {
var cssHeader string
func (app *appContext) loadCSSHeader() string {
l := len(css)
h := ""
for i, f := range css {
h += "</css/" + f + ">; rel=preload; as=style"
h += "<" + app.URLBase + "/css/" + f + ">; rel=preload; as=style"
if l > 1 && i != (l-1) {
h += ", "
}
}
return h
}()
}
func (app *appContext) getURLBase(gc *gin.Context) string {
if strings.HasPrefix(gc.Request.URL.String(), app.URLBase) {
return app.URLBase
}
return ""
}
func gcHTML(gc *gin.Context, code int, file string, templ gin.H) {
gc.Header("Cache-Control", "no-cache")
@ -34,7 +43,7 @@ func (app *appContext) pushResources(gc *gin.Context, admin bool) {
if admin {
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"}
for _, f := range toPush {
if err := pusher.Push(f, nil); err != nil {
if err := pusher.Push(app.URLBase+f, nil); err != nil {
app.debug.Printf("Failed HTTP2 ServerPush of \"%s\": %+v", f, err)
}
}
@ -60,7 +69,7 @@ func (app *appContext) AdminPage(gc *gin.Context) {
notificationsEnabled, _ := app.config.Section("notifications").Key("enabled").Bool()
ombiEnabled := app.config.Section("ombi").Key("enabled").MustBool(false)
gcHTML(gc, http.StatusOK, "admin.html", gin.H{
"urlBase": app.URLBase,
"urlBase": app.getURLBase(gc),
"cssClass": app.cssClass,
"contactMessage": "",
"email_enabled": emailEnabled,
@ -134,9 +143,8 @@ func (app *appContext) InviteProxy(gc *gin.Context) {
Password: claims["password"].(string),
Code: claims["invite"].(string),
}
f, success := app.newUser(req, true)
_, success := app.newUser(req, true)
if !success {
f(gc)
fail()
return
}
@ -144,6 +152,7 @@ func (app *appContext) InviteProxy(gc *gin.Context) {
"strings": app.storage.lang.Form[lang].Strings,
"successMessage": app.config.Section("ui").Key("success_message").String(),
"contactMessage": app.config.Section("ui").Key("contact_message").String(),
"jfLink": app.config.Section("jellyfin").Key("public_server").String(),
})
inv, ok := app.storage.invites[code]
if ok {
@ -158,7 +167,7 @@ func (app *appContext) InviteProxy(gc *gin.Context) {
email = ""
}
gcHTML(gc, http.StatusOK, "form-loader.html", gin.H{
"urlBase": app.URLBase,
"urlBase": app.getURLBase(gc),
"cssClass": app.cssClass,
"contactMessage": app.config.Section("ui").Key("contact_message").String(),
"helpMessage": app.config.Section("ui").Key("help_message").String(),