Skip to content

Commit

Permalink
Protected routes have token refresh method, all CRUD methods work wit…
Browse files Browse the repository at this point in the history
…h the user database and firebase console (#37)

* protected routes have method to refresh token, all CRUD Methods work with the database and firebase console.

* took out console logs

* removed test code

---------

Co-authored-by: subinqkim <[email protected]>
Co-authored-by: michellelin1 <[email protected]>
  • Loading branch information
3 people authored Jan 23, 2024
1 parent 39cccb0 commit 1e5863b
Show file tree
Hide file tree
Showing 9 changed files with 1,067 additions and 7 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ dist
# DynamoDB Local files
.dynamodb/

# firebase sdk
firebase-adminsdk.json

# TernJS port file
.tern-port

Expand Down
3 changes: 3 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ require('dotenv').config();
// routes
const users = require('./routes/users');

const { authRouter } = require('./routes/auth');

const email = require('./routes/nodeMailer');

const app = express();
Expand All @@ -30,6 +32,7 @@ app.use('/published-schedule', publishedScheduleRouter);
app.use('/users', users);
app.use('/catalog', catalogRouter);
app.use('/nodeMailer', email);
app.use('/auth', authRouter);

app.listen(PORT, () => {
console.log(`Server listening on ${PORT}`);
Expand Down
9 changes: 9 additions & 0 deletions firebase.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const admin = require('firebase-admin');

require('dotenv').config();

const credentials = require('./firebase-adminsdk.json');

admin.initializeApp({ credential: admin.credential.cert(credentials) });

module.exports = admin;
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"eslint-plugin-prettier": "^4.0.0",
"express": "^4.17.1",
"express-promise-router": "^4.1.1",
"firebase-admin": "^12.0.0",
"nodemailer": "^6.9.7",
"nodemon": "^2.0.14",
"pg": "^8.8.0",
Expand Down
41 changes: 41 additions & 0 deletions routes/auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
const express = require('express');

const authRouter = express();
const admin = require('../firebase');

authRouter.use(express.json());

// This method makes a call to Firebase that will verify the access token attached to the request's cookies
// This method is used to make sure that only users who have appropriate access tokens can access backend routes.
const verifyToken = async (req, res, next) => {
try {
const {
cookies: { accessToken },
} = req;
if (!accessToken) {
return res.status(400).send('@verifyToken no access token');
}
const decodedToken = await admin.auth().verifyIdToken(accessToken);
if (!decodedToken) {
return res.status(400).send('Empty token from firebase');
}
return next();
} catch (err) {
return res.status(400).send('@verifyToken no access token');
}
};

// This method makes a call to firebase that will verify the access token attached to the request's cookies
// This method is used to make sure that only users who have appropriate access tokens can access frontend routes.
authRouter.get('/verifyToken/:accessToken', async (req, res) => {
try {
const { accessToken } = req.params;
const decodedToken = await admin.auth().verifyIdToken(accessToken);
return res.status(200).send(decodedToken.uid);
} catch (err) {
console.log('err', err);
return res.status(400).send('@verifyToken no access token');
}
});

module.exports = { verifyToken, authRouter };
2 changes: 0 additions & 2 deletions routes/nodeMailer.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ emailRouter.use(express.json());

emailRouter.post('/send', (req, res) => {
const { email, messageHtml, subject } = req.body;
console.log('req.body', req.body);
console.log('email', email);
const mail = {
from: `${process.env.REACT_APP_EMAIL_FIRST_NAME} ${process.env.REACT_APP_EMAIL_LAST_NAME} ${process.env.REACT_APP_EMAIL_USERNAME}`,
to: email,
Expand Down
23 changes: 21 additions & 2 deletions routes/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ const { db } = require('../server/db');

const userRouter = express.Router();

const admin = require('../firebase');

userRouter.get('/', async (req, res) => {
try {
const allUsers = await db.query(`SELECT * FROM users;`);
Expand All @@ -13,6 +15,17 @@ userRouter.get('/', async (req, res) => {
}
});

// logInWithEmailAndPassword() needs to get specific user id
userRouter.get('/:uid', async (req, res) => {
try {
const { uid } = req.params;
const user = await db.query(`SELECT * FROM users WHERE id = $1;`, [uid]);
res.status(200).json(keysToCamel(user));
} catch (err) {
res.status(500).send(err.message);
}
});

userRouter.get('/pending-accounts', async (req, res) => {
try {
const pendingAccounts = await db.query(`SELECT * FROM users WHERE approved = FALSE;`);
Expand All @@ -22,9 +35,10 @@ userRouter.get('/pending-accounts', async (req, res) => {
}
});

userRouter.post('/', async (req, res) => {
userRouter.post('/create', async (req, res) => {
try {
const { id, email, type, approved } = req.body;
// console.log('req.body', req.body);
await db.query(`INSERT INTO users (id, email, "type", approved) VALUES ($1, $2, $3, $4);`, [
id,
email,
Expand All @@ -35,14 +49,15 @@ userRouter.post('/', async (req, res) => {
id,
});
} catch (err) {
console.log('err', err);
res.status(500).json({
status: 'Failed',
msg: err.message,
});
}
});

userRouter.put('/:uid', async (req, res) => {
userRouter.put('/approve/:uid', async (req, res) => {
try {
const { uid } = req.params;
const updatedApproval = await db.query(
Expand All @@ -58,6 +73,10 @@ userRouter.put('/:uid', async (req, res) => {
userRouter.delete('/:uid', async (req, res) => {
try {
const { uid } = req.params;

// Firebase delete
await admin.auth().deleteUser(uid);

const deletedUser = await db.query(`DELETE FROM users WHERE id = $1 RETURNING *;`, [uid]);
res.status(200).send(keysToCamel(deletedUser));
} catch (err) {
Expand Down
1 change: 1 addition & 0 deletions transporter.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const nodemailer = require('nodemailer');
require('dotenv').config();

// sender information

const transport = {
host: 'smtp.gmail.com', // e.g. smtp.gmail.com
auth: {
Expand Down
Loading

0 comments on commit 1e5863b

Please sign in to comment.