# Enterprise SCIM Component

The Enterprise SCIM Component can be used to assist in creating, maintaining, and deleting a SCIM client for your customers.

## Installation

1. [Install shadcn](https://docs.byo.propelauth.com/component-library/installation) in your application.
2. 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](https://docs.byo.propelauth.com/scim/overview#one-scim-route-to-rule-them-all) for more information.

### api `ScimApi`

Includes four methods to be used to fetch, create, edit, and delete SCIM connections in your backend. See [below](https://docs.byo.propelauth.com/component-library/components/enterprise-scim#frontend-example) 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](https://docs.byo.propelauth.com/scim/management-reference#create-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](https://docs.byo.propelauth.com/scim/management-reference#reset-scim-connection-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](https://docs.byo.propelauth.com/scim/management-reference#delete-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](https://docs.byo.propelauth.com/scim/management-reference#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](https://docs.byo.propelauth.com/scim/management-reference#create-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](https://docs.byo.propelauth.com/scim/management-reference#reset-scim-connection-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

[Deletes a SCIM connection](https://docs.byo.propelauth.com/scim/management-reference#delete-scim-connection).

```
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 });
    }
});
```
