mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2025-12-18 20:04:17 +01:00
sso
This commit is contained in:
parent
058a81d554
commit
b4471edff1
@ -83,6 +83,16 @@ public class ConfigController {
|
||||
applicationProperties.getSecurity().getEnableLogin() && userService != null;
|
||||
configData.put("enableLogin", enableLogin);
|
||||
|
||||
// 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
|
||||
boolean smtpEnabled = applicationProperties.getMail().isEnabled();
|
||||
boolean invitesEnabled = applicationProperties.getMail().isEnableInvites();
|
||||
|
||||
@ -386,9 +386,22 @@ public class UserController {
|
||||
}
|
||||
}
|
||||
|
||||
if (authType.equalsIgnoreCase(AuthenticationType.SSO.toString())) {
|
||||
userService.saveUser(username, AuthenticationType.SSO, effectiveTeamId, role);
|
||||
// Parse authentication type
|
||||
AuthenticationType authenticationType;
|
||||
try {
|
||||
authenticationType = AuthenticationType.valueOf(authType.toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
|
||||
.body(Map.of("error", "Invalid authentication type specified."));
|
||||
}
|
||||
|
||||
// For SSO types (SSO, OAUTH2, SAML2), password is not required
|
||||
if (authenticationType == AuthenticationType.SSO
|
||||
|| authenticationType == AuthenticationType.OAUTH2
|
||||
|| authenticationType == AuthenticationType.SAML2) {
|
||||
userService.saveUser(username, authenticationType, effectiveTeamId, role);
|
||||
} else {
|
||||
// For WEB auth type, password is required
|
||||
if (password == null || password.isBlank()) {
|
||||
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
|
||||
.body(Map.of("error", "Password is required."));
|
||||
|
||||
@ -5223,9 +5223,11 @@ username = "Username (Email)"
|
||||
usernamePlaceholder = "user@example.com"
|
||||
password = "Password"
|
||||
passwordPlaceholder = "Enter password"
|
||||
passwordRequired = "Password is required"
|
||||
role = "Role"
|
||||
team = "Team (Optional)"
|
||||
teamPlaceholder = "Select a team"
|
||||
authType = "Authentication Type"
|
||||
forcePasswordChange = "Force password change on first login"
|
||||
cancel = "Cancel"
|
||||
submit = "Add Member"
|
||||
@ -5234,6 +5236,12 @@ passwordTooShort = "Password must be at least 6 characters"
|
||||
success = "User created successfully"
|
||||
error = "Failed to create user"
|
||||
|
||||
[workspace.people.authType]
|
||||
password = "Password"
|
||||
oauth = "OAuth2"
|
||||
saml = "SAML2"
|
||||
ssoDescription = "User will authenticate via SSO provider"
|
||||
|
||||
[workspace.people.editMember]
|
||||
title = "Edit Member"
|
||||
editing = "Editing:"
|
||||
|
||||
@ -23,6 +23,8 @@ export interface AppConfig {
|
||||
logoStyle?: 'modern' | 'classic';
|
||||
enableLogin?: boolean;
|
||||
enableEmailInvites?: boolean;
|
||||
enableOAuth?: boolean;
|
||||
enableSaml?: boolean;
|
||||
isAdmin?: boolean;
|
||||
enableAlphaFunctionality?: boolean;
|
||||
enableAnalytics?: boolean | null;
|
||||
|
||||
@ -55,6 +55,7 @@ export default function InviteMembersModal({ opened, onClose }: InviteMembersMod
|
||||
password: '',
|
||||
role: 'ROLE_USER',
|
||||
teamId: undefined as number | undefined,
|
||||
authType: 'WEB' as 'WEB' | 'OAUTH2' | 'SAML2',
|
||||
forceChange: false,
|
||||
});
|
||||
|
||||
@ -119,11 +120,17 @@ export default function InviteMembersModal({ opened, onClose }: InviteMembersMod
|
||||
}));
|
||||
|
||||
const handleInviteUser = async () => {
|
||||
if (!inviteForm.username || !inviteForm.password) {
|
||||
if (!inviteForm.username) {
|
||||
alert({ alertType: 'error', title: t('workspace.people.addMember.usernameRequired') });
|
||||
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 {
|
||||
setProcessing(true);
|
||||
await userManagementService.createUser({
|
||||
@ -131,7 +138,7 @@ export default function InviteMembersModal({ opened, onClose }: InviteMembersMod
|
||||
password: inviteForm.password,
|
||||
role: inviteForm.role,
|
||||
teamId: inviteForm.teamId,
|
||||
authType: 'password',
|
||||
authType: inviteForm.authType.toLowerCase(),
|
||||
forceChange: inviteForm.forceChange,
|
||||
});
|
||||
alert({ alertType: 'success', title: t('workspace.people.addMember.success') });
|
||||
@ -142,6 +149,7 @@ export default function InviteMembersModal({ opened, onClose }: InviteMembersMod
|
||||
password: '',
|
||||
role: 'ROLE_USER',
|
||||
teamId: undefined,
|
||||
authType: 'WEB',
|
||||
forceChange: false,
|
||||
});
|
||||
} catch (error: any) {
|
||||
@ -228,6 +236,7 @@ export default function InviteMembersModal({ opened, onClose }: InviteMembersMod
|
||||
password: '',
|
||||
role: 'ROLE_USER',
|
||||
teamId: undefined,
|
||||
authType: 'WEB',
|
||||
forceChange: false,
|
||||
});
|
||||
setEmailInviteForm({
|
||||
@ -486,14 +495,42 @@ export default function InviteMembersModal({ opened, onClose }: InviteMembersMod
|
||||
onChange={(e) => setInviteForm({ ...inviteForm, username: e.currentTarget.value })}
|
||||
required
|
||||
/>
|
||||
<TextInput
|
||||
label={t('workspace.people.addMember.password')}
|
||||
type="password"
|
||||
placeholder={t('workspace.people.addMember.passwordPlaceholder')}
|
||||
value={inviteForm.password}
|
||||
onChange={(e) => setInviteForm({ ...inviteForm, password: e.currentTarget.value })}
|
||||
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
|
||||
label={t('workspace.people.addMember.password')}
|
||||
type="password"
|
||||
placeholder={t('workspace.people.addMember.passwordPlaceholder')}
|
||||
value={inviteForm.password}
|
||||
onChange={(e) => setInviteForm({ ...inviteForm, password: e.currentTarget.value })}
|
||||
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
|
||||
label={t('workspace.people.addMember.role')}
|
||||
data={roleOptions}
|
||||
@ -510,11 +547,6 @@ export default function InviteMembersModal({ opened, onClose }: InviteMembersMod
|
||||
clearable
|
||||
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 })}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user