{"version":3,"file":"yonius.fastify.esm.mjs","sources":["../js/base/error.js","../js/base/auth.js","../js/util/config.js","../js/fastify/auth.js"],"sourcesContent":["export class YoniusError extends Error {\r\n    constructor(message, code = 500) {\r\n        super(message);\r\n        this.name = this.constructor.name;\r\n        this.message = message;\r\n        this.code = code;\r\n    }\r\n\r\n    get isClient() {\r\n        return Math.floor(this.code / 100) === 4;\r\n    }\r\n\r\n    get isServer() {\r\n        return Math.floor(this.code / 100) === 5;\r\n    }\r\n}\r\n\r\nexport class OperationalError extends YoniusError {\r\n    constructor(message = \"Operational error\", code = 500) {\r\n        super(message, code);\r\n    }\r\n}\r\n\r\nexport class NotFoundError extends OperationalError {\r\n    constructor(message = \"Not found\", code = 404) {\r\n        super(message, code);\r\n    }\r\n}\r\n\r\nexport class NotImplementedError extends OperationalError {\r\n    constructor(message = \"Not implemented\", code = 501) {\r\n        super(message, code);\r\n    }\r\n}\r\n\r\nexport class ValidationError extends OperationalError {\r\n    constructor(message = \"Validation of submitted data failed\", code = 400) {\r\n        super(message, code);\r\n    }\r\n}\r\n\r\nexport class AttributeError extends YoniusError {\r\n    constructor(message = \"Attribute not found\") {\r\n        super(message);\r\n    }\r\n}\r\n\r\nexport default YoniusError;\r\n","import { OperationalError } from \"./error\";\r\n\r\n/**\r\n * Ensures that the current \"session\" context contains the\r\n * requested ACL token as valid.\r\n *\r\n * In case the validation fails an exception is raised\r\n * indicating the auth validation error.\r\n *\r\n * @param {String} token The ACL token to ensure permission,\r\n * the logged user should be allowed to id.\r\n * @param {Object} ctx The context object to be used in\r\n * the session basic ACL retrieval, should contain proper\r\n * injected methods for retrieval (eg: `getAcl`).\r\n */\r\nexport const ensurePermissions = async (token, ctx) => {\r\n    // retrieves the ACL values from the current context and\r\n    // then uses the ACL to obtain the valid expanded tokens map\r\n    const acl = ctx.getAcl ? await ctx.getAcl(ctx) : {};\r\n    const tokens = toTokensM(acl);\r\n\r\n    // in case the permission validation test is not positive\r\n    // then an exception should be raised indicating the issue\r\n    if (!hasPermission(token, tokens)) {\r\n        throw new OperationalError(\"You don't have authorization to access this resource\", 401);\r\n    }\r\n};\r\n\r\n/**\r\n * Converts the provided list of token strings separated by dots\r\n * into a map based representation on an hierarchical structure.\r\n *\r\n * @param {Array} tokens A linear array of tokens to convert into\r\n * an hierarchical representation.\r\n * @returns {Object} The map containing the hierarchy of tokens\r\n * for the provided linear string based sequence of tokens.\r\n */\r\nexport const toTokensM = tokens => {\r\n    const tokensM = {};\r\n\r\n    if (tokens === undefined) return tokensM;\r\n    if (tokens === null) return tokensM;\r\n    if (!Array.isArray(tokens)) return tokensM;\r\n\r\n    for (const token of tokens) {\r\n        let tokensC = tokensM;\r\n        const tokenL = token.split(\".\");\r\n        const head = tokenL.slice(0, tokenL.length - 1);\r\n        const tail = tokenL[tokenL.length - 1];\r\n\r\n        for (const tokenP of head) {\r\n            let current = tokensC[tokenP] || {};\r\n            const isDict = typeof current === \"object\";\r\n            if (!isDict) current = { _: current };\r\n            tokensC[tokenP] = current;\r\n            tokensC = current;\r\n        }\r\n\r\n        const leaf = tokensC[tail] || null;\r\n        if (leaf && typeof leaf === \"object\") leaf._ = true;\r\n        else tokensC[tail] = true;\r\n    }\r\n\r\n    return tokensM;\r\n};\r\n\r\nexport const hasPermission = (token, tokensM = null) => {\r\n    if (!token) return true;\r\n    if (tokensM === undefined || tokensM === null) return false;\r\n\r\n    const tokenL = token.split(\".\");\r\n    for (const tokenP of tokenL) {\r\n        if (typeof tokensM !== \"object\") return false;\r\n        if (tokensM[\"*\"]) return true;\r\n        if (tokensM[tokenP] === undefined) return false;\r\n        tokensM = tokensM[tokenP];\r\n    }\r\n\r\n    const isDict = typeof tokensM === \"object\";\r\n    const result = isDict ? tokensM._ || false : tokensM;\r\n\r\n    return Boolean(result);\r\n};\r\n\r\nexport default ensurePermissions;\r\n","import * as fs from \"fs\";\r\nimport { resolve, join, normalize, dirname } from \"path\";\r\nimport { pathExists, expandUser, getEnvObject } from \"./fs\";\r\n\r\nconst FILE_NAME = \"yonius.json\";\r\n\r\nconst HOME_FILE = \"~/.home\";\r\n\r\nconst IMPORT_NAMES = [\"$import\", \"$include\", \"$IMPORT\", \"$INCLUDE\"];\r\n\r\nconst CASTS = {\r\n    int: v => (typeof v === \"number\" ? v : parseInt(v)),\r\n    float: v => (typeof v === \"number\" ? v : parseFloat(v)),\r\n    bool: v => (typeof v === \"boolean\" ? v : [\"1\", \"true\", \"True\"].includes(v)),\r\n    list: v => (Array.isArray(v) ? v : v.split(\";\")),\r\n    tuple: v => (Array.isArray(v) ? v : v.split(\";\"))\r\n};\r\n\r\nexport const globals =\r\n    typeof global === \"undefined\"\r\n        ? typeof window === \"undefined\"\r\n            ? typeof self === \"undefined\"\r\n                ? {}\r\n                : self\r\n            : window\r\n        : global;\r\n\r\nglobals.CONFIGS = globals.CONFIGS === undefined ? {} : globals.CONFIGS;\r\n\r\nglobals.CONFIG_F = globals.CONFIG_F === undefined ? [] : globals.CONFIG_F;\r\n\r\nglobals.HOMES = globals.HOMES === undefined ? [] : globals.HOMES;\r\n\r\nglobals.LOADED = globals.LOADED === undefined ? false : globals.LOADED;\r\n\r\nexport const conf = function(name, fallback = undefined, cast = null, ctx = null) {\r\n    const configs = ctx ? ctx.configs : globals.CONFIGS;\r\n    cast = _castR(cast);\r\n    let value = configs[name] === undefined ? fallback : configs[name];\r\n    if (cast && value !== undefined && value !== null) value = cast(value);\r\n    return value;\r\n};\r\n\r\nexport const confP = async function(name, fallback = undefined, cast = null, ctx = null) {\r\n    await load();\r\n    return conf(name, fallback, cast, ctx);\r\n};\r\n\r\nexport const confS = function(name, value, ctx = null) {\r\n    const configs = ctx ? ctx.configs : globals.CONFIGS;\r\n    configs[name] = value;\r\n};\r\n\r\nexport const load = async function(\r\n    names = [FILE_NAME],\r\n    path = null,\r\n    encoding = \"utf-8\",\r\n    force = false,\r\n    ctx = null\r\n) {\r\n    if (globals.LOADED && !force) return;\r\n    let paths = [];\r\n    const homes = await getHomes();\r\n    for (const home of homes) {\r\n        paths = paths.concat([join(home), join(home, \".config\")]);\r\n    }\r\n    paths.push(path);\r\n    for (const path of paths) {\r\n        for (const name of names) {\r\n            await loadFile(name, path, encoding, ctx);\r\n        }\r\n    }\r\n    await loadEnv(ctx);\r\n    globals.LOADED = true;\r\n};\r\n\r\nexport const loadFile = async function(\r\n    name = FILE_NAME,\r\n    path = null,\r\n    encoding = \"utf-8\",\r\n    ctx = null\r\n) {\r\n    const configs = ctx ? ctx.configs : globals.CONFIGS;\r\n    const configF = ctx ? ctx.configF : globals.CONFIG_F;\r\n\r\n    let key;\r\n    let value;\r\n    let exists;\r\n    let filePath;\r\n\r\n    if (path) path = normalize(path);\r\n    if (path) filePath = join(path, name);\r\n    else filePath = name;\r\n\r\n    filePath = resolve(filePath);\r\n    filePath = normalize(filePath);\r\n    const basePath = dirname(filePath);\r\n\r\n    exists = await pathExists(filePath);\r\n    if (!exists) return;\r\n\r\n    exists = configF.includes(filePath);\r\n    if (exists) configF.splice(configF.indexOf(filePath), 1);\r\n    configF.push(filePath);\r\n\r\n    const data = await fs.promises.readFile(filePath, { encoding: encoding });\r\n    const dataJ = JSON.parse(data);\r\n\r\n    await _loadIncludes(basePath, dataJ, encoding);\r\n\r\n    for ([key, value] of Object.entries(dataJ)) {\r\n        if (!_isValid(key)) continue;\r\n        configs[key] = value;\r\n    }\r\n};\r\n\r\nexport const loadEnv = async function(ctx = null) {\r\n    const env = getEnvObject();\r\n    const configs = ctx ? ctx.configs : globals.CONFIGS;\r\n    if (env === undefined || env === null) return;\r\n    Object.entries(env).forEach(function([key, value]) {\r\n        configs[key] = value;\r\n    });\r\n};\r\n\r\nexport const getHomes = async function(\r\n    filePath = HOME_FILE,\r\n    fallback = \"~\",\r\n    encoding = \"utf-8\",\r\n    forceDefault = false\r\n) {\r\n    if (globals.HOMES.length > 0) return globals.HOMES;\r\n\r\n    const env = getEnvObject();\r\n\r\n    globals.HOMES = env.HOMES === undefined ? null : env.HOMES;\r\n    globals.HOMES = globals.HOMES ? globals.HOMES.split(\";\") : globals.HOMES;\r\n    if (globals.HOMES !== null) return globals.HOMES;\r\n\r\n    fallback = expandUser(fallback);\r\n    fallback = normalize(fallback);\r\n    globals.HOMES = [fallback];\r\n\r\n    filePath = expandUser(filePath);\r\n    filePath = normalize(filePath);\r\n    const exists = await pathExists(filePath);\r\n    if (!exists) return globals.HOMES;\r\n\r\n    if (!forceDefault) globals.HOMES.splice(0, globals.HOMES.length);\r\n\r\n    let data = await fs.promises.readFile(filePath, { encoding: encoding });\r\n    data = data.trim();\r\n\r\n    let paths = data.split(/\\r?\\n/);\r\n    paths = paths.map(v => v.trim());\r\n\r\n    for (let path of paths) {\r\n        path = path.trim();\r\n        if (!path) continue;\r\n        path = expandUser(path);\r\n        path = normalize(path);\r\n        globals.HOMES.push(path);\r\n    }\r\n\r\n    return globals.HOMES;\r\n};\r\n\r\nexport const _castR = function(cast) {\r\n    return CASTS[cast] === undefined ? cast : CASTS[cast];\r\n};\r\n\r\nexport const _loadIncludes = async function(basePath, config, encoding = \"utf-8\") {\r\n    let includes = [];\r\n\r\n    for (const alias of IMPORT_NAMES) {\r\n        includes = config[alias] === undefined ? includes : config[alias];\r\n    }\r\n\r\n    if (typeof includes === \"string\") {\r\n        includes = includes.split(\";\");\r\n    }\r\n\r\n    for (const include of includes) {\r\n        await loadFile(include, basePath, encoding);\r\n    }\r\n};\r\n\r\nexport const _isValid = function(key) {\r\n    if (IMPORT_NAMES.includes(key)) return false;\r\n    return true;\r\n};\r\n\r\nexport const _isDevel = function() {\r\n    return [\"DEBUG\"].includes(conf(\"LEVEL\", \"INFO\"));\r\n};\r\n\r\nexport const _isSecure = function() {\r\n    return conf(\"SECURE\", true, \"bool\");\r\n};\r\n\r\nexport default conf;\r\n","import { ensurePermissions } from \"../base\";\r\n\r\nexport const ensureFastify = token => {\r\n    return (req, res, next) => {\r\n        ensurePermissions(token, req).catch(next).then(next);\r\n    };\r\n};\r\n\r\nexport default ensureFastify;\r\n"],"names":[],"mappings":";;;;;;;;;;;;AAAO,MAAM,WAAW,SAAS,KAAK,CAAC;AACvC,IAAI,WAAW,CAAC,OAAO,EAAE,IAAI,GAAG,GAAG,EAAE;AACrC,QAAQ,KAAK,CAAC,OAAO,CAAC,CAAC;AACvB,QAAQ,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;AAC1C,QAAQ,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;AAC/B,QAAQ,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;AACzB,KAAK;AACL;AACA,IAAI,IAAI,QAAQ,GAAG;AACnB,QAAQ,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC;AACjD,KAAK;AACL;AACA,IAAI,IAAI,QAAQ,GAAG;AACnB,QAAQ,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC;AACjD,KAAK;AACL,CAAC;AACD;AACO,MAAM,gBAAgB,SAAS,WAAW,CAAC;AAClD,IAAI,WAAW,CAAC,OAAO,GAAG,mBAAmB,EAAE,IAAI,GAAG,GAAG,EAAE;AAC3D,QAAQ,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;AAC7B,KAAK;AACL;;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAM,iBAAiB,GAAG,OAAO,KAAK,EAAE,GAAG,KAAK;AACvD;AACA;AACA,IAAI,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;AACxD,IAAI,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;AAClC;AACA;AACA;AACA,IAAI,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE;AACvC,QAAQ,MAAM,IAAI,gBAAgB,CAAC,sDAAsD,EAAE,GAAG,CAAC,CAAC;AAChG,KAAK;AACL,CAAC,CAAC;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAM,SAAS,GAAG,MAAM,IAAI;AACnC,IAAI,MAAM,OAAO,GAAG,EAAE,CAAC;AACvB;AACA,IAAI,IAAI,MAAM,KAAK,SAAS,EAAE,OAAO,OAAO,CAAC;AAC7C,IAAI,IAAI,MAAM,KAAK,IAAI,EAAE,OAAO,OAAO,CAAC;AACxC,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,OAAO,OAAO,CAAC;AAC/C;AACA,IAAI,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE;AAChC,QAAQ,IAAI,OAAO,GAAG,OAAO,CAAC;AAC9B,QAAQ,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AACxC,QAAQ,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACxD,QAAQ,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AAC/C;AACA,QAAQ,KAAK,MAAM,MAAM,IAAI,IAAI,EAAE;AACnC,YAAY,IAAI,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;AAChD,YAAY,MAAM,MAAM,GAAG,OAAO,OAAO,KAAK,QAAQ,CAAC;AACvD,YAAY,IAAI,CAAC,MAAM,EAAE,OAAO,GAAG,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC;AAClD,YAAY,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC;AACtC,YAAY,OAAO,GAAG,OAAO,CAAC;AAC9B,SAAS;AACT;AACA,QAAQ,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;AAC3C,QAAQ,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;AAC5D,aAAa,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAClC,KAAK;AACL;AACA,IAAI,OAAO,OAAO,CAAC;AACnB,CAAC,CAAC;AACF;AACO,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,KAAK;AACxD,IAAI,IAAI,CAAC,KAAK,EAAE,OAAO,IAAI,CAAC;AAC5B,IAAI,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,IAAI,EAAE,OAAO,KAAK,CAAC;AAChE;AACA,IAAI,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AACpC,IAAI,KAAK,MAAM,MAAM,IAAI,MAAM,EAAE;AACjC,QAAQ,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,OAAO,KAAK,CAAC;AACtD,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,OAAO,IAAI,CAAC;AACtC,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,SAAS,EAAE,OAAO,KAAK,CAAC;AACxD,QAAQ,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;AAClC,KAAK;AACL;AACA,IAAI,MAAM,MAAM,GAAG,OAAO,OAAO,KAAK,QAAQ,CAAC;AAC/C,IAAI,MAAM,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC,IAAI,KAAK,GAAG,OAAO,CAAC;AACzD;AACA,IAAI,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC;AAC3B,CAAC;;AChEM,MAAM,OAAO;AACpB,IAAI,OAAO,MAAM,KAAK,WAAW;AACjC,UAAU,OAAO,MAAM,KAAK,WAAW;AACvC,cAAc,OAAO,IAAI,KAAK,WAAW;AACzC,kBAAkB,EAAE;AACpB,kBAAkB,IAAI;AACtB,cAAc,MAAM;AACpB,UAAU,MAAM,CAAC;AACjB;AACA,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,KAAK,SAAS,GAAG,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;AACvE;AACA,OAAO,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,KAAK,SAAS,GAAG,EAAE,GAAG,OAAO,CAAC,QAAQ,CAAC;AAC1E;AACA,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,KAAK,SAAS,GAAG,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC;AACjE;AACA,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,KAAK,SAAS,GAAG,KAAK,GAAG,OAAO,CAAC,MAAM;;AC/B1D,MAAC,aAAa,GAAG,KAAK,IAAI;AACtC,IAAI,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,KAAK;AAC/B,QAAQ,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC7D,KAAK,CAAC;AACN;;;;"}