-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
121 lines (105 loc) · 3.01 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
120
121
const AWS = require("aws-sdk");
const fs = require("fs").promises;
const s3 = new AWS.S3({
signatureVersion: "v4",
});
const dynamodb = new AWS.DynamoDB();
module.exports.handler = async (event) => {
const permalinkPath = /^\/link\/(?<token>[^/]*)$/;
const revokePermalinkPath = /^\/revoke\/(?<token>[^/]*)$/;
if (event.requestContext.http.path === "/") {
const [html, files, permalinksTable] = await Promise.all([
fs.readFile(__dirname+"/index.html", "utf8"),
(async () => {
// does not handle pagination, only for demonstration
const objects = await s3.listObjectsV2({Bucket: process.env.BUCKET}).promise();
return objects.Contents.map((object) => {
return `
<tr>
<td>${object.Key}</td>
<td>
<button data-permalink-key="${encodeURIComponent(object.Key)}" class="create-permalink">Create permalink</button>
</td>
</tr>
`;
}).join("");
})(),
(async () => {
const items = await dynamodb.scan({
TableName: process.env.TABLE,
}).promise();
return items.Items.length > 0 ? items.Items.map(({Token: {S: Token}, Key: {S: Key}}) => `
<tr>
<td><a target="_blank" href="https://${event.requestContext.domainName}/link/${Token}">Open</a></td>
<td>${Key}</td>
<td><button data-token="${Token}" class="revoke">Revoke</button></form>
</td>
</tr>
`).join("") : "<tr><td colspan=\"3\">No permalinks yet</td></tr>";
})(),
]);
const htmlWithDebug = html.replace("$$FILES_CONTENTS$$", files).replace("$$PERMALINKS_CONTENTS$$", permalinksTable);
return {
statusCode: 200,
headers: {
"Content-Type": "text/html",
},
body: htmlWithDebug,
};
} else if (event.requestContext.http.path.match(permalinkPath)) {
const {token} = event.requestContext.http.path.match(permalinkPath).groups;
const permalink = await dynamodb.getItem({
TableName: process.env.TABLE,
Key: {
Token: {
S: token,
},
},
}).promise();
if (!permalink.Item) {
return {
statusCode: 404,
};
}
const key = permalink.Item.Key.S;
const file = await s3.getSignedUrlPromise("getObject", {Bucket: process.env.BUCKET, Key: key});
return {
statusCode: 303,
headers: {
Location: file,
},
};
} else if (event.requestContext.http.path === "/create_permalink" && event.requestContext.http.method === "POST" && event.body) {
const {key} = JSON.parse(event.body);
// important!
// make sure that the user has access to the object!
const token = require("crypto").randomBytes(32).toString("hex");
await dynamodb.putItem({
TableName: process.env.TABLE,
Item: {
Token: {
S: token,
},
Key: {
S: key,
},
},
}).promise();
return {
statusCode: 200,
};
} else if (event.requestContext.http.path.match(revokePermalinkPath) && event.requestContext.http.method === "PUT") {
const {token} = event.requestContext.http.path.match(revokePermalinkPath).groups;
await dynamodb.deleteItem({
TableName: process.env.TABLE,
Key: {
Token: {
S: token,
},
},
}).promise();
return {
statusCode: 200,
};
}
};