-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
119 lines (99 loc) · 3.71 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
// This file is managed through github at https://github.com/ckhordiasma/log-bullet-visitors/ using github actions.
const AWS = require('aws-sdk');
const dynamo = new AWS.DynamoDB.DocumentClient();
exports.handler = async (event, context) => {
//console.log('Received event:', JSON.stringify(event, null, 2));
let body;
let statusCode = '200';
const allowedOrigins = ["https://af-vcd.github.io",
"https://ea-pods-team.github.io",
"https://ckhordiasma.github.io",
"http://www.lightningwithinfive.com"];
// this logic allows me to have multiple allowed origins
let allowedOrigin = '';
for(let origin of allowedOrigins){
if(event.headers.origin == origin){
allowedOrigin = origin;
}
}
const headers = {
'Content-Type': 'application/json',
"Access-Control-Allow-Headers":"*",
"Access-Control-Allow-Origin": allowedOrigin,
"Access-Control-Allow-Methods":"POST,GET,OPTIONS"
};
if(! event.headers.origin ){
statusCode = '400';
body = "Error - No origin specified in request";
return {statusCode, body, headers};
} else if(! allowedOrigin){
statusCode = '400';
body = "Error - The origin \"" + event.headers.origin + "\" is not permitted to make a request";
return {statusCode, body, headers};
}
const routeSuffix = ' /LogVisitors';
// I routed OPTIONS seperately in the API gateway, so that the routekey shows up as 'OPTIONS /LogVisitors'
// and can route a happy status accordingly.
if(event.routeKey == 'OPTIONS' + routeSuffix){
return {
statusCode,
body,
headers
}
}
// Also custom routed GET and POST in the same way as OPTIONS. This has the nice
// security feature of only allowing GET, POST, and OPTIONS into my lambda through the API gateway.
const WEEK_MS = 1000*60*60*24*7;
const logKey = 'VisitLog';
const table = 'Statistics2';
const countParams = {
TableName:table,
Select: "COUNT",
KeyConditionExpression: "#id = :log and #date between :start_date and :end_date",
ExpressionAttributeNames: {
"#date": "Date",
"#id" : "StatsID"
},
ExpressionAttributeValues: {
":start_date": Date.now()-WEEK_MS,
":end_date": Date.now(),
":log": logKey
}
};
let result;
try {
switch (event.routeKey) {
case 'GET' + routeSuffix:
result = await dynamo.query(countParams).promise();
body = {Count: result.Count }
break;
case 'POST' + routeSuffix:
const timestamp = new Date().getTime();
//defining StatsID to be VisitLog_timestamp_RANDOMNUMBER
const params = {
TableName : table,
Item: {
"StatsID": logKey,
"Date": timestamp,
"Site": event.headers.referer
}
}
await dynamo.put(params).promise();
result = await dynamo.query(countParams).promise();
body = {Count: result.Count }
break;
default:
throw new Error(`Unsupported method "${event.routeKey}"`);
}
} catch (err) {
statusCode = '400';
body = err.message;
} finally {
body = JSON.stringify(body);
}
return {
statusCode,
body,
headers,
};
};