@maroonedsoftware/scim 0.3.2 → 0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/AGENTS.md CHANGED
@@ -80,13 +80,13 @@ contract is inseparable from HTTP.
80
80
 
81
81
  ### Errors
82
82
 
83
- | Export | Kind | Shape | Notes |
84
- | ----------------- | ---------- | ----------------------------------------------------------- | -------------------------------------------- |
85
- | `ScimError` | class | `extends HttpError` | So `errorMiddleware` already understands it. |
83
+ | Export | Kind | Shape | Notes |
84
+ | ----------------- | ---------- | ----------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
85
+ | `ScimError` | class | `extends HttpError` | So `errorMiddleware` already understands it. |
86
86
  | `scimError` | function | `(status, scimType?, statusText?) => ScimError` | The factory to use. The third argument is the HTTP status text; put the operator-facing reason on `.withDetails({ message })`, which `toScimBody` renders as `detail`. |
87
- | `IsScimError` | type guard | — | — |
88
- | `ScimErrorType` | type | `'invalidFilter'`, `'insufficientScope'`, `'mutability'`, … | RFC 7644 §3.12 `scimType` values. |
89
- | `ScimErrorSchema` | constant | The error envelope URN | — |
87
+ | `IsScimError` | type guard | — | — |
88
+ | `ScimErrorType` | type | `'invalidFilter'`, `'insufficientScope'`, `'mutability'`, … | RFC 7644 §3.12 `scimType` values. |
89
+ | `ScimErrorSchema` | constant | The error envelope URN | — |
90
90
 
91
91
  ### Repositories and services
92
92
 
@@ -95,21 +95,21 @@ contract is inseparable from HTTP.
95
95
  | `ScimUserRepository` | abstract class | Implement over your datastore. |
96
96
  | `ScimGroupRepository` | abstract class | Implement over your datastore. |
97
97
  | `ScimListQuery` | interface | `{ filter?: ScimFilterNode; startIndex; count; sortBy?; sortOrder?; attributes?; excludedAttributes? }` — **the parsed AST**, never the raw string. |
98
- | `projectScimResource` | function | `(resource, schemas: ScimSchema[], projection?) => resource` — applies `attributes` / `excludedAttributes` and strips `returned: 'never'`. |
99
- | `ScimProjection` | interface | `{ attributes?: string[]; excludedAttributes?: string[] }` |
98
+ | `projectScimResource` | function | `(resource, schemas: ScimSchema[], projection?) => resource` — applies `attributes` / `excludedAttributes` and strips `returned: 'never'`. |
99
+ | `ScimProjection` | interface | `{ attributes?: string[]; excludedAttributes?: string[] }` |
100
100
  | `ScimListResult<TResource>` | interface | `{ resources; totalResults }` — `totalResults` is the **filter-matching total**, not the page size. |
101
101
  | `ScimSortOrder` | type | `'ascending' \| 'descending'` |
102
102
  | `ScimUserService` / `ScimGroupService` / `ScimServiceProviderService` | class | Sit between the router and the repositories. |
103
103
 
104
104
  ### Middleware and router
105
105
 
106
- | Export | Kind | Shape | Notes |
107
- | --------------------------- | --------- | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
108
- | `scimErrorMiddleware` | function | `() => ServerKitMiddleware` | **Replaces** `errorMiddleware()` on the SCIM mountpoint. |
109
- | `scimContentTypeMiddleware` | function | `() => ServerKitMiddleware` | Enforces `application/scim+json`. |
110
- | `SCIM_MEDIA_TYPE` | constant | `'application/scim+json'` | — |
111
- | `requireScimScope` | function | `(scope: string) => ServerKitRouterMiddleware` | Reads `ctx.authenticationSession.claims.scimScopes`. `*` grants everything. |
112
- | `createScimRouter` | function | `(options: CreateScimRouterOptions) => Router<unknown, ServerKitContext>` | Mounts every endpoint below. |
106
+ | Export | Kind | Shape | Notes |
107
+ | --------------------------- | --------- | -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
108
+ | `scimErrorMiddleware` | function | `() => ServerKitMiddleware` | **Replaces** `errorMiddleware()` on the SCIM mountpoint. |
109
+ | `scimContentTypeMiddleware` | function | `() => ServerKitMiddleware` | Enforces `application/scim+json`. |
110
+ | `SCIM_MEDIA_TYPE` | constant | `'application/scim+json'` | — |
111
+ | `requireScimScope` | function | `(scope: string) => ServerKitRouterMiddleware` | Reads `ctx.authenticationSession.claims.scimScopes`. `*` grants everything. |
112
+ | `createScimRouter` | function | `(options: CreateScimRouterOptions) => Router<unknown, ServerKitContext>` | Mounts every endpoint below. |
113
113
  | `CreateScimRouterOptions` | interface | `{ userService, groupService, serviceProviderService, routeGuards?, maxResults?, baseUrl? }` | `maxResults` defaults to the service-provider config's `filter.maxResults`, then 200. Set `baseUrl` whenever the router is mounted under a prefix. |
114
114
 
115
115
  Endpoints mounted: `GET|POST /Users`, `GET|PUT|PATCH|DELETE /Users/:id`, `POST /Users/.search`, the
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types/list.response.ts","../src/types/patch.op.ts","../src/schemas/user.schema.ts","../src/schemas/group.schema.ts","../src/schemas/enterprise.user.schema.ts","../src/schemas/resource.type.schema.ts","../src/schemas/service.provider.config.schema.ts","../src/schemas/index.ts","../src/errors/scim.error.ts","../src/filter/filter.tokenizer.ts","../src/filter/filter.parser.ts","../src/patch/patch.applier.ts","../src/projection/attribute.projection.ts","../src/repositories/scim.user.repository.ts","../src/repositories/scim.group.repository.ts","../src/services/scim.user.service.ts","../src/services/scim.group.service.ts","../src/services/scim.service.provider.service.ts","../src/middleware/scim.content.type.middleware.ts","../src/middleware/scim.error.middleware.ts","../src/middleware/require.scim.scope.middleware.ts","../src/router/scim.router.ts"],"sourcesContent":["/**\n * Schema URI for the SCIM ListResponse message (RFC 7644 §3.4.2).\n */\nexport const ListResponseSchema = 'urn:ietf:params:scim:api:messages:2.0:ListResponse';\n\n/**\n * SCIM ListResponse envelope returned from list/search endpoints.\n */\nexport interface ScimListResponse<TResource> {\n schemas: [typeof ListResponseSchema];\n totalResults: number;\n startIndex?: number;\n itemsPerPage?: number;\n Resources?: TResource[];\n}\n","/**\n * Schema URI for the SCIM PatchOp message (RFC 7644 §3.5.2).\n */\nexport const PatchOpSchema = 'urn:ietf:params:scim:api:messages:2.0:PatchOp';\n\n/**\n * Operation kinds permitted in a SCIM PATCH request.\n * Case-insensitive on the wire; normalised internally.\n */\nexport type ScimPatchOpKind = 'add' | 'replace' | 'remove';\n\n/**\n * A single PATCH operation as it appears in a PatchOp request body.\n */\nexport interface ScimPatchOp {\n op: ScimPatchOpKind | Uppercase<ScimPatchOpKind> | Capitalize<ScimPatchOpKind>;\n path?: string;\n value?: unknown;\n}\n\n/**\n * The full PatchOp request envelope.\n */\nexport interface ScimPatchRequest {\n schemas: [typeof PatchOpSchema];\n Operations: ScimPatchOp[];\n}\n","import type { ScimAttributeDefinition, ScimSchema } from './schema.types.js';\n\n/** Schema URI for the SCIM core User resource. */\nexport const UserSchemaId = 'urn:ietf:params:scim:schemas:core:2.0:User';\n\n/**\n * RFC 7643 §4.1: SCIM core User schema definition. A condensed but\n * spec-compliant subset suitable for `/Schemas` discovery.\n */\nexport const userSchema: ScimSchema = {\n id: UserSchemaId,\n name: 'User',\n description: 'User Account',\n meta: { resourceType: 'Schema', location: `/Schemas/${UserSchemaId}` },\n attributes: [\n {\n name: 'userName',\n type: 'string',\n multiValued: false,\n description: 'Unique identifier for the User, typically used by the user to directly authenticate.',\n required: true,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'server',\n },\n {\n name: 'name',\n type: 'complex',\n multiValued: false,\n description: \"The components of the user's real name.\",\n required: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n subAttributes: [\n {\n name: 'formatted',\n type: 'string',\n multiValued: false,\n description: 'Full name formatted for display.',\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'familyName',\n type: 'string',\n multiValued: false,\n description: 'Family name (last name).',\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'givenName',\n type: 'string',\n multiValued: false,\n description: 'Given name (first name).',\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'middleName',\n type: 'string',\n multiValued: false,\n description: 'Middle name.',\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'honorificPrefix',\n type: 'string',\n multiValued: false,\n description: 'Honorific prefix (e.g., Ms., Dr.).',\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'honorificSuffix',\n type: 'string',\n multiValued: false,\n description: 'Honorific suffix (e.g., Jr., III).',\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n ],\n },\n {\n name: 'displayName',\n type: 'string',\n multiValued: false,\n description: 'Name displayed to end-users.',\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'nickName',\n type: 'string',\n multiValued: false,\n description: 'Casual name of the User.',\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'profileUrl',\n type: 'reference',\n multiValued: false,\n description: \"URL of the User's online profile.\",\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n referenceTypes: ['external'],\n },\n {\n name: 'title',\n type: 'string',\n multiValued: false,\n description: 'Title of the User.',\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'userType',\n type: 'string',\n multiValued: false,\n description: 'Used to identify the relationship between the organization and the user.',\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'preferredLanguage',\n type: 'string',\n multiValued: false,\n description: 'Preferred language as per RFC 7231.',\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'locale',\n type: 'string',\n multiValued: false,\n description: 'Default location of the User.',\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'timezone',\n type: 'string',\n multiValued: false,\n description: 'Time zone in IANA format.',\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'active',\n type: 'boolean',\n multiValued: false,\n description: 'Whether the user is active.',\n required: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'password',\n type: 'string',\n multiValued: false,\n description: 'Cleartext password (write-only).',\n required: false,\n caseExact: false,\n mutability: 'writeOnly',\n returned: 'never',\n uniqueness: 'none',\n },\n {\n name: 'emails',\n type: 'complex',\n multiValued: true,\n description: 'Email addresses for the user.',\n required: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n subAttributes: multiValuedSubAttrs('email'),\n },\n {\n name: 'phoneNumbers',\n type: 'complex',\n multiValued: true,\n description: 'Phone numbers for the user.',\n required: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n subAttributes: multiValuedSubAttrs('phone'),\n },\n {\n name: 'groups',\n type: 'complex',\n multiValued: true,\n description: 'Groups the user is a member of (read-only).',\n required: false,\n mutability: 'readOnly',\n returned: 'default',\n uniqueness: 'none',\n subAttributes: [\n {\n name: 'value',\n type: 'string',\n multiValued: false,\n description: 'Identifier of the Group.',\n required: false,\n caseExact: true,\n mutability: 'readOnly',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: '$ref',\n type: 'reference',\n multiValued: false,\n description: 'URI of the Group resource.',\n required: false,\n caseExact: true,\n mutability: 'readOnly',\n returned: 'default',\n uniqueness: 'none',\n referenceTypes: ['Group'],\n },\n {\n name: 'display',\n type: 'string',\n multiValued: false,\n description: 'Human-readable Group name.',\n required: false,\n caseExact: false,\n mutability: 'readOnly',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'type',\n type: 'string',\n multiValued: false,\n description: 'Membership type.',\n required: false,\n caseExact: false,\n mutability: 'readOnly',\n returned: 'default',\n uniqueness: 'none',\n canonicalValues: ['direct', 'indirect'],\n },\n ],\n },\n ],\n};\n\nfunction multiValuedSubAttrs(kind: string): ScimAttributeDefinition[] {\n return [\n {\n name: 'value',\n type: 'string',\n multiValued: false,\n description: `${kind} value.`,\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'display',\n type: 'string',\n multiValued: false,\n description: 'Human-readable display value.',\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'type',\n type: 'string',\n multiValued: false,\n description: `Function of the ${kind} (e.g., work, home).`,\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'primary',\n type: 'boolean',\n multiValued: false,\n description: 'Whether this is the primary value.',\n required: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n ];\n}\n","import type { ScimSchema } from './schema.types.js';\n\n/** Schema URI for the SCIM core Group resource. */\nexport const GroupSchemaId = 'urn:ietf:params:scim:schemas:core:2.0:Group';\n\n/**\n * RFC 7643 §4.2: SCIM core Group schema definition.\n */\nexport const groupSchema: ScimSchema = {\n id: GroupSchemaId,\n name: 'Group',\n description: 'Group',\n meta: { resourceType: 'Schema', location: `/Schemas/${GroupSchemaId}` },\n attributes: [\n {\n name: 'displayName',\n type: 'string',\n multiValued: false,\n description: 'Human-readable name for the Group.',\n required: true,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'members',\n type: 'complex',\n multiValued: true,\n description: 'List of Group members.',\n required: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n subAttributes: [\n {\n name: 'value',\n type: 'string',\n multiValued: false,\n description: 'Identifier of the member.',\n required: false,\n caseExact: true,\n mutability: 'immutable',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: '$ref',\n type: 'reference',\n multiValued: false,\n description: 'URI of the member resource.',\n required: false,\n caseExact: true,\n mutability: 'immutable',\n returned: 'default',\n uniqueness: 'none',\n referenceTypes: ['User', 'Group'],\n },\n {\n name: 'display',\n type: 'string',\n multiValued: false,\n description: 'Human-readable name of the member.',\n required: false,\n caseExact: false,\n mutability: 'immutable',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'type',\n type: 'string',\n multiValued: false,\n description: 'Member type.',\n required: false,\n caseExact: false,\n mutability: 'immutable',\n returned: 'default',\n uniqueness: 'none',\n canonicalValues: ['User', 'Group'],\n },\n ],\n },\n ],\n};\n","import type { ScimSchema } from './schema.types.js';\n\n/** Schema URI for the SCIM EnterpriseUser extension. */\nexport const EnterpriseUserSchemaId = 'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User';\n\n/**\n * RFC 7643 §4.3: EnterpriseUser extension schema definition.\n */\nexport const enterpriseUserSchema: ScimSchema = {\n id: EnterpriseUserSchemaId,\n name: 'EnterpriseUser',\n description: 'Enterprise User extension',\n meta: { resourceType: 'Schema', location: `/Schemas/${EnterpriseUserSchemaId}` },\n attributes: [\n {\n name: 'employeeNumber',\n type: 'string',\n multiValued: false,\n description: 'Employee number.',\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'costCenter',\n type: 'string',\n multiValued: false,\n description: 'Cost center.',\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'organization',\n type: 'string',\n multiValued: false,\n description: 'Organization name.',\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'division',\n type: 'string',\n multiValued: false,\n description: 'Division name.',\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'department',\n type: 'string',\n multiValued: false,\n description: 'Department name.',\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'manager',\n type: 'complex',\n multiValued: false,\n description: 'The manager of the user.',\n required: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n subAttributes: [\n {\n name: 'value',\n type: 'string',\n multiValued: false,\n description: 'Manager user id.',\n required: false,\n caseExact: true,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: '$ref',\n type: 'reference',\n multiValued: false,\n description: 'URI of the manager User resource.',\n required: false,\n caseExact: true,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n referenceTypes: ['User'],\n },\n {\n name: 'displayName',\n type: 'string',\n multiValued: false,\n description: 'Manager display name.',\n required: false,\n caseExact: false,\n mutability: 'readOnly',\n returned: 'default',\n uniqueness: 'none',\n },\n ],\n },\n ],\n};\n","import { UserSchemaId } from './user.schema.js';\nimport { GroupSchemaId } from './group.schema.js';\nimport { EnterpriseUserSchemaId } from './enterprise.user.schema.js';\n\n/** Schema URI for the SCIM ResourceType resource. */\nexport const ResourceTypeSchemaId = 'urn:ietf:params:scim:schemas:core:2.0:ResourceType';\n\nexport interface ScimResourceType {\n schemas: [typeof ResourceTypeSchemaId];\n id: string;\n name: string;\n endpoint: string;\n description: string;\n schema: string;\n schemaExtensions?: Array<{ schema: string; required: boolean }>;\n meta: {\n resourceType: 'ResourceType';\n location?: string;\n };\n}\n\nexport const userResourceType: ScimResourceType = {\n schemas: [ResourceTypeSchemaId],\n id: 'User',\n name: 'User',\n endpoint: '/Users',\n description: 'User Account',\n schema: UserSchemaId,\n schemaExtensions: [{ schema: EnterpriseUserSchemaId, required: false }],\n meta: { resourceType: 'ResourceType', location: '/ResourceTypes/User' },\n};\n\nexport const groupResourceType: ScimResourceType = {\n schemas: [ResourceTypeSchemaId],\n id: 'Group',\n name: 'Group',\n endpoint: '/Groups',\n description: 'Group',\n schema: GroupSchemaId,\n meta: { resourceType: 'ResourceType', location: '/ResourceTypes/Group' },\n};\n","/** Schema URI for the SCIM ServiceProviderConfig resource. */\nexport const ServiceProviderConfigSchemaId = 'urn:ietf:params:scim:schemas:core:2.0:ServiceProviderConfig';\n\n/** Authentication scheme advertised by `/ServiceProviderConfig`. */\nexport interface ScimAuthenticationScheme {\n type: 'oauth' | 'oauth2' | 'oauthbearertoken' | 'httpbasic' | 'httpdigest';\n name: string;\n description: string;\n specUri?: string;\n documentationUri?: string;\n primary?: boolean;\n}\n\n/** Optional features the service provider supports (RFC 7643 §5). */\nexport interface ScimServiceProviderConfigOptions {\n documentationUri?: string;\n patch?: { supported: boolean };\n bulk?: { supported: boolean; maxOperations: number; maxPayloadSize: number };\n filter?: { supported: boolean; maxResults: number };\n changePassword?: { supported: boolean };\n sort?: { supported: boolean };\n etag?: { supported: boolean };\n authenticationSchemes?: ScimAuthenticationScheme[];\n}\n\n/** Materialised ServiceProviderConfig response. */\nexport interface ScimServiceProviderConfig extends Required<Omit<ScimServiceProviderConfigOptions, 'documentationUri' | 'authenticationSchemes'>> {\n schemas: [typeof ServiceProviderConfigSchemaId];\n documentationUri?: string;\n authenticationSchemes: ScimAuthenticationScheme[];\n meta: {\n resourceType: 'ServiceProviderConfig';\n location?: string;\n };\n}\n\nconst defaultBearer: ScimAuthenticationScheme = {\n type: 'oauthbearertoken',\n name: 'OAuth Bearer Token',\n description: 'Authentication scheme using the OAuth Bearer Token Standard.',\n specUri: 'https://www.rfc-editor.org/info/rfc6750',\n primary: true,\n};\n\n/**\n * Build a SCIM ServiceProviderConfig response object, layering caller options\n * over the toolkit's defaults (PATCH on, filter on, sort on; bulk/changePassword/etag off).\n */\nexport const buildServiceProviderConfig = (options: ScimServiceProviderConfigOptions = {}): ScimServiceProviderConfig => ({\n schemas: [ServiceProviderConfigSchemaId],\n documentationUri: options.documentationUri,\n patch: options.patch ?? { supported: true },\n bulk: options.bulk ?? { supported: false, maxOperations: 0, maxPayloadSize: 0 },\n filter: options.filter ?? { supported: true, maxResults: 200 },\n changePassword: options.changePassword ?? { supported: false },\n sort: options.sort ?? { supported: true },\n etag: options.etag ?? { supported: false },\n authenticationSchemes: options.authenticationSchemes ?? [defaultBearer],\n meta: { resourceType: 'ServiceProviderConfig', location: '/ServiceProviderConfig' },\n});\n","export * from './schema.types.js';\nexport * from './user.schema.js';\nexport * from './group.schema.js';\nexport * from './enterprise.user.schema.js';\nexport * from './resource.type.schema.js';\nexport * from './service.provider.config.schema.js';\n\nimport { userSchema } from './user.schema.js';\nimport { groupSchema } from './group.schema.js';\nimport { enterpriseUserSchema } from './enterprise.user.schema.js';\n\n/** All SCIM core + extension schemas this package ships. */\nexport const coreSchemas = [userSchema, groupSchema, enterpriseUserSchema];\n","import { HttpError, HttpStatusCodes, type HttpStatusMessage } from '@maroonedsoftware/errors';\n\n/** Schema URI for the SCIM Error message. */\nexport const ScimErrorSchema = 'urn:ietf:params:scim:api:messages:2.0:Error';\n\n/**\n * `scimType` values defined by RFC 7644 §3.12 plus the few extensions clients\n * commonly emit. Keep this open as `string` to allow vendor-specific values.\n */\nexport type ScimErrorType =\n | 'invalidFilter'\n | 'tooMany'\n | 'uniqueness'\n | 'mutability'\n | 'invalidSyntax'\n | 'invalidPath'\n | 'noTarget'\n | 'invalidValue'\n | 'invalidVers'\n | 'sensitive'\n | 'insufficientScope'\n | (string & {});\n\n/**\n * SCIM error envelope (RFC 7644 §3.12). The HTTP status comes from\n * the underlying {@link HttpError}; the JSON body matches:\n *\n * ```json\n * { \"schemas\": [\"urn:ietf:params:scim:api:messages:2.0:Error\"], \"status\": \"404\", \"scimType\": \"invalidPath\", \"detail\": \"...\" }\n * ```\n */\nexport class ScimError extends HttpError {\n /** SCIM-specific error subtype, see RFC 7644 §3.12. */\n readonly scimType?: ScimErrorType;\n\n constructor(statusCode: HttpStatusCodes, scimType?: ScimErrorType, message?: HttpStatusMessage<HttpStatusCodes>) {\n // No `Object.setPrototypeOf` here: `ServerkitError` restores the prototype from\n // `new.target`, which is already the right class. Pinning it to `ScimError.prototype`\n // would overwrite that and break `instanceof` for anything subclassing this.\n super(statusCode, message);\n this.scimType = scimType;\n }\n\n /**\n * Build the SCIM error JSON body for this error.\n *\n * `detail` prefers a string `message` from {@link ServerkitError.details}, falling\n * back to the error's own message. The package raises errors as\n * `scimError(409, 'uniqueness', 'Conflict').withDetails({ message: '...' })`, where\n * the constructor's third argument is only the HTTP status text; without this\n * preference every provisioning client would see `\"detail\": \"Conflict\"` and never\n * the reason.\n */\n toScimBody(): { schemas: [typeof ScimErrorSchema]; status: string; scimType?: ScimErrorType; detail?: string } {\n const detailFromDetails = this.details?.message;\n return {\n schemas: [ScimErrorSchema],\n status: String(this.statusCode),\n ...(this.scimType ? { scimType: this.scimType } : {}),\n detail: typeof detailFromDetails === 'string' ? detailFromDetails : this.message,\n };\n }\n}\n\n/** Type guard for {@link ScimError}. */\nexport const IsScimError = (error: unknown): error is ScimError => error instanceof ScimError;\n\n/**\n * Factory for building a SCIM-shaped HTTP error. The returned object behaves like\n * an {@link HttpError}, so chained `.withDetails()` / `.withCause()` /\n * `.withInternalDetails()` work as usual.\n *\n * @example\n * ```ts\n * throw scimError(400, 'invalidFilter', 'Bad Request');\n * ```\n */\nexport const scimError = <Status extends HttpStatusCodes>(\n statusCode: Status,\n scimType?: ScimErrorType,\n message?: HttpStatusMessage<Status>,\n): ScimError => new ScimError(statusCode, scimType, message);\n","import { scimError } from '../errors/scim.error.js';\n\nexport type ScimTokenKind =\n | 'identifier' // attribute path, including dots, colons, dashes, and URN segments\n | 'string'\n | 'number'\n | 'true'\n | 'false'\n | 'null'\n | 'and'\n | 'or'\n | 'not'\n | 'lparen'\n | 'rparen'\n | 'lbracket'\n | 'rbracket'\n | 'op'; // eq, ne, co, sw, ew, gt, ge, lt, le, pr\n\nexport interface ScimToken {\n kind: ScimTokenKind;\n /** For `identifier`/`string`/`op`: the textual value. For `number`: numeric. */\n value: string | number | boolean | null;\n /** Source position where the token starts. */\n start: number;\n}\n\nconst COMPARISON_OPS = new Set(['eq', 'ne', 'co', 'sw', 'ew', 'gt', 'ge', 'lt', 'le', 'pr']);\n\n/**\n * Tokenize a SCIM filter expression into a stream of {@link ScimToken}s.\n * Throws a `400 invalidFilter` SCIM error on malformed input.\n */\nexport const tokenizeScimFilter = (input: string): ScimToken[] => {\n const tokens: ScimToken[] = [];\n let i = 0;\n\n while (i < input.length) {\n const ch = input[i]!;\n\n if (ch === ' ' || ch === '\\t' || ch === '\\n' || ch === '\\r') {\n i += 1;\n continue;\n }\n\n if (ch === '(') {\n tokens.push({ kind: 'lparen', value: '(', start: i });\n i += 1;\n continue;\n }\n if (ch === ')') {\n tokens.push({ kind: 'rparen', value: ')', start: i });\n i += 1;\n continue;\n }\n if (ch === '[') {\n tokens.push({ kind: 'lbracket', value: '[', start: i });\n i += 1;\n continue;\n }\n if (ch === ']') {\n tokens.push({ kind: 'rbracket', value: ']', start: i });\n i += 1;\n continue;\n }\n\n if (ch === '\"') {\n const start = i;\n i += 1;\n let value = '';\n while (i < input.length && input[i] !== '\"') {\n if (input[i] === '\\\\' && i + 1 < input.length) {\n const next = input[i + 1]!;\n if (next === '\"' || next === '\\\\' || next === '/') {\n value += next;\n i += 2;\n continue;\n }\n if (next === 'n') {\n value += '\\n';\n i += 2;\n continue;\n }\n if (next === 't') {\n value += '\\t';\n i += 2;\n continue;\n }\n if (next === 'r') {\n value += '\\r';\n i += 2;\n continue;\n }\n if (next === 'b') {\n value += '\\b';\n i += 2;\n continue;\n }\n if (next === 'f') {\n value += '\\f';\n i += 2;\n continue;\n }\n throw scimError(400, 'invalidFilter', 'Bad Request').withDetails({ position: i, message: `Unsupported escape sequence \\\\${next}` });\n }\n value += input[i];\n i += 1;\n }\n if (i >= input.length) {\n throw scimError(400, 'invalidFilter', 'Bad Request').withDetails({ position: start, message: 'Unterminated string literal' });\n }\n i += 1; // consume closing quote\n tokens.push({ kind: 'string', value, start });\n continue;\n }\n\n if (ch === '-' || (ch >= '0' && ch <= '9')) {\n const start = i;\n let raw = '';\n if (ch === '-') {\n raw += ch;\n i += 1;\n }\n while (i < input.length && /[0-9]/.test(input[i]!)) {\n raw += input[i];\n i += 1;\n }\n if (input[i] === '.') {\n raw += '.';\n i += 1;\n while (i < input.length && /[0-9]/.test(input[i]!)) {\n raw += input[i];\n i += 1;\n }\n }\n if (input[i] === 'e' || input[i] === 'E') {\n raw += input[i];\n i += 1;\n if (input[i] === '+' || input[i] === '-') {\n raw += input[i];\n i += 1;\n }\n while (i < input.length && /[0-9]/.test(input[i]!)) {\n raw += input[i];\n i += 1;\n }\n }\n const num = Number(raw);\n if (Number.isNaN(num)) {\n throw scimError(400, 'invalidFilter', 'Bad Request').withDetails({ position: start, message: `Invalid numeric literal \"${raw}\"` });\n }\n tokens.push({ kind: 'number', value: num, start });\n continue;\n }\n\n if (isIdentifierStart(ch)) {\n const start = i;\n let raw = '';\n while (i < input.length && isIdentifierPart(input[i]!)) {\n raw += input[i];\n i += 1;\n }\n const lower = raw.toLowerCase();\n switch (lower) {\n case 'true':\n tokens.push({ kind: 'true', value: true, start });\n continue;\n case 'false':\n tokens.push({ kind: 'false', value: false, start });\n continue;\n case 'null':\n tokens.push({ kind: 'null', value: null, start });\n continue;\n case 'and':\n case 'or':\n case 'not':\n tokens.push({ kind: lower, value: lower, start });\n continue;\n }\n if (COMPARISON_OPS.has(lower)) {\n tokens.push({ kind: 'op', value: lower, start });\n continue;\n }\n tokens.push({ kind: 'identifier', value: raw, start });\n continue;\n }\n\n throw scimError(400, 'invalidFilter', 'Bad Request').withDetails({ position: i, message: `Unexpected character \"${ch}\"` });\n }\n\n return tokens;\n};\n\nconst isIdentifierStart = (ch: string): boolean => /[A-Za-z_$]/.test(ch);\n\nconst isIdentifierPart = (ch: string): boolean => /[A-Za-z0-9_.\\-:$]/.test(ch);\n","import { scimError } from '../errors/scim.error.js';\nimport type { ScimFilterNode, ScimComparisonOperator } from './filter.ast.js';\nimport { tokenizeScimFilter, type ScimToken } from './filter.tokenizer.js';\n\n/**\n * Parse a SCIM filter expression (RFC 7644 §3.4.2.2) into a typed AST.\n * Throws a `400 invalidFilter` SCIM error on malformed input.\n *\n * Operator precedence (highest first):\n * 1. parentheses, value-path brackets, `not(...)`\n * 2. comparison\n * 3. `and`\n * 4. `or`\n */\nexport const parseScimFilter = (input: string): ScimFilterNode => {\n const trimmed = input.trim();\n if (trimmed.length === 0) {\n throw scimError(400, 'invalidFilter', 'Bad Request').withDetails({ message: 'Filter is empty' });\n }\n const tokens = tokenizeScimFilter(trimmed);\n const parser = new Parser(tokens);\n const node = parser.parseOr();\n parser.expectEnd();\n return node;\n};\n\nclass Parser {\n private pos = 0;\n\n constructor(private readonly tokens: ScimToken[]) {}\n\n parseOr(): ScimFilterNode {\n let left = this.parseAnd();\n while (this.peek()?.kind === 'or') {\n this.consume();\n const right = this.parseAnd();\n left = { kind: 'logical', operator: 'or', left, right };\n }\n return left;\n }\n\n parseAnd(): ScimFilterNode {\n let left = this.parseUnary();\n while (this.peek()?.kind === 'and') {\n this.consume();\n const right = this.parseUnary();\n left = { kind: 'logical', operator: 'and', left, right };\n }\n return left;\n }\n\n parseUnary(): ScimFilterNode {\n const token = this.peek();\n if (token?.kind === 'not') {\n this.consume();\n this.expect('lparen', 'Expected \"(\" after \"not\"');\n const inner = this.parseOr();\n this.expect('rparen', 'Expected \")\" to close \"not(...)\"');\n return { kind: 'not', filter: inner };\n }\n if (token?.kind === 'lparen') {\n this.consume();\n const inner = this.parseOr();\n this.expect('rparen', 'Expected \")\"');\n return inner;\n }\n return this.parseComparisonOrValuePath();\n }\n\n parseComparisonOrValuePath(): ScimFilterNode {\n const token = this.peek();\n if (!token || token.kind !== 'identifier') {\n throw this.error(token, 'Expected attribute path');\n }\n this.consume();\n const attribute = String(token.value);\n\n const next = this.peek();\n if (next?.kind === 'lbracket') {\n this.consume();\n const inner = this.parseOr();\n this.expect('rbracket', 'Expected \"]\" to close value-path filter');\n return { kind: 'valuePath', attribute, filter: inner };\n }\n\n if (!next || next.kind !== 'op') {\n throw this.error(next, 'Expected comparison operator');\n }\n this.consume();\n const operator = String(next.value) as ScimComparisonOperator;\n\n if (operator === 'pr') {\n return { kind: 'comparison', attribute, operator };\n }\n\n const valueToken = this.peek();\n if (!valueToken) {\n throw this.error(valueToken, `Expected value after operator \"${operator}\"`);\n }\n this.consume();\n\n if (\n valueToken.kind === 'string' ||\n valueToken.kind === 'number' ||\n valueToken.kind === 'true' ||\n valueToken.kind === 'false' ||\n valueToken.kind === 'null'\n ) {\n return { kind: 'comparison', attribute, operator, value: valueToken.value as string | number | boolean | null };\n }\n throw this.error(valueToken, `Expected literal value after operator \"${operator}\"`);\n }\n\n expectEnd(): void {\n const remaining = this.peek();\n if (remaining) {\n throw this.error(remaining, 'Unexpected trailing tokens');\n }\n }\n\n private peek(): ScimToken | undefined {\n return this.tokens[this.pos];\n }\n\n private consume(): ScimToken | undefined {\n const token = this.tokens[this.pos];\n this.pos += 1;\n return token;\n }\n\n private expect(kind: ScimToken['kind'], message: string): ScimToken {\n const token = this.peek();\n if (!token || token.kind !== kind) {\n throw this.error(token, message);\n }\n this.consume();\n return token;\n }\n\n private error(token: ScimToken | undefined, message: string) {\n return scimError(400, 'invalidFilter', 'Bad Request').withDetails({\n message,\n position: token?.start ?? -1,\n });\n }\n}\n","import { scimError } from '../errors/scim.error.js';\nimport { parseScimFilter } from '../filter/filter.parser.js';\nimport type { ScimFilterNode } from '../filter/filter.ast.js';\nimport type { ScimPatchOp, ScimPatchOpKind } from '../types/patch.op.js';\n\n/**\n * Apply a SCIM PATCH operation list to a resource (RFC 7644 §3.5.2).\n * Returns a *new* object — the input is not mutated.\n *\n * Supports the standard `add` / `replace` / `remove` operations and the path\n * mini-language including dotted sub-attributes and value-path filters\n * (e.g. `emails[type eq \"work\"].value`).\n */\nexport const applyScimPatch = <T extends Record<string, unknown>>(resource: T, ops: ScimPatchOp[]): T => {\n // Deep-clone so mutations don't leak to the caller.\n let next: Record<string, unknown> = structuredClone(resource);\n for (const op of ops) {\n next = applyOne(next, op);\n }\n return next as T;\n};\n\nconst applyOne = (resource: Record<string, unknown>, op: ScimPatchOp): Record<string, unknown> => {\n const kind = normaliseOpKind(op.op);\n\n if (op.path === undefined || op.path === '') {\n if (kind === 'remove') {\n throw scimError(400, 'noTarget', 'Bad Request').withDetails({ message: '\"remove\" requires a path' });\n }\n if (typeof op.value !== 'object' || op.value === null || Array.isArray(op.value)) {\n throw scimError(400, 'invalidValue', 'Bad Request').withDetails({ message: 'Pathless add/replace requires an object value' });\n }\n return mergeObject(resource, op.value as Record<string, unknown>, kind);\n }\n\n const path = parsePatchPath(op.path);\n return applyAtPath(resource, path, kind, op.value);\n};\n\nconst normaliseOpKind = (op: ScimPatchOp['op']): ScimPatchOpKind => {\n const lower = String(op).toLowerCase();\n if (lower === 'add' || lower === 'replace' || lower === 'remove') return lower;\n throw scimError(400, 'invalidSyntax', 'Bad Request').withDetails({ message: `Unknown PATCH op \"${op}\"` });\n};\n\ninterface ParsedPath {\n /** Top-level attribute, possibly with sub-attribute segments. */\n segments: string[];\n /** Optional value-path filter applied to the leaf attribute. */\n filter?: ScimFilterNode;\n /** Sub-attribute applied after the value-path filter (e.g. `.value`). */\n filterSubAttr?: string;\n}\n\nconst parsePatchPath = (raw: string): ParsedPath => {\n // Split off optional `[...]filter` segment.\n const bracketStart = raw.indexOf('[');\n if (bracketStart === -1) {\n return { segments: raw.split('.').filter(Boolean) };\n }\n\n const bracketEnd = findMatchingBracket(raw, bracketStart);\n if (bracketEnd === -1) {\n throw scimError(400, 'invalidPath', 'Bad Request').withDetails({ message: 'Unterminated value-path filter' });\n }\n\n const head = raw.slice(0, bracketStart);\n const filterSrc = raw.slice(bracketStart + 1, bracketEnd);\n const tail = raw.slice(bracketEnd + 1);\n\n const segments = head.split('.').filter(Boolean);\n if (segments.length === 0) {\n throw scimError(400, 'invalidPath', 'Bad Request').withDetails({ message: 'Value-path filter requires a target attribute' });\n }\n\n const filter = parseScimFilter(filterSrc);\n\n let filterSubAttr: string | undefined;\n if (tail.length > 0) {\n if (!tail.startsWith('.')) {\n throw scimError(400, 'invalidPath', 'Bad Request').withDetails({ message: 'Expected \".\" after value-path filter' });\n }\n filterSubAttr = tail.slice(1);\n if (filterSubAttr.length === 0 || filterSubAttr.includes('[')) {\n throw scimError(400, 'invalidPath', 'Bad Request').withDetails({ message: 'Invalid sub-attribute after value-path filter' });\n }\n }\n\n return { segments, filter, filterSubAttr };\n};\n\nconst findMatchingBracket = (input: string, openIndex: number): number => {\n let depth = 0;\n let inString = false;\n for (let i = openIndex; i < input.length; i += 1) {\n const ch = input[i]!;\n if (inString) {\n if (ch === '\\\\') {\n i += 1;\n continue;\n }\n if (ch === '\"') inString = false;\n continue;\n }\n if (ch === '\"') {\n inString = true;\n continue;\n }\n if (ch === '[') depth += 1;\n else if (ch === ']') {\n depth -= 1;\n if (depth === 0) return i;\n }\n }\n return -1;\n};\n\nconst applyAtPath = (resource: Record<string, unknown>, path: ParsedPath, kind: ScimPatchOpKind, value: unknown): Record<string, unknown> => {\n const [head, ...rest] = path.segments;\n if (!head) {\n throw scimError(400, 'invalidPath', 'Bad Request').withDetails({ message: 'Empty PATCH path' });\n }\n\n if (path.filter && rest.length === 0) {\n return applyFilteredOp(resource, head, path.filter, path.filterSubAttr, kind, value);\n }\n\n if (rest.length === 0) {\n return applySimpleOp(resource, head, kind, value);\n }\n\n const child = resource[head];\n const childObj: Record<string, unknown> = isPlainObject(child) ? { ...child } : {};\n const updated = applyAtPath(childObj, { ...path, segments: rest }, kind, value);\n return { ...resource, [head]: updated };\n};\n\nconst applySimpleOp = (resource: Record<string, unknown>, attr: string, kind: ScimPatchOpKind, value: unknown): Record<string, unknown> => {\n if (kind === 'remove') {\n const next = { ...resource };\n delete next[attr];\n return next;\n }\n\n if (kind === 'replace') {\n return { ...resource, [attr]: value };\n }\n\n // add: for multi-valued attributes, append; otherwise replace.\n const existing = resource[attr];\n if (Array.isArray(existing) && Array.isArray(value)) {\n return { ...resource, [attr]: [...existing, ...value] };\n }\n if (Array.isArray(existing) && value !== undefined) {\n return { ...resource, [attr]: [...existing, value] };\n }\n if (existing === undefined && Array.isArray(value)) {\n return { ...resource, [attr]: [...value] };\n }\n if (isPlainObject(existing) && isPlainObject(value)) {\n return { ...resource, [attr]: { ...existing, ...value } };\n }\n return { ...resource, [attr]: value };\n};\n\nconst applyFilteredOp = (\n resource: Record<string, unknown>,\n attr: string,\n filter: ScimFilterNode,\n subAttr: string | undefined,\n kind: ScimPatchOpKind,\n value: unknown,\n): Record<string, unknown> => {\n const collection = resource[attr];\n if (!Array.isArray(collection)) {\n if (kind === 'add') {\n // Per RFC, add on a non-existent target creates it. For value-path on a\n // missing collection, the closest behaviour is to materialise the matched\n // item from the supplied value.\n return { ...resource, [attr]: [{ ...(value as Record<string, unknown>) }] };\n }\n throw scimError(400, 'noTarget', 'Bad Request').withDetails({ message: `Attribute \"${attr}\" is not multi-valued` });\n }\n\n const matched: number[] = [];\n collection.forEach((item, index) => {\n if (isPlainObject(item) && evaluateFilter(item, filter)) matched.push(index);\n });\n\n if (matched.length === 0 && kind !== 'add') {\n throw scimError(400, 'noTarget', 'Bad Request').withDetails({ message: `No items matched value-path filter on \"${attr}\"` });\n }\n\n if (kind === 'remove') {\n const next = collection.filter((_, idx) => !matched.includes(idx));\n return { ...resource, [attr]: next };\n }\n\n if (kind === 'add' && matched.length === 0) {\n const seed = isPlainObject(value) ? { ...value } : { value };\n return { ...resource, [attr]: [...collection, seed] };\n }\n\n const next = collection.map((item, idx) => {\n if (!matched.includes(idx) || !isPlainObject(item)) return item;\n if (subAttr !== undefined) {\n if (kind === 'replace' || kind === 'add') {\n return { ...item, [subAttr]: value };\n }\n }\n if (kind === 'replace') {\n return isPlainObject(value) ? { ...item, ...value } : value;\n }\n // add: shallow merge\n return isPlainObject(value) ? { ...item, ...value } : item;\n });\n return { ...resource, [attr]: next };\n};\n\nconst mergeObject = (target: Record<string, unknown>, source: Record<string, unknown>, kind: ScimPatchOpKind): Record<string, unknown> => {\n if (kind === 'replace') {\n return { ...target, ...source };\n }\n // add: deep-merge for nested objects, append for arrays\n const out: Record<string, unknown> = { ...target };\n for (const [key, val] of Object.entries(source)) {\n const existing = out[key];\n if (Array.isArray(existing) && Array.isArray(val)) {\n defineOwn(out, key, [...existing, ...val]);\n } else if (isPlainObject(existing) && isPlainObject(val)) {\n defineOwn(out, key, mergeObject(existing, val, kind));\n } else {\n defineOwn(out, key, val);\n }\n }\n return out;\n};\n\n/**\n * Assign a key without going through a setter. PATCH values come straight off\n * the request body, and plain assignment to `__proto__` invokes the inherited\n * setter and reparents the object instead of storing an attribute.\n */\nconst defineOwn = (target: Record<string, unknown>, key: string, value: unknown): void => {\n Object.defineProperty(target, key, { value, writable: true, enumerable: true, configurable: true });\n};\n\nconst evaluateFilter = (item: Record<string, unknown>, filter: ScimFilterNode): boolean => {\n switch (filter.kind) {\n case 'comparison':\n return evaluateComparison(item, filter.attribute, filter.operator, filter.value);\n case 'logical':\n return filter.operator === 'and'\n ? evaluateFilter(item, filter.left) && evaluateFilter(item, filter.right)\n : evaluateFilter(item, filter.left) || evaluateFilter(item, filter.right);\n case 'not':\n return !evaluateFilter(item, filter.filter);\n case 'valuePath': {\n const nested = item[filter.attribute];\n if (!Array.isArray(nested)) return false;\n return nested.some(child => isPlainObject(child) && evaluateFilter(child, filter.filter));\n }\n }\n};\n\nconst evaluateComparison = (item: Record<string, unknown>, attr: string, op: string, value: unknown): boolean => {\n const segments = attr.split('.');\n let current: unknown = item;\n for (const seg of segments) {\n if (!isPlainObject(current)) return false;\n current = current[seg];\n }\n if (op === 'pr') return current !== undefined && current !== null && current !== '';\n if (current === undefined || current === null) return false;\n\n switch (op) {\n case 'eq':\n return current === value;\n case 'ne':\n return current !== value;\n case 'co':\n return typeof current === 'string' && typeof value === 'string' && current.toLowerCase().includes(value.toLowerCase());\n case 'sw':\n return typeof current === 'string' && typeof value === 'string' && current.toLowerCase().startsWith(value.toLowerCase());\n case 'ew':\n return typeof current === 'string' && typeof value === 'string' && current.toLowerCase().endsWith(value.toLowerCase());\n case 'gt':\n return compareScalar(current, value) > 0;\n case 'ge':\n return compareScalar(current, value) >= 0;\n case 'lt':\n return compareScalar(current, value) < 0;\n case 'le':\n return compareScalar(current, value) <= 0;\n default:\n return false;\n }\n};\n\nconst compareScalar = (a: unknown, b: unknown): number => {\n if (typeof a === 'number' && typeof b === 'number') return a - b;\n const sa = String(a);\n const sb = String(b);\n if (sa < sb) return -1;\n if (sa > sb) return 1;\n return 0;\n};\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n};\n","import { ScimAttributeDefinition, ScimSchema } from '../schemas/schema.types.js';\n\n/**\n * Requested attribute projection for a SCIM response, from the `attributes` and\n * `excludedAttributes` query parameters (RFC 7644 §3.9). The two are mutually\n * exclusive; when a client sends both, `attributes` wins, being the more\n * restrictive of the pair.\n */\nexport interface ScimProjection {\n /** Attribute paths to return, in addition to those whose `returned` is `'always'`. */\n attributes?: string[];\n /** Attribute paths to omit. Attributes whose `returned` is `'always'` are never omitted. */\n excludedAttributes?: string[];\n}\n\n/**\n * Attributes every SCIM resource carries regardless of projection. RFC 7643 §7\n * treats `id`, `schemas`, and `meta` as `returned: 'always'`, but they are not\n * listed in the core schemas' `attributes` arrays, so they are matched by name.\n */\nconst ALWAYS_RETURNED = new Set(['id', 'schemas', 'meta']);\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n\n/**\n * Split an attribute path into segments, tolerating the fully-qualified form\n * clients send for extension attributes\n * (`urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:department`).\n * The URN prefix becomes its own leading segment so it lines up with the\n * extension's top-level key on the resource.\n */\nconst splitPath = (path: string): string[] => {\n const urnBoundary = path.lastIndexOf(':');\n if (urnBoundary === -1) return path.split('.');\n return [path.slice(0, urnBoundary), ...path.slice(urnBoundary + 1).split('.')];\n};\n\n/**\n * A set of requested attribute paths. Comparisons are case-insensitive, as SCIM\n * attribute names are (RFC 7643 §2.1).\n */\nclass PathSet {\n private readonly paths: string[][];\n\n constructor(paths: string[]) {\n this.paths = paths.map(p => splitPath(p).map(s => s.toLowerCase()));\n }\n\n get empty(): boolean {\n return this.paths.length === 0;\n }\n\n /** Whether `segments` is at or above a requested path — `name` matches a request for `name.givenName`. */\n coversOrLeadsTo(segments: string[]): boolean {\n const target = segments.map(s => s.toLowerCase());\n return this.paths.some(path => {\n const shared = Math.min(path.length, target.length);\n for (let i = 0; i < shared; i++) {\n if (path[i] !== target[i]) return false;\n }\n return true;\n });\n }\n\n /** Whether `segments` is at or below a requested path — `name.givenName` matches a request for `name`. */\n isAtOrBelow(segments: string[]): boolean {\n const target = segments.map(s => s.toLowerCase());\n return this.paths.some(path => {\n if (path.length > target.length) return false;\n return path.every((segment, i) => segment === target[i]);\n });\n }\n}\n\nconst findDefinition = (definitions: ScimAttributeDefinition[], name: string): ScimAttributeDefinition | undefined =>\n definitions.find(d => d.name.toLowerCase() === name.toLowerCase());\n\ntype ProjectionMode = 'include' | 'exclude' | 'default';\n\n/**\n * Project a SCIM resource for the wire.\n *\n * Two things happen here, and only the first is optional:\n *\n * 1. `attributes` / `excludedAttributes` are applied, per RFC 7644 §3.9.\n * 2. Attributes the schema declares `returned: 'never'` are stripped\n * unconditionally. `password` is the one that matters: it is `writeOnly` and\n * `never`, so a repository that round-trips whatever it stored must not be\n * able to hand it back to a provisioning client.\n *\n * Attributes declared `returned: 'request'` come back only when named in\n * `attributes`. Keys no schema defines — a repository's own bookkeeping field,\n * an extension the caller did not declare — are kept unless a projection\n * excludes them, since the package cannot know they are safe to drop.\n *\n * @param resource - The resource to project. Not mutated.\n * @param schemas - The resource's schemas: the core one first, then any\n * extensions. An extension's attributes are matched under the resource key\n * named by its schema `id`.\n * @param projection - The requested projection; omit for schema rules only.\n * @returns A new resource object with the projection applied.\n */\nexport const projectScimResource = <T extends Record<string, unknown>>(\n resource: T,\n schemas: ScimSchema[],\n projection: ScimProjection = {},\n): T => {\n const requested = new PathSet(projection.attributes ?? []);\n const excluded = new PathSet(projection.excludedAttributes ?? []);\n const mode: ProjectionMode = !requested.empty ? 'include' : !excluded.empty ? 'exclude' : 'default';\n\n const [core, ...extensions] = schemas;\n const extensionsById = new Map(extensions.map(schema => [schema.id.toLowerCase(), schema]));\n\n return projectObject(resource, core?.attributes ?? [], extensionsById, [], mode, requested, excluded) as T;\n};\n\nconst projectObject = (\n source: Record<string, unknown>,\n definitions: ScimAttributeDefinition[],\n extensionsById: Map<string, ScimSchema>,\n prefix: string[],\n mode: ProjectionMode,\n requested: PathSet,\n excluded: PathSet,\n): Record<string, unknown> => {\n const out: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(source)) {\n const segments = [...prefix, key];\n const extension = prefix.length === 0 ? extensionsById.get(key.toLowerCase()) : undefined;\n const definition = findDefinition(definitions, key);\n const alwaysReturned = definition?.returned === 'always' || (prefix.length === 0 && ALWAYS_RETURNED.has(key.toLowerCase()));\n\n if (definition?.returned === 'never') continue;\n\n if (!alwaysReturned) {\n if (mode === 'include' && !requested.coversOrLeadsTo(segments)) continue;\n if (mode === 'exclude' && excluded.isAtOrBelow(segments)) continue;\n if (mode !== 'include' && definition?.returned === 'request') continue;\n }\n\n // A schema extension is a nested object keyed by its URN; its attributes are\n // defined by the extension schema, not by the core one.\n if (extension && isPlainObject(value)) {\n out[key] = projectObject(value, extension.attributes, extensionsById, segments, mode, requested, excluded);\n continue;\n }\n\n const subDefinitions = definition?.subAttributes;\n if (subDefinitions && Array.isArray(value)) {\n out[key] = value.map(entry =>\n isPlainObject(entry) ? projectObject(entry, subDefinitions, extensionsById, segments, mode, requested, excluded) : entry,\n );\n continue;\n }\n if (subDefinitions && isPlainObject(value)) {\n out[key] = projectObject(value, subDefinitions, extensionsById, segments, mode, requested, excluded);\n continue;\n }\n\n out[key] = value;\n }\n\n return out;\n};\n","import type { ScimUser } from '../types/scim.user.js';\nimport type { ScimListQuery, ScimListResult } from './repository.types.js';\n\n/**\n * Storage contract for SCIM `User` resources. The package ships only this\n * abstract class — implement it against your datastore (Kysely, Prisma,\n * Drizzle, in-memory) and pass the instance to {@link createScimRouter}.\n *\n * Implementations are responsible for:\n * - Translating the parsed filter AST in {@link ScimListQuery.filter} into a\n * native query.\n * - Honouring `startIndex` (1-based) and `count` for pagination.\n * - Returning the total number of matching resources, not just the page size.\n * - Persisting `meta.created` / `meta.lastModified` timestamps.\n *\n * Modeled as an abstract class so the runtime reference is a valid InjectKit\n * token (interfaces aren't preserved at runtime).\n */\nexport abstract class ScimUserRepository {\n /** Look up a user by server-assigned id. Return `undefined` if not found. */\n abstract findById(id: string): Promise<ScimUser | undefined>;\n\n /** Look up a user by `userName` (case-insensitive per RFC 7643). */\n abstract findByUserName(userName: string): Promise<ScimUser | undefined>;\n\n /** Look up a user by `externalId` (client-supplied identifier). */\n abstract findByExternalId(externalId: string): Promise<ScimUser | undefined>;\n\n /** List users matching a parsed query. */\n abstract list(query: ScimListQuery): Promise<ScimListResult<ScimUser>>;\n\n /** Persist a fully-formed user. `id`, `schemas`, and `meta` are already populated by {@link ScimUserService}. */\n abstract create(user: ScimUser): Promise<ScimUser>;\n\n /** Replace the entirety of an existing user (PUT semantics). */\n abstract replace(id: string, user: ScimUser): Promise<ScimUser>;\n\n /** Delete a user by id. Implementations may treat missing ids as a no-op. */\n abstract delete(id: string): Promise<void>;\n}\n","import type { ScimGroup } from '../types/scim.group.js';\nimport type { ScimListQuery, ScimListResult } from './repository.types.js';\n\n/**\n * Storage contract for SCIM `Group` resources. See\n * {@link ScimUserRepository} for general implementation guidance.\n */\nexport abstract class ScimGroupRepository {\n /** Look up a group by server-assigned id. */\n abstract findById(id: string): Promise<ScimGroup | undefined>;\n\n /** Look up a group by `displayName`. */\n abstract findByDisplayName(displayName: string): Promise<ScimGroup | undefined>;\n\n /** Look up a group by `externalId`. */\n abstract findByExternalId(externalId: string): Promise<ScimGroup | undefined>;\n\n /** List groups matching a parsed query. */\n abstract list(query: ScimListQuery): Promise<ScimListResult<ScimGroup>>;\n\n /** Persist a new group. */\n abstract create(group: ScimGroup): Promise<ScimGroup>;\n\n /** Replace the entirety of an existing group (PUT semantics). */\n abstract replace(id: string, group: ScimGroup): Promise<ScimGroup>;\n\n /** Delete a group by id. */\n abstract delete(id: string): Promise<void>;\n}\n","import { randomUUID } from 'node:crypto';\nimport { DateTime } from 'luxon';\nimport { Injectable } from 'injectkit';\nimport { Logger } from '@maroonedsoftware/logger';\nimport { ScimUserRepository } from '../repositories/scim.user.repository.js';\nimport type { ScimListQuery, ScimListResult } from '../repositories/repository.types.js';\nimport type { ScimUser } from '../types/scim.user.js';\nimport type { ScimPatchOp } from '../types/patch.op.js';\nimport { applyScimPatch } from '../patch/patch.applier.js';\nimport { scimError } from '../errors/scim.error.js';\nimport { UserSchemaId } from '../schemas/user.schema.js';\nimport { EnterpriseUserSchemaId } from '../schemas/enterprise.user.schema.js';\n\n/**\n * Application service wrapping a {@link ScimUserRepository}. Owns id and meta\n * assignment, uniqueness enforcement, and PATCH application — keeping the\n * repository focused on storage concerns.\n */\n@Injectable()\nexport class ScimUserService {\n constructor(\n private readonly repository: ScimUserRepository,\n private readonly logger: Logger,\n ) {}\n\n /**\n * Fetch a single user by id.\n *\n * @throws {ScimError} 404 if no user exists with the given id.\n */\n async get(id: string): Promise<ScimUser> {\n const user = await this.repository.findById(id);\n if (!user) throw scimError(404, undefined, 'Not Found').withDetails({ message: `User \"${id}\" not found` });\n return user;\n }\n\n /**\n * List users matching a parsed SCIM query, returning the page plus the\n * total number of matches (for the `totalResults` envelope field).\n */\n async list(query: ScimListQuery): Promise<ScimListResult<ScimUser>> {\n return this.repository.list(query);\n }\n\n /**\n * Create a new user. Assigns a server-generated `id`, fills `meta.created`\n * and `meta.lastModified`, and ensures the resource's `schemas` includes the\n * core User URN (and the EnterpriseUser URN when the extension is present).\n *\n * An `id` on the payload is ignored: RFC 7643 §3.1 makes it readOnly and\n * server-assigned.\n *\n * @throws {ScimError} 400 `invalidValue` when `userName` is missing.\n * @throws {ScimError} 409 `uniqueness` when `userName` already exists.\n */\n async create(payload: Partial<ScimUser>): Promise<ScimUser> {\n if (!payload.userName) {\n throw scimError(400, 'invalidValue', 'Bad Request').withDetails({ message: '\"userName\" is required' });\n }\n const existing = await this.repository.findByUserName(payload.userName);\n if (existing) {\n throw scimError(409, 'uniqueness', 'Conflict').withDetails({ message: `userName \"${payload.userName}\" already exists` });\n }\n const now = DateTime.utc().toISO();\n // RFC 7643 §3.1 makes `id` server-assigned and readOnly. Honouring a client-supplied\n // one lets a POST collide with an existing record's primary key.\n const id = randomUUID();\n const user: ScimUser = {\n ...payload,\n id,\n userName: payload.userName,\n schemas: this.normaliseSchemas(payload.schemas, payload),\n meta: {\n resourceType: 'User',\n created: now,\n lastModified: now,\n location: `/Users/${id}`,\n },\n };\n this.logger.debug('scim: creating user', { id, userName: user.userName });\n return this.repository.create(user);\n }\n\n /**\n * Replace an existing user wholesale (PUT semantics). Preserves the original\n * `id` and `meta.created`; updates `meta.lastModified`.\n *\n * @throws {ScimError} 404 when no user exists with the given id.\n * @throws {ScimError} 400 `invalidValue` when `userName` is missing.\n * @throws {ScimError} 409 `uniqueness` when changing `userName` would collide\n * with another existing user.\n */\n async replace(id: string, payload: Partial<ScimUser>): Promise<ScimUser> {\n const existing = await this.repository.findById(id);\n if (!existing) throw scimError(404, undefined, 'Not Found').withDetails({ message: `User \"${id}\" not found` });\n if (!payload.userName) {\n throw scimError(400, 'invalidValue', 'Bad Request').withDetails({ message: '\"userName\" is required' });\n }\n if (payload.userName !== existing.userName) {\n const conflict = await this.repository.findByUserName(payload.userName);\n if (conflict && conflict.id !== id) {\n throw scimError(409, 'uniqueness', 'Conflict').withDetails({ message: `userName \"${payload.userName}\" already exists` });\n }\n }\n const now = DateTime.utc().toISO();\n const user: ScimUser = {\n ...payload,\n id,\n userName: payload.userName,\n schemas: this.normaliseSchemas(payload.schemas, payload),\n meta: {\n ...existing.meta,\n lastModified: now,\n location: existing.meta.location ?? `/Users/${id}`,\n },\n };\n return this.repository.replace(id, user);\n }\n\n /**\n * Apply a sequence of SCIM PATCH ops (RFC 7644 §3.5.2) and persist the\n * result via `replace`. Updates `meta.lastModified`.\n *\n * @throws {ScimError} 404 when no user exists with the given id.\n * @throws {ScimError} 400 propagated from {@link applyScimPatch} for invalid\n * paths, unknown ops, or no-target failures, or `invalidValue` when the patch\n * would remove the required `userName`.\n * @throws {ScimError} 409 `uniqueness` when the patch changes `userName` to a\n * value already owned by another user.\n */\n async patch(id: string, ops: ScimPatchOp[]): Promise<ScimUser> {\n const existing = await this.repository.findById(id);\n if (!existing) throw scimError(404, undefined, 'Not Found').withDetails({ message: `User \"${id}\" not found` });\n const patched = applyScimPatch(existing as unknown as Record<string, unknown>, ops) as unknown as ScimUser;\n if (!patched.userName) {\n throw scimError(400, 'invalidValue', 'Bad Request').withDetails({ message: '\"userName\" is required' });\n }\n if (patched.userName !== existing.userName) {\n const conflict = await this.repository.findByUserName(patched.userName);\n if (conflict && conflict.id !== id) {\n throw scimError(409, 'uniqueness', 'Conflict').withDetails({ message: `userName \"${patched.userName}\" already exists` });\n }\n }\n patched.id = existing.id;\n patched.meta = {\n ...existing.meta,\n lastModified: DateTime.utc().toISO(),\n };\n return this.repository.replace(id, patched);\n }\n\n /**\n * Delete a user by id.\n *\n * @throws {ScimError} 404 when no user exists with the given id.\n */\n async delete(id: string): Promise<void> {\n const existing = await this.repository.findById(id);\n if (!existing) throw scimError(404, undefined, 'Not Found').withDetails({ message: `User \"${id}\" not found` });\n await this.repository.delete(id);\n }\n\n private normaliseSchemas(provided: string[] | undefined, payload: Partial<ScimUser>): string[] {\n const schemas = new Set<string>(provided ?? []);\n schemas.add(UserSchemaId);\n if (payload[EnterpriseUserSchemaId]) {\n schemas.add(EnterpriseUserSchemaId);\n }\n return Array.from(schemas);\n }\n}\n","import { randomUUID } from 'node:crypto';\nimport { DateTime } from 'luxon';\nimport { Injectable } from 'injectkit';\nimport { Logger } from '@maroonedsoftware/logger';\nimport { ScimGroupRepository } from '../repositories/scim.group.repository.js';\nimport type { ScimListQuery, ScimListResult } from '../repositories/repository.types.js';\nimport type { ScimGroup } from '../types/scim.group.js';\nimport type { ScimPatchOp } from '../types/patch.op.js';\nimport { applyScimPatch } from '../patch/patch.applier.js';\nimport { scimError } from '../errors/scim.error.js';\nimport { GroupSchemaId } from '../schemas/group.schema.js';\n\n/**\n * Application service wrapping a {@link ScimGroupRepository}. Mirrors\n * {@link ScimUserService}: id/meta assignment, uniqueness on `displayName`,\n * and PATCH application.\n */\n@Injectable()\nexport class ScimGroupService {\n constructor(\n private readonly repository: ScimGroupRepository,\n private readonly logger: Logger,\n ) {}\n\n /**\n * Fetch a single group by id.\n *\n * @throws {ScimError} 404 when no group exists with the given id.\n */\n async get(id: string): Promise<ScimGroup> {\n const group = await this.repository.findById(id);\n if (!group) throw scimError(404, undefined, 'Not Found').withDetails({ message: `Group \"${id}\" not found` });\n return group;\n }\n\n /**\n * List groups matching a parsed SCIM query, returning the page plus the\n * total number of matches.\n */\n async list(query: ScimListQuery): Promise<ScimListResult<ScimGroup>> {\n return this.repository.list(query);\n }\n\n /**\n * Create a new group. Assigns a server-generated `id` and fills `meta`\n * timestamps. An `id` on the payload is ignored: RFC 7643 §3.1 makes it\n * readOnly and server-assigned.\n *\n * @throws {ScimError} 400 `invalidValue` when `displayName` is missing.\n * @throws {ScimError} 409 `uniqueness` when `displayName` already exists.\n */\n async create(payload: Partial<ScimGroup>): Promise<ScimGroup> {\n if (!payload.displayName) {\n throw scimError(400, 'invalidValue', 'Bad Request').withDetails({ message: '\"displayName\" is required' });\n }\n const existing = await this.repository.findByDisplayName(payload.displayName);\n if (existing) {\n throw scimError(409, 'uniqueness', 'Conflict').withDetails({ message: `displayName \"${payload.displayName}\" already exists` });\n }\n const now = DateTime.utc().toISO();\n // RFC 7643 §3.1 makes `id` server-assigned and readOnly. Honouring a client-supplied\n // one lets a POST collide with an existing record's primary key.\n const id = randomUUID();\n const group: ScimGroup = {\n ...payload,\n id,\n displayName: payload.displayName,\n schemas: this.normaliseSchemas(payload.schemas),\n meta: {\n resourceType: 'Group',\n created: now,\n lastModified: now,\n location: `/Groups/${id}`,\n },\n };\n this.logger.debug('scim: creating group', { id, displayName: group.displayName });\n return this.repository.create(group);\n }\n\n /**\n * Replace an existing group wholesale (PUT semantics). Preserves `id` and\n * `meta.created`; updates `meta.lastModified`.\n *\n * @throws {ScimError} 404 when no group exists with the given id.\n * @throws {ScimError} 400 `invalidValue` when `displayName` is missing.\n * @throws {ScimError} 409 `uniqueness` when changing `displayName` would collide.\n */\n async replace(id: string, payload: Partial<ScimGroup>): Promise<ScimGroup> {\n const existing = await this.repository.findById(id);\n if (!existing) throw scimError(404, undefined, 'Not Found').withDetails({ message: `Group \"${id}\" not found` });\n if (!payload.displayName) {\n throw scimError(400, 'invalidValue', 'Bad Request').withDetails({ message: '\"displayName\" is required' });\n }\n if (payload.displayName !== existing.displayName) {\n const conflict = await this.repository.findByDisplayName(payload.displayName);\n if (conflict && conflict.id !== id) {\n throw scimError(409, 'uniqueness', 'Conflict').withDetails({ message: `displayName \"${payload.displayName}\" already exists` });\n }\n }\n const now = DateTime.utc().toISO();\n const group: ScimGroup = {\n ...payload,\n id,\n displayName: payload.displayName,\n schemas: this.normaliseSchemas(payload.schemas),\n meta: {\n ...existing.meta,\n lastModified: now,\n location: existing.meta.location ?? `/Groups/${id}`,\n },\n };\n return this.repository.replace(id, group);\n }\n\n /**\n * Apply a sequence of SCIM PATCH ops and persist the result. Updates\n * `meta.lastModified`.\n *\n * @throws {ScimError} 404 when no group exists with the given id.\n * @throws {ScimError} 400 propagated from {@link applyScimPatch}.\n */\n async patch(id: string, ops: ScimPatchOp[]): Promise<ScimGroup> {\n const existing = await this.repository.findById(id);\n if (!existing) throw scimError(404, undefined, 'Not Found').withDetails({ message: `Group \"${id}\" not found` });\n const patched = applyScimPatch(existing as unknown as Record<string, unknown>, ops) as unknown as ScimGroup;\n patched.id = existing.id;\n patched.meta = {\n ...existing.meta,\n lastModified: DateTime.utc().toISO(),\n };\n return this.repository.replace(id, patched);\n }\n\n /**\n * Delete a group by id.\n *\n * @throws {ScimError} 404 when no group exists with the given id.\n */\n async delete(id: string): Promise<void> {\n const existing = await this.repository.findById(id);\n if (!existing) throw scimError(404, undefined, 'Not Found').withDetails({ message: `Group \"${id}\" not found` });\n await this.repository.delete(id);\n }\n\n private normaliseSchemas(provided: string[] | undefined): string[] {\n const schemas = new Set<string>(provided ?? []);\n schemas.add(GroupSchemaId);\n return Array.from(schemas);\n }\n}\n","import { Injectable } from 'injectkit';\nimport {\n buildServiceProviderConfig,\n type ScimServiceProviderConfig,\n type ScimServiceProviderConfigOptions,\n} from '../schemas/service.provider.config.schema.js';\nimport { coreSchemas } from '../schemas/index.js';\nimport { userResourceType, groupResourceType, type ScimResourceType } from '../schemas/resource.type.schema.js';\nimport type { ScimSchema } from '../schemas/schema.types.js';\nimport { scimError } from '../errors/scim.error.js';\n\n/**\n * Serves the SCIM discovery endpoints: `/ServiceProviderConfig`, `/Schemas`,\n * and `/ResourceTypes`. The config is fixed at construction time — what the\n * server advertises must match what the router actually implements.\n */\n@Injectable()\nexport class ScimServiceProviderService {\n private readonly config: ScimServiceProviderConfig;\n private readonly schemas: ScimSchema[];\n private readonly resourceTypes: ScimResourceType[];\n\n constructor(options: ScimServiceProviderConfigOptions = {}) {\n this.config = buildServiceProviderConfig(options);\n this.schemas = coreSchemas;\n this.resourceTypes = [userResourceType, groupResourceType];\n }\n\n /** The materialised `/ServiceProviderConfig` response. */\n getServiceProviderConfig(): ScimServiceProviderConfig {\n return this.config;\n }\n\n /** Every schema known to this server, served from `/Schemas`. */\n listSchemas(): ScimSchema[] {\n return this.schemas;\n }\n\n /**\n * Look up a single schema by its URN.\n *\n * @throws {ScimError} 404 if the URN is not registered.\n */\n getSchema(id: string): ScimSchema {\n const found = this.schemas.find(s => s.id === id);\n if (!found) throw scimError(404, undefined, 'Not Found').withDetails({ message: `Schema \"${id}\" not found` });\n return found;\n }\n\n /** Every resource type known to this server, served from `/ResourceTypes`. */\n listResourceTypes(): ScimResourceType[] {\n return this.resourceTypes;\n }\n\n /**\n * Look up a single resource type by id (e.g. `User`, `Group`).\n *\n * @throws {ScimError} 404 if the id is not registered.\n */\n getResourceType(id: string): ScimResourceType {\n const found = this.resourceTypes.find(rt => rt.id === id);\n if (!found) throw scimError(404, undefined, 'Not Found').withDetails({ message: `ResourceType \"${id}\" not found` });\n return found;\n }\n}\n","import type { ServerKitMiddleware } from '@maroonedsoftware/koa';\nimport { scimError } from '../errors/scim.error.js';\n\n/** SCIM media type per RFC 7644 §3.8. */\nexport const SCIM_MEDIA_TYPE = 'application/scim+json';\n\n/**\n * Enforce that mutating SCIM requests carry `Content-Type: application/scim+json`\n * (or `application/json`, which the spec accepts for backward compatibility),\n * and tag the response so it serialises with the SCIM media type.\n */\nexport const scimContentTypeMiddleware = (): ServerKitMiddleware => {\n return async (ctx, next) => {\n const method = ctx.method.toUpperCase();\n if (method === 'POST' || method === 'PUT' || method === 'PATCH') {\n const contentType = (ctx.request.headers['content-type'] ?? '').toLowerCase();\n if (contentType && !contentType.includes(SCIM_MEDIA_TYPE) && !contentType.includes('application/json')) {\n throw scimError(415, undefined, 'Unsupported Media Type').withDetails({\n message: `Content-Type must be ${SCIM_MEDIA_TYPE}`,\n });\n }\n }\n await next();\n if (ctx.body !== undefined && ctx.body !== null) {\n ctx.type = SCIM_MEDIA_TYPE;\n }\n };\n};\n","import type { ServerKitMiddleware } from '@maroonedsoftware/koa';\nimport { IsHttpError, IsServerkitError } from '@maroonedsoftware/errors';\nimport { IsScimError, ScimError, ScimErrorSchema } from '../errors/scim.error.js';\nimport { SCIM_MEDIA_TYPE } from './scim.content.type.middleware.js';\n\n/**\n * SCIM-shaped error middleware. Catches errors thrown by downstream handlers\n * and renders them as the RFC 7644 §3.12 envelope with `Content-Type:\n * application/scim+json`.\n *\n * Mount this *inside* a SCIM sub-router (or in front of the SCIM router on\n * its own Koa instance) — do not replace the application-wide\n * `errorMiddleware` from `@maroonedsoftware/koa` with it.\n */\nexport const scimErrorMiddleware = (): ServerKitMiddleware => {\n return async (ctx, next) => {\n try {\n await next();\n if (ctx.status === 404 && !ctx.body) {\n const status = 404;\n ctx.status = status;\n ctx.type = SCIM_MEDIA_TYPE;\n ctx.body = {\n schemas: [ScimErrorSchema],\n status: String(status),\n detail: `Not Found: ${ctx.URL.pathname}`,\n };\n }\n } catch (error) {\n if (IsScimError(error)) {\n respondWithScimError(ctx, error);\n ctx.app.emit('error', error, ctx);\n return;\n }\n if (IsHttpError(error)) {\n respondWithScimError(ctx, new ScimError(error.statusCode).withDetails(error.details ?? {}).withCause(error));\n ctx.app.emit('error', error, ctx);\n return;\n }\n const status = 500;\n const detail = IsServerkitError(error) ? error.message : 'Internal Server Error';\n ctx.status = status;\n ctx.type = SCIM_MEDIA_TYPE;\n ctx.body = {\n schemas: [ScimErrorSchema],\n status: String(status),\n detail,\n };\n ctx.app.emit('error', error, ctx);\n }\n };\n};\n\nconst respondWithScimError = (ctx: Parameters<ServerKitMiddleware>[0], error: ScimError): void => {\n ctx.status = error.statusCode;\n ctx.type = SCIM_MEDIA_TYPE;\n ctx.body = error.toScimBody();\n if (error.headers) {\n for (const [name, value] of Object.entries(error.headers)) {\n ctx.set(name, value);\n }\n }\n};\n","import type { ServerKitRouterMiddleware } from '@maroonedsoftware/koa';\nimport { invalidAuthenticationSession } from '@maroonedsoftware/authentication';\nimport { scimError } from '../errors/scim.error.js';\n\n/**\n * Router middleware enforcing that the current request carries a SCIM scope\n * on its authentication session. The scope list is read from\n * `ctx.authenticationSession.claims.scimScopes` — a string array the consumer\n * populates when minting the session for the bearer token.\n *\n * Wildcard scope `*` in the session grants every check.\n */\nexport const requireScimScope = (scope: string): ServerKitRouterMiddleware => {\n return async (ctx, next) => {\n const session = ctx.authenticationSession;\n if (!session || session === invalidAuthenticationSession) {\n throw scimError(401, undefined, 'Unauthorized')\n .addHeader('WWW-Authenticate', 'Bearer error=\"invalid_token\"')\n .withDetails({ message: 'Missing or invalid bearer token' });\n }\n const granted = session.claims?.scimScopes;\n if (!Array.isArray(granted) || (!granted.includes('*') && !granted.includes(scope))) {\n throw scimError(403, 'insufficientScope', 'Forbidden').withDetails({ message: `Scope \"${scope}\" required` });\n }\n await next();\n };\n};\n","import type { ServerKitContext, ServerKitRouterMiddleware } from '@maroonedsoftware/koa';\nimport { bodyParserMiddleware, ServerKitRouter } from '@maroonedsoftware/koa';\nimport type Router from '@koa/router';\nimport { ScimUserService } from '../services/scim.user.service.js';\nimport { ScimGroupService } from '../services/scim.group.service.js';\nimport { ScimServiceProviderService } from '../services/scim.service.provider.service.js';\nimport type { ScimUser } from '../types/scim.user.js';\nimport type { ScimGroup } from '../types/scim.group.js';\nimport { type ScimPatchOp, type ScimPatchRequest, PatchOpSchema } from '../types/patch.op.js';\nimport { ListResponseSchema, type ScimListResponse } from '../types/list.response.js';\nimport { type ScimListQuery, type ScimSortOrder } from '../repositories/repository.types.js';\nimport { parseScimFilter } from '../filter/filter.parser.js';\nimport { scimError } from '../errors/scim.error.js';\nimport { SCIM_MEDIA_TYPE } from '../middleware/scim.content.type.middleware.js';\nimport { projectScimResource, type ScimProjection } from '../projection/attribute.projection.js';\nimport { userSchema } from '../schemas/user.schema.js';\nimport { groupSchema } from '../schemas/group.schema.js';\nimport { enterpriseUserSchema } from '../schemas/enterprise.user.schema.js';\n\n/**\n * Options for {@link createScimRouter}. The caller constructs the three\n * services (wiring them to their backing repositories and a logger) and\n * hands them in.\n */\nexport interface CreateScimRouterOptions {\n /** Service handling all `/Users` endpoints. */\n userService: ScimUserService;\n /** Service handling all `/Groups` endpoints. */\n groupService: ScimGroupService;\n /** Service that owns `/Schemas`, `/ResourceTypes`, `/ServiceProviderConfig`. */\n serviceProviderService: ScimServiceProviderService;\n /** Optional middleware mounted on every route (e.g. `requireScimScope('users:read')`). */\n routeGuards?: ServerKitRouterMiddleware[];\n /**\n * Maximum page size returned from list endpoints. Defaults to the\n * `serviceProviderService` `filter.maxResults` value, falling back to 200.\n */\n maxResults?: number;\n /**\n * Absolute base URL this router is reachable at, e.g.\n * `https://api.example.com/scim/v2`. When set, `meta.location` and the\n * `Location` response header are rendered against it, as RFC 7643 §3.1 wants\n * a resource URI. Leave it unset to keep the previous behaviour of emitting a\n * root-relative path (`/Users/{id}`), which is wrong for any deployment that\n * mounts the router under a prefix.\n */\n baseUrl?: string;\n}\n\n/**\n * Build a SCIM 2.0 server router. Mount it inside a Koa app that already has\n * `serverKitContextMiddleware` and `authenticationMiddleware` configured, and\n * use `scimErrorMiddleware()` instead of the default `errorMiddleware()` for\n * the SCIM mountpoint.\n *\n * Endpoints (RFC 7644 §3.4):\n * - `GET /Users` — list users (with `filter`, `startIndex`, `count`, `sortBy`, `sortOrder`)\n * - `POST /Users` — create user\n * - `GET /Users/:id` — fetch one user\n * - `PUT /Users/:id` — replace user\n * - `PATCH /Users/:id` — apply PATCH ops\n * - `DELETE /Users/:id` — delete user\n * - `POST /Users/.search` — list-via-POST so large filters can be sent in the body\n * - Same six endpoints for `/Groups` and `/Groups/.search`\n * - `GET /Schemas`, `GET /Schemas/:id`\n * - `GET /ResourceTypes`, `GET /ResourceTypes/:id`\n * - `GET /ServiceProviderConfig`\n */\nexport const createScimRouter = (options: CreateScimRouterOptions): Router<unknown, ServerKitContext> => {\n const router = ServerKitRouter();\n const guards = options.routeGuards ?? [];\n const json = bodyParserMiddleware([SCIM_MEDIA_TYPE, 'application/json']);\n const maxResults = options.maxResults ?? options.serviceProviderService.getServiceProviderConfig().filter.maxResults ?? 200;\n const baseUrl = options.baseUrl?.replace(/\\/+$/, '');\n\n /**\n * Render a resource's `meta.location` against the configured base URL. The\n * services assign a root-relative path because they do not know where the\n * router is mounted; without a `baseUrl` that path is left as-is.\n */\n const withLocation = <T extends { id: string; meta: { location?: string } }>(resource: T, endpoint: 'Users' | 'Groups'): T =>\n baseUrl ? { ...resource, meta: { ...resource.meta, location: `${baseUrl}/${endpoint}/${resource.id}` } } : resource;\n\n // Discovery endpoints — RFC 7644 §4 says these MAY be unauthenticated. Apply\n // the route guards anyway so the consumer can decide.\n router.get('/ServiceProviderConfig', ...guards, async ctx => {\n ctx.body = options.serviceProviderService.getServiceProviderConfig();\n ctx.type = SCIM_MEDIA_TYPE;\n });\n\n router.get('/Schemas', ...guards, async ctx => {\n ctx.body = listEnvelope(options.serviceProviderService.listSchemas());\n ctx.type = SCIM_MEDIA_TYPE;\n });\n\n router.get('/Schemas/:id', ...guards, async ctx => {\n ctx.body = options.serviceProviderService.getSchema(ctx.params.id!);\n ctx.type = SCIM_MEDIA_TYPE;\n });\n\n router.get('/ResourceTypes', ...guards, async ctx => {\n ctx.body = listEnvelope(options.serviceProviderService.listResourceTypes());\n ctx.type = SCIM_MEDIA_TYPE;\n });\n\n router.get('/ResourceTypes/:id', ...guards, async ctx => {\n ctx.body = options.serviceProviderService.getResourceType(ctx.params.id!);\n ctx.type = SCIM_MEDIA_TYPE;\n });\n\n // Users\n router.get('/Users', ...guards, async ctx => {\n const query = parseListQueryFromUrl(ctx.query, maxResults);\n const result = await options.userService.list(query);\n ctx.body = listEnvelope(result.resources.map(user => projectUser(withLocation(user, 'Users'), query)), query, result.totalResults);\n ctx.type = SCIM_MEDIA_TYPE;\n });\n\n router.post('/Users/.search', ...guards, json, async ctx => {\n const requestBody = takeRequestBody(ctx);\n const query = parseListQueryFromBody(requestBody, maxResults);\n const result = await options.userService.list(query);\n ctx.body = listEnvelope(result.resources.map(user => projectUser(withLocation(user, 'Users'), query)), query, result.totalResults);\n ctx.type = SCIM_MEDIA_TYPE;\n });\n\n router.post('/Users', ...guards, json, async ctx => {\n const payload = takeRequestBody(ctx) as Partial<ScimUser>;\n const created = await options.userService.create(payload);\n ctx.status = 201;\n const located = withLocation(created, 'Users');\n ctx.body = projectUser(located, parseProjectionFromUrl(ctx.query));\n ctx.type = SCIM_MEDIA_TYPE;\n if (located.meta.location) ctx.set('Location', located.meta.location);\n });\n\n router.get('/Users/:id', ...guards, async ctx => {\n ctx.body = projectUser(withLocation(await options.userService.get(ctx.params.id!), 'Users'), parseProjectionFromUrl(ctx.query));\n ctx.type = SCIM_MEDIA_TYPE;\n });\n\n router.put('/Users/:id', ...guards, json, async ctx => {\n const payload = takeRequestBody(ctx) as Partial<ScimUser>;\n ctx.body = projectUser(withLocation(await options.userService.replace(ctx.params.id!, payload), 'Users'), parseProjectionFromUrl(ctx.query));\n ctx.type = SCIM_MEDIA_TYPE;\n });\n\n router.patch('/Users/:id', ...guards, json, async ctx => {\n const requestBody = takeRequestBody(ctx) as Partial<ScimPatchRequest>;\n const ops = validatePatchRequest(requestBody);\n ctx.body = projectUser(withLocation(await options.userService.patch(ctx.params.id!, ops), 'Users'), parseProjectionFromUrl(ctx.query));\n ctx.type = SCIM_MEDIA_TYPE;\n });\n\n router.delete('/Users/:id', ...guards, async ctx => {\n await options.userService.delete(ctx.params.id!);\n ctx.status = 204;\n });\n\n // Groups\n router.get('/Groups', ...guards, async ctx => {\n const query = parseListQueryFromUrl(ctx.query, maxResults);\n const result = await options.groupService.list(query);\n ctx.body = listEnvelope(result.resources.map(group => projectGroup(withLocation(group, 'Groups'), query)), query, result.totalResults);\n ctx.type = SCIM_MEDIA_TYPE;\n });\n\n router.post('/Groups/.search', ...guards, json, async ctx => {\n const requestBody = takeRequestBody(ctx);\n const query = parseListQueryFromBody(requestBody, maxResults);\n const result = await options.groupService.list(query);\n ctx.body = listEnvelope(result.resources.map(group => projectGroup(withLocation(group, 'Groups'), query)), query, result.totalResults);\n ctx.type = SCIM_MEDIA_TYPE;\n });\n\n router.post('/Groups', ...guards, json, async ctx => {\n const payload = takeRequestBody(ctx) as Partial<ScimGroup>;\n const created = await options.groupService.create(payload);\n ctx.status = 201;\n const located = withLocation(created, 'Groups');\n ctx.body = projectGroup(located, parseProjectionFromUrl(ctx.query));\n ctx.type = SCIM_MEDIA_TYPE;\n if (located.meta.location) ctx.set('Location', located.meta.location);\n });\n\n router.get('/Groups/:id', ...guards, async ctx => {\n ctx.body = projectGroup(withLocation(await options.groupService.get(ctx.params.id!), 'Groups'), parseProjectionFromUrl(ctx.query));\n ctx.type = SCIM_MEDIA_TYPE;\n });\n\n router.put('/Groups/:id', ...guards, json, async ctx => {\n const payload = takeRequestBody(ctx) as Partial<ScimGroup>;\n ctx.body = projectGroup(withLocation(await options.groupService.replace(ctx.params.id!, payload), 'Groups'), parseProjectionFromUrl(ctx.query));\n ctx.type = SCIM_MEDIA_TYPE;\n });\n\n router.patch('/Groups/:id', ...guards, json, async ctx => {\n const requestBody = takeRequestBody(ctx) as Partial<ScimPatchRequest>;\n const ops = validatePatchRequest(requestBody);\n ctx.body = projectGroup(withLocation(await options.groupService.patch(ctx.params.id!, ops), 'Groups'), parseProjectionFromUrl(ctx.query));\n ctx.type = SCIM_MEDIA_TYPE;\n });\n\n router.delete('/Groups/:id', ...guards, async ctx => {\n await options.groupService.delete(ctx.params.id!);\n ctx.status = 204;\n });\n\n return router;\n};\n\n/** Schemas a `/Users` response is projected against: the core one plus the enterprise extension. */\nconst userSchemas = [userSchema, enterpriseUserSchema];\n\n/**\n * Project a user for the wire. Applies the requested `attributes` /\n * `excludedAttributes` and always strips attributes the schema declares\n * `returned: 'never'` — notably `password`, which is `writeOnly` and must never\n * come back out of a repository that stored what it was given.\n */\nconst projectUser = (user: ScimUser, projection: ScimProjection): ScimUser =>\n projectScimResource(user as unknown as Record<string, unknown>, userSchemas, projection) as unknown as ScimUser;\n\n/** Project a group for the wire. See {@link projectUser}. */\nconst projectGroup = (group: ScimGroup, projection: ScimProjection): ScimGroup =>\n projectScimResource(group as unknown as Record<string, unknown>, [groupSchema], projection) as unknown as ScimGroup;\n\n/**\n * Read the `attributes` / `excludedAttributes` projection from a query string.\n * RFC 7644 §3.9 allows them on single-resource reads and writes as well as lists.\n */\nconst parseProjectionFromUrl = (query: ServerKitContext['query']): ScimProjection => ({\n attributes: parseCsvParam(pickStringParam(query, 'attributes')),\n excludedAttributes: parseCsvParam(pickStringParam(query, 'excludedAttributes')),\n});\n\n/**\n * `bodyParserMiddleware` writes the parsed request body to `ctx.parsedBody`\n * (distinct from `ctx.body`, which is the response). Return it for the handler.\n */\nconst takeRequestBody = (ctx: ServerKitContext): unknown => {\n return ctx.parsedBody;\n};\n\nconst parseListQueryFromUrl = (query: ServerKitContext['query'], maxResults: number): ScimListQuery => {\n const filterRaw = pickStringParam(query, 'filter');\n return {\n filter: filterRaw ? parseScimFilter(filterRaw) : undefined,\n startIndex: parsePositiveInt(pickStringParam(query, 'startIndex'), 1),\n count: clamp(parseCount(pickStringParam(query, 'count'), maxResults), 0, maxResults),\n sortBy: pickStringParam(query, 'sortBy'),\n sortOrder: parseSortOrder(pickStringParam(query, 'sortOrder')),\n attributes: parseCsvParam(pickStringParam(query, 'attributes')),\n excludedAttributes: parseCsvParam(pickStringParam(query, 'excludedAttributes')),\n };\n};\n\nconst parseListQueryFromBody = (body: unknown, maxResults: number): ScimListQuery => {\n if (!isPlainObject(body)) {\n throw scimError(400, 'invalidSyntax', 'Bad Request').withDetails({ message: 'Search body must be a JSON object' });\n }\n const filterRaw = typeof body.filter === 'string' ? body.filter : undefined;\n return {\n filter: filterRaw ? parseScimFilter(filterRaw) : undefined,\n startIndex: typeof body.startIndex === 'number' && body.startIndex > 0 ? Math.floor(body.startIndex) : 1,\n count: clamp(typeof body.count === 'number' ? Math.floor(body.count) : maxResults, 0, maxResults),\n sortBy: typeof body.sortBy === 'string' ? body.sortBy : undefined,\n sortOrder: parseSortOrder(typeof body.sortOrder === 'string' ? body.sortOrder : undefined),\n attributes: Array.isArray(body.attributes) ? body.attributes.filter((a): a is string => typeof a === 'string') : undefined,\n excludedAttributes: Array.isArray(body.excludedAttributes)\n ? body.excludedAttributes.filter((a): a is string => typeof a === 'string')\n : undefined,\n };\n};\n\nconst parseSortOrder = (raw: string | undefined): ScimSortOrder | undefined => {\n if (raw === 'ascending' || raw === 'descending') return raw;\n return undefined;\n};\n\n/**\n * Parse the `count` query parameter. RFC 7644 §3.4.2.4 gives a value below 1 its own\n * meaning — return no resources, but still report `totalResults` — which is the probe\n * Okta and Entra make when setting up a connection. A non-numeric or absent value\n * falls back to the configured page size.\n */\nconst parseCount = (raw: string | undefined, fallback: number): number => {\n if (raw === undefined) return fallback;\n const n = Number(raw);\n if (!Number.isFinite(n)) return fallback;\n return n < 1 ? 0 : Math.floor(n);\n};\n\nconst parsePositiveInt = (raw: string | undefined, fallback: number): number => {\n if (raw === undefined) return fallback;\n const n = Number(raw);\n if (!Number.isFinite(n) || n < 1) return fallback;\n return Math.floor(n);\n};\n\nconst clamp = (value: number, min: number, max: number): number => Math.max(min, Math.min(max, value));\n\nconst parseCsvParam = (raw: string | undefined): string[] | undefined => {\n if (!raw) return undefined;\n const parts = raw\n .split(',')\n .map(s => s.trim())\n .filter(Boolean);\n return parts.length > 0 ? parts : undefined;\n};\n\nconst pickStringParam = (query: ServerKitContext['query'], key: string): string | undefined => {\n const value = query[key];\n if (typeof value === 'string') return value;\n if (Array.isArray(value) && typeof value[0] === 'string') return value[0];\n return undefined;\n};\n\nconst validatePatchRequest = (body: Partial<ScimPatchRequest> | unknown): ScimPatchOp[] => {\n if (!isPlainObject(body)) {\n throw scimError(400, 'invalidSyntax', 'Bad Request').withDetails({ message: 'PATCH request must be a JSON object' });\n }\n if (!Array.isArray(body.schemas) || !body.schemas.includes(PatchOpSchema)) {\n throw scimError(400, 'invalidSyntax', 'Bad Request').withDetails({ message: `PATCH request schemas must include \"${PatchOpSchema}\"` });\n }\n if (!Array.isArray(body.Operations) || body.Operations.length === 0) {\n throw scimError(400, 'invalidValue', 'Bad Request').withDetails({ message: '\"Operations\" must be a non-empty array' });\n }\n return body.Operations as ScimPatchOp[];\n};\n\nconst listEnvelope = <T>(resources: T[], query?: ScimListQuery, total?: number): ScimListResponse<T> => ({\n schemas: [ListResponseSchema],\n totalResults: total ?? resources.length,\n startIndex: query?.startIndex ?? 1,\n itemsPerPage: resources.length,\n Resources: resources,\n});\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n};\n"],"mappings":"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","names":["ListResponseSchema","PatchOpSchema","UserSchemaId","userSchema","id","name","description","meta","resourceType","location","attributes","type","multiValued","required","caseExact","mutability","returned","uniqueness","subAttributes","referenceTypes","multiValuedSubAttrs","canonicalValues","kind","GroupSchemaId","groupSchema","id","name","description","meta","resourceType","location","attributes","type","multiValued","required","caseExact","mutability","returned","uniqueness","subAttributes","referenceTypes","canonicalValues","EnterpriseUserSchemaId","enterpriseUserSchema","id","name","description","meta","resourceType","location","attributes","type","multiValued","required","caseExact","mutability","returned","uniqueness","subAttributes","referenceTypes","ResourceTypeSchemaId","userResourceType","schemas","id","name","endpoint","description","schema","UserSchemaId","schemaExtensions","EnterpriseUserSchemaId","required","meta","resourceType","location","groupResourceType","GroupSchemaId","ServiceProviderConfigSchemaId","defaultBearer","type","name","description","specUri","primary","buildServiceProviderConfig","options","schemas","documentationUri","patch","supported","bulk","maxOperations","maxPayloadSize","filter","maxResults","changePassword","sort","etag","authenticationSchemes","meta","resourceType","location","coreSchemas","userSchema","groupSchema","enterpriseUserSchema","HttpError","ScimErrorSchema","ScimError","HttpError","scimType","statusCode","message","toScimBody","detailFromDetails","details","schemas","status","String","detail","IsScimError","error","scimError","COMPARISON_OPS","Set","tokenizeScimFilter","input","tokens","i","length","ch","push","kind","value","start","next","scimError","withDetails","position","message","raw","test","num","Number","isNaN","isIdentifierStart","isIdentifierPart","lower","toLowerCase","has","parseScimFilter","input","trimmed","trim","length","scimError","withDetails","message","tokens","tokenizeScimFilter","parser","Parser","node","parseOr","expectEnd","pos","left","parseAnd","peek","kind","consume","right","operator","parseUnary","token","expect","inner","filter","parseComparisonOrValuePath","error","attribute","String","value","next","valueToken","remaining","position","start","applyScimPatch","resource","ops","next","structuredClone","op","applyOne","kind","normaliseOpKind","path","undefined","scimError","withDetails","message","value","Array","isArray","mergeObject","parsePatchPath","applyAtPath","lower","String","toLowerCase","raw","bracketStart","indexOf","segments","split","filter","Boolean","bracketEnd","findMatchingBracket","head","slice","filterSrc","tail","length","parseScimFilter","filterSubAttr","startsWith","includes","input","openIndex","depth","inString","i","ch","rest","applyFilteredOp","applySimpleOp","child","childObj","isPlainObject","updated","attr","existing","subAttr","collection","matched","forEach","item","index","evaluateFilter","push","_","idx","seed","map","target","source","out","key","val","Object","entries","defineOwn","defineProperty","writable","enumerable","configurable","evaluateComparison","attribute","operator","left","right","nested","some","current","seg","endsWith","compareScalar","a","b","sa","sb","ALWAYS_RETURNED","Set","isPlainObject","value","Array","isArray","splitPath","path","urnBoundary","lastIndexOf","split","slice","PathSet","paths","map","p","s","toLowerCase","empty","length","coversOrLeadsTo","segments","target","some","shared","Math","min","i","isAtOrBelow","every","segment","findDefinition","definitions","name","find","d","projectScimResource","resource","schemas","projection","requested","attributes","excluded","excludedAttributes","mode","core","extensions","extensionsById","Map","schema","id","projectObject","source","prefix","out","key","Object","entries","extension","get","undefined","definition","alwaysReturned","returned","has","subDefinitions","subAttributes","entry","ScimUserRepository","ScimGroupRepository","randomUUID","DateTime","Injectable","Logger","ScimUserService","repository","logger","get","id","user","findById","scimError","undefined","withDetails","message","list","query","create","payload","userName","existing","findByUserName","now","DateTime","utc","toISO","randomUUID","schemas","normaliseSchemas","meta","resourceType","created","lastModified","location","debug","replace","conflict","patch","ops","patched","applyScimPatch","delete","provided","Set","add","UserSchemaId","EnterpriseUserSchemaId","Array","from","randomUUID","DateTime","Injectable","Logger","ScimGroupService","repository","logger","get","id","group","findById","scimError","undefined","withDetails","message","list","query","create","payload","displayName","existing","findByDisplayName","now","DateTime","utc","toISO","randomUUID","schemas","normaliseSchemas","meta","resourceType","created","lastModified","location","debug","replace","conflict","patch","ops","patched","applyScimPatch","delete","provided","Set","add","GroupSchemaId","Array","from","Injectable","ScimServiceProviderService","config","schemas","resourceTypes","options","buildServiceProviderConfig","coreSchemas","userResourceType","groupResourceType","getServiceProviderConfig","listSchemas","getSchema","id","found","find","s","scimError","undefined","withDetails","message","listResourceTypes","getResourceType","rt","SCIM_MEDIA_TYPE","scimContentTypeMiddleware","ctx","next","method","toUpperCase","contentType","request","headers","toLowerCase","includes","scimError","undefined","withDetails","message","body","type","IsHttpError","IsServerkitError","scimErrorMiddleware","ctx","next","status","body","type","SCIM_MEDIA_TYPE","schemas","ScimErrorSchema","String","detail","URL","pathname","error","IsScimError","respondWithScimError","app","emit","IsHttpError","ScimError","statusCode","withDetails","details","withCause","IsServerkitError","message","toScimBody","headers","name","value","Object","entries","set","invalidAuthenticationSession","requireScimScope","scope","ctx","next","session","authenticationSession","invalidAuthenticationSession","scimError","undefined","addHeader","withDetails","message","granted","claims","scimScopes","Array","isArray","includes","bodyParserMiddleware","ServerKitRouter","createScimRouter","options","router","ServerKitRouter","guards","routeGuards","json","bodyParserMiddleware","SCIM_MEDIA_TYPE","maxResults","serviceProviderService","getServiceProviderConfig","filter","baseUrl","replace","withLocation","resource","endpoint","meta","location","id","get","ctx","body","type","listEnvelope","listSchemas","getSchema","params","listResourceTypes","getResourceType","query","parseListQueryFromUrl","result","userService","list","resources","map","user","projectUser","totalResults","post","requestBody","takeRequestBody","parseListQueryFromBody","payload","created","create","status","located","parseProjectionFromUrl","set","put","patch","ops","validatePatchRequest","delete","groupService","group","projectGroup","userSchemas","userSchema","enterpriseUserSchema","projection","projectScimResource","groupSchema","attributes","parseCsvParam","pickStringParam","excludedAttributes","parsedBody","filterRaw","parseScimFilter","undefined","startIndex","parsePositiveInt","count","clamp","parseCount","sortBy","sortOrder","parseSortOrder","isPlainObject","scimError","withDetails","message","Math","floor","Array","isArray","a","raw","fallback","n","Number","isFinite","value","min","max","parts","split","s","trim","Boolean","length","key","schemas","includes","PatchOpSchema","Operations","total","ListResponseSchema","itemsPerPage","Resources"]}
1
+ {"version":3,"sources":["../src/types/list.response.ts","../src/types/patch.op.ts","../src/schemas/user.schema.ts","../src/schemas/group.schema.ts","../src/schemas/enterprise.user.schema.ts","../src/schemas/resource.type.schema.ts","../src/schemas/service.provider.config.schema.ts","../src/schemas/index.ts","../src/errors/scim.error.ts","../src/filter/filter.tokenizer.ts","../src/filter/filter.parser.ts","../src/patch/patch.applier.ts","../src/projection/attribute.projection.ts","../src/repositories/scim.user.repository.ts","../src/repositories/scim.group.repository.ts","../src/services/scim.user.service.ts","../src/services/scim.group.service.ts","../src/services/scim.service.provider.service.ts","../src/middleware/scim.content.type.middleware.ts","../src/middleware/scim.error.middleware.ts","../src/middleware/require.scim.scope.middleware.ts","../src/router/scim.router.ts"],"sourcesContent":["/**\n * Schema URI for the SCIM ListResponse message (RFC 7644 §3.4.2).\n */\nexport const ListResponseSchema = 'urn:ietf:params:scim:api:messages:2.0:ListResponse';\n\n/**\n * SCIM ListResponse envelope returned from list/search endpoints.\n */\nexport interface ScimListResponse<TResource> {\n schemas: [typeof ListResponseSchema];\n totalResults: number;\n startIndex?: number;\n itemsPerPage?: number;\n Resources?: TResource[];\n}\n","/**\n * Schema URI for the SCIM PatchOp message (RFC 7644 §3.5.2).\n */\nexport const PatchOpSchema = 'urn:ietf:params:scim:api:messages:2.0:PatchOp';\n\n/**\n * Operation kinds permitted in a SCIM PATCH request.\n * Case-insensitive on the wire; normalised internally.\n */\nexport type ScimPatchOpKind = 'add' | 'replace' | 'remove';\n\n/**\n * A single PATCH operation as it appears in a PatchOp request body.\n */\nexport interface ScimPatchOp {\n op: ScimPatchOpKind | Uppercase<ScimPatchOpKind> | Capitalize<ScimPatchOpKind>;\n path?: string;\n value?: unknown;\n}\n\n/**\n * The full PatchOp request envelope.\n */\nexport interface ScimPatchRequest {\n schemas: [typeof PatchOpSchema];\n Operations: ScimPatchOp[];\n}\n","import type { ScimAttributeDefinition, ScimSchema } from './schema.types.js';\n\n/** Schema URI for the SCIM core User resource. */\nexport const UserSchemaId = 'urn:ietf:params:scim:schemas:core:2.0:User';\n\n/**\n * RFC 7643 §4.1: SCIM core User schema definition. A condensed but\n * spec-compliant subset suitable for `/Schemas` discovery.\n */\nexport const userSchema: ScimSchema = {\n id: UserSchemaId,\n name: 'User',\n description: 'User Account',\n meta: { resourceType: 'Schema', location: `/Schemas/${UserSchemaId}` },\n attributes: [\n {\n name: 'userName',\n type: 'string',\n multiValued: false,\n description: 'Unique identifier for the User, typically used by the user to directly authenticate.',\n required: true,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'server',\n },\n {\n name: 'name',\n type: 'complex',\n multiValued: false,\n description: \"The components of the user's real name.\",\n required: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n subAttributes: [\n {\n name: 'formatted',\n type: 'string',\n multiValued: false,\n description: 'Full name formatted for display.',\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'familyName',\n type: 'string',\n multiValued: false,\n description: 'Family name (last name).',\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'givenName',\n type: 'string',\n multiValued: false,\n description: 'Given name (first name).',\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'middleName',\n type: 'string',\n multiValued: false,\n description: 'Middle name.',\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'honorificPrefix',\n type: 'string',\n multiValued: false,\n description: 'Honorific prefix (e.g., Ms., Dr.).',\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'honorificSuffix',\n type: 'string',\n multiValued: false,\n description: 'Honorific suffix (e.g., Jr., III).',\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n ],\n },\n {\n name: 'displayName',\n type: 'string',\n multiValued: false,\n description: 'Name displayed to end-users.',\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'nickName',\n type: 'string',\n multiValued: false,\n description: 'Casual name of the User.',\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'profileUrl',\n type: 'reference',\n multiValued: false,\n description: \"URL of the User's online profile.\",\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n referenceTypes: ['external'],\n },\n {\n name: 'title',\n type: 'string',\n multiValued: false,\n description: 'Title of the User.',\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'userType',\n type: 'string',\n multiValued: false,\n description: 'Used to identify the relationship between the organization and the user.',\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'preferredLanguage',\n type: 'string',\n multiValued: false,\n description: 'Preferred language as per RFC 7231.',\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'locale',\n type: 'string',\n multiValued: false,\n description: 'Default location of the User.',\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'timezone',\n type: 'string',\n multiValued: false,\n description: 'Time zone in IANA format.',\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'active',\n type: 'boolean',\n multiValued: false,\n description: 'Whether the user is active.',\n required: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'password',\n type: 'string',\n multiValued: false,\n description: 'Cleartext password (write-only).',\n required: false,\n caseExact: false,\n mutability: 'writeOnly',\n returned: 'never',\n uniqueness: 'none',\n },\n {\n name: 'emails',\n type: 'complex',\n multiValued: true,\n description: 'Email addresses for the user.',\n required: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n subAttributes: multiValuedSubAttrs('email'),\n },\n {\n name: 'phoneNumbers',\n type: 'complex',\n multiValued: true,\n description: 'Phone numbers for the user.',\n required: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n subAttributes: multiValuedSubAttrs('phone'),\n },\n {\n name: 'groups',\n type: 'complex',\n multiValued: true,\n description: 'Groups the user is a member of (read-only).',\n required: false,\n mutability: 'readOnly',\n returned: 'default',\n uniqueness: 'none',\n subAttributes: [\n {\n name: 'value',\n type: 'string',\n multiValued: false,\n description: 'Identifier of the Group.',\n required: false,\n caseExact: true,\n mutability: 'readOnly',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: '$ref',\n type: 'reference',\n multiValued: false,\n description: 'URI of the Group resource.',\n required: false,\n caseExact: true,\n mutability: 'readOnly',\n returned: 'default',\n uniqueness: 'none',\n referenceTypes: ['Group'],\n },\n {\n name: 'display',\n type: 'string',\n multiValued: false,\n description: 'Human-readable Group name.',\n required: false,\n caseExact: false,\n mutability: 'readOnly',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'type',\n type: 'string',\n multiValued: false,\n description: 'Membership type.',\n required: false,\n caseExact: false,\n mutability: 'readOnly',\n returned: 'default',\n uniqueness: 'none',\n canonicalValues: ['direct', 'indirect'],\n },\n ],\n },\n ],\n};\n\nfunction multiValuedSubAttrs(kind: string): ScimAttributeDefinition[] {\n return [\n {\n name: 'value',\n type: 'string',\n multiValued: false,\n description: `${kind} value.`,\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'display',\n type: 'string',\n multiValued: false,\n description: 'Human-readable display value.',\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'type',\n type: 'string',\n multiValued: false,\n description: `Function of the ${kind} (e.g., work, home).`,\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'primary',\n type: 'boolean',\n multiValued: false,\n description: 'Whether this is the primary value.',\n required: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n ];\n}\n","import type { ScimSchema } from './schema.types.js';\n\n/** Schema URI for the SCIM core Group resource. */\nexport const GroupSchemaId = 'urn:ietf:params:scim:schemas:core:2.0:Group';\n\n/**\n * RFC 7643 §4.2: SCIM core Group schema definition.\n */\nexport const groupSchema: ScimSchema = {\n id: GroupSchemaId,\n name: 'Group',\n description: 'Group',\n meta: { resourceType: 'Schema', location: `/Schemas/${GroupSchemaId}` },\n attributes: [\n {\n name: 'displayName',\n type: 'string',\n multiValued: false,\n description: 'Human-readable name for the Group.',\n required: true,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'members',\n type: 'complex',\n multiValued: true,\n description: 'List of Group members.',\n required: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n subAttributes: [\n {\n name: 'value',\n type: 'string',\n multiValued: false,\n description: 'Identifier of the member.',\n required: false,\n caseExact: true,\n mutability: 'immutable',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: '$ref',\n type: 'reference',\n multiValued: false,\n description: 'URI of the member resource.',\n required: false,\n caseExact: true,\n mutability: 'immutable',\n returned: 'default',\n uniqueness: 'none',\n referenceTypes: ['User', 'Group'],\n },\n {\n name: 'display',\n type: 'string',\n multiValued: false,\n description: 'Human-readable name of the member.',\n required: false,\n caseExact: false,\n mutability: 'immutable',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'type',\n type: 'string',\n multiValued: false,\n description: 'Member type.',\n required: false,\n caseExact: false,\n mutability: 'immutable',\n returned: 'default',\n uniqueness: 'none',\n canonicalValues: ['User', 'Group'],\n },\n ],\n },\n ],\n};\n","import type { ScimSchema } from './schema.types.js';\n\n/** Schema URI for the SCIM EnterpriseUser extension. */\nexport const EnterpriseUserSchemaId = 'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User';\n\n/**\n * RFC 7643 §4.3: EnterpriseUser extension schema definition.\n */\nexport const enterpriseUserSchema: ScimSchema = {\n id: EnterpriseUserSchemaId,\n name: 'EnterpriseUser',\n description: 'Enterprise User extension',\n meta: { resourceType: 'Schema', location: `/Schemas/${EnterpriseUserSchemaId}` },\n attributes: [\n {\n name: 'employeeNumber',\n type: 'string',\n multiValued: false,\n description: 'Employee number.',\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'costCenter',\n type: 'string',\n multiValued: false,\n description: 'Cost center.',\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'organization',\n type: 'string',\n multiValued: false,\n description: 'Organization name.',\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'division',\n type: 'string',\n multiValued: false,\n description: 'Division name.',\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'department',\n type: 'string',\n multiValued: false,\n description: 'Department name.',\n required: false,\n caseExact: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: 'manager',\n type: 'complex',\n multiValued: false,\n description: 'The manager of the user.',\n required: false,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n subAttributes: [\n {\n name: 'value',\n type: 'string',\n multiValued: false,\n description: 'Manager user id.',\n required: false,\n caseExact: true,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n },\n {\n name: '$ref',\n type: 'reference',\n multiValued: false,\n description: 'URI of the manager User resource.',\n required: false,\n caseExact: true,\n mutability: 'readWrite',\n returned: 'default',\n uniqueness: 'none',\n referenceTypes: ['User'],\n },\n {\n name: 'displayName',\n type: 'string',\n multiValued: false,\n description: 'Manager display name.',\n required: false,\n caseExact: false,\n mutability: 'readOnly',\n returned: 'default',\n uniqueness: 'none',\n },\n ],\n },\n ],\n};\n","import { UserSchemaId } from './user.schema.js';\nimport { GroupSchemaId } from './group.schema.js';\nimport { EnterpriseUserSchemaId } from './enterprise.user.schema.js';\n\n/** Schema URI for the SCIM ResourceType resource. */\nexport const ResourceTypeSchemaId = 'urn:ietf:params:scim:schemas:core:2.0:ResourceType';\n\nexport interface ScimResourceType {\n schemas: [typeof ResourceTypeSchemaId];\n id: string;\n name: string;\n endpoint: string;\n description: string;\n schema: string;\n schemaExtensions?: Array<{ schema: string; required: boolean }>;\n meta: {\n resourceType: 'ResourceType';\n location?: string;\n };\n}\n\nexport const userResourceType: ScimResourceType = {\n schemas: [ResourceTypeSchemaId],\n id: 'User',\n name: 'User',\n endpoint: '/Users',\n description: 'User Account',\n schema: UserSchemaId,\n schemaExtensions: [{ schema: EnterpriseUserSchemaId, required: false }],\n meta: { resourceType: 'ResourceType', location: '/ResourceTypes/User' },\n};\n\nexport const groupResourceType: ScimResourceType = {\n schemas: [ResourceTypeSchemaId],\n id: 'Group',\n name: 'Group',\n endpoint: '/Groups',\n description: 'Group',\n schema: GroupSchemaId,\n meta: { resourceType: 'ResourceType', location: '/ResourceTypes/Group' },\n};\n","/** Schema URI for the SCIM ServiceProviderConfig resource. */\nexport const ServiceProviderConfigSchemaId = 'urn:ietf:params:scim:schemas:core:2.0:ServiceProviderConfig';\n\n/** Authentication scheme advertised by `/ServiceProviderConfig`. */\nexport interface ScimAuthenticationScheme {\n type: 'oauth' | 'oauth2' | 'oauthbearertoken' | 'httpbasic' | 'httpdigest';\n name: string;\n description: string;\n specUri?: string;\n documentationUri?: string;\n primary?: boolean;\n}\n\n/** Optional features the service provider supports (RFC 7643 §5). */\nexport interface ScimServiceProviderConfigOptions {\n documentationUri?: string;\n patch?: { supported: boolean };\n bulk?: { supported: boolean; maxOperations: number; maxPayloadSize: number };\n filter?: { supported: boolean; maxResults: number };\n changePassword?: { supported: boolean };\n sort?: { supported: boolean };\n etag?: { supported: boolean };\n authenticationSchemes?: ScimAuthenticationScheme[];\n}\n\n/** Materialised ServiceProviderConfig response. */\nexport interface ScimServiceProviderConfig extends Required<Omit<ScimServiceProviderConfigOptions, 'documentationUri' | 'authenticationSchemes'>> {\n schemas: [typeof ServiceProviderConfigSchemaId];\n documentationUri?: string;\n authenticationSchemes: ScimAuthenticationScheme[];\n meta: {\n resourceType: 'ServiceProviderConfig';\n location?: string;\n };\n}\n\nconst defaultBearer: ScimAuthenticationScheme = {\n type: 'oauthbearertoken',\n name: 'OAuth Bearer Token',\n description: 'Authentication scheme using the OAuth Bearer Token Standard.',\n specUri: 'https://www.rfc-editor.org/info/rfc6750',\n primary: true,\n};\n\n/**\n * Build a SCIM ServiceProviderConfig response object, layering caller options\n * over the toolkit's defaults (PATCH on, filter on, sort on; bulk/changePassword/etag off).\n */\nexport const buildServiceProviderConfig = (options: ScimServiceProviderConfigOptions = {}): ScimServiceProviderConfig => ({\n schemas: [ServiceProviderConfigSchemaId],\n documentationUri: options.documentationUri,\n patch: options.patch ?? { supported: true },\n bulk: options.bulk ?? { supported: false, maxOperations: 0, maxPayloadSize: 0 },\n filter: options.filter ?? { supported: true, maxResults: 200 },\n changePassword: options.changePassword ?? { supported: false },\n sort: options.sort ?? { supported: true },\n etag: options.etag ?? { supported: false },\n authenticationSchemes: options.authenticationSchemes ?? [defaultBearer],\n meta: { resourceType: 'ServiceProviderConfig', location: '/ServiceProviderConfig' },\n});\n","export * from './schema.types.js';\nexport * from './user.schema.js';\nexport * from './group.schema.js';\nexport * from './enterprise.user.schema.js';\nexport * from './resource.type.schema.js';\nexport * from './service.provider.config.schema.js';\n\nimport { userSchema } from './user.schema.js';\nimport { groupSchema } from './group.schema.js';\nimport { enterpriseUserSchema } from './enterprise.user.schema.js';\n\n/** All SCIM core + extension schemas this package ships. */\nexport const coreSchemas = [userSchema, groupSchema, enterpriseUserSchema];\n","import { HttpError, HttpStatusCodes, type HttpStatusMessage } from '@maroonedsoftware/errors';\n\n/** Schema URI for the SCIM Error message. */\nexport const ScimErrorSchema = 'urn:ietf:params:scim:api:messages:2.0:Error';\n\n/**\n * `scimType` values defined by RFC 7644 §3.12 plus the few extensions clients\n * commonly emit. Keep this open as `string` to allow vendor-specific values.\n */\nexport type ScimErrorType =\n | 'invalidFilter'\n | 'tooMany'\n | 'uniqueness'\n | 'mutability'\n | 'invalidSyntax'\n | 'invalidPath'\n | 'noTarget'\n | 'invalidValue'\n | 'invalidVers'\n | 'sensitive'\n | 'insufficientScope'\n | (string & {});\n\n/**\n * SCIM error envelope (RFC 7644 §3.12). The HTTP status comes from\n * the underlying {@link HttpError}; the JSON body matches:\n *\n * ```json\n * { \"schemas\": [\"urn:ietf:params:scim:api:messages:2.0:Error\"], \"status\": \"404\", \"scimType\": \"invalidPath\", \"detail\": \"...\" }\n * ```\n */\nexport class ScimError extends HttpError {\n /** SCIM-specific error subtype, see RFC 7644 §3.12. */\n readonly scimType?: ScimErrorType;\n\n constructor(statusCode: HttpStatusCodes, scimType?: ScimErrorType, message?: HttpStatusMessage<HttpStatusCodes>) {\n // No `Object.setPrototypeOf` here: `ServerkitError` restores the prototype from\n // `new.target`, which is already the right class. Pinning it to `ScimError.prototype`\n // would overwrite that and break `instanceof` for anything subclassing this.\n super(statusCode, message);\n this.scimType = scimType;\n }\n\n /**\n * Build the SCIM error JSON body for this error.\n *\n * `detail` prefers a string `message` from {@link ServerkitError.details}, falling\n * back to the error's own message. The package raises errors as\n * `scimError(409, 'uniqueness', 'Conflict').withDetails({ message: '...' })`, where\n * the constructor's third argument is only the HTTP status text; without this\n * preference every provisioning client would see `\"detail\": \"Conflict\"` and never\n * the reason.\n */\n toScimBody(): { schemas: [typeof ScimErrorSchema]; status: string; scimType?: ScimErrorType; detail?: string } {\n const detailFromDetails = this.details?.message;\n return {\n schemas: [ScimErrorSchema],\n status: String(this.statusCode),\n ...(this.scimType ? { scimType: this.scimType } : {}),\n detail: typeof detailFromDetails === 'string' ? detailFromDetails : this.message,\n };\n }\n}\n\n/** Type guard for {@link ScimError}. */\nexport const IsScimError = (error: unknown): error is ScimError => error instanceof ScimError;\n\n/**\n * Factory for building a SCIM-shaped HTTP error. The returned object behaves like\n * an {@link HttpError}, so chained `.withDetails()` / `.withCause()` /\n * `.withInternalDetails()` work as usual.\n *\n * @example\n * ```ts\n * throw scimError(400, 'invalidFilter', 'Bad Request');\n * ```\n */\nexport const scimError = <Status extends HttpStatusCodes>(\n statusCode: Status,\n scimType?: ScimErrorType,\n message?: HttpStatusMessage<Status>,\n): ScimError => new ScimError(statusCode, scimType, message);\n","import { scimError } from '../errors/scim.error.js';\n\nexport type ScimTokenKind =\n | 'identifier' // attribute path, including dots, colons, dashes, and URN segments\n | 'string'\n | 'number'\n | 'true'\n | 'false'\n | 'null'\n | 'and'\n | 'or'\n | 'not'\n | 'lparen'\n | 'rparen'\n | 'lbracket'\n | 'rbracket'\n | 'op'; // eq, ne, co, sw, ew, gt, ge, lt, le, pr\n\nexport interface ScimToken {\n kind: ScimTokenKind;\n /** For `identifier`/`string`/`op`: the textual value. For `number`: numeric. */\n value: string | number | boolean | null;\n /** Source position where the token starts. */\n start: number;\n}\n\nconst COMPARISON_OPS = new Set(['eq', 'ne', 'co', 'sw', 'ew', 'gt', 'ge', 'lt', 'le', 'pr']);\n\n/**\n * Tokenize a SCIM filter expression into a stream of {@link ScimToken}s.\n * Throws a `400 invalidFilter` SCIM error on malformed input.\n */\nexport const tokenizeScimFilter = (input: string): ScimToken[] => {\n const tokens: ScimToken[] = [];\n let i = 0;\n\n while (i < input.length) {\n const ch = input[i]!;\n\n if (ch === ' ' || ch === '\\t' || ch === '\\n' || ch === '\\r') {\n i += 1;\n continue;\n }\n\n if (ch === '(') {\n tokens.push({ kind: 'lparen', value: '(', start: i });\n i += 1;\n continue;\n }\n if (ch === ')') {\n tokens.push({ kind: 'rparen', value: ')', start: i });\n i += 1;\n continue;\n }\n if (ch === '[') {\n tokens.push({ kind: 'lbracket', value: '[', start: i });\n i += 1;\n continue;\n }\n if (ch === ']') {\n tokens.push({ kind: 'rbracket', value: ']', start: i });\n i += 1;\n continue;\n }\n\n if (ch === '\"') {\n const start = i;\n i += 1;\n let value = '';\n while (i < input.length && input[i] !== '\"') {\n if (input[i] === '\\\\' && i + 1 < input.length) {\n const next = input[i + 1]!;\n if (next === '\"' || next === '\\\\' || next === '/') {\n value += next;\n i += 2;\n continue;\n }\n if (next === 'n') {\n value += '\\n';\n i += 2;\n continue;\n }\n if (next === 't') {\n value += '\\t';\n i += 2;\n continue;\n }\n if (next === 'r') {\n value += '\\r';\n i += 2;\n continue;\n }\n if (next === 'b') {\n value += '\\b';\n i += 2;\n continue;\n }\n if (next === 'f') {\n value += '\\f';\n i += 2;\n continue;\n }\n throw scimError(400, 'invalidFilter', 'Bad Request').withDetails({ position: i, message: `Unsupported escape sequence \\\\${next}` });\n }\n value += input[i];\n i += 1;\n }\n if (i >= input.length) {\n throw scimError(400, 'invalidFilter', 'Bad Request').withDetails({ position: start, message: 'Unterminated string literal' });\n }\n i += 1; // consume closing quote\n tokens.push({ kind: 'string', value, start });\n continue;\n }\n\n if (ch === '-' || (ch >= '0' && ch <= '9')) {\n const start = i;\n let raw = '';\n if (ch === '-') {\n raw += ch;\n i += 1;\n }\n while (i < input.length && /[0-9]/.test(input[i]!)) {\n raw += input[i];\n i += 1;\n }\n if (input[i] === '.') {\n raw += '.';\n i += 1;\n while (i < input.length && /[0-9]/.test(input[i]!)) {\n raw += input[i];\n i += 1;\n }\n }\n if (input[i] === 'e' || input[i] === 'E') {\n raw += input[i];\n i += 1;\n if (input[i] === '+' || input[i] === '-') {\n raw += input[i];\n i += 1;\n }\n while (i < input.length && /[0-9]/.test(input[i]!)) {\n raw += input[i];\n i += 1;\n }\n }\n const num = Number(raw);\n if (Number.isNaN(num)) {\n throw scimError(400, 'invalidFilter', 'Bad Request').withDetails({ position: start, message: `Invalid numeric literal \"${raw}\"` });\n }\n tokens.push({ kind: 'number', value: num, start });\n continue;\n }\n\n if (isIdentifierStart(ch)) {\n const start = i;\n let raw = '';\n while (i < input.length && isIdentifierPart(input[i]!)) {\n raw += input[i];\n i += 1;\n }\n const lower = raw.toLowerCase();\n switch (lower) {\n case 'true':\n tokens.push({ kind: 'true', value: true, start });\n continue;\n case 'false':\n tokens.push({ kind: 'false', value: false, start });\n continue;\n case 'null':\n tokens.push({ kind: 'null', value: null, start });\n continue;\n case 'and':\n case 'or':\n case 'not':\n tokens.push({ kind: lower, value: lower, start });\n continue;\n }\n if (COMPARISON_OPS.has(lower)) {\n tokens.push({ kind: 'op', value: lower, start });\n continue;\n }\n tokens.push({ kind: 'identifier', value: raw, start });\n continue;\n }\n\n throw scimError(400, 'invalidFilter', 'Bad Request').withDetails({ position: i, message: `Unexpected character \"${ch}\"` });\n }\n\n return tokens;\n};\n\nconst isIdentifierStart = (ch: string): boolean => /[A-Za-z_$]/.test(ch);\n\nconst isIdentifierPart = (ch: string): boolean => /[A-Za-z0-9_.\\-:$]/.test(ch);\n","import { scimError } from '../errors/scim.error.js';\nimport type { ScimFilterNode, ScimComparisonOperator } from './filter.ast.js';\nimport { tokenizeScimFilter, type ScimToken } from './filter.tokenizer.js';\n\n/**\n * Parse a SCIM filter expression (RFC 7644 §3.4.2.2) into a typed AST.\n * Throws a `400 invalidFilter` SCIM error on malformed input.\n *\n * Operator precedence (highest first):\n * 1. parentheses, value-path brackets, `not(...)`\n * 2. comparison\n * 3. `and`\n * 4. `or`\n */\nexport const parseScimFilter = (input: string): ScimFilterNode => {\n const trimmed = input.trim();\n if (trimmed.length === 0) {\n throw scimError(400, 'invalidFilter', 'Bad Request').withDetails({ message: 'Filter is empty' });\n }\n const tokens = tokenizeScimFilter(trimmed);\n const parser = new Parser(tokens);\n const node = parser.parseOr();\n parser.expectEnd();\n return node;\n};\n\nclass Parser {\n private pos = 0;\n\n constructor(private readonly tokens: ScimToken[]) {}\n\n parseOr(): ScimFilterNode {\n let left = this.parseAnd();\n while (this.peek()?.kind === 'or') {\n this.consume();\n const right = this.parseAnd();\n left = { kind: 'logical', operator: 'or', left, right };\n }\n return left;\n }\n\n parseAnd(): ScimFilterNode {\n let left = this.parseUnary();\n while (this.peek()?.kind === 'and') {\n this.consume();\n const right = this.parseUnary();\n left = { kind: 'logical', operator: 'and', left, right };\n }\n return left;\n }\n\n parseUnary(): ScimFilterNode {\n const token = this.peek();\n if (token?.kind === 'not') {\n this.consume();\n this.expect('lparen', 'Expected \"(\" after \"not\"');\n const inner = this.parseOr();\n this.expect('rparen', 'Expected \")\" to close \"not(...)\"');\n return { kind: 'not', filter: inner };\n }\n if (token?.kind === 'lparen') {\n this.consume();\n const inner = this.parseOr();\n this.expect('rparen', 'Expected \")\"');\n return inner;\n }\n return this.parseComparisonOrValuePath();\n }\n\n parseComparisonOrValuePath(): ScimFilterNode {\n const token = this.peek();\n if (!token || token.kind !== 'identifier') {\n throw this.error(token, 'Expected attribute path');\n }\n this.consume();\n const attribute = String(token.value);\n\n const next = this.peek();\n if (next?.kind === 'lbracket') {\n this.consume();\n const inner = this.parseOr();\n this.expect('rbracket', 'Expected \"]\" to close value-path filter');\n return { kind: 'valuePath', attribute, filter: inner };\n }\n\n if (!next || next.kind !== 'op') {\n throw this.error(next, 'Expected comparison operator');\n }\n this.consume();\n const operator = String(next.value) as ScimComparisonOperator;\n\n if (operator === 'pr') {\n return { kind: 'comparison', attribute, operator };\n }\n\n const valueToken = this.peek();\n if (!valueToken) {\n throw this.error(valueToken, `Expected value after operator \"${operator}\"`);\n }\n this.consume();\n\n if (\n valueToken.kind === 'string' ||\n valueToken.kind === 'number' ||\n valueToken.kind === 'true' ||\n valueToken.kind === 'false' ||\n valueToken.kind === 'null'\n ) {\n return { kind: 'comparison', attribute, operator, value: valueToken.value as string | number | boolean | null };\n }\n throw this.error(valueToken, `Expected literal value after operator \"${operator}\"`);\n }\n\n expectEnd(): void {\n const remaining = this.peek();\n if (remaining) {\n throw this.error(remaining, 'Unexpected trailing tokens');\n }\n }\n\n private peek(): ScimToken | undefined {\n return this.tokens[this.pos];\n }\n\n private consume(): ScimToken | undefined {\n const token = this.tokens[this.pos];\n this.pos += 1;\n return token;\n }\n\n private expect(kind: ScimToken['kind'], message: string): ScimToken {\n const token = this.peek();\n if (!token || token.kind !== kind) {\n throw this.error(token, message);\n }\n this.consume();\n return token;\n }\n\n private error(token: ScimToken | undefined, message: string) {\n return scimError(400, 'invalidFilter', 'Bad Request').withDetails({\n message,\n position: token?.start ?? -1,\n });\n }\n}\n","import { scimError } from '../errors/scim.error.js';\nimport { parseScimFilter } from '../filter/filter.parser.js';\nimport type { ScimFilterNode } from '../filter/filter.ast.js';\nimport type { ScimPatchOp, ScimPatchOpKind } from '../types/patch.op.js';\n\n/**\n * Apply a SCIM PATCH operation list to a resource (RFC 7644 §3.5.2).\n * Returns a *new* object — the input is not mutated.\n *\n * Supports the standard `add` / `replace` / `remove` operations and the path\n * mini-language including dotted sub-attributes and value-path filters\n * (e.g. `emails[type eq \"work\"].value`).\n */\nexport const applyScimPatch = <T extends Record<string, unknown>>(resource: T, ops: ScimPatchOp[]): T => {\n // Deep-clone so mutations don't leak to the caller.\n let next: Record<string, unknown> = structuredClone(resource);\n for (const op of ops) {\n next = applyOne(next, op);\n }\n return next as T;\n};\n\nconst applyOne = (resource: Record<string, unknown>, op: ScimPatchOp): Record<string, unknown> => {\n const kind = normaliseOpKind(op.op);\n\n if (op.path === undefined || op.path === '') {\n if (kind === 'remove') {\n throw scimError(400, 'noTarget', 'Bad Request').withDetails({ message: '\"remove\" requires a path' });\n }\n if (typeof op.value !== 'object' || op.value === null || Array.isArray(op.value)) {\n throw scimError(400, 'invalidValue', 'Bad Request').withDetails({ message: 'Pathless add/replace requires an object value' });\n }\n return mergeObject(resource, op.value as Record<string, unknown>, kind);\n }\n\n const path = parsePatchPath(op.path);\n return applyAtPath(resource, path, kind, op.value);\n};\n\nconst normaliseOpKind = (op: ScimPatchOp['op']): ScimPatchOpKind => {\n const lower = String(op).toLowerCase();\n if (lower === 'add' || lower === 'replace' || lower === 'remove') return lower;\n throw scimError(400, 'invalidSyntax', 'Bad Request').withDetails({ message: `Unknown PATCH op \"${op}\"` });\n};\n\ninterface ParsedPath {\n /** Top-level attribute, possibly with sub-attribute segments. */\n segments: string[];\n /** Optional value-path filter applied to the leaf attribute. */\n filter?: ScimFilterNode;\n /** Sub-attribute applied after the value-path filter (e.g. `.value`). */\n filterSubAttr?: string;\n}\n\nconst parsePatchPath = (raw: string): ParsedPath => {\n // Split off optional `[...]filter` segment.\n const bracketStart = raw.indexOf('[');\n if (bracketStart === -1) {\n return { segments: raw.split('.').filter(Boolean) };\n }\n\n const bracketEnd = findMatchingBracket(raw, bracketStart);\n if (bracketEnd === -1) {\n throw scimError(400, 'invalidPath', 'Bad Request').withDetails({ message: 'Unterminated value-path filter' });\n }\n\n const head = raw.slice(0, bracketStart);\n const filterSrc = raw.slice(bracketStart + 1, bracketEnd);\n const tail = raw.slice(bracketEnd + 1);\n\n const segments = head.split('.').filter(Boolean);\n if (segments.length === 0) {\n throw scimError(400, 'invalidPath', 'Bad Request').withDetails({ message: 'Value-path filter requires a target attribute' });\n }\n\n const filter = parseScimFilter(filterSrc);\n\n let filterSubAttr: string | undefined;\n if (tail.length > 0) {\n if (!tail.startsWith('.')) {\n throw scimError(400, 'invalidPath', 'Bad Request').withDetails({ message: 'Expected \".\" after value-path filter' });\n }\n filterSubAttr = tail.slice(1);\n if (filterSubAttr.length === 0 || filterSubAttr.includes('[')) {\n throw scimError(400, 'invalidPath', 'Bad Request').withDetails({ message: 'Invalid sub-attribute after value-path filter' });\n }\n }\n\n return { segments, filter, filterSubAttr };\n};\n\nconst findMatchingBracket = (input: string, openIndex: number): number => {\n let depth = 0;\n let inString = false;\n for (let i = openIndex; i < input.length; i += 1) {\n const ch = input[i]!;\n if (inString) {\n if (ch === '\\\\') {\n i += 1;\n continue;\n }\n if (ch === '\"') inString = false;\n continue;\n }\n if (ch === '\"') {\n inString = true;\n continue;\n }\n if (ch === '[') depth += 1;\n else if (ch === ']') {\n depth -= 1;\n if (depth === 0) return i;\n }\n }\n return -1;\n};\n\nconst applyAtPath = (resource: Record<string, unknown>, path: ParsedPath, kind: ScimPatchOpKind, value: unknown): Record<string, unknown> => {\n const [head, ...rest] = path.segments;\n if (!head) {\n throw scimError(400, 'invalidPath', 'Bad Request').withDetails({ message: 'Empty PATCH path' });\n }\n\n if (path.filter && rest.length === 0) {\n return applyFilteredOp(resource, head, path.filter, path.filterSubAttr, kind, value);\n }\n\n if (rest.length === 0) {\n return applySimpleOp(resource, head, kind, value);\n }\n\n const child = resource[head];\n const childObj: Record<string, unknown> = isPlainObject(child) ? { ...child } : {};\n const updated = applyAtPath(childObj, { ...path, segments: rest }, kind, value);\n return { ...resource, [head]: updated };\n};\n\nconst applySimpleOp = (resource: Record<string, unknown>, attr: string, kind: ScimPatchOpKind, value: unknown): Record<string, unknown> => {\n if (kind === 'remove') {\n const next = { ...resource };\n delete next[attr];\n return next;\n }\n\n if (kind === 'replace') {\n return { ...resource, [attr]: value };\n }\n\n // add: for multi-valued attributes, append; otherwise replace.\n const existing = resource[attr];\n if (Array.isArray(existing) && Array.isArray(value)) {\n return { ...resource, [attr]: [...existing, ...value] };\n }\n if (Array.isArray(existing) && value !== undefined) {\n return { ...resource, [attr]: [...existing, value] };\n }\n if (existing === undefined && Array.isArray(value)) {\n return { ...resource, [attr]: [...value] };\n }\n if (isPlainObject(existing) && isPlainObject(value)) {\n return { ...resource, [attr]: { ...existing, ...value } };\n }\n return { ...resource, [attr]: value };\n};\n\nconst applyFilteredOp = (\n resource: Record<string, unknown>,\n attr: string,\n filter: ScimFilterNode,\n subAttr: string | undefined,\n kind: ScimPatchOpKind,\n value: unknown,\n): Record<string, unknown> => {\n const collection = resource[attr];\n if (!Array.isArray(collection)) {\n if (kind === 'add') {\n // Per RFC, add on a non-existent target creates it. For value-path on a\n // missing collection, the closest behaviour is to materialise the matched\n // item from the supplied value.\n return { ...resource, [attr]: [{ ...(value as Record<string, unknown>) }] };\n }\n throw scimError(400, 'noTarget', 'Bad Request').withDetails({ message: `Attribute \"${attr}\" is not multi-valued` });\n }\n\n const matched: number[] = [];\n collection.forEach((item, index) => {\n if (isPlainObject(item) && evaluateFilter(item, filter)) matched.push(index);\n });\n\n if (matched.length === 0 && kind !== 'add') {\n throw scimError(400, 'noTarget', 'Bad Request').withDetails({ message: `No items matched value-path filter on \"${attr}\"` });\n }\n\n if (kind === 'remove') {\n const next = collection.filter((_, idx) => !matched.includes(idx));\n return { ...resource, [attr]: next };\n }\n\n if (kind === 'add' && matched.length === 0) {\n const seed = isPlainObject(value) ? { ...value } : { value };\n return { ...resource, [attr]: [...collection, seed] };\n }\n\n const next = collection.map((item, idx) => {\n if (!matched.includes(idx) || !isPlainObject(item)) return item;\n if (subAttr !== undefined) {\n if (kind === 'replace' || kind === 'add') {\n return { ...item, [subAttr]: value };\n }\n }\n if (kind === 'replace') {\n return isPlainObject(value) ? { ...item, ...value } : value;\n }\n // add: shallow merge\n return isPlainObject(value) ? { ...item, ...value } : item;\n });\n return { ...resource, [attr]: next };\n};\n\nconst mergeObject = (target: Record<string, unknown>, source: Record<string, unknown>, kind: ScimPatchOpKind): Record<string, unknown> => {\n if (kind === 'replace') {\n return { ...target, ...source };\n }\n // add: deep-merge for nested objects, append for arrays\n const out: Record<string, unknown> = { ...target };\n for (const [key, val] of Object.entries(source)) {\n const existing = out[key];\n if (Array.isArray(existing) && Array.isArray(val)) {\n defineOwn(out, key, [...existing, ...val]);\n } else if (isPlainObject(existing) && isPlainObject(val)) {\n defineOwn(out, key, mergeObject(existing, val, kind));\n } else {\n defineOwn(out, key, val);\n }\n }\n return out;\n};\n\n/**\n * Assign a key without going through a setter. PATCH values come straight off\n * the request body, and plain assignment to `__proto__` invokes the inherited\n * setter and reparents the object instead of storing an attribute.\n */\nconst defineOwn = (target: Record<string, unknown>, key: string, value: unknown): void => {\n Object.defineProperty(target, key, { value, writable: true, enumerable: true, configurable: true });\n};\n\nconst evaluateFilter = (item: Record<string, unknown>, filter: ScimFilterNode): boolean => {\n switch (filter.kind) {\n case 'comparison':\n return evaluateComparison(item, filter.attribute, filter.operator, filter.value);\n case 'logical':\n return filter.operator === 'and'\n ? evaluateFilter(item, filter.left) && evaluateFilter(item, filter.right)\n : evaluateFilter(item, filter.left) || evaluateFilter(item, filter.right);\n case 'not':\n return !evaluateFilter(item, filter.filter);\n case 'valuePath': {\n const nested = item[filter.attribute];\n if (!Array.isArray(nested)) return false;\n return nested.some(child => isPlainObject(child) && evaluateFilter(child, filter.filter));\n }\n }\n};\n\nconst evaluateComparison = (item: Record<string, unknown>, attr: string, op: string, value: unknown): boolean => {\n const segments = attr.split('.');\n let current: unknown = item;\n for (const seg of segments) {\n if (!isPlainObject(current)) return false;\n current = current[seg];\n }\n if (op === 'pr') return current !== undefined && current !== null && current !== '';\n if (current === undefined || current === null) return false;\n\n switch (op) {\n case 'eq':\n return current === value;\n case 'ne':\n return current !== value;\n case 'co':\n return typeof current === 'string' && typeof value === 'string' && current.toLowerCase().includes(value.toLowerCase());\n case 'sw':\n return typeof current === 'string' && typeof value === 'string' && current.toLowerCase().startsWith(value.toLowerCase());\n case 'ew':\n return typeof current === 'string' && typeof value === 'string' && current.toLowerCase().endsWith(value.toLowerCase());\n case 'gt':\n return compareScalar(current, value) > 0;\n case 'ge':\n return compareScalar(current, value) >= 0;\n case 'lt':\n return compareScalar(current, value) < 0;\n case 'le':\n return compareScalar(current, value) <= 0;\n default:\n return false;\n }\n};\n\nconst compareScalar = (a: unknown, b: unknown): number => {\n if (typeof a === 'number' && typeof b === 'number') return a - b;\n const sa = String(a);\n const sb = String(b);\n if (sa < sb) return -1;\n if (sa > sb) return 1;\n return 0;\n};\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n};\n","import { ScimAttributeDefinition, ScimSchema } from '../schemas/schema.types.js';\n\n/**\n * Requested attribute projection for a SCIM response, from the `attributes` and\n * `excludedAttributes` query parameters (RFC 7644 §3.9). The two are mutually\n * exclusive; when a client sends both, `attributes` wins, being the more\n * restrictive of the pair.\n */\nexport interface ScimProjection {\n /** Attribute paths to return, in addition to those whose `returned` is `'always'`. */\n attributes?: string[];\n /** Attribute paths to omit. Attributes whose `returned` is `'always'` are never omitted. */\n excludedAttributes?: string[];\n}\n\n/**\n * Attributes every SCIM resource carries regardless of projection. RFC 7643 §7\n * treats `id`, `schemas`, and `meta` as `returned: 'always'`, but they are not\n * listed in the core schemas' `attributes` arrays, so they are matched by name.\n */\nconst ALWAYS_RETURNED = new Set(['id', 'schemas', 'meta']);\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => typeof value === 'object' && value !== null && !Array.isArray(value);\n\n/**\n * Split an attribute path into segments, tolerating the fully-qualified form\n * clients send for extension attributes\n * (`urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:department`).\n * The URN prefix becomes its own leading segment so it lines up with the\n * extension's top-level key on the resource.\n */\nconst splitPath = (path: string): string[] => {\n const urnBoundary = path.lastIndexOf(':');\n if (urnBoundary === -1) return path.split('.');\n return [path.slice(0, urnBoundary), ...path.slice(urnBoundary + 1).split('.')];\n};\n\n/**\n * A set of requested attribute paths. Comparisons are case-insensitive, as SCIM\n * attribute names are (RFC 7643 §2.1).\n */\nclass PathSet {\n private readonly paths: string[][];\n\n constructor(paths: string[]) {\n this.paths = paths.map(p => splitPath(p).map(s => s.toLowerCase()));\n }\n\n get empty(): boolean {\n return this.paths.length === 0;\n }\n\n /** Whether `segments` is at or above a requested path — `name` matches a request for `name.givenName`. */\n coversOrLeadsTo(segments: string[]): boolean {\n const target = segments.map(s => s.toLowerCase());\n return this.paths.some(path => {\n const shared = Math.min(path.length, target.length);\n for (let i = 0; i < shared; i++) {\n if (path[i] !== target[i]) return false;\n }\n return true;\n });\n }\n\n /** Whether `segments` is at or below a requested path — `name.givenName` matches a request for `name`. */\n isAtOrBelow(segments: string[]): boolean {\n const target = segments.map(s => s.toLowerCase());\n return this.paths.some(path => {\n if (path.length > target.length) return false;\n return path.every((segment, i) => segment === target[i]);\n });\n }\n}\n\nconst findDefinition = (definitions: ScimAttributeDefinition[], name: string): ScimAttributeDefinition | undefined =>\n definitions.find(d => d.name.toLowerCase() === name.toLowerCase());\n\ntype ProjectionMode = 'include' | 'exclude' | 'default';\n\n/**\n * Project a SCIM resource for the wire.\n *\n * Two things happen here, and only the first is optional:\n *\n * 1. `attributes` / `excludedAttributes` are applied, per RFC 7644 §3.9.\n * 2. Attributes the schema declares `returned: 'never'` are stripped\n * unconditionally. `password` is the one that matters: it is `writeOnly` and\n * `never`, so a repository that round-trips whatever it stored must not be\n * able to hand it back to a provisioning client.\n *\n * Attributes declared `returned: 'request'` come back only when named in\n * `attributes`. Keys no schema defines — a repository's own bookkeeping field,\n * an extension the caller did not declare — are kept unless a projection\n * excludes them, since the package cannot know they are safe to drop.\n *\n * @param resource - The resource to project. Not mutated.\n * @param schemas - The resource's schemas: the core one first, then any\n * extensions. An extension's attributes are matched under the resource key\n * named by its schema `id`.\n * @param projection - The requested projection; omit for schema rules only.\n * @returns A new resource object with the projection applied.\n */\nexport const projectScimResource = <T extends Record<string, unknown>>(resource: T, schemas: ScimSchema[], projection: ScimProjection = {}): T => {\n const requested = new PathSet(projection.attributes ?? []);\n const excluded = new PathSet(projection.excludedAttributes ?? []);\n const mode: ProjectionMode = !requested.empty ? 'include' : !excluded.empty ? 'exclude' : 'default';\n\n const [core, ...extensions] = schemas;\n const extensionsById = new Map(extensions.map(schema => [schema.id.toLowerCase(), schema]));\n\n return projectObject(resource, core?.attributes ?? [], extensionsById, [], mode, requested, excluded) as T;\n};\n\nconst projectObject = (\n source: Record<string, unknown>,\n definitions: ScimAttributeDefinition[],\n extensionsById: Map<string, ScimSchema>,\n prefix: string[],\n mode: ProjectionMode,\n requested: PathSet,\n excluded: PathSet,\n): Record<string, unknown> => {\n const out: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(source)) {\n const segments = [...prefix, key];\n const extension = prefix.length === 0 ? extensionsById.get(key.toLowerCase()) : undefined;\n const definition = findDefinition(definitions, key);\n const alwaysReturned = definition?.returned === 'always' || (prefix.length === 0 && ALWAYS_RETURNED.has(key.toLowerCase()));\n\n if (definition?.returned === 'never') continue;\n\n if (!alwaysReturned) {\n if (mode === 'include' && !requested.coversOrLeadsTo(segments)) continue;\n if (mode === 'exclude' && excluded.isAtOrBelow(segments)) continue;\n if (mode !== 'include' && definition?.returned === 'request') continue;\n }\n\n // A schema extension is a nested object keyed by its URN; its attributes are\n // defined by the extension schema, not by the core one.\n if (extension && isPlainObject(value)) {\n out[key] = projectObject(value, extension.attributes, extensionsById, segments, mode, requested, excluded);\n continue;\n }\n\n const subDefinitions = definition?.subAttributes;\n if (subDefinitions && Array.isArray(value)) {\n out[key] = value.map(entry =>\n isPlainObject(entry) ? projectObject(entry, subDefinitions, extensionsById, segments, mode, requested, excluded) : entry,\n );\n continue;\n }\n if (subDefinitions && isPlainObject(value)) {\n out[key] = projectObject(value, subDefinitions, extensionsById, segments, mode, requested, excluded);\n continue;\n }\n\n out[key] = value;\n }\n\n return out;\n};\n","import type { ScimUser } from '../types/scim.user.js';\nimport type { ScimListQuery, ScimListResult } from './repository.types.js';\n\n/**\n * Storage contract for SCIM `User` resources. The package ships only this\n * abstract class — implement it against your datastore (Kysely, Prisma,\n * Drizzle, in-memory) and pass the instance to {@link createScimRouter}.\n *\n * Implementations are responsible for:\n * - Translating the parsed filter AST in {@link ScimListQuery.filter} into a\n * native query.\n * - Honouring `startIndex` (1-based) and `count` for pagination.\n * - Returning the total number of matching resources, not just the page size.\n * - Persisting `meta.created` / `meta.lastModified` timestamps.\n *\n * Modeled as an abstract class so the runtime reference is a valid InjectKit\n * token (interfaces aren't preserved at runtime).\n */\nexport abstract class ScimUserRepository {\n /** Look up a user by server-assigned id. Return `undefined` if not found. */\n abstract findById(id: string): Promise<ScimUser | undefined>;\n\n /** Look up a user by `userName` (case-insensitive per RFC 7643). */\n abstract findByUserName(userName: string): Promise<ScimUser | undefined>;\n\n /** Look up a user by `externalId` (client-supplied identifier). */\n abstract findByExternalId(externalId: string): Promise<ScimUser | undefined>;\n\n /** List users matching a parsed query. */\n abstract list(query: ScimListQuery): Promise<ScimListResult<ScimUser>>;\n\n /** Persist a fully-formed user. `id`, `schemas`, and `meta` are already populated by {@link ScimUserService}. */\n abstract create(user: ScimUser): Promise<ScimUser>;\n\n /** Replace the entirety of an existing user (PUT semantics). */\n abstract replace(id: string, user: ScimUser): Promise<ScimUser>;\n\n /** Delete a user by id. Implementations may treat missing ids as a no-op. */\n abstract delete(id: string): Promise<void>;\n}\n","import type { ScimGroup } from '../types/scim.group.js';\nimport type { ScimListQuery, ScimListResult } from './repository.types.js';\n\n/**\n * Storage contract for SCIM `Group` resources. See\n * {@link ScimUserRepository} for general implementation guidance.\n */\nexport abstract class ScimGroupRepository {\n /** Look up a group by server-assigned id. */\n abstract findById(id: string): Promise<ScimGroup | undefined>;\n\n /** Look up a group by `displayName`. */\n abstract findByDisplayName(displayName: string): Promise<ScimGroup | undefined>;\n\n /** Look up a group by `externalId`. */\n abstract findByExternalId(externalId: string): Promise<ScimGroup | undefined>;\n\n /** List groups matching a parsed query. */\n abstract list(query: ScimListQuery): Promise<ScimListResult<ScimGroup>>;\n\n /** Persist a new group. */\n abstract create(group: ScimGroup): Promise<ScimGroup>;\n\n /** Replace the entirety of an existing group (PUT semantics). */\n abstract replace(id: string, group: ScimGroup): Promise<ScimGroup>;\n\n /** Delete a group by id. */\n abstract delete(id: string): Promise<void>;\n}\n","import { randomUUID } from 'node:crypto';\nimport { DateTime } from 'luxon';\nimport { Injectable } from 'injectkit';\nimport { Logger } from '@maroonedsoftware/logger';\nimport { ScimUserRepository } from '../repositories/scim.user.repository.js';\nimport type { ScimListQuery, ScimListResult } from '../repositories/repository.types.js';\nimport type { ScimUser } from '../types/scim.user.js';\nimport type { ScimPatchOp } from '../types/patch.op.js';\nimport { applyScimPatch } from '../patch/patch.applier.js';\nimport { scimError } from '../errors/scim.error.js';\nimport { UserSchemaId } from '../schemas/user.schema.js';\nimport { EnterpriseUserSchemaId } from '../schemas/enterprise.user.schema.js';\n\n/**\n * Application service wrapping a {@link ScimUserRepository}. Owns id and meta\n * assignment, uniqueness enforcement, and PATCH application — keeping the\n * repository focused on storage concerns.\n */\n@Injectable()\nexport class ScimUserService {\n constructor(\n private readonly repository: ScimUserRepository,\n private readonly logger: Logger,\n ) {}\n\n /**\n * Fetch a single user by id.\n *\n * @throws {ScimError} 404 if no user exists with the given id.\n */\n async get(id: string): Promise<ScimUser> {\n const user = await this.repository.findById(id);\n if (!user) throw scimError(404, undefined, 'Not Found').withDetails({ message: `User \"${id}\" not found` });\n return user;\n }\n\n /**\n * List users matching a parsed SCIM query, returning the page plus the\n * total number of matches (for the `totalResults` envelope field).\n */\n async list(query: ScimListQuery): Promise<ScimListResult<ScimUser>> {\n return this.repository.list(query);\n }\n\n /**\n * Create a new user. Assigns a server-generated `id`, fills `meta.created`\n * and `meta.lastModified`, and ensures the resource's `schemas` includes the\n * core User URN (and the EnterpriseUser URN when the extension is present).\n *\n * An `id` on the payload is ignored: RFC 7643 §3.1 makes it readOnly and\n * server-assigned.\n *\n * @throws {ScimError} 400 `invalidValue` when `userName` is missing.\n * @throws {ScimError} 409 `uniqueness` when `userName` already exists.\n */\n async create(payload: Partial<ScimUser>): Promise<ScimUser> {\n if (!payload.userName) {\n throw scimError(400, 'invalidValue', 'Bad Request').withDetails({ message: '\"userName\" is required' });\n }\n const existing = await this.repository.findByUserName(payload.userName);\n if (existing) {\n throw scimError(409, 'uniqueness', 'Conflict').withDetails({ message: `userName \"${payload.userName}\" already exists` });\n }\n const now = DateTime.utc().toISO();\n // RFC 7643 §3.1 makes `id` server-assigned and readOnly. Honouring a client-supplied\n // one lets a POST collide with an existing record's primary key.\n const id = randomUUID();\n const user: ScimUser = {\n ...payload,\n id,\n userName: payload.userName,\n schemas: this.normaliseSchemas(payload.schemas, payload),\n meta: {\n resourceType: 'User',\n created: now,\n lastModified: now,\n location: `/Users/${id}`,\n },\n };\n this.logger.debug('scim: creating user', { id, userName: user.userName });\n return this.repository.create(user);\n }\n\n /**\n * Replace an existing user wholesale (PUT semantics). Preserves the original\n * `id` and `meta.created`; updates `meta.lastModified`.\n *\n * @throws {ScimError} 404 when no user exists with the given id.\n * @throws {ScimError} 400 `invalidValue` when `userName` is missing.\n * @throws {ScimError} 409 `uniqueness` when changing `userName` would collide\n * with another existing user.\n */\n async replace(id: string, payload: Partial<ScimUser>): Promise<ScimUser> {\n const existing = await this.repository.findById(id);\n if (!existing) throw scimError(404, undefined, 'Not Found').withDetails({ message: `User \"${id}\" not found` });\n if (!payload.userName) {\n throw scimError(400, 'invalidValue', 'Bad Request').withDetails({ message: '\"userName\" is required' });\n }\n if (payload.userName !== existing.userName) {\n const conflict = await this.repository.findByUserName(payload.userName);\n if (conflict && conflict.id !== id) {\n throw scimError(409, 'uniqueness', 'Conflict').withDetails({ message: `userName \"${payload.userName}\" already exists` });\n }\n }\n const now = DateTime.utc().toISO();\n const user: ScimUser = {\n ...payload,\n id,\n userName: payload.userName,\n schemas: this.normaliseSchemas(payload.schemas, payload),\n meta: {\n ...existing.meta,\n lastModified: now,\n location: existing.meta.location ?? `/Users/${id}`,\n },\n };\n return this.repository.replace(id, user);\n }\n\n /**\n * Apply a sequence of SCIM PATCH ops (RFC 7644 §3.5.2) and persist the\n * result via `replace`. Updates `meta.lastModified`.\n *\n * @throws {ScimError} 404 when no user exists with the given id.\n * @throws {ScimError} 400 propagated from {@link applyScimPatch} for invalid\n * paths, unknown ops, or no-target failures, or `invalidValue` when the patch\n * would remove the required `userName`.\n * @throws {ScimError} 409 `uniqueness` when the patch changes `userName` to a\n * value already owned by another user.\n */\n async patch(id: string, ops: ScimPatchOp[]): Promise<ScimUser> {\n const existing = await this.repository.findById(id);\n if (!existing) throw scimError(404, undefined, 'Not Found').withDetails({ message: `User \"${id}\" not found` });\n const patched = applyScimPatch(existing as unknown as Record<string, unknown>, ops) as unknown as ScimUser;\n if (!patched.userName) {\n throw scimError(400, 'invalidValue', 'Bad Request').withDetails({ message: '\"userName\" is required' });\n }\n if (patched.userName !== existing.userName) {\n const conflict = await this.repository.findByUserName(patched.userName);\n if (conflict && conflict.id !== id) {\n throw scimError(409, 'uniqueness', 'Conflict').withDetails({ message: `userName \"${patched.userName}\" already exists` });\n }\n }\n patched.id = existing.id;\n patched.meta = {\n ...existing.meta,\n lastModified: DateTime.utc().toISO(),\n };\n return this.repository.replace(id, patched);\n }\n\n /**\n * Delete a user by id.\n *\n * @throws {ScimError} 404 when no user exists with the given id.\n */\n async delete(id: string): Promise<void> {\n const existing = await this.repository.findById(id);\n if (!existing) throw scimError(404, undefined, 'Not Found').withDetails({ message: `User \"${id}\" not found` });\n await this.repository.delete(id);\n }\n\n private normaliseSchemas(provided: string[] | undefined, payload: Partial<ScimUser>): string[] {\n const schemas = new Set<string>(provided ?? []);\n schemas.add(UserSchemaId);\n if (payload[EnterpriseUserSchemaId]) {\n schemas.add(EnterpriseUserSchemaId);\n }\n return Array.from(schemas);\n }\n}\n","import { randomUUID } from 'node:crypto';\nimport { DateTime } from 'luxon';\nimport { Injectable } from 'injectkit';\nimport { Logger } from '@maroonedsoftware/logger';\nimport { ScimGroupRepository } from '../repositories/scim.group.repository.js';\nimport type { ScimListQuery, ScimListResult } from '../repositories/repository.types.js';\nimport type { ScimGroup } from '../types/scim.group.js';\nimport type { ScimPatchOp } from '../types/patch.op.js';\nimport { applyScimPatch } from '../patch/patch.applier.js';\nimport { scimError } from '../errors/scim.error.js';\nimport { GroupSchemaId } from '../schemas/group.schema.js';\n\n/**\n * Application service wrapping a {@link ScimGroupRepository}. Mirrors\n * {@link ScimUserService}: id/meta assignment, uniqueness on `displayName`,\n * and PATCH application.\n */\n@Injectable()\nexport class ScimGroupService {\n constructor(\n private readonly repository: ScimGroupRepository,\n private readonly logger: Logger,\n ) {}\n\n /**\n * Fetch a single group by id.\n *\n * @throws {ScimError} 404 when no group exists with the given id.\n */\n async get(id: string): Promise<ScimGroup> {\n const group = await this.repository.findById(id);\n if (!group) throw scimError(404, undefined, 'Not Found').withDetails({ message: `Group \"${id}\" not found` });\n return group;\n }\n\n /**\n * List groups matching a parsed SCIM query, returning the page plus the\n * total number of matches.\n */\n async list(query: ScimListQuery): Promise<ScimListResult<ScimGroup>> {\n return this.repository.list(query);\n }\n\n /**\n * Create a new group. Assigns a server-generated `id` and fills `meta`\n * timestamps. An `id` on the payload is ignored: RFC 7643 §3.1 makes it\n * readOnly and server-assigned.\n *\n * @throws {ScimError} 400 `invalidValue` when `displayName` is missing.\n * @throws {ScimError} 409 `uniqueness` when `displayName` already exists.\n */\n async create(payload: Partial<ScimGroup>): Promise<ScimGroup> {\n if (!payload.displayName) {\n throw scimError(400, 'invalidValue', 'Bad Request').withDetails({ message: '\"displayName\" is required' });\n }\n const existing = await this.repository.findByDisplayName(payload.displayName);\n if (existing) {\n throw scimError(409, 'uniqueness', 'Conflict').withDetails({ message: `displayName \"${payload.displayName}\" already exists` });\n }\n const now = DateTime.utc().toISO();\n // RFC 7643 §3.1 makes `id` server-assigned and readOnly. Honouring a client-supplied\n // one lets a POST collide with an existing record's primary key.\n const id = randomUUID();\n const group: ScimGroup = {\n ...payload,\n id,\n displayName: payload.displayName,\n schemas: this.normaliseSchemas(payload.schemas),\n meta: {\n resourceType: 'Group',\n created: now,\n lastModified: now,\n location: `/Groups/${id}`,\n },\n };\n this.logger.debug('scim: creating group', { id, displayName: group.displayName });\n return this.repository.create(group);\n }\n\n /**\n * Replace an existing group wholesale (PUT semantics). Preserves `id` and\n * `meta.created`; updates `meta.lastModified`.\n *\n * @throws {ScimError} 404 when no group exists with the given id.\n * @throws {ScimError} 400 `invalidValue` when `displayName` is missing.\n * @throws {ScimError} 409 `uniqueness` when changing `displayName` would collide.\n */\n async replace(id: string, payload: Partial<ScimGroup>): Promise<ScimGroup> {\n const existing = await this.repository.findById(id);\n if (!existing) throw scimError(404, undefined, 'Not Found').withDetails({ message: `Group \"${id}\" not found` });\n if (!payload.displayName) {\n throw scimError(400, 'invalidValue', 'Bad Request').withDetails({ message: '\"displayName\" is required' });\n }\n if (payload.displayName !== existing.displayName) {\n const conflict = await this.repository.findByDisplayName(payload.displayName);\n if (conflict && conflict.id !== id) {\n throw scimError(409, 'uniqueness', 'Conflict').withDetails({ message: `displayName \"${payload.displayName}\" already exists` });\n }\n }\n const now = DateTime.utc().toISO();\n const group: ScimGroup = {\n ...payload,\n id,\n displayName: payload.displayName,\n schemas: this.normaliseSchemas(payload.schemas),\n meta: {\n ...existing.meta,\n lastModified: now,\n location: existing.meta.location ?? `/Groups/${id}`,\n },\n };\n return this.repository.replace(id, group);\n }\n\n /**\n * Apply a sequence of SCIM PATCH ops and persist the result. Updates\n * `meta.lastModified`.\n *\n * @throws {ScimError} 404 when no group exists with the given id.\n * @throws {ScimError} 400 propagated from {@link applyScimPatch}.\n */\n async patch(id: string, ops: ScimPatchOp[]): Promise<ScimGroup> {\n const existing = await this.repository.findById(id);\n if (!existing) throw scimError(404, undefined, 'Not Found').withDetails({ message: `Group \"${id}\" not found` });\n const patched = applyScimPatch(existing as unknown as Record<string, unknown>, ops) as unknown as ScimGroup;\n patched.id = existing.id;\n patched.meta = {\n ...existing.meta,\n lastModified: DateTime.utc().toISO(),\n };\n return this.repository.replace(id, patched);\n }\n\n /**\n * Delete a group by id.\n *\n * @throws {ScimError} 404 when no group exists with the given id.\n */\n async delete(id: string): Promise<void> {\n const existing = await this.repository.findById(id);\n if (!existing) throw scimError(404, undefined, 'Not Found').withDetails({ message: `Group \"${id}\" not found` });\n await this.repository.delete(id);\n }\n\n private normaliseSchemas(provided: string[] | undefined): string[] {\n const schemas = new Set<string>(provided ?? []);\n schemas.add(GroupSchemaId);\n return Array.from(schemas);\n }\n}\n","import { Injectable } from 'injectkit';\nimport {\n buildServiceProviderConfig,\n type ScimServiceProviderConfig,\n type ScimServiceProviderConfigOptions,\n} from '../schemas/service.provider.config.schema.js';\nimport { coreSchemas } from '../schemas/index.js';\nimport { userResourceType, groupResourceType, type ScimResourceType } from '../schemas/resource.type.schema.js';\nimport type { ScimSchema } from '../schemas/schema.types.js';\nimport { scimError } from '../errors/scim.error.js';\n\n/**\n * Serves the SCIM discovery endpoints: `/ServiceProviderConfig`, `/Schemas`,\n * and `/ResourceTypes`. The config is fixed at construction time — what the\n * server advertises must match what the router actually implements.\n */\n@Injectable()\nexport class ScimServiceProviderService {\n private readonly config: ScimServiceProviderConfig;\n private readonly schemas: ScimSchema[];\n private readonly resourceTypes: ScimResourceType[];\n\n constructor(options: ScimServiceProviderConfigOptions = {}) {\n this.config = buildServiceProviderConfig(options);\n this.schemas = coreSchemas;\n this.resourceTypes = [userResourceType, groupResourceType];\n }\n\n /** The materialised `/ServiceProviderConfig` response. */\n getServiceProviderConfig(): ScimServiceProviderConfig {\n return this.config;\n }\n\n /** Every schema known to this server, served from `/Schemas`. */\n listSchemas(): ScimSchema[] {\n return this.schemas;\n }\n\n /**\n * Look up a single schema by its URN.\n *\n * @throws {ScimError} 404 if the URN is not registered.\n */\n getSchema(id: string): ScimSchema {\n const found = this.schemas.find(s => s.id === id);\n if (!found) throw scimError(404, undefined, 'Not Found').withDetails({ message: `Schema \"${id}\" not found` });\n return found;\n }\n\n /** Every resource type known to this server, served from `/ResourceTypes`. */\n listResourceTypes(): ScimResourceType[] {\n return this.resourceTypes;\n }\n\n /**\n * Look up a single resource type by id (e.g. `User`, `Group`).\n *\n * @throws {ScimError} 404 if the id is not registered.\n */\n getResourceType(id: string): ScimResourceType {\n const found = this.resourceTypes.find(rt => rt.id === id);\n if (!found) throw scimError(404, undefined, 'Not Found').withDetails({ message: `ResourceType \"${id}\" not found` });\n return found;\n }\n}\n","import type { ServerKitMiddleware } from '@maroonedsoftware/koa';\nimport { scimError } from '../errors/scim.error.js';\n\n/** SCIM media type per RFC 7644 §3.8. */\nexport const SCIM_MEDIA_TYPE = 'application/scim+json';\n\n/**\n * Enforce that mutating SCIM requests carry `Content-Type: application/scim+json`\n * (or `application/json`, which the spec accepts for backward compatibility),\n * and tag the response so it serialises with the SCIM media type.\n */\nexport const scimContentTypeMiddleware = (): ServerKitMiddleware => {\n return async (ctx, next) => {\n const method = ctx.method.toUpperCase();\n if (method === 'POST' || method === 'PUT' || method === 'PATCH') {\n const contentType = (ctx.request.headers['content-type'] ?? '').toLowerCase();\n if (contentType && !contentType.includes(SCIM_MEDIA_TYPE) && !contentType.includes('application/json')) {\n throw scimError(415, undefined, 'Unsupported Media Type').withDetails({\n message: `Content-Type must be ${SCIM_MEDIA_TYPE}`,\n });\n }\n }\n await next();\n if (ctx.body !== undefined && ctx.body !== null) {\n ctx.type = SCIM_MEDIA_TYPE;\n }\n };\n};\n","import type { ServerKitMiddleware } from '@maroonedsoftware/koa';\nimport { IsHttpError, IsServerkitError } from '@maroonedsoftware/errors';\nimport { IsScimError, ScimError, ScimErrorSchema } from '../errors/scim.error.js';\nimport { SCIM_MEDIA_TYPE } from './scim.content.type.middleware.js';\n\n/**\n * SCIM-shaped error middleware. Catches errors thrown by downstream handlers\n * and renders them as the RFC 7644 §3.12 envelope with `Content-Type:\n * application/scim+json`.\n *\n * Mount this *inside* a SCIM sub-router (or in front of the SCIM router on\n * its own Koa instance) — do not replace the application-wide\n * `errorMiddleware` from `@maroonedsoftware/koa` with it.\n */\nexport const scimErrorMiddleware = (): ServerKitMiddleware => {\n return async (ctx, next) => {\n try {\n await next();\n if (ctx.status === 404 && !ctx.body) {\n const status = 404;\n ctx.status = status;\n ctx.type = SCIM_MEDIA_TYPE;\n ctx.body = {\n schemas: [ScimErrorSchema],\n status: String(status),\n detail: `Not Found: ${ctx.URL.pathname}`,\n };\n }\n } catch (error) {\n if (IsScimError(error)) {\n respondWithScimError(ctx, error);\n ctx.app.emit('error', error, ctx);\n return;\n }\n if (IsHttpError(error)) {\n respondWithScimError(ctx, new ScimError(error.statusCode).withDetails(error.details ?? {}).withCause(error));\n ctx.app.emit('error', error, ctx);\n return;\n }\n const status = 500;\n const detail = IsServerkitError(error) ? error.message : 'Internal Server Error';\n ctx.status = status;\n ctx.type = SCIM_MEDIA_TYPE;\n ctx.body = {\n schemas: [ScimErrorSchema],\n status: String(status),\n detail,\n };\n ctx.app.emit('error', error, ctx);\n }\n };\n};\n\nconst respondWithScimError = (ctx: Parameters<ServerKitMiddleware>[0], error: ScimError): void => {\n ctx.status = error.statusCode;\n ctx.type = SCIM_MEDIA_TYPE;\n ctx.body = error.toScimBody();\n if (error.headers) {\n for (const [name, value] of Object.entries(error.headers)) {\n ctx.set(name, value);\n }\n }\n};\n","import type { ServerKitRouterMiddleware } from '@maroonedsoftware/koa';\nimport { invalidAuthenticationSession } from '@maroonedsoftware/authentication';\nimport { scimError } from '../errors/scim.error.js';\n\n/**\n * Router middleware enforcing that the current request carries a SCIM scope\n * on its authentication session. The scope list is read from\n * `ctx.authenticationSession.claims.scimScopes` — a string array the consumer\n * populates when minting the session for the bearer token.\n *\n * Wildcard scope `*` in the session grants every check.\n */\nexport const requireScimScope = (scope: string): ServerKitRouterMiddleware => {\n return async (ctx, next) => {\n const session = ctx.authenticationSession;\n if (!session || session === invalidAuthenticationSession) {\n throw scimError(401, undefined, 'Unauthorized')\n .addHeader('WWW-Authenticate', 'Bearer error=\"invalid_token\"')\n .withDetails({ message: 'Missing or invalid bearer token' });\n }\n const granted = session.claims?.scimScopes;\n if (!Array.isArray(granted) || (!granted.includes('*') && !granted.includes(scope))) {\n throw scimError(403, 'insufficientScope', 'Forbidden').withDetails({ message: `Scope \"${scope}\" required` });\n }\n await next();\n };\n};\n","import type { ServerKitContext, ServerKitRouterMiddleware } from '@maroonedsoftware/koa';\nimport { bodyParserMiddleware, ServerKitRouter } from '@maroonedsoftware/koa';\nimport type Router from '@koa/router';\nimport { ScimUserService } from '../services/scim.user.service.js';\nimport { ScimGroupService } from '../services/scim.group.service.js';\nimport { ScimServiceProviderService } from '../services/scim.service.provider.service.js';\nimport type { ScimUser } from '../types/scim.user.js';\nimport type { ScimGroup } from '../types/scim.group.js';\nimport { type ScimPatchOp, type ScimPatchRequest, PatchOpSchema } from '../types/patch.op.js';\nimport { ListResponseSchema, type ScimListResponse } from '../types/list.response.js';\nimport { type ScimListQuery, type ScimSortOrder } from '../repositories/repository.types.js';\nimport { parseScimFilter } from '../filter/filter.parser.js';\nimport { scimError } from '../errors/scim.error.js';\nimport { SCIM_MEDIA_TYPE } from '../middleware/scim.content.type.middleware.js';\nimport { projectScimResource, type ScimProjection } from '../projection/attribute.projection.js';\nimport { userSchema } from '../schemas/user.schema.js';\nimport { groupSchema } from '../schemas/group.schema.js';\nimport { enterpriseUserSchema } from '../schemas/enterprise.user.schema.js';\n\n/**\n * Options for {@link createScimRouter}. The caller constructs the three\n * services (wiring them to their backing repositories and a logger) and\n * hands them in.\n */\nexport interface CreateScimRouterOptions {\n /** Service handling all `/Users` endpoints. */\n userService: ScimUserService;\n /** Service handling all `/Groups` endpoints. */\n groupService: ScimGroupService;\n /** Service that owns `/Schemas`, `/ResourceTypes`, `/ServiceProviderConfig`. */\n serviceProviderService: ScimServiceProviderService;\n /** Optional middleware mounted on every route (e.g. `requireScimScope('users:read')`). */\n routeGuards?: ServerKitRouterMiddleware[];\n /**\n * Maximum page size returned from list endpoints. Defaults to the\n * `serviceProviderService` `filter.maxResults` value, falling back to 200.\n */\n maxResults?: number;\n /**\n * Absolute base URL this router is reachable at, e.g.\n * `https://api.example.com/scim/v2`. When set, `meta.location` and the\n * `Location` response header are rendered against it, as RFC 7643 §3.1 wants\n * a resource URI. Leave it unset to keep the previous behaviour of emitting a\n * root-relative path (`/Users/{id}`), which is wrong for any deployment that\n * mounts the router under a prefix.\n */\n baseUrl?: string;\n}\n\n/**\n * Build a SCIM 2.0 server router. Mount it inside a Koa app that already has\n * `serverKitContextMiddleware` and `authenticationMiddleware` configured, and\n * use `scimErrorMiddleware()` instead of the default `errorMiddleware()` for\n * the SCIM mountpoint.\n *\n * Endpoints (RFC 7644 §3.4):\n * - `GET /Users` — list users (with `filter`, `startIndex`, `count`, `sortBy`, `sortOrder`)\n * - `POST /Users` — create user\n * - `GET /Users/:id` — fetch one user\n * - `PUT /Users/:id` — replace user\n * - `PATCH /Users/:id` — apply PATCH ops\n * - `DELETE /Users/:id` — delete user\n * - `POST /Users/.search` — list-via-POST so large filters can be sent in the body\n * - Same six endpoints for `/Groups` and `/Groups/.search`\n * - `GET /Schemas`, `GET /Schemas/:id`\n * - `GET /ResourceTypes`, `GET /ResourceTypes/:id`\n * - `GET /ServiceProviderConfig`\n */\nexport const createScimRouter = (options: CreateScimRouterOptions): Router<unknown, ServerKitContext> => {\n const router = ServerKitRouter();\n const guards = options.routeGuards ?? [];\n const json = bodyParserMiddleware([SCIM_MEDIA_TYPE, 'application/json']);\n const maxResults = options.maxResults ?? options.serviceProviderService.getServiceProviderConfig().filter.maxResults ?? 200;\n const baseUrl = options.baseUrl?.replace(/\\/+$/, '');\n\n /**\n * Render a resource's `meta.location` against the configured base URL. The\n * services assign a root-relative path because they do not know where the\n * router is mounted; without a `baseUrl` that path is left as-is.\n */\n const withLocation = <T extends { id: string; meta: { location?: string } }>(resource: T, endpoint: 'Users' | 'Groups'): T =>\n baseUrl ? { ...resource, meta: { ...resource.meta, location: `${baseUrl}/${endpoint}/${resource.id}` } } : resource;\n\n // Discovery endpoints — RFC 7644 §4 says these MAY be unauthenticated. Apply\n // the route guards anyway so the consumer can decide.\n router.get('/ServiceProviderConfig', ...guards, async ctx => {\n ctx.body = options.serviceProviderService.getServiceProviderConfig();\n ctx.type = SCIM_MEDIA_TYPE;\n });\n\n router.get('/Schemas', ...guards, async ctx => {\n ctx.body = listEnvelope(options.serviceProviderService.listSchemas());\n ctx.type = SCIM_MEDIA_TYPE;\n });\n\n router.get('/Schemas/:id', ...guards, async ctx => {\n ctx.body = options.serviceProviderService.getSchema(ctx.params.id!);\n ctx.type = SCIM_MEDIA_TYPE;\n });\n\n router.get('/ResourceTypes', ...guards, async ctx => {\n ctx.body = listEnvelope(options.serviceProviderService.listResourceTypes());\n ctx.type = SCIM_MEDIA_TYPE;\n });\n\n router.get('/ResourceTypes/:id', ...guards, async ctx => {\n ctx.body = options.serviceProviderService.getResourceType(ctx.params.id!);\n ctx.type = SCIM_MEDIA_TYPE;\n });\n\n // Users\n router.get('/Users', ...guards, async ctx => {\n const query = parseListQueryFromUrl(ctx.query, maxResults);\n const result = await options.userService.list(query);\n ctx.body = listEnvelope(\n result.resources.map(user => projectUser(withLocation(user, 'Users'), query)),\n query,\n result.totalResults,\n );\n ctx.type = SCIM_MEDIA_TYPE;\n });\n\n router.post('/Users/.search', ...guards, json, async ctx => {\n const requestBody = takeRequestBody(ctx);\n const query = parseListQueryFromBody(requestBody, maxResults);\n const result = await options.userService.list(query);\n ctx.body = listEnvelope(\n result.resources.map(user => projectUser(withLocation(user, 'Users'), query)),\n query,\n result.totalResults,\n );\n ctx.type = SCIM_MEDIA_TYPE;\n });\n\n router.post('/Users', ...guards, json, async ctx => {\n const payload = takeRequestBody(ctx) as Partial<ScimUser>;\n const created = await options.userService.create(payload);\n ctx.status = 201;\n const located = withLocation(created, 'Users');\n ctx.body = projectUser(located, parseProjectionFromUrl(ctx.query));\n ctx.type = SCIM_MEDIA_TYPE;\n if (located.meta.location) ctx.set('Location', located.meta.location);\n });\n\n router.get('/Users/:id', ...guards, async ctx => {\n ctx.body = projectUser(withLocation(await options.userService.get(ctx.params.id!), 'Users'), parseProjectionFromUrl(ctx.query));\n ctx.type = SCIM_MEDIA_TYPE;\n });\n\n router.put('/Users/:id', ...guards, json, async ctx => {\n const payload = takeRequestBody(ctx) as Partial<ScimUser>;\n ctx.body = projectUser(withLocation(await options.userService.replace(ctx.params.id!, payload), 'Users'), parseProjectionFromUrl(ctx.query));\n ctx.type = SCIM_MEDIA_TYPE;\n });\n\n router.patch('/Users/:id', ...guards, json, async ctx => {\n const requestBody = takeRequestBody(ctx) as Partial<ScimPatchRequest>;\n const ops = validatePatchRequest(requestBody);\n ctx.body = projectUser(withLocation(await options.userService.patch(ctx.params.id!, ops), 'Users'), parseProjectionFromUrl(ctx.query));\n ctx.type = SCIM_MEDIA_TYPE;\n });\n\n router.delete('/Users/:id', ...guards, async ctx => {\n await options.userService.delete(ctx.params.id!);\n ctx.status = 204;\n });\n\n // Groups\n router.get('/Groups', ...guards, async ctx => {\n const query = parseListQueryFromUrl(ctx.query, maxResults);\n const result = await options.groupService.list(query);\n ctx.body = listEnvelope(\n result.resources.map(group => projectGroup(withLocation(group, 'Groups'), query)),\n query,\n result.totalResults,\n );\n ctx.type = SCIM_MEDIA_TYPE;\n });\n\n router.post('/Groups/.search', ...guards, json, async ctx => {\n const requestBody = takeRequestBody(ctx);\n const query = parseListQueryFromBody(requestBody, maxResults);\n const result = await options.groupService.list(query);\n ctx.body = listEnvelope(\n result.resources.map(group => projectGroup(withLocation(group, 'Groups'), query)),\n query,\n result.totalResults,\n );\n ctx.type = SCIM_MEDIA_TYPE;\n });\n\n router.post('/Groups', ...guards, json, async ctx => {\n const payload = takeRequestBody(ctx) as Partial<ScimGroup>;\n const created = await options.groupService.create(payload);\n ctx.status = 201;\n const located = withLocation(created, 'Groups');\n ctx.body = projectGroup(located, parseProjectionFromUrl(ctx.query));\n ctx.type = SCIM_MEDIA_TYPE;\n if (located.meta.location) ctx.set('Location', located.meta.location);\n });\n\n router.get('/Groups/:id', ...guards, async ctx => {\n ctx.body = projectGroup(withLocation(await options.groupService.get(ctx.params.id!), 'Groups'), parseProjectionFromUrl(ctx.query));\n ctx.type = SCIM_MEDIA_TYPE;\n });\n\n router.put('/Groups/:id', ...guards, json, async ctx => {\n const payload = takeRequestBody(ctx) as Partial<ScimGroup>;\n ctx.body = projectGroup(withLocation(await options.groupService.replace(ctx.params.id!, payload), 'Groups'), parseProjectionFromUrl(ctx.query));\n ctx.type = SCIM_MEDIA_TYPE;\n });\n\n router.patch('/Groups/:id', ...guards, json, async ctx => {\n const requestBody = takeRequestBody(ctx) as Partial<ScimPatchRequest>;\n const ops = validatePatchRequest(requestBody);\n ctx.body = projectGroup(withLocation(await options.groupService.patch(ctx.params.id!, ops), 'Groups'), parseProjectionFromUrl(ctx.query));\n ctx.type = SCIM_MEDIA_TYPE;\n });\n\n router.delete('/Groups/:id', ...guards, async ctx => {\n await options.groupService.delete(ctx.params.id!);\n ctx.status = 204;\n });\n\n return router;\n};\n\n/** Schemas a `/Users` response is projected against: the core one plus the enterprise extension. */\nconst userSchemas = [userSchema, enterpriseUserSchema];\n\n/**\n * Project a user for the wire. Applies the requested `attributes` /\n * `excludedAttributes` and always strips attributes the schema declares\n * `returned: 'never'` — notably `password`, which is `writeOnly` and must never\n * come back out of a repository that stored what it was given.\n */\nconst projectUser = (user: ScimUser, projection: ScimProjection): ScimUser =>\n projectScimResource(user as unknown as Record<string, unknown>, userSchemas, projection) as unknown as ScimUser;\n\n/** Project a group for the wire. See {@link projectUser}. */\nconst projectGroup = (group: ScimGroup, projection: ScimProjection): ScimGroup =>\n projectScimResource(group as unknown as Record<string, unknown>, [groupSchema], projection) as unknown as ScimGroup;\n\n/**\n * Read the `attributes` / `excludedAttributes` projection from a query string.\n * RFC 7644 §3.9 allows them on single-resource reads and writes as well as lists.\n */\nconst parseProjectionFromUrl = (query: ServerKitContext['query']): ScimProjection => ({\n attributes: parseCsvParam(pickStringParam(query, 'attributes')),\n excludedAttributes: parseCsvParam(pickStringParam(query, 'excludedAttributes')),\n});\n\n/**\n * `bodyParserMiddleware` writes the parsed request body to `ctx.parsedBody`\n * (distinct from `ctx.body`, which is the response). Return it for the handler.\n */\nconst takeRequestBody = (ctx: ServerKitContext): unknown => {\n return ctx.parsedBody;\n};\n\nconst parseListQueryFromUrl = (query: ServerKitContext['query'], maxResults: number): ScimListQuery => {\n const filterRaw = pickStringParam(query, 'filter');\n return {\n filter: filterRaw ? parseScimFilter(filterRaw) : undefined,\n startIndex: parsePositiveInt(pickStringParam(query, 'startIndex'), 1),\n count: clamp(parseCount(pickStringParam(query, 'count'), maxResults), 0, maxResults),\n sortBy: pickStringParam(query, 'sortBy'),\n sortOrder: parseSortOrder(pickStringParam(query, 'sortOrder')),\n attributes: parseCsvParam(pickStringParam(query, 'attributes')),\n excludedAttributes: parseCsvParam(pickStringParam(query, 'excludedAttributes')),\n };\n};\n\nconst parseListQueryFromBody = (body: unknown, maxResults: number): ScimListQuery => {\n if (!isPlainObject(body)) {\n throw scimError(400, 'invalidSyntax', 'Bad Request').withDetails({ message: 'Search body must be a JSON object' });\n }\n const filterRaw = typeof body.filter === 'string' ? body.filter : undefined;\n return {\n filter: filterRaw ? parseScimFilter(filterRaw) : undefined,\n startIndex: typeof body.startIndex === 'number' && body.startIndex > 0 ? Math.floor(body.startIndex) : 1,\n count: clamp(typeof body.count === 'number' ? Math.floor(body.count) : maxResults, 0, maxResults),\n sortBy: typeof body.sortBy === 'string' ? body.sortBy : undefined,\n sortOrder: parseSortOrder(typeof body.sortOrder === 'string' ? body.sortOrder : undefined),\n attributes: Array.isArray(body.attributes) ? body.attributes.filter((a): a is string => typeof a === 'string') : undefined,\n excludedAttributes: Array.isArray(body.excludedAttributes)\n ? body.excludedAttributes.filter((a): a is string => typeof a === 'string')\n : undefined,\n };\n};\n\nconst parseSortOrder = (raw: string | undefined): ScimSortOrder | undefined => {\n if (raw === 'ascending' || raw === 'descending') return raw;\n return undefined;\n};\n\n/**\n * Parse the `count` query parameter. RFC 7644 §3.4.2.4 gives a value below 1 its own\n * meaning — return no resources, but still report `totalResults` — which is the probe\n * Okta and Entra make when setting up a connection. A non-numeric or absent value\n * falls back to the configured page size.\n */\nconst parseCount = (raw: string | undefined, fallback: number): number => {\n if (raw === undefined) return fallback;\n const n = Number(raw);\n if (!Number.isFinite(n)) return fallback;\n return n < 1 ? 0 : Math.floor(n);\n};\n\nconst parsePositiveInt = (raw: string | undefined, fallback: number): number => {\n if (raw === undefined) return fallback;\n const n = Number(raw);\n if (!Number.isFinite(n) || n < 1) return fallback;\n return Math.floor(n);\n};\n\nconst clamp = (value: number, min: number, max: number): number => Math.max(min, Math.min(max, value));\n\nconst parseCsvParam = (raw: string | undefined): string[] | undefined => {\n if (!raw) return undefined;\n const parts = raw\n .split(',')\n .map(s => s.trim())\n .filter(Boolean);\n return parts.length > 0 ? parts : undefined;\n};\n\nconst pickStringParam = (query: ServerKitContext['query'], key: string): string | undefined => {\n const value = query[key];\n if (typeof value === 'string') return value;\n if (Array.isArray(value) && typeof value[0] === 'string') return value[0];\n return undefined;\n};\n\nconst validatePatchRequest = (body: Partial<ScimPatchRequest> | unknown): ScimPatchOp[] => {\n if (!isPlainObject(body)) {\n throw scimError(400, 'invalidSyntax', 'Bad Request').withDetails({ message: 'PATCH request must be a JSON object' });\n }\n if (!Array.isArray(body.schemas) || !body.schemas.includes(PatchOpSchema)) {\n throw scimError(400, 'invalidSyntax', 'Bad Request').withDetails({ message: `PATCH request schemas must include \"${PatchOpSchema}\"` });\n }\n if (!Array.isArray(body.Operations) || body.Operations.length === 0) {\n throw scimError(400, 'invalidValue', 'Bad Request').withDetails({ message: '\"Operations\" must be a non-empty array' });\n }\n return body.Operations as ScimPatchOp[];\n};\n\nconst listEnvelope = <T>(resources: T[], query?: ScimListQuery, total?: number): ScimListResponse<T> => ({\n schemas: [ListResponseSchema],\n totalResults: total ?? resources.length,\n startIndex: query?.startIndex ?? 1,\n itemsPerPage: resources.length,\n Resources: resources,\n});\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n};\n"],"mappings":"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","names":["ListResponseSchema","PatchOpSchema","UserSchemaId","userSchema","id","name","description","meta","resourceType","location","attributes","type","multiValued","required","caseExact","mutability","returned","uniqueness","subAttributes","referenceTypes","multiValuedSubAttrs","canonicalValues","kind","GroupSchemaId","groupSchema","id","name","description","meta","resourceType","location","attributes","type","multiValued","required","caseExact","mutability","returned","uniqueness","subAttributes","referenceTypes","canonicalValues","EnterpriseUserSchemaId","enterpriseUserSchema","id","name","description","meta","resourceType","location","attributes","type","multiValued","required","caseExact","mutability","returned","uniqueness","subAttributes","referenceTypes","ResourceTypeSchemaId","userResourceType","schemas","id","name","endpoint","description","schema","UserSchemaId","schemaExtensions","EnterpriseUserSchemaId","required","meta","resourceType","location","groupResourceType","GroupSchemaId","ServiceProviderConfigSchemaId","defaultBearer","type","name","description","specUri","primary","buildServiceProviderConfig","options","schemas","documentationUri","patch","supported","bulk","maxOperations","maxPayloadSize","filter","maxResults","changePassword","sort","etag","authenticationSchemes","meta","resourceType","location","coreSchemas","userSchema","groupSchema","enterpriseUserSchema","HttpError","ScimErrorSchema","ScimError","HttpError","scimType","statusCode","message","toScimBody","detailFromDetails","details","schemas","status","String","detail","IsScimError","error","scimError","COMPARISON_OPS","Set","tokenizeScimFilter","input","tokens","i","length","ch","push","kind","value","start","next","scimError","withDetails","position","message","raw","test","num","Number","isNaN","isIdentifierStart","isIdentifierPart","lower","toLowerCase","has","parseScimFilter","input","trimmed","trim","length","scimError","withDetails","message","tokens","tokenizeScimFilter","parser","Parser","node","parseOr","expectEnd","pos","left","parseAnd","peek","kind","consume","right","operator","parseUnary","token","expect","inner","filter","parseComparisonOrValuePath","error","attribute","String","value","next","valueToken","remaining","position","start","applyScimPatch","resource","ops","next","structuredClone","op","applyOne","kind","normaliseOpKind","path","undefined","scimError","withDetails","message","value","Array","isArray","mergeObject","parsePatchPath","applyAtPath","lower","String","toLowerCase","raw","bracketStart","indexOf","segments","split","filter","Boolean","bracketEnd","findMatchingBracket","head","slice","filterSrc","tail","length","parseScimFilter","filterSubAttr","startsWith","includes","input","openIndex","depth","inString","i","ch","rest","applyFilteredOp","applySimpleOp","child","childObj","isPlainObject","updated","attr","existing","subAttr","collection","matched","forEach","item","index","evaluateFilter","push","_","idx","seed","map","target","source","out","key","val","Object","entries","defineOwn","defineProperty","writable","enumerable","configurable","evaluateComparison","attribute","operator","left","right","nested","some","current","seg","endsWith","compareScalar","a","b","sa","sb","ALWAYS_RETURNED","Set","isPlainObject","value","Array","isArray","splitPath","path","urnBoundary","lastIndexOf","split","slice","PathSet","paths","map","p","s","toLowerCase","empty","length","coversOrLeadsTo","segments","target","some","shared","Math","min","i","isAtOrBelow","every","segment","findDefinition","definitions","name","find","d","projectScimResource","resource","schemas","projection","requested","attributes","excluded","excludedAttributes","mode","core","extensions","extensionsById","Map","schema","id","projectObject","source","prefix","out","key","Object","entries","extension","get","undefined","definition","alwaysReturned","returned","has","subDefinitions","subAttributes","entry","ScimUserRepository","ScimGroupRepository","randomUUID","DateTime","Injectable","Logger","ScimUserService","repository","logger","get","id","user","findById","scimError","undefined","withDetails","message","list","query","create","payload","userName","existing","findByUserName","now","DateTime","utc","toISO","randomUUID","schemas","normaliseSchemas","meta","resourceType","created","lastModified","location","debug","replace","conflict","patch","ops","patched","applyScimPatch","delete","provided","Set","add","UserSchemaId","EnterpriseUserSchemaId","Array","from","randomUUID","DateTime","Injectable","Logger","ScimGroupService","repository","logger","get","id","group","findById","scimError","undefined","withDetails","message","list","query","create","payload","displayName","existing","findByDisplayName","now","DateTime","utc","toISO","randomUUID","schemas","normaliseSchemas","meta","resourceType","created","lastModified","location","debug","replace","conflict","patch","ops","patched","applyScimPatch","delete","provided","Set","add","GroupSchemaId","Array","from","Injectable","ScimServiceProviderService","config","schemas","resourceTypes","options","buildServiceProviderConfig","coreSchemas","userResourceType","groupResourceType","getServiceProviderConfig","listSchemas","getSchema","id","found","find","s","scimError","undefined","withDetails","message","listResourceTypes","getResourceType","rt","SCIM_MEDIA_TYPE","scimContentTypeMiddleware","ctx","next","method","toUpperCase","contentType","request","headers","toLowerCase","includes","scimError","undefined","withDetails","message","body","type","IsHttpError","IsServerkitError","scimErrorMiddleware","ctx","next","status","body","type","SCIM_MEDIA_TYPE","schemas","ScimErrorSchema","String","detail","URL","pathname","error","IsScimError","respondWithScimError","app","emit","IsHttpError","ScimError","statusCode","withDetails","details","withCause","IsServerkitError","message","toScimBody","headers","name","value","Object","entries","set","invalidAuthenticationSession","requireScimScope","scope","ctx","next","session","authenticationSession","invalidAuthenticationSession","scimError","undefined","addHeader","withDetails","message","granted","claims","scimScopes","Array","isArray","includes","bodyParserMiddleware","ServerKitRouter","createScimRouter","options","router","ServerKitRouter","guards","routeGuards","json","bodyParserMiddleware","SCIM_MEDIA_TYPE","maxResults","serviceProviderService","getServiceProviderConfig","filter","baseUrl","replace","withLocation","resource","endpoint","meta","location","id","get","ctx","body","type","listEnvelope","listSchemas","getSchema","params","listResourceTypes","getResourceType","query","parseListQueryFromUrl","result","userService","list","resources","map","user","projectUser","totalResults","post","requestBody","takeRequestBody","parseListQueryFromBody","payload","created","create","status","located","parseProjectionFromUrl","set","put","patch","ops","validatePatchRequest","delete","groupService","group","projectGroup","userSchemas","userSchema","enterpriseUserSchema","projection","projectScimResource","groupSchema","attributes","parseCsvParam","pickStringParam","excludedAttributes","parsedBody","filterRaw","parseScimFilter","undefined","startIndex","parsePositiveInt","count","clamp","parseCount","sortBy","sortOrder","parseSortOrder","isPlainObject","scimError","withDetails","message","Math","floor","Array","isArray","a","raw","fallback","n","Number","isFinite","value","min","max","parts","split","s","trim","Boolean","length","key","schemas","includes","PatchOpSchema","Operations","total","ListResponseSchema","itemsPerPage","Resources"]}
@@ -1 +1 @@
1
- {"version":3,"file":"attribute.projection.d.ts","sourceRoot":"","sources":["../../src/projection/attribute.projection.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAEjF;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,sFAAsF;IACtF,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,4FAA4F;IAC5F,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC/B;AAmED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,mBAAmB,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnE,UAAU,CAAC,EACX,SAAS,UAAU,EAAE,EACrB,aAAY,cAAmB,KAC9B,CASF,CAAC"}
1
+ {"version":3,"file":"attribute.projection.d.ts","sourceRoot":"","sources":["../../src/projection/attribute.projection.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAEjF;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,sFAAsF;IACtF,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,4FAA4F;IAC5F,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC/B;AAkED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,mBAAmB,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,CAAC,EAAE,SAAS,UAAU,EAAE,EAAE,aAAY,cAAmB,KAAG,CAS5I,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"scim.router.d.ts","sourceRoot":"","sources":["../../src/router/scim.router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAEzF,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AACrE,OAAO,EAAE,0BAA0B,EAAE,MAAM,8CAA8C,CAAC;AAc1F;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC,+CAA+C;IAC/C,WAAW,EAAE,eAAe,CAAC;IAC7B,gDAAgD;IAChD,YAAY,EAAE,gBAAgB,CAAC;IAC/B,gFAAgF;IAChF,sBAAsB,EAAE,0BAA0B,CAAC;IACnD,0FAA0F;IAC1F,WAAW,CAAC,EAAE,yBAAyB,EAAE,CAAC;IAC1C;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,gBAAgB,GAAI,SAAS,uBAAuB,KAAG,MAAM,CAAC,OAAO,EAAE,gBAAgB,CA6InG,CAAC"}
1
+ {"version":3,"file":"scim.router.d.ts","sourceRoot":"","sources":["../../src/router/scim.router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAEzF,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AACrE,OAAO,EAAE,0BAA0B,EAAE,MAAM,8CAA8C,CAAC;AAc1F;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC,+CAA+C;IAC/C,WAAW,EAAE,eAAe,CAAC;IAC7B,gDAAgD;IAChD,YAAY,EAAE,gBAAgB,CAAC;IAC/B,gFAAgF;IAChF,sBAAsB,EAAE,0BAA0B,CAAC;IACnD,0FAA0F;IAC1F,WAAW,CAAC,EAAE,yBAAyB,EAAE,CAAC;IAC1C;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,gBAAgB,GAAI,SAAS,uBAAuB,KAAG,MAAM,CAAC,OAAO,EAAE,gBAAgB,CA6JnG,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maroonedsoftware/scim",
3
- "version": "0.3.2",
3
+ "version": "0.3.4",
4
4
  "description": "SCIM 2.0 (RFC 7643/7644) server toolkit for ServerKit — schemas, filter parser, PATCH applier, error envelope, and a Koa router with abstract repositories.",
5
5
  "author": {
6
6
  "name": "Marooned Software",
@@ -36,9 +36,9 @@
36
36
  "dependencies": {
37
37
  "injectkit": "^1.7.1",
38
38
  "luxon": "^3.7.2",
39
- "@maroonedsoftware/authentication": "5.0.0",
39
+ "@maroonedsoftware/authentication": "5.1.0",
40
40
  "@maroonedsoftware/errors": "1.9.1",
41
- "@maroonedsoftware/koa": "3.2.7",
41
+ "@maroonedsoftware/koa": "4.1.0",
42
42
  "@maroonedsoftware/logger": "1.1.9",
43
43
  "@maroonedsoftware/utilities": "1.11.5"
44
44
  },