Skip to content

Commit 3335a67

Browse files
Migration to firebase Authentication (#72)
Squashed and merge commits. Read the complete list of changes in PR #72 Replaced custom JWT Authentication with firebase Authentication integration Rewrote test cases with firebase Authentication integration Disabled auth API endpoint (May be removed in future commits) Refactored and added firebase Authentication support in the GitHub Actions continuous integration
1 parent 283be6f commit 3335a67

39 files changed

+1559
-631
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
version: '3.8'
2+
3+
services:
4+
mongo:
5+
image: mongo
6+
restart: always
7+
environment:
8+
MONGO_INITDB_ROOT_USERNAME: root
9+
MONGO_INITDB_ROOT_PASSWORD: password
10+
volumes:
11+
- db-data:/data/db
12+
13+
app:
14+
depends_on:
15+
- mongo
16+
build:
17+
context: '${GITHUB_WORKSPACE}'
18+
dockerfile: Dockerfile-ci
19+
environment:
20+
- TEST_FIREBASE_CLIENT_API_KEY=${TEST_FIREBASE_CLIENT_API_KEY}
21+
- GOOGLE_APPLICATION_CREDENTIALS=${GOOGLE_APPLICATION_CREDENTIALS}
22+
ports:
23+
- 8080:8080
24+
command: 'npm run test-ci'
25+
26+
volumes:
27+
db-data:

.github/ci/firebase.gpg

1.7 KB
Binary file not shown.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/bin/sh
2+
3+
# Script to decrypt firebase secret
4+
5+
# Create the environment and decrypt the file
6+
mkdir $HOME/secrets
7+
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPTION_PASSPHRASE" --output firebase_secret.json ./.github/ci/firebase.gpg

.github/workflows/app-test-container.yml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,13 @@ jobs:
2222
- name: docker layer caching
2323
uses: satackey/action-docker-layer-caching@v0.0.8
2424
continue-on-error: true
25+
- name: descrypt firebase secret
26+
run: ./.github/scripts/decrypt_firebase_secret.sh
27+
env:
28+
DECRYPTION_PASSPHRASE: ${{ secrets.DECRYPTION_PASSPHRASE }}
2529
- name: Run test in container
26-
run: docker-compose --file docker-compose-test-ci.yml up --build --exit-code-from app
30+
shell: bash
31+
env:
32+
TEST_FIREBASE_CLIENT_API_KEY: ${{ secrets.TEST_FIREBASE_CLIENT_API_KEY }}
33+
GOOGLE_APPLICATION_CREDENTIALS: ./firebase_secret.json
34+
run: docker-compose --file ./.github/ci/docker-compose-test-ci.yml up --build --exit-code-from app

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,6 @@ dist
102102

103103
# TernJS port file
104104
.tern-port
105+
106+
# custom
107+
*firebase-adminsdk*.json

Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ COPY . .
2121
# The container environmental variables.
2222
ENV PORT=8080
2323
ENV MONGODB_URI=mongodb://root:password@mongo:27017/softwareRepository?authSource=admin
24-
ENV BCRYPT_SALT_ROUNDS=YOUR_BCRYPT_SALT_ROUNDS
2524
ENV TEST_MONGODB_URI=mongodb://root:password@mongo:27017/softwareRepositoryTest?authSource=admin
26-
ENV JWT_SECRET=YOUR_JWT_SECRET
25+
ENV TEST_FIREBASE_CLIENT_API_KEY=YOUR_TEST_FIREBASE_CLIENT_API_KEY
26+
ENV GOOGLE_APPLICATION_CREDENTIALS=YOUR_GOOGLE_SERVICE_ACCOUNT_FILE_PATH
2727

2828
# The container listens on port 8080.
2929
EXPOSE 8080

Dockerfile-ci

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# SoftwareRepository's Dockerfile
2+
# With comments to aid in my learning of docker.
3+
4+
# To use official nodejs base docker image.
5+
FROM node:12
6+
7+
# The working directory where any subsequent instructions in the Dockerfile will be executed on.
8+
WORKDIR /app
9+
10+
# I want to install dependencies first so they can be cache.
11+
# Hence, I copy the package.json file first to the work directory for installing the dependencies in the subsequent command (npm install).
12+
COPY package.json .
13+
14+
# Run npm install to install the dependencies specified in package.json
15+
RUN npm install
16+
17+
# After the dependencies are installed, I copy over the source code of the web application to the current working directory.
18+
# Note: In this case, I add .dockerignore file (similar to .gitignore) and add node_modules to the .dockerignore file so that my local node_modules directory will not be copied to the container's working directory.
19+
COPY . .
20+
21+
# The container environmental variables.
22+
ENV PORT=8080
23+
ENV MONGODB_URI=mongodb://root:password@mongo:27017/softwareRepository?authSource=admin
24+
ENV TEST_MONGODB_URI=mongodb://root:password@mongo:27017/softwareRepositoryTest?authSource=admin
25+
ENV TEST_FIREBASE_CLIENT_API_KEY=YOUR_TEST_FIREBASE_CLIENT_API_KEY
26+
ENV GOOGLE_APPLICATION_CREDENTIALS=YOUR_GOOGLE_SERVICE_ACCOUNT_FILE_PATH
27+
28+
# The container listens on port 8080.
29+
EXPOSE 8080
30+
31+
# Should only have one cmd in a Dockerfile. Tells container how to run the application.
32+
# In this case, the command is npm start.
33+
# An exec form (Array of strings). It does not start up a shell session unlike run.
34+
CMD ["npm", "start"]

app.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ const usersRouter = require('./routes/api/users');
1010

1111
const middleware = require('./utils/middleware');
1212
const logger = require('./utils/logger');
13-
const loginRouter = require('./routes/api/auth');
14-
const softwaresRouter = require('./routes/api/softwares');
13+
const authRouter = require('./routes/api/auth');
14+
const softwareRouter = require('./routes/api/software');
1515

1616
const app = express();
1717

@@ -59,8 +59,8 @@ app.use(
5959
// Routes
6060
app.use(rootRouter);
6161
app.use('/api/users', usersRouter);
62-
app.use('/api/auth', loginRouter);
63-
app.use('/api/softwares', softwaresRouter);
62+
app.use('/api/auth', authRouter);
63+
app.use('/api/software', softwareRouter);
6464

6565
app.use(middleware.unknownEndPoint);
6666
app.use(middleware.errorHandler);

controllers/api/authController.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,9 @@ const postAuth = async (req, res) => {
1515
},
1616
);
1717

18-
const passwordCorrect =
19-
user === null
20-
? false
21-
: await bcrypt.compare(body.password, user.passwordHash);
18+
const passwordCorrect = user === null
19+
? false
20+
: await bcrypt.compare(body.password, user.passwordHash);
2221

2322
if (!(user && passwordCorrect)) {
2423
return res.status('401').json({

controllers/api/softwaresController.js renamed to controllers/api/softwareController.js

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ const Software = require('../../models/software');
33
const User = require('../../models/user');
44
const databaseUtils = require('../../utils/databaseUtils');
55

6-
const getSoftwares = async (req, res) => {
6+
const getSoftware = async (req, res) => {
77
const softwares = await Software.find({})
88
.populate('meta.addedByUser', {
99
username: 1,
@@ -16,9 +16,9 @@ const getSoftwares = async (req, res) => {
1616
res.status(200).json(softwares);
1717
};
1818

19-
const postSoftwares = async (req, res) => {
19+
const postSoftware = async (req, res) => {
2020
const { body } = req;
21-
const userId = body.decodedToken.id;
21+
const userId = body.decodedToken.backendId;
2222

2323
// Refer to software Model for required parameters.
2424
const softwareObject = {
@@ -60,10 +60,10 @@ const postSoftwares = async (req, res) => {
6060
return res.status(201).json(saved);
6161
};
6262

63-
const putSoftware = async (req, res) => {
63+
const patchSoftwareById = async (req, res) => {
6464
const { id } = req.params;
6565
const { body } = req;
66-
const userId = body.decodedToken.id;
66+
const userId = body.decodedToken.backendId;
6767

6868
// To configure dotObject transformation to not modify how the array is represented.
6969
dotObject.keepArray = true;
@@ -103,7 +103,7 @@ const putSoftware = async (req, res) => {
103103
return res.status(200).json(updated);
104104
};
105105

106-
const getSoftware = async (req, res) => {
106+
const getSoftwareById = async (req, res) => {
107107
const { id } = req.params;
108108

109109
const software = await Software.findById(id);
@@ -120,7 +120,7 @@ const getSoftware = async (req, res) => {
120120
return res.status(200).json(response);
121121
};
122122

123-
const deleteSoftware = async (req, res) => {
123+
const deleteSoftwareById = async (req, res) => {
124124
const { id } = req.params;
125125

126126
const response = await Software.findByIdAndDelete(id);
@@ -136,9 +136,9 @@ const deleteSoftware = async (req, res) => {
136136
};
137137

138138
module.exports = {
139-
getSoftwares,
140-
postSoftwares,
141-
putSoftware,
142139
getSoftware,
143-
deleteSoftware,
140+
postSoftware,
141+
patchSoftwareById,
142+
getSoftwareById,
143+
deleteSoftwareById,
144144
};

0 commit comments

Comments
 (0)