Skip to content

Commit 3c6ff6f

Browse files
waleedlatif1claude
andcommitted
test(scim): cover provisioning, the reconcile job, and group membership; say "token"
Provisioning use case (20), reconcile job (12), and the permission-group add/remove primitives (13) now have tests that assert call arguments, result fields, audit lists, and thrown status + scimType. User-facing wording is "token", as every provider labels it (Okta API Token, Entra Secret Token, OneLogin SCIM Bearer Token, JumpCloud Token Key), and to keep clear of Sim's own connected-account credentials. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DGXcwsHzYGp6pUDWRtJKpz
1 parent dede150 commit 3c6ff6f

10 files changed

Lines changed: 1113 additions & 26 deletions

File tree

apps/docs/content/docs/platform/enterprise/scim.mdx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,11 @@ https://<your-sim-domain>/api/scim/v2
5252
</Step>
5353

5454
<Step>
55-
### Issue a credential
55+
### Issue a token
5656

57-
Choose whether the credential expires (never, 90 days, or a year) and select **Issue credential**. The token appears once — copy it straight into your provider.
57+
Choose whether the token expires (never, 90 days, or a year) and select **Issue token**. It appears once — copy it straight into your provider.
5858

59-
Two credentials can be active at a time, so you can rotate without downtime: issue the new one, update your provider, confirm a sync succeeds, then revoke the old one.
59+
Two tokens can be active at a time, so you can rotate without downtime: issue the new one, update your provider, confirm a sync succeeds, then revoke the old one.
6060
</Step>
6161

6262
<Step>
@@ -70,7 +70,7 @@ In your Okta app, open **Provisioning → Integration** and select **Configure A
7070
- **SCIM connector base URL**: `https://<your-sim-domain>/api/scim/v2`
7171
- **Unique identifier field for users**: `userName`
7272
- **Supported provisioning actions**: Push New Users, Push Profile Updates, Push Groups
73-
- **Authentication Mode**: HTTP Header, with your Sim credential as the token
73+
- **Authentication Mode**: HTTP Header, with your Sim token
7474

7575
Select **Test API Credentials**, then save. Under **Provisioning → To App**, enable Create Users, Update User Attributes, and Deactivate Users.
7676

@@ -82,7 +82,7 @@ Okta never deletes users over SCIM. Unassigning someone, or deactivating them in
8282
In your enterprise application, open **Provisioning** and set Provisioning Mode to **Automatic**.
8383

8484
- **Tenant URL**: `https://<your-sim-domain>/api/scim/v2`
85-
- **Secret Token**: your Sim credential
85+
- **Secret Token**: your Sim token
8686

8787
Select **Test Connection**, then save and start provisioning.
8888

@@ -94,7 +94,7 @@ Entra runs an initial cycle over everyone in scope, then incremental cycles roug
9494
Add a **SCIM Provisioner with SAML** app.
9595

9696
- **SCIM Base URL**: `https://<your-sim-domain>/api/scim/v2`
97-
- **SCIM Bearer Token**: your Sim credential
97+
- **SCIM Bearer Token**: your Sim token
9898

9999
Enable provisioning and choose what happens when a user is removed. Suspend maps to a Sim suspension; Delete removes their membership.
100100

@@ -104,7 +104,7 @@ Enable provisioning and choose what happens when a user is removed. Suspend maps
104104
Add a **Custom SCIM** identity management integration.
105105

106106
- **Base URL**: `https://<your-sim-domain>/api/scim/v2`
107-
- **Token Key**: your Sim credential
107+
- **Token Key**: your Sim token
108108

109109
Enable group sync if you plan to map groups.
110110

@@ -154,7 +154,7 @@ Sim also re-applies every group mapping once an hour, so drift cannot persist. Y
154154
## Reference
155155

156156
- Base URL: `https://<your-sim-domain>/api/scim/v2`
157-
- Authentication: `Authorization: Bearer <credential>`
157+
- Authentication: `Authorization: Bearer <token>`
158158
- Resources: `/Users`, `/Groups`, plus `/ServiceProviderConfig`, `/ResourceTypes`, and `/Schemas`
159159
- Filters: `eq` only, up to ten terms joined with `and`. Users: `id`, `userName`, `externalId`, `emails.value` (also `emails[type eq "work"].value`), `active`. Groups: `id`, `displayName`, `externalId`
160160
- Limits: 1,500 requests per minute per connection, 1 MB per request, 5,000 members per group

apps/sim/ee/scim/components/scim-section.tsx

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ function ConnectionDetails({ organizationId, connection }: ConnectionDetailsProp
387387
})
388388
setIssuedSecret(result.secret)
389389
} catch (error) {
390-
toast.error(getErrorMessage(error, 'Failed to issue credential'))
390+
toast.error(getErrorMessage(error, 'Failed to issue token'))
391391
}
392392
}
393393

@@ -396,9 +396,9 @@ function ConnectionDetails({ organizationId, connection }: ConnectionDetailsProp
396396
try {
397397
await revokeCredential.mutateAsync({ organizationId, credentialId: pendingRevoke.id })
398398
setPendingRevoke(null)
399-
toast.success('Credential revoked')
399+
toast.success('Token revoked')
400400
} catch (error) {
401-
toast.error(getErrorMessage(error, 'Failed to revoke credential'))
401+
toast.error(getErrorMessage(error, 'Failed to revoke token'))
402402
}
403403
}
404404

@@ -457,12 +457,12 @@ function ConnectionDetails({ organizationId, connection }: ConnectionDetailsProp
457457
))}
458458

459459
<SettingRow
460-
label='Credentials'
460+
label='Tokens'
461461
description='The token is shown once. Two can be active at a time so you can rotate without downtime.'
462462
>
463463
<div className='flex flex-col gap-3'>
464464
{connection.credentials.length === 0 ? (
465-
<SettingsEmptyState variant='inline'>No credentials yet.</SettingsEmptyState>
465+
<SettingsEmptyState variant='inline'>No tokens yet.</SettingsEmptyState>
466466
) : (
467467
connection.credentials.map((credential) => (
468468
<CredentialRow
@@ -474,7 +474,7 @@ function ConnectionDetails({ organizationId, connection }: ConnectionDetailsProp
474474
)}
475475
<div className='flex flex-wrap items-center gap-2'>
476476
<ChipSelect
477-
aria-label='Credential expiry'
477+
aria-label='Token expiry'
478478
align='start'
479479
value={credentialExpiry}
480480
onChange={(next) => setCredentialExpiry(next as CredentialExpiry)}
@@ -485,7 +485,7 @@ function ConnectionDetails({ organizationId, connection }: ConnectionDetailsProp
485485
onClick={handleIssue}
486486
disabled={issueCredential.isPending || connection.credentials.length >= 2}
487487
>
488-
{issueCredential.isPending ? 'Issuing...' : 'Issue credential'}
488+
{issueCredential.isPending ? 'Issuing...' : 'Issue token'}
489489
</Chip>
490490
</div>
491491
</div>
@@ -541,11 +541,11 @@ function ConnectionDetails({ organizationId, connection }: ConnectionDetailsProp
541541
<ChipConfirmModal
542542
open={pendingRevoke !== null}
543543
onOpenChange={(open) => !open && setPendingRevoke(null)}
544-
title='Revoke credential'
544+
title='Revoke token'
545545
text={[
546546
'Revoke ',
547547
{ text: pendingRevoke?.tokenPrefix ?? '', bold: true },
548-
'? Your identity provider stops syncing the moment it next uses this token. Issue a new credential first if you are rotating.',
548+
'? Your identity provider stops syncing the moment it next uses this token. Issue a new token first if you are rotating.',
549549
]}
550550
confirm={{
551551
label: 'Revoke',

apps/sim/ee/scim/lib/application/admin/credentials.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ export const revokeScimCredential = defineAuthorizedScimAdminUseCase({
118118
connectionId: scimCredential.connectionId,
119119
})
120120

121-
if (!revoked) throw new OrchestrationError('not_found', 'Credential not found')
121+
if (!revoked) throw new OrchestrationError('not_found', 'Token not found')
122122
return { success: true as const, revoked }
123123
},
124124
projectAudit: ({ result }) => ({

apps/sim/ee/scim/lib/application/authorized-scim-use-case.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ async function loadActiveConnection(
8282
.limit(1)
8383

8484
if (!row || row.status !== 'active') {
85-
throw new ScimError(401, undefined, 'Invalid SCIM credential', {
85+
throw new ScimError(401, undefined, 'Invalid SCIM token', {
8686
'WWW-Authenticate': 'Bearer realm="SCIM"',
8787
})
8888
}

0 commit comments

Comments
 (0)