/
storage-interface.js
110 lines (90 loc) · 2.74 KB
/
storage-interface.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
const bcrypt = require('bcryptjs');
const fs = require('fs');
const AWS = require('aws-sdk');
const { DateTime } = require("luxon");
const shortid = require('shortid');
const ddb = new AWS.DynamoDB.DocumentClient();
class StorageInterface {
async registerNewDevice(deviceId, apiKey, expires) {
let salt = await bcrypt.genSalt(10);
const params = {
TableName: process.env.DEVICES_TABLE_NAME,
Item: {
deviceId,
hashedApiKey: await bcrypt.hash(apiKey, salt),
expires: epochTime(expires),
created: epochTime()
}
};
await ddb.put(params).promise();
}
async getDeviceDetails(deviceId) {
const params = {
TableName: process.env.DEVICES_TABLE_NAME,
Key: {
deviceId: deviceId
}
};
let response = await ddb.get(params).promise();
return response.Item || false;
}
async isApiKeyValid(storedHash, apiKey) {
return await bcrypt.compare(apiKey, storedHash);
}
async storeConnectionToken(deviceId, connectionToken, expires) {
const params = {
TableName: process.env.CONNECTION_TOKENS_TABLE_NAME,
Item: {
connectionToken,
deviceId,
expires: epochTime(expires),
created: epochTime()
}
};
await ddb.put(params).promise();
}
async userFromDropboxDetails(dropboxAccountId, dropboxAccessToken) {
// First check if this user exists already.
let existingUserResult = await ddb.query({
ExpressionAttributeValues: {
':dropboxAccountId' : dropboxAccountId
},
KeyConditionExpression: 'dropboxAccountId = :dropboxAccountId',
ProjectionExpression: 'userId',
TableName: process.env.USERS_TABLE_NAME,
IndexName: 'dropboxAccountIdIndex',
Limit: 1
}).promise();
let existingUserFound = existingUserResult.Items.length === 1;
let userId = existingUserFound ? existingUserResult.Items[0].userId : shortid.generate();
if (existingUserFound) {
// The access token will have changed, so we might as well update it.
await ddb.update({
TableName: process.env.USERS_TABLE_NAME,
Key: { userId },
UpdateExpression: 'set dropboxAccessToken = :t, updated = :u',
ExpressionAttributeValues: {
':t' : dropboxAccessToken,
':u' : epochTime()
}
}).promise();
} else {
await ddb.put({
TableName: process.env.USERS_TABLE_NAME,
Item: {
userId,
dropboxAccountId,
dropboxAccessToken,
created: epochTime(),
updated: epochTime()
}
}).promise();
}
return userId;
}
}
module.exports = StorageInterface;
// ---
function epochTime(luxonObj = DateTime.utc()) {
return Math.round(luxonObj.toSeconds());
}