diff --git a/.github/workflows/firebase-hosting-merge.yml b/.github/workflows/firebase-hosting-merge.yml new file mode 100644 index 00000000..027fa95c --- /dev/null +++ b/.github/workflows/firebase-hosting-merge.yml @@ -0,0 +1,20 @@ +# This file was auto-generated by the Firebase CLI +# https://github.com/firebase/firebase-tools + +name: Deploy to Firebase Hosting on merge +"on": + push: + branches: + - master +jobs: + build_and_deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - run: npm run build + - uses: FirebaseExtended/action-hosting-deploy@v0 + with: + repoToken: "${{ secrets.GITHUB_TOKEN }}" + firebaseServiceAccount: "${{ secrets.FIREBASE_SERVICE_ACCOUNT_CODELABZ_GSOC24 }}" + channelId: live + projectId: codelabz-gsoc24 diff --git a/.github/workflows/firebase-hosting-pull-request.yml b/.github/workflows/firebase-hosting-pull-request.yml new file mode 100644 index 00000000..4d9726e0 --- /dev/null +++ b/.github/workflows/firebase-hosting-pull-request.yml @@ -0,0 +1,17 @@ +# This file was auto-generated by the Firebase CLI +# https://github.com/firebase/firebase-tools + +name: Deploy to Firebase Hosting on PR +"on": pull_request +jobs: + build_and_preview: + if: "${{ github.event.pull_request.head.repo.full_name == github.repository }}" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - run: npm run build + - uses: FirebaseExtended/action-hosting-deploy@v0 + with: + repoToken: "${{ secrets.GITHUB_TOKEN }}" + firebaseServiceAccount: "${{ secrets.FIREBASE_SERVICE_ACCOUNT_CODELABZ_GSOC24 }}" + projectId: codelabz-gsoc24 diff --git a/database.rules.json b/database.rules.json index f1366029..4335e236 100644 --- a/database.rules.json +++ b/database.rules.json @@ -1,4 +1,5 @@ { + /* Visit https://firebase.google.com/docs/database/security to learn more about security rules. */ "rules": { ".read": false, ".write": false diff --git a/firestore.rules b/firestore.rules index 8d700cd7..5f1ef816 100644 --- a/firestore.rules +++ b/firestore.rules @@ -1,8 +1,19 @@ rules_version = '2'; + service cloud.firestore { match /databases/{database}/documents { + + // This rule allows anyone with your Firestore database reference to view, edit, + // and delete all data in your Firestore database. It is useful for getting + // started, but it is configured to expire after 30 days because it + // leaves your app open to attackers. At that time, all client + // requests to your Firestore database will be denied. + // + // Make sure to write security rules for your app before that time, or else + // all client requests to your Firestore database will be denied until you Update + // your rules match /{document=**} { - allow read, write: if true; + allow read, write: if request.time < timestamp.date(2024, 3, 4); } } } \ No newline at end of file diff --git a/functions/.eslintrc.js b/functions/.eslintrc.js new file mode 100644 index 00000000..65f0d8b1 --- /dev/null +++ b/functions/.eslintrc.js @@ -0,0 +1,25 @@ +module.exports = { + env: { + es6: true, + node: true + }, + parserOptions: { + ecmaVersion: 2018 + }, + extends: ["eslint:recommended", "google"], + rules: { + "no-restricted-globals": ["error", "name", "length"], + "prefer-arrow-callback": "error", + quotes: ["error", "double", { allowTemplateLiterals: true }] + }, + overrides: [ + { + files: ["**/*.spec.*"], + env: { + mocha: true + }, + rules: {} + } + ], + globals: {} +}; diff --git a/functions/.gitignore b/functions/.gitignore index 70197f08..40b878db 100644 --- a/functions/.gitignore +++ b/functions/.gitignore @@ -1,2 +1 @@ -node_modules/ -private/ +node_modules/ \ No newline at end of file diff --git a/functions/index.js b/functions/index.js index 8e98586a..6fa37be1 100644 --- a/functions/index.js +++ b/functions/index.js @@ -1,50 +1,19 @@ -const functions = require("firebase-functions"); -const dotenv = require("dotenv"); -dotenv.config({ - path: "../.env" -}); - /** - * +++++++++++++++++++CLOUD FUNCTIONS+++++++++++++++++++++++++++++ - */ - -/**Import functions + * Import function triggers from their respective submodules: + * + * const {onCall} = require("firebase-functions/v2/https"); + * const {onDocumentWritten} = require("firebase-functions/v2/firestore"); + * + * See a full list of supported triggers at https://firebase.google.com/docs/functions */ -const onCallFunctions = require("./cloud_functions/onCallFunctions"); -const onCreateFunctions = require("./cloud_functions/onCreateFunctions"); -const onWriteFunctions = require("./cloud_functions/onWriteFunctions"); -const onUpdateFunctions = require("./cloud_functions/onUpdateFunctions"); -const pubSubFunctions = require("./cloud_functions/pubSubFunctions"); - -//+++++++++++++++++++++onCall Functions+++++++++++++++++++++++++++++++++ -exports.resendVerificationEmail = functions.https.onCall( - onCallFunctions.resendVerificationEmailHandler -); - -exports.sendPasswordUpdateEmail = functions.https.onCall( - onCallFunctions.sendPasswordUpdateEmailHandler -); - -//+++++++++++++++++++++onCreate Functions+++++++++++++++++++++++++++++++ -exports.sendVerificationEmail = functions.auth - .user() - .onCreate(onCreateFunctions.sendVerificationEmailHandler); - -exports.createOrganization = functions.firestore - .document("cl_org_general/{org_handle}") - .onCreate(onCreateFunctions.createOrganizationHandler); -//++++++++++++++++++++onWrite Functions+++++++++++++++++++++++++++++++ -exports.registerUserHandle = functions.firestore - .document("cl_user/{uid}") - .onWrite(onWriteFunctions.registerUserHandleHandler); +const { onRequest } = require("firebase-functions/v2/https"); +const logger = require("firebase-functions/logger"); -//++++++++++++++++++++onUpdate Functions++++++++++++++++++++++++++++++ -exports.updateOrgUser = functions.firestore - .document("cl_org_general/{org_handle}/cl_org_users/users") - .onUpdate(onUpdateFunctions.addOrgUserHandler); +// Create and deploy your first functions +// https://firebase.google.com/docs/functions/get-started -//++++++++++++++++++++Pub/Sub Functions++++++++++++++++++++++++++++++ -exports.deleteTutorialSteps = functions.pubsub - .schedule("every 7 days") - .onRun(pubSubFunctions.deleteTutorialStepsHandler); +// exports.helloWorld = onRequest((request, response) => { +// logger.info("Hello logs!", {structuredData: true}); +// response.send("Hello from Firebase!"); +// }); diff --git a/functions/package.json b/functions/package.json index f20d6f03..a88bc5e2 100644 --- a/functions/package.json +++ b/functions/package.json @@ -10,18 +10,17 @@ "logs": "firebase functions:log" }, "engines": { - "node": "10" + "node": "18" }, + "main": "index.js", "dependencies": { - "dotenv": "^16.0.1", - "firebase-admin": "^9.0.0", - "firebase-functions": "^3.9.0", - "lodash": "^4.17.19" + "firebase-admin": "^11.8.0", + "firebase-functions": "^4.3.1" }, "devDependencies": { - "eslint": "^5.12.0", - "eslint-plugin-promise": "^4.0.1", - "firebase-functions-test": "^0.2.0" + "eslint": "^8.15.0", + "eslint-config-google": "^0.14.0", + "firebase-functions-test": "^3.1.0" }, "private": true } diff --git a/functions/private/cl-dev-pk.json b/functions/private/cl-dev-pk.json new file mode 100644 index 00000000..f4009e09 --- /dev/null +++ b/functions/private/cl-dev-pk.json @@ -0,0 +1,13 @@ +{ + "type": "service_account", + "project_id": "codelabz-gsoc24", + "private_key_id": "f6aec9fe78ebf53b5f6086cdbd09e245f6c0cd22", + "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCexj7GEzOAbBBJ\nSamCs16P0+CZuzoOir3O1a4GCE2/dGwf7E6YNKzvSqJYexS0FNJwjol16vVx0jUt\n+NJS9kpkTPf3ds4p++5DAy46rom61ktMYz/YZvWTnkke+0+oR50+L8VZrtn8rW2m\n5vhX8uZcx/Mj1+sVC4xMQPPrUwFDTHEkahKkYsnhSmStwHsOGG/KaeKttnTUN0OX\nJSwCtIfHWiKc2eWskgoYeI6V4JHhgp7/G3DJjZAtTMbS8dyXlYuTGMb8upkYSZu5\n8i7sSQcOKmUXU3/ddnlwYX7nmg1NhOmBg0pUSrS4jmagqGjis9N2TrBjzDX1U2I1\ntWQBhICHAgMBAAECggEAAoVJarq3wNG9fOVCfB2aN5uqZn9J/gA4izQUzBSb49I6\nPFPzopYTf+HtOeJhdN/FFbqYPdsBEoppkiqab8JL5AykxO3fQc4K/WuWLEzEno3X\nf76DoPfhe4ix/5jOrgzN5WERN61/Z5Bs2FZftoItI2eAWZDhwTbjf1CjVdGFwWNK\n3dlMlVauDvbMKZABan8bjsLTVAox95hXVuqWrqVtheHwpT+hmXgcmdeOx9DlSPSs\nDHEYnlh6O6gxY9RiQ7LAjws68eO9GxCZDkfvM3Ok/g6SIswrgWL2yTBq8SPKDcwM\nNs2Aulb9jnYsC324u5vBS1UXw6Y0xdyn2pxwtGrqoQKBgQDbI33z0u18lA2ZPx6G\nPqHUdW62i+vbCHLWYB6fCha7t39ZhieVpuVvfcN2XmLiPmFUJqMbxuSEn7qK3DcP\n+g/wEAvbouCm2oB+LQkE4WR7j1Uam+hQYN7s2yxXcqiX4VW3wgIpYY1XNnHqZkup\n8yGSu0mfXR67uGMvdBLVIFRz1QKBgQC5e1vwWXVXSTMO7Ml3T7ea30aM+LyMA6Bi\nBlNcqRaXvcB3DalNBHzabKFB7P2UR8ZH1nBOliEVeKJhP4+itlBl0GqVq1EP88VC\nIdPNreWjdoUyFlqnLOu1xaEOJAEve4YS+V5AJzCmozQJNvmdeVkOitzv0XvV+Flp\nuUBqlNd86wKBgDmJJQ26iL4XxUZCK0qF8UluF8Z4EFHu8u/URtXs+TEKKbagoY4K\nRt0yAPr4JzBNvpIwnsyxONiVc4336cEZH8wg+mwNZLyKTAhU3LRaVV6XsHmPC7zm\n4kD//rFrGlbeQ/o+RwEEau7GDbzEZQNXIa573AWqlmIlNG2GJVet6F6NAoGBAKXv\nDDMbdPRfkgP6JcpNUM6GjNE0/UitPeA0FIPC6Wla4kIfwKQcLa4inKkj4T+0blh6\nKQLFIFfbEjm56UABpi9Pouq+1shUptYg+SD6P4RbVZGXmgYRE9YMNac24rCd6zYy\nTPVLmiSZwMW1nt4YX2m5JSqO2CB2C1ef2VcATT99AoGAT/nNCZN8C+gu1gJ6mkmq\nJDgNdLV907vKenZlOez5EB6Uns20v1YyOuK7EyMUnf9NHr/5ZyPw+yT7RCJ28YO3\nclXF4gkKuVwcxm/ccsZhmqBb2EzrF1rnbcgtEocRG3zYmPhFZdqeHLQ9/GSneC8Q\neAxgoA/wdxA/piq5GTpiFKg=\n-----END PRIVATE KEY-----\n", + "client_email": "firebase-adminsdk-45w7y@codelabz-gsoc24.iam.gserviceaccount.com", + "client_id": "112002644236744622520", + "auth_uri": "https://accounts.google.com/o/oauth2/auth", + "token_uri": "https://oauth2.googleapis.com/token", + "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", + "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-45w7y%40codelabz-gsoc24.iam.gserviceaccount.com", + "universe_domain": "googleapis.com" +} diff --git a/public/index.html b/public/index.html index 75393131..db385020 100644 --- a/public/index.html +++ b/public/index.html @@ -1,41 +1,89 @@ - +
- - - - - + + +You're seeing this because you've successfully setup Firebase Hosting. Now it's time to go build something extraordinary!
+ Open Hosting Documentation +Firebase SDK Loading…
+ + diff --git a/src/components/Card/CardWithoutPicture.jsx b/src/components/Card/CardWithoutPicture.jsx index abc4ecb0..4de144c0 100644 --- a/src/components/Card/CardWithoutPicture.jsx +++ b/src/components/Card/CardWithoutPicture.jsx @@ -72,6 +72,8 @@ export default function CardWithoutPicture({ tutorial }) { const dispatch = useDispatch(); const firebase = useFirebase(); const firestore = useFirestore(); + const [toggleTitle, setToggleTitle] = useState(false); + const [toggleSummary, setToggleSummary] = useState(false); const handleIncrement = () => { setCount(count + 1); }; @@ -147,7 +149,37 @@ export default function CardWithoutPicture({ tutorial }) { data-testId="codelabzDetails" >