This commit is contained in:
xfarrow 2023-10-13 10:37:09 +02:00
parent 69559fabec
commit 190313f1b1
3 changed files with 72 additions and 31 deletions

8
backend/apis/nodejs/.env Normal file
View File

@ -0,0 +1,8 @@
# Blink configuration file
API_SERVER_PORT = 3000
POSTGRES_SERVER = localhost
POSTGRES_USERNAME = postgres
POSTGRES_PASSWORD = postgres
POSTGRES_PORT = 5432

View File

@ -1,5 +1,4 @@
/* /*
This code is part of Blink This code is part of Blink
licensed under GPLv3 licensed under GPLv3
@ -8,27 +7,23 @@
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
*/ */
// require() always returns a function
const express = require('express'); const express = require('express');
const api_controller = require('./api_controller.js'); const api_controller = require('./api_controller.js');
require('dotenv').config();
// We can do express() because the express
// module exports a function. Exporting a function
// means making a JavaScript function defined in one
// module available for use in another module.
const app = express(); const app = express();
const port = 3000; const port = process.env.API_SERVER_PORT;
// Middleware which parses JSON for POST requests // Middleware which parses JSON for POST requests
app.use(express.json()); app.use(express.json());
app.post('/blinkapi/register', api_controller.register); app.post('/blinkapi/register', api_controller.register);
app.post('/blinkapi/login', api_controller.login); app.post('/blinkapi/login', api_controller.login);
app.get('/blinkapi/person/:id', api_controller.verifyToken, api_controller.person);
// Start the server // Start the server
app.listen(port, () => { app.listen(port, () => {

View File

@ -1,5 +1,4 @@
/* /*
This code is part of Blink This code is part of Blink
licensed under GPLv3 licensed under GPLv3
@ -8,24 +7,27 @@
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
*/ */
const bcrypt = require('bcrypt'); const bcrypt = require('bcrypt');
const crypto = require('crypto'); const crypto = require('crypto');
const pgp = require('pg-promise')(); const pgp = require('pg-promise')();
const jwt = require('jsonwebtoken'); const jwt = require('jsonwebtoken');
require('dotenv').config();
const database_configuration = { const database_configuration = {
host: "localhost", host: process.env.POSTGRES_SERVER,
port: 5432, port: process.env.POSTGRES_PORT,
database: "Blink", database: "Blink",
user: "postgres", user: process.env.POSTGRES_USERNAME,
password: "postgres" password: process.env.POSTGRES_PASSWORD
}; };
const db = pgp(database_configuration); const db = pgp(database_configuration);
// ======== API ENDPOINTS ========
// POST
async function register(req, res){ async function register(req, res){
const userData = req.body; const userData = req.body;
@ -83,7 +85,7 @@ async function register(req, res){
} }
} }
// When the user logs in, the API endpoint must generate a JWT // POST
async function login(req, res){ async function login(req, res){
const userData = req.body; const userData = req.body;
@ -96,7 +98,7 @@ async function login(req, res){
const person = await checkUserCredentials(userData.email, userData.password); const person = await checkUserCredentials(userData.email, userData.password);
if (person){ if (person){
const token = generateToken(person); const token = generateToken(person.id);
res.status(200).json({ token }); res.status(200).json({ token });
} }
else{ else{
@ -104,6 +106,26 @@ async function login(req, res){
} }
} }
// GET
async function person(req, res){
try {
const user = await db.oneOrNone('SELECT * FROM "Person" WHERE id = $1 and enabled = $2' , [req.params.id, false]);
if(user){
if(user.id == req.jwt.person_id || user.active == true){
return res.status(200).send(user);
}
}
return res.status(403);
}
catch (error) {
console.log(error);
return res.status(500);
}
}
// ======== END API ENDPOINTS ========
async function checkUserCredentials(email, password){ async function checkUserCredentials(email, password){
try { try {
const user = await db.oneOrNone('SELECT * FROM "Person" WHERE email = $1 and enabled = $2', [email, false]); const user = await db.oneOrNone('SELECT * FROM "Person" WHERE email = $1 and enabled = $2', [email, false]);
@ -121,24 +143,40 @@ async function checkUserCredentials(email, password){
} }
} }
function generateToken(person) { function generateToken(person_id) {
const payload = { const payload = {
id: person.id, person_id: person_id
email: person.email,
display_name: person.display_name,
date_of_birth: person.date_of_birth,
available: person.available,
enabled: person.enabled,
place_of_living: person.place_of_living
}; };
// const payload = person;
const token = jwt.sign(payload, 'your-secret-key', { expiresIn: '1h' }); const token = jwt.sign(payload, 'your-secret-key', { expiresIn: '1h' });
return token; return token;
} }
// Middlware
function verifyToken(req, res, next) {
const token = req.headers.authorization;
if (!token) {
return res.status(403).send('No token provided');
}
jwt.verify(token, 'your-secret-key', (err, decoded) => {
if (err) {
return res.status(401).send('Failed to authenticate token');
}
// If the token is valid, store the decoded data in the request object
req.jwt = decoded;
next();
});
}
// Exporting a function
// means making a JavaScript function defined in one
// module available for use in another module.
module.exports = { module.exports = {
register, register,
login login,
person,
verifyToken
}; };