diff --git a/.badges/coverage.svg b/.badges/coverage.svg
index f3c5605..b7e5b4d 100644
--- a/.badges/coverage.svg
+++ b/.badges/coverage.svg
@@ -10,8 +10,8 @@
Coverage
Coverage
- 76%
- 76%
+ 76%
+ 76%
\ No newline at end of file
diff --git a/.badges/file-count.svg b/.badges/file-count.svg
index 54ad8d7..7b0eb48 100644
--- a/.badges/file-count.svg
+++ b/.badges/file-count.svg
@@ -1,6 +1,6 @@
-
\ No newline at end of file
diff --git a/nodemon.json b/nodemon.json
index 61fb5c1..18201ef 100644
--- a/nodemon.json
+++ b/nodemon.json
@@ -1,4 +1,4 @@
{
"ignore": [".git", "node_modules/**/node_modules", "server/super_admin/**"],
- "watch": ["server/**", "public/**", "server/schema.sql"]
+ "watch": ["server/**", "server/schema.sql"]
}
diff --git a/public/util/Auth.js b/public/util/Auth.js
index e64a27a..ac75fc5 100644
--- a/public/util/Auth.js
+++ b/public/util/Auth.js
@@ -64,7 +64,7 @@ export async function login() {
console.log('Logging in...');
if (auth.currentUser) {
// use firebase auth information if available (otherwise we rely on the existing idtoken session storage item if it has been set)
- let idToken = await auth.currentUser.getIdToken(/* forceRefresh */ true);
+ const idToken = await auth.currentUser.getIdToken(/* forceRefresh */ true);
sessionStorage.setItem('idtoken', idToken);
} else if (!sessionStorage.getItem('idtoken')) return false;
const res = await GET('/isLoggedIn');
diff --git a/public/util/Client.js b/public/util/Client.js
index 0bfc60b..734c0b6 100644
--- a/public/util/Client.js
+++ b/public/util/Client.js
@@ -9,7 +9,7 @@ export const IS_SAFARI = /^((?!chrome|android).)*safari/i.test(navigator.userAge
/** Requests a resource from the server. Should only retrieve data */
export async function GET(url) {
return await fetch(SERVER_URL + url, {
- headers: { idtoken: sessionStorage.getItem('idtoken') },
+ headers: { Authorization: 'Bearer ' + sessionStorage.getItem('idtoken') },
});
}
@@ -20,7 +20,7 @@ export async function POST(url, data) {
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
- idtoken: sessionStorage.getItem('idtoken'),
+ Authorization: 'Bearer ' + sessionStorage.getItem('idtoken'),
},
body: JSON.stringify(data),
});
@@ -33,7 +33,7 @@ export async function PATCH(url, data) {
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
- idtoken: sessionStorage.getItem('idtoken'),
+ Authorization: 'Bearer ' + sessionStorage.getItem('idtoken'),
},
body: JSON.stringify(data),
});
@@ -43,7 +43,7 @@ export async function PATCH(url, data) {
export async function DELETE(url) {
return await fetch(SERVER_URL + url, {
method: 'DELETE',
- headers: { idtoken: sessionStorage.getItem('idtoken') },
+ headers: { Authorization: 'Bearer ' + sessionStorage.getItem('idtoken') },
});
}
@@ -54,7 +54,7 @@ export async function PUT(url, data) {
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
- idtoken: sessionStorage.getItem('idtoken'),
+ Authorization: 'Bearer ' + sessionStorage.getItem('idtoken'),
},
body: JSON.stringify(data),
});
diff --git a/scripts/badges.js b/scripts/badges.js
index fa5b42b..3651105 100644
--- a/scripts/badges.js
+++ b/scripts/badges.js
@@ -1,6 +1,8 @@
const fs = require('fs');
const exec = require('child_process').exec;
+if (!fs.existsSync('./.badges')) fs.mkdirSync('./.badges');
+
function createBadge(label, value, leftWidth, rightWidth, color, filename) {
const totalWidth = leftWidth + rightWidth;
const svg = /*html*/ `
@@ -18,10 +20,10 @@ function createBadge(label, value, leftWidth, rightWidth, color, filename) {
}" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)">${label}
${label}
${value}
${value}
diff --git a/server/Auth.js b/server/Auth.js
index dc034ca..7784894 100644
--- a/server/Auth.js
+++ b/server/Auth.js
@@ -111,11 +111,11 @@ async function getAccess(uid, businessId, requiredPrivileges = {}) {
* @effects sends response status error codes for failed auth
*/
async function handleAuth(request, response, businessId = false, requiredPrivileges = {}) {
- if (!request.headers.idtoken) {
+ if (!request.headers.authorization || !request.headers.authorization.startsWith('Bearer ')) {
response.status(400).send('No idtoken provided, user does not appear to be signed in');
return false;
}
- const uid = await getUID(request.headers.idtoken);
+ const uid = await getUID(request.headers.authorization.substring(7));
if (!uid) {
response.status(401).send('Idtoken is invalid, login has likely expired');
return false;
diff --git a/test/utils.js b/test/captureConsole.js
similarity index 100%
rename from test/utils.js
rename to test/captureConsole.js
diff --git a/test/client.test.js b/test/client.test.js
index b8fddaf..b41bff6 100644
--- a/test/client.test.js
+++ b/test/client.test.js
@@ -5,7 +5,7 @@ const assert = require('node:assert');
// eslint-disable-next-line no-unused-vars
const { Builder, Browser, By, Key, until, WebDriver } = require('selenium-webdriver'); // read about selenium here: https://www.selenium.dev/documentation/en/webdriver/
const chrome = require('selenium-webdriver/chrome'); // read about chrome options here: https://chromedriver.chromium.org/capabilities
-const { captureConsole } = require('./utils.js');
+const { captureConsole } = require('./captureConsole.js');
captureConsole('./test.client.log');
describe('Client', () => {
diff --git a/test/server.test.js b/test/server.test.js
index 8f38547..05cc032 100644
--- a/test/server.test.js
+++ b/test/server.test.js
@@ -4,7 +4,7 @@ const { describe, it, before, beforeEach } = require('node:test'); // read about
const assert = require('node:assert');
const request = require('supertest'); // we use supertest to test HTTP requests/responses. Read more here: https://github.com/ladjs/supertest
const { v4 } = require('uuid');
-const { captureConsole } = require('./utils.js');
+const { captureConsole } = require('./captureConsole.js');
captureConsole('./test.server.log');
// import code to test
@@ -145,16 +145,24 @@ describe('Server', () => {
request(app).get('/isLoggedIn').expect(400).end(done);
});
it('Should return 401 Unauthorized when an invalid token is provided', (t, done) => {
- request(app).get('/isLoggedIn').set('idtoken', INVALID_TOKEN).expect(401).end(done);
+ request(app)
+ .get('/isLoggedIn')
+ .set('Authorization', 'Bearer ' + INVALID_TOKEN)
+ .expect(401)
+ .end(done);
});
it('Should return 401 Unauthorized when a valid but expired token is provided', (t, done) => {
- request(app).get('/isLoggedIn').set('idToken', EXPIRED_TOKEN).expect(401).end(done);
+ request(app)
+ .get('/isLoggedIn')
+ .set('Authorization', 'Bearer ' + EXPIRED_TOKEN)
+ .expect(401)
+ .end(done);
});
it('Should return 200 OK and the correct userid when a valid token is provided', (t, done) => {
mockToken(t);
request(app)
.get('/isLoggedIn')
- .set('idToken', VALID_TOKEN)
+ .set('Authorization', 'Bearer ' + VALID_TOKEN)
.expect(200)
.expect('Content-Type', /text/)
.expect(VALID_AUTH.user_id)
@@ -274,14 +282,14 @@ describe('Server', () => {
]);
await request(app)
.get('/businesses/1/joincode')
- .set('idToken', VALID_TOKEN)
+ .set('Authorization', 'Bearer ' + VALID_TOKEN)
.expect(403);
});
it('Should create a new user when handleAuth is called with a valid but unseen userid', async t => {
mockToken(t);
await request(app)
.get('/isLoggedIn')
- .set('idToken', VALID_TOKEN)
+ .set('Authorization', 'Bearer ' + VALID_TOKEN)
.expect(200)
.expect('Content-Type', /text/)
.expect(VALID_AUTH.user_id);
@@ -388,7 +396,7 @@ describe('Server', () => {
mockToken(t);
await request(app)
.get('/businesses')
- .set('idToken', VALID_TOKEN)
+ .set('Authorization', 'Bearer ' + VALID_TOKEN)
.expect(200)
.expect('Content-Type', /json/)
.expect([
@@ -412,7 +420,7 @@ describe('Server', () => {
mockToken(t);
await request(app)
.put('/businesses/' + businessId1 + '/name')
- .set('idToken', VALID_TOKEN)
+ .set('Authorization', 'Bearer ' + VALID_TOKEN)
.query({ new: 'testname2' })
.expect(200);
@@ -431,7 +439,7 @@ describe('Server', () => {
mockToken(t);
await request(app)
.put('/businesses/' + businessId2 + '/name')
- .set('idToken', VALID_TOKEN)
+ .set('Authorization', 'Bearer ' + VALID_TOKEN)
.query({ new: 'testname2' })
.expect(403);
@@ -444,7 +452,7 @@ describe('Server', () => {
mockToken(t);
await request(app)
.put('/businesses/' + businessId2 + '/name')
- .set('idToken', VALID_TOKEN)
+ .set('Authorization', 'Bearer ' + VALID_TOKEN)
.query({ new: 'testname2' })
.expect(403);
});
@@ -461,14 +469,14 @@ describe('Server', () => {
skipTokenVerification(t, 'testuid', 'testname', 'testemail');
const res = await request(app)
.get('/businesses/' + businessId + '/joincode')
- .set('idToken', 'testtoken')
+ .set('Authorization', 'Bearer testtoken')
.expect(200)
.expect('Content-Type', /json/);
mockToken(t);
const joincode = JSON.parse(res.text).joincode;
await request(app)
.post('/businesses/' + businessId + '/members')
- .set('idToken', VALID_TOKEN)
+ .set('Authorization', 'Bearer ' + VALID_TOKEN)
.query({ joincode: joincode })
.expect(200);
const members = await db().all(
@@ -490,14 +498,14 @@ describe('Server', () => {
skipTokenVerification(t, 'testuid', 'testname', 'testemail');
const res = await request(app)
.get('/businesses/' + businessId1 + '/joincode')
- .set('idToken', 'testtoken')
+ .set('Authorization', 'Bearer testtoken')
.expect(200)
.expect('Content-Type', /json/);
mockToken(t);
const joincode = JSON.parse(res.text).joincode;
await request(app)
.post('/businesses/' + businessId2 + '/members')
- .set('idToken', VALID_TOKEN)
+ .set('Authorization', 'Bearer ' + VALID_TOKEN)
.query({ joincode: joincode })
.expect(403);
const members = await db().all(
@@ -533,11 +541,11 @@ describe('Server', () => {
mockToken(t, 2);
await request(app)
.delete('/businesses/' + businessId1 + '/members/me')
- .set('idToken', VALID_TOKEN)
+ .set('Authorization', 'Bearer ' + VALID_TOKEN)
.expect(200);
await request(app)
.delete('/businesses/' + businessId2 + '/members/me')
- .set('idToken', VALID_TOKEN)
+ .set('Authorization', 'Bearer ' + VALID_TOKEN)
.expect(403);
});
it('Should only allow kicking non-owner members', async t => {
@@ -567,17 +575,17 @@ describe('Server', () => {
// owner can't be removed
await request(app)
.delete('/businesses/' + businessId + '/members/' + VALID_AUTH.user_id)
- .set('idToken', VALID_TOKEN)
+ .set('Authorization', 'Bearer ' + VALID_TOKEN)
.expect(400);
// member can be removed
await request(app)
.delete('/businesses/' + businessId + '/members/testuid')
- .set('idToken', VALID_TOKEN)
+ .set('Authorization', 'Bearer ' + VALID_TOKEN)
.expect(200);
// non-member can't be removed
await request(app)
.delete('/businesses/' + businessId + '/members/testuid')
- .set('idToken', VALID_TOKEN)
+ .set('Authorization', 'Bearer ' + VALID_TOKEN)
.expect(400);
});
it('Should return the correct attendance data for a business', async t => {
@@ -616,7 +624,7 @@ describe('Server', () => {
mockToken(t, 1);
await request(app)
.get('/businesses/' + businessId + '/attendance')
- .set('idToken', VALID_TOKEN)
+ .set('Authorization', 'Bearer ' + VALID_TOKEN)
.expect(200)
.expect('Content-Type', /json/)
.expect([
@@ -708,7 +716,7 @@ describe('Server', () => {
mockToken(t, 1);
await request(app)
.get('/businesses/' + businessId1)
- .set('idToken', VALID_TOKEN)
+ .set('Authorization', 'Bearer ' + VALID_TOKEN)
.query({ businessId: businessId1 })
.expect(200)
.expect('Content-Type', /json/)
@@ -751,19 +759,19 @@ describe('Server', () => {
// don't allow setting owner role
await request(app)
.put('/businesses/' + businessId + '/members/testuid/role')
- .set('idToken', VALID_TOKEN)
+ .set('Authorization', 'Bearer ' + VALID_TOKEN)
.query({ new: 'owner' })
.expect(403);
// don't allow changing the owner's role
await request(app)
.put('/businesses/' + businessId + '/members/' + VALID_AUTH.user_id + '/role')
- .set('idToken', VALID_TOKEN)
+ .set('Authorization', 'Bearer ' + VALID_TOKEN)
.query({ new: 'admin' })
.expect(403);
// allow setting other roles
await request(app)
.put('/businesses/' + businessId + '/members/testuid/role')
- .set('idToken', VALID_TOKEN)
+ .set('Authorization', 'Bearer ' + VALID_TOKEN)
.query({ new: 'admin' })
.expect(200);
const members = await db().all(
@@ -777,12 +785,12 @@ describe('Server', () => {
mockToken(t, 2);
await request(app)
.put('/username')
- .set('idToken', VALID_TOKEN)
+ .set('Authorization', 'Bearer ' + VALID_TOKEN)
.query({ new: 'testname' })
.expect(200);
await request(app)
.get('/username')
- .set('idToken', VALID_TOKEN)
+ .set('Authorization', 'Bearer ' + VALID_TOKEN)
.expect(200)
.expect('Content-Type', /json/)
.expect({ name: 'testname' });