@@ -77,23 +77,37 @@ interface RevokeAccessTokenResponse {
77
77
revoked : boolean ;
78
78
}
79
79
80
- interface TokenResponse {
81
- refresh_token : string ;
82
- access_token : string ;
83
- token_type : string ;
84
- expires_in : number ;
85
- scope : string ;
80
+ interface GetTokenResponse {
81
+ refresh_token ? : string ;
82
+ access_token ? : string ;
83
+ token_type ? : string ;
84
+ expires_in ? : number ;
85
+ scope ? : string ;
86
86
}
87
87
88
- /**
89
- * Twitter OAuth2 Authentication Client
90
- */
91
- export class OAuth2User implements AuthClient {
88
+ interface Token {
89
+ refresh_token ?: string ;
92
90
access_token ?: string ;
93
91
token_type ?: string ;
94
92
expires_at ?: Date ;
95
93
scope ?: string ;
96
- refresh_token ?: string ;
94
+ }
95
+
96
+ function processTokenResponse ( token : GetTokenResponse ) : Token {
97
+ const { expires_in, ...rest } = token ;
98
+ return {
99
+ ...rest ,
100
+ ...( ! ! expires_in && {
101
+ expires_at : new Date ( Date . now ( ) + expires_in * 1000 ) ,
102
+ } ) ,
103
+ } ;
104
+ }
105
+
106
+ /**
107
+ * Twitter OAuth2 Authentication Client
108
+ */
109
+ export class OAuth2User implements AuthClient {
110
+ token ?: Token ;
97
111
#options: OAuth2UserOptions ;
98
112
#code_verifier?: string ;
99
113
#code_challenge?: string ;
@@ -104,16 +118,16 @@ export class OAuth2User implements AuthClient {
104
118
/**
105
119
* Refresh the access token
106
120
*/
107
- async refreshAccessToken ( ) : Promise < void > {
108
- const refresh_token = this . refresh_token ;
121
+ async refreshAccessToken ( ) : Promise < { token : Token } > {
122
+ const refresh_token = this . token ?. refresh_token ;
109
123
const { client_id, client_secret, request_options } = this . #options;
110
124
if ( ! client_id ) {
111
125
throw new Error ( "client_id is required" ) ;
112
126
}
113
127
if ( ! refresh_token ) {
114
128
throw new Error ( "refresh_token is required" ) ;
115
129
}
116
- const data = await rest < TokenResponse > ( {
130
+ const data = await rest < GetTokenResponse > ( {
117
131
...request_options ,
118
132
endpoint : `/2/oauth2/token` ,
119
133
params : {
@@ -130,26 +144,17 @@ export class OAuth2User implements AuthClient {
130
144
} ) ,
131
145
} ,
132
146
} ) ;
133
- this . updateToken ( data ) ;
134
- }
135
-
136
- /**
137
- * Update token information
138
- */
139
- updateToken ( data : TokenResponse ) : void {
140
- this . refresh_token = data . refresh_token ;
141
- this . access_token = data . access_token ;
142
- this . token_type = data . token_type ;
143
- this . expires_at = new Date ( Date . now ( ) + data . expires_in * 1000 ) ;
144
- this . scope = data . scope ;
147
+ const token = processTokenResponse ( data ) ;
148
+ this . token = token ;
149
+ return { token } ;
145
150
}
146
151
147
152
/**
148
153
* Check if an access token is expired
149
154
*/
150
155
isAccessTokenExpired ( ) : boolean {
151
- const refresh_token = this . refresh_token ;
152
- const expires_at = this . expires_at ;
156
+ const refresh_token = this . token ?. refresh_token ;
157
+ const expires_at = this . token ?. expires_at ;
153
158
return (
154
159
! ! refresh_token &&
155
160
( ! expires_at || expires_at <= new Date ( Date . now ( ) + 1000 ) )
@@ -159,7 +164,7 @@ export class OAuth2User implements AuthClient {
159
164
/**
160
165
* Request an access token
161
166
*/
162
- async requestAccessToken ( code ?: string ) : Promise < void > {
167
+ async requestAccessToken ( code ?: string ) : Promise < { token : Token } > {
163
168
const { client_id, client_secret, callback, request_options } =
164
169
this . #options;
165
170
const code_verifier = this . #code_verifier;
@@ -176,7 +181,7 @@ export class OAuth2User implements AuthClient {
176
181
client_id,
177
182
redirect_uri : callback ,
178
183
} ;
179
- const data = await rest < TokenResponse > ( {
184
+ const data = await rest < GetTokenResponse > ( {
180
185
...request_options ,
181
186
endpoint : `/2/oauth2/token` ,
182
187
params,
@@ -189,16 +194,18 @@ export class OAuth2User implements AuthClient {
189
194
} ) ,
190
195
} ,
191
196
} ) ;
192
- this . updateToken ( data ) ;
197
+ const token = processTokenResponse ( data ) ;
198
+ this . token = token ;
199
+ return { token } ;
193
200
}
194
201
195
202
/**
196
203
* Revoke an access token
197
204
*/
198
205
async revokeAccessToken ( ) : Promise < RevokeAccessTokenResponse > {
199
206
const { client_id, client_secret, request_options } = this . #options;
200
- const access_token = this . access_token ;
201
- const refresh_token = this . refresh_token ;
207
+ const access_token = this . token ?. access_token ;
208
+ const refresh_token = this . token ?. refresh_token ;
202
209
if ( ! client_id ) {
203
210
throw new Error ( "client_id is required" ) ;
204
211
}
@@ -260,10 +267,10 @@ export class OAuth2User implements AuthClient {
260
267
}
261
268
262
269
async getAuthHeader ( ) : Promise < AuthHeader > {
263
- if ( ! this . access_token ) throw new Error ( "access_token is required" ) ;
270
+ if ( ! this . token ?. access_token ) throw new Error ( "access_token is required" ) ;
264
271
if ( this . isAccessTokenExpired ( ) ) await this . refreshAccessToken ( ) ;
265
272
return {
266
- Authorization : `Bearer ${ this . access_token } ` ,
273
+ Authorization : `Bearer ${ this . token . access_token } ` ,
267
274
} ;
268
275
}
269
276
}
0 commit comments