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 }