changepermissions & 1 rankserver
This commit is contained in:
Generated
+3
-3
@@ -6130,9 +6130,9 @@
|
||||
}
|
||||
},
|
||||
"rpclibrary": {
|
||||
"version": "1.8.3",
|
||||
"resolved": "https://registry.npmjs.org/rpclibrary/-/rpclibrary-1.8.3.tgz",
|
||||
"integrity": "sha512-8pQRbMXQKCf3+v+XM01d+1Bw73pg5YzgyhW/ACpYON1I4re5fZAjWGPyLc+ms+MlYQIlKc3Uk92PGot2sbb85Q==",
|
||||
"version": "1.9.2",
|
||||
"resolved": "https://registry.npmjs.org/rpclibrary/-/rpclibrary-1.9.2.tgz",
|
||||
"integrity": "sha512-MOtVm0IBRLryXag1IwkYNPVFegbvW10+MbCjhr3GptO3MA7nHZ545ammgoCWnREtGOgFeN4Jib/EBDOJ9Ep41Q==",
|
||||
"requires": {
|
||||
"bsock": "^0.1.9",
|
||||
"http": "0.0.0",
|
||||
|
||||
+1
-1
@@ -45,7 +45,7 @@
|
||||
"path": "^0.12.7",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"rimraf": "^3.0.0",
|
||||
"rpclibrary": "^1.8.3",
|
||||
"rpclibrary": "^1.9.2",
|
||||
"simple-git": "^1.124.0",
|
||||
"spawn-sync": "^2.0.0",
|
||||
"sqlite3": "^4.1.1",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { RPCServer, Socket } from "rpclibrary";
|
||||
import { RPCServer, Socket, RPCInterface } from "rpclibrary";
|
||||
import { Inject, Injectable } from "../../Injector/ServiceDecorator";
|
||||
import { FrontworkAdmin } from "../../Admin/Admin";
|
||||
import { GuildManager } from "../Guild/GuildManager";
|
||||
@@ -23,10 +23,9 @@ const uuid = require('uuid/v4')
|
||||
const salt = "6pIbc6yjSN"
|
||||
const ONE_WEEK = 604800000
|
||||
|
||||
type Serverstate = {
|
||||
server: RPCServer,
|
||||
type Serverstate<SubresT, InterfaceT extends RPCInterface> = {
|
||||
server: RPCServer<SubresT, InterfaceT>,
|
||||
port : number,
|
||||
allowed: string[]
|
||||
};
|
||||
|
||||
|
||||
@@ -51,8 +50,9 @@ implements FrontworkComponent<UserManagerIfc, UserManagerFeatureIfc>, IUserManag
|
||||
private character : CharacterManager
|
||||
|
||||
exporters :any[] = []
|
||||
rankServers : {[rank in Rank] : Serverstate}
|
||||
rankServer : Serverstate<{}, FrontcraftFeatureIfc>
|
||||
userLogins : {[username in string] : UserRecord} = {}
|
||||
allowed: string[] = []
|
||||
|
||||
exportRPCs = () => [
|
||||
this.login,
|
||||
@@ -145,19 +145,11 @@ implements FrontworkComponent<UserManagerIfc, UserManagerFeatureIfc>, IUserManag
|
||||
}
|
||||
})))
|
||||
|
||||
//start rankServers
|
||||
let rankServers = { } as any
|
||||
await Promise.all(_Rank.map(async (r,i) => {
|
||||
const port = 20001 + i
|
||||
const rankServer = await this.startRankServer(r, port)
|
||||
rankServers[r] = {
|
||||
server: rankServer,
|
||||
port: port,
|
||||
allowed: []
|
||||
}
|
||||
}))
|
||||
this.rankServers = rankServers
|
||||
getLogger('UserManager').debug(Object.values(this.rankServers).length+" rank servers started")
|
||||
const rankServer = await this.startRankServer(20001)
|
||||
this.rankServer = {
|
||||
server: rankServer,
|
||||
port: 20001
|
||||
}
|
||||
setInterval(this.checkExpiredSessions, 600_000)
|
||||
}
|
||||
|
||||
@@ -166,20 +158,17 @@ implements FrontworkComponent<UserManagerIfc, UserManagerFeatureIfc>, IUserManag
|
||||
Object.values(x.connections).forEach(c => c.destroy())
|
||||
})
|
||||
|
||||
Object.values(this.rankServers)
|
||||
.map(state => {
|
||||
try{
|
||||
return state.server.destroy()
|
||||
}catch(e){
|
||||
getLogger('UserManager').warn(e)
|
||||
}
|
||||
})
|
||||
try{
|
||||
return this.rankServer.server.destroy()
|
||||
}catch(e){
|
||||
//getLogger('UserManager').warn(e)
|
||||
}
|
||||
}
|
||||
|
||||
checkExpiredSessions = () => {
|
||||
Object.values(this.userLogins).map(userLogin => {
|
||||
const auth = userLogin.auth
|
||||
if(!this.checkToken(auth.token.value, auth.user.rank)){
|
||||
if(!this.checkToken(auth.token.value)){
|
||||
this.logout(auth.user.username, auth.token.value)
|
||||
}
|
||||
})
|
||||
@@ -232,6 +221,13 @@ implements FrontworkComponent<UserManagerIfc, UserManagerFeatureIfc>, IUserManag
|
||||
await this.admin.knex('rpcpermissions')
|
||||
.where('rpcname', '=', permission.rpcname)
|
||||
.update(permission)
|
||||
|
||||
await Promise.all(
|
||||
Object.entries(this.userLogins).map(([username, record]) => {
|
||||
if(record.user.rank === "ADMIN") return
|
||||
return this.adminLogout(username)
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
getPermissions = async () : Promise<RPCPermission[]> => {
|
||||
@@ -313,15 +309,10 @@ implements FrontworkComponent<UserManagerIfc, UserManagerFeatureIfc>, IUserManag
|
||||
await sock.call('kick')
|
||||
}))
|
||||
|
||||
Object.values(this.rankServers)
|
||||
.forEach(state => {
|
||||
state.allowed = state.allowed.filter(allowed => allowed !== this.userLogins[username].auth.token.value)
|
||||
})
|
||||
this.allowed = this.allowed.filter(allowed => allowed !== this.userLogins[username].auth.token.value)
|
||||
delete this.userLogins[username]
|
||||
}
|
||||
}catch(e){
|
||||
getLogger('UserManager').warn(e)
|
||||
}
|
||||
}catch(e){}
|
||||
}
|
||||
|
||||
wipeCurrency = async () => {
|
||||
@@ -356,11 +347,11 @@ implements FrontworkComponent<UserManagerIfc, UserManagerFeatureIfc>, IUserManag
|
||||
const userAuth : Auth = {
|
||||
token: token,
|
||||
user: user,
|
||||
port: this.rankServers[user.rank].port
|
||||
port: this.rankServer.port
|
||||
}
|
||||
|
||||
this.userLogins[user.username] = {connections: {}, auth: userAuth, user:user}
|
||||
this.rankServers[user.rank].allowed.push(token.value)
|
||||
this.allowed.push(token.value)
|
||||
return userAuth
|
||||
}
|
||||
|
||||
@@ -378,49 +369,43 @@ implements FrontworkComponent<UserManagerIfc, UserManagerFeatureIfc>, IUserManag
|
||||
return
|
||||
}
|
||||
|
||||
startRankServer = async (rank : Rank, port: number) : Promise<RPCServer> => {
|
||||
startRankServer = async (port: number) : Promise<RPCServer<{},FrontcraftFeatureIfc>> => {
|
||||
let rpcs = [
|
||||
...this.exportRPCFeatures(),
|
||||
...this.exporters.flatMap((exp) => exp.exportRPCFeatures())
|
||||
]
|
||||
let rpcServer = new RPCServer<{},FrontcraftFeatureIfc>(port, rpcs, {
|
||||
accessFilter: async (sesame, exporter) => {
|
||||
const record = this.getUserRecordByToken(sesame!)
|
||||
if(!record) return false
|
||||
return await this.getPermission(exporter.name, record.user.rank)
|
||||
},
|
||||
closeHandler: (socket) => {
|
||||
Object.values(this.userLogins)
|
||||
.forEach(login => delete login.connections[socket.port])
|
||||
|
||||
const allowedRPCs = await this.getRPCForRank(rank)
|
||||
let rpcServer
|
||||
let n = 0
|
||||
while(!rpcServer){
|
||||
n++
|
||||
await Promise.race([
|
||||
new Promise((res, rej) => {
|
||||
rpcServer = new RPCServer(port, allowedRPCs, {
|
||||
closeHandler: (socket) => {
|
||||
Object.values(this.userLogins)
|
||||
.forEach(login => delete login.connections[socket.port])
|
||||
},
|
||||
connectionHandler: (socket) => {
|
||||
this.checkConnection(socket).then(res => {
|
||||
if(!res){
|
||||
socket.destroy();
|
||||
}
|
||||
}).catch((e) => {
|
||||
socket.destroy();
|
||||
})
|
||||
},
|
||||
errorHandler: (socket, e, rpcName, args) => {
|
||||
getLogger('UserManager').error(rpcName, args, e);
|
||||
},
|
||||
sesame: (sesame) => this.checkToken(sesame),
|
||||
visibility: '0.0.0.0'
|
||||
})
|
||||
|
||||
},
|
||||
connectionHandler: (socket) => {
|
||||
this.checkConnection(socket).then(res => {
|
||||
if(!res){
|
||||
socket.destroy();
|
||||
}
|
||||
}).catch((e) => {
|
||||
socket.destroy();
|
||||
getLogger('UserManager').warn(e);
|
||||
})
|
||||
},
|
||||
errorHandler: (socket, e, rpcName, args) => {
|
||||
getLogger('UserManager').error(rpcName, args, e);
|
||||
},
|
||||
sesame: (sesame) => this.checkToken(sesame, rank),
|
||||
visibility: '0.0.0.0'
|
||||
})
|
||||
res()
|
||||
}),
|
||||
new Promise((res, rej) => setTimeout(res, 500))
|
||||
])
|
||||
if(!rpcServer && n>1)
|
||||
getLogger('UserManager').warn("createServer retry nr.", n, 'port', port)
|
||||
}
|
||||
return rpcServer
|
||||
}
|
||||
|
||||
checkToken = (token: string, rank: Rank) : boolean => this.rankServers[rank].allowed.includes(token)
|
||||
&& Object.values(this.userLogins).find(login => login.auth.token.value === token)!.auth.token.created > Date.now() - ONE_WEEK
|
||||
checkToken = (token: string) : boolean => this.allowed.includes(token)
|
||||
&& Object.values(this.userLogins).find(login => login.auth.token.value === token)!.auth.token.created > Date.now() - ONE_WEEK
|
||||
|
||||
checkTokenOwnedByUser = (username: string, tokenValue: string) => {
|
||||
username = username.toLowerCase()
|
||||
|
||||
Generated
+3
-3
@@ -17940,9 +17940,9 @@
|
||||
"integrity": "sha512-ZYzRkETgBrdEGzL5JSKimvjI2CX7ioyZCkX2BpcfyjqI+079W0wHAyj5W4rIZMcDSOHgLZtgz1IdDi/vU77KEQ=="
|
||||
},
|
||||
"rpclibrary": {
|
||||
"version": "1.8.3",
|
||||
"resolved": "https://registry.npmjs.org/rpclibrary/-/rpclibrary-1.8.3.tgz",
|
||||
"integrity": "sha512-8pQRbMXQKCf3+v+XM01d+1Bw73pg5YzgyhW/ACpYON1I4re5fZAjWGPyLc+ms+MlYQIlKc3Uk92PGot2sbb85Q==",
|
||||
"version": "1.9.2",
|
||||
"resolved": "https://registry.npmjs.org/rpclibrary/-/rpclibrary-1.9.2.tgz",
|
||||
"integrity": "sha512-MOtVm0IBRLryXag1IwkYNPVFegbvW10+MbCjhr3GptO3MA7nHZ545ammgoCWnREtGOgFeN4Jib/EBDOJ9Ep41Q==",
|
||||
"requires": {
|
||||
"bsock": "^0.1.9",
|
||||
"http": "0.0.0",
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
"normalize.css": "6.0.0",
|
||||
"pace-js": "1.0.2",
|
||||
"roboto-fontface": "0.8.0",
|
||||
"rpclibrary": "^1.8.3",
|
||||
"rpclibrary": "^1.9.2",
|
||||
"rxjs": "6.5.2",
|
||||
"rxjs-compat": "6.3.0",
|
||||
"socicon": "3.0.5",
|
||||
|
||||
@@ -9,7 +9,11 @@
|
||||
|
||||
<div class="header-container">
|
||||
<nb-actions size="small">
|
||||
|
||||
<nb-action
|
||||
*ngIf="modifyPermissions"
|
||||
icon="settings-2-outline"
|
||||
link="/permissions">
|
||||
</nb-action>
|
||||
<nb-action
|
||||
*ngIf="!newmessage"
|
||||
icon="message-square-outline"
|
||||
|
||||
@@ -48,6 +48,7 @@ export class HeaderComponent implements OnInit, OnDestroy {
|
||||
chatlog: ShoutMessage[] = []
|
||||
newmessage = false
|
||||
lastmessage = "asdasd"
|
||||
modifyPermissions
|
||||
|
||||
constructor(private sidebarService: NbSidebarService,
|
||||
private router: Router,
|
||||
@@ -62,7 +63,7 @@ export class HeaderComponent implements OnInit, OnDestroy {
|
||||
this.themeService.changeTheme("dark");
|
||||
|
||||
this.currentTheme = this.themeService.currentTheme;
|
||||
|
||||
this.modifyPermissions = this.api.get('modifyPermissions')
|
||||
this.user = this.api.getCurrentUser()
|
||||
if(this.user)
|
||||
this.userMenu.unshift({ title: 'Profile', link: '/frontcraft/user/'+this.user.username });
|
||||
|
||||
@@ -2,7 +2,11 @@ import { ExtraOptions, RouterModule, Routes } from '@angular/router';
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
const routes: Routes = [
|
||||
|
||||
{
|
||||
path: 'permissions',
|
||||
loadChildren: () => import('./frontcraft/permissions/permissions.module')
|
||||
.then(m => m.PermissionsModule),
|
||||
},
|
||||
{
|
||||
path: 'auth',
|
||||
loadChildren: () => import('./frontcraft/auth/auth.module')
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
<nb-card>
|
||||
<nb-card-body>
|
||||
<table>
|
||||
<tr>
|
||||
<th>
|
||||
Name
|
||||
</th>
|
||||
<th *ngFor="let rank of ranks">
|
||||
{{rank}}
|
||||
</th>
|
||||
</tr>
|
||||
<tr *ngFor="let perm of permissions">
|
||||
<td>{{perm.rpcname}}</td>
|
||||
<td *ngFor="let rank of ranks">
|
||||
<nb-toggle
|
||||
[(ngModel)]="perm[rank]"
|
||||
(checkedChange)="settingChanged($event, rank, perm)">
|
||||
</nb-toggle>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</nb-card-body>
|
||||
</nb-card>
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ApiService as ApiService } from '../../services/login-api';
|
||||
import { Router } from '@angular/router';
|
||||
import { _Rank, _Class, _Race, RPCPermission } from '../../../../../../backend/Types/Types'
|
||||
import { NbToastrService } from '@nebular/theme';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'changePermissions',
|
||||
templateUrl: './changePermissions.component.html',
|
||||
})
|
||||
export class ChangePermissionsComponent implements OnInit{
|
||||
|
||||
permissions:RPCPermission[] = []
|
||||
ranks = _Rank
|
||||
|
||||
constructor(
|
||||
private router : Router,
|
||||
private api : ApiService,
|
||||
private toastr: NbToastrService
|
||||
){}
|
||||
|
||||
async ngOnInit(){
|
||||
const modify = this.api.get('modifyPermissions')
|
||||
if(!modify) return
|
||||
this.permissions = await modify.getPermissions()
|
||||
}
|
||||
|
||||
settingChanged = async (value, key, perm:RPCPermission) => {
|
||||
const modify = this.api.get('modifyPermissions')
|
||||
if(!modify) return
|
||||
|
||||
|
||||
perm[key] = value
|
||||
console.log(perm);
|
||||
|
||||
|
||||
await modify.setPermission(perm).catch(e => {
|
||||
|
||||
})
|
||||
this.toastr.success('Permission updated', 'Success')
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ApiService } from '../services/login-api';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'auth-layout',
|
||||
template: `
|
||||
<ngx-one-column-no-sidebar-layout>
|
||||
<router-outlet></router-outlet>
|
||||
</ngx-one-column-no-sidebar-layout>
|
||||
`,
|
||||
})
|
||||
|
||||
export class PermissionsComponent implements OnInit{
|
||||
constructor(
|
||||
private loginSvc : ApiService,
|
||||
private router: Router
|
||||
){}
|
||||
|
||||
ngOnInit(){
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { PermissionsComponent } from './permissions-layout.component';
|
||||
import { ChangePermissionsComponent } from './changePermissions/changePermissions.component';
|
||||
|
||||
export const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: PermissionsComponent,
|
||||
children: [
|
||||
{
|
||||
path: '**',
|
||||
component: ChangePermissionsComponent,
|
||||
},
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule],
|
||||
})
|
||||
export class PermissionsRoutingModule {
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
import {
|
||||
NbAlertModule,
|
||||
NbButtonModule,
|
||||
NbCheckboxModule,
|
||||
NbInputModule,
|
||||
NbMenuModule,
|
||||
NbCardModule,
|
||||
NbSelectModule,
|
||||
NbToggleModule
|
||||
} from '@nebular/theme';
|
||||
import { PermissionsComponent } from './permissions-layout.component';
|
||||
import { ThemeModule } from '../../@theme/theme.module';
|
||||
import { PermissionsRoutingModule } from './permissions-routing.module';
|
||||
import { ChangePermissionsComponent } from './changePermissions/changePermissions.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
NbToggleModule,
|
||||
PermissionsRoutingModule,
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
RouterModule,
|
||||
NbAlertModule,
|
||||
NbInputModule,
|
||||
NbButtonModule,
|
||||
NbCheckboxModule,
|
||||
ThemeModule,
|
||||
NbMenuModule,
|
||||
NbCardModule,
|
||||
NbSelectModule
|
||||
],
|
||||
declarations: [
|
||||
PermissionsComponent,
|
||||
ChangePermissionsComponent,
|
||||
],
|
||||
})
|
||||
export class PermissionsModule {
|
||||
}
|
||||
@@ -34,7 +34,7 @@ export class ApiService{
|
||||
)
|
||||
|
||||
sock.hook('kick', () => {
|
||||
this.logout()
|
||||
this.kick()
|
||||
})
|
||||
|
||||
sock.hook('getUserData', () => auth)
|
||||
@@ -110,6 +110,11 @@ export class ApiService{
|
||||
return async (msg: ShoutMessage) => await this.get('Shoutbox').shout(res.uuid, msg)
|
||||
}
|
||||
|
||||
kick = async () => {
|
||||
await this.logout()
|
||||
location.reload()
|
||||
}
|
||||
|
||||
logout = async () => {
|
||||
this.cookieSvc.set('token', undefined)
|
||||
if(this.auth){
|
||||
|
||||
+21
-7
@@ -129,6 +129,18 @@ describe('Frontcraft', () => {
|
||||
return client.UserManager.createUser(user)
|
||||
}
|
||||
|
||||
const login = async (name: string) : Promise<Auth> => {
|
||||
const auth = await client.UserManager.login(name, 'ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb')
|
||||
|
||||
if(users[name]) users[name] = {
|
||||
...users[name],
|
||||
auth: auth
|
||||
}
|
||||
|
||||
|
||||
return auth
|
||||
}
|
||||
|
||||
const createAccountAndUser = async (acc: protoAccount) => {
|
||||
const account = await createAccount({
|
||||
pwhash: 'ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb', //sha256("a")
|
||||
@@ -199,6 +211,14 @@ describe('Frontcraft', () => {
|
||||
server.stop()
|
||||
})
|
||||
|
||||
it('can set permissions', (done) => {
|
||||
Promise.all(
|
||||
defaultPermissions.map(perm => adminClient.modifyPermissions.setPermission(perm)),
|
||||
).then(_ => {
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it('create raids', (done) => {
|
||||
let insertRaid = <Raid>{
|
||||
description: "Test raid 1",
|
||||
@@ -587,13 +607,7 @@ describe('Frontcraft', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it('can set permissions', (done) => {
|
||||
Promise.all(
|
||||
defaultPermissions.map(perm => adminClient.modifyPermissions.setPermission(perm)),
|
||||
).then(_ => {
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
it('start raid', (done) => {
|
||||
client.RaidManager.getRaids().then((r) => {
|
||||
|
||||
Reference in New Issue
Block a user