Skip to content

Commit

Permalink
added compresion; removed extraneous console logs; added attendqr.com…
Browse files Browse the repository at this point in the history
… to cors whitelist
  • Loading branch information
SanderGi committed Apr 14, 2024
1 parent 8b4718a commit 6d9df76
Show file tree
Hide file tree
Showing 9 changed files with 47 additions and 137 deletions.
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
![Tests](https://github.com/clr-li/AttendanceScanner/actions/workflows/tests.yml/badge.svg)
[![Coverage](./.badges/coverage.svg)](https://github.com/clr-li/AttendanceScanner)

This project uses QR codes to take attendance and a SQLite database to store data of businesses, attendees, and events. It uses oauth2 through Firebase Auth to authenticate users using Google as the identity provider and has custom authorization logic. Braintree is used as the payment gateway for the electronic payment/subscription system. Automated tests are written using Node Test Runner and Selenium and CI/CD run through Github Actions.
This project uses QR codes to take attendance and a SQLite database to store data of groups, attendees, and events. It uses oauth2 through Firebase Auth to authenticate users has custom authorization logic. Braintree is used as the payment gateway for the electronic payment/subscription system. Automated tests are written using Node Test Runner and Selenium and run through Github Actions. Deployment is done via a docker container with the Node.js express app on Fly.io and static files via Firebase Hosting.
URL: https://attendancescannerqr.web.app

# Development
Expand Down Expand Up @@ -40,22 +40,25 @@ URL: https://attendancescannerqr.web.app
- To only deploy static files: `npm run deploy:fire`
- To run the server locally with production settings: `npm run docker:build && npm run docker:run`

### Update database
### Update Database

- To update the database schema, change the `schema.sql` file accordingly (note this file should only contain DDL statements). If you are running the `npm run dev` server, a new migration file will automatically be created in the `migration` folder and applied locally. Otherwise, you can run `sam make` to create it and `sam migrate` to apply it locally. Run `sam status` to verify your changes and optionally inspect the autocreated migration file. Once you are satisfied everything is in order, `npm run deploy` changes like normal and the production server will automatically apply the new migration file.
- To purge the Braintree payment vault test data, login to the Braintree sandbox, click the gear icon and select "Purge Test Data"

### Manage Deployment
## Manage Deployment

- Configure server: [fly.io](https://fly.io/apps/attendqr)
- [Memory usage and requests dashboard](https://fly-metrics.net/d/fly-app/fly-app?orgId=726754)
- [View logs](https://fly-metrics.net/d/fly-logs/fly-logs?orgId=726754&var-app=attendqr)
- [Invite team members](https://fly.io/dashboard/alexander-metzger/team)
- Configure firebase: [firebase console](https://console.firebase.google.com/u/0/project/attendancescannerqr/overview)
- [Configure auth](https://console.firebase.google.com/u/0/project/attendancescannerqr/authentication/users)
- [Docs for static file hosting](https://firebase.google.com/docs/hosting)
- [Configure hosting](https://console.firebase.google.com/u/0/project/attendancescannerqr/hosting/sites/attendancescannerqr)
- Configure Braintree: [sandbox](https://sandbox.braintreegateway.com/login)
- [Docs for testing](https://developers.braintreepayments.com/start/hello-server/node)
- [Docs for production](https://developer.paypal.com/braintree/docs/start/go-live/node)
- Configure Cloudflare: [domains](https://dash.cloudflare.com/ff1b48a9d7c023abb7950e2e6f3a7f7e/domains/attendqr.com)
- [attendqr.com](https://dash.cloudflare.com/ff1b48a9d7c023abb7950e2e6f3a7f7e/attendqr.com)

## Automated Testing

Expand Down
150 changes: 28 additions & 122 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"dependencies": {
"body-parser": "^1.20.1",
"braintree": "^3.13.0",
"compression": "^1.7.4",
"cors": "^2.8.5",
"express": "^4.18.2",
"express-admin": "^2.0.0",
Expand Down
1 change: 0 additions & 1 deletion server/Auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,6 @@ async function handleAuth(request, response, businessId = false, requiredPrivile
router.get('/isLoggedIn', async (request, response) => {
const uid = await handleAuth(request, response);
if (!uid) return;
console.log('logged in: ' + uid);
response.send(uid);
});

Expand Down
2 changes: 0 additions & 2 deletions server/Business.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ async function createBusiness(uid, name, subscriptionId) {
await db().run(
...SQL`INSERT INTO Members (business_id, user_id, role) VALUES (${businessId}, ${uid}, 'owner')`,
);
console.log('Created new business with id: ' + businessId);
return businessId;
}

Expand All @@ -37,7 +36,6 @@ async function deleteBusiness(businessId) {
await db().run(...SQL`DELETE FROM Events WHERE business_id = ${businessId}`);
await db().run(...SQL`DELETE FROM Members WHERE business_id = ${businessId}`);
await db().run(...SQL`DELETE FROM Businesses WHERE id = ${businessId}`);
console.log('Deleted the business with id: ' + businessId);
}

// ============================ BUSINESS ROUTES ============================
Expand Down
2 changes: 1 addition & 1 deletion server/Database.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ async function reinitializeIfNotExists(dbFile = ':memory:', schemaFile = './serv
else console.log('Database file not found (creating a new one): ' + dbFile);

if (db) await db.close();
db = await Database.connect(dbFile);
db = await Database.connect(dbFile, undefined, process.env.DEVELOPMENT === 'true');
await db.run('PRAGMA foreign_keys = ON;');

if (dbFile === ':memory:' || dbFile === '') {
Expand Down
1 change: 1 addition & 0 deletions server/Event.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ function createEventSequence(
if (frequency === 'daily') current.setDate(current.getDate() + interval);
else if (frequency === 'weekly') current.setDate(current.getDate() + 7 * interval);
else if (frequency === 'monthly') current.setMonth(current.getMonth() + interval);
else throw new Error('Invalid frequency');
}
}

Expand Down
4 changes: 0 additions & 4 deletions server/Payment.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ async function getClientToken(uid) {
.get(...SQL`SELECT customer_id FROM Users WHERE id = ${uid}`)
.then(row => row?.customer_id);
const tokenOptions = {};
console.log('CustomerId requested a client token: ' + customerId);
if (customerId) {
tokenOptions.customerId = customerId;
tokenOptions.options = {
Expand Down Expand Up @@ -168,8 +167,6 @@ router.post('/checkout', async (request, response) => {
const customerId = customer.id; // e.g 160923
paymentToken = customer.paymentMethods[0].token; // e.g f28wm

console.log('Created customer with id: ' + customerId);

// save customer id in database so we can find their information in the braintree vault later
await db().run(...SQL`UPDATE Users SET customer_id = ${customerId} WHERE id = ${uid}`);
}
Expand All @@ -187,7 +184,6 @@ router.post('/checkout', async (request, response) => {
);
return;
}
console.log('Added subscription via paymentToken: ' + paymentToken);
const businessId = await createBusiness(uid, businessName, subscriptionResult.subscription.id);

response.status(200);
Expand Down
12 changes: 9 additions & 3 deletions server/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,22 @@ const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json({ limit: '10mb' }));

// cors - make server endpoints available on firebase domain
// compression - compresses responses to reduce latency
const compression = require('compression');
app.use(compression());

// cors - make server endpoints available on production domain
const cors = require('cors');
let corsOptions = {
origin: 'https://attendancescannerqr.web.app',
origin: 'https://attendqr.com',
};
app.use(cors(corsOptions));

// ============================ PUBLIC (STATIC) FILES ============================
// http://expressjs.com/en/starter/static-files.html
app.use(express.static('public'));
if (process.env.DEVELOPMENT === 'true') {
app.use(express.static('public'));
}

// ============================ DATABASE ============================
const schemaFile = './server/schema.sql'; // filepath for the database schema
Expand Down

0 comments on commit 6d9df76

Please sign in to comment.