mirror of
https://github.com/arsvendg/Stirling-PDF.git
synced 2026-07-16 19:33:11 +02:00
Fix V2 SSO user creation (#5079)
# Description of Changes --- ## Checklist ### General - [ ] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [ ] I have read the [Stirling-PDF Developer Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md) (if applicable) - [ ] I have read the [How to add new languages to Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md) (if applicable) - [ ] I have performed a self-review of my own code - [ ] My changes generate no new warnings ### Documentation - [ ] I have updated relevant docs on [Stirling-PDF's doc repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/) (if functionality has heavily changed) - [ ] I have read the section [Add New Translation Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only) ### Translations (if applicable) - [ ] I ran [`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md) ### UI Changes (if applicable) - [ ] Screenshots or videos demonstrating the UI changes are attached (e.g., as comments or direct attachments in the PR) ### Testing (if applicable) - [ ] I have tested my changes locally. Refer to the [Testing Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing) for more details.
This commit is contained in:
+10
@@ -112,6 +112,16 @@ public class ConfigController {
|
|||||||
"showSettingsWhenNoLogin",
|
"showSettingsWhenNoLogin",
|
||||||
applicationProperties.getSystem().isShowSettingsWhenNoLogin());
|
applicationProperties.getSystem().isShowSettingsWhenNoLogin());
|
||||||
|
|
||||||
|
// SSO Provider settings
|
||||||
|
boolean enableOAuth =
|
||||||
|
applicationProperties.getSecurity().getOauth2() != null
|
||||||
|
&& applicationProperties.getSecurity().getOauth2().getEnabled();
|
||||||
|
boolean enableSaml =
|
||||||
|
applicationProperties.getSecurity().getSaml2() != null
|
||||||
|
&& applicationProperties.getSecurity().getSaml2().getEnabled();
|
||||||
|
configData.put("enableOAuth", enableOAuth);
|
||||||
|
configData.put("enableSaml", enableSaml);
|
||||||
|
|
||||||
// Mail settings - check both SMTP enabled AND invites enabled
|
// Mail settings - check both SMTP enabled AND invites enabled
|
||||||
boolean smtpEnabled = applicationProperties.getMail().isEnabled();
|
boolean smtpEnabled = applicationProperties.getMail().isEnabled();
|
||||||
boolean invitesEnabled = applicationProperties.getMail().isEnableInvites();
|
boolean invitesEnabled = applicationProperties.getMail().isEnableInvites();
|
||||||
|
|||||||
@@ -5797,9 +5797,11 @@ username = "Username (Email)"
|
|||||||
usernamePlaceholder = "[email protected]"
|
usernamePlaceholder = "[email protected]"
|
||||||
password = "Password"
|
password = "Password"
|
||||||
passwordPlaceholder = "Enter password"
|
passwordPlaceholder = "Enter password"
|
||||||
|
passwordRequired = "Password is required"
|
||||||
role = "Role"
|
role = "Role"
|
||||||
team = "Team (Optional)"
|
team = "Team (Optional)"
|
||||||
teamPlaceholder = "Select a team"
|
teamPlaceholder = "Select a team"
|
||||||
|
authType = "Authentication Type"
|
||||||
forcePasswordChange = "Force password change on first login"
|
forcePasswordChange = "Force password change on first login"
|
||||||
cancel = "Cancel"
|
cancel = "Cancel"
|
||||||
submit = "Add Member"
|
submit = "Add Member"
|
||||||
@@ -5808,6 +5810,12 @@ passwordTooShort = "Password must be at least 6 characters"
|
|||||||
success = "User created successfully"
|
success = "User created successfully"
|
||||||
error = "Failed to create user"
|
error = "Failed to create user"
|
||||||
|
|
||||||
|
[workspace.people.authType]
|
||||||
|
password = "Password"
|
||||||
|
oauth = "OAuth2"
|
||||||
|
saml = "SAML2"
|
||||||
|
ssoDescription = "User will authenticate via SSO provider"
|
||||||
|
|
||||||
[workspace.people.editMember]
|
[workspace.people.editMember]
|
||||||
title = "Edit Member"
|
title = "Edit Member"
|
||||||
editing = "Editing:"
|
editing = "Editing:"
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ export interface AppConfig {
|
|||||||
enableLogin?: boolean;
|
enableLogin?: boolean;
|
||||||
showSettingsWhenNoLogin?: boolean;
|
showSettingsWhenNoLogin?: boolean;
|
||||||
enableEmailInvites?: boolean;
|
enableEmailInvites?: boolean;
|
||||||
|
enableOAuth?: boolean;
|
||||||
|
enableSaml?: boolean;
|
||||||
isAdmin?: boolean;
|
isAdmin?: boolean;
|
||||||
enableAlphaFunctionality?: boolean;
|
enableAlphaFunctionality?: boolean;
|
||||||
enableAnalytics?: boolean | null;
|
enableAnalytics?: boolean | null;
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ export default function InviteMembersModal({ opened, onClose, onSuccess }: Invit
|
|||||||
password: '',
|
password: '',
|
||||||
role: 'ROLE_USER',
|
role: 'ROLE_USER',
|
||||||
teamId: undefined as number | undefined,
|
teamId: undefined as number | undefined,
|
||||||
|
authType: 'WEB' as 'WEB' | 'OAUTH2' | 'SAML2',
|
||||||
forceChange: false,
|
forceChange: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -120,11 +121,17 @@ export default function InviteMembersModal({ opened, onClose, onSuccess }: Invit
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
const handleInviteUser = async () => {
|
const handleInviteUser = async () => {
|
||||||
if (!inviteForm.username || !inviteForm.password) {
|
if (!inviteForm.username) {
|
||||||
alert({ alertType: 'error', title: t('workspace.people.addMember.usernameRequired') });
|
alert({ alertType: 'error', title: t('workspace.people.addMember.usernameRequired') });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Password is only required for WEB auth type
|
||||||
|
if (inviteForm.authType === 'WEB' && !inviteForm.password) {
|
||||||
|
alert({ alertType: 'error', title: t('workspace.people.addMember.passwordRequired', 'Password is required') });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
setProcessing(true);
|
setProcessing(true);
|
||||||
await userManagementService.createUser({
|
await userManagementService.createUser({
|
||||||
@@ -132,7 +139,7 @@ export default function InviteMembersModal({ opened, onClose, onSuccess }: Invit
|
|||||||
password: inviteForm.password,
|
password: inviteForm.password,
|
||||||
role: inviteForm.role,
|
role: inviteForm.role,
|
||||||
teamId: inviteForm.teamId,
|
teamId: inviteForm.teamId,
|
||||||
authType: 'password',
|
authType: inviteForm.authType,
|
||||||
forceChange: inviteForm.forceChange,
|
forceChange: inviteForm.forceChange,
|
||||||
});
|
});
|
||||||
alert({ alertType: 'success', title: t('workspace.people.addMember.success') });
|
alert({ alertType: 'success', title: t('workspace.people.addMember.success') });
|
||||||
@@ -144,6 +151,7 @@ export default function InviteMembersModal({ opened, onClose, onSuccess }: Invit
|
|||||||
password: '',
|
password: '',
|
||||||
role: 'ROLE_USER',
|
role: 'ROLE_USER',
|
||||||
teamId: undefined,
|
teamId: undefined,
|
||||||
|
authType: 'WEB',
|
||||||
forceChange: false,
|
forceChange: false,
|
||||||
});
|
});
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
@@ -243,6 +251,7 @@ export default function InviteMembersModal({ opened, onClose, onSuccess }: Invit
|
|||||||
password: '',
|
password: '',
|
||||||
role: 'ROLE_USER',
|
role: 'ROLE_USER',
|
||||||
teamId: undefined,
|
teamId: undefined,
|
||||||
|
authType: 'WEB',
|
||||||
forceChange: false,
|
forceChange: false,
|
||||||
});
|
});
|
||||||
setEmailInviteForm({
|
setEmailInviteForm({
|
||||||
@@ -501,6 +510,26 @@ export default function InviteMembersModal({ opened, onClose, onSuccess }: Invit
|
|||||||
onChange={(e) => setInviteForm({ ...inviteForm, username: e.currentTarget.value })}
|
onChange={(e) => setInviteForm({ ...inviteForm, username: e.currentTarget.value })}
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{/* Auth Type Selector - only show if SSO is enabled */}
|
||||||
|
{(config?.enableOAuth || config?.enableSaml) && (
|
||||||
|
<Select
|
||||||
|
label={t('workspace.people.addMember.authType', 'Authentication Type')}
|
||||||
|
data={[
|
||||||
|
{ value: 'WEB', label: t('workspace.people.authType.password', 'Password') },
|
||||||
|
...(config?.enableOAuth ? [{ value: 'OAUTH2', label: t('workspace.people.authType.oauth', 'OAuth2') }] : []),
|
||||||
|
...(config?.enableSaml ? [{ value: 'SAML2', label: t('workspace.people.authType.saml', 'SAML2') }] : []),
|
||||||
|
]}
|
||||||
|
value={inviteForm.authType}
|
||||||
|
onChange={(value) => setInviteForm({ ...inviteForm, authType: (value as 'WEB' | 'OAUTH2' | 'SAML2') || 'WEB' })}
|
||||||
|
comboboxProps={{ withinPortal: true, zIndex: Z_INDEX_OVER_CONFIG_MODAL }}
|
||||||
|
description={inviteForm.authType !== 'WEB' ? t('workspace.people.authType.ssoDescription', 'User will authenticate via SSO provider') : undefined}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Password field - only required for WEB auth type */}
|
||||||
|
{inviteForm.authType === 'WEB' && (
|
||||||
|
<>
|
||||||
<TextInput
|
<TextInput
|
||||||
label={t('workspace.people.addMember.password')}
|
label={t('workspace.people.addMember.password')}
|
||||||
type="password"
|
type="password"
|
||||||
@@ -509,6 +538,14 @@ export default function InviteMembersModal({ opened, onClose, onSuccess }: Invit
|
|||||||
onChange={(e) => setInviteForm({ ...inviteForm, password: e.currentTarget.value })}
|
onChange={(e) => setInviteForm({ ...inviteForm, password: e.currentTarget.value })}
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
|
<Checkbox
|
||||||
|
label={t('workspace.people.addMember.forcePasswordChange', 'Force password change on first login')}
|
||||||
|
checked={inviteForm.forceChange}
|
||||||
|
onChange={(e) => setInviteForm({ ...inviteForm, forceChange: e.currentTarget.checked })}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
<Select
|
<Select
|
||||||
label={t('workspace.people.addMember.role')}
|
label={t('workspace.people.addMember.role')}
|
||||||
data={roleOptions}
|
data={roleOptions}
|
||||||
@@ -525,11 +562,6 @@ export default function InviteMembersModal({ opened, onClose, onSuccess }: Invit
|
|||||||
clearable
|
clearable
|
||||||
comboboxProps={{ withinPortal: true, zIndex: Z_INDEX_OVER_CONFIG_MODAL }}
|
comboboxProps={{ withinPortal: true, zIndex: Z_INDEX_OVER_CONFIG_MODAL }}
|
||||||
/>
|
/>
|
||||||
<Checkbox
|
|
||||||
label={t('workspace.people.addMember.forcePasswordChange', 'Force password change on first login')}
|
|
||||||
checked={inviteForm.forceChange}
|
|
||||||
onChange={(e) => setInviteForm({ ...inviteForm, forceChange: e.currentTarget.checked })}
|
|
||||||
/>
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ export interface CreateUserRequest {
|
|||||||
password?: string;
|
password?: string;
|
||||||
role: string;
|
role: string;
|
||||||
teamId?: number;
|
teamId?: number;
|
||||||
authType: 'password' | 'SSO';
|
authType: 'WEB' | 'OAUTH2' | 'SAML2';
|
||||||
forceChange?: boolean;
|
forceChange?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user