Enterprise SCIM Component | PropelAuth BYO Documentation
Enterprise SCIM Component
The Enterprise SCIM Component can be used to assist in creating, maintaining, and deleting a SCIM client for your customers.
Installation
- Install shadcn in your application.
- Install the component.
npx shadcn@latest add https://components.propelauth.com/r/enterprise-scim.json
Properties
scimEndpointUrl string
The URL where you handle SCIM requests. See here for more information.
api ScimApi
Includes four methods to be used to fetch, create, edit, and delete SCIM connections in your backend. See below for an example.
get
() => Promise<ScimApiResult<ScimConfiguration>>;
A fetch request to your backend that expects hasApiKey and expiresAt in the response.
create
(params: {expiresAt?: number}) => Promise<ScimApiResult<{ scimApiKey: string }>>
A POST request to your backend to create a SCIM connection. Expects the SCIM API key in the response.
reset
(params: {expiresAt?: number}) => Promise<ScimApiResult<{ scimApiKey: string }>>
A PATCH request to your backend to reset a SCIM API Key. Expects the SCIM API key in the response.
remove
() => Promise<ScimApiResult<void>>
A DELETE request to your backend to delete a SCIM connection.
onGenerate (apiKey: string) => void (optional)
Callback when a new SCIM connection is generated.
onReset (apiKey: string) => void (optional)
Callback when a SCIM API Key is reset.
onDelete () => void (optional)
Callback when a SCIM connection is deleted.
Frontend Example
import ScimSetup from '@/components/scim/scim-setup';
import type { ScimApi } from '@/lib/scim/scim-types';
const api: ScimApi = {
async get() {
const r = await fetch(`/api/setup/scim`);
return { ok: true, data: await r.json() };
},
async create(body) {
const r = await fetch(`/api/setup/scim`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body),
});
return { ok: true, data: await r.json() };
},
async reset(body) {
const r = await fetch(`/api/setup/sso`, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body),
});
return { ok: true, data: await r.json() };
},
async remove() {
const r = await fetch(`/api/setup/sso`, { method: "DELETE" });
return await r.json();
},
};
export default function Page() {
return (
<ScimSetup
scimEndpointUrl="https://api.example.com/scim"
api={api}
onGenerate={(apiKey) => console.log('Generated:', apiKey)}
onReset={(apiKey) => console.log('Reset:', apiKey)}
onDelete={() => console.log('Deleted')}
/>
);
}
Backend Example
It is required to build four routes in your backend to use the SsoSetup component - each corresponding with one of the three methods included in the api argument detailed above.
GET
Use the Fetch SCIM Connection API to check if the customer has a connection.
router.get("/api/setup/scim", async (_req: Request, res: Response) => {
const result = await client.scim.management.fetchScimConnection({
customerId: "{your_id_for_your_customer}",
});
if (result.ok) {
const response = {
hasApiKey: true,
expiresAt: result.scimApiKeyValidUntil,
};
res.json(response);
} else {
const response = {
hasApiKey: false
};
res.json(response);
}
});
POST
Creates a SCIM connection using the expiresAt property sent from the frontend component.
router.post("/api/setup/scim", async (req: Request, res: Response) => {
const createResult = await client.scim.management.createScimConnection({
customerId: "{your_id_for_your_customer}",
scimApiKeyExpiration: req.body.expiresAt,
});
if (result.ok) {
const response = {
scimApiKey: createResult.data.scimApiKey,
};
res.json(response);
} else {
res.status(400).json({ error: result.error });
}
});
PUT
Resets the SCIM API Key using the expiresAt property sent from the frontend component.
router.put("/api/setup/scim", async (req: Request, res: Response) => {
const createResult = await client.scim.management.resetScimApiKey({
customerId: "{your_id_for_your_customer}",
scimApiKeyExpiration: req.body.expiresAt,
});
if (result.ok) {
const response = {
scimApiKey: createResult.data.scimApiKey,
};
res.json(response);
} else {
res.status(400).json({ error: result.error });
}
});
DELETE
router.delete("/api/setup/scim", async (_req: Request, res: Response) => {
const deleteResult = await client.sso.management.deleteScimConnection({
customerId: "{your_id_for_your_customer}",
});
if (deleteResult.ok) {
res.json({ message: "SCIM connection deleted successfully" });
} else {
res.status(404).json({ error: result.error });
}
});