raspi-back/app/jableshandler.js

163 lines
5.4 KiB
JavaScript
Executable File

const {writeDB, writeDefinition, deleteDefinition, getDefinition, updateObject, setup} = require("jables2")
const {encodePW, verifyPW} = require("./verlikifyhandler")
const {addRouteToScope} = require("./scopes")
const {addHupTask} = require("./huphandler")
setup("udb", "./.j2").then(()=>{
getScopes().then((scopes)=>{
scopes.forEach((scope)=>{
scope.content.forEach((content)=>{
addRouteToScope(content, scope.scope)
})
})
})
})
const userBase = {indexKey:"id", path:"user"}
const scopeBase = {indexKey:"scope", path:"scope"}
const getUsers = ()=>new Promise((res)=>{
getDefinition("user").then(({Versions})=>{
res(Versions)
}, (error)=>{
// console.log(error)
res([])
})
})
const getUser = ({name, id})=>new Promise((res, rej)=>{
getUsers().then((users)=>{
const user = users.find((user)=>id!=undefined?user.id==id:user.name==name)
if(user){
res(user)
}else{
rej({error: 404, message:`can't find ${id!=undefined?id:name}`})
}
})
})
const newUser = ({name, passwort, admin, passHint})=>new Promise((res, rej)=>{
getUser({name}).then(()=>{
rej({error: 401, message:`${name} already exists`})
}, ()=>{
const {uid, pass} = encodePW(passwort)
writeDefinition(updateObject(userBase, {name, id:uid, pass, passHint, scopes:admin?["admin"]:[]}))
res()
})
})
const patchUser = ({id, name, passwort, passHint})=>new Promise((res, rej)=>{
getUser({id}).then((user)=>{
if(name){
getUsers().then((users)=>{
if(!users.find((user)=>user.name==name)){
user.name = name;
patchUser({id, passwort, passHint}).then(res, rej)
}else{
rej({error: 401, message:"patch failed"})
}
})
}else if(passwort && passHint){
const {pass} = encodePW(passwort, id)
user.pass = pass;
writeDefinition(updateObject(userBase, user));
res()
}else{
writeDefinition(updateObject(userBase, user))
res()
}
}, rej)
})
const login = ({name, passwort})=>new Promise((res, rej)=>{
getUser({name}).then(({id, pass, scopes, blocked, passHint})=>{
if(blocked){
rej({error:403, message:blocked})
}else if(verifyPW(id, passwort, pass)){
res({scopes, id})
} else{
rej({error: 401, message:passHint})
}
}, rej)
})
const logout = ({id})=>new Promise((res, rej)=>{
getUser({id}).then(()=>{
writeDefinition(updateObject(userBase, {id, lockout:Date.now()}))
res();
}, rej)
})
const getLock = ({id})=>new Promise((res, rej)=>{
getUser({id}).then(({lockout})=>{
res(lockout||0)
}, rej)
})
const blockUser = ({id, blocked})=>new Promise((res, rej)=>{
getUser({id}).then((user)=>{
writeDefinition(updateObject(userBase, user, {blocked, lockout: Date.now()}))
res()
}, rej)
})
const addUserScope = (id, scope)=>new Promise((res, rej)=>{
getUser({id}).then((user)=>{
if(user.scopes){
user.scopes.push(scope)
}else{
user.scopes=[scope]
}
writeDefinition(updateObject(userbase, user))
res()
}, rej)
})
const removeUserScope = (id, scope)=>new Promise((res, rej)=>{
getUser({id}).then((user)=>{
if(!user.scopes||!user.scopes.includes(scope)){
rej({error: 404, message:`${scope} not found on ${id}`})
}else{
user.scopes.splice(user.scopes.indexOf(scope), 1);
writeDefinition(updateObject(userBase, user))
res()
}
}, rej)
})
const getScopes = ()=>new Promise((res)=>{
getDefinition("scope").then(({Versions})=>{
res(Versions)
}, ()=>{
res([]);
})
})
const getScopeContent = ({scope})=>new Promise((res, rej)=>{
getScopes().then((scopes)=>{
const rscope = scopes.find((rsc)=>rsc.scope==scope);
if(rscope){
res(rscope.content)
}else{
rej({error: 404, message:`${scope} not found`})
}
})
})
const getScopesForContent = ({content})=>new Promise((res, rej)=>{
getScopes().then((scopes)=>{
const scopeEntries = scopes.filter((scopeentry)=>scopeentry.content.includes(content))
if(scopeEntries.length){
res(scopeEntries.map(({scope})=>scope))
}else{
rej({error:404, message:`${content} has no entries`})
}
})
})
const addScopeEntry = ({scope, content})=>new Promise((res, rej)=>{
getScopeContent({scope}).then((contents)=>{
if(contents.includes(content)){
rej({error:"409", message:`${content} already in ${scope}`})
}else{
contents.push(content);
writeDefinition(updateObject(scopeBase, {scope}))
res()
}
}, ()=>{
writeDefinition(updateObject(scopeBase, {scope, content:[content]}))
res()
})
})
addHupTask("DB", writeDB)
module.exports = {
getUsers, getUser, newUser, blockUser, addUserScope, removeUserScope, login, logout, getLock, patchUser, addScopeEntry, getScopeContent, getScopesForContent
}