-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
bee16dc
commit 6b88200
Showing
39 changed files
with
11,209 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} |
Oops, something went wrong.