@@ -4,15 +4,17 @@ var request = require('request');
4
4
var config = require ( './config' ) ;
5
5
var h = require ( './helper' ) ;
6
6
7
+ // update options with user credentials
8
+ function signOpts ( opts , user ) {
9
+ opts . headers . Cookie = 'PHPSESSID=' + user . sessionId +
10
+ ';csrftoken=' + user . sessionCSRF + ';' ;
11
+ opts . headers [ 'X-CSRFToken' ] = user . sessionCSRF ;
12
+ }
13
+
7
14
function makeOpts ( url ) {
8
- var opts = { url : url , headers : { } } ;
15
+ var opts = { url : url , headers : { } , _expectedStatus : 200 } ;
9
16
var core = require ( './core' ) ;
10
- if ( core . isLogin ( ) ) {
11
- var user = core . getUser ( ) ;
12
- opts . headers . Cookie = 'PHPSESSID=' + user . sessionId +
13
- ';csrftoken=' + user . sessionCSRF + ';' ;
14
- opts . headers [ 'X-CSRFToken' ] = user . sessionCSRF ;
15
- }
17
+ if ( core . isLogin ( ) ) signOpts ( opts , core . getUser ( ) ) ;
16
18
return opts ;
17
19
}
18
20
@@ -34,10 +36,44 @@ function checkError(e, resp, expectedStatus, msg) {
34
36
}
35
37
}
36
38
39
+ // leetcode.com is limiting one session alive in the same time,
40
+ // which means once you login on web, your cli session will get
41
+ // expired immediately. In that case we will try to re-login in
42
+ // the backend to give a seamless user experience.
43
+ function requestWithReLogin ( opts , cb ) {
44
+ if ( ! config . AUTO_LOGIN )
45
+ return request ( opts , cb ) ;
46
+
47
+ var core = require ( './core' ) ;
48
+ var user = core . getUser ( ) ;
49
+
50
+ request ( opts , function ( e , resp , body ) {
51
+ e = checkError ( e , resp , opts . _expectedStatus ) ;
52
+
53
+ // not 403: transparently pass down
54
+ if ( ! e || e . statusCode !== 403 )
55
+ return cb ( e , resp , body ) ;
56
+
57
+ // if 403: try re-login
58
+ console . log ( 'session expired, auto re-login...' ) ;
59
+
60
+ core . login ( user , function ( e2 , user ) {
61
+ if ( e2 ) return cb ( e , resp , body ) ;
62
+
63
+ console . log ( 'login successfully, cont\'d...' ) ;
64
+ signOpts ( opts , user ) ;
65
+
66
+ request ( opts , cb ) ;
67
+ } ) ;
68
+ } ) ;
69
+ }
70
+
37
71
var leetcodeClient = { } ;
38
72
39
73
leetcodeClient . getProblems = function ( cb ) {
40
- request ( makeOpts ( config . PROBLEMS_URL ) , function ( e , resp , body ) {
74
+ var opts = makeOpts ( config . PROBLEMS_URL ) ;
75
+
76
+ requestWithReLogin ( opts , function ( e , resp , body ) {
41
77
e = checkError ( e , resp , 200 ) ;
42
78
if ( e ) return cb ( e ) ;
43
79
@@ -135,8 +171,10 @@ function verifyResult(opts, jobs, results, cb) {
135
171
if ( jobs . length === 0 )
136
172
return cb ( null , results ) ;
137
173
174
+ opts . method = 'GET' ;
138
175
opts . url = config . VERIFY_URL . replace ( '$id' , jobs [ 0 ] . id ) ;
139
- request . get ( opts , function ( e , resp , body ) {
176
+
177
+ requestWithReLogin ( opts , function ( e , resp , body ) {
140
178
e = checkError ( e , resp , 200 ) ;
141
179
if ( e ) return cb ( e ) ;
142
180
@@ -153,6 +191,7 @@ function verifyResult(opts, jobs, results, cb) {
153
191
154
192
leetcodeClient . testProblem = function ( problem , cb ) {
155
193
var opts = makeOpts ( ) ;
194
+ opts . method = 'POST' ;
156
195
opts . url = config . TEST_URL . replace ( '$key' , problem . key ) ;
157
196
opts . headers . Origin = config . BASE_URL ;
158
197
opts . headers . Referer = problem . link ;
@@ -166,7 +205,7 @@ leetcodeClient.testProblem = function(problem, cb) {
166
205
'typed_code' : h . getFileData ( problem . file )
167
206
} ;
168
207
169
- request . post ( opts , function ( e , resp , body ) {
208
+ requestWithReLogin ( opts , function ( e , resp , body ) {
170
209
e = checkError ( e , resp , 200 ) ;
171
210
if ( e ) return cb ( e ) ;
172
211
@@ -183,6 +222,7 @@ leetcodeClient.testProblem = function(problem, cb) {
183
222
184
223
leetcodeClient . submitProblem = function ( problem , cb ) {
185
224
var opts = makeOpts ( ) ;
225
+ opts . method = 'POST' ;
186
226
opts . url = config . SUBMIT_URL . replace ( '$key' , problem . key ) ;
187
227
opts . headers . Origin = config . BASE_URL ;
188
228
opts . headers . Referer = problem . link ;
@@ -196,7 +236,7 @@ leetcodeClient.submitProblem = function(problem, cb) {
196
236
'typed_code' : h . getFileData ( problem . file )
197
237
} ;
198
238
199
- request . post ( opts , function ( e , resp , body ) {
239
+ requestWithReLogin ( opts , function ( e , resp , body ) {
200
240
e = checkError ( e , resp , 200 ) ;
201
241
if ( e ) return cb ( e ) ;
202
242
0 commit comments