PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.16
Yatra – Travel Booking & Tour Operator Software v3.0.16
3.0.16 3.0.15 3.0.14 3.0.14.1 3.0.14.2 3.0.12 3.0.13 3.0.11 3.0.10 3.0.9 3.0.8 3.0.7 3.0.6 3.0.5 3.0.5.1 3.0.4 3.0.3 3.0.2.9 3.0.2.7 3.0.2.8 3.0.2.6 trunk 1.0.0 2.0.0 2.0.1 All 84 releases
← All changes | resources/js/hooks/usePermissions.ts +67 -22 3.0.4 → 3.0.16 View file →
@@ -36,47 +36,92 @@
36 36 return window.yatraAdmin?.isPro || false;
37 37 }, []);
38 38
39 39 /**
40 - * Check if user has a specific capability
40 + * Check if the current user has a specific capability.
41 + *
42 + * Sources, in order:
43 + * 1. `window.yatraAdmin.capabilities` — server-built map of every
44 + * `yatra_*` cap the user passes via WP-native `current_user_can`.
45 + * Built by AdminAssetsProvider from `$current_user->allcaps`,
46 + * filtered to the `yatra_` prefix.
47 + * 2. `window.yatraAdmin.userCaps` — Team module's enriched list,
48 + * includes the same caps + anything added via the user_has_cap
49 + * filter (admin fallback, per-user grants, derived caps).
50 + * 3. `window.yatraAdmin.isWpAdmin` — last-resort fallback for site
51 + * owners so they're never locked out of anything.
52 + *
53 + * Default-deny when none match. The previous implementation had a
54 + * hardcoded "every user gets yatra_view_trips / yatra_edit_trips /
55 + * yatra_view_bookings" map that broke the Team & Access module — an
56 + * Accountant calling `can('yatra_edit_trips')` returned true via that
57 + * defaults map, leaking Tools / Modules / etc. into their UI even
58 + * though their role doesn't grant edit_trips.
59 + *
41 60 * @param capability - Capability to check
42 61 * @returns True if user has capability
43 62 */
44 63 const can = useCallback(
45 64 (capability: string): boolean => {
46 - // Check direct capabilities
65 + // 1) Server-built per-user cap map (yatra_* only).
47 66 if (capabilities[capability] === true) {
48 67 return true;
49 68 }
50 69
51 - // Check permissions array
70 + // 2) Team module's enriched userCaps list.
71 + const userCaps = (
72 + window.yatraAdmin as { userCaps?: string[] } | undefined
73 + )?.userCaps;
74 + if (Array.isArray(userCaps) && userCaps.includes(capability)) {
75 + return true;
76 + }
77 +
78 + // 3) Legacy permissions array (kept for back-compat with any
79 + // code path that pre-dates the capabilities map).
52 80 if (permissions.includes(capability)) {
53 81 return true;
54 82 }
55 83
56 - // Check for Pro-only features
84 + // 4) WP admin fallback — site owners pass everything.
85 + //
86 + // Belt-and-suspenders: we check THREE signals in case one of
87 + // them goes missing on a particular install. All three are
88 + // injected by AdminAssetsProvider, but defense in depth is
89 + // cheap and protects against:
90 + // - server-side filters stripping isWpAdmin from localized data
91 + // - JSON-encoding edge cases where booleans get coerced
92 + // - roles arrays that contain admin even when capabilities map
93 + // was built from a stale $current_user (page-cache + role
94 + // changes)
95 + const adm = window.yatraAdmin as
96 + | {
97 + isWpAdmin?: unknown;
98 + roles?: unknown;
99 + capabilities?: Record<string, unknown>;
100 + }
101 + | undefined;
102 + if (adm) {
103 + if (
104 + adm.isWpAdmin === true ||
105 + adm.isWpAdmin === "1" ||
106 + adm.isWpAdmin === 1
107 + ) {
108 + return true;
109 + }
110 + if (Array.isArray(adm.roles) && adm.roles.includes("administrator")) {
111 + return true;
112 + }
113 + if (adm.capabilities && adm.capabilities["manage_options"] === true) {
114 + return true;
115 + }
116 + }
117 +
118 + // 5) Pro-only check stays for completeness.
57 119 if (capability.startsWith("yatra_pro_") && !isPro) {
58 120 return false;
59 121 }
60 122
61 - // Default capabilities
62 - const defaultCapabilities: Record<string, boolean> = {
63 - manage_yatra: true, // Default admin capability
64 - yatra_view_trips: true,
65 - yatra_edit_trips: true,
66 - yatra_delete_trips: true,
67 - yatra_view_bookings: true,
68 - yatra_edit_bookings: true,
69 - yatra_delete_bookings: true,
70 - yatra_view_customers: true,
71 - yatra_edit_customers: true,
72 - yatra_delete_customers: true,
73 - yatra_view_reviews: true,
74 - yatra_edit_reviews: true,
75 - yatra_delete_reviews: true,
76 - };
77 -
78 - return defaultCapabilities[capability] || false;
123 + return false;
79 124 },
80 125 [capabilities, permissions, isPro],
81 126 );
82 127