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

Compare commits

...

4 Commits

12 changed files with 89 additions and 28 deletions

View File

@ -274,6 +274,18 @@
"value": false, "value": false,
"advanced": true, "advanced": true,
"description": "Navigate directly to the above URL instead of needing the user to click \"Continue\"." "description": "Navigate directly to the above URL instead of needing the user to click \"Continue\"."
},
"login_appearance": {
"name": "Login screen appearance",
"required": false,
"requires_restart": false,
"type": "select",
"options": [
["clear", "Transparent"],
["opaque", "Opaque"]
],
"value": "clear",
"description": "Appearance of the Admin login screen."
} }
} }
}, },
@ -406,6 +418,14 @@
"required": "false", "required": "false",
"description": "Click the edit icon next to the \"User Page\" Setting to add custom Markdown messages that will be shown to the user. Note message cards are not private, little effort is required for anyone to view them." "description": "Click the edit icon next to the \"User Page\" Setting to add custom Markdown messages that will be shown to the user. Note message cards are not private, little effort is required for anyone to view them."
}, },
"show_link": {
"name": "Show Link on Admin Login page",
"required": false,
"requires_restart": false,
"type": "bool",
"value": true,
"description": "Whether or not to show a link to the \"My Account\" page on the admin login screen, to direct lost users."
},
"referrals": { "referrals": {
"name": "User Referrals", "name": "User Referrals",
"required": false, "required": false,

View File

@ -15,6 +15,9 @@
--border-width-4: 5px; --border-width-4: 5px;
--border-width-8: 8px; --border-width-8: 8px;
font-family: 'Hanken Grotesk', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; font-family: 'Hanken Grotesk', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
--bg-light: #fff;
--bg-dark: #101010;
} }
.light { .light {
@ -26,11 +29,11 @@
} }
.dark body { .dark body {
background-color: #101010; background-color: var(--bg-dark);
} }
html:not(.dark) body { html:not(.dark) body {
background-color: #fff; background-color: var(--bg-light);
} }
.dark select, .dark option, .dark input { .dark select, .dark option, .dark input {

View File

@ -10,6 +10,24 @@
background-color: rgba(0,0,0,40%); background-color: rgba(0,0,0,40%);
} }
.wall {
position: fixed;
z-index: 11;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: auto;
}
html.dark .wall {
background-color: var(--bg-dark);
}
html:not(.dark) .wall {
background-color: var(--bg-light);
}
.modal-close { .modal-close {
float: right; float: right;
color: #aaa; color: #aaa;

View File

@ -18,6 +18,7 @@
window.jfAdminOnly = {{ .jfAdminOnly }}; window.jfAdminOnly = {{ .jfAdminOnly }};
window.jfAllowAll = {{ .jfAllowAll }}; window.jfAllowAll = {{ .jfAllowAll }};
window.referralsEnabled = {{ .referralsEnabled }}; window.referralsEnabled = {{ .referralsEnabled }};
window.loginAppearance = "{{ .loginAppearance }}";
</script> </script>
<title>Admin - jfa-go</title> <title>Admin - jfa-go</title>
{{ template "header.html" . }} {{ template "header.html" . }}
@ -465,7 +466,7 @@
</div> </div>
{{ if .userPageEnabled }} {{ if .userPageEnabled }}
<div class="top-4 right-4 absolute"> <div class="top-4 right-4 absolute">
<a class="button ~info" href="/my/account"><i class="ri-account-circle-fill mr-2"></i>{{ .strings.myAccount }}</a> <a class="button ~info" href="{{ .urlBase }}/my/account"><i class="ri-account-circle-fill mr-2"></i>{{ .strings.myAccount }}</a>
</div> </div>
{{ end }} {{ end }}
<div class="page-container"> <div class="page-container">

View File

@ -7,6 +7,14 @@
</div> </div>
{{ end }} {{ end }}
{{ end }} {{ end }}
{{ if index . "userPageEnabled" }}
{{ if and .userPageEnabled .showUserPageLink }}
<div class="card mx-2 flex-initial w-[100%] xl:w-[35%] mb-4 xl:mb-0 dark:~d_neutral @low content">
<span class="heading row">{{ .strings.loginNotAdmin }}</span>
<a class="button ~info h-12 w-100" href="{{ .urlBase }}/my/account"><i class="ri-account-circle-fill mr-2"></i>{{ .strings.myAccount }}</a>
</div>
{{ end }}
{{ end }}
<form class="card mx-2 flex-auto form-login w-[100%] xl:w-[55%] mb-0" href=""> <form class="card mx-2 flex-auto form-login w-[100%] xl:w-[55%] mb-0" href="">
<span class="heading">{{ .strings.login }}</span> <span class="heading">{{ .strings.login }}</span>
<input type="text" class="field input ~neutral @high mt-4 mb-2" placeholder="{{ .strings.username }}" id="login-user"> <input type="text" class="field input ~neutral @high mt-4 mb-2" placeholder="{{ .strings.username }}" id="login-user">

View File

@ -123,7 +123,8 @@
"userPageLogin": "User Page: Login", "userPageLogin": "User Page: Login",
"userPagePage": "User Page: Page", "userPagePage": "User Page: Page",
"buildTime": "Build Time", "buildTime": "Build Time",
"builtBy": "Built By" "builtBy": "Built By",
"loginNotAdmin": "Not an Admin?"
}, },
"notifications": { "notifications": {
"changedEmailAddress": "Changed email address of {n}.", "changedEmailAddress": "Changed email address of {n}.",

View File

@ -160,12 +160,11 @@ func (app *appContext) loadRoutes(router *gin.Engine) {
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 {
var user *gin.RouterGroup
if userPageEnabled {
user = router.Group(p+"/my", app.userAuth())
}
router.POST(p+"/logout", app.Logout) router.POST(p+"/logout", app.Logout)
api.DELETE(p+"/users", app.DeleteUsers) api.DELETE(p+"/users", app.DeleteUsers)
api.GET(p+"/users", app.GetUsers) api.GET(p+"/users", app.GetUsers)
@ -234,22 +233,22 @@ func (app *appContext) loadRoutes(router *gin.Engine) {
} }
if userPageEnabled { if userPageEnabled {
user.GET(p+"/details", app.MyDetails) user.GET("/details", app.MyDetails)
user.POST(p+"/contact", app.SetMyContactMethods) user.POST("/contact", app.SetMyContactMethods)
user.POST(p+"/logout", app.LogoutUser) user.POST("/logout", app.LogoutUser)
user.POST(p+"/email", app.ModifyMyEmail) user.POST("/email", app.ModifyMyEmail)
user.GET(p+"/discord/invite", app.MyDiscordServerInvite) user.GET("/discord/invite", app.MyDiscordServerInvite)
user.GET(p+"/pin/:service", app.GetMyPIN) user.GET("/pin/:service", app.GetMyPIN)
user.GET(p+"/discord/verified/:pin", app.MyDiscordVerifiedInvite) user.GET("/discord/verified/:pin", app.MyDiscordVerifiedInvite)
user.GET(p+"/telegram/verified/:pin", app.MyTelegramVerifiedInvite) user.GET("/telegram/verified/:pin", app.MyTelegramVerifiedInvite)
user.POST(p+"/matrix/user", app.MatrixSendMyPIN) user.POST("/matrix/user", app.MatrixSendMyPIN)
user.GET(p+"/matrix/verified/:userID/:pin", app.MatrixCheckMyPIN) user.GET("/matrix/verified/:userID/:pin", app.MatrixCheckMyPIN)
user.DELETE(p+"/discord", app.UnlinkMyDiscord) user.DELETE("/discord", app.UnlinkMyDiscord)
user.DELETE(p+"/telegram", app.UnlinkMyTelegram) user.DELETE("/telegram", app.UnlinkMyTelegram)
user.DELETE(p+"/matrix", app.UnlinkMyMatrix) user.DELETE("/matrix", app.UnlinkMyMatrix)
user.POST(p+"/password", app.ChangeMyPassword) user.POST("/password", app.ChangeMyPassword)
if app.config.Section("user_page").Key("referrals").MustBool(false) { if app.config.Section("user_page").Key("referrals").MustBool(false) {
user.GET(p+"/referral", app.GetMyReferral) user.GET("/referral", app.GetMyReferral)
} }
} }
} }

View File

@ -163,7 +163,7 @@ window.onpopstate = (event: PopStateEvent) => {
window.tabs.switch(event.state); window.tabs.switch(event.state);
} }
const login = new Login(window.modals.login as Modal, "/"); const login = new Login(window.modals.login as Modal, "/", window.loginAppearance);
login.onLogin = () => { login.onLogin = () => {
console.log("Logged in."); console.log("Logged in.");
window.updater = new Updater(); window.updater = new Updater();

View File

@ -8,13 +8,21 @@ export class Login {
private _endpoint: string; private _endpoint: string;
private _onLogin: (username: string, password: string) => void; private _onLogin: (username: string, password: string) => void;
private _logoutButton: HTMLElement = null; private _logoutButton: HTMLElement = null;
private _wall: HTMLElement;
private _hasOpacityWall: boolean = false;
constructor(modal: Modal, endpoint: string) { constructor(modal: Modal, endpoint: string, appearance: string) {
this._endpoint = endpoint; this._endpoint = endpoint;
this._url = window.URLBase + endpoint; this._url = window.URLBase + endpoint;
if (this._url[this._url.length-1] != '/') this._url += "/"; if (this._url[this._url.length-1] != '/') this._url += "/";
this._modal = modal; this._modal = modal;
if (appearance == "opaque") {
this._hasOpacityWall = true;
this._wall = document.createElement("div");
this._wall.classList.add("wall");
this._modal.asElement().parentElement.appendChild(this._wall);
}
this._form = this._modal.asElement().querySelector(".form-login") as HTMLFormElement; this._form = this._modal.asElement().querySelector(".form-login") as HTMLFormElement;
this._form.onsubmit = (event: SubmitEvent) => { this._form.onsubmit = (event: SubmitEvent) => {
event.preventDefault(); event.preventDefault();
@ -86,6 +94,7 @@ export class Login {
if (this._onLogin) { if (this._onLogin) {
this._onLogin(username, password); this._onLogin(username, password);
} }
if (this._hasOpacityWall) this._wall.remove();
this._modal.close(); this._modal.close();
if (this._logoutButton != null) if (this._logoutButton != null)
this._logoutButton.classList.remove("unfocused"); this._logoutButton.classList.remove("unfocused");

View File

@ -41,6 +41,7 @@ declare interface Window {
jfAdminOnly: boolean; jfAdminOnly: boolean;
jfAllowAll: boolean; jfAllowAll: boolean;
referralsEnabled: boolean; referralsEnabled: boolean;
loginAppearance: string;
} }
declare interface Update { declare interface Update {

View File

@ -556,7 +556,6 @@ changePasswordButton.addEventListener("click", () => {
} }
}); });
}); });
// FIXME: Submit & Validate
document.addEventListener("details-reload", () => { document.addEventListener("details-reload", () => {
_get("/my/details", null, (req: XMLHttpRequest) => { _get("/my/details", null, (req: XMLHttpRequest) => {
@ -645,7 +644,7 @@ document.addEventListener("details-reload", () => {
}); });
}); });
const login = new Login(window.modals.login as Modal, "/my/"); const login = new Login(window.modals.login as Modal, "/my/", "opaque");
login.onLogin = () => { login.onLogin = () => {
console.log("Logged in."); console.log("Logged in.");
document.querySelector(".page-container").classList.remove("unfocused"); document.querySelector(".page-container").classList.remove("unfocused");

View File

@ -175,7 +175,9 @@ func (app *appContext) AdminPage(gc *gin.Context) {
"jfAdminOnly": jfAdminOnly, "jfAdminOnly": jfAdminOnly,
"jfAllowAll": jfAllowAll, "jfAllowAll": jfAllowAll,
"userPageEnabled": app.config.Section("user_page").Key("enabled").MustBool(false), "userPageEnabled": app.config.Section("user_page").Key("enabled").MustBool(false),
"showUserPageLink": app.config.Section("user_page").Key("show_link").MustBool(true),
"referralsEnabled": app.config.Section("user_page").Key("enabled").MustBool(false) && app.config.Section("user_page").Key("referrals").MustBool(false), "referralsEnabled": app.config.Section("user_page").Key("enabled").MustBool(false) && app.config.Section("user_page").Key("referrals").MustBool(false),
"loginAppearance": app.config.Section("ui").Key("login_appearance").MustString("clear"),
}) })
} }