Skip to content

Commit a7e17d7

Browse files
committed
can edit admins
1 parent 45afdea commit a7e17d7

File tree

6 files changed

+120
-35
lines changed

6 files changed

+120
-35
lines changed

app/authorize.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ module.exports = function authorize(cookie, privateKey, accessLevel){
1515
if(err || decoded.level < accessLevel){
1616
passed = false;
1717
}
18-
resolve(passed);
18+
resolve({passed, token: decoded});
1919
});
2020
}
2121
catch{
22-
resolve(false);
22+
resolve({passed: false});
2323
}
2424
});
2525
}

app/routes/changeAdmin.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
const Database = require('../services/database');
2+
const bcrypt = require('bcrypt');
3+
const util = require('util');
4+
const saltRounds = 10;
5+
const hash = util.promisify(bcrypt.hash);
6+
7+
module.exports = {
8+
path: '/api/changeAdmin',
9+
method: 'POST',
10+
accessLevel: 1,
11+
handler: async (request, responce) => {
12+
const json = await JSON.parse(request.body);
13+
let player = await Database.admins.get(json.name);
14+
if(json.password){
15+
if(request.token.level != 3 && request.token.name != json.name){
16+
responce.status(403).text('Forbidden.')
17+
return;
18+
}
19+
player.password = await hash(json.password, saltRounds);
20+
responce.setHeader('Set-Cookie', [`jwt=; Secure; HttpOnly`])
21+
}
22+
if(json.level){
23+
if(request.token.level != 3){
24+
responce.status(403).text('Forbidden.')
25+
return;
26+
}
27+
player.level = json.level;
28+
}
29+
await Database.admins.update(json.name, player);
30+
responce.status(200).text('Admin changed.')
31+
}
32+
}

app/server.js

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,12 @@ function startAdminServer(){
7878
if(routes[i].path == path && routes[i].method == request.method){
7979
if(!routes[i].public){
8080
authorize(request.headers.cookie, key, routes[i].accessLevel || 2).then(result => {
81-
if(result){
81+
if(result.passed){
8282
routes[i].handler(
8383
{
8484
headers: request.headers,
85-
body: buffer
85+
body: buffer,
86+
token: result.token
8687
},
8788
new Responce(responce)
8889
);
@@ -140,38 +141,35 @@ startAdminServer();
140141
SSL.watch(server, startAdminServer);
141142

142143
class Responce{
143-
_status = 200;
144+
_headers = {};
144145

145146
constructor(responce){
146147
this.responce = responce;
147148
}
148149
status(status){
149-
this._status = status;
150+
this.setHeader(':status', status);
150151
return this;
151152
}
152153
json(json){
153-
this.responce.stream.respond({
154-
'content-type': 'application/json; charset=utf-8',
155-
':status': this._status
156-
});
154+
this.setHeader('content-type', 'application/json; charset=utf-8');
155+
this.responce.stream.respond(this._headers);
157156
this.responce.stream.end(JSON.stringify(json));
158157
}
159158
text(text){
160-
this.responce.stream.respond({
161-
'content-type': 'text/plain; charset=utf-8',
162-
':status': this._status
163-
});
159+
this.setHeader('content-type', 'text/plain; charset=utf-8');
160+
this.responce.stream.respond(this._headers);
164161
this.responce.stream.end(text);
165162
}
166163
eventstream(){
167-
this.responce.stream.respond({
168-
'content-type': 'text/event-stream',
169-
'cache-controll': 'no-cache',
170-
':status': this._status
171-
});
164+
this.setHeader('content-type', 'text/event-stream');
165+
this.setHeader('cache-controll', 'no-cache');
166+
this.responce.stream.respond(this._headers);
172167
return this;
173168
}
174169
write(data){
175170
this.responce.stream.write(data);
176171
}
172+
setHeader(header, value){
173+
this._headers[header] = value;
174+
}
177175
}

svelte/src/EnumInput.svelte

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22
export let name;
33
export let value;
44
export let options;
5+
export let optionsDisplay;
56
</script>
67

78
<div>
89
<label for={name}>{name}</label>
910
<select bind:value={value} type="text" name={name} id={name}>
10-
{#each options as option}
11-
<option value={option}>{option}</option>
11+
{#each options as option, i}
12+
<option value={option}>{optionsDisplay[i] || option}</option>
1213
{/each}
1314
</select>
1415
</div>

svelte/src/TextInput.svelte

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
<script>
22
export let value;
33
export let name;
4+
export let password;
45
</script>
56

67
<div>
78
<div class="wr">
89
<label for={name}><slot></slot></label>
9-
<input bind:value type="text" {name} id={name}>
10+
{#if password}
11+
<input bind:value type="password" {name} id={name}>
12+
{:else}
13+
<input bind:value type="text" {name} id={name}>
14+
{/if}
1015
</div>
1116
</div>
1217

svelte/src/pages/Settings.svelte

Lines changed: 62 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import IntInput from '../IntInput.svelte';
77
import BoolInput from '../BoolInput.svelte';
88
import defaultSettings from '../../../app/defaultSettings.js';
9+
import IconButton from '../IconButton.svelte';
910
1011
const tabs = ['General', 'Game Settings', 'Backups', 'Player Permissions', 'Advanced', 'Admins'];
1112
let currentTab = 0;
@@ -88,6 +89,29 @@
8889
.then(json => {
8990
admins = json;
9091
});
92+
93+
let permissionLevel = 3;
94+
let isEditingAdmin = false;
95+
let editingAdmin = {};
96+
function editAdmin(id){
97+
isEditingAdmin = true;
98+
editingAdmin.id = id;
99+
editingAdmin.name = admins[id].name;
100+
editingAdmin.level = admins[id].level;
101+
}
102+
function sendEditAdmin(){
103+
let body = {
104+
name: editingAdmin.name,
105+
level: editingAdmin.level
106+
};
107+
if(editingAdmin.settingPassword && editingAdmin.password == editingAdmin.confirmPassword) {
108+
body.password = editingAdmin.password;
109+
}
110+
fetch(`/api/changeAdmin`, {cache: 'no-cache', method: 'post', headers: {'Content-Type': 'text/json'}, body: JSON.stringify(body)})
111+
.then(response => {
112+
113+
});
114+
}
91115
</script>
92116

93117
<div class="main" in:fly="{{ x: 200, duration: 600 }}" out:fly="{{ x: -200, duration: 600 }}">
@@ -164,20 +188,45 @@
164188
<BoolInput bind:value={settings.texturepackRequired} name="Texturepack Required"></BoolInput>
165189
<BoolInput bind:value={settings.contentLogFileEnabled} name="Content Log File Enabled"></BoolInput>
166190
{:else if currentTab == 5}
167-
{#each admins as admin}
168-
<div class='admin'>
169-
<p class='admin-name'>{admin.name}</p>
170-
<p class='admin-level'>
171-
{#if admins.level == 1}
172-
Player Manager
173-
{:else if admins.level == 2}
174-
Server Manager
175-
{:else if admin.level == 3}
176-
Owner
177-
{/if}
178-
</p>
191+
{#if isEditingAdmin}
192+
<div>
193+
<p class='admin-name'>{editingAdmin.name}</p>
194+
{#if permissionLevel == 3}
195+
<EnumInput bind:value={editingAdmin.level} name="Role" options={[1, 2, 3]} optionsDisplay={['Player Manager', 'Server Manager', 'Owner']}></EnumInput>
196+
{/if}
197+
{#if editingAdmin.settingPassword}
198+
<TextInput name="password" bind:value={editingAdmin.password} password>Set Password</TextInput>
199+
<TextInput name="confirm password" bind:value={editingAdmin.confirmPassword} password>Confirm Password</TextInput>
200+
{:else}
201+
<Button on:click={() => {editingAdmin.settingPassword = true}}>Set New Password</Button>
202+
{/if}
203+
<Button>Delete Admin</Button>
204+
<div>
205+
<button on:click={sendEditAdmin} style="float: left; width:50%;">Confirm</button>
206+
<button on:click={()=>{isEditingAdmin = false}} style="float: right; width:50%;">Cancel</button>
207+
</div>
179208
</div>
180-
{/each}
209+
{:else}
210+
{#each admins as admin, i}
211+
<div class='admin'>
212+
<div style="float: left; margin-right: 20px">
213+
<p class='admin-name'>{admin.name}</p>
214+
<p class='admin-level'>
215+
{#if admin.level == 1}
216+
Player Manager
217+
{:else if admin.level == 2}
218+
Server Manager
219+
{:else if admin.level == 3}
220+
Owner
221+
{/if}
222+
</p>
223+
</div>
224+
{#if permissionLevel === 3}
225+
<IconButton style="float: right; margin-top: 10px;" src="/icons/edit.svg" on:click={() => {if(permissionLevel === 3) editAdmin(i)}}></IconButton>
226+
{/if}
227+
</div>
228+
{/each}
229+
{/if}
181230
{/if}
182231
{#if unsavedChanged}
183232
<Button on:click={saveSettings}>Save Settings</Button>

0 commit comments

Comments
 (0)