From c404ff377c71557d843af18e6e09a099c479515b Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Fri, 1 May 2020 17:06:52 -0700 Subject: [PATCH] Adding reference docs + paramterized some environment variables + new firebase environments. + firebase ref docs. --- _reference/SampleEnv.md | 11 --- _reference/dropletSetup.md | 73 +++++++++++++++++ _reference/firebase.md | 15 ++++ firebase/functions/index.js | 81 +++++++++---------- server/firebase/firebase-handler.js | 12 +-- .../firebase/imex-dev-firebase-adminsdk.json | 12 +++ .../firebase/imex-prod-firebase-adminsdk.json | 12 +++ 7 files changed, 153 insertions(+), 63 deletions(-) delete mode 100644 _reference/SampleEnv.md create mode 100644 _reference/dropletSetup.md create mode 100644 _reference/firebase.md create mode 100644 server/firebase/imex-dev-firebase-adminsdk.json create mode 100644 server/firebase/imex-prod-firebase-adminsdk.json diff --git a/_reference/SampleEnv.md b/_reference/SampleEnv.md deleted file mode 100644 index aef3218b0..000000000 --- a/_reference/SampleEnv.md +++ /dev/null @@ -1,11 +0,0 @@ -server.env - -AWSAccessKeyId=AKIAJYNXY5KCA25PB2JA -AWSSecretKey=iYO/navUhHuEXc6fMgfUh1y3VZY1hF6ISrUMZ4de -Bucket=bodyshop-app-dev - - -client.env -REACT_APP_GRAPHQL_ENDPOINT=https://bodyshop-dev-db.herokuapp.com/v1/graphql -REACT_APP_GRAPHQL_ENDPOINT_WS=wss://bodyshop-dev-db.herokuapp.com/v1/graphql -REACT_APP_GA_CODE=217352234 diff --git a/_reference/dropletSetup.md b/_reference/dropletSetup.md new file mode 100644 index 000000000..eefd783d3 --- /dev/null +++ b/_reference/dropletSetup.md @@ -0,0 +1,73 @@ +**Create an SSH key for local computer** + +ssh-keygen -t rsa -C "your_email@example.com" + +Copy the new key to clipboard: +* Windows: clip < id_rsa.pub +* Linux: sudo apt-get install xclip +xclip -sel clip < ~/.ssh/id_rsa.pub +* Mac: pbcopy < ~/.ssh/id_rsa.pub +* Manual Copy: cat ~/.ssh/id_rsa.pub + +Add the SSH key to the drop creation screen. + + +1. Create a new user to replace root user + 1. # adduser bob + 2. # usermod -aG sudo bob + 3. # su - bob + 4. $ mkdir ~/.ssh + 5. $ chmod 700 ~/.ssh + 6. $ nano ~/.ssh/authorized_keys + 7. Add the copied SSH key and save. + 8. $ chmod 600 ~/.ssh/authorized_keys #Restrict access to authroized keys. +2. Setup the Firewall + 1. $ sudo ufw allow OpenSSH. + 2. $ sudo ufw enable +3. Add Nginx & Configure + 1. $ sudo apt-get update + 2. $ sudo apt-get install nginx + 3. sudo ufw allow 'Nginx Full' + 4. $ sudo ufw app list + 1. Nginx Full: Opens both port 80 (normal, unencrypted web traffic) and port 443 (TLS/SSL encrypted traffic) + 2. Nginx Http: Opens only port 80 (normal, unencrypted web traffic) + 3. Nginx Https: Opens only port 443 (TLS/SSL encrypted traffic) + 5. Should now be able to go to IP and see nginx responding with a blank page. +4. Install Certbot + 1. $ sudo add-apt-repository ppa:certbot/certbot + 2. $ sudo apt-get update + 3. $ sudo apt install python-certbot-nginx + 4. $ sudo nano /etc/nginx/sites-available/default + 5. Find the existing server_name line and replace the underscore with your domain name: + ... + server_name example.com www.example.com; + ... + 6. $ sudo nginx -t //Verify syntax. + 7. $ sudo systemctl reload nginx +5. Generate Certificate + 1. $ sudo certbot --nginx -d example.com -d www.example.com //Follow prompts. + 2. $ sudo certbot renew --dry-run //Dry run to test auto renewal. +6. Install NodeJs + 1. $ curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash - + 2. $ sudo apt install nodejs + 3. $ node --version +7. Clone Source Code + 1. $ git clone git@bitbucket.org:snaptsoft/bodyshop.git //Requires SSH setup. + 2. $ cd bodyshop && npm install //Install all server dependencies. +8. Setup PM2 + 1. $ npm install pm2 -g + 2. $ pm2 start server.js + 3. $ pm2 startup ubuntu //Ensure it starts when server does. +9. Alter Nginx config + 1. sudo nano /etc/nginx/sites-available/default + 2. Add Appropriate server names to the file. www. and non-www. + 3. Add the following inside the location block: + proxy_pass http://localhost:{{YOUR-APP-PORT-IN-YOUR-CODE}}; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_set_header Host $host; + proxy_cache_bypass $http_upgrade; + + + diff --git a/_reference/firebase.md b/_reference/firebase.md new file mode 100644 index 000000000..ba407f4cf --- /dev/null +++ b/_reference/firebase.md @@ -0,0 +1,15 @@ +1. Create a new project +2. Setup sign in methods to be user and email only. +3. Update .env to include config. +4. Setup the Firebase CLI + 1. cd to client firebase at server directory. + 2. ensure all dependencies installed + 1. $ npm install firebase-functions@latest firebase-admin@latest --save + 2. $ npm install -g firebase-tools + 3. $ firebase login //Login as needed. +5. Set the current projct + 1. firebase use +6. Deploy the function + 1. $ firebase deploy --only functions +7. Add the allowed domains. +8. Update server variables including FIREBASE_ADMINSDK_JSON, FIREBASE_DATABASE_URL \ No newline at end of file diff --git a/firebase/functions/index.js b/firebase/functions/index.js index 3583ca696..779dc1893 100644 --- a/firebase/functions/index.js +++ b/firebase/functions/index.js @@ -2,33 +2,32 @@ const functions = require("firebase-functions"); const admin = require("firebase-admin"); admin.initializeApp(functions.config().firebase); -//TODO Move this to an environment parameter. -const GRAPHQL_ENDPOINT = functions.config().auth.graphql_endpoint; -const HASURA_SECRET_ADMIN_KEY = functions.config().auth.hasura_secret_admin_key; -const UPSERT_USER = ` -mutation upsert_user($authEmail: String!, $authToken: String!) { - insert_users( - objects: [ - { -email:$authEmail, - authid:$authToken - } - ], - on_conflict: { - constraint: users_pkey, - update_columns: [authid] - } - ) { - returning { -authid - } - } -} -`; +// //TODO Move this to an environment parameter. +// const GRAPHQL_ENDPOINT = functions.config().auth.graphql_endpoint; +// const HASURA_SECRET_ADMIN_KEY = functions.config().auth.hasura_secret_admin_key; +// const UPSERT_USER = ` +// mutation upsert_user($authEmail: String!, $authToken: String!) { +// insert_users( +// objects: [ +// { +// email:$authEmail, +// authid:$authToken +// } +// ], +// on_conflict: { +// constraint: users_pkey, +// update_columns: [authid] +// } +// ) { +// returning { +// authid +// } +// } +// } +// `; // On sign up. -exports.processSignUp = functions.auth.user().onCreate(user => { - console.log(user); +exports.processSignUp = functions.auth.user().onCreate((user) => { // Check if user meets role criteria: // Your custom logic here: to decide what roles and other `x-hasura-*` should the user get let customClaims; @@ -37,16 +36,16 @@ exports.processSignUp = functions.auth.user().onCreate(user => { "https://hasura.io/jwt/claims": { "x-hasura-default-role": "admin", "x-hasura-allowed-roles": ["user", "admin"], - "x-hasura-user-id": user.uid - } + "x-hasura-user-id": user.uid, + }, }; } else { customClaims = { "https://hasura.io/jwt/claims": { "x-hasura-default-role": "user", "x-hasura-allowed-roles": ["user"], - "x-hasura-user-id": user.uid - } + "x-hasura-user-id": user.uid, + }, }; } @@ -65,17 +64,15 @@ exports.processSignUp = functions.auth.user().onCreate(user => { // }); // Set custom user claims on this newly created user. - return admin - .auth() - .setCustomUserClaims(user.uid, customClaims) - .then(() => { - // Update real-time database to notify client to force refresh. - const metadataRef = admin.database().ref("metadata/" + user.uid); - // Set the refresh time to the current UTC timestamp. - // This will be captured on the client to force a token refresh. - return metadataRef.set({ refreshTime: new Date().getTime() }); - }) - .catch(error => { - console.log(error); - }); + return admin.auth().setCustomUserClaims(user.uid, customClaims); + // .then(() => { + // // Update real-time database to notify client to force refresh. + // const metadataRef = admin.database().ref("metadata/" + user.uid); + // // Set the refresh time to the current UTC timestamp. + // // This will be captured on the client to force a token refresh. + // return metadataRef.set({ refreshTime: new Date().getTime() }); + // }) + // .catch(error => { + // console.log(error); + // }); }); diff --git a/server/firebase/firebase-handler.js b/server/firebase/firebase-handler.js index 6e9819bd3..ce43bec98 100644 --- a/server/firebase/firebase-handler.js +++ b/server/firebase/firebase-handler.js @@ -1,25 +1,17 @@ var admin = require("firebase-admin"); -var serviceAccount = require("../../bodyshop-dev-firebase-adminsdk.json"); +var serviceAccount = require(process.env.FIREBASE_ADMINSDK_JSON); admin.initializeApp({ credential: admin.credential.cert(serviceAccount), - databaseURL: "https://bodyshop-dev-b1cb6.firebaseio.com", + databaseURL: process.env.FIREBASE_DATABASE_URL, }); -//var defaultApp = admin.initializeApp(defaultAppConfig); exports.admin = admin; exports.sendNotification = (req, res) => { console.log("Firebase Send."); - // const { ids } = req.body; - // const url = cloudinary.utils.download_zip_url({ public_ids: ids }); - //Prod - // var registrationToken = - // "c3-6vUcehzdDe4rdfUr1JP:APA91bEbZiO1j7M4O1IHzWEiczqNoT7udFH9wE7m-Ob-2wRRRxEv6gyBY64fYVvFkfOGdLNJic6kcAr7ImpUy3jHXlWvUqtdUQ-uRhZoWa-IgJSCIgfT7pjDnvCakvr45YyAms4neP1s"; - - //Dev var registrationToken = "fqIWg8ENDFyrRrMWJ1sItR:APA91bHirdZ05Zo66flMlvala97SMXoiQGwP4oCvMwd-vVrSauD_WoNim3kXHGqyP-bzENjkXwA5icyUAReFbeHn6dIaPcbpcsXuY73-eJAXvZiu1gIsrd1BOsnj3dEMT7Q4F6mTPth1"; var message = { diff --git a/server/firebase/imex-dev-firebase-adminsdk.json b/server/firebase/imex-dev-firebase-adminsdk.json new file mode 100644 index 000000000..31fde1800 --- /dev/null +++ b/server/firebase/imex-dev-firebase-adminsdk.json @@ -0,0 +1,12 @@ +{ + "type": "service_account", + "project_id": "imex-dev", + "private_key_id": "4cd5bdb92b883cba1309ee8a7dda4b9925e8f264", + "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDIWWXzD7vPBc1l\nBlbIQRpu8XnQ5CL4kgv2ZsoJ4tQ8cOYRez/puvwI0lZbMIr4KhVEeoe3am0gOXMY\niYmu3MLm7SZEZW/V7aawx462WprlAP9KcwSlVcNC+lSWLrPVvnuRXGi5SWdDBW60\ne2WRqbZKWkMATQkzLZzOLb8wt9VDU5TcY5t4NB7vrTJZLApxZAhX9jyaqR0WjgdS\nsoGNWwfo+wZqgaLHkdf68ELQ+8bJepbj8sExnJmwwiTvXlsYNSs1lTP1Dis56nKe\nRkSlbevyGgO9PGpWH1WIzZP5/vHANWShdXsvuacZ3TCnhNf+ST78A7mTWw8DMSvI\novtfzHrVAgMBAAECggEARdwGVI6z6igXypY/RGyPDwhcdZ5XI12pli2ZXYEeiETF\ntGrJinKM13agbgOrMYVbDRm8oRQXIRlnLLMoszR/MY6XvVmxeWL4sMOk26kUQa3r\nVsZsZEpXX89yFzwJsQpOhA045wLVYuVOCNjOPdBzo9F9c2lpP9MzziDdfdtcHbE1\nR1o3wdwl3RiRS6wEeOsKTCBI3e9eytSh48wBFbYtFjOO07u4Err7iMfdd7WcaOpC\nCUAbnphq3IEKksSWzA/h/UZYCQFX4SJILwY2A5l8wji31ojoMZn+UTWHZeuhA5zW\nzy1rof1o5NHDoQGmGGBLEWs461ylifq8ZFc/u3kNsQKBgQDn5hDMLJ9dUs5e+Z+6\nxP5gvq4/Bwi6AVX76DdWSaCW+jDV03OC8voH0UzbJKZ81/mMDhFL10KRbbG8tBoU\ncpOMpSrsDqIu9C6iniKK5nggzVaqpWduqiHT59duHh4ohcgmhoRAaeCy5Q1u2aOs\nuhUpsX1CPma73Wuw9otPV8n//wKBgQDdK+wGgBl8otkEtNoOGxVdIjyY/3tSKjJN\nA1oW21Q+KKHk3nQ0MQv69XxwmFuyAkco0aT/9w1YjSLhFiDnPTGdsyOlPyzWjzKt\ny7rQQ99W9E6MxHoT4tA0S6UUY55jsnPB+ytckPW8CMc89MKp1Qw1Wx/HsTNoRLtq\nbjb+USGFKwKBgEUc4Cy5r9VUdIUByIUVaOrUaYIHSqaE92dYUgW5c88LSbqwhmCk\nobfqvQki5yuWAp2nI6iCwygslSg0VQF7FFZ6c0xfIB72T1/P2WOkRHEiQY4iNa1Z\nrzNEiYQcHcjd9kTlGk1IQNuQQGylGI7F9sCyUS6JAn1DBHF9SQ+gjmdpAoGAQVsH\nRex4m5Hrmy5t+RkbuQey7GsiX+dEMem5p2Nsg2myXVU29W1A4wnDmeoLvpBZwsAg\nh9rTQMWD9wt48Zvtm3IiKGSAtW5fRWgcbgqAZsuOop40jMfLSojH4TyGw2MqPbog\n2Bul4cieR270Twc7slCZFYNRc5BL6WlkKsaCpz0CgYBlHGMoqaplAWVYJp+O7bbD\nsW8C8+FlFYoT26q8/TCj7dKxKSARsV9vg3eDBz0qCTMIqZGpMHWzF0Fkpr9ZqYdZ\nEvYdmrI+oSi657IQqan0vZwn7QBooE/opBwElHXjhCeAVLmDseLG3sK8OqcbW3aG\n1K7HV6sirgihrTS8iOqs4Q==\n-----END PRIVATE KEY-----\n", + "client_email": "firebase-adminsdk-f2zkh@imex-dev.iam.gserviceaccount.com", + "client_id": "105392652141030688709", + "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-f2zkh%40imex-dev.iam.gserviceaccount.com" +} diff --git a/server/firebase/imex-prod-firebase-adminsdk.json b/server/firebase/imex-prod-firebase-adminsdk.json new file mode 100644 index 000000000..90d3362e8 --- /dev/null +++ b/server/firebase/imex-prod-firebase-adminsdk.json @@ -0,0 +1,12 @@ +{ + "type": "service_account", + "project_id": "imex-prod", + "private_key_id": "5eacc85af252be59a0dcf08009b3219eaabced2e", + "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDLYLP7i2CDFPQw\n1yz6RM1DV3KEEDF9PmbPDcun4P66n5fK2w4fool81MsfAR2no5j38FNM7cDYpo2S\n9e48T3lFxybBHm8PP1DMfMeTys7FGdW/Q0/pdYQRZbPhqSqwJZuj05lkObI4l6V3\nIDIP5wtiOwYSQAp6Vga8atD/sAq+DsOqTbZ5CniBwIlvCVhwcjhf/dry+Tm0ZH6P\nu4bQGD3GL3PQ6cd00oDKE+Gv2emDrgvjmB03RTQDFoBI+bxsMDYhoN7mYS2PfUQD\ndsH+RXqu8dWzPJhacosp3DMfgvgPIdxCR8/h4LT/v20hYNdhGTwZAZUHbEUCEkgf\nOZ0Xa7IVAgMBAAECggEAIR75kMCtEgvqjL2uPH/R8eKe6rT8akosUhIMFaYFtfzh\nqo6sKSi+PU8mWUFERBXXhqFj34ZkvqO5MLLOfpHuzRdWz2KWcaQ9E2BK3F3N+Llx\nXvmmXP3faTnn5ps3MYKeazq9o13mEWNY9iKPJJna979nCLfXPP8fj7XRnaJczYCt\njh+LuzFxtsP9qFXFhTu+0Ji7g7FttQSq/p4JR5Ybhp4t5m8P6GPg+NzC3qZ4b/96\nP0XQNnKHq2bRE4PKP7n8pomNenIDi4/QPmARlxzpAOvTNHwXqgWGf7HG5Sv0bl1F\nNLnHcS6g2aMXq9ZPaaG+4auFNrQ6mQzsf+nVxvYU7QKBgQDz/Vdvs5eTMyu2Cwf2\noSzxh6YYKwgKMUl2jZqEZb1I5/2fB02/mnlAU01WQfcHewlA4J4uJnMvVo3G6guO\nxBfUDnb4TylbxMVyYesJfprOdRyfeOYBuxbjfqpee2aJKtWANxrDe9MZW1p8Ztcy\nTWZIVgmrGvNiT+Z6xKCrv8apSwKBgQDVY5ZQG6ZAYDfMf7j/G67QG31kUJ1GGJNq\nXfg8cjB5nJnF5tM2tdLNje2fthlmhRV44+/xsqiRbI1p8i6iPS9gW/rEsujoFbaB\nGzfRwFgijTxGjgR1Irk1/rTZxnZXYMqhgap9a6Pgw0PttUkFbduSXpQQV/EYTCWs\nL3yrw7pWHwKBgQC3z+t4VqdhmRJcMhFMx34RdC04VerXquv6aZG4HuGsNEJI9Xqo\nV5rzUA6aZlXRh+qfutjQUd1DE4T6D0anxqlg84jDZvf0j9hkZMpqO7wqv+XRaoZ1\nVVpYBwwY5ASKX/+6eUkrbnTJzJ3tzJhg6BifdFoSUtp6/VDYupuE6JSk4wKBgAeX\nz5VyJmxMADBKqy6IsaO+FqwnIjGIVlaGmXqtJYRuShp8qC9eMO4XiskQFb9MJQN0\nOOmEzfK+xhlrALXNL45iN34gT6FShHf7m/Tev0QbenWYQBha7/Q35/+HzFY3n343\nuvVTizVIPXaL6NlEm3eN3f7m4jFXJFAIMIt8H3lJAoGAfveAtfrMMVru9jDZShmY\n+LaVvauSCdq0mtzB9gz/jFA0LC6LXnPjkk0Vul/fOpq1S9E/0PhKELxTgEeobP7a\n2gqa16r12nMkAUlfjlKwuwy1AxEyqpaCLI1raoOFCa9YbrChDtNJp5cLq2z6CZzU\nt19swf9G6W9RbKi8NUGeu1M=\n-----END PRIVATE KEY-----\n", + "client_email": "firebase-adminsdk-m6ypm@imex-prod.iam.gserviceaccount.com", + "client_id": "107364429775431537388", + "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-m6ypm%40imex-prod.iam.gserviceaccount.com" +}