From e4e6f5b39bd12733035837506065c83561fc0f6d Mon Sep 17 00:00:00 2001 From: Diego Lavayen Alarcon Date: Thu, 14 Apr 2022 11:31:13 +0100 Subject: [PATCH 1/4] feat: implement basic authentication with firebase: - Components for signing up, signing in and signing out - firebase configuration settings - protected components bases on authentication --- .env | 7 + package-lock.json | 832 +++++++++++++++++++++++++ package.json | 1 + src/App.js | 8 +- src/components/AuthenticationMethod.js | 29 + src/components/Header.js | 16 + src/components/SignIn.js | 49 ++ src/components/SignOut.js | 13 + src/components/SignUp.js | 62 ++ src/components/TaskForm.js | 4 +- src/firebase.js | 12 + src/hooks/useForm.js | 20 + src/hooks/useInput.js | 17 - src/providers/Authentication.js | 46 ++ 14 files changed, 1094 insertions(+), 22 deletions(-) create mode 100644 src/components/AuthenticationMethod.js create mode 100644 src/components/Header.js create mode 100644 src/components/SignIn.js create mode 100644 src/components/SignOut.js create mode 100644 src/components/SignUp.js create mode 100644 src/firebase.js create mode 100644 src/hooks/useForm.js delete mode 100644 src/hooks/useInput.js create mode 100644 src/providers/Authentication.js diff --git a/.env b/.env index 50bf507..c7db42e 100644 --- a/.env +++ b/.env @@ -1 +1,8 @@ REACT_APP_API_ENDPOINT=https://jsonplaceholder.typicode.com/todos + +REACT_APP_apiKey=AIzaSyAj85Ywt-FIO87x5KPw_HJZCvsx0CEESmg +REACT_APP_authDomain=oct-2021-8d609.firebaseapp.com +REACT_APP_projectId=oct-2021-8d609 +REACT_APP_storageBucket=oct-2021-8d609.appspot.com +REACT_APP_messagingSenderId=743275450929 +REACT_APP_appId=1:743275450929:web:e37fef7d55cd22456efb10 diff --git a/package-lock.json b/package-lock.json index 0d21fd1..ed491a7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1351,6 +1351,613 @@ } } }, + "@firebase/analytics": { + "version": "0.7.7", + "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.7.7.tgz", + "integrity": "sha512-duzzyDmBSF2ql6lp0m2jxmOH5PIgw0utqSXRjSgoYzD7lURncMAZVC2u3IgsAoUNTW/lcBSHpv+t4lnxTCNMCw==", + "requires": { + "@firebase/component": "0.5.12", + "@firebase/installations": "0.5.7", + "@firebase/logger": "0.3.2", + "@firebase/util": "1.5.1", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/analytics-compat": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.1.8.tgz", + "integrity": "sha512-2XBPTFD4DPVZUJZ2tPOib7BfyHB/Ucfq3DfYMNRZFUrgctABTO/lRwjm3oqv4EsoqEOlbxRurvfFN8BQEe28LA==", + "requires": { + "@firebase/analytics": "0.7.7", + "@firebase/analytics-types": "0.7.0", + "@firebase/component": "0.5.12", + "@firebase/util": "1.5.1", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/analytics-types": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.7.0.tgz", + "integrity": "sha512-DNE2Waiwy5+zZnCfintkDtBfaW6MjIG883474v6Z0K1XZIvl76cLND4iv0YUb48leyF+PJK1KO2XrgHb/KpmhQ==" + }, + "@firebase/app": { + "version": "0.7.20", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.7.20.tgz", + "integrity": "sha512-tTVrEYCbEKBcMp/bj5rUa35iM32W5z9l3jbLAqDh0ZM2yO4JvF08a3hHacZ32XDh9Av/yCgla0QmVPp/Z2klNg==", + "requires": { + "@firebase/component": "0.5.12", + "@firebase/logger": "0.3.2", + "@firebase/util": "1.5.1", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/app-check": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.5.5.tgz", + "integrity": "sha512-thGjl8Ys2VFKitUUM/xqkXXV8GS56yUdOBMpsjpTSH5iwa49dSBUTGzbwmUMARSkiSF+AzcjNonO6LQczTU/AA==", + "requires": { + "@firebase/component": "0.5.12", + "@firebase/logger": "0.3.2", + "@firebase/util": "1.5.1", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/app-check-compat": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.2.5.tgz", + "integrity": "sha512-W1jGGcXXw1sdFia3qqnhlkg/5aQGiV6lAurq0FxfMXiV+qUxVuQ2roRbkJrcuJ3jxth8OGOir/yxOk/4YwkfHA==", + "requires": { + "@firebase/app-check": "0.5.5", + "@firebase/app-check-types": "0.4.0", + "@firebase/component": "0.5.12", + "@firebase/logger": "0.3.2", + "@firebase/util": "1.5.1", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/app-check-interop-types": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.1.0.tgz", + "integrity": "sha512-uZfn9s4uuRsaX5Lwx+gFP3B6YsyOKUE+Rqa6z9ojT4VSRAsZFko9FRn6OxQUA1z5t5d08fY4pf+/+Dkd5wbdbA==" + }, + "@firebase/app-check-types": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@firebase/app-check-types/-/app-check-types-0.4.0.tgz", + "integrity": "sha512-SsWafqMABIOu7zLgWbmwvHGOeQQVQlwm42kwwubsmfLmL4Sf5uGpBfDhQ0CAkpi7bkJ/NwNFKafNDL9prRNP0Q==" + }, + "@firebase/app-compat": { + "version": "0.1.21", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.1.21.tgz", + "integrity": "sha512-zKRjOt6JXZ6gBdl3ELdjvEQ7cdrsrCjLEaLttBxioqW9VxXZfBOgP38uUb0baJk2XNEUA6YWM+H/bg1y+FGFYA==", + "requires": { + "@firebase/app": "0.7.20", + "@firebase/component": "0.5.12", + "@firebase/logger": "0.3.2", + "@firebase/util": "1.5.1", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/app-types": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.7.0.tgz", + "integrity": "sha512-6fbHQwDv2jp/v6bXhBw2eSRbNBpxHcd1NBF864UksSMVIqIyri9qpJB1Mn6sGZE+bnDsSQBC5j2TbMxYsJQkQg==" + }, + "@firebase/auth": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-0.19.11.tgz", + "integrity": "sha512-9bctXmQA5pRhLL03wkbg6ibmhoTMa8QRHm3uDnb+iyMcHTJ5AyILRc5AVPS9FsnpWPDOLiVjtuMC28D6iC+zew==", + "requires": { + "@firebase/component": "0.5.12", + "@firebase/logger": "0.3.2", + "@firebase/util": "1.5.1", + "node-fetch": "2.6.7", + "selenium-webdriver": "4.0.0-rc-1", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/auth-compat": { + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.2.11.tgz", + "integrity": "sha512-6C42yXevri3F7H1LS3h524UsQsUlzGuszlIL3YsDuS+WJFqBe8I5AHOEM+Opi/VtIpWaXxPhWsp75TQndaCjKA==", + "requires": { + "@firebase/auth": "0.19.11", + "@firebase/auth-types": "0.11.0", + "@firebase/component": "0.5.12", + "@firebase/util": "1.5.1", + "node-fetch": "2.6.7", + "selenium-webdriver": "^4.0.0-beta.2", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/auth-interop-types": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.1.6.tgz", + "integrity": "sha512-etIi92fW3CctsmR9e3sYM3Uqnoq861M0Id9mdOPF6PWIg38BXL5k4upCNBggGUpLIS0H1grMOvy/wn1xymwe2g==" + }, + "@firebase/auth-types": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.11.0.tgz", + "integrity": "sha512-q7Bt6cx+ySj9elQHTsKulwk3+qDezhzRBFC9zlQ1BjgMueUOnGMcvqmU0zuKlQ4RhLSH7MNAdBV2znVaoN3Vxw==" + }, + "@firebase/component": { + "version": "0.5.12", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.5.12.tgz", + "integrity": "sha512-gAKwxo0Ev+rp7Px+Yr71WbcC0CM9Tevhv0g38ORp2p57HqGjY65D3MD+jTKGZl58N/0nmX6MRRKym3bq/3k1gw==", + "requires": { + "@firebase/util": "1.5.1", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/database": { + "version": "0.12.7", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.12.7.tgz", + "integrity": "sha512-HL2NMQ3Ce5YNM2MdEuACHmU9NQEwq2F64R0XK+CReph40skxp+A7TvlJDO5bTAC0s3l3ebgCA9VmxfJu5R6UAA==", + "requires": { + "@firebase/auth-interop-types": "0.1.6", + "@firebase/component": "0.5.12", + "@firebase/logger": "0.3.2", + "@firebase/util": "1.5.1", + "faye-websocket": "0.11.4", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/database-compat": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-0.1.7.tgz", + "integrity": "sha512-T1mleRv2A8wyTV/jUuOdkN9Tl2lz0RGauqGc9nxP3AUzS9m3gIDN7u4CahZSdJlkR6tSU/MEWlfs5Q/oZStqxg==", + "requires": { + "@firebase/component": "0.5.12", + "@firebase/database": "0.12.7", + "@firebase/database-types": "0.9.6", + "@firebase/logger": "0.3.2", + "@firebase/util": "1.5.1", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/database-types": { + "version": "0.9.6", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.9.6.tgz", + "integrity": "sha512-E7U28X+FtVtug7EkIkaOXbdP8ghCPno21WWgEiDKsneY28N5WOwccfXqSzHgAAezkR40ht/ZqXlCsUhEpv6JXw==", + "requires": { + "@firebase/app-types": "0.7.0", + "@firebase/util": "1.5.1" + } + }, + "@firebase/firestore": { + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-3.4.7.tgz", + "integrity": "sha512-bE8k72cw0zJKOsKTOeRp2As0nNZIv3To9qQe0mTtHu4O8dSdst6izSXixZEXDOuMf/dp7VOY8+VBW/ZqeqWQsA==", + "requires": { + "@firebase/component": "0.5.12", + "@firebase/logger": "0.3.2", + "@firebase/util": "1.5.1", + "@firebase/webchannel-wrapper": "0.6.1", + "@grpc/grpc-js": "^1.3.2", + "@grpc/proto-loader": "^0.6.0", + "node-fetch": "2.6.7", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/firestore-compat": { + "version": "0.1.16", + "resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.1.16.tgz", + "integrity": "sha512-nLSBYGTkcGDbNFHBBMl74e7gwNo++BDTALlWNBaYRjTNj0TctYt8q4lggNy+MxXRQhP+dZjq/mrClS9T8RJZ4g==", + "requires": { + "@firebase/component": "0.5.12", + "@firebase/firestore": "3.4.7", + "@firebase/firestore-types": "2.5.0", + "@firebase/util": "1.5.1", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/firestore-types": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-2.5.0.tgz", + "integrity": "sha512-I6c2m1zUhZ5SH0cWPmINabDyH5w0PPFHk2UHsjBpKdZllzJZ2TwTkXbDtpHUZNmnc/zAa0WNMNMvcvbb/xJLKA==" + }, + "@firebase/functions": { + "version": "0.7.10", + "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.7.10.tgz", + "integrity": "sha512-d+8M6RENmrF2/Y2J+V3fuad6Vq8aiwEzeJCl5sdUA4TydAnAPmGPaEz7uEyaxp8gIx/j373CZy2jTuI3PCxEyw==", + "requires": { + "@firebase/app-check-interop-types": "0.1.0", + "@firebase/auth-interop-types": "0.1.6", + "@firebase/component": "0.5.12", + "@firebase/messaging-interop-types": "0.1.0", + "@firebase/util": "1.5.1", + "node-fetch": "2.6.7", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/functions-compat": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.1.11.tgz", + "integrity": "sha512-4U3BU4hOPAhG5YKpLAY/qKhNxsEn4yWSJHLc83H81Y75o2jSsyVklFR2bZNHl0qfq6A7KwUbL8HU48qLbhPlGg==", + "requires": { + "@firebase/component": "0.5.12", + "@firebase/functions": "0.7.10", + "@firebase/functions-types": "0.5.0", + "@firebase/util": "1.5.1", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/functions-types": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.5.0.tgz", + "integrity": "sha512-qza0M5EwX+Ocrl1cYI14zoipUX4gI/Shwqv0C1nB864INAD42Dgv4v94BCyxGHBg2kzlWy8PNafdP7zPO8aJQA==" + }, + "@firebase/installations": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.5.7.tgz", + "integrity": "sha512-qt6crxYyzUc19OYmNunOilcPUrVd+g0VJ42C3+clFJXsYzHey9xfr4q+5vALTJKLXbsX3QPzqEFEpe37sGSRRQ==", + "requires": { + "@firebase/component": "0.5.12", + "@firebase/util": "1.5.1", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/logger": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.3.2.tgz", + "integrity": "sha512-lzLrcJp9QBWpo40OcOM9B8QEtBw2Fk1zOZQdvv+rWS6gKmhQBCEMc4SMABQfWdjsylBcDfniD1Q+fUX1dcBTXA==", + "requires": { + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/messaging": { + "version": "0.9.11", + "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.9.11.tgz", + "integrity": "sha512-AdUvAz3S6fAhGlaP0gAT83vuuLtieXzr8TKjEeREbz/cJHx3DKZuDPK1RVElQos0ACc5kFtSJrKlEa8N2rdYjQ==", + "requires": { + "@firebase/component": "0.5.12", + "@firebase/installations": "0.5.7", + "@firebase/messaging-interop-types": "0.1.0", + "@firebase/util": "1.5.1", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/messaging-compat": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.1.11.tgz", + "integrity": "sha512-icqaH66Fdn1704WRnF3NxPuDYA7SQTJv1klDuN2/LZi029w2jd9j7Tkld2egcwDgF2IrIIgxdCTRcwFZQIG2kQ==", + "requires": { + "@firebase/component": "0.5.12", + "@firebase/messaging": "0.9.11", + "@firebase/util": "1.5.1", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/messaging-interop-types": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@firebase/messaging-interop-types/-/messaging-interop-types-0.1.0.tgz", + "integrity": "sha512-DbvUl/rXAZpQeKBnwz0NYY5OCqr2nFA0Bj28Fmr3NXGqR4PAkfTOHuQlVtLO1Nudo3q0HxAYLa68ZDAcuv2uKQ==" + }, + "@firebase/performance": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.5.7.tgz", + "integrity": "sha512-V8dIYqCr+STiwY09JRPlRo1X59nwpT+s5gy34pdF4DNe/9Ck2XN0WkzDRb1oYwRtMl1cvWwLktbjtFICp4VYfA==", + "requires": { + "@firebase/component": "0.5.12", + "@firebase/installations": "0.5.7", + "@firebase/logger": "0.3.2", + "@firebase/util": "1.5.1", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/performance-compat": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/@firebase/performance-compat/-/performance-compat-0.1.7.tgz", + "integrity": "sha512-U0kxTs5mhzLM4tEkLCnlThgdJUh43dZQsk3Q9/fhuI4FrI8I2uUhx6BMVnyeiT7O9G4lEmhV3ag3QSmzdw4hzQ==", + "requires": { + "@firebase/component": "0.5.12", + "@firebase/logger": "0.3.2", + "@firebase/performance": "0.5.7", + "@firebase/performance-types": "0.1.0", + "@firebase/util": "1.5.1", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/performance-types": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.1.0.tgz", + "integrity": "sha512-6p1HxrH0mpx+622Ql6fcxFxfkYSBpE3LSuwM7iTtYU2nw91Hj6THC8Bc8z4nboIq7WvgsT/kOTYVVZzCSlXl8w==" + }, + "@firebase/polyfill": { + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@firebase/polyfill/-/polyfill-0.3.36.tgz", + "integrity": "sha512-zMM9oSJgY6cT2jx3Ce9LYqb0eIpDE52meIzd/oe/y70F+v9u1LDqk5kUF5mf16zovGBWMNFmgzlsh6Wj0OsFtg==", + "requires": { + "core-js": "3.6.5", + "promise-polyfill": "8.1.3", + "whatwg-fetch": "2.0.4" + }, + "dependencies": { + "core-js": { + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz", + "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==" + }, + "whatwg-fetch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz", + "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==" + } + } + }, + "@firebase/remote-config": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.3.6.tgz", + "integrity": "sha512-eec1gbwFWslZZKdwC/tAC1cM1cUQSr+beS/uNkevrrC0cOjAJ1xqFPayvd0e2kbjAO2+pbp1Oe0yreORe28Cvg==", + "requires": { + "@firebase/component": "0.5.12", + "@firebase/installations": "0.5.7", + "@firebase/logger": "0.3.2", + "@firebase/util": "1.5.1", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/remote-config-compat": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-compat/-/remote-config-compat-0.1.7.tgz", + "integrity": "sha512-i3qfpqNL1iYRP8JSxorV9vQuReTst/xJ6voEodIiTR/JbTM0pXlQ4E+zlS5Nw+6GzsZUW21cmXwk1Yzz5a0AFQ==", + "requires": { + "@firebase/component": "0.5.12", + "@firebase/logger": "0.3.2", + "@firebase/remote-config": "0.3.6", + "@firebase/remote-config-types": "0.2.0", + "@firebase/util": "1.5.1", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/remote-config-types": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.2.0.tgz", + "integrity": "sha512-hqK5sCPeZvcHQ1D6VjJZdW6EexLTXNMJfPdTwbD8NrXUw6UjWC4KWhLK/TSlL0QPsQtcKRkaaoP+9QCgKfMFPw==" + }, + "@firebase/storage": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.9.4.tgz", + "integrity": "sha512-oDqIIxoGMuchwTDHugDE/ul0h+hFVh7eAmvIWHrchaj0R2BTivb+H5qgszWjlCs2pjHS6waGsnSGJgpBTW4AeA==", + "requires": { + "@firebase/component": "0.5.12", + "@firebase/util": "1.5.1", + "node-fetch": "2.6.7", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/storage-compat": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/@firebase/storage-compat/-/storage-compat-0.1.12.tgz", + "integrity": "sha512-Qa21YWM5AZvRSH8/lmT4r//xdlEP01azt0GHgcX+MkKLi18qpPjgXpxCstVALH4XCKBP0RMaNiIToWIRTdRSxw==", + "requires": { + "@firebase/component": "0.5.12", + "@firebase/storage": "0.9.4", + "@firebase/storage-types": "0.6.0", + "@firebase/util": "1.5.1", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/storage-types": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.6.0.tgz", + "integrity": "sha512-1LpWhcCb1ftpkP/akhzjzeFxgVefs6eMD2QeKiJJUGH1qOiows2w5o0sKCUSQrvrRQS1lz3SFGvNR1Ck/gqxeA==" + }, + "@firebase/util": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.5.1.tgz", + "integrity": "sha512-ojwPg8sKVcoU/kC1QdTrD+eUDyjQkZyiH9tlouXeZdAeDddCYNvHgIeBQhZt62WIcjlNhy1zro/xdV5nUUU38A==", + "requires": { + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/webchannel-wrapper": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.6.1.tgz", + "integrity": "sha512-9FqhNjKQWpQ3fGnSOCovHOm+yhhiorKEqYLAfd525jWavunDJcx8rOW6i6ozAh+FbwcYMkL7b+3j4UR/30MpoQ==" + }, + "@grpc/grpc-js": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.6.3.tgz", + "integrity": "sha512-2B9WnKGowOHvcicX5WOVpA3KlLqm1qfPdd4oFeyzJCT6g8hk6aobBnD7QhqZc8/2e5GU0OGTV4QvvzMdDRAH+w==", + "requires": { + "@grpc/proto-loader": "^0.6.4", + "@types/node": ">=12.12.47" + } + }, + "@grpc/proto-loader": { + "version": "0.6.9", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.9.tgz", + "integrity": "sha512-UlcCS8VbsU9d3XTXGiEVFonN7hXk+oMXZtoHHG2oSA1/GcDP1q6OUgs20PzHDGizzyi8ufGSUDlk3O2NyY7leg==", + "requires": { + "@types/long": "^4.0.1", + "lodash.camelcase": "^4.3.0", + "long": "^4.0.0", + "protobufjs": "^6.10.0", + "yargs": "^16.2.0" + } + }, "@humanwhocodes/config-array": { "version": "0.9.5", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", @@ -1920,6 +2527,60 @@ } } }, + "@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" + }, + "@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" + }, + "@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", + "requires": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" + }, + "@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" + }, + "@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" + }, + "@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" + }, + "@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" + }, "@rollup/plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", @@ -2449,6 +3110,11 @@ "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=" }, + "@types/long": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", + "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" + }, "@types/mime": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", @@ -5295,6 +5961,39 @@ "path-exists": "^4.0.0" } }, + "firebase": { + "version": "9.6.10", + "resolved": "https://registry.npmjs.org/firebase/-/firebase-9.6.10.tgz", + "integrity": "sha512-pnWXhH2J/O5To/TXEp7Dx1nSKkDRspl1bo4f4p6f2noVrn3lvz+cbQNM7DTT0xyA0RsNM/V7aSv3ZbAQj8Od3Q==", + "requires": { + "@firebase/analytics": "0.7.7", + "@firebase/analytics-compat": "0.1.8", + "@firebase/app": "0.7.20", + "@firebase/app-check": "0.5.5", + "@firebase/app-check-compat": "0.2.5", + "@firebase/app-compat": "0.1.21", + "@firebase/app-types": "0.7.0", + "@firebase/auth": "0.19.11", + "@firebase/auth-compat": "0.2.11", + "@firebase/database": "0.12.7", + "@firebase/database-compat": "0.1.7", + "@firebase/firestore": "3.4.7", + "@firebase/firestore-compat": "0.1.16", + "@firebase/functions": "0.7.10", + "@firebase/functions-compat": "0.1.11", + "@firebase/installations": "0.5.7", + "@firebase/messaging": "0.9.11", + "@firebase/messaging-compat": "0.1.11", + "@firebase/performance": "0.5.7", + "@firebase/performance-compat": "0.1.7", + "@firebase/polyfill": "0.3.36", + "@firebase/remote-config": "0.3.6", + "@firebase/remote-config-compat": "0.1.7", + "@firebase/storage": "0.9.4", + "@firebase/storage-compat": "0.1.12", + "@firebase/util": "1.5.1" + } + }, "flat-cache": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", @@ -5873,6 +6572,11 @@ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==" }, + "immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=" + }, "immer": { "version": "9.0.12", "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.12.tgz", @@ -7594,6 +8298,33 @@ "object.assign": "^4.1.2" } }, + "jszip": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.9.1.tgz", + "integrity": "sha512-H9A60xPqJ1CuC4Ka6qxzXZeU8aNmgOeP5IFqwJbQQwtu2EUYxota3LdsiZWplF7Wgd9tkAd0mdu36nceSaPuYw==", + "requires": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "set-immediate-shim": "~1.0.1" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + } + } + }, "kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -7636,6 +8367,14 @@ "type-check": "~0.4.0" } }, + "lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "requires": { + "immediate": "~3.0.5" + } + }, "lilconfig": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.5.tgz", @@ -7674,6 +8413,11 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" + }, "lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -7699,6 +8443,11 @@ "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=" }, + "long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -7959,6 +8708,35 @@ } } }, + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "requires": { + "whatwg-url": "^5.0.0" + }, + "dependencies": { + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + } + } + }, "node-forge": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", @@ -8177,6 +8955,11 @@ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" }, + "pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + }, "param-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", @@ -9112,6 +9895,11 @@ "asap": "~2.0.6" } }, + "promise-polyfill": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-8.1.3.tgz", + "integrity": "sha512-MG5r82wBzh7pSKDRa9y+vllNHz3e3d4CNj1PQE4BQYxLme0gKYYBm9YENq+UkEikyZ0XbiGWxYlVw3Rl9O/U8g==" + }, "prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", @@ -9131,6 +9919,26 @@ "react-is": "^16.13.1" } }, + "protobufjs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.2.tgz", + "integrity": "sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw==", + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + } + }, "proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -9815,6 +10623,17 @@ "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=" }, + "selenium-webdriver": { + "version": "4.0.0-rc-1", + "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-4.0.0-rc-1.tgz", + "integrity": "sha512-bcrwFPRax8fifRP60p7xkWDGSJJoMkPAzufMlk5K2NyLPht/YZzR2WcIk1+3gR8VOCLlst1P2PI+MXACaFzpIw==", + "requires": { + "jszip": "^3.6.0", + "rimraf": "^3.0.2", + "tmp": "^0.2.1", + "ws": ">=7.4.6" + } + }, "selfsigned": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.0.1.tgz", @@ -9942,6 +10761,11 @@ "send": "0.17.2" } }, + "set-immediate-shim": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=" + }, "setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -10501,6 +11325,14 @@ "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" }, + "tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "requires": { + "rimraf": "^3.0.0" + } + }, "tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", diff --git a/package.json b/package.json index 23c50c1..5e73023 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "@testing-library/jest-dom": "^5.16.4", "@testing-library/react": "^12.1.4", "@testing-library/user-event": "^13.5.0", + "firebase": "^9.6.10", "react": "^18.0.0", "react-dom": "^18.0.0", "react-scripts": "5.0.0", diff --git a/src/App.js b/src/App.js index 3940c2d..bf0ff44 100644 --- a/src/App.js +++ b/src/App.js @@ -1,8 +1,10 @@ import Loading from './components/Loading'; import Error from './components/Error'; import TaskList from './components/TaskList'; +import Header from './components/Header'; import { useFetch } from './hooks/useFetch'; +import { AuthenticationProvider } from './providers/Authentication'; const App = () => { const [state, tasks, update, add] = useFetch( @@ -18,14 +20,14 @@ const App = () => { }; return ( - <> -

TODO List

+ +
{state === 'PENDING' && } {state === 'SUCCESS' && ( )} {state === 'FAILED' && Something went wrong} - + ); }; diff --git a/src/components/AuthenticationMethod.js b/src/components/AuthenticationMethod.js new file mode 100644 index 0000000..d26539e --- /dev/null +++ b/src/components/AuthenticationMethod.js @@ -0,0 +1,29 @@ +import { useState } from 'react'; + +import SignUp from './SignUp'; +import SignIn from './SignIn'; + +const AuthenticationMethod = () => { + const [authMethod, setAuthMethod] = useState(); + + const handleClick = (method) => { + setAuthMethod(method); + }; + + if (authMethod === undefined) { + return ( + <> + + + + ); + } + + if (authMethod === 'sign-up') { + return ; + } + + return ; +}; + +export default AuthenticationMethod; diff --git a/src/components/Header.js b/src/components/Header.js new file mode 100644 index 0000000..2211d3b --- /dev/null +++ b/src/components/Header.js @@ -0,0 +1,16 @@ +import { useAuthentication } from '../providers/Authentication'; +import AuthenticationMethod from './AuthenticationMethod'; +import SignOut from './SignOut'; + +const Header = () => { + const { currentUser } = useAuthentication(); + + return ( + <> +

TODO List

+ {currentUser ? : } + + ); +}; + +export default Header; diff --git a/src/components/SignIn.js b/src/components/SignIn.js new file mode 100644 index 0000000..1bd1a80 --- /dev/null +++ b/src/components/SignIn.js @@ -0,0 +1,49 @@ +import { useState } from 'react'; +import { useForm } from '../hooks/useForm'; +import { useAuthentication } from '../providers/Authentication'; + +const SignIn = () => { + const [error, setError] = useState(); + const [form, updateForm, resetForm] = useForm({ email: '', password: '' }); + const { signIn } = useAuthentication(); + + const handleSubmit = (event) => { + event.preventDefault(); + + if (form.email && form.password) { + signIn(form.email, form.password) + .then(() => { + resetForm(); + }) + .catch((error) => { + setError(error.message); + }); + } else { + setError('email and password cannot be empty'); + } + }; + + return ( +
+ + + + {error &&

{error}

} +
+ ); +}; + +export default SignIn; diff --git a/src/components/SignOut.js b/src/components/SignOut.js new file mode 100644 index 0000000..ae08b98 --- /dev/null +++ b/src/components/SignOut.js @@ -0,0 +1,13 @@ +import { useAuthentication } from '../providers/Authentication'; + +const SignOut = () => { + const { signOut } = useAuthentication(); + + const handleClick = () => { + signOut(); + }; + + return ; +}; + +export default SignOut; diff --git a/src/components/SignUp.js b/src/components/SignUp.js new file mode 100644 index 0000000..17c6ded --- /dev/null +++ b/src/components/SignUp.js @@ -0,0 +1,62 @@ +import { useState } from 'react'; +import { useForm } from '../hooks/useForm'; +import { useAuthentication } from '../providers/Authentication'; + +const SignUp = () => { + const [error, setError] = useState(); + const [form, updateForm, resetForm] = useForm({ + email: '', + password: '', + passwordConfirmation: '', + }); + const { signUp } = useAuthentication(); + + const handleSubmit = (event) => { + event.preventDefault(); + if ( + form.email && + form.password && + form.password === form.passwordConfirmation + ) { + signUp(form.email, form.password) + .then(() => { + resetForm(); + }) + .catch((error) => { + setError(error.message); + }); + } else { + setError('email and password cannot be empty'); + } + }; + + return ( +
+ + + + + {error &&

{error}

} +
+ ); +}; + +export default SignUp; diff --git a/src/components/TaskForm.js b/src/components/TaskForm.js index dbca0a2..49722ae 100644 --- a/src/components/TaskForm.js +++ b/src/components/TaskForm.js @@ -1,7 +1,7 @@ -import { useInput } from '../hooks/useInput'; +import { useForm } from '../hooks/useForm'; const TaskForm = ({ addTask }) => { - const [{ task }, update, reset] = useInput({ task: '' }); + const [{ task }, update, reset] = useForm({ task: '' }); const handleInputChange = (event) => { update(event); diff --git a/src/firebase.js b/src/firebase.js new file mode 100644 index 0000000..9b691d1 --- /dev/null +++ b/src/firebase.js @@ -0,0 +1,12 @@ +import { initializeApp } from 'firebase/app'; + +const firebaseConfig = { + apiKey: process.env.REACT_APP_apiKey, + authDomain: process.env.REACT_APP_authDomain, + projectId: process.env.REACT_APP_projectId, + storageBucket: process.env.REACT_APP_storageBucket, + messagingSenderId: process.env.REACT_APP_messagingSenderId, + appId: process.env.REACT_APP_appId, +}; + +export const app = initializeApp(firebaseConfig); diff --git a/src/hooks/useForm.js b/src/hooks/useForm.js new file mode 100644 index 0000000..5f55c74 --- /dev/null +++ b/src/hooks/useForm.js @@ -0,0 +1,20 @@ +import { useState } from 'react'; + +export const useForm = (initialState) => { + const [form, setForm] = useState(initialState); + + const updateForm = (event) => { + setForm((previous) => { + return { + ...previous, + [event.target.name]: event.target.value, + }; + }); + }; + + const resetForm = () => { + setForm(initialState); + }; + + return [form, updateForm, resetForm]; +}; diff --git a/src/hooks/useInput.js b/src/hooks/useInput.js deleted file mode 100644 index 310af22..0000000 --- a/src/hooks/useInput.js +++ /dev/null @@ -1,17 +0,0 @@ -import { useState } from 'react'; - -export const useInput = (initialValues) => { - const [input, setInput] = useState(initialValues); - - const update = (event) => { - setInput((previous) => { - return { ...previous, [event.target.name]: event.target.value }; - }); - }; - - const reset = () => { - setInput(initialValues); - }; - - return [input, update, reset]; -}; diff --git a/src/providers/Authentication.js b/src/providers/Authentication.js new file mode 100644 index 0000000..adcf371 --- /dev/null +++ b/src/providers/Authentication.js @@ -0,0 +1,46 @@ +import { createContext, useContext, useState, useEffect } from 'react'; +import { + getAuth, + createUserWithEmailAndPassword, + signInWithEmailAndPassword, +} from 'firebase/auth'; + +import { app } from '../firebase'; + +const AuthenticationContext = createContext(); + +export const useAuthentication = () => useContext(AuthenticationContext); + +export const AuthenticationProvider = ({ children }) => { + const auth = getAuth(app); + const [currentUser, setCurrentUser] = useState(undefined); + + const signUp = (email, password) => { + return createUserWithEmailAndPassword(auth, email, password); + }; + const signIn = (email, password) => { + return signInWithEmailAndPassword(auth, email, password); + }; + const signOut = () => { + return auth.signOut(); + }; + + useEffect(() => { + auth.onAuthStateChanged((user) => { + setCurrentUser(user); + }); + }, []); + + const value = { + currentUser, + signUp, + signIn, + signOut, + }; + + return ( + + {children} + + ); +}; From 7d0dad2ccc0ea1c5918ae2743f06d522fbcc80c2 Mon Sep 17 00:00:00 2001 From: Diego Lavayen Alarcon Date: Thu, 14 Apr 2022 11:36:29 +0100 Subject: [PATCH 2/4] feat: display task list for authenticated users only --- src/App.js | 30 ++++++------------------------ src/components/TaskPage.js | 30 ++++++++++++++++++++++++++++++ src/index.js | 5 ++++- 3 files changed, 40 insertions(+), 25 deletions(-) create mode 100644 src/components/TaskPage.js diff --git a/src/App.js b/src/App.js index bf0ff44..55499d6 100644 --- a/src/App.js +++ b/src/App.js @@ -1,33 +1,15 @@ -import Loading from './components/Loading'; -import Error from './components/Error'; -import TaskList from './components/TaskList'; import Header from './components/Header'; +import TaskPage from './components/TaskPage'; -import { useFetch } from './hooks/useFetch'; -import { AuthenticationProvider } from './providers/Authentication'; +import { useAuthentication } from './providers/Authentication'; const App = () => { - const [state, tasks, update, add] = useFetch( - process.env.REACT_APP_API_ENDPOINT, - ); - - const updateTask = (task) => { - update(task.id, task); - }; - - const addTask = (title) => { - add({ title, completed: false }); - }; - + const { currentUser } = useAuthentication(); return ( - + <>
- {state === 'PENDING' && } - {state === 'SUCCESS' && ( - - )} - {state === 'FAILED' && Something went wrong} - + {currentUser && } + ); }; diff --git a/src/components/TaskPage.js b/src/components/TaskPage.js new file mode 100644 index 0000000..7bb7eda --- /dev/null +++ b/src/components/TaskPage.js @@ -0,0 +1,30 @@ +import Loading from './Loading'; +import Error from './Error'; +import TaskList from './TaskList'; + +import { useFetch } from '../hooks/useFetch'; + +const TaskPage = () => { + const [state, tasks, update, add] = useFetch( + process.env.REACT_APP_API_ENDPOINT, + ); + + const updateTask = (task) => { + update(task.id, task); + }; + + const addTask = (title) => { + add({ title, completed: false }); + }; + return ( + <> + {state === 'PENDING' && } + {state === 'SUCCESS' && ( + + )} + {state === 'FAILED' && Something went wrong} + + ); +}; + +export default TaskPage; diff --git a/src/index.js b/src/index.js index f452ad2..8e15f4f 100644 --- a/src/index.js +++ b/src/index.js @@ -2,10 +2,13 @@ import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import App from './App'; +import { AuthenticationProvider } from './providers/Authentication'; ReactDOM.render( - + + + , document.getElementById('root'), ); From 7bb762057fe6260cec69212c920e9e84a4caabf4 Mon Sep 17 00:00:00 2001 From: Diego Lavayen Alarcon Date: Thu, 14 Apr 2022 11:47:37 +0100 Subject: [PATCH 3/4] feat: add sign in with google provider --- src/components/AuthenticationMethod.js | 3 +++ src/components/Header.js | 4 ++++ src/providers/Authentication.js | 8 ++++++++ 3 files changed, 15 insertions(+) diff --git a/src/components/AuthenticationMethod.js b/src/components/AuthenticationMethod.js index d26539e..efb7147 100644 --- a/src/components/AuthenticationMethod.js +++ b/src/components/AuthenticationMethod.js @@ -2,9 +2,11 @@ import { useState } from 'react'; import SignUp from './SignUp'; import SignIn from './SignIn'; +import { useAuthentication } from '../providers/Authentication'; const AuthenticationMethod = () => { const [authMethod, setAuthMethod] = useState(); + const { signInWithGoogle } = useAuthentication(); const handleClick = (method) => { setAuthMethod(method); @@ -15,6 +17,7 @@ const AuthenticationMethod = () => { <> + ); } diff --git a/src/components/Header.js b/src/components/Header.js index 2211d3b..a98ede0 100644 --- a/src/components/Header.js +++ b/src/components/Header.js @@ -5,6 +5,10 @@ import SignOut from './SignOut'; const Header = () => { const { currentUser } = useAuthentication(); + if (currentUser === undefined) { + return null; + } + return ( <>

TODO List

diff --git a/src/providers/Authentication.js b/src/providers/Authentication.js index adcf371..fb2e139 100644 --- a/src/providers/Authentication.js +++ b/src/providers/Authentication.js @@ -3,6 +3,8 @@ import { getAuth, createUserWithEmailAndPassword, signInWithEmailAndPassword, + signInWithPopup, + GoogleAuthProvider, } from 'firebase/auth'; import { app } from '../firebase'; @@ -25,6 +27,11 @@ export const AuthenticationProvider = ({ children }) => { return auth.signOut(); }; + const signInWithGoogle = () => { + const provider = new GoogleAuthProvider(); + return signInWithPopup(auth, provider); + }; + useEffect(() => { auth.onAuthStateChanged((user) => { setCurrentUser(user); @@ -36,6 +43,7 @@ export const AuthenticationProvider = ({ children }) => { signUp, signIn, signOut, + signInWithGoogle, }; return ( From 5bcb4b52e44e797dec9e13b8e05ab09a7ff5db4f Mon Sep 17 00:00:00 2001 From: Diego Lavayen Alarcon Date: Thu, 14 Apr 2022 11:52:35 +0100 Subject: [PATCH 4/4] feat: adding some profile information (available for free when user's logged in with Google Provider) --- src/components/Header.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/components/Header.js b/src/components/Header.js index a98ede0..8bedf8d 100644 --- a/src/components/Header.js +++ b/src/components/Header.js @@ -12,7 +12,15 @@ const Header = () => { return ( <>

TODO List

- {currentUser ? : } + {currentUser ? ( + <> + + {currentUser.displayName &&

Hi {currentUser.displayName}

} + {currentUser.photoURL && } + + ) : ( + + )} ); };