ratty-blush
ratty-blush5d ago

how to pass custom params to access control of show page

I am using antdesign and nextjs. I have a show page like this
"use client";

import { Show } from "@refinedev/antd";
import { CanAccess, useParsed, useShow } from "@refinedev/core";
import { Typography } from "antd";
import { useParams } from "next/navigation";
import { useCompany } from "src/hooks/use-company";
import { Job } from "src/types/job.type";

export default function JobShow() {
const { id } = useParsed();
const companyId = useCompany();
const { query } = useShow<Job>({
resource: "job",
id,
meta: {
companyId,
},
});

return (
<Show>
<Typography.Title>{query.data?.data.title}</Typography.Title>
<Typography.Paragraph>{query.data?.data.description}</Typography.Paragraph>
</Show>
);
}
"use client";

import { Show } from "@refinedev/antd";
import { CanAccess, useParsed, useShow } from "@refinedev/core";
import { Typography } from "antd";
import { useParams } from "next/navigation";
import { useCompany } from "src/hooks/use-company";
import { Job } from "src/types/job.type";

export default function JobShow() {
const { id } = useParsed();
const companyId = useCompany();
const { query } = useShow<Job>({
resource: "job",
id,
meta: {
companyId,
},
});

return (
<Show>
<Typography.Title>{query.data?.data.title}</Typography.Title>
<Typography.Paragraph>{query.data?.data.description}</Typography.Paragraph>
</Show>
);
}
But from here how can i pass companyId to accesscontrol provider params?
2 Replies
kapa.ai
kapa.ai5d ago
Hi @Supa hot fire. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- To pass the companyId to the access control provider for your show page, you have a few options. Let me explain how you can do this: Option 1: Wrap your Show component with CanAccess The most straightforward approach is to wrap your <Show> component with the <CanAccess> component and pass the companyId as a parameter:
"use client";

import { Show } from "@refinedev/antd";
import { CanAccess, useParsed, useShow } from "@refinedev/core";
import { Typography } from "antd";
import { useParams } from "next/navigation";
import { useCompany } from "src/hooks/use-company";
import { Job } from "src/types/job.type";

export default function JobShow() {
const { id } = useParsed();
const companyId = useCompany();
const { query } = useShow<Job>({
resource: "job",
id,
meta: {
companyId,
},
});

return (
<CanAccess
resource="job"
action="show"
params={{ id, companyId }}
>
<Show>
<Typography.Title>{query.data?.data.title}</Typography.Title>
<Typography.Paragraph>{query.data?.data.description}</Typography.Paragraph>
</Show>
</CanAccess>
);
}
"use client";

import { Show } from "@refinedev/antd";
import { CanAccess, useParsed, useShow } from "@refinedev/core";
import { Typography } from "antd";
import { useParams } from "next/navigation";
import { useCompany } from "src/hooks/use-company";
import { Job } from "src/types/job.type";

export default function JobShow() {
const { id } = useParsed();
const companyId = useCompany();
const { query } = useShow<Job>({
resource: "job",
id,
meta: {
companyId,
},
});

return (
<CanAccess
resource="job"
action="show"
params={{ id, companyId }}
>
<Show>
<Typography.Title>{query.data?.data.title}</Typography.Title>
<Typography.Paragraph>{query.data?.data.description}</Typography.Paragraph>
</Show>
</CanAccess>
);
}
This approach allows you to explicitly pass the companyId to the access control provider through the params property of the <CanAccess> component CanAccess Component. Option 2: Disable built-in access control in Show and handle it manually Another approach is to disable the built-in access control in the <Show> component and handle it manually:
"use client";
import { Show } from "@refinedev/antd";
import { useCan, useParsed, useShow } from "@refinedev/core";
import { Typography } from "antd";
import { useParams } from "next/navigation";
import { useCompany } from "src/hooks/use-company";
import { Job } from "src/types/job.type";

export default function JobShow() {
const { id } = useParsed();
const companyId = useCompany();
const { query } = useShow<Job>({
resource: "job",
id,
meta: {
companyId,
},
});

const { data: canAccess } = useCan({
resource: "job",
action: "show",
params: { id, companyId }
});

if (!canAccess?.can) {
return <div>You don't have permission to view this job.</div>;
}

return (
<Show>
<Typography.Title>{query.data?.data.title}</Typography.Title>
<Typography.Paragraph>{query.data?.data.description}</Typography.Paragraph>
</Show>
);
}
"use client";
import { Show } from "@refinedev/antd";
import { useCan, useParsed, useShow } from "@refinedev/core";
import { Typography } from "antd";
import { useParams } from "next/navigation";
import { useCompany } from "src/hooks/use-company";
import { Job } from "src/types/job.type";

export default function JobShow() {
const { id } = useParsed();
const companyId = useCompany();
const { query } = useShow<Job>({
resource: "job",
id,
meta: {
companyId,
},
});

const { data: canAccess } = useCan({
resource: "job",
action: "show",
params: { id, companyId }
});

if (!canAccess?.can) {
return <div>You don't have permission to view this job.</div>;
}

return (
<Show>
<Typography.Title>{query.data?.data.title}</Typography.Title>
<Typography.Paragraph>{query.data?.data.description}</Typography.Paragraph>
</Show>
);
}
In this approach, you're using the useCan hook to check permissions manually with your custom parameters useCan Hook. How Access Control Works When you use the <Show> component, it internally checks for access control using the resource and action parameters. However, it doesn't automatically pass custom parameters like your companyId. In your access control provider implementation, you would handle these parameters like this:
const accessControlProvider = {
can: async ({ resource, action, params }) => {
// Here params will contain the id and companyId you passed
if (resource === "job" && action === "show") {
const { id, companyId } = params;

// Your authorization logic using companyId
// ...

return { can: true }; // or { can: false, reason: "Unauthorized" }
}

return { can: true };
}
};
const accessControlProvider = {
can: async ({ resource, action, params }) => {
// Here params will contain the id and companyId you passed
if (resource === "job" && action === "show") {
const { id, companyId } = params;

// Your authorization logic using companyId
// ...

return { can: true }; // or { can: false, reason: "Unauthorized" }
}

return { can: true };
}
};
This way, your access control provider can make decisions based on both the job ID and the company ID. Remember that the params object in your access control provider will contain all the parameters you pass to the <CanAccess> component or the useCan hook. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai5d ago
<@541506908301819930> Kapa.ai is still learning and improving, please let me know how I did by reacting below.

Did you find this page helpful?