@connectid-tools/idp-selector-react 6.10.0-alpha.2 → 6.10.0-alpha.4
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 +3 -1
- package/CidButton.js +5 -4
- package/README.md +35 -22
- package/compatibility.d.ts +1 -1
- package/compatibility.js +8 -9
- package/{compability.test.js → compatibility.test.js} +42 -18
- package/package.json +1 -1
- package/types.d.ts +4 -3
- package/userAgent.d.ts +0 -2
- package/userAgent.js +0 -2
- /package/{compability.test.d.ts → compatibility.test.d.ts} +0 -0
package/CidButton.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import './CidButton.css';
|
|
2
2
|
import './global.css';
|
|
3
|
-
import { CertificationStatus, CidButtonLabel, CidButtonSize, CidButtonTheme, CidButtonType, Claim, CompatibilityWarnings, IntroTextType, LogoMode, RequiredCertification } from './types';
|
|
3
|
+
import { Browser, CertificationStatus, CidButtonLabel, CidButtonSize, CidButtonTheme, CidButtonType, Claim, CompatibilityWarnings, IntroTextType, LogoMode, RequiredCertification } from './types';
|
|
4
4
|
type CidButtonProps = {
|
|
5
5
|
onProceed: (authorisationServerId: string, compatibilityWarnings: CompatibilityWarnings) => void;
|
|
6
6
|
claims: Claim[];
|
|
@@ -22,10 +22,12 @@ type CidButtonProps = {
|
|
|
22
22
|
showInfoContent?: boolean;
|
|
23
23
|
onError?: (error: string) => void;
|
|
24
24
|
showCompatibilityWarnings?: boolean;
|
|
25
|
+
supportIncognito?: boolean;
|
|
25
26
|
forceMobile?: boolean;
|
|
26
27
|
forceIos?: boolean;
|
|
27
28
|
forceAndroid?: boolean;
|
|
28
29
|
forceIncognito?: boolean;
|
|
30
|
+
forceBrowser?: Browser;
|
|
29
31
|
};
|
|
30
32
|
export declare const CidButton: React.FC<CidButtonProps>;
|
|
31
33
|
export {};
|
package/CidButton.js
CHANGED
|
@@ -27,13 +27,14 @@ import './global.css';
|
|
|
27
27
|
import { getCurrentUrlOrigin } from './navigator';
|
|
28
28
|
import { isIntroTextTypeValid, isRequiredClaimsValid } from './validator';
|
|
29
29
|
import detectIncognito from './incognito';
|
|
30
|
-
import { getDeviceType, isAndroid,
|
|
30
|
+
import { getBrowserName, getDeviceType, isAndroid, isIos } 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 = () => { }, showCompatibilityWarnings = false, 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
|
|
37
|
+
forceBrowser = undefined, // only for testing purposes
|
|
37
38
|
}) => {
|
|
38
39
|
const { data: participants, error, isLoading, } = useSWR(participantsUri, () => __awaiter(void 0, void 0, void 0, function* () {
|
|
39
40
|
const response = yield fetch(participantsUri);
|
|
@@ -131,13 +132,13 @@ forceIncognito = false, // only for testing purposes
|
|
|
131
132
|
const isMobile = forceMobile || getDeviceType() === 'mobile';
|
|
132
133
|
const idpHasAppCertification = hasCertification(authorisationServerCertifications, 'Channel', 'app');
|
|
133
134
|
const compatibility = getCompatibility({
|
|
135
|
+
supportIncognito,
|
|
134
136
|
idpHasAppCertification,
|
|
135
137
|
isMobile,
|
|
136
138
|
isIncognito: forceIncognito || !!isIncognito,
|
|
137
139
|
isAndroid: forceAndroid || isAndroid(),
|
|
138
140
|
isIos: forceIos || isIos(),
|
|
139
|
-
|
|
140
|
-
isChromeBrowser: isChromeBrowser(),
|
|
141
|
+
browser: forceBrowser || getBrowserName(),
|
|
141
142
|
});
|
|
142
143
|
if (showCompatibilityWarnings && compatibility.mightFail) {
|
|
143
144
|
const confirmText = getCompatibilityConfirmText(compatibility);
|
package/README.md
CHANGED
|
@@ -29,28 +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
|
|
53
|
-
| showCompatibilityWarnings |
|
|
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 |
|
|
54
55
|
|
|
55
56
|
#### CompatibilityWarnings type
|
|
56
57
|
|
|
@@ -70,6 +71,12 @@ It returns information about the compatibility of the user's browser and device
|
|
|
70
71
|
- `mobileOs`: The operating system of the mobile device, if applicable.
|
|
71
72
|
- `browser`: The browser being used by the user.
|
|
72
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
|
+
|
|
73
80
|
#### certificationStatus values
|
|
74
81
|
|
|
75
82
|
- `Active`: only IDPs with active certification
|
|
@@ -252,6 +259,12 @@ The SVG image below the ConnectID button has either option dark or light mode. B
|
|
|
252
259
|
|
|
253
260
|
## 🚀 Release Notes
|
|
254
261
|
|
|
262
|
+
### 6.10.0-alpha.4 (Jun 20, 2025)
|
|
263
|
+
- Add test support for Samsung and Chrome browsers.
|
|
264
|
+
|
|
265
|
+
### 6.10.0-alpha.3 (Jun 20, 2025)
|
|
266
|
+
- Add `supportIncognito` option.
|
|
267
|
+
|
|
255
268
|
### 6.10.0-alpha.2 (Jun 17, 2025)
|
|
256
269
|
- Add `showCompatibilityWarnings` option.
|
|
257
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" | "
|
|
3
|
+
export declare const getMightFail: (env: Pick<CompatibilityEnvironment, "supportIncognito" | "idpHasAppCertification" | "isMobile" | "isIncognito" | "isAndroid" | "isIos" | "browser">) => boolean;
|
package/compatibility.js
CHANGED
|
@@ -1,35 +1,34 @@
|
|
|
1
|
-
import { getBrowserName } from './userAgent';
|
|
2
1
|
export const getCompatibility = (env) => {
|
|
3
|
-
const { idpHasAppCertification, isAndroid,
|
|
2
|
+
const { supportIncognito, idpHasAppCertification, isAndroid, isIncognito, isMobile, isIos, browser } = env;
|
|
4
3
|
const mightFail = getMightFail({
|
|
4
|
+
supportIncognito,
|
|
5
5
|
idpHasAppCertification,
|
|
6
6
|
isMobile,
|
|
7
7
|
isIncognito,
|
|
8
8
|
isAndroid,
|
|
9
9
|
isIos,
|
|
10
|
-
|
|
11
|
-
isChromeBrowser,
|
|
10
|
+
browser
|
|
12
11
|
});
|
|
13
12
|
return {
|
|
14
13
|
isMobile,
|
|
15
14
|
isIncognito,
|
|
16
15
|
mobileOs: isAndroid ? 'android' : isIos ? 'ios' : 'other',
|
|
17
|
-
browser
|
|
16
|
+
browser,
|
|
18
17
|
mightFail,
|
|
19
18
|
};
|
|
20
19
|
};
|
|
21
20
|
export const getMightFail = (env) => {
|
|
22
|
-
const { idpHasAppCertification, isMobile, isIncognito, isAndroid,
|
|
21
|
+
const { supportIncognito, idpHasAppCertification, isMobile, isIncognito, isAndroid, isIos, browser } = env;
|
|
23
22
|
if (!idpHasAppCertification || !isMobile) {
|
|
24
23
|
return false;
|
|
25
24
|
}
|
|
26
|
-
if (isIncognito && isAndroid &&
|
|
25
|
+
if (!supportIncognito && isIncognito && isAndroid && browser === 'chrome') {
|
|
27
26
|
return true;
|
|
28
27
|
}
|
|
29
|
-
if (isAndroid &&
|
|
28
|
+
if (isAndroid && browser === 'samsung') {
|
|
30
29
|
return true;
|
|
31
30
|
}
|
|
32
|
-
if (isIncognito && isIos) {
|
|
31
|
+
if (!supportIncognito && isIncognito && isIos) {
|
|
33
32
|
return true;
|
|
34
33
|
}
|
|
35
34
|
return false;
|
|
@@ -4,93 +4,117 @@ 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,
|
|
10
11
|
isAndroid: false,
|
|
11
12
|
isIos: false,
|
|
12
|
-
|
|
13
|
-
isChromeBrowser: false,
|
|
13
|
+
browser: 'other',
|
|
14
14
|
});
|
|
15
15
|
assert.deepStrictEqual(compatibility, {
|
|
16
16
|
isMobile: true,
|
|
17
17
|
isIncognito: false,
|
|
18
18
|
mobileOs: 'other',
|
|
19
19
|
browser: 'other',
|
|
20
|
-
mightFail: false
|
|
20
|
+
mightFail: false,
|
|
21
21
|
});
|
|
22
22
|
});
|
|
23
23
|
});
|
|
24
24
|
describe('getMightFail', () => {
|
|
25
25
|
it('should return false when idpHasAppCertification is false', () => {
|
|
26
26
|
const mightFail = getMightFail({
|
|
27
|
+
supportIncognito: false,
|
|
27
28
|
idpHasAppCertification: false,
|
|
28
29
|
isMobile: true,
|
|
29
30
|
isIncognito: false,
|
|
30
31
|
isAndroid: false,
|
|
31
32
|
isIos: false,
|
|
32
|
-
|
|
33
|
-
isChromeBrowser: false,
|
|
33
|
+
browser: 'other',
|
|
34
34
|
});
|
|
35
35
|
assert.ok(mightFail === false);
|
|
36
36
|
});
|
|
37
37
|
it('should return false when isMobile is false', () => {
|
|
38
38
|
const mightFail = getMightFail({
|
|
39
|
+
supportIncognito: false,
|
|
39
40
|
idpHasAppCertification: true,
|
|
40
41
|
isMobile: false,
|
|
41
42
|
isIncognito: false,
|
|
42
43
|
isAndroid: false,
|
|
43
44
|
isIos: false,
|
|
44
|
-
|
|
45
|
-
isChromeBrowser: false,
|
|
45
|
+
browser: 'other',
|
|
46
46
|
});
|
|
47
47
|
assert.ok(mightFail === false);
|
|
48
48
|
});
|
|
49
|
-
it('should return true when
|
|
49
|
+
it('should return true when does not support incognito and settings are incognito/android/chrome', () => {
|
|
50
50
|
const mightFail = getMightFail({
|
|
51
|
+
supportIncognito: false,
|
|
51
52
|
idpHasAppCertification: true,
|
|
52
53
|
isMobile: true,
|
|
53
54
|
isIncognito: true,
|
|
54
55
|
isAndroid: true,
|
|
55
56
|
isIos: false,
|
|
56
|
-
|
|
57
|
-
isChromeBrowser: true,
|
|
57
|
+
browser: 'chrome',
|
|
58
58
|
});
|
|
59
59
|
assert.ok(mightFail === true);
|
|
60
60
|
});
|
|
61
|
-
it('should return
|
|
61
|
+
it('should return false when supports incognito and settings are incognito/android/chrome', () => {
|
|
62
|
+
const mightFail = getMightFail({
|
|
63
|
+
supportIncognito: true,
|
|
64
|
+
idpHasAppCertification: true,
|
|
65
|
+
isMobile: true,
|
|
66
|
+
isIncognito: true,
|
|
67
|
+
isAndroid: true,
|
|
68
|
+
isIos: false,
|
|
69
|
+
browser: 'chrome',
|
|
70
|
+
});
|
|
71
|
+
assert.ok(mightFail === false);
|
|
72
|
+
});
|
|
73
|
+
it('should return true when android/samsung', () => {
|
|
62
74
|
const mightFail = getMightFail({
|
|
75
|
+
supportIncognito: false,
|
|
63
76
|
idpHasAppCertification: true,
|
|
64
77
|
isMobile: true,
|
|
65
78
|
isIncognito: false,
|
|
66
79
|
isAndroid: true,
|
|
67
80
|
isIos: false,
|
|
68
|
-
|
|
69
|
-
isChromeBrowser: false,
|
|
81
|
+
browser: 'samsung',
|
|
70
82
|
});
|
|
71
83
|
assert.ok(mightFail === true);
|
|
72
84
|
});
|
|
73
|
-
it('should return true when
|
|
85
|
+
it('should return true when does not support incognito and settings are incognito/ios', () => {
|
|
74
86
|
const mightFail = getMightFail({
|
|
87
|
+
supportIncognito: false,
|
|
75
88
|
idpHasAppCertification: true,
|
|
76
89
|
isMobile: true,
|
|
77
90
|
isIncognito: true,
|
|
78
91
|
isAndroid: false,
|
|
79
92
|
isIos: true,
|
|
80
|
-
|
|
81
|
-
isChromeBrowser: false,
|
|
93
|
+
browser: 'safari',
|
|
82
94
|
});
|
|
83
95
|
assert.ok(mightFail === true);
|
|
84
96
|
});
|
|
97
|
+
it('should return false when supports incognito and settings are incognito/ios', () => {
|
|
98
|
+
const mightFail = getMightFail({
|
|
99
|
+
supportIncognito: true,
|
|
100
|
+
idpHasAppCertification: true,
|
|
101
|
+
isMobile: true,
|
|
102
|
+
isIncognito: true,
|
|
103
|
+
isAndroid: false,
|
|
104
|
+
isIos: true,
|
|
105
|
+
browser: 'safari',
|
|
106
|
+
});
|
|
107
|
+
assert.ok(mightFail === false);
|
|
108
|
+
});
|
|
85
109
|
it('should return false when none of the conditions are met', () => {
|
|
86
110
|
const mightFail = getMightFail({
|
|
111
|
+
supportIncognito: false,
|
|
87
112
|
idpHasAppCertification: true,
|
|
88
113
|
isMobile: true,
|
|
89
114
|
isIncognito: false,
|
|
90
115
|
isAndroid: false,
|
|
91
116
|
isIos: false,
|
|
92
|
-
|
|
93
|
-
isChromeBrowser: false,
|
|
117
|
+
browser: 'other',
|
|
94
118
|
});
|
|
95
119
|
assert.ok(mightFail === false);
|
|
96
120
|
});
|
package/package.json
CHANGED
package/types.d.ts
CHANGED
|
@@ -38,19 +38,20 @@ export type CidButtonTypeConfig = {
|
|
|
38
38
|
hasHowItWorks: boolean;
|
|
39
39
|
hasLearnMore: boolean;
|
|
40
40
|
};
|
|
41
|
+
export type Browser = 'chrome' | 'samsung' | 'safari' | 'firefox' | 'other';
|
|
41
42
|
export type CompatibilityEnvironment = {
|
|
43
|
+
supportIncognito: boolean;
|
|
42
44
|
isMobile: boolean;
|
|
43
45
|
isIncognito: boolean;
|
|
44
46
|
idpHasAppCertification: boolean;
|
|
45
47
|
isAndroid: boolean;
|
|
46
48
|
isIos: boolean;
|
|
47
|
-
|
|
48
|
-
isChromeBrowser: boolean;
|
|
49
|
+
browser: Browser;
|
|
49
50
|
};
|
|
50
51
|
export type CompatibilityWarnings = {
|
|
51
52
|
mightFail: boolean;
|
|
52
53
|
isMobile: boolean;
|
|
53
54
|
isIncognito: boolean;
|
|
54
55
|
mobileOs: 'android' | 'ios' | 'other';
|
|
55
|
-
browser:
|
|
56
|
+
browser: Browser;
|
|
56
57
|
};
|
package/userAgent.d.ts
CHANGED
|
@@ -2,6 +2,4 @@ import { Device } from './types';
|
|
|
2
2
|
export declare const getDeviceType: () => Device;
|
|
3
3
|
export declare const isAndroid: () => boolean;
|
|
4
4
|
export declare const isIos: () => boolean;
|
|
5
|
-
export declare const isChromeBrowser: () => boolean;
|
|
6
|
-
export declare const isSamsungBrowser: () => boolean;
|
|
7
5
|
export declare const getBrowserName: () => "other" | "chrome" | "samsung" | "safari" | "firefox";
|
package/userAgent.js
CHANGED
|
@@ -10,8 +10,6 @@ export const getDeviceType = () => {
|
|
|
10
10
|
};
|
|
11
11
|
export const isAndroid = () => /Android/i.test(navigator.userAgent);
|
|
12
12
|
export const isIos = () => /iPhone|iPad|iPod/i.test(navigator.userAgent);
|
|
13
|
-
export const isChromeBrowser = () => /Chrome/.test(navigator.userAgent) && !/Edg|OPR|Brave/.test(navigator.userAgent);
|
|
14
|
-
export const isSamsungBrowser = () => /SamsungBrowser/.test(navigator.userAgent);
|
|
15
13
|
export const getBrowserName = () => {
|
|
16
14
|
const ua = navigator.userAgent.toLowerCase();
|
|
17
15
|
if (ua.includes('samsungbrowser')) {
|
|
File without changes
|