@connectid-tools/idp-selector-react 6.7.0 → 6.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Popup.css +21 -50
- package/Popup.js +8 -16
- package/README.md +3 -0
- package/certification.d.ts +1 -1
- package/certification.js +16 -15
- package/certification.test.js +88 -77
- package/package.json +3 -3
package/Popup.css
CHANGED
|
@@ -153,7 +153,8 @@
|
|
|
153
153
|
flex-shrink: 0;
|
|
154
154
|
}
|
|
155
155
|
.cid-idp-selector-popup-participants {
|
|
156
|
-
|
|
156
|
+
list-style: none;
|
|
157
|
+
margin: 24px 0 16px 0;
|
|
157
158
|
display: grid;
|
|
158
159
|
grid-template-columns: 225px 225px;
|
|
159
160
|
grid-gap: 16px;
|
|
@@ -173,33 +174,11 @@
|
|
|
173
174
|
padding: 8px 16px;
|
|
174
175
|
border: 1px solid #E9E9E9;
|
|
175
176
|
}
|
|
176
|
-
.cid-idp-selector-popup-participant-greyed-out {
|
|
177
|
-
display: flex;
|
|
178
|
-
align-items: center;
|
|
179
|
-
border-radius: 12px;
|
|
180
|
-
cursor: pointer;
|
|
181
|
-
box-sizing: border-box;
|
|
182
|
-
padding: 8px 16px;
|
|
183
|
-
border: 1px solid #E9E9E9;
|
|
184
|
-
background-color: #F4F4F4;
|
|
185
|
-
cursor: default;
|
|
186
|
-
margin-bottom: 4px;
|
|
187
|
-
}
|
|
188
|
-
.cid-idp-selector-popup-participant-greyed-out-text {
|
|
189
|
-
color: #5C5C5C;
|
|
190
|
-
font-size: 10px;
|
|
191
|
-
}
|
|
192
177
|
.cid-idp-selector-popup-participant-icon {
|
|
193
178
|
width: 32px;
|
|
194
179
|
height: 32px;
|
|
195
180
|
border-radius: 8px;
|
|
196
181
|
}
|
|
197
|
-
.cid-idp-selector-popup-participant-icon-greyed-out {
|
|
198
|
-
width: 32px;
|
|
199
|
-
height: 32px;
|
|
200
|
-
border-radius: 8px;
|
|
201
|
-
opacity: 60%
|
|
202
|
-
}
|
|
203
182
|
.cid-idp-selector-popup-participant-description {
|
|
204
183
|
position: absolute;
|
|
205
184
|
width: 1px;
|
|
@@ -224,16 +203,26 @@
|
|
|
224
203
|
text-overflow: ellipsis;
|
|
225
204
|
width: 90%;
|
|
226
205
|
}
|
|
227
|
-
.cid-idp-selector-popup-
|
|
228
|
-
|
|
206
|
+
.cid-idp-selector-popup-missing {
|
|
207
|
+
border-radius: 12px;
|
|
208
|
+
background: #F4F4F4;
|
|
209
|
+
padding: 18px;
|
|
210
|
+
}
|
|
211
|
+
.cid-idp-selector-popup-missing-title {
|
|
212
|
+
color: var(--charcoal);
|
|
229
213
|
font-family: var(--font);
|
|
214
|
+
font-size: 12px;
|
|
215
|
+
font-weight: 600;
|
|
216
|
+
line-height: 120%;
|
|
217
|
+
margin: 0;
|
|
218
|
+
}
|
|
219
|
+
.cid-idp-selector-popup-missing-text {
|
|
230
220
|
color: var(--charcoal75);
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
221
|
+
font-family: var(--font);
|
|
222
|
+
font-size: 12px;
|
|
223
|
+
font-weight: 400;
|
|
224
|
+
line-height: 120%;
|
|
225
|
+
margin: 8px 0 0 0;
|
|
237
226
|
}
|
|
238
227
|
.cid-idp-selector-popup-manual {
|
|
239
228
|
font-family: var(--font);
|
|
@@ -294,18 +283,6 @@
|
|
|
294
283
|
max-width: 466px;
|
|
295
284
|
}
|
|
296
285
|
|
|
297
|
-
.cid-greyout-participant-name {
|
|
298
|
-
position: absolute;
|
|
299
|
-
display: inline-flex;
|
|
300
|
-
flex-direction: row;
|
|
301
|
-
align-items: center;
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
.cid-idp-selector-button-info-icon-greyed-out {
|
|
305
|
-
margin-right: 2px;
|
|
306
|
-
flex-shrink: 0;
|
|
307
|
-
}
|
|
308
|
-
|
|
309
286
|
@media (prefers-reduced-motion: reduce) {
|
|
310
287
|
.cid-idp-selector-popup-logo-dot {
|
|
311
288
|
animation: none;
|
|
@@ -324,6 +301,7 @@
|
|
|
324
301
|
margin: 20px 0;
|
|
325
302
|
}
|
|
326
303
|
.cid-idp-selector-popup-participants {
|
|
304
|
+
margin: 16px 0 12px 0;
|
|
327
305
|
grid-template-columns: 190px 190px;
|
|
328
306
|
}
|
|
329
307
|
}
|
|
@@ -358,13 +336,9 @@
|
|
|
358
336
|
margin: 20px auto 0 auto;
|
|
359
337
|
}
|
|
360
338
|
.cid-idp-selector-popup-participants {
|
|
361
|
-
margin-top: 12px;
|
|
362
339
|
grid-template-columns: 1fr;
|
|
363
340
|
max-height: 550px;
|
|
364
341
|
}
|
|
365
|
-
.cid-idp-selector-popup-participant-greyed-out {
|
|
366
|
-
margin-bottom: 8px;
|
|
367
|
-
}
|
|
368
342
|
.cid-idp-selector-popup-participant-name {
|
|
369
343
|
overflow: inherit;
|
|
370
344
|
white-space: normal;
|
|
@@ -372,9 +346,6 @@
|
|
|
372
346
|
width: 100%;
|
|
373
347
|
font-size: 16px;
|
|
374
348
|
}
|
|
375
|
-
.cid-greyout-participant-name {
|
|
376
|
-
margin-top: -6px;
|
|
377
|
-
}
|
|
378
349
|
.cid-idp-selector-popup-close {
|
|
379
350
|
position: absolute;
|
|
380
351
|
padding: 8px;
|
package/Popup.js
CHANGED
|
@@ -12,7 +12,7 @@ import { useEffect, useRef, useState } from 'react';
|
|
|
12
12
|
import ReactDOM from 'react-dom';
|
|
13
13
|
import { useMediaQuery } from 'react-responsive';
|
|
14
14
|
import { useAnalytics } from './analytics';
|
|
15
|
-
import { filterAuthorisationServers, getManualAuthorisationServer
|
|
15
|
+
import { filterAuthorisationServers, getManualAuthorisationServer } from './certification';
|
|
16
16
|
import './global.css';
|
|
17
17
|
import { InfoBox } from './InfoBox';
|
|
18
18
|
import { getCurrentUrlOrigin } from './navigator';
|
|
@@ -20,7 +20,6 @@ import { NoIdpError } from './NoIdpError';
|
|
|
20
20
|
import { ParticipantsLoader } from './ParticipantsLoader';
|
|
21
21
|
import './Popup.css';
|
|
22
22
|
import { useOverrideShiftTab, useOverrideTab } from './TabHook';
|
|
23
|
-
import { getDeviceType } from './userAgent';
|
|
24
23
|
import detectIncognito from './incognito';
|
|
25
24
|
export const Popup = ({ onProceed, onCancel, onError, claims, requiredClaims, showAllParticipants, certificationStatus, popupTitle, rpDataSharingDescription, enableManualVerification, requiredCertifications, rpLogoUrl, participants, error, isLoading, }) => {
|
|
26
25
|
const [isIncognito, setIsIncognito] = useState();
|
|
@@ -123,14 +122,6 @@ export const Popup = ({ onProceed, onCancel, onError, claims, requiredClaims, sh
|
|
|
123
122
|
}
|
|
124
123
|
return (_jsxs(_Fragment, { children: [_jsx("div", { className: "cid-idp-selector-popup-title-container", children: renderClaimsTitle() }), renderClaimList()] }));
|
|
125
124
|
};
|
|
126
|
-
const participantTile = (AuthorisationServerId, CustomerFriendlyName, CustomerFriendlyLogoUri, deviceType) => {
|
|
127
|
-
if (deviceType === 'desktop') {
|
|
128
|
-
return (_jsxs("div", { children: [_jsx("span", { id: `participant-greyed-out-description-${CustomerFriendlyName}`, className: "cid-idp-selector-popup-participant-description", "aria-hidden": "true", children: "available on mobile only" }), _jsxs("li", { "data-testid": "participant-greyed-out", className: "cid-idp-selector-popup-participant-greyed-out", "aria-disabled": "true", "aria-describedby": `participant-greyed-out-description-${CustomerFriendlyName}`, tabIndex: 0, children: [_jsx("img", { className: "cid-idp-selector-popup-participant-icon-greyed-out", src: CustomerFriendlyLogoUri, alt: `${CustomerFriendlyName} logo` }), _jsx("div", { className: "cid-idp-selector-popup-participant-name-greyed-out", title: CustomerFriendlyName, "data-testid": "participant-name", children: CustomerFriendlyName })] }, AuthorisationServerId), _jsxs("div", { className: "cid-greyout-participant-name", children: [_jsxs("svg", { className: "cid-idp-selector-button-info-icon-greyed-out", width: "8", height: "8", viewBox: "0 0 13 13", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [_jsx("path", { d: "M6.53509 12.3572C9.59207 12.3572 12.0702 9.81483 12.0702 6.67859C12.0702 3.54239 9.59207 1 6.53509 1C3.47814 1 1 3.54239 1 6.67859C1 9.81483 3.47814 12.3572 6.53509 12.3572Z", stroke: "#262626", strokeLinecap: "round", strokeLinejoin: "round" }), _jsx("path", { d: "M5.25781 9.29883H7.81247", stroke: "#262626", strokeLinecap: "round", strokeLinejoin: "round" }), _jsx("path", { d: "M6.53515 4.49472C6.7703 4.49472 6.96093 4.29915 6.96093 4.05791C6.96093 3.81666 6.7703 3.62109 6.53515 3.62109C6.3 3.62109 6.10938 3.81666 6.10938 4.05791C6.10938 4.29915 6.3 4.49472 6.53515 4.49472Z", fill: "#262626", stroke: "#262626", strokeLinecap: "round", strokeLinejoin: "round" }), _jsx("path", { d: "M6.53515 9.29989V6.24219H5.68359", stroke: "#262626", strokeLinecap: "round", strokeLinejoin: "round" })] }), _jsx("div", { "data-testid": "cid-greyout-participant-name-mobile-only", className: "cid-idp-selector-popup-participant-greyed-out-text", "aria-describedby": `participant-greyed-out-description-${CustomerFriendlyName}`, children: "Available on mobile only" })] })] }));
|
|
129
|
-
}
|
|
130
|
-
else {
|
|
131
|
-
return (_jsxs("li", { "data-testid": "participant", className: "cid-idp-selector-popup-participant", tabIndex: 0, onClick: () => onProceed(AuthorisationServerId, CustomerFriendlyName), children: [_jsx("img", { className: "cid-idp-selector-popup-participant-icon", src: CustomerFriendlyLogoUri, alt: `${CustomerFriendlyName} logo` }), _jsx("div", { className: "cid-idp-selector-popup-participant-name", title: CustomerFriendlyName, "data-testid": "participant-name", children: CustomerFriendlyName })] }, AuthorisationServerId));
|
|
132
|
-
}
|
|
133
|
-
};
|
|
134
125
|
const renderAuthorisationServers = () => {
|
|
135
126
|
if (isLoading) {
|
|
136
127
|
return (_jsxs("div", { className: "cid-idp-selector-popup-provider-wrapper", children: [_jsx("h3", { className: "cid-idp-selector-popup-subtitle", children: "Choose a provider" }), _jsx(ParticipantsLoader, {})] }));
|
|
@@ -142,18 +133,19 @@ export const Popup = ({ onProceed, onCancel, onError, claims, requiredClaims, sh
|
|
|
142
133
|
return (_jsx("div", { className: "cid-idp-selector-popup-info-box-wrapper-warn", children: _jsx(NoIdpError, { dataTestId: "participant-error", hasManualIdp: false }) }));
|
|
143
134
|
}
|
|
144
135
|
const authorisationServers = participants
|
|
145
|
-
.
|
|
146
|
-
.flat()
|
|
136
|
+
.flatMap((participant) => participant.AuthorisationServers)
|
|
147
137
|
.sort((authServer1, authServer2) => authServer1.CustomerFriendlyName.localeCompare(authServer2.CustomerFriendlyName));
|
|
148
138
|
const manualAuthorisationServer = getManualAuthorisationServer(authorisationServers, showAllParticipants);
|
|
149
139
|
const authorisationServersWithoutManual = authorisationServers.filter(({ AuthorisationServerId }) => AuthorisationServerId !== (manualAuthorisationServer === null || manualAuthorisationServer === void 0 ? void 0 : manualAuthorisationServer.AuthorisationServerId));
|
|
150
140
|
const filterByClaims = requiredClaims || claims;
|
|
151
141
|
const filteredAuthorisationServers = filterAuthorisationServers(authorisationServersWithoutManual, showAllParticipants, certificationStatus, filterByClaims, requiredCertifications);
|
|
152
|
-
|
|
142
|
+
// Getting all auth servers that have certifications with profile type 'Redirect' and profile variant 'FAPI2 Adv. OP w/Private Key, PAR'
|
|
143
|
+
const authorisationServerWithProfileRedirectFapi2 = authorisationServersWithoutManual.filter(({ AuthorisationServerCertifications }) => {
|
|
144
|
+
return AuthorisationServerCertifications.find(({ ProfileType, ProfileVariant }) => ProfileType === 'Redirect' && ProfileVariant === 'FAPI2 Adv. OP w/Private Key, PAR');
|
|
145
|
+
});
|
|
146
|
+
const missingAuthorisationServerWithProfileRedirectFapi2 = authorisationServerWithProfileRedirectFapi2.length !== filteredAuthorisationServers.length;
|
|
153
147
|
const hasManualIdp = enableManualVerification && !!manualAuthorisationServer;
|
|
154
|
-
return (_jsxs(_Fragment, { children: [filteredAuthorisationServers.length > 0 ? (_jsxs("div", { className: "cid-idp-selector-popup-provider-wrapper", children: [_jsx("h3", { className: "cid-idp-selector-popup-subtitle", children: "Choose a provider" }), _jsx("ul", { className: "cid-idp-selector-popup-participants", "data-testid": "participants", children:
|
|
155
|
-
return (_jsx("div", { children: participantTile(authServer.AuthorisationServerId, authServer.CustomerFriendlyName, authServer.CustomerFriendlyLogoUri, device) }, authServer.AuthorisationServerId));
|
|
156
|
-
}) })] })) : (_jsx("div", { className: "cid-idp-selector-popup-info-box-error-wrapper", "data-testid": "popup-error-info-box", children: _jsx(NoIdpError, { hasManualIdp: hasManualIdp }) })), enableManualVerification && manualAuthorisationServer && (_jsx(_Fragment, { children: _jsxs("p", { className: "cid-idp-selector-popup-manual", children: [_jsx("span", { className: "cid-idp-selector-popup-manual-title", "data-testid": "manual-verification-text", children: "Or, use a document to verify your identity" }), _jsx("span", { className: "cid-idp-selector-popup-manual-action", tabIndex: 0, onClick: () => onProceed(manualAuthorisationServer.AuthorisationServerId, manualAuthorisationServer.CustomerFriendlyName), "data-testid": "manual-verification-action", role: "link", children: "Verify with a document" }), _jsx("span", { className: "cid-idp-selector-popup-manual-description", children: "ConnectID does not collect, hold or store your personal information at any time." })] }) }))] }));
|
|
148
|
+
return (_jsxs(_Fragment, { children: [filteredAuthorisationServers.length > 0 ? (_jsxs("div", { className: "cid-idp-selector-popup-provider-wrapper", children: [_jsx("h3", { className: "cid-idp-selector-popup-subtitle", children: "Choose a provider" }), _jsx("ul", { className: "cid-idp-selector-popup-participants", "data-testid": "participants", children: filteredAuthorisationServers.map(({ AuthorisationServerId, CustomerFriendlyName, CustomerFriendlyLogoUri }) => (_jsxs("li", { "data-testid": "participant", className: "cid-idp-selector-popup-participant", tabIndex: 0, onClick: () => onProceed(AuthorisationServerId, CustomerFriendlyName), children: [_jsx("img", { className: "cid-idp-selector-popup-participant-icon", src: CustomerFriendlyLogoUri, alt: `${CustomerFriendlyName} logo` }), _jsx("div", { className: "cid-idp-selector-popup-participant-name", title: CustomerFriendlyName, "data-testid": "participant-name", children: CustomerFriendlyName })] }, AuthorisationServerId))) }), missingAuthorisationServerWithProfileRedirectFapi2 && (_jsxs("div", { className: "cid-idp-selector-popup-missing", "data-testid": "missing-auth-server", children: [_jsx("p", { className: "cid-idp-selector-popup-missing-title", children: "Can't find your provider?" }), _jsx("p", { className: "cid-idp-selector-popup-missing-text", children: "Not all of our identity providers are available for this verification." })] }))] })) : (_jsx("div", { className: "cid-idp-selector-popup-info-box-error-wrapper", "data-testid": "popup-error-info-box", children: _jsx(NoIdpError, { hasManualIdp: hasManualIdp }) })), enableManualVerification && manualAuthorisationServer && (_jsx(_Fragment, { children: _jsxs("p", { className: "cid-idp-selector-popup-manual", children: [_jsx("span", { className: "cid-idp-selector-popup-manual-title", "data-testid": "manual-verification-text", children: "Or, use a document to verify your identity" }), _jsx("span", { className: "cid-idp-selector-popup-manual-action", tabIndex: 0, onClick: () => onProceed(manualAuthorisationServer.AuthorisationServerId, manualAuthorisationServer.CustomerFriendlyName), "data-testid": "manual-verification-action", role: "link", children: "Verify with a document" }), _jsx("span", { className: "cid-idp-selector-popup-manual-description", children: "ConnectID does not collect, hold or store your personal information at any time." })] }) }))] }));
|
|
157
149
|
};
|
|
158
150
|
return ReactDOM.createPortal(_jsxs("div", { className: "cid-idp-selector-popup", tabIndex: 0, ref: popupRef, onKeyDown: handleEnterEsc, children: [_jsxs("div", { className: "cid-idp-selector-popup-logo-container", children: [_jsxs("div", { className: "cid-idp-selector-popup-logos", children: [_jsxs("svg", { role: "img", focusable: "false", className: "cid-idp-selector-popup-logo", viewBox: "0 0 132.37 157.84", "data-testid": "cid-logo", children: [_jsx("title", { children: "ConnectID logo" }), _jsx("path", { d: "M102.22,91.65c0,19.9-16.13,36.03-36.03,36.03s-36.03-16.13-36.03-36.03,16.13-36.03,36.03-36.03c9.95,0,18.96,4.03,25.48,10.55l40.71-40.71c-6.52-6.52-10.55-15.52-10.55-25.46h-30.14c0,13.45,4.02,25.95,10.92,36.39-10.45-6.9-22.96-10.93-36.42-10.93C29.63,25.47,0,55.1,0,91.65s29.63,66.19,66.19,66.19,66.19-29.63,66.19-66.19h-30.16Z" })] }), rpLogoUrl && (_jsxs(_Fragment, { children: [_jsxs("div", { className: "cid-idp-selector-popup-logo-dots", children: [_jsx("div", { className: "cid-idp-selector-popup-logo-dot" }), _jsx("div", { className: "cid-idp-selector-popup-logo-dot" }), _jsx("div", { className: "cid-idp-selector-popup-logo-dot" })] }), _jsx("img", { className: "cid-idp-selector-popup-logo-rp", src: rpLogoUrl, alt: "RP logo", "data-testid": "rp-logo" })] }))] }), _jsxs("button", { "aria-label": "Close popup", "data-testid": "popup-close", className: "cid-idp-selector-popup-close", onClick: onCancel, tabIndex: 0, ref: closeButtonRef, children: [_jsx("span", { className: "cid-idp-selector-popup-close-label", children: "Close" }), _jsx("svg", { clipRule: "evenodd", fillRule: "evenodd", strokeLinejoin: "round", strokeMiterlimit: "2", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", children: _jsx("path", { d: "m12 10.93 5.719-5.72c.146-.146.339-.219.531-.219.404 0 .75.324.75.749 0 .193-.073.385-.219.532l-5.72 5.719 5.719 5.719c.147.147.22.339.22.531 0 .427-.349.75-.75.75-.192 0-.385-.073-.531-.219l-5.719-5.719-5.719 5.719c-.146.146-.339.219-.531.219-.401 0-.75-.323-.75-.75 0-.192.073-.384.22-.531l5.719-5.719-5.72-5.719c-.146-.147-.219-.339-.219-.532 0-.425.346-.749.75-.749.192 0 .385.073.531.219z" }) })] })] }), _jsxs("div", { className: "cid-idp-selector-popup-title-description-container", children: [_jsx("h2", { className: "cid-idp-selector-popup-title", children: popupTitle }), _jsx("p", { className: "cid-idp-selector-popup-description", children: rpDataSharingDescription })] }), renderClaims(), renderAuthorisationServers(), _jsx("div", { className: "cid-idp-selector-popup-info-box-wrapper", children: _jsxs(InfoBox, { children: [_jsx("h4", { className: "cid-idp-selector-popup-info-box-title", children: "What is ConnectID?" }), _jsxs("p", { className: "cid-idp-selector-popup-info-box-text", "data-testid": "whats-cid-text", children: ["ConnectID is an Australian-owned digital identity solution which allows you to securely prove who you are. ConnectID does not see or store your personal data. Visit", ' ', _jsx("a", { className: "cid-idp-selector-popup-info-box-link", href: "https://www.connectid.com.au", onClick: handleConnectIdLinkClicked, target: "_blank", tabIndex: 0, "data-testid": "info-box-link", ref: infoboxLinkRef, children: "connectid.com.au" }), ' ', "to find out more."] })] }) })] }), document.querySelector('body'));
|
|
159
151
|
};
|
package/README.md
CHANGED
|
@@ -222,6 +222,9 @@ The SVG image below the ConnectID button has either option dark or light mode. B
|
|
|
222
222
|
|
|
223
223
|
## 🚀 Release Notes
|
|
224
224
|
|
|
225
|
+
### 6.8.0 (May 7, 2025)
|
|
226
|
+
- Show message in the IDP list when any IDP with `ProfileType=Redirect` and `ProfileVariant=FAPI2 Adv. OP w/Private Key, PAR` is not being displayed.
|
|
227
|
+
|
|
225
228
|
### 6.7.0 (May 5, 2025)
|
|
226
229
|
- Detect incognito.
|
|
227
230
|
|
package/certification.d.ts
CHANGED
|
@@ -3,6 +3,6 @@ export declare const filterAuthorisationServers: (authorisationServers: Authoris
|
|
|
3
3
|
export declare const getManualAuthorisationServer: (authorisationServers: AuthorisationServer[], showAllParticipants: boolean) => AuthorisationServer | undefined;
|
|
4
4
|
export declare const removeExpiredOrNotStartedCertifications: (authorisationServers: AuthorisationServer[]) => AuthorisationServer[];
|
|
5
5
|
export declare const filterAuthorisationServerByClaims: (authorisationServers: AuthorisationServer[], claims: Claim[]) => AuthorisationServer[];
|
|
6
|
-
export declare const mapAuthorisationServerToDeviceType: (authorisationServers: AuthorisationServer[], deviceType: Device) => Map<AuthorisationServer, Device>;
|
|
7
6
|
export declare const filterAuthorisationServerByCertification: (authorisationServers: AuthorisationServer[], status: CertificationStatus, requiredCertifications?: RequiredCertification[]) => AuthorisationServer[];
|
|
7
|
+
export declare const filterAuthorisationServerByDevice: (authorisationServers: AuthorisationServer[], deviceType: Device) => AuthorisationServer[];
|
|
8
8
|
export declare const hasStarted: (startDateStr: string) => boolean;
|
package/certification.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getDeviceType } from './userAgent';
|
|
1
2
|
const requiredCertificationsMap = {
|
|
2
3
|
'TDIF.IDP': { type: 'TDIF Accreditation', variant: 'Identity Provider' },
|
|
3
4
|
'Redirect.FAPI2': { type: 'Redirect', variant: 'FAPI2 Adv. OP w/Private Key, PAR' },
|
|
@@ -6,7 +7,9 @@ export const filterAuthorisationServers = (authorisationServers, showAllParticip
|
|
|
6
7
|
if (showAllParticipants)
|
|
7
8
|
return authorisationServers;
|
|
8
9
|
const authorisationServersWithValidCertifications = removeExpiredOrNotStartedCertifications(authorisationServers);
|
|
9
|
-
const
|
|
10
|
+
const device = getDeviceType();
|
|
11
|
+
const filteredAuthorisationServersByDevice = filterAuthorisationServerByDevice(authorisationServersWithValidCertifications, device);
|
|
12
|
+
const filteredAuthorisationServersByClaims = filterAuthorisationServerByClaims(filteredAuthorisationServersByDevice, claims);
|
|
10
13
|
const filteredAuthorisationServers = filterAuthorisationServerByCertification(filteredAuthorisationServersByClaims, certificationStatus, requiredCertifications);
|
|
11
14
|
return filteredAuthorisationServers;
|
|
12
15
|
};
|
|
@@ -37,20 +40,6 @@ export const filterAuthorisationServerByClaims = (authorisationServers, claims)
|
|
|
37
40
|
return profileVariants.every((profileVariant) => authorisationServerProfileVariants.includes(profileVariant));
|
|
38
41
|
});
|
|
39
42
|
};
|
|
40
|
-
export const mapAuthorisationServerToDeviceType = (authorisationServers, deviceType) => {
|
|
41
|
-
const authServerMap = new Map();
|
|
42
|
-
if (deviceType === 'mobile') {
|
|
43
|
-
authorisationServers.forEach((authorisationServer) => {
|
|
44
|
-
authServerMap.set(authorisationServer, 'mobile');
|
|
45
|
-
});
|
|
46
|
-
return authServerMap;
|
|
47
|
-
}
|
|
48
|
-
authorisationServers.map((authorisationServer) => {
|
|
49
|
-
const channelCertifications = authorisationServer.AuthorisationServerCertifications.filter((cert) => cert.ProfileType === 'Channel');
|
|
50
|
-
authServerMap.set(authorisationServer, channelCertifications.length === 1 && channelCertifications[0].ProfileVariant === 'app' ? 'desktop' : 'mobile');
|
|
51
|
-
});
|
|
52
|
-
return authServerMap;
|
|
53
|
-
};
|
|
54
43
|
export const filterAuthorisationServerByCertification = (authorisationServers, status, requiredCertifications) => {
|
|
55
44
|
const filteredByStatus = filterByStatus(authorisationServers, status);
|
|
56
45
|
const filteredByStatusAndRequiredCertifications = filterByRequiredCertifications(filteredByStatus, requiredCertifications);
|
|
@@ -81,6 +70,18 @@ const filterByRequiredCertifications = (authorisationServers, requiredCertificat
|
|
|
81
70
|
return requiredCertificationsFound === requiredCertifications.length;
|
|
82
71
|
});
|
|
83
72
|
};
|
|
73
|
+
// mobile return all authorisation servers
|
|
74
|
+
// tablet and desktop return all authorisation servers but those ones with only one certification and that certification is app
|
|
75
|
+
export const filterAuthorisationServerByDevice = (authorisationServers, deviceType) => {
|
|
76
|
+
if (deviceType === 'mobile')
|
|
77
|
+
return authorisationServers;
|
|
78
|
+
const onlyAppAuthorisationServers = authorisationServers.filter((authorisationServer) => {
|
|
79
|
+
const channelCertifications = authorisationServer.AuthorisationServerCertifications.filter((cert) => cert.ProfileType === 'Channel');
|
|
80
|
+
return channelCertifications.length === 1 && channelCertifications[0].ProfileVariant === 'app';
|
|
81
|
+
});
|
|
82
|
+
const onlyAppAuthorisationServersIds = onlyAppAuthorisationServers.map((authorisationServer) => authorisationServer.AuthorisationServerId);
|
|
83
|
+
return authorisationServers.filter((authorisationServer) => !onlyAppAuthorisationServersIds.includes(authorisationServer.AuthorisationServerId));
|
|
84
|
+
};
|
|
84
85
|
const isExpired = (expiryDateStr) => {
|
|
85
86
|
const expiryDate = parseCertificationDate(expiryDateStr);
|
|
86
87
|
expiryDate.setHours(23);
|
package/certification.test.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import assert from 'node:assert';
|
|
2
2
|
import { describe, it } from 'node:test';
|
|
3
|
-
import { filterAuthorisationServerByClaims, filterAuthorisationServers, getManualAuthorisationServer,
|
|
3
|
+
import { filterAuthorisationServerByClaims, filterAuthorisationServerByDevice, filterAuthorisationServers, getManualAuthorisationServer, removeExpiredOrNotStartedCertifications, } from './certification';
|
|
4
4
|
describe('filterAuthorisationServers', () => {
|
|
5
5
|
it('should return all authorisation servers if showAllParticipants is true regardless of certification status, required certifications and claims', () => {
|
|
6
6
|
const authorisationServers = [
|
|
@@ -306,82 +306,93 @@ describe('removeExpiredCertifications', () => {
|
|
|
306
306
|
});
|
|
307
307
|
});
|
|
308
308
|
describe('filterAuthorisationServerByDevice', () => {
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
CustomerFriendlyName: 'Mock Bank C',
|
|
342
|
-
AuthorisationServerCertifications: [
|
|
343
|
-
{
|
|
344
|
-
CertificationStartDate: '10/04/1900',
|
|
345
|
-
CertificationExpirationDate: '10/04/2024',
|
|
346
|
-
Status: 'Certified',
|
|
347
|
-
ProfileVariant: 'app',
|
|
348
|
-
ProfileType: 'Channel',
|
|
349
|
-
},
|
|
350
|
-
],
|
|
351
|
-
},
|
|
352
|
-
{
|
|
353
|
-
AuthorisationServerId: 'fa8573a1-953a-4085-b5f7-070a42a4d5a1',
|
|
354
|
-
CustomerFriendlyLogoUri: 'https://static.sandbox.connectid.com.au/BankC.svg',
|
|
355
|
-
CustomerFriendlyName: 'Mock Bank D',
|
|
356
|
-
AuthorisationServerCertifications: [],
|
|
357
|
-
},
|
|
358
|
-
];
|
|
359
|
-
it('should return all auth servers when device is mobile', () => {
|
|
360
|
-
const authServers = mapAuthorisationServerToDeviceType(authorisationServers, 'mobile');
|
|
361
|
-
const values = Array.from(authServers.values());
|
|
362
|
-
assert.deepStrictEqual(values.every((value) => value === 'mobile'), true);
|
|
363
|
-
});
|
|
364
|
-
it('should not return auth servers with only app cert when device is desktop', () => {
|
|
365
|
-
const authServers = mapAuthorisationServerToDeviceType(authorisationServers, 'desktop');
|
|
366
|
-
const filteredAuthServers = Array.from(authServers)
|
|
367
|
-
.filter(([_, device]) => device === 'mobile')
|
|
368
|
-
.map(([key, _]) => key);
|
|
369
|
-
assert.deepStrictEqual(filteredAuthServers, [
|
|
370
|
-
authorisationServers[0],
|
|
371
|
-
authorisationServers[1],
|
|
372
|
-
authorisationServers[3],
|
|
373
|
-
]);
|
|
309
|
+
it('should return all authorisation servers for mobile', () => {
|
|
310
|
+
const authorisationServers = [
|
|
311
|
+
{
|
|
312
|
+
AuthorisationServerId: '1',
|
|
313
|
+
CustomerFriendlyLogoUri: 'https://static.sandbox.connectid.com.au/BankA.svg',
|
|
314
|
+
CustomerFriendlyName: 'Mock Bank A',
|
|
315
|
+
AuthorisationServerCertifications: [
|
|
316
|
+
{
|
|
317
|
+
ProfileType: 'Channel',
|
|
318
|
+
ProfileVariant: 'app',
|
|
319
|
+
CertificationExpirationDate: '10/04/2099',
|
|
320
|
+
Status: 'Certified',
|
|
321
|
+
CertificationStartDate: '10/04/1900',
|
|
322
|
+
},
|
|
323
|
+
],
|
|
324
|
+
},
|
|
325
|
+
{
|
|
326
|
+
AuthorisationServerId: '2',
|
|
327
|
+
CustomerFriendlyLogoUri: 'https://static.sandbox.connectid.com.au/BankA.svg',
|
|
328
|
+
CustomerFriendlyName: 'Mock Bank B',
|
|
329
|
+
AuthorisationServerCertifications: [
|
|
330
|
+
{
|
|
331
|
+
ProfileType: 'Channel',
|
|
332
|
+
ProfileVariant: 'web',
|
|
333
|
+
CertificationExpirationDate: '10/04/2099',
|
|
334
|
+
Status: 'Certified',
|
|
335
|
+
CertificationStartDate: '10/04/1900',
|
|
336
|
+
},
|
|
337
|
+
],
|
|
338
|
+
},
|
|
339
|
+
];
|
|
340
|
+
assert.deepStrictEqual(filterAuthorisationServerByDevice(authorisationServers, 'mobile'), authorisationServers);
|
|
374
341
|
});
|
|
375
|
-
it('should
|
|
376
|
-
const
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
342
|
+
it('should return all authorisation servers except those with only app certification when desktop', () => {
|
|
343
|
+
const authorisationServers = [
|
|
344
|
+
{
|
|
345
|
+
AuthorisationServerId: '1',
|
|
346
|
+
CustomerFriendlyLogoUri: 'https://static.sandbox.connectid.com.au/BankA.svg',
|
|
347
|
+
CustomerFriendlyName: 'Mock Bank A',
|
|
348
|
+
// has only app certification (removed)
|
|
349
|
+
AuthorisationServerCertifications: [
|
|
350
|
+
{
|
|
351
|
+
ProfileType: 'Channel',
|
|
352
|
+
ProfileVariant: 'app',
|
|
353
|
+
CertificationExpirationDate: '10/04/2099',
|
|
354
|
+
Status: 'Certified',
|
|
355
|
+
CertificationStartDate: '10/04/1900',
|
|
356
|
+
},
|
|
357
|
+
],
|
|
358
|
+
},
|
|
359
|
+
{
|
|
360
|
+
AuthorisationServerId: '2',
|
|
361
|
+
CustomerFriendlyLogoUri: 'https://static.sandbox.connectid.com.au/BankA.svg',
|
|
362
|
+
CustomerFriendlyName: 'Mock Bank B',
|
|
363
|
+
AuthorisationServerCertifications: [
|
|
364
|
+
{
|
|
365
|
+
ProfileType: 'Channel',
|
|
366
|
+
ProfileVariant: 'web',
|
|
367
|
+
CertificationExpirationDate: '10/04/2099',
|
|
368
|
+
Status: 'Certified',
|
|
369
|
+
CertificationStartDate: '10/04/1900',
|
|
370
|
+
},
|
|
371
|
+
],
|
|
372
|
+
},
|
|
373
|
+
{
|
|
374
|
+
AuthorisationServerId: '3',
|
|
375
|
+
CustomerFriendlyLogoUri: 'https://static.sandbox.connectid.com.au/BankA.svg',
|
|
376
|
+
CustomerFriendlyName: 'Mock Bank C',
|
|
377
|
+
// has web and app certifications (okay)
|
|
378
|
+
AuthorisationServerCertifications: [
|
|
379
|
+
{
|
|
380
|
+
ProfileType: 'Channel',
|
|
381
|
+
ProfileVariant: 'app',
|
|
382
|
+
CertificationExpirationDate: '10/04/2099',
|
|
383
|
+
Status: 'Certified',
|
|
384
|
+
CertificationStartDate: '10/04/1900',
|
|
385
|
+
},
|
|
386
|
+
{
|
|
387
|
+
ProfileType: 'Channel',
|
|
388
|
+
ProfileVariant: 'web',
|
|
389
|
+
CertificationExpirationDate: '10/04/2099',
|
|
390
|
+
Status: 'Certified',
|
|
391
|
+
CertificationStartDate: '10/04/1900',
|
|
392
|
+
},
|
|
393
|
+
],
|
|
394
|
+
},
|
|
395
|
+
];
|
|
396
|
+
assert.deepStrictEqual(filterAuthorisationServerByDevice(authorisationServers, 'desktop'), [authorisationServers[1], authorisationServers[2]]);
|
|
386
397
|
});
|
|
387
398
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@connectid-tools/idp-selector-react",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.8.0",
|
|
4
4
|
"description": "React component for IDP Selector.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
"homepage": "https://github.com/connectid-tools/idp-selector-react",
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@babel/preset-typescript": "^7.27.1",
|
|
29
|
-
"@types/node": "^22.15.
|
|
30
|
-
"@types/react": "^18.3.
|
|
29
|
+
"@types/node": "^22.15.14",
|
|
30
|
+
"@types/react": "^18.3.21",
|
|
31
31
|
"@types/react-dom": "^18.3.7",
|
|
32
32
|
"cypress": "^13.17.0",
|
|
33
33
|
"jest-environment-jsdom": "^29.7.0",
|