@opengis/fastify-table
Version:
core-plugins
99 lines (78 loc) • 4.19 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 '../../../plugins/hook/funcs/applyHook.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) {
return reply.status(403).send('access restricted');
}
const menus = isProduction && menuCache.length ? menuCache : await readMenu();
const { rows } = await pgClients.client.query(`select property_key as key,property_text as val from admin.properties where property_key~'^(${config.settingKeys || 'site|map|admin'})'`);
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') && 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 => routes?.includes(item.path)) } : el));
const filtered = userMenus.filter(el => el.menu?.length || 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 };
}