Api: Convert numbered ids to strings before lookups#1520
Open
MrDirkelz wants to merge 102 commits into
Open
Conversation
…zation with support for dynamic group assignments and JWT verification
…gs and condition handling
…ppearance - Removed "always" condition type and defaulted to "authenticated" in AuthProviderGroupMappings.vue - Updated OAuth terminology to "auth provider" in AuthProviderOverview.vue - Enhanced database initialization to check socket connection before revoking access in database.ts - Modified AuthProviderCondition type to remove "always" condition in dto.ts - Added .claudeignore for dependency and build artifacts - Created CLAUDE.md for project overview and development workflow - Introduced dry_run_mappings.json for future mappings - Added AuthProviderAppearance.vue for customizable appearance settings - Created AuthProviderAuthConfig.vue for authentication configuration inputs - Implemented AuthProviderClaimMappings.vue for JWT claim mapping management - Added AuthProviderFormActions.vue for save, delete, and close actions - Created AuthProviderFormErrors.vue for displaying form validation errors - Introduced AuthProviderIconSection.vue for icon upload and opacity settings - Added AuthProviderLabelAndType.vue for provider label input - Implemented AuthProviderUserFieldMappings.vue for user field claim overrides
…ault group management
…cation handling; modify GlobalConfigDto documentation; enhance JWT processing; adjust Socketio user details handling; refine SideBar visibility permissions
…ken function for OAuth handling; update database tests for connection state management; refine applyLocalChangeAck method to handle partial local changes
…er and globalConfig ACL entries; initialize identities array on User documents
…ndex data for Content documents
…balConfig ACL entries for groups; initialize identities array on User documents
…ched identities; enhance user provisioning logic in AuthIdentityService; clear accessMap on revoked documents in database tests
… tests to manage accessMap for document deletion scenarios
…fig to accessMap; refactor error handling in sync functions; update AuthProviderUserFieldMappings to use v-model for provider
…n sync functions; update tests to include AuthProvider and GlobalConfig document types
…e for open state in dialog components; enhance access verification with default empty array for memberOf
…gement - Updated AuthProviderAuthConfig.vue to utilize a model for provider properties instead of individual props. - Simplified event emissions by directly binding model values in AuthProviderFormModal.vue and related components. - Enhanced AuthProviderGroupMappings.vue with inline editing capabilities for conditions and improved UI for group selection. - Adjusted AuthProviderIconSection.vue to directly bind icon opacity to the provider model. - Removed unused claimMappings from AuthProviderDto in dto.ts. - Improved createEditable utility to optimize filtering and modification tracking. - Added useDexieLiveQueryAsEditable utility for enhanced editable state management. - Updated LCombobox.vue to support inline tags for better user experience. - Enhanced modal styling in LModal.vue for improved visual consistency.
…ync service tests.
…te global config to default permissions.
…to optimize the `accessMap` listener in the database.
… test coverage for auth provider components and logic.
…alidation Collapse the duplicated redirect-handled / no-callback branches in setupAuth() for both app and cms: the provider-resolution, header/socket wiring, and token fetch now run in one shared block after handleRedirectCallbackIfPresent(). CMS preserves its reset + open- provider-modal behavior on token failure for the returning-user path; app keeps swallowing token errors since public browsing is a valid unauthenticated state. Pull form-local concerns out of useAuthProviders and into FormModal where they belong: staging JWT config (with a comment explaining the singleton sync-block it protects against), per-field validation, isFormValid, hasAttemptedSubmit, and the staging-vs-singleton dirty diff. FormModal now exposes isDirty and hasAttemptedSubmit via defineModel, and handles duplicate via an imperative prepareForDuplicate hook so in-progress JWT edits carry over to the clone without the staging watcher wiping them. Rework the composable around the slimmer surface: authProviderConfig computed, isProviderEdited helper, isFormDirty ref bound to FormModal's v-model, and saveProvider now takes the stagingConfig as an argument instead of reading it from its own state. The showModal close-cleanup watcher uses flush: 'sync' so the route guard and the composable spec harness observe the reset synchronously. AuthProviderOverview's destructure drops from 38 to 28 bindings and wires the new FormModal API, including a formModalRef for the duplicate handoff. Tighten auth provider credential validation so the save button and error messages reject obvious garbage: domain must be a plain RFC 1123 hostname (no scheme, path, port, or whitespace); client ID must be at least 8 characters with no whitespace; audience must parse as an absolute http(s) URL. Rules are intentionally provider-agnostic rather than Auth0-only since the auth layer is slated to accept other OIDC providers. Update useAuthProviders.spec.ts to match: isDirty-tracking and isFormValid describe blocks removed (those now belong to a FormModal component spec), new isDirtyAny-route-guard and isProviderEdited coverage, saveProvider tests pass an explicit stagingConfig, and a new test verifies that a non-empty stagingConfig is committed into the singleton on save.
…n set Rename `groupId: string` to `groupIds: string[]` on AuthProviderGroupMapping so one condition set can grant membership in multiple local groups at once, instead of forcing users to duplicate the same conditions across N mappings. The CMS UI was already driving a multi-select LCombobox and storing its per-row selection as `string[][]` — this refactor makes the underlying data shape match what the UI already supported. DTO and shared type: rename the field on both copies (api/src/dto/AuthProviderConfigDto.ts + shared/src/types/dto.ts) and swap class-validator from @IsString+@isnotempty to @isarray+@ArrayNotEmpty+ @IsString({each:true}), preserving the "must assign at least one group" guarantee the scalar used to provide. API runtime: evaluateGroupAssignments reads mapping.groupIds, falling back to legacy `groupId` when absent so existing singleton docs in the wild keep resolving correctly until they're rewritten. On match, every entry in groupIds is added to assignedGroups. Left a TODO(post-migration) marking the fallback for deletion once all deployments have saved at least once post-release. Write-path normalizer: processAuthProviderConfigDto now walks doc.providers[*].groupMappings[*] and coerces `{ groupId }` to `{ groupIds: [groupId] }`, deleting the legacy key. Any write from an old client (pre-refactor CMS, pre-refactor add-auth-provider.ts, or a direct API call) gets transparently migrated on its first save, which lets the DTO validator require `groupIds` unconditionally. CMS GroupMappings.vue: load staging as `m.groupIds ?? legacy-fallback`, write back via renamed updateMappingGroupIds with shallow-equal echo guard, update the search filter to match any assigned group, and rework the helper copy / combobox placeholders to use plural phrasing. FormModal rejects save when any mapping has zero groups assigned so the Save button stays honest instead of bouncing off server validation. add-auth-provider.ts: interactive prompt now accepts comma-separated group IDs per rule, the AUTO_GROUP_MAPPINGS shape is migrated, and the auto-vs-extra merge keys on a sorted-joined groupIds signature so a user-supplied mapping targeting the exact same group set overrides the auto default. Different group sets stay as distinct rules. Tests: authIdentity.service.spec.ts updates 6 fixtures and adds coverage for multi-group assignment, cross-mapping de-duplication, the legacy `groupId` fallback path, and empty-groupIds skipping. processAuthProviderConfigDto.spec.ts adds 5 cases for the normalizer (legacy→new, both keys present, neither key, missing providers, missing groupMappings). GroupMappings.spec.ts updates fixtures and adds tests for LCombobox-driven multi-select and legacy-shape render.
DefaultPermissionsDto redeclared memberOf locally while extending _baseDto, duplicating the single field _contentBaseDto exists to provide. Switch the API class and the shared-type mirror to extend the content base so memberOf is inherited, keeping the DTO in line with every other content-bearing document.
- api main.spec: mock useGlobalFilters on the Nest app stub - app ProfileMenu/TopBar specs: toggle isAuthPluginInstalled so useAuthWithPrivacyPolicy returns the mocked auth0 instead of the unauthenticated fallback - cms ProfileMenu/SideBar/waitUntilAuth0IsLoaded specs: add isAuthPluginInstalled to the @/auth vi.mock so imports resolve
setupAuth ran before app.use(router), so router.replace() to strip the Auth0 callback query params threw "Cannot read properties of undefined (reading '_s')" from vue-router internals. Drop the router dependency from setupAuth and use history.replaceState for the URL cleanup instead.
The global-groups button never appeared because DefaultPermissions is not mirrored into Dexie (by design — see sync.ts), yet useAuthProviders was reading it via a Dexie live query and always got undefined. Switch to ApiLiveQueryAsEditable, mirroring the AuthProviderConfig pattern, and persist saves through the query instead of db.upsert.
…cs, and saveDefaultGroups is verified against the captured change request instead of Dexie.
llowedHeaders might have to be made configurable. The shared client library supports injection of custom headers (use for x-auth-provider-id and the Authorization header), and could potentially be used for other custom headers as well.
…ough the change feed, the handler now evicts the deleted provider from providerCache and its JWKS client from jwksClients. Also evicts any auto-group-mapping cache for the deleted doc ID. This means deleting a provider immediately cuts off access — no server restart needed. Fix 2 — Generic error messages: resolveOrDefault now always throws "Invalid authentication token" to the client, regardless of the underlying failure (expired, wrong signature, wrong audience, etc.). The real error is logged at warn level with the providerId for debugging. Attackers can no longer distinguish between clock issues, key mismatches, or audience misconfigurations from the HTTP response.
Co-authored-by: Ivan Slabbert <ivanslabbert@users.noreply.github.com>
…fix duplicate button - After JWT verification, check that the token's `azp`/`client_id` claim matches the provider's configured clientId. Prevents tokens issued for one client from being accepted under a different provider's context. - Fix duplicate button in AutoGroupMappingModal: remove snapshot reset after duplicate so isDirty stays true and save is enabled. - Update evaluateGroupAssignments tests to use AND logic (`.every`) matching the updated implementation.
Optional name and summary fields on AutoGroupMappingsDto let admins label and describe each mapping. The display card shows the name as the title (falling back to the condition summary) with the summary as a subtitle. Both fields are included in the overview search filter.
Provider-less AutoGroupMappings documents (no providerId) now serve as global default groups for all users, replacing the DefaultPermissions singleton. The DefaultPermissions DTO, processor, enum value, and all references are removed. - providerId is now optional on AutoGroupMappingsDto - authIdentity.service derives default groups by querying AutoGroupMappings with no providerId instead of querying DefaultPermissions - CMS modal derives global mode from empty providerId (no special prop) - Display card shows globe icon for provider-less mappings - Collapsed name/summary into a single description field - Setup script option 3 creates AutoGroupMappings instead of DefaultPermissions
- Add "Global (All Users)" option to the provider filter dropdown - Use warning color scheme on display card badges for global mappings - Add gap between filter bar and first card - Update global mapping message to guide users to select a provider - Fix shrinking icon in LBadge with shrink-0 - Re-add lastChangeRequest variable in useAuthProviders spec - Rename GroupMappings spec to AutoGroupMappingConditions spec - Fix AuthProviderSelectionModal spec for updated empty state text
- Add no-divider prop to auth provider FormModal to remove the divider line between content and action buttons - Remove border-t from FormActions component
- Remove DefaultPermissions references from app/src/sync.spec.ts - Add tests for multiple global and provider-specific group mappings merging and deduplication in authIdentity.service.spec.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.