1//
2// URLs
3// \ (•◡•) /
4//
5// Some URLs are special you know.
6
7
8const EXPIRED_ACCESS_TOKENS = {
9 GOOGLE: {}
10}
11
12
13export async function transformUrl(url, app) {
14 const parts = url.split("://")
15
16 switch (parts[ 0 ]) {
17
18 case "dropbox": {
19 const dropboxBits = parts[ 1 ].split("@")
20 const accessToken = dropboxBits[ 0 ]
21 const filePath = dropboxBits[ 1 ]
22
23 return fetch(
24 "https://api.dropboxapi.com/2/files/get_temporary_link",
25 {
26 method: "POST"
27 , body: JSON.stringify({ path: filePath })
28 , headers: new Headers({
29 "Authorization": "Bearer " + accessToken,
30 "Content-Type": "application/json"
31 })
32 }
33 ).then(
34 response => response.json()
35 ).then(
36 response => response.link
37 )
38 }
39
40 case "google": {
41 let finalAccessToken
42
43 const googleBits = parts[ 1 ].split("@")
44 const [ accessToken, expiresAtString, refreshToken, clientId, clientSecret, srcId ] = googleBits[ 0 ].split(":")
45 const fileId = googleBits[ 1 ]
46
47 // Unix timestamp in milliseconds
48 const inXminutes = Date.now() + 5 * 60 * 1000 // 5 minutes
49 const expiresAt = parseInt(expiresAtString, 10)
50 const isAlmostExpired = expiresAt <= inXminutes
51
52 if (EXPIRED_ACCESS_TOKENS.GOOGLE[ accessToken ]) {
53 const replacement = EXPIRED_ACCESS_TOKENS.GOOGLE[ accessToken ]
54
55 if (replacement.newExpiresAt <= inXminutes) {
56 finalAccessToken = await refreshGoogleAccessToken({
57 app, clientId, clientSecret, refreshToken, srcId, oldToken: accessToken
58 })
59 } else {
60 finalAccessToken = replacement.newToken
61 }
62
63 } else if (isAlmostExpired) {
64 finalAccessToken = await refreshGoogleAccessToken({
65 app, clientId, clientSecret, refreshToken, srcId, oldToken: accessToken
66 })
67
68 } else {
69 finalAccessToken = accessToken
70
71 }
72
73 return Promise.resolve(
74 `https://www.googleapis.com/drive/v3/files/${encodeURIComponent(fileId)}?alt=media&bearer_token=${encodeURIComponent(finalAccessToken)}`
75 )
76 }
77
78 default:
79 return Promise.resolve(url)
80
81 }
82}
83
84
85
86// GOOGLE
87
88
89async function refreshGoogleAccessToken({ app, clientId, clientSecret, oldToken, refreshToken, srcId }) {
90 console.log("🔐 Refreshing Google Drive access token")
91
92 const url = new URL("https://www.googleapis.com/oauth2/v4/token")
93
94 url.searchParams.set("client_id", clientId)
95 url.searchParams.set("client_secret", clientSecret)
96 url.searchParams.set("refresh_token", refreshToken)
97 url.searchParams.set("grant_type", "refresh_token")
98
99 const serverResponse = await fetch(url, { method: "POST" }).then(r => r.json())
100 const newToken = serverResponse.access_token
101 const newExpiresAt = Date.now() + (serverResponse.expires_in * 1000)
102
103 EXPIRED_ACCESS_TOKENS.GOOGLE[ oldToken ] = {
104 oldToken,
105 newToken,
106 newExpiresAt,
107 refreshToken
108 }
109
110 app.ports.refreshedAccessToken.send({
111 service: "Google",
112 sourceId: srcId,
113 accessToken: newToken,
114 expiresAt: newExpiresAt
115 })
116
117 return serverResponse.access_token
118}