Skip to content

Commit

Permalink
app final
Browse files Browse the repository at this point in the history
  • Loading branch information
danilocatapan authored Apr 17, 2020
1 parent bee16dc commit 6b88200
Show file tree
Hide file tree
Showing 39 changed files with 11,209 additions and 0 deletions.
38 changes: 38 additions & 0 deletions td-notes-app/app/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
const express = require('express');
const compression = require('compression');
const path = require('path');
const bodyParser = require('body-parser');
const cors = require('cors');

const appRoutes = require('./routes/app-routes');
const app = express();

app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');

app.use(cors());
app.use(compression());
app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, '../public')));
app.use(appRoutes);

// catch 404 and forward to error handler
app.use(function (req, res, next) {
// var err = new Error('Not Found');
// err.status = 404;
// next(err);
res.render('index');
});

// error handler
// will print stacktrace
app.use(function(err, req, res, next) {
console.log(err);
res.status(err.status || 500);
res.json({
message: err.message,
status: err.status
});
});

module.exports = app;
213 changes: 213 additions & 0 deletions td-notes-app/app/routes/app-routes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
const express = require('express');
const moment = require('moment');
const _ = require('underscore');
var request = require("request");

const uuidv4 = require('uuid/v4');
const jwtDecode = require('jwt-decode');

const router = express.Router();

const AWS = require('aws-sdk');
AWS.config.update({ region: 'us-west-2' });

const tableName = 'td_notes';
var user_id;
var user_name;

// Custom Auth Middleware to get Credentials from Cognito
var customAuth = function (req, res, next) {

let id_token = req.headers.authorization;
var decoded = jwtDecode(id_token);

AWS.config.credentials = new AWS.CognitoIdentityCredentials({
// IdentityPoolId: process.env.ID_POOL,
IdentityPoolId: 'INSERT_YOUR_COGNITO_POOL_ID_HERE',
Logins: {
'accounts.google.com': id_token
}
});

AWS.config.credentials.get((error) => {
user_id = AWS.config.credentials.identityId;
user_name = decoded.name;
if(user_id) {
//authentication successful
docClient = new AWS.DynamoDB.DocumentClient();
next();
} else {
//unauthorized
res.status(401).send();
}
});

};

router.post('/api/tokensignin', (req, res, next)=>{
let id_token = req.body.id_token;

let tokeninfoEndpoint = 'https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=' + id_token;

let options = {
url: tokeninfoEndpoint,
method: 'GET'
};

request(options, (error, response, body) => {
if(response && response.statusCode) {
return res.status(response.statusCode).send();
} else {
return res.status(400).send();
}
});
});

router.post('/api/note', customAuth, (req, res, next)=>{
let item = req.body.Item;
item.user_id = user_id;
item.user_name = user_name;
item.note_id = user_id + ':' + uuidv4();
item.timestamp = moment().unix();
item.expires = moment().add(90, 'days').unix();

docClient.put({
TableName : tableName,
Item: item
}, (err, data)=>{
if(err) {
console.log(err);
return res.status(err.statusCode).send({
message: err.message,
status: err.statusCode
});
} else {
return res.status(200).send(item);
}
});
});

router.patch('/api/note', customAuth, (req, res, next)=>{

let item = req.body.Item;
item.user_id = user_id;
item.user_name = user_name;
item.expires = moment().add(90, 'days').unix();

docClient.put({
TableName : tableName,
Item: item,
ConditionExpression: '#t = :t',
ExpressionAttributeNames: {
'#t': 'timestamp'
},
ExpressionAttributeValues: {
':t': item.timestamp
}
}, (err, data)=>{
if(err) {
console.log(err);
return res.status(err.statusCode).send({
message: err.message,
status: err.statusCode
});
} else {
return res.status(200).send(item);
}
});
});

router.get('/api/notes', customAuth, (req, res, next) => {

let limit = req.query.limit ? parseInt(req.query.limit) : 5;
let params = {
TableName: tableName,
KeyConditionExpression: "user_id = :uid",
ExpressionAttributeValues: {
":uid": user_id
},
Limit: limit,
ScanIndexForward: false
};

let startTimestamp = req.query.start ? parseInt(req.query.start) : 0;

if (startTimestamp > 0) {
params.ExclusiveStartKey = {
user_id: user_id,
timestamp: startTimestamp
}
}

docClient.query(params, (err, data)=>{
if(err) {
console.log(err);
return res.status(err.statusCode).send({
message: err.message,
status: err.statusCode
});
} else {
return res.status(200).send(data);
}
});
});

router.get('/api/note/:note_id', customAuth, (req, res, next) => {

let note_id = req.params.note_id;
let params = {
TableName: tableName,
IndexName: "note_id-index",
KeyConditionExpression: "note_id = :note_id",
ExpressionAttributeValues: {
":note_id": note_id
},
Limit: 1
};

docClient.query(params, (err, data)=>{
if(err) {
console.log(err);
return res.status(err.statusCode).send({
message: err.message,
status: err.statusCode
});
} else {
if(!_.isEmpty(data.Items)) {
return res.status(200).send(data.Items[0]);
} else {
return res.status(404).send();
}
}
});
});

router.delete('/api/note/:timestamp', customAuth, (req, res, next) => {
let timestamp = parseInt(req.params.timestamp);

let params = {
TableName: tableName,
Key: {
user_id: user_id,
timestamp: timestamp
}
};

docClient.delete(params, (err, data)=>{
if(err) {
console.log(err);
return res.status(err.statusCode).send({
message: err.message,
status: err.statusCode
});
} else {
return res.status(200).send();
}
});
});

router.get('/', (req, res, next)=>{
res.render('index');
});

module.exports = router;
22 changes: 22 additions & 0 deletions td-notes-app/app/views/index.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="en">

<head>
<base href="/">
<title>TD Notes App</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
crossorigin="anonymous">
<script defer src="https://use.fontawesome.com/releases/v5.0.9/js/all.js" integrity="sha384-8iPTk2s/jMVj81dnzb/iFR2sdA7u06vHJyyLlAd4snFpCl/SnyUjRrbdJsw1pGIl"
crossorigin="anonymous"></script>
<link rel='stylesheet' href='styles/style.css' />
<!-- Insert your Web Application Client ID from Google API Console below-->
<meta name="google-signin-client_id" content="REPLACE_ME_WITH_YOUR_WEB_CLIENT_ID.apps.googleusercontent.com">
<script src="https://apis.google.com/js/platform.js"></script>
</head>

<body>
<app-root>Loading ...</app-root>
<script src="/scripts/app/bundle.js"></script>
</body>

</html>
89 changes: 89 additions & 0 deletions td-notes-app/bin/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#!/usr/bin/env node

/**
* Module dependencies.
*/
const http = require('http');
const debug = require('debug')('node-rest:server');

const app = require('../app/app');

/**
* Get port from environment and store in Express.
*/
const port = normalizePort(process.env.PORT || '3000');
app.set('port', port);

/**
* Create HTTP server.
*/
const server = http.createServer(app);

/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port, function() {
console.log('Server listening on port: ', port);
});

server.on('error', onError);
server.on('listening', onListening);

/**
* Normalize a port into a number, string, or false.
*/

function normalizePort(val) {
var port = parseInt(val, 10);

if (isNaN(port)) {
// named pipe
return val;
}

if (port >= 0) {
// port number
return port;
}

return false;
}

/**
* Event listener for HTTP server "error" event.
*/

function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}

var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;

// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}

/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}
Loading

0 comments on commit 6b88200

Please sign in to comment.