mirror of
https://github.com/hrfee/jfa-go.git
synced 2025-01-03 15:00:12 +00:00
Fix bug with invites in webui, add profile selector
invite codes starting with a digit don't work with the webui, so GenerateInvite regenerates uuids until theres one that doesn't.
This commit is contained in:
parent
32b8ed4aa2
commit
b6ceee508c
10
api.go
10
api.go
@ -3,6 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -399,7 +400,13 @@ func (app *appContext) GenerateInvite(gc *gin.Context) {
|
|||||||
current_time := time.Now()
|
current_time := time.Now()
|
||||||
valid_till := current_time.AddDate(0, 0, req.Days)
|
valid_till := current_time.AddDate(0, 0, req.Days)
|
||||||
valid_till = valid_till.Add(time.Hour*time.Duration(req.Hours) + time.Minute*time.Duration(req.Minutes))
|
valid_till = valid_till.Add(time.Hour*time.Duration(req.Hours) + time.Minute*time.Duration(req.Minutes))
|
||||||
|
// make sure code doesn't begin with number
|
||||||
invite_code := shortuuid.New()
|
invite_code := shortuuid.New()
|
||||||
|
_, err := strconv.Atoi(string(invite_code[0]))
|
||||||
|
for err == nil {
|
||||||
|
invite_code = shortuuid.New()
|
||||||
|
_, err = strconv.Atoi(string(invite_code[0]))
|
||||||
|
}
|
||||||
var invite Invite
|
var invite Invite
|
||||||
invite.Created = current_time
|
invite.Created = current_time
|
||||||
if req.MultipleUses {
|
if req.MultipleUses {
|
||||||
@ -449,7 +456,8 @@ func (app *appContext) SetProfile(gc *gin.Context) {
|
|||||||
var req profileReq
|
var req profileReq
|
||||||
gc.BindJSON(&req)
|
gc.BindJSON(&req)
|
||||||
app.debug.Printf("%s: Setting profile to \"%s\"", req.Invite, req.Profile)
|
app.debug.Printf("%s: Setting profile to \"%s\"", req.Invite, req.Profile)
|
||||||
if _, ok := app.storage.profiles[req.Profile]; !ok {
|
// "" means "Don't apply profile"
|
||||||
|
if _, ok := app.storage.profiles[req.Profile]; !ok && req.Profile != "" {
|
||||||
app.err.Printf("%s: Profile \"%s\" not found", req.Invite, req.Profile)
|
app.err.Printf("%s: Profile \"%s\" not found", req.Invite, req.Profile)
|
||||||
respond(500, "Profile not found", gc)
|
respond(500, "Profile not found", gc)
|
||||||
return
|
return
|
||||||
|
@ -365,6 +365,11 @@
|
|||||||
</label>
|
</label>
|
||||||
<div id="noLimitWarning" class="form-text" style="display: none;">Warning: Unlimited usage invites pose a risk if published online.</div>
|
<div id="noLimitWarning" class="form-text" style="display: none;">Warning: Unlimited usage invites pose a risk if published online.</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group" style="margin-bottom: 1rem;">
|
||||||
|
<label for="inviteProfile">Account creation profile</label>
|
||||||
|
<select class="form-control form-select" id="inviteProfile" name="profile">
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
{{ if .email_enabled }}
|
{{ if .email_enabled }}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="send_to_address">Send invite to address</label>
|
<label for="send_to_address">Send invite to address</label>
|
||||||
|
11
main.go
11
main.go
@ -334,6 +334,17 @@ func start(asDaemon, firstCall bool) {
|
|||||||
if !(len(app.storage.policy) == 0 && len(app.storage.configuration) == 0 && len(app.storage.displayprefs) == 0) {
|
if !(len(app.storage.policy) == 0 && len(app.storage.configuration) == 0 && len(app.storage.displayprefs) == 0) {
|
||||||
app.info.Println("Migrating user template files to new profile format")
|
app.info.Println("Migrating user template files to new profile format")
|
||||||
app.storage.migrateToProfile()
|
app.storage.migrateToProfile()
|
||||||
|
for _, path := range [3]string{app.storage.policy_path, app.storage.configuration_path, app.storage.displayprefs_path} {
|
||||||
|
if _, err := os.Stat(path); !os.IsNotExist(err) {
|
||||||
|
dir, fname := filepath.Split(path)
|
||||||
|
newFname := strings.Replace(fname, ".json", ".old.json", 1)
|
||||||
|
err := os.Rename(path, filepath.Join(dir, newFname))
|
||||||
|
if err != nil {
|
||||||
|
app.err.Fatalf("Failed to rename %s: %s", fname, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
app.info.Println("In case of a problem, your original files have been renamed to <file>.old.json")
|
||||||
app.storage.storeProfiles()
|
app.storage.storeProfiles()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,19 +142,15 @@ function addItem(invite: Invite): void {
|
|||||||
let profiles = `
|
let profiles = `
|
||||||
<label class="input-group-text" for="profile_${CSS.escape(invite.code)}">Profile: </label>
|
<label class="input-group-text" for="profile_${CSS.escape(invite.code)}">Profile: </label>
|
||||||
<select class="form-select" id="profile_${CSS.escape(invite.code)}" onchange="setProfile(this)">
|
<select class="form-select" id="profile_${CSS.escape(invite.code)}" onchange="setProfile(this)">
|
||||||
|
<option value="NoProfile" selected>No Profile</option>
|
||||||
`;
|
`;
|
||||||
let match = false;
|
|
||||||
for (const i in availableProfiles) {
|
for (const i in availableProfiles) {
|
||||||
let selected = "";
|
let selected = "";
|
||||||
if (availableProfiles[i] == invite.profile) {
|
if (availableProfiles[i] == invite.profile) {
|
||||||
selected = "selected";
|
selected = "selected";
|
||||||
match = true;
|
|
||||||
}
|
}
|
||||||
profiles += `<option value="${availableProfiles[i]}" ${selected}>${availableProfiles[i]}</option>`;
|
profiles += `<option value="${availableProfiles[i]}" ${selected}>${availableProfiles[i]}</option>`;
|
||||||
}
|
}
|
||||||
if (!match) {
|
|
||||||
profiles += `<option value="" selected></option>`;
|
|
||||||
}
|
|
||||||
profiles += `</select>`;
|
profiles += `</select>`;
|
||||||
|
|
||||||
let dateCreated: string;
|
let dateCreated: string;
|
||||||
@ -209,7 +205,7 @@ function addItem(invite: Invite): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function updateInvite(invite: Invite): void {
|
function updateInvite(invite: Invite): void {
|
||||||
document.getElementById(CSS.escape(invite.code) + "_expiry").textContent = invite.expiresIn;
|
document.getElementById(invite.code + "_expiry").textContent = invite.expiresIn;
|
||||||
const remainingUses: any = document.getElementById(CSS.escape(invite.code) + "_remainingUses");
|
const remainingUses: any = document.getElementById(CSS.escape(invite.code) + "_remainingUses");
|
||||||
if (remainingUses) {
|
if (remainingUses) {
|
||||||
remainingUses.textContent = `Remaining uses: ${invite.remainingUses}`;
|
remainingUses.textContent = `Remaining uses: ${invite.remainingUses}`;
|
||||||
@ -237,6 +233,18 @@ function generateInvites(empty?: boolean): void {
|
|||||||
if (this.readyState == 4) {
|
if (this.readyState == 4) {
|
||||||
let data = this.response;
|
let data = this.response;
|
||||||
availableProfiles = data['profiles'];
|
availableProfiles = data['profiles'];
|
||||||
|
const Profiles = document.getElementById('inviteProfile') as HTMLSelectElement;
|
||||||
|
let innerHTML = "";
|
||||||
|
for (let i = 0; i < availableProfiles.length; i++) {
|
||||||
|
const profile = availableProfiles[i];
|
||||||
|
innerHTML += `
|
||||||
|
<option value="${profile}" ${(i == 0) ? "selected" : ""}>${profile}</option>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
innerHTML += `
|
||||||
|
<option value="NoProfile" ${(availableProfiles.length == 0) ? "selected" : ""}>No Profile</option>
|
||||||
|
`;
|
||||||
|
Profiles.innerHTML = innerHTML;
|
||||||
if (data['invites'] == null || data['invites'].length == 0) {
|
if (data['invites'] == null || data['invites'].length == 0) {
|
||||||
document.getElementById('invites').textContent = '';
|
document.getElementById('invites').textContent = '';
|
||||||
addItem(emptyInvite());
|
addItem(emptyInvite());
|
||||||
@ -311,6 +319,9 @@ fixCheckboxes();
|
|||||||
if (!send['multiple-uses'] || send['no-limit']) {
|
if (!send['multiple-uses'] || send['no-limit']) {
|
||||||
delete send['remaining-uses'];
|
delete send['remaining-uses'];
|
||||||
}
|
}
|
||||||
|
if (send["profile"] == "NoProfile") {
|
||||||
|
send["profile"] = "";
|
||||||
|
}
|
||||||
const sendToAddress: any = document.getElementById('send_to_address');
|
const sendToAddress: any = document.getElementById('send_to_address');
|
||||||
const sendToAddressEnabled: any = document.getElementById('send_to_address_enabled');
|
const sendToAddressEnabled: any = document.getElementById('send_to_address_enabled');
|
||||||
if (sendToAddress && sendToAddressEnabled) {
|
if (sendToAddress && sendToAddressEnabled) {
|
||||||
@ -318,6 +329,7 @@ fixCheckboxes();
|
|||||||
delete send['send_to_address'];
|
delete send['send_to_address'];
|
||||||
delete send['send_to_address_enabled'];
|
delete send['send_to_address_enabled'];
|
||||||
}
|
}
|
||||||
|
console.log(send);
|
||||||
_post("/generateInvite", send, function (): void {
|
_post("/generateInvite", send, function (): void {
|
||||||
if (this.readyState == 4) {
|
if (this.readyState == 4) {
|
||||||
button.textContent = 'Generate';
|
button.textContent = 'Generate';
|
||||||
@ -334,10 +346,14 @@ function setProfile(select: HTMLSelectElement): void {
|
|||||||
if (!select.value) {
|
if (!select.value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
let val = select.value;
|
||||||
|
if (select.value == "NoProfile") {
|
||||||
|
val = ""
|
||||||
|
}
|
||||||
const invite = select.id.replace("profile_", "");
|
const invite = select.id.replace("profile_", "");
|
||||||
const send = {
|
const send = {
|
||||||
"invite": invite,
|
"invite": invite,
|
||||||
"profile": select.value
|
"profile": val
|
||||||
};
|
};
|
||||||
_post("/setProfile", send, function (): void {
|
_post("/setProfile", send, function (): void {
|
||||||
if (this.readyState == 4 && this.status != 200) {
|
if (this.readyState == 4 && this.status != 200) {
|
||||||
|
@ -22,11 +22,12 @@ function serializeForm(id: string): Object {
|
|||||||
break;
|
break;
|
||||||
case "select-one":
|
case "select-one":
|
||||||
case "select":
|
case "select":
|
||||||
let val: string | number = (el as HTMLSelectElement).value;
|
let val: string = (el as HTMLSelectElement).value.toString();
|
||||||
if (+val != NaN) {
|
if (!isNaN(val as any)) {
|
||||||
val = +val;
|
formData[name] = +val;
|
||||||
}
|
} else {
|
||||||
formData[name] = val;
|
formData[name] = val;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user