1
0
mirror of https://github.com/sasjs/adapter.git synced 2026-01-11 06:10:05 +00:00

fix(*): store CSRF tokens in Request Client

This commit is contained in:
Krishna Acondy
2021-01-24 18:23:18 +00:00
parent 3a9cd46e6e
commit e0d85f458b
7 changed files with 572 additions and 679 deletions

View File

@@ -1,116 +1,63 @@
import { needsRetry, isUrl } from './utils'
import { CsrfToken } from './types/CsrfToken'
import { isUrl } from './utils'
import { UploadFile } from './types/UploadFile'
import { ErrorResponse } from './types'
import axios, { AxiosInstance } from 'axios'
import { isLogInRequired } from './auth'
const requestRetryLimit = 5
import { RequestClient } from './request/client'
export class FileUploader {
private httpClient: AxiosInstance
constructor(
private appLoc: string,
serverUrl: string,
private jobsPath: string,
private setCsrfTokenWeb: any,
private csrfToken: CsrfToken | null = null
private requestClient: RequestClient
) {
if (serverUrl) isUrl(serverUrl)
this.httpClient = axios.create({ baseURL: serverUrl })
}
private retryCount = 0
public uploadFile(sasJob: string, files: UploadFile[], params: any) {
return new Promise((resolve, reject) => {
if (files?.length < 1)
reject(new ErrorResponse('At least one file must be provided.'))
if (!sasJob || sasJob === '')
reject(new ErrorResponse('sasJob must be provided.'))
if (files?.length < 1)
return Promise.reject(
new ErrorResponse('At least one file must be provided.')
)
if (!sasJob || sasJob === '')
return Promise.reject(new ErrorResponse('sasJob must be provided.'))
let paramsString = ''
let paramsString = ''
for (let param in params) {
if (params.hasOwnProperty(param)) {
paramsString += `&${param}=${params[param]}`
}
for (let param in params) {
if (params.hasOwnProperty(param)) {
paramsString += `&${param}=${params[param]}`
}
}
const program = this.appLoc
? this.appLoc.replace(/\/?$/, '/') + sasJob.replace(/^\//, '')
: sasJob
const uploadUrl = `${this.jobsPath}/?${
'_program=' + program
}${paramsString}`
const program = this.appLoc
? this.appLoc.replace(/\/?$/, '/') + sasJob.replace(/^\//, '')
: sasJob
const uploadUrl = `${this.jobsPath}/?${
'_program=' + program
}${paramsString}`
const headers = {
'cache-control': 'no-cache'
}
const formData = new FormData()
const formData = new FormData()
for (let file of files) {
formData.append('file', file.file, file.fileName)
}
for (let file of files) {
formData.append('file', file.file, file.fileName)
}
const csrfToken = this.requestClient.getCsrfToken('file')
if (csrfToken) formData.append('_csrf', csrfToken.value)
if (this.csrfToken) formData.append('_csrf', this.csrfToken.value)
const headers = {
'cache-control': 'no-cache',
Accept: '*/*',
'Content-Type': 'text/plain'
}
this.httpClient
.post(uploadUrl, formData, { responseType: 'text', headers })
.then(async (response) => {
if (response.status !== 200) {
if (response.status === 403) {
const tokenHeader = response.headers.get('X-CSRF-HEADER')
if (tokenHeader) {
const token = response.headers.get(tokenHeader)
this.csrfToken = {
headerName: tokenHeader,
value: token || ''
}
this.setCsrfTokenWeb(this.csrfToken)
}
}
}
return response.data
})
.then((responseText) => {
if (isLogInRequired(responseText))
reject(new ErrorResponse('You must be logged in to upload a file.'))
if (needsRetry(responseText)) {
if (this.retryCount < requestRetryLimit) {
this.retryCount++
this.uploadFile(sasJob, files, params).then(
(res: any) => resolve(res),
(err: any) => reject(err)
)
} else {
this.retryCount = 0
reject(responseText)
}
} else {
this.retryCount = 0
try {
resolve(JSON.parse(responseText))
} catch (e) {
reject(
new ErrorResponse(
'Error while parsing json from upload response.',
e
)
)
}
}
})
.catch((err: any) => {
reject(new ErrorResponse('Upload request failed.', err))
})
})
return this.requestClient
.post(uploadUrl, formData, undefined, headers)
.then((res) => res.result)
.catch((err: Error) => {
return Promise.reject(
new ErrorResponse('File upload request failed', err)
)
})
}
}