@@ -93,17 +93,24 @@ class DropboxBackupStorageAdapter {
9393 sessionID : ?string ,
9494 offset : number ,
9595 chunk : Buffer ,
96- ) : Promise < string > {
96+ ) : Promise < {
97+ + accessToken : string ,
98+ + sessionID : string ,
99+ } > {
97100 if ( ! sessionID ) {
98- const response = await this . contentRequest (
99- accessToken ,
100- 'files/upload_session/start' ,
101- { close : false } ,
102- chunk ,
103- ) ;
104- return response . session_id ;
101+ const { accessToken : currentAccessToken , response } =
102+ await this . contentRequest (
103+ accessToken ,
104+ 'files/upload_session/start' ,
105+ { close : false } ,
106+ chunk ,
107+ ) ;
108+ return {
109+ accessToken : currentAccessToken ,
110+ sessionID : response . session_id ,
111+ } ;
105112 }
106- await this . contentRequest (
113+ const { accessToken : currentAccessToken } = await this . contentRequest (
107114 accessToken ,
108115 'files/upload_session/append_v2' ,
109116 {
@@ -115,7 +122,10 @@ class DropboxBackupStorageAdapter {
115122 } ,
116123 chunk ,
117124 ) ;
118- return sessionID ;
125+ return {
126+ accessToken : currentAccessToken ,
127+ sessionID,
128+ } ;
119129 }
120130
121131 async finishUpload (
@@ -124,9 +134,9 @@ class DropboxBackupStorageAdapter {
124134 sessionID : ?string ,
125135 offset : number ,
126136 chunk : Buffer ,
127- ) : Promise < void > {
137+ ) : Promise < string > {
128138 if ( ! sessionID ) {
129- await this . contentRequest (
139+ const { accessToken : currentAccessToken } = await this . contentRequest (
130140 accessToken ,
131141 'files/upload' ,
132142 {
@@ -137,9 +147,9 @@ class DropboxBackupStorageAdapter {
137147 } ,
138148 chunk ,
139149 ) ;
140- return ;
150+ return currentAccessToken ;
141151 }
142- await this . contentRequest (
152+ const { accessToken : currentAccessToken } = await this . contentRequest (
143153 accessToken ,
144154 'files/upload_session/finish' ,
145155 {
@@ -156,6 +166,7 @@ class DropboxBackupStorageAdapter {
156166 } ,
157167 chunk ,
158168 ) ;
169+ return currentAccessToken ;
159170 }
160171
161172 filePath ( filename : string ) : string {
@@ -212,36 +223,54 @@ class DropboxBackupStorageAdapter {
212223 endpoint : string ,
213224 args : Object ,
214225 content : Buffer ,
215- ) : Promise < any > {
216- const response = await nodeFetch (
217- `https://content.dropboxapi.com/2/${ endpoint } ` ,
218- {
219- method : 'POST' ,
220- body : content ,
221- headers : {
222- 'Authorization' : `Bearer ${ accessToken } ` ,
223- 'Content-Type' : 'application/octet-stream' ,
224- 'Dropbox-API-Arg' : JSON . stringify ( args ) ,
226+ ) : Promise < {
227+ + accessToken : string ,
228+ + response : any ,
229+ } > {
230+ const tryContentRequest = async (
231+ currentAccessToken : string ,
232+ ) : Promise < {
233+ + accessToken : string ,
234+ + response : any ,
235+ } > => {
236+ const response = await nodeFetch (
237+ `https://content.dropboxapi.com/2/${ endpoint } ` ,
238+ {
239+ method : 'POST' ,
240+ body : content ,
241+ headers : {
242+ 'Authorization' : `Bearer ${ currentAccessToken } ` ,
243+ 'Content-Type' : 'application/octet-stream' ,
244+ 'Dropbox-API-Arg' : JSON . stringify ( args ) ,
245+ } ,
225246 } ,
226- } ,
227- ) ;
228- if ( ! response . ok ) {
229- const responseText = await response . text ( ) ;
230- throw mapDropboxError ( response . status , responseText ) ;
231- }
247+ ) ;
248+ if ( ! response . ok ) {
249+ const responseText = await response . text ( ) ;
250+ if (
251+ response . status === 401 &&
252+ responseText . includes ( 'expired_access_token' )
253+ ) {
254+ const refreshedAccessToken = await this . refreshAccessToken ( ) ;
255+ return await tryContentRequest ( refreshedAccessToken ) ;
256+ }
257+ throw mapDropboxError ( response . status , responseText ) ;
258+ }
232259
233- const responseText = await response . text ( ) ;
234- if ( ! responseText ) {
235- return { } ;
236- }
237- return JSON . parse ( responseText ) ;
260+ const responseText = await response . text ( ) ;
261+ return {
262+ accessToken : currentAccessToken ,
263+ response : responseText ? JSON . parse ( responseText ) : { } ,
264+ } ;
265+ } ;
266+ return await tryContentRequest ( accessToken ) ;
238267 }
239268}
240269
241270const dropboxChunkSize = 16 * 1024 * 1024 ;
242271class DropboxUploadWriteStream extends Writable {
243272 + adapter : DropboxBackupStorageAdapter ;
244- + accessToken : string ;
273+ accessToken : string ;
245274 + filename : string ;
246275 sessionID : ?string ;
247276 offset : number ;
@@ -290,19 +319,21 @@ class DropboxUploadWriteStream extends Writable {
290319 this . bufferedChunk = Buffer . concat ( [ this . bufferedChunk , buffer ] ) ;
291320 while ( this . bufferedChunk . length >= dropboxChunkSize ) {
292321 const uploadChunk = this . bufferedChunk . subarray ( 0 , dropboxChunkSize ) ;
293- this . sessionID = await this . adapter . uploadChunk (
322+ const uploadResponse = await this . adapter . uploadChunk (
294323 this . accessToken ,
295324 this . sessionID ,
296325 this . offset ,
297326 uploadChunk ,
298327 ) ;
328+ this . accessToken = uploadResponse . accessToken ;
329+ this . sessionID = uploadResponse . sessionID ;
299330 this . offset += uploadChunk . length ;
300331 this . bufferedChunk = this . bufferedChunk . subarray ( dropboxChunkSize ) ;
301332 }
302333 }
303334
304335 async finish ( ) : Promise < void > {
305- await this . adapter . finishUpload (
336+ this . accessToken = await this . adapter . finishUpload (
306337 this . accessToken ,
307338 this . filename ,
308339 this . sessionID ,
0 commit comments