@@ -21,6 +21,9 @@ import Tabs from 'components/base/forms/Tabs'
21
21
import TabItem from 'components/base/forms/TabItem'
22
22
import { AttributeName } from 'common/types/responses'
23
23
import SAMLAttributeMappingTable from 'components/SAMLAttributeMappingTable'
24
+ import Input from 'components/base/forms/Input'
25
+ import Icon from 'components/Icon'
26
+ import Project from 'common/project'
24
27
25
28
type CreateSAML = {
26
29
organisationId : number
@@ -52,6 +55,12 @@ const CreateSAML: FC<CreateSAML> = ({ organisationId, samlName }) => {
52
55
{ skip : ! samlName } ,
53
56
)
54
57
58
+ const acsUrl = new URL ( `/auth/saml/${ name } /response/` , Project . api ) . href
59
+ const copyAcsUrl = async ( ) => {
60
+ await navigator . clipboard . writeText ( acsUrl )
61
+ toast ( 'Copied to clipboard' )
62
+ }
63
+
55
64
useEffect ( ( ) => {
56
65
if ( isSuccess && data ) {
57
66
setPreviousName ( data . name )
@@ -101,9 +110,10 @@ const CreateSAML: FC<CreateSAML> = ({ organisationId, samlName }) => {
101
110
className = 'mt-2'
102
111
title = 'Name*'
103
112
data-test = 'saml-name'
104
- tooltip = 'A short name for the organization , used as the input when clicking "Single Sign-on " at login, should only consist of alphanumeric characters, plus (+), underscore (_), and hyphen (-) .'
113
+ tooltip = 'An URL-friendly name for this configuration , used as the input when selecting "Single Sign-On " at login. It determines the Assertion Consumer Service (ACS) URL that your identity provider must post SAML responses to. This cannot be changed after the SAML configuration is created .'
105
114
tooltipPlace = 'right'
106
115
value = { name }
116
+ disabled = { isEdit }
107
117
onChange = { ( event : React . ChangeEvent < HTMLInputElement > ) => {
108
118
const newName = Utils . safeParseEventValue ( event ) . replace ( / / g, '_' )
109
119
if ( validateName ( newName ) ) {
@@ -121,7 +131,7 @@ const CreateSAML: FC<CreateSAML> = ({ organisationId, samlName }) => {
121
131
className = 'mt-2 mb-4'
122
132
title = 'Frontend URL*'
123
133
data-test = 'frontend-url'
124
- tooltip = 'The base URL of the Flagsmith dashboard'
134
+ tooltip = 'The base URL of the Flagsmith dashboard. Users will be redirected here after authenticating successfully. '
125
135
tooltipPlace = 'right'
126
136
value = { data ?. frontend_url || frontendUrl }
127
137
onChange = { ( event : React . ChangeEvent < HTMLInputElement > ) => {
@@ -136,8 +146,8 @@ const CreateSAML: FC<CreateSAML> = ({ organisationId, samlName }) => {
136
146
/>
137
147
< InputGroup
138
148
className = 'mt-2 mb-4'
139
- title = 'Allow IDP initiated'
140
- tooltip = 'Determines whether logins can be initiated from the IDP'
149
+ title = 'Allow IdP- initiated logins '
150
+ tooltip = "Enable this to allow logins initiated by your identity provider. If disabled, users can only log in from Flagsmith's login page."
141
151
tooltipPlace = 'right'
142
152
component = {
143
153
< Switch
@@ -151,7 +161,7 @@ const CreateSAML: FC<CreateSAML> = ({ organisationId, samlName }) => {
151
161
< FormGroup className = 'mb-1' >
152
162
< div className = 'mt-2 p-0' >
153
163
< Row >
154
- < label className = 'form-label' > IDP Metadata XML</ label >
164
+ < label className = 'form-label' > IdP metadata XML</ label >
155
165
{ data ?. idp_metadata_xml && (
156
166
< div className = 'ml-2 clickable' onClick = { downloadIDPMetadata } >
157
167
< Tooltip
@@ -203,6 +213,35 @@ const CreateSAML: FC<CreateSAML> = ({ organisationId, samlName }) => {
203
213
< ErrorMessage error = { createError || updateError } />
204
214
</ div >
205
215
) }
216
+ { isEdit && (
217
+ < div className = 'mt-12' >
218
+ < Tooltip
219
+ title = {
220
+ < label >
221
+ Assertion Consumer Service (ACS) URL
222
+ < Icon name = 'info-outlined' />
223
+ </ label >
224
+ }
225
+ >
226
+ Also known as sign-on URL. Your identity provider needs to know this
227
+ URL to send SAML responses to it.
228
+ </ Tooltip >
229
+ < div
230
+ onClick = { ( e ) => e . stopPropagation ( ) }
231
+ className = 'flex flex-row gap-2'
232
+ >
233
+ < Input className = 'w-full flex-1' value = { acsUrl } readOnly />
234
+ < Button
235
+ onClick = { ( ) => {
236
+ copyAcsUrl ( )
237
+ } }
238
+ className = 'me-2 btn-with-icon'
239
+ >
240
+ < Icon name = 'copy' width = { 20 } fill = '#656D7B' />
241
+ </ Button >
242
+ </ div >
243
+ </ div >
244
+ ) }
206
245
< div className = 'text-right py-2' >
207
246
{ isEdit && (
208
247
< Button
@@ -273,13 +312,11 @@ const CreateSAML: FC<CreateSAML> = ({ organisationId, samlName }) => {
273
312
return (
274
313
< div className = 'create-feature-tab mt-3' >
275
314
< InputGroup
276
- title = { 'SAML Attribute Name*' }
277
- tooltip = 'This is the attribute name where you want to store the information received from the SAML identity provider'
278
- tooltipPlace = 'right'
315
+ title = { 'Flagsmith user attribute' }
279
316
component = {
280
317
< Select
281
318
value = { djangoAttributeName }
282
- placeholder = 'Select a SAML attribute name '
319
+ placeholder = 'Select a Flagsmith user attribute '
283
320
options = { samlAttributes }
284
321
onChange = { ( m : samlAttributeType ) => {
285
322
setDjangoAttributeName ( m )
@@ -290,9 +327,9 @@ const CreateSAML: FC<CreateSAML> = ({ organisationId, samlName }) => {
290
327
/>
291
328
< InputGroup
292
329
className = 'mt-2'
293
- title = 'IDP Attribute Name *'
330
+ title = 'IdP attribute name *'
294
331
data-test = 'attribute-name'
295
- tooltip = 'This is the specific value of the attribute sent by the SAML identity provider '
332
+ tooltip = 'The value(s) of this SAML attribute from your identity provider will be saved to the selected Flagsmith user attribute. '
296
333
tooltipPlace = 'right'
297
334
value = { ipdAttributeName }
298
335
onChange = { ( event : React . ChangeEvent < HTMLInputElement > ) => {
0 commit comments