@sasjs/adapter 3.10.0 → 3.10.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3 @@
1
+ export declare class InvalidCsrfError extends Error {
2
+ constructor();
3
+ }
package/package.json CHANGED
@@ -44,18 +44,16 @@
44
44
  "license": "ISC",
45
45
  "devDependencies": {
46
46
  "@cypress/webpack-preprocessor": "5.9.1",
47
- "@types/form-data": "2.5.0",
48
- "cypress": "7.7.0",
49
- "typedoc-neo-theme": "1.1.1",
50
- "typedoc-plugin-external-module-name": "4.0.6",
51
47
  "@types/axios": "0.14.0",
52
48
  "@types/express": "4.17.13",
49
+ "@types/form-data": "2.5.0",
53
50
  "@types/jest": "27.4.0",
54
51
  "@types/mime": "2.0.3",
55
52
  "@types/pem": "1.9.6",
56
53
  "@types/tough-cookie": "4.0.1",
57
54
  "copyfiles": "2.4.1",
58
55
  "cp": "0.2.0",
56
+ "cypress": "7.7.0",
59
57
  "dotenv": "16.0.0",
60
58
  "express": "4.17.3",
61
59
  "jest": "27.4.7",
@@ -63,6 +61,7 @@
63
61
  "node-polyfill-webpack-plugin": "1.1.4",
64
62
  "path": "0.12.7",
65
63
  "pem": "1.14.6",
64
+ "prettier": "2.7.1",
66
65
  "process": "0.11.10",
67
66
  "rimraf": "3.0.2",
68
67
  "semantic-release": "18.0.0",
@@ -72,6 +71,8 @@
72
71
  "tslint": "6.1.3",
73
72
  "tslint-config-prettier": "1.18.0",
74
73
  "typedoc": "0.22.11",
74
+ "typedoc-neo-theme": "1.1.1",
75
+ "typedoc-plugin-external-module-name": "4.0.6",
75
76
  "typedoc-plugin-rename-defaults": "0.4.0",
76
77
  "typescript": "4.5.5",
77
78
  "webpack": "5.69.0",
@@ -86,5 +87,5 @@
86
87
  "https": "1.0.0",
87
88
  "tough-cookie": "4.0.0"
88
89
  },
89
- "version": "3.10.0"
90
+ "version": "3.10.3"
90
91
  }
@@ -240,7 +240,7 @@ export async function executeScript(
240
240
 
241
241
  jobResult = await requestClient
242
242
  .get<any>(resultLink, access_token, 'text/plain')
243
- .catch(async (e) => {
243
+ .catch(async (e: any) => {
244
244
  if (e instanceof NotFoundError) {
245
245
  if (logLink) {
246
246
  const logUrl = `${logLink.href}/content`
@@ -271,7 +271,7 @@ export async function executeScript(
271
271
  })
272
272
 
273
273
  return { result: jobResult?.result, log }
274
- } catch (e) {
274
+ } catch (e: any) {
275
275
  interface HttpError {
276
276
  status: number
277
277
  }
@@ -4,7 +4,7 @@ export const writeStream = async (
4
4
  stream: WriteStream,
5
5
  content: string
6
6
  ): Promise<void> =>
7
- stream.write(content + '\n', (e) => {
7
+ stream.write(content + '\n', (e: any) => {
8
8
  if (e) return Promise.reject(e)
9
9
 
10
10
  return Promise.resolve()
@@ -169,15 +169,23 @@ export class WebJobExecutor extends BaseJobExecutor {
169
169
  ? res.result.log.map((logLine: any) => logLine.line).join('\n')
170
170
  : res.result.log
171
171
 
172
- const resObj = res
173
-
174
- if (this.serverType === ServerType.Sasjs) {
175
- if (res.result._webout < 1)
176
- throw new JobExecutionError(
177
- 0,
178
- 'Job execution failed',
179
- parsedSasjsServerLog
180
- )
172
+ const resObj =
173
+ this.serverType === ServerType.Sasjs
174
+ ? {
175
+ result: res.result._webout,
176
+ log: parsedSasjsServerLog
177
+ }
178
+ : res
179
+
180
+ if (
181
+ this.serverType === ServerType.Sasjs &&
182
+ res.result._webout.length < 1
183
+ ) {
184
+ throw new JobExecutionError(
185
+ 0,
186
+ `No webout was returned by job ${program}. Server type is SASJS and the calling function is WebJobExecutor. Please check the SAS log for more info.`,
187
+ parsedSasjsServerLog
188
+ )
181
189
  }
182
190
 
183
191
  this.requestClient!.appendRequest(resObj, sasJob, config.debug)
@@ -19,6 +19,7 @@ import {
19
19
  parseSourceCode,
20
20
  createAxiosInstance
21
21
  } from '../utils'
22
+ import { InvalidCsrfError } from '../types/errors/InvalidCsrfError'
22
23
 
23
24
  export interface HttpClient {
24
25
  get<T>(
@@ -206,7 +207,7 @@ export class RequestClient implements HttpClient {
206
207
 
207
208
  return this.parseResponse<T>(response)
208
209
  })
209
- .catch(async (e) => {
210
+ .catch(async (e: any) => {
210
211
  return await this.handleError(
211
212
  e,
212
213
  () =>
@@ -247,7 +248,7 @@ export class RequestClient implements HttpClient {
247
248
 
248
249
  return this.parseResponse<T>(response)
249
250
  })
250
- .catch(async (e) => {
251
+ .catch(async (e: any) => {
251
252
  return await this.handleError(e, () =>
252
253
  this.post<T>(url, data, accessToken, contentType, overrideHeaders)
253
254
  )
@@ -271,7 +272,7 @@ export class RequestClient implements HttpClient {
271
272
  throwIfError(response)
272
273
  return this.parseResponse<T>(response)
273
274
  })
274
- .catch(async (e) => {
275
+ .catch(async (e: any) => {
275
276
  return await this.handleError(e, () =>
276
277
  this.put<T>(url, data, accessToken, overrideHeaders)
277
278
  )
@@ -290,7 +291,7 @@ export class RequestClient implements HttpClient {
290
291
  throwIfError(response)
291
292
  return this.parseResponse<T>(response)
292
293
  })
293
- .catch(async (e) => {
294
+ .catch(async (e: any) => {
294
295
  return await this.handleError(e, () => this.delete<T>(url, accessToken))
295
296
  })
296
297
  }
@@ -308,7 +309,7 @@ export class RequestClient implements HttpClient {
308
309
  throwIfError(response)
309
310
  return this.parseResponse<T>(response)
310
311
  })
311
- .catch(async (e) => {
312
+ .catch(async (e: any) => {
312
313
  return await this.handleError(e, () =>
313
314
  this.patch<T>(url, data, accessToken)
314
315
  )
@@ -498,6 +499,24 @@ export class RequestClient implements HttpClient {
498
499
  throw e
499
500
  }
500
501
 
502
+ if (e instanceof InvalidCsrfError) {
503
+ // Fetching root will inject CSRF token in cookie
504
+ await this.httpClient
505
+ .get('/', {
506
+ withCredentials: true
507
+ })
508
+ .catch((err) => {
509
+ throw prefixMessage(err, 'Error while re-fetching CSRF token.')
510
+ })
511
+
512
+ return await callback().catch((err: any) => {
513
+ throw prefixMessage(
514
+ err,
515
+ 'Error while executing callback in handleError. '
516
+ )
517
+ })
518
+ }
519
+
501
520
  if (response?.status === 403 || response?.status === 449) {
502
521
  this.parseAndSetCsrfToken(response)
503
522
 
@@ -584,9 +603,17 @@ export class RequestClient implements HttpClient {
584
603
  export const throwIfError = (response: AxiosResponse) => {
585
604
  switch (response.status) {
586
605
  case 400:
587
- if (typeof response.data === 'object') {
606
+ if (
607
+ typeof response.data === 'object' &&
608
+ response.data.error === 'invalid_grant'
609
+ ) {
610
+ // In SASVIYA when trying to get access token, if auth code is wrong status code will be 400 so in such case we return login required error.
588
611
  throw new LoginRequiredError(response.data)
589
612
  }
613
+
614
+ if (response.data.toLowerCase() === 'invalid csrf token!') {
615
+ throw new InvalidCsrfError()
616
+ }
590
617
  break
591
618
  case 401:
592
619
  if (typeof response.data === 'object') {
@@ -68,7 +68,7 @@ export class Sas9RequestClient extends RequestClient {
68
68
  throwIfError(response)
69
69
  return this.parseResponse<T>(response)
70
70
  })
71
- .catch(async (e) => {
71
+ .catch(async (e: any) => {
72
72
  return await this.handleError(
73
73
  e,
74
74
  () =>
@@ -113,7 +113,7 @@ export class Sas9RequestClient extends RequestClient {
113
113
  throwIfError(response)
114
114
  return this.parseResponse<T>(response)
115
115
  })
116
- .catch(async (e) => {
116
+ .catch(async (e: any) => {
117
117
  return await this.handleError(e, () =>
118
118
  this.post<T>(url, data, accessToken, contentType, overrideHeaders)
119
119
  )
@@ -0,0 +1,9 @@
1
+ export class InvalidCsrfError extends Error {
2
+ constructor() {
3
+ const message = 'Invalid CSRF token!'
4
+
5
+ super(`Auth error: ${message}`)
6
+ this.name = 'InvalidCsrfError'
7
+ Object.setPrototypeOf(this, InvalidCsrfError.prototype)
8
+ }
9
+ }
@@ -15,7 +15,7 @@ export const getValidJson = (str: string | object): object => {
15
15
  if (str === '') return {}
16
16
 
17
17
  return JSON.parse(str)
18
- } catch (e) {
18
+ } catch (e: any) {
19
19
  if (e instanceof JsonParseArrayError) throw e
20
20
  throw new InvalidJsonError()
21
21
  }
@@ -4,7 +4,7 @@ export const parseSasViyaLog = (logResponse: { items: any[] }) => {
4
4
  log = logResponse.items
5
5
  ? logResponse.items.map((i) => i.line).join('\n')
6
6
  : JSON.stringify(logResponse)
7
- } catch (e) {
7
+ } catch (e: any) {
8
8
  console.error('An error has occurred while parsing the log response', e)
9
9
  log = logResponse
10
10
  }
@@ -8,7 +8,7 @@ export const parseWeboutResponse = (response: string, url?: string): string => {
8
8
  sasResponse = response
9
9
  .split('>>weboutBEGIN<<')[1]
10
10
  .split('>>weboutEND<<')[0]
11
- } catch (e) {
11
+ } catch (e: any) {
12
12
  if (url) throw new WeboutResponseError(url)
13
13
 
14
14
  sasResponse = ''
@@ -0,0 +1,3 @@
1
+ export declare class InvalidCsrfError extends Error {
2
+ constructor();
3
+ }