Skip to content

Commit 390541a

Browse files
authored
Merge pull request #211 from wwWallet/insufficient-creds
handling "HandleOutboundRequestError" type of errors
2 parents c10e145 + 4bdcbc7 commit 390541a

File tree

4 files changed

+88
-7
lines changed

4 files changed

+88
-7
lines changed

src/App.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ const PrivateRoute = React.lazy(() => import('./components/PrivateRoute'));
2323
const CredentialDetail = React.lazy(() => import('./pages/Home/CredentialDetail'));
2424
const SelectCredentialsPopup = React.lazy(() => import('./components/Popups/SelectCredentials'));
2525
const PinInputPopup = React.lazy(() => import('./components/Popups/PinInput'));
26+
const MessagePopup = React.lazy(() => import('./components/Popups/MessagePopup'));
2627
const VerificationResult = React.lazy(() => import('./pages/VerificationResult/VerificationResult'));
2728

2829

@@ -51,7 +52,11 @@ function App() {
5152
conformantCredentialsMap,
5253
showPinInputPopup,
5354
setShowPinInputPopup,
54-
verifierDomainName
55+
verifierDomainName,
56+
showMessagePopup,
57+
setMessagePopup,
58+
textMessagePopup,
59+
typeMessagePopup,
5560
} = useCheckURL(url);
5661

5762
useEffect(() => {
@@ -99,6 +104,9 @@ function App() {
99104
{showPinInputPopup &&
100105
<PinInputPopup showPopup={showPinInputPopup} setShowPopup={setShowPinInputPopup} />
101106
}
107+
{showMessagePopup &&
108+
<MessagePopup type={typeMessagePopup} message={textMessagePopup} onClose={() => setMessagePopup(false)} />
109+
}
102110
</HandlerNotification>
103111
</Suspense>
104112
</Router>

src/components/Popups/MessagePopup.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// MessagePopup.js
2+
import React from 'react';
3+
import { FaCheckCircle, FaExclamationCircle } from 'react-icons/fa';
4+
import { useTranslation } from 'react-i18next';
5+
6+
const MessagePopup = ({ type, message, onClose }) => {
7+
const { title, description } = message || {};
8+
const { t } = useTranslation();
9+
10+
const IconComponent = type === 'error' ? FaExclamationCircle : FaCheckCircle;
11+
12+
const titleColor = type === 'error' ? 'text-red-500' : 'text-green-600';
13+
14+
return (
15+
<div className="fixed inset-0 flex items-center justify-center z-50">
16+
<div className="absolute inset-0 bg-black opacity-50" onClick={() => onClose()}></div>
17+
18+
<div className="bg-white p-4 rounded-lg shadow-lg w-full lg:w-[33.33%] sm:w-[66.67%] z-10 relative m-4">
19+
<div className="flex items-start justify-between border-b rounded-t dark:border-gray-600">
20+
21+
<h2 className={`text-lg font-bold mb-2 flex items-center ${titleColor}`}>
22+
<IconComponent size={20} className="inline mr-1" />
23+
{title}
24+
</h2>
25+
<button type="button" className="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ml-auto inline-flex justify-center items-center dark:hover:bg-gray-600 dark:hover:text-white" onClick={() => onClose()}>
26+
<svg className="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14">
27+
<path stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6" />
28+
</svg>
29+
</button>
30+
</div>
31+
<hr className="mb-2 border-t border-custom-blue/80" />
32+
<p className="mb-2 mt-4">
33+
{description}
34+
</p>
35+
<div className="flex justify-end space-x-2 pt-4">
36+
<button
37+
type="button"
38+
className="px-4 py-2 text-white bg-gray-500 hover:bg-gray-600 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-gray-300 dark:hover:bg-gray-400"
39+
onClick={onClose}
40+
>
41+
{t('messagePopup.close')}
42+
</button>
43+
</div>
44+
</div>
45+
</div>
46+
);
47+
};
48+
49+
export default MessagePopup;

src/components/useCheckURL.ts

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import { useEffect, useState, Dispatch, SetStateAction } from 'react';
22
import { useApi } from '../api';
33
import { useLocalStorageKeystore } from '../services/LocalStorageKeystore';
4+
import { useTranslation } from 'react-i18next';
45

6+
export enum HandleOutboundRequestError {
7+
INSUFFICIENT_CREDENTIALS = "INSUFFICIENT_CREDENTIALS",
8+
}
59

610
function useCheckURL(urlToCheck: string): {
711
showSelectCredentialsPopup: boolean,
@@ -10,7 +14,11 @@ function useCheckURL(urlToCheck: string): {
1014
conformantCredentialsMap: any,
1115
showPinInputPopup: boolean,
1216
setShowPinInputPopup: Dispatch<SetStateAction<boolean>>,
13-
verifierDomainName: string
17+
verifierDomainName: string,
18+
showMessagePopup: boolean;
19+
setMessagePopup: Dispatch<SetStateAction<boolean>>;
20+
textMessagePopup: { title: string, description: string };
21+
typeMessagePopup: string;
1422
} {
1523
const api = useApi();
1624
const isLoggedIn: boolean = api.isLoggedIn();
@@ -19,8 +27,11 @@ function useCheckURL(urlToCheck: string): {
1927
const [selectionMap, setSelectionMap] = useState<string | null>(null);
2028
const [conformantCredentialsMap, setConformantCredentialsMap] = useState(null);
2129
const [verifierDomainName, setVerifierDomainName] = useState("");
22-
30+
const [showMessagePopup, setMessagePopup] = useState<boolean>(false);
31+
const [textMessagePopup, setTextMessagePopup] = useState<{ title: string, description: string }>({ title: "", description: "" });
32+
const [typeMessagePopup, setTypeMessagePopup] = useState<string>("");
2333
const keystore = useLocalStorageKeystore();
34+
const { t } = useTranslation();
2435

2536
useEffect(() => {
2637

@@ -29,8 +40,14 @@ function useCheckURL(urlToCheck: string): {
2940
const wwwallet_camera_was_used = new URL(url).searchParams.get('wwwallet_camera_was_used');
3041

3142
const res = await api.post('/communication/handle', { url, camera_was_used: (wwwallet_camera_was_used != null && wwwallet_camera_was_used === 'true') });
32-
const { redirect_to, conformantCredentialsMap, verifierDomainName, preauth, ask_for_pin } = res.data;
33-
43+
const { redirect_to, conformantCredentialsMap, verifierDomainName, preauth, ask_for_pin, error } = res.data;
44+
if (error && error == HandleOutboundRequestError.INSUFFICIENT_CREDENTIALS) {
45+
console.error(`${HandleOutboundRequestError.INSUFFICIENT_CREDENTIALS}`);
46+
setTextMessagePopup({ title: `${t('messagePopup.insufficientCredentials.title')}`, description: `${t('messagePopup.insufficientCredentials.description')}` });
47+
setTypeMessagePopup('error');
48+
setMessagePopup(true);
49+
return false;
50+
}
3451
if (preauth && preauth == true) {
3552
if (ask_for_pin) {
3653
setShowPinInputPopup(true);
@@ -65,7 +82,7 @@ function useCheckURL(urlToCheck: string): {
6582

6683
if (urlToCheck && isLoggedIn && window.location.pathname === "/cb") {
6784
(async () => {
68-
await communicationHandler(urlToCheck);
85+
await communicationHandler(urlToCheck);
6986
})();
7087
}
7188

@@ -89,7 +106,7 @@ function useCheckURL(urlToCheck: string): {
89106
}
90107
}, [api, keystore, selectionMap]);
91108

92-
return {showSelectCredentialsPopup, setShowSelectCredentialsPopup, setSelectionMap, conformantCredentialsMap, showPinInputPopup, setShowPinInputPopup, verifierDomainName };
109+
return { showSelectCredentialsPopup, setShowSelectCredentialsPopup, setSelectionMap, conformantCredentialsMap, showPinInputPopup, setShowPinInputPopup, verifierDomainName, showMessagePopup, setMessagePopup, textMessagePopup, typeMessagePopup };
93110
}
94111

95112
export default useCheckURL;

src/locales/en.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,13 @@
7878
"weakPasswordError": "Weak password",
7979
"welcomeMessage": "Welcome to <highlight>wwWallet</highlight>"
8080
},
81+
"messagePopup": {
82+
"close": "Close",
83+
"insufficientCredentials": {
84+
"title": "Insufficient Credentials",
85+
"description": "One or more of the credentials you want to present do not exist for selection."
86+
}
87+
},
8188
"notFound": {
8289
"homeButton": "Back to Home",
8390
"message": "Sorry, the page you're looking for cannot be accessed",

0 commit comments

Comments
 (0)