-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathauthentication.js
109 lines (95 loc) · 3.14 KB
/
authentication.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
'use strict';
const Remarkable = require('remarkable-typescript');
const uuid = require('uuid');
// This function runs before every outbound request. You can have as many as you
// need. They'll need to each be registered in your index.js file.
const includeSessionKeyHeader = (request, z, bundle) => {
if (bundle.authData.device_token) {
request.headers = request.headers || {};
request.headers['Authorization'] = 'Bearer ' + bundle.authData.device_token;
}
z.console.log(request);
return request;
};
const testAuth = (z, bundle) => z.request({
method: 'GET',
url: 'https://document-storage-production-dot-remarkable-production.appspot.com/document-storage/json/2/docs',
});
// This function runs after every outbound request. You can use it to check for
// errors or modify the response. You can have as many as you need. They'll need
// to each be registered in your index.js file.
const handleBadResponses = (response, z, bundle) => {
if (response.status >= 401) {
throw new z.errors.Error(
// This message is surfaced to the user
'The API Key you supplied is incorrect',
'AuthenticationError',
response.status,
);
}
return response;
};
/*
* Register your reMarkable and generate a device token. You must do this first to pair your device if you didn't
* specify a token. This may take a few seconds to complete. It seems that the deviceToken never expires.
* Params: { code: string }
* Returns: deviceToken: string
*/
const getSessionKey = async (z, bundle) => {
if (bundle.authData.device_token) {
return await refreshAccessToken(z, bundle);
} else {
return await getAccessToken(z, bundle);
}
};
const getAccessToken = async (z, bundle) => {
const promise = z.request(`https://my.remarkable.com/token/json/2/device/new`, {
method: 'POST',
body: {
code: bundle.authData.one_time_code,
deviceDesc: 'browser-chrome',
deviceId: uuid.v4(),
},
headers: {
'content-type': 'application/json',
},
});
// Needs to return at minimum, `access_token`, and if your app also does refresh, then `refresh_token` too
return promise.then((response) => {
if (response.status !== 200) {
throw new Error('Unable to fetch access token: ' + response.content);
}
bundle.authData.root_token = response.content;
return refreshAccessToken(z, bundle);
});
};
const refreshAccessToken = async (z, bundle) => {
z.console.log('refreshing');
const client = new Remarkable.Remarkable({deviceToken: bundle.authData.root_token});
let token = await client.refreshToken();
return {
root_token: bundle.authData.root_token,
device_token: token,
};
};
module.exports = {
config: {
type: 'session',
fields: [
{
key: 'one_time_code',
type: 'string',
label: 'Remarkable One-time Code',
helpText: 'You must register your reMarkable [here].(https://my.remarkable.com/connect/desktop)',
required: true,
},
],
test: testAuth,
sessionConfig: {
perform: getSessionKey,
},
connectionLabel: 'Remarkable',
},
befores: [includeSessionKeyHeader],
afters: [handleBadResponses],
};