This commit is contained in:
peter
2019-11-09 11:53:36 +01:00
parent 92824d67a5
commit a7a5a85033
10 changed files with 79 additions and 32 deletions
+3 -3
View File
@@ -4961,9 +4961,9 @@
} }
}, },
"rpclibrary": { "rpclibrary": {
"version": "1.4.0", "version": "1.4.1",
"resolved": "https://registry.npmjs.org/rpclibrary/-/rpclibrary-1.4.0.tgz", "resolved": "https://registry.npmjs.org/rpclibrary/-/rpclibrary-1.4.1.tgz",
"integrity": "sha512-JUU7+HymV2ZTI+NrIVOiIr5LGFoRsPq4k/ffdUonqIpd9fjOHBQ2/PFLVXx9z94+dKxdqN8/D9ZXPwU03ovZrg==", "integrity": "sha512-Tv9zOBVT8JFMZfTJgmnX9vvUvtALCDtj/cnlYw2SxsFnj1MuH9VgPniSfThUgdwZZknjFuYVfhLaYb9Yl+eRxQ==",
"requires": { "requires": {
"bsock": "^0.1.9", "bsock": "^0.1.9",
"http": "0.0.0", "http": "0.0.0",
+1 -1
View File
@@ -37,7 +37,7 @@
"node-fetch": "^2.6.0", "node-fetch": "^2.6.0",
"path": "^0.12.7", "path": "^0.12.7",
"rimraf": "^3.0.0", "rimraf": "^3.0.0",
"rpclibrary": "^1.4.0", "rpclibrary": "^1.4.1",
"simple-git": "^1.124.0", "simple-git": "^1.124.0",
"spawn-sync": "^2.0.0", "spawn-sync": "^2.0.0",
"sqlite3": "^4.1.0", "sqlite3": "^4.1.0",
+12 -5
View File
@@ -146,12 +146,19 @@ implements TableDefinitionExporter {
this.knex = Knex(conf) this.knex = Knex(conf)
await Promise.all(this.getTableDefinitions().map(async (def)=>{ await Promise.all(
this.getTableDefinitions()
//make unique by name
.filter((other, index, self) => index === self.findIndex(
(self) => self.name === other.name)
)
//create table if not exists
.map(async (def)=> {
const hasTable = await this.knex.schema.hasTable(def.name) const hasTable = await this.knex.schema.hasTable(def.name)
if(!hasTable){ if(!hasTable)
await this.knex.schema.createTable(def.name, def.tableBuilder) return await this.knex.schema.createTable(def.name, def.tableBuilder)
} })
})) )
return this.knex return this.knex
} }
+2 -2
View File
@@ -94,13 +94,13 @@ implements FrontworkComponent<ItemManagerFeatureIfc>, TableDefinitionExporter{
const allItems = [...T1] const allItems = [...T1]
const countCache = await this.countItems() const countCache = await this.countItems()
if(countCache != allItems.length){ if(countCache != allItems.length){
const items:Item[] = await Promise.all(allItems.map(async (i) => this.getItem(i))) const items:Item[] = await Promise.all(allItems.map((i) => this.getItem(i)))
try{ try{
await this.admin await this.admin
.knex('items') .knex('items')
.insert(items) .insert(items)
}catch(e){ }catch(e){
console.error(e) console.info("Skipping item insertion")
} }
} }
} }
+18 -5
View File
@@ -1,5 +1,5 @@
import { RPCServer } from "rpclibrary"; import { RPCServer } from "rpclibrary";
import { TableDefiniton, AnyRPCExporter, User, RPCPermission, _Rank, Token, Auth } from "../../Types/Types"; import { TableDefiniton, AnyRPCExporter, User, RPCPermission, _Rank, Token, Auth, FrontcraftFeatureIfc, Rank } from "../../Types/Types";
import { FrontworkAdmin } from "../../Admin/Admin"; import { FrontworkAdmin } from "../../Admin/Admin";
import { PrivilegedRPCExporter } from "../../Types/PrivilegedRPCExporter"; import { PrivilegedRPCExporter } from "../../Types/PrivilegedRPCExporter";
import { FrontworkComponent } from "../../Types/FrontworkComponent"; import { FrontworkComponent } from "../../Types/FrontworkComponent";
@@ -65,7 +65,7 @@ implements FrontworkComponent{
},{ },{
name: 'rpcpermissions', name: 'rpcpermissions',
tableBuilder: (table) => { tableBuilder: (table) => {
table.string("rpcName").primary().notNullable() table.string("name").primary().notNullable()
table.boolean("ADMIN").defaultTo(true).notNullable() table.boolean("ADMIN").defaultTo(true).notNullable()
_Rank.forEach(r => table.boolean(r).defaultTo(false).notNullable()) _Rank.forEach(r => table.boolean(r).defaultTo(false).notNullable())
} }
@@ -83,9 +83,9 @@ implements FrontworkComponent{
async initialize(){ async initialize(){
await Promise.all( await Promise.all(
[this, ...this.exporters].flatMap(exp => exp.exportRPCFeatures().map(async (rpc) => { [this, ...this.exporters].flatMap(exp => exp.exportRPCFeatures().map(async (feature) => {
try{ try{
await this.admin.knex.insert({ rpcname: rpc.name }).into('rpcpermissions') await this.admin.knex.insert({ name: feature.name }).into('rpcpermissions')
}catch(e){} }catch(e){}
}))) })))
@@ -102,8 +102,21 @@ implements FrontworkComponent{
return await this.admin.knex.select('*').from('rpcpermissions') return await this.admin.knex.select('*').from('rpcpermissions')
} }
getPermission = async (feature: keyof FrontcraftFeatureIfc, rank:Rank) : Promise<boolean> => {
const perm : RPCPermission[] = await this.admin.knex
.select(rank)
.from('rpcpermissions')
.where('name', '=', feature)
if(perm.length === 0) return false
return perm[0][rank]
}
getRPCForUser = async (user:User): Promise<AnyRPCExporter[]> => { getRPCForUser = async (user:User): Promise<AnyRPCExporter[]> => {
return [...this.exportRPCFeatures(), ...this.exporters.flatMap((exp) => exp.exportRPCFeatures())] return [
...this.exportRPCFeatures(),
...this.exporters.flatMap((exp) => exp.exportRPCFeatures())
].filter(async (feature) => await this.getPermission(<keyof FrontcraftFeatureIfc> feature.name, user.rank))
} }
createUser = async(user:User): Promise<User> => { createUser = async(user:User): Promise<User> => {
+4
View File
@@ -89,3 +89,7 @@ export type RaidManagerFeatureIfc = {
sign: (user:User, raid:Raid, attending:boolean) => Promise<any> sign: (user:User, raid:Raid, attending:boolean) => Promise<any>
} }
} }
export type SomeOf<T> = {
[K in keyof T]? : T[K]
}
+3 -3
View File
@@ -14269,9 +14269,9 @@
"integrity": "sha512-ZYzRkETgBrdEGzL5JSKimvjI2CX7ioyZCkX2BpcfyjqI+079W0wHAyj5W4rIZMcDSOHgLZtgz1IdDi/vU77KEQ==" "integrity": "sha512-ZYzRkETgBrdEGzL5JSKimvjI2CX7ioyZCkX2BpcfyjqI+079W0wHAyj5W4rIZMcDSOHgLZtgz1IdDi/vU77KEQ=="
}, },
"rpclibrary": { "rpclibrary": {
"version": "1.4.0", "version": "1.4.2",
"resolved": "https://registry.npmjs.org/rpclibrary/-/rpclibrary-1.4.0.tgz", "resolved": "https://registry.npmjs.org/rpclibrary/-/rpclibrary-1.4.2.tgz",
"integrity": "sha512-JUU7+HymV2ZTI+NrIVOiIr5LGFoRsPq4k/ffdUonqIpd9fjOHBQ2/PFLVXx9z94+dKxdqN8/D9ZXPwU03ovZrg==", "integrity": "sha512-IFigD+65a9MM+1AgEH5nurUzCyMg9hawqtnOA67/PtTGP5GsnWxaFESKl03k8L/PQ8ptZkWcub/63bfxkrwyMw==",
"requires": { "requires": {
"bsock": "^0.1.9", "bsock": "^0.1.9",
"http": "0.0.0", "http": "0.0.0",
+1 -1
View File
@@ -69,7 +69,7 @@
"normalize.css": "6.0.0", "normalize.css": "6.0.0",
"pace-js": "1.0.2", "pace-js": "1.0.2",
"roboto-fontface": "0.8.0", "roboto-fontface": "0.8.0",
"rpclibrary": "^1.4.0", "rpclibrary": "^1.4.2",
"rxjs": "6.5.2", "rxjs": "6.5.2",
"rxjs-compat": "6.3.0", "rxjs-compat": "6.3.0",
"socicon": "3.0.5", "socicon": "3.0.5",
+3
View File
@@ -19,6 +19,9 @@ export class AppComponent implements OnInit {
ngOnInit(): void { ngOnInit(): void {
this.analytics.trackPageViews(); this.analytics.trackPageViews();
this.loginSvc.getFeature('createUser').then( (f) => {
})
window['s'] = this.loginSvc window['s'] = this.loginSvc
} }
} }
+29 -9
View File
@@ -1,14 +1,14 @@
import { Injectable } from "@angular/core"; import { Injectable } from "@angular/core";
import {RPCSocket} from 'rpclibrary/js/src/Frontend' import {RPCSocket} from 'rpclibrary/js/src/Frontend'
import { Token, Auth, User, _Rank, _Class, FrontcraftFeatureIfc, LoginManagerIfc, } from '../../../../backend/Types/Types' import { Token, Auth, User, _Class, FrontcraftFeatureIfc, LoginManagerIfc, SomeOf, } from '../../../../backend/Types/Types'
import { CookieService } from 'ngx-cookie-service'; import { CookieService } from 'ngx-cookie-service';
@Injectable() @Injectable()
export class LoginApiService{ export class LoginApiService{
private socket:RPCSocket & LoginManagerIfc; private socket:RPCSocket & LoginManagerIfc;
private auth:Auth private auth:Auth
private privSocket: RPCSocket & FrontcraftFeatureIfc private privSocket: RPCSocket & SomeOf<FrontcraftFeatureIfc>
constructor( constructor(
private cookieSvc : CookieService private cookieSvc : CookieService
@@ -16,10 +16,21 @@ export class LoginApiService{
getUnprivilegedSocket = () : RPCSocket & LoginManagerIfc => this.socket getUnprivilegedSocket = () : RPCSocket & LoginManagerIfc => this.socket
private getPrivilegedSocket = async (auth:Auth) : Promise<RPCSocket & FrontcraftFeatureIfc> => { private getPrivilegedSocket = async (auth:Auth) : Promise<RPCSocket & SomeOf<FrontcraftFeatureIfc>> => {
if(this.privSocket) return this.privSocket if(this.privSocket) return this.privSocket
if(auth.user.rank === 'Guest'){
return await RPCSocket.makeSocket<SomeOf<FrontcraftFeatureIfc>>(
20001,
window.location.hostname
)
}
try{ try{
const sock: RPCSocket & FrontcraftFeatureIfc = await new RPCSocket(auth.port, window.location.hostname).connect(auth.token.value) const sock = await RPCSocket.makeSocket<SomeOf<FrontcraftFeatureIfc>>(
auth.port,
window.location.hostname,
auth.token.value
)
//login success //login success
this.auth = auth this.auth = auth
this.privSocket = sock this.privSocket = sock
@@ -31,6 +42,11 @@ export class LoginApiService{
} }
} }
getFeature = async <K extends keyof FrontcraftFeatureIfc>(feature : K) : Promise<void | FrontcraftFeatureIfc[K]> => {
const sock = await this.getPrivilegedSocket(this.auth)
if(sock[feature]) return <FrontcraftFeatureIfc[K]> sock[feature]
}
getCurrentUser = () : User => this.auth getCurrentUser = () : User => this.auth
? this.auth.user ? this.auth.user
: { : {
@@ -40,12 +56,12 @@ export class LoginApiService{
rank: 'Guest' rank: 'Guest'
} }
authenticate = async (token : Token | string) : Promise<RPCSocket & FrontcraftFeatureIfc> => { authenticate = async (token : Token | string) : Promise<RPCSocket & SomeOf<FrontcraftFeatureIfc>> => {
const auth = await this.socket.Authenticator.authenticate(token) const auth = await this.socket.Authenticator.authenticate(token)
return await this.getPrivilegedSocket(auth) return await this.getPrivilegedSocket(auth)
} }
login = async (username, password) => { login = async (username: string, password: string) => {
const buf = str2arraybuf(password) const buf = str2arraybuf(password)
const pwHash = await crypto.subtle.digest('SHA-256', buf); const pwHash = await crypto.subtle.digest('SHA-256', buf);
const token = await this.socket.Authenticator.login(username, buf2hex(pwHash)) const token = await this.socket.Authenticator.login(username, buf2hex(pwHash))
@@ -69,12 +85,16 @@ export class LoginApiService{
} }
initialize = async () : Promise<RPCSocket> => { initialize = async () : Promise<RPCSocket> => {
const sock : RPCSocket & LoginManagerIfc = await new RPCSocket(20000, window.location.hostname).connect() const sock = await RPCSocket.makeSocket<LoginManagerIfc>(20000, window.location.hostname)
this.socket = sock this.socket = sock
const cookie = this.getCookie() const cookie = this.getCookie()
if(cookie) { if(cookie) {
try{
return await this.authenticate(cookie) return await this.authenticate(cookie)
}catch(e){
this.logout()
}
} }
return sock return sock
@@ -89,7 +109,7 @@ function buf2hex(buffer) { // buffer is an ArrayBuffer
return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join(''); return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
} }
//angular depenency manager requires this
export function initializeLoginSvc(svc: LoginApiService): () => Promise<RPCSocket> { export function initializeLoginSvc(svc: LoginApiService): () => Promise<any> {
return svc.initialize return svc.initialize
} }