fix: allow app admins to access MedSchedule UI and API

This commit is contained in:
2026-07-15 11:10:46 +03:00
parent 9c6eaa5dcf
commit 2b682d5ad3
2 changed files with 7 additions and 17 deletions

View File

@@ -1208,7 +1208,7 @@ function MedScheduleNavItem({ collapsed }: { collapsed: boolean }) {
const [location] = useLocation(); const [location] = useLocation();
const isActive = location === '/med' || location.startsWith('/med/'); const isActive = location === '/med' || location.startsWith('/med/');
if (user?.organization?.slug !== 'medschedule') return null; if (user?.organization?.slug !== 'medschedule' && !isAdmin(user)) return null;
if (collapsed) { if (collapsed) {
return ( return (

View File

@@ -2,7 +2,7 @@ import { Router } from "express";
import type { Express, Request, Response, NextFunction } from "express"; import type { Express, Request, Response, NextFunction } from "express";
import type { Response as ExpressResponse } from "express"; import type { Response as ExpressResponse } from "express";
import { authenticateToken, type AuthenticatedRequest } from "../middleware/auth.middleware"; import { authenticateToken, type AuthenticatedRequest } from "../middleware/auth.middleware";
import { tenantIsolation } from "../middleware/tenant.middleware";
import { medScheduleStorage } from "./storage"; import { medScheduleStorage } from "./storage";
interface MedRequest extends AuthenticatedRequest { interface MedRequest extends AuthenticatedRequest {
@@ -17,24 +17,16 @@ async function resolveMedOrganizationId(): Promise<number> {
return cachedMedOrgId; return cachedMedOrgId;
} }
function medOrgResolver() {
return async (_req: Request, _res: Response, next: NextFunction) => {
try {
await resolveMedOrganizationId();
next();
} catch (err) {
next(err as Error);
}
};
}
function requireMedOrganization() { function requireMedOrganization() {
return async (req: MedRequest, res: Response, next: NextFunction) => { return async (req: MedRequest, res: Response, next: NextFunction) => {
const medOrgId = await resolveMedOrganizationId(); const medOrgId = await resolveMedOrganizationId();
req.medOrganizationId = medOrgId; req.medOrganizationId = medOrgId;
// Если запрос от аутентифицированного пользователя, убедимся, что он принадлежит к org MedSchedule // MedSchedule API работает в контексте org medschedule, а не текущей org пользователя
if (req.user && req.user.organizationId !== medOrgId) { req.organizationId = medOrgId;
// Доступ разрешён либо членам org medschedule, либо администраторам приложения
if (req.user && req.user.organizationId !== medOrgId && req.user.appRole !== "admin") {
return res.status(403).json({ return res.status(403).json({
success: false, success: false,
error: "Этот раздел доступен только пользователям MedSchedule", error: "Этот раздел доступен только пользователям MedSchedule",
@@ -55,8 +47,6 @@ function parseDate(value: unknown): Date | null {
export function registerMedScheduleRoutes(app: Express) { export function registerMedScheduleRoutes(app: Express) {
const router = Router(); const router = Router();
router.use(authenticateToken); router.use(authenticateToken);
router.use(tenantIsolation);
router.use(medOrgResolver());
router.use(requireMedOrganization()); router.use(requireMedOrganization());
// ===================== // =====================