@opengis/fastify-table
Version:
core-plugins
106 lines (105 loc) • 4.54 kB
JavaScript
/* eslint-disable no-param-reassign */
/* eslint-disable camelcase */
/* eslint-disable no-nested-ternary */
import { join } from "node:path";
import { existsSync, readdirSync, readFileSync } from "node:fs";
import config from "../../../../config.js";
import pgClients from "../../../plugins/pg/pgClients.js";
import { applyHook } from "../../../../utils.js";
import menuDirs from "../../../plugins/table/funcs/menuDirs.js";
const menuCache = [];
// check module dir
const moduleDir = join(process.cwd(), "module");
const dirs = existsSync(moduleDir)
? readdirSync(moduleDir).map((el) => join(moduleDir, el, "menu.json"))
: [];
const isProduction = process.env.NODE_ENV === "production";
// readMenu();
async function readMenu() {
const menuList = dirs.concat(menuDirs).filter((el) => existsSync(el));
const list = menuList
.filter((el, idx, arr) => el && arr.indexOf(el) === idx)
.map((el) => readFileSync(el, "utf-8")); // sync
const menus = list
.reduce((p, el) => p.concat(JSON.parse(el)), [])
.map((el) => ({ order: 0, ...el }))
.sort((a, b) => a.order > b.order ? 1 : b.order > a.order ? -1 : 0);
if (!menuCache.length) {
menus.forEach((el) => menuCache.push(el));
}
return menus;
}
export default async function adminMenu({ user = {}, session, pg = pgClients.client, }, reply) {
const time = Date.now();
if (!user.uid && !config.auth?.disable && reply) {
return reply.status(403).send("access restricted");
}
const menus = isProduction && menuCache.length ? menuCache : await readMenu();
if (!pg)
return { menus };
const rows = pgClients.client?.pk?.["admin.properties"]
? await pgClients.client
.query(`select property_key as key,property_text as val from admin.properties where property_key~'^(${config.settingKeys || "site|map|admin"})'`)
.then((el) => el.rows || [])
: [];
const settings = rows.reduce((p, { key, val }) => {
const [k1, k2] = key.split(".");
p[k1] = p[k1] || {};
p[k1][k2] = val;
return p;
}, {});
if (config.settings)
Object.assign(settings, config.settings);
// update user access
const { user_name, sur_name, father_name, email, phone, uid } = user;
const result = {
settings,
user: {
uid,
user_name,
sur_name,
father_name,
email,
phone,
},
};
await applyHook("userMenu", result);
if (session &&
user?.uid &&
!user.user_type?.includes?.("admin") &&
!user.type?.includes?.("admin") &&
user.user_type !== "viewer" &&
pg.pk?.["admin.role_access"]) {
const { type, gl = [], routes = [], } = await pg
.query(`select user_type as type, b.gl,routes from admin.users a
left join lateral (
select array_agg(role_id) as gl from admin.user_roles
where user_uid=a.uid
and role_id in ( select role_id from admin.roles where enabled)
)b on 1=1
left join lateral (
select array_agg(route_id) as routes from admin.role_access where role_id=any(b.gl)
)r on 1=1
where uid=$1`, [user.uid])
.then((el) => el.rows[0] || {});
/* const { interfaces = [] } = await pg.query(`select array_agg(route_id) as interfaces from admin.role_access
where user_uid=$1 or role_id=any($2::text[])`, [user.uid, gl]).then((res) => res.rows?.[0] || {}); */
Object.assign(user, { type, group_list: gl, routes });
session?.set?.("passport", { user });
if (type?.includes?.("admin")) {
return { time: Date.now() - time, menus, ...result };
}
const userMenus = menus.map((el) => el.menu
? {
...el,
menu: el.menu.filter((item) => item.public || routes?.includes(item.path)),
}
: el);
const filtered = userMenus.filter((el) => el.menu?.length || el.public || routes?.includes(el.path));
return { time: Date.now() - time, menus: filtered, ...result };
// .filter((el, idx, arr) => arr.map((el) => el?.ua || el?.en || el?.name).indexOf(el?.ua || el?.en || el?.name) === idx)
}
// skip dupes?
// .filter((el, idx, arr) => arr.map((el) => el?.ua || el?.en || el?.name).indexOf(el?.ua || el?.en || el?.name) === idx)
return { time: Date.now() - time, menus, ...result };
}