@connectid-tools/idp-selector-react 6.10.0-alpha.1 → 6.10.0-alpha.3
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/CidButton.d.ts +2 -0
- package/CidButton.js +18 -1
- package/README.md +45 -21
- package/compatibility.d.ts +1 -1
- package/compatibility.js +5 -4
- package/{compability.test.js → compatibility.test.js} +37 -4
- package/package.json +4 -4
- package/types.d.ts +1 -0
- /package/{compability.test.d.ts → compatibility.test.d.ts} +0 -0
package/CidButton.d.ts
CHANGED
|
@@ -21,6 +21,8 @@ type CidButtonProps = {
|
|
|
21
21
|
logoLockupStyle?: LogoMode;
|
|
22
22
|
showInfoContent?: boolean;
|
|
23
23
|
onError?: (error: string) => void;
|
|
24
|
+
showCompatibilityWarnings?: boolean;
|
|
25
|
+
supportIncognito?: boolean;
|
|
24
26
|
forceMobile?: boolean;
|
|
25
27
|
forceIos?: boolean;
|
|
26
28
|
forceAndroid?: boolean;
|
package/CidButton.js
CHANGED
|
@@ -30,7 +30,7 @@ import detectIncognito from './incognito';
|
|
|
30
30
|
import { getDeviceType, isAndroid, isChromeBrowser, isIos, isSamsungBrowser } from './userAgent';
|
|
31
31
|
import { hasCertification } from './certification';
|
|
32
32
|
import { getCompatibility } from './compatibility';
|
|
33
|
-
export const CidButton = ({ onProceed, claims, requiredClaims, rpLogoUrl, requiredCertifications, label = 'Verify', size = 'regular', type, introTextType, fullProcessCollapsible = false, participantsUri = 'https://data.directory.connectid.com.au/participants', certificationStatus = 'Active', rpDataSharingDescription = 'Your details will be shared with the current website.', enableManualVerification = false, showAllParticipants = false, theme = 'dark', logoLockupStyle = 'light', showInfoContent = false, onError = () => { }, forceMobile = false, // only for testing purposes
|
|
33
|
+
export const CidButton = ({ onProceed, claims, requiredClaims, rpLogoUrl, requiredCertifications, label = 'Verify', size = 'regular', type, introTextType, fullProcessCollapsible = false, participantsUri = 'https://data.directory.connectid.com.au/participants', certificationStatus = 'Active', rpDataSharingDescription = 'Your details will be shared with the current website.', enableManualVerification = false, showAllParticipants = false, theme = 'dark', logoLockupStyle = 'light', showInfoContent = false, onError = () => { }, showCompatibilityWarnings = false, supportIncognito = false, forceMobile = false, // only for testing purposes
|
|
34
34
|
forceIos = false, // only for testing purposes
|
|
35
35
|
forceAndroid = false, // only for testing purposes
|
|
36
36
|
forceIncognito = false, // only for testing purposes
|
|
@@ -119,12 +119,19 @@ forceIncognito = false, // only for testing purposes
|
|
|
119
119
|
});
|
|
120
120
|
track();
|
|
121
121
|
}, []);
|
|
122
|
+
const getCompatibilityConfirmText = (compatibilityWarnings) => {
|
|
123
|
+
if (compatibilityWarnings.mobileOs === 'android' && compatibilityWarnings.browser === 'samsung') {
|
|
124
|
+
return 'It looks like you are using Samsung Browser. This generally will not work - we suggest using Chrome and trying again.\nClick on "Cancel" to abort or "OK" to proceed.';
|
|
125
|
+
}
|
|
126
|
+
return 'It looks like you are in incognito mode. This generally will not work - we suggest switching out of incognito mode and trying again.\nClick on "Cancel" to abort or "OK" to proceed.';
|
|
127
|
+
};
|
|
122
128
|
const handleOnProceed = (authorisationServerId, authorisationServerName, authorisationServerCertifications) => {
|
|
123
129
|
analytics === null || analytics === void 0 ? void 0 : analytics.track('IDP Selected', Object.assign(Object.assign({}, analyticsData), { authorisationServerId, idp_name: authorisationServerName, incognito: isIncognito }));
|
|
124
130
|
setShowPopup(false);
|
|
125
131
|
const isMobile = forceMobile || getDeviceType() === 'mobile';
|
|
126
132
|
const idpHasAppCertification = hasCertification(authorisationServerCertifications, 'Channel', 'app');
|
|
127
133
|
const compatibility = getCompatibility({
|
|
134
|
+
supportIncognito,
|
|
128
135
|
idpHasAppCertification,
|
|
129
136
|
isMobile,
|
|
130
137
|
isIncognito: forceIncognito || !!isIncognito,
|
|
@@ -133,6 +140,16 @@ forceIncognito = false, // only for testing purposes
|
|
|
133
140
|
isSamsungBrowser: isSamsungBrowser(),
|
|
134
141
|
isChromeBrowser: isChromeBrowser(),
|
|
135
142
|
});
|
|
143
|
+
if (showCompatibilityWarnings && compatibility.mightFail) {
|
|
144
|
+
const confirmText = getCompatibilityConfirmText(compatibility);
|
|
145
|
+
if (confirm(confirmText)) {
|
|
146
|
+
onProceed(authorisationServerId, compatibility);
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
setShowPopup(true);
|
|
150
|
+
}
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
136
153
|
onProceed(authorisationServerId, compatibility);
|
|
137
154
|
};
|
|
138
155
|
const handleButtonClick = () => {
|
package/README.md
CHANGED
|
@@ -29,27 +29,29 @@ Your page should render a widget similar to this 👇 And when the button is cli
|
|
|
29
29
|
|
|
30
30
|
## ⭐ CidButton Options
|
|
31
31
|
|
|
32
|
-
|
|
|
33
|
-
|
|
34
|
-
| onProceed
|
|
35
|
-
| claims
|
|
36
|
-
| requiredClaims
|
|
37
|
-
| label
|
|
38
|
-
| size
|
|
39
|
-
| participantsUri
|
|
40
|
-
| certificationStatus
|
|
41
|
-
| requiredCertifications
|
|
42
|
-
| rpLogoUrl
|
|
43
|
-
| rpDataSharingDescription |
|
|
44
|
-
| enableManualVerification |
|
|
45
|
-
| type
|
|
46
|
-
| introTextType
|
|
47
|
-
| fullProcessCollapsible
|
|
48
|
-
| showAllParticipants
|
|
49
|
-
| theme
|
|
50
|
-
| logoLockupStyle
|
|
51
|
-
| showInfoContent
|
|
52
|
-
| onError
|
|
32
|
+
| option | description | type | required | default |
|
|
33
|
+
|-----|-------------|------|----------|---------|
|
|
34
|
+
| onProceed | Callback when Proceed button is clicked | (id: string, warnings: CompatibilityWarnings) => void | yes | - |
|
|
35
|
+
| claims | Claims to display and request from IDP | Claim[] | yes | - |
|
|
36
|
+
| requiredClaims | Subset of `claims` that must be supported | Claim[] | no (`claims` used if not set) | - |
|
|
37
|
+
| label | Button label (avoid 'Sign Up') | 'Verify'\|'Login'\|'Sign Up'\|'Age check'\|'Sign up'\|'Authenticate'\|'Checkout' | no | 'Verify' |
|
|
38
|
+
| size | Button size | 'regular'\|'large' | no | 'regular' |
|
|
39
|
+
| participantsUri | API URI for IDPs | string | no | 'https://data.directory.connectid.com.au/participants' |
|
|
40
|
+
| certificationStatus | Filter IDPs by certification | 'Active'\|'All' | no | 'Active' |
|
|
41
|
+
| requiredCertifications | Filter by certifications | RequiredCertification[] | no | All certifications |
|
|
42
|
+
| rpLogoUrl | RP logo URL (40x40) | URL | no | No logo |
|
|
43
|
+
| rpDataSharingDescription | Explains how data is used | string | no | 'Your details will be shared with the current website.' |
|
|
44
|
+
| enableManualVerification | Show manual verification option | boolean | no | false |
|
|
45
|
+
| type | Widget type [More](#type) | 'tiny'\|'medium benefits'\|'medium process'\|'full benefits'\|'full process' | no | undefined |
|
|
46
|
+
| introTextType | Text above button [More](#introTextType) | 'verify-trust'\|'verify-account'\|'power'\|'sign-up'\|'bank-details-plus-personal-info'\|'bank-details-only'\|'verify-age' | yes if `type` is set | - |
|
|
47
|
+
| fullProcessCollapsible | Collapse process items (for `full process`) | boolean | no | false |
|
|
48
|
+
| showAllParticipants | Show all IDPs (testing) | boolean | no | false |
|
|
49
|
+
| theme | Button theme | 'dark'\|'light' | no | 'dark' |
|
|
50
|
+
| logoLockupStyle | Logo theme | 'dark'\|'light' | no | 'light' |
|
|
51
|
+
| showInfoContent | Show text below button [More](#infoContent) | boolean | no | false |
|
|
52
|
+
| onError | Called on error | () => void | no | () => {} |
|
|
53
|
+
| showCompatibilityWarnings | Show compatibility popup [More](#showCompatibilityWarnings) | boolean | no | false |
|
|
54
|
+
| supportIncognito | Whether RP supports incognito mode or not (to be able to support incognito mode RP website cannot use browser storage like `cookies`, `sessionStorage`, `localStorage`, etc). | boolean | no | false |
|
|
53
55
|
|
|
54
56
|
#### CompatibilityWarnings type
|
|
55
57
|
|
|
@@ -69,6 +71,12 @@ It returns information about the compatibility of the user's browser and device
|
|
|
69
71
|
- `mobileOs`: The operating system of the mobile device, if applicable.
|
|
70
72
|
- `browser`: The browser being used by the user.
|
|
71
73
|
|
|
74
|
+
Here are the possible reasons why the flow might fail:
|
|
75
|
+
| Scenario | Why it might fail | Suggested message | Incognito support |
|
|
76
|
+
|---|---|---|---|
|
|
77
|
+
| Mobile incognito (`isMobile: true`, `isIncognito: true`) | When a user is returned from the IDP app to the your RP site, the user will be returned in a new incognito tab. If your app relies on `cookies`, `sessionStorage` or `localStorage` it will not have access to any of the these values from the user's original tab. If your flow relies on them it will not be able to continue. | "You are using incognito mode – this may not work properly. Please switch to normal mode." | If `supportIncognito` is set to `true`, this flow will not fail. |
|
|
78
|
+
| Android Samsung browser (`isMobile: true`, `mobileOs: 'android'`, `browser: 'samsung'`) | The Samsung browser default settings prevent the opening of App Links, meaning the IDP app may not open when the user is redirected. User may need to use an alternate browser on the mobile device, or a desktop device. | "It looks like you are using the Samsung browser which may not work properly with this provider. We suggest trying an alternate browser on your mobile, or using a desktop device." | Regardless of `supportIncognito` value, this flow might fail. |
|
|
79
|
+
|
|
72
80
|
#### certificationStatus values
|
|
73
81
|
|
|
74
82
|
- `Active`: only IDPs with active certification
|
|
@@ -219,6 +227,16 @@ This is an optional field in addition with the widgets below the ConnectID butto
|
|
|
219
227
|

|
|
220
228
|
</details>
|
|
221
229
|
|
|
230
|
+
### <a name="showCompatibilityWarnings"></a>showCompatibilityWarnings option
|
|
231
|
+
|
|
232
|
+
If set to `true`, a popup with compatibility warnings will be displayed after an IDP is selected, if the conditions are met. The popup will show information about the compatibility of the user's browser, device, incognito/private mode with the ConnectID flow and the user can decide whether they want to proceed or not.
|
|
233
|
+
|
|
234
|
+
<details>
|
|
235
|
+
<summary>Show compatibility warnings</summary>
|
|
236
|
+
|
|
237
|
+

|
|
238
|
+
</details>
|
|
239
|
+
|
|
222
240
|
|
|
223
241
|
### <a name="logoLockupStyle"></a>logoLockup option
|
|
224
242
|
|
|
@@ -241,6 +259,12 @@ The SVG image below the ConnectID button has either option dark or light mode. B
|
|
|
241
259
|
|
|
242
260
|
## 🚀 Release Notes
|
|
243
261
|
|
|
262
|
+
### 6.10.0-alpha.3 (Jun 20, 2025)
|
|
263
|
+
- Add `supportIncognito` option.
|
|
264
|
+
|
|
265
|
+
### 6.10.0-alpha.2 (Jun 17, 2025)
|
|
266
|
+
- Add `showCompatibilityWarnings` option.
|
|
267
|
+
|
|
244
268
|
### 6.10.0-alpha.1 (Jun 12, 2025)
|
|
245
269
|
- Rename `compabilityWarnings` to `compatibilityWarnings`.
|
|
246
270
|
|
package/compatibility.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { CompatibilityEnvironment, CompatibilityWarnings } from './types';
|
|
2
2
|
export declare const getCompatibility: (env: CompatibilityEnvironment) => CompatibilityWarnings;
|
|
3
|
-
export declare const getMightFail: (env: Pick<CompatibilityEnvironment, "idpHasAppCertification" | "isMobile" | "isIncognito" | "isAndroid" | "isIos" | "isSamsungBrowser" | "isChromeBrowser">) => boolean;
|
|
3
|
+
export declare const getMightFail: (env: Pick<CompatibilityEnvironment, "supportIncognito" | "idpHasAppCertification" | "isMobile" | "isIncognito" | "isAndroid" | "isIos" | "isSamsungBrowser" | "isChromeBrowser">) => boolean;
|
package/compatibility.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { getBrowserName } from './userAgent';
|
|
2
2
|
export const getCompatibility = (env) => {
|
|
3
|
-
const { idpHasAppCertification, isAndroid, isChromeBrowser, isIncognito, isMobile, isSamsungBrowser, isIos } = env;
|
|
3
|
+
const { supportIncognito, idpHasAppCertification, isAndroid, isChromeBrowser, isIncognito, isMobile, isSamsungBrowser, isIos, } = env;
|
|
4
4
|
const mightFail = getMightFail({
|
|
5
|
+
supportIncognito,
|
|
5
6
|
idpHasAppCertification,
|
|
6
7
|
isMobile,
|
|
7
8
|
isIncognito,
|
|
@@ -19,17 +20,17 @@ export const getCompatibility = (env) => {
|
|
|
19
20
|
};
|
|
20
21
|
};
|
|
21
22
|
export const getMightFail = (env) => {
|
|
22
|
-
const { idpHasAppCertification, isMobile, isIncognito, isAndroid, isChromeBrowser, isSamsungBrowser, isIos } = env;
|
|
23
|
+
const { supportIncognito, idpHasAppCertification, isMobile, isIncognito, isAndroid, isChromeBrowser, isSamsungBrowser, isIos, } = env;
|
|
23
24
|
if (!idpHasAppCertification || !isMobile) {
|
|
24
25
|
return false;
|
|
25
26
|
}
|
|
26
|
-
if (isIncognito && isAndroid && isChromeBrowser) {
|
|
27
|
+
if (!supportIncognito && isIncognito && isAndroid && isChromeBrowser) {
|
|
27
28
|
return true;
|
|
28
29
|
}
|
|
29
30
|
if (isAndroid && isSamsungBrowser) {
|
|
30
31
|
return true;
|
|
31
32
|
}
|
|
32
|
-
if (isIncognito && isIos) {
|
|
33
|
+
if (!supportIncognito && isIncognito && isIos) {
|
|
33
34
|
return true;
|
|
34
35
|
}
|
|
35
36
|
return false;
|
|
@@ -4,6 +4,7 @@ import { getCompatibility, getMightFail } from './compatibility';
|
|
|
4
4
|
describe('getCompatibility', () => {
|
|
5
5
|
it('should return compatibility warnings', () => {
|
|
6
6
|
const compatibility = getCompatibility({
|
|
7
|
+
supportIncognito: false,
|
|
7
8
|
idpHasAppCertification: true,
|
|
8
9
|
isMobile: true,
|
|
9
10
|
isIncognito: false,
|
|
@@ -17,13 +18,14 @@ describe('getCompatibility', () => {
|
|
|
17
18
|
isIncognito: false,
|
|
18
19
|
mobileOs: 'other',
|
|
19
20
|
browser: 'other',
|
|
20
|
-
mightFail: false
|
|
21
|
+
mightFail: false,
|
|
21
22
|
});
|
|
22
23
|
});
|
|
23
24
|
});
|
|
24
25
|
describe('getMightFail', () => {
|
|
25
26
|
it('should return false when idpHasAppCertification is false', () => {
|
|
26
27
|
const mightFail = getMightFail({
|
|
28
|
+
supportIncognito: false,
|
|
27
29
|
idpHasAppCertification: false,
|
|
28
30
|
isMobile: true,
|
|
29
31
|
isIncognito: false,
|
|
@@ -36,6 +38,7 @@ describe('getMightFail', () => {
|
|
|
36
38
|
});
|
|
37
39
|
it('should return false when isMobile is false', () => {
|
|
38
40
|
const mightFail = getMightFail({
|
|
41
|
+
supportIncognito: false,
|
|
39
42
|
idpHasAppCertification: true,
|
|
40
43
|
isMobile: false,
|
|
41
44
|
isIncognito: false,
|
|
@@ -46,8 +49,9 @@ describe('getMightFail', () => {
|
|
|
46
49
|
});
|
|
47
50
|
assert.ok(mightFail === false);
|
|
48
51
|
});
|
|
49
|
-
it('should return true when
|
|
52
|
+
it('should return true when does not support incognito and settings are incognito/android/chrome', () => {
|
|
50
53
|
const mightFail = getMightFail({
|
|
54
|
+
supportIncognito: false,
|
|
51
55
|
idpHasAppCertification: true,
|
|
52
56
|
isMobile: true,
|
|
53
57
|
isIncognito: true,
|
|
@@ -58,8 +62,22 @@ describe('getMightFail', () => {
|
|
|
58
62
|
});
|
|
59
63
|
assert.ok(mightFail === true);
|
|
60
64
|
});
|
|
61
|
-
it('should return
|
|
65
|
+
it('should return false when supports incognito and settings are incognito/android/chrome', () => {
|
|
62
66
|
const mightFail = getMightFail({
|
|
67
|
+
supportIncognito: true,
|
|
68
|
+
idpHasAppCertification: true,
|
|
69
|
+
isMobile: true,
|
|
70
|
+
isIncognito: true,
|
|
71
|
+
isAndroid: true,
|
|
72
|
+
isIos: false,
|
|
73
|
+
isSamsungBrowser: false,
|
|
74
|
+
isChromeBrowser: true,
|
|
75
|
+
});
|
|
76
|
+
assert.ok(mightFail === false);
|
|
77
|
+
});
|
|
78
|
+
it('should return true when android/samsung', () => {
|
|
79
|
+
const mightFail = getMightFail({
|
|
80
|
+
supportIncognito: false,
|
|
63
81
|
idpHasAppCertification: true,
|
|
64
82
|
isMobile: true,
|
|
65
83
|
isIncognito: false,
|
|
@@ -70,8 +88,9 @@ describe('getMightFail', () => {
|
|
|
70
88
|
});
|
|
71
89
|
assert.ok(mightFail === true);
|
|
72
90
|
});
|
|
73
|
-
it('should return true when
|
|
91
|
+
it('should return true when does not support incognito and settings are incognito/ios', () => {
|
|
74
92
|
const mightFail = getMightFail({
|
|
93
|
+
supportIncognito: false,
|
|
75
94
|
idpHasAppCertification: true,
|
|
76
95
|
isMobile: true,
|
|
77
96
|
isIncognito: true,
|
|
@@ -82,8 +101,22 @@ describe('getMightFail', () => {
|
|
|
82
101
|
});
|
|
83
102
|
assert.ok(mightFail === true);
|
|
84
103
|
});
|
|
104
|
+
it('should return false when supports incognito and settings are incognito/ios', () => {
|
|
105
|
+
const mightFail = getMightFail({
|
|
106
|
+
supportIncognito: true,
|
|
107
|
+
idpHasAppCertification: true,
|
|
108
|
+
isMobile: true,
|
|
109
|
+
isIncognito: true,
|
|
110
|
+
isAndroid: false,
|
|
111
|
+
isIos: true,
|
|
112
|
+
isSamsungBrowser: false,
|
|
113
|
+
isChromeBrowser: false,
|
|
114
|
+
});
|
|
115
|
+
assert.ok(mightFail === false);
|
|
116
|
+
});
|
|
85
117
|
it('should return false when none of the conditions are met', () => {
|
|
86
118
|
const mightFail = getMightFail({
|
|
119
|
+
supportIncognito: false,
|
|
87
120
|
idpHasAppCertification: true,
|
|
88
121
|
isMobile: true,
|
|
89
122
|
isIncognito: false,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@connectid-tools/idp-selector-react",
|
|
3
|
-
"version": "6.10.0-alpha.
|
|
3
|
+
"version": "6.10.0-alpha.3",
|
|
4
4
|
"description": "React component for IDP Selector.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -26,16 +26,16 @@
|
|
|
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.
|
|
29
|
+
"@types/node": "^22.15.32",
|
|
30
30
|
"@types/react": "^18.3.23",
|
|
31
31
|
"@types/react-dom": "^18.3.7",
|
|
32
|
-
"cypress": "^14.
|
|
32
|
+
"cypress": "^14.5.0",
|
|
33
33
|
"jest-environment-jsdom": "^29.7.0",
|
|
34
34
|
"prettier": "^3.5.3",
|
|
35
35
|
"react": "^18.3.1",
|
|
36
36
|
"react-dom": "^18.3.1",
|
|
37
37
|
"replace-in-file": "^8.3.0",
|
|
38
|
-
"tsx": "^4.
|
|
38
|
+
"tsx": "^4.20.3",
|
|
39
39
|
"typescript": "^5.8.3"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
package/types.d.ts
CHANGED
|
File without changes
|