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

Compare commits

...

4 Commits

12 changed files with 89 additions and 28 deletions

View File

@ -274,6 +274,18 @@
"value": false,
"advanced": true,
"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",
"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": {
"name": "User Referrals",
"required": false,

View File

@ -15,6 +15,9 @@
--border-width-4: 5px;
--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";
--bg-light: #fff;
--bg-dark: #101010;
}
.light {
@ -26,11 +29,11 @@
}
.dark body {
background-color: #101010;
background-color: var(--bg-dark);
}
html:not(.dark) body {
background-color: #fff;
background-color: var(--bg-light);
}
.dark select, .dark option, .dark input {

View File

@ -10,6 +10,24 @@
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 {
float: right;
color: #aaa;

View File

@ -18,6 +18,7 @@
window.jfAdminOnly = {{ .jfAdminOnly }};
window.jfAllowAll = {{ .jfAllowAll }};
window.referralsEnabled = {{ .referralsEnabled }};
window.loginAppearance = "{{ .loginAppearance }}";
</script>
<title>Admin - jfa-go</title>
{{ template "header.html" . }}
@ -465,7 +466,7 @@
</div>
{{ if .userPageEnabled }}
<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>
{{ end }}
<div class="page-container">

View File

@ -7,6 +7,14 @@
</div>
{{ 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="">
<span class="heading">{{ .strings.login }}</span>
<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",
"userPagePage": "User Page: Page",
"buildTime": "Build Time",
"builtBy": "Built By"
"builtBy": "Built By",
"loginNotAdmin": "Not an Admin?"
},
"notifications": {
"changedEmailAddress": "Changed email address of {n}.",

View File

@ -160,12 +160,11 @@ func (app *appContext) loadRoutes(router *gin.Engine) {
api := router.Group("/", app.webAuth())
var user *gin.RouterGroup
if userPageEnabled {
user = router.Group("/my", app.userAuth())
}
for _, p := range routePrefixes {
var user *gin.RouterGroup
if userPageEnabled {
user = router.Group(p+"/my", app.userAuth())
}
router.POST(p+"/logout", app.Logout)
api.DELETE(p+"/users", app.DeleteUsers)
api.GET(p+"/users", app.GetUsers)
@ -234,22 +233,22 @@ func (app *appContext) loadRoutes(router *gin.Engine) {
}
if userPageEnabled {
user.GET(p+"/details", app.MyDetails)
user.POST(p+"/contact", app.SetMyContactMethods)
user.POST(p+"/logout", app.LogoutUser)
user.POST(p+"/email", app.ModifyMyEmail)
user.GET(p+"/discord/invite", app.MyDiscordServerInvite)
user.GET(p+"/pin/:service", app.GetMyPIN)
user.GET(p+"/discord/verified/:pin", app.MyDiscordVerifiedInvite)
user.GET(p+"/telegram/verified/:pin", app.MyTelegramVerifiedInvite)
user.POST(p+"/matrix/user", app.MatrixSendMyPIN)
user.GET(p+"/matrix/verified/:userID/:pin", app.MatrixCheckMyPIN)
user.DELETE(p+"/discord", app.UnlinkMyDiscord)
user.DELETE(p+"/telegram", app.UnlinkMyTelegram)
user.DELETE(p+"/matrix", app.UnlinkMyMatrix)
user.POST(p+"/password", app.ChangeMyPassword)
user.GET("/details", app.MyDetails)
user.POST("/contact", app.SetMyContactMethods)
user.POST("/logout", app.LogoutUser)
user.POST("/email", app.ModifyMyEmail)
user.GET("/discord/invite", app.MyDiscordServerInvite)
user.GET("/pin/:service", app.GetMyPIN)
user.GET("/discord/verified/:pin", app.MyDiscordVerifiedInvite)
user.GET("/telegram/verified/:pin", app.MyTelegramVerifiedInvite)
user.POST("/matrix/user", app.MatrixSendMyPIN)
user.GET("/matrix/verified/:userID/:pin", app.MatrixCheckMyPIN)
user.DELETE("/discord", app.UnlinkMyDiscord)
user.DELETE("/telegram", app.UnlinkMyTelegram)
user.DELETE("/matrix", app.UnlinkMyMatrix)
user.POST("/password", app.ChangeMyPassword)
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);
}
const login = new Login(window.modals.login as Modal, "/");
const login = new Login(window.modals.login as Modal, "/", window.loginAppearance);
login.onLogin = () => {
console.log("Logged in.");
window.updater = new Updater();

View File

@ -8,13 +8,21 @@ export class Login {
private _endpoint: string;
private _onLogin: (username: string, password: string) => void;
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._url = window.URLBase + endpoint;
if (this._url[this._url.length-1] != '/') this._url += "/";
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.onsubmit = (event: SubmitEvent) => {
event.preventDefault();
@ -86,6 +94,7 @@ export class Login {
if (this._onLogin) {
this._onLogin(username, password);
}
if (this._hasOpacityWall) this._wall.remove();
this._modal.close();
if (this._logoutButton != null)
this._logoutButton.classList.remove("unfocused");

View File

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

View File

@ -556,7 +556,6 @@ changePasswordButton.addEventListener("click", () => {
}
});
});
// FIXME: Submit & Validate
document.addEventListener("details-reload", () => {
_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 = () => {
console.log("Logged in.");
document.querySelector(".page-container").classList.remove("unfocused");

View File

@ -175,7 +175,9 @@ func (app *appContext) AdminPage(gc *gin.Context) {
"jfAdminOnly": jfAdminOnly,
"jfAllowAll": jfAllowAll,
"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),
"loginAppearance": app.config.Section("ui").Key("login_appearance").MustString("clear"),
})
}