diff --git a/changelogs/fragments/10908.yml b/changelogs/fragments/10908.yml
new file mode 100644
index 000000000000..fdc653eb284b
--- /dev/null
+++ b/changelogs/fragments/10908.yml
@@ -0,0 +1,2 @@
+fix:
+- Trim collaboratorId when adding collaborators for workspace ([#10908](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/10908))
diff --git a/src/plugins/workspace/public/components/workspace_form/add_collaborator_button.test.tsx b/src/plugins/workspace/public/components/workspace_form/add_collaborator_button.test.tsx
index 82d4bae43c66..417dda986761 100644
--- a/src/plugins/workspace/public/components/workspace_form/add_collaborator_button.test.tsx
+++ b/src/plugins/workspace/public/components/workspace_form/add_collaborator_button.test.tsx
@@ -108,6 +108,45 @@ describe('AddCollaboratorButton', () => {
]);
});
+ it('should trim collaborator IDs when adding collaborators', () => {
+ const mockOnAdd = jest.fn().mockImplementation(({ onAddCollaborators }) => {
+ onAddCollaborators([
+ {
+ accessLevel: 'readOnly',
+ collaboratorId: ' user-with-spaces ',
+ permissionType: 'user',
+ },
+ {
+ accessLevel: 'admin',
+ collaboratorId: '\tgroup-with-tabs\t',
+ permissionType: 'group',
+ },
+ ]);
+ });
+ const displayedTypes = [
+ {
+ name: 'add user',
+ buttonLabel: 'add user',
+ onAdd: mockOnAdd,
+ id: 'user',
+ },
+ ];
+ const { getByTestId, getByText } = render(
+
+ );
+ const button = getByTestId('add-collaborator-button');
+ fireEvent.click(button);
+ const addUserButton = getByText('add user');
+ fireEvent.click(addUserButton);
+
+ expect(mockProps.handleSubmitPermissionSettings).toHaveBeenCalledWith([
+ { id: 0, modes: ['library_write', 'write'], type: 'user', userId: 'admin' },
+ { group: 'group', id: 1, modes: ['library_read', 'read'], type: 'group' },
+ { id: 2, modes: ['library_read', 'read'], type: 'user', userId: 'user-with-spaces' },
+ { id: 3, modes: ['library_write', 'write'], type: 'group', group: 'group-with-tabs' },
+ ]);
+ });
+
it('should throw DuplicateCollaboratorError with consistent details', async () => {
let errorCached: DuplicateCollaboratorError | undefined;
const mockOnAdd = jest.fn(async ({ onAddCollaborators }) => {
diff --git a/src/plugins/workspace/public/components/workspace_form/add_collaborator_button.tsx b/src/plugins/workspace/public/components/workspace_form/add_collaborator_button.tsx
index ab4dab59af9f..59ff833cb834 100644
--- a/src/plugins/workspace/public/components/workspace_form/add_collaborator_button.tsx
+++ b/src/plugins/workspace/public/components/workspace_form/add_collaborator_button.tsx
@@ -56,19 +56,23 @@ export const AddCollaboratorButton = ({
const onAddCollaborators = async (collaborators: WorkspaceCollaborator[]) => {
const uniqueCollaboratorIds = new Set();
- const addedSettings = collaborators.map(({ permissionType, accessLevel, collaboratorId }) => ({
- type: permissionType,
- modes: accessLevelNameToWorkspacePermissionModesMap[accessLevel],
- id: nextIdGenerator(),
- ...(permissionType === WorkspacePermissionItemType.User
- ? {
- userId: collaboratorId,
- }
- : {
- group: collaboratorId,
- }),
- collaboratorId,
- })) as Array;
+ const addedSettings = collaborators.map(({ permissionType, accessLevel, collaboratorId }) => {
+ const trimmedId = collaboratorId.trim();
+ return {
+ type: permissionType,
+ modes: accessLevelNameToWorkspacePermissionModesMap[accessLevel],
+ id: nextIdGenerator(),
+ ...(permissionType === WorkspacePermissionItemType.User
+ ? {
+ userId: trimmedId,
+ }
+ : {
+ group: trimmedId,
+ }),
+ collaboratorId: trimmedId,
+ };
+ }) as Array;
+
const existingDuplicateSettings = addedSettings.filter((permissionSettingToAdd) =>
hasSameUserIdOrGroup(permissionSettings, permissionSettingToAdd)
);