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

chore(*): refactor, move all auth-related code to auth folder

This commit is contained in:
Krishna Acondy
2021-01-24 13:07:15 +00:00
parent e31774ae9d
commit aed39c2ec4
12 changed files with 342 additions and 266 deletions

View File

@@ -12,7 +12,7 @@ export const computeTests = (adapter: SASjs): TestSuite => ({
return adapter.startComputeJob("/Public/app/common/sendArr", data);
},
assertion: (res: any) => {
const expectedProperties = ["id", "applicationName", "attributes"]
const expectedProperties = ["id", "applicationName", "attributes"];
return validate(expectedProperties, res);
}
},
@@ -21,11 +21,22 @@ export const computeTests = (adapter: SASjs): TestSuite => ({
description: "Should start a compute job and return the job",
test: () => {
const data: any = { table1: [{ col1: "first col value" }] };
return adapter.startComputeJob("/Public/app/common/sendArr", data, {}, "", true);
return adapter.startComputeJob(
"/Public/app/common/sendArr",
data,
{},
"",
true
);
},
assertion: (res: any) => {
const expectedProperties = ["id", "state", "creationTimeStamp", "jobConditionCode"]
return validate(expectedProperties, res.result);
const expectedProperties = [
"id",
"state",
"creationTimeStamp",
"jobConditionCode"
];
return validate(expectedProperties, res.job);
}
},
{
@@ -38,19 +49,19 @@ export const computeTests = (adapter: SASjs): TestSuite => ({
`output;`,
`end;`,
`run;`
]
];
return adapter.executeScriptSASViya(
'sasCode.sas',
"sasCode.sas",
fileLines,
'SAS Studio compute context',
"SAS Studio compute context",
undefined,
true
)
);
},
assertion: (res: any) => {
const expectedLogContent = `1 data;\\n2 do x=1 to 100;\\n3 output;\\n4 end;\\n5 run;\\n\\n`
const expectedLogContent = `1 data;\\n2 do x=1 to 100;\\n3 output;\\n4 end;\\n5 run;\\n\\n`;
return validateLog(expectedLogContent, res.log);
}
},
@@ -58,21 +69,21 @@ export const computeTests = (adapter: SASjs): TestSuite => ({
title: "Execute Script Viya - failed job",
description: "Should execute sas file and return log",
test: () => {
const fileLines = [
`%abort;`
]
return adapter.executeScriptSASViya(
'sasCode.sas',
fileLines,
'SAS Studio compute context',
undefined,
true
).catch((err: any) => err )
const fileLines = [`%abort;`];
return adapter
.executeScriptSASViya(
"sasCode.sas",
fileLines,
"SAS Studio compute context",
undefined,
true
)
.catch((err: any) => err);
},
assertion: (res: any) => {
const expectedLogContent = `1 %abort;\\nERROR: The %ABORT statement is not valid in open code.\\n`
const expectedLogContent = `1 %abort;\\nERROR: The %ABORT statement is not valid in open code.\\n`;
return validateLog(expectedLogContent, res.log);
}
}
@@ -80,16 +91,16 @@ export const computeTests = (adapter: SASjs): TestSuite => ({
});
const validateLog = (text: string, log: string): boolean => {
const isValid = JSON.stringify(log).includes(text)
const isValid = JSON.stringify(log).includes(text);
return isValid
}
return isValid;
};
const validate = (expectedProperties: string[], data: any): boolean => {
const actualProperties = Object.keys(data);
const isValid = expectedProperties.every(
(property) => actualProperties.includes(property)
const isValid = expectedProperties.every((property) =>
actualProperties.includes(property)
);
return isValid
}
return isValid;
};

View File

@@ -23,11 +23,12 @@ export const sasjsRequestTests = (adapter: SASjs): TestSuite => ({
},
{
title: "Make error and capture log",
description: "Should make an error and capture log, in the same time it is testing if debug override is working",
description:
"Should make an error and capture log, in the same time it is testing if debug override is working",
test: async () => {
return new Promise(async (resolve, reject) => {
adapter
.request("common/makeErr", data, {debug: true})
.request("common/makeErr", data, { debug: true })
.then((res) => {
//no action here, this request must throw error
})
@@ -38,9 +39,11 @@ export const sasjsRequestTests = (adapter: SASjs): TestSuite => ({
req.serviceLink.includes("makeErr")
) || null;
if (!makeErrRequest) resolve(false)
if (!makeErrRequest) return resolve(false);
resolve(!!(makeErrRequest.logFile && makeErrRequest.logFile.length > 0));
return resolve(
!!(makeErrRequest.logFile && makeErrRequest.logFile.length > 0)
);
});
});
},

View File

@@ -1,8 +1,9 @@
import { isLogInRequired, needsRetry, isUrl } from './utils'
import { needsRetry, isUrl } from './utils'
import { CsrfToken } from './types/CsrfToken'
import { UploadFile } from './types/UploadFile'
import { ErrorResponse } from './types'
import axios, { AxiosInstance } from 'axios'
import { isLogInRequired } from './auth'
const requestRetryLimit = 5

View File

@@ -1,8 +1,6 @@
import {
isAuthorizeFormRequired,
parseAndSubmitAuthorizeForm,
convertToCSV,
makeRequest,
isRelativePath,
isUri,
isUrl
@@ -24,12 +22,15 @@ import { SessionManager } from './SessionManager'
import { ContextManager } from './ContextManager'
import { timestampToYYYYMMDDHHMMSS } from '@sasjs/utils/time'
import { Logger, LogLevel } from '@sasjs/utils/logger'
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'
import { isAuthorizeFormRequired } from './auth/isAuthorizeFormRequired'
/**
* A client for interfacing with the SAS Viya REST API.
*
*/
export class SASViyaApiClient {
private httpClient: AxiosInstance
constructor(
private serverUrl: string,
private rootFolderName: string,
@@ -37,6 +38,7 @@ export class SASViyaApiClient {
private setCsrfToken: (csrfToken: CsrfToken) => void
) {
if (serverUrl) isUrl(serverUrl)
this.httpClient = axios.create({ baseURL: serverUrl })
}
private csrfToken: CsrfToken | null = null
@@ -146,10 +148,11 @@ export class SASViyaApiClient {
headers.Authorization = `Bearer ${accessToken}`
}
const { result: contexts } = await this.request<{ items: Context[] }>(
`${this.serverUrl}/compute/contexts?limit=10000`,
{ headers }
const { result: contexts } = await this.get<{ items: Context[] }>(
`/compute/contexts?limit=10000`,
accessToken
)
const executionContext =
contexts.items && contexts.items.length
? contexts.items.find((c: any) => c.name === contextName)
@@ -165,9 +168,10 @@ export class SASViyaApiClient {
'Content-Type': 'application/json'
}
}
const { result: createdSession } = await this.request<Session>(
`${this.serverUrl}/compute/contexts/${executionContext.id}/sessions`,
createSessionRequest
const { result: createdSession } = await this.post<Session>(
`/compute/contexts/${executionContext.id}/sessions`,
{},
accessToken
)
return createdSession
@@ -370,22 +374,18 @@ export class SASViyaApiClient {
}
// Execute job in session
const postJobRequest = {
method: 'POST',
headers,
body: JSON.stringify({
name: fileName,
description: 'Powered by SASjs',
code: linesOfCode,
variables: jobVariables,
arguments: jobArguments
})
}
const { result: postedJob, etag } = await this.request<Job>(
`${this.serverUrl}/compute/sessions/${executionSessionId}/jobs`,
postJobRequest
).catch((err) => {
const jobRequestBody = JSON.stringify({
name: fileName,
description: 'Powered by SASjs',
code: linesOfCode,
variables: jobVariables,
arguments: jobArguments
})
const { result: postedJob, etag } = await this.post<Job>(
`/compute/sessions/${executionSessionId}/jobs`,
jobRequestBody,
accessToken
).catch((err: any) => {
throw err
})
@@ -409,9 +409,9 @@ export class SASViyaApiClient {
pollOptions
)
const { result: currentJob } = await this.request<Job>(
`${this.serverUrl}/compute/sessions/${executionSessionId}/jobs/${postedJob.id}`,
{ headers }
const { result: currentJob } = await this.get<Job>(
`/compute/sessions/${executionSessionId}/jobs/${postedJob.id}`,
accessToken
).catch((err) => {
throw err
})
@@ -422,11 +422,9 @@ export class SASViyaApiClient {
const logLink = currentJob.links.find((l) => l.rel === 'log')
if (debug && logLink) {
log = await this.request<any>(
`${this.serverUrl}${logLink.href}/content?limit=10000`,
{
headers
}
log = await this.get<any>(
`${logLink.href}/content?limit=10000`,
accessToken
)
.then((res: any) =>
res.result.items.map((i: any) => i.line).join('\n')
@@ -449,18 +447,16 @@ export class SASViyaApiClient {
}
if (resultLink) {
jobResult = await this.request<any>(
`${this.serverUrl}${resultLink}`,
{ headers },
'text'
jobResult = await this.get<any>(
resultLink,
accessToken,
'text/plain'
).catch(async (e) => {
if (e && e.status === 404) {
if (logLink) {
log = await this.request<any>(
`${this.serverUrl}${logLink.href}/content?limit=10000`,
{
headers
}
log = await this.get<any>(
`${logLink.href}/content?limit=10000`,
accessToken
)
.then((res: any) =>
res.result.items.map((i: any) => i.line).join('\n')
@@ -471,7 +467,7 @@ export class SASViyaApiClient {
return Promise.reject({
status: 500,
log: log
log
})
}
}
@@ -568,22 +564,13 @@ export class SASViyaApiClient {
}
}
const createFolderRequest: RequestInit = {
method: 'POST',
body: JSON.stringify({
const { result: createFolderResponse } = await this.post<Folder>(
`/folders/folders?parentFolderUri=${parentFolderUri}`,
JSON.stringify({
name: folderName,
type: 'folder'
})
}
createFolderRequest.headers = { 'Content-Type': 'application/json' }
if (accessToken) {
createFolderRequest.headers.Authorization = `Bearer ${accessToken}`
}
const { result: createFolderResponse } = await this.request<Folder>(
`${this.serverUrl}/folders/folders?parentFolderUri=${parentFolderUri}`,
createFolderRequest
}),
accessToken
)
// update folder map with newly created folder.
@@ -617,13 +604,9 @@ export class SASViyaApiClient {
parentFolderUri = await this.getFolderUri(parentFolderPath, accessToken)
}
const createJobDefinitionRequest: RequestInit = {
method: 'POST',
headers: {
'Content-Type': 'application/vnd.sas.job.definition+json',
Accept: 'application/vnd.sas.job.definition+json'
},
body: JSON.stringify({
return await this.post<Job>(
`${this.serverUrl}/jobDefinitions/definitions?parentFolderUri=${parentFolderUri}`,
JSON.stringify({
name: jobName,
parameters: [
{
@@ -634,19 +617,8 @@ export class SASViyaApiClient {
],
type: 'Compute',
code
})
}
if (accessToken) {
createJobDefinitionRequest!.headers = {
...createJobDefinitionRequest.headers,
Authorization: `Bearer ${accessToken}`
}
}
return await this.request<Job>(
`${this.serverUrl}/jobDefinitions/definitions?parentFolderUri=${parentFolderUri}`,
createJobDefinitionRequest
}),
accessToken
)
}
@@ -795,13 +767,10 @@ export class SASViyaApiClient {
if (accessToken) {
headers.Authorization = `Bearer ${accessToken}`
}
const deleteResponse = await this.request(url, {
method: 'DELETE',
credentials: 'include',
headers
})
return deleteResponse
const deleteResponse = await this.delete(url, accessToken)
return deleteResponse.result
}
/**
@@ -871,9 +840,9 @@ export class SASViyaApiClient {
throw new Error(`URI of job definition was not found.`)
}
const { result: jobDefinition } = await this.request<JobDefinition>(
const { result: jobDefinition } = await this.get<JobDefinition>(
`${this.serverUrl}${jobDefinitionLink.href}`,
{ headers }
accessToken
)
code = jobDefinition.code
@@ -948,20 +917,10 @@ export class SASViyaApiClient {
const jobDefinitionLink = jobToExecute?.links.find(
(l) => l.rel === 'getResource'
)?.href
const requestInfo: any = {
method: 'GET'
}
const headers: any = { 'Content-Type': 'application/json' }
if (!!accessToken) {
headers.Authorization = `Bearer ${accessToken}`
}
requestInfo.headers = headers
const { result: jobDefinition } = await this.request<Job>(
const { result: jobDefinition } = await this.get<Job>(
`${this.serverUrl}${jobDefinitionLink}`,
requestInfo
accessToken
)
const jobArguments: { [key: string]: any } = {
@@ -988,48 +947,43 @@ export class SASViyaApiClient {
jobArguments[`_webin_name${index + 1}`] = fileInfo.tableName
})
const postJobRequest = {
method: 'POST',
headers,
body: JSON.stringify({
name: `exec-${jobName}`,
description: 'Powered by SASjs',
jobDefinition,
arguments: jobArguments
})
}
const { result: postedJob, etag } = await this.request<Job>(
const postJobRequestBody = JSON.stringify({
name: `exec-${jobName}`,
description: 'Powered by SASjs',
jobDefinition,
arguments: jobArguments
})
const { result: postedJob, etag } = await this.post<Job>(
`${this.serverUrl}/jobExecution/jobs?_action=wait`,
postJobRequest
postJobRequestBody
)
const jobStatus = await this.pollJobState(postedJob, etag, accessToken)
const { result: currentJob } = await this.request<Job>(
const { result: currentJob } = await this.get<Job>(
`${this.serverUrl}/jobExecution/jobs/${postedJob.id}`,
{ headers }
accessToken
)
let jobResult
let log
if (jobStatus === 'failed') {
return Promise.reject(currentJob.error)
}
const resultLink = currentJob.results['_webout.json']
const logLink = currentJob.links.find((l) => l.rel === 'log')
if (resultLink) {
jobResult = await this.request<any>(
jobResult = await this.get<any>(
`${this.serverUrl}${resultLink}/content`,
{ headers },
'text'
accessToken,
'text/plain'
)
}
if (debug && logLink) {
log = await this.request<any>(
log = await this.get<any>(
`${this.serverUrl}${logLink.href}/content`,
{
headers
}
accessToken
).then((res: any) => res.result.items.map((i: any) => i.line).join('\n'))
}
if (jobStatus === 'failed') {
return Promise.reject({ error: currentJob.error, log })
}
return { result: jobResult?.result, log }
}
@@ -1042,22 +996,13 @@ export class SASViyaApiClient {
}
const url = '/folders/folders/@item?path=' + path
const requestInfo: any = {
method: 'GET'
}
if (accessToken) {
requestInfo.headers = { Authorization: `Bearer ${accessToken}` }
}
const { result: folder } = await this.request<Folder>(
`${this.serverUrl}${url}`,
requestInfo
)
const { result: folder } = await this.get<Folder>(`${url}`, accessToken)
if (!folder) {
throw new Error(`The path ${path} does not exist on ${this.serverUrl}`)
}
const { result: members } = await this.request<{ items: any[] }>(
`${this.serverUrl}/folders/folders/${folder.id}/members?limit=${folder.memberCount}`,
requestInfo
const { result: members } = await this.get<{ items: any[] }>(
`/folders/folders/${folder.id}/members?limit=${folder.memberCount}`,
accessToken
)
const itemsAtRoot = members.items
@@ -1093,12 +1038,10 @@ export class SASViyaApiClient {
Promise.reject(`Job state link was not found.`)
}
const { result: state } = await this.request<string>(
const { result: state } = await this.get<string>(
`${this.serverUrl}${stateLink.href}?_action=wait&wait=30`,
{
headers
},
'text'
accessToken,
'text/plain'
)
const currentState = state.trim()
@@ -1116,12 +1059,10 @@ export class SASViyaApiClient {
postedJobState === 'pending'
) {
if (stateLink) {
const { result: jobState } = await this.request<string>(
const { result: jobState } = await this.get<string>(
`${this.serverUrl}${stateLink.href}?_action=wait&wait=30`,
{
headers
},
'text'
accessToken,
'text/plain'
)
postedJobState = jobState.trim()
@@ -1164,17 +1105,10 @@ export class SASViyaApiClient {
)
}
const createFileRequest = {
method: 'POST',
body: csv,
headers
}
const uploadResponse = await this.request<any>(
const uploadResponse = await this.uploadFile(
`${this.serverUrl}/files/files#rawUpload`,
createFileRequest,
'json',
'fileUpload'
csv,
accessToken
)
uploadedFiles.push({ tableName, file: uploadResponse.result })
@@ -1184,16 +1118,10 @@ export class SASViyaApiClient {
private async getFolderUri(folderPath: string, accessToken?: string) {
const url = '/folders/folders/@item?path=' + folderPath
const requestInfo: any = {
method: 'GET'
}
if (accessToken) {
requestInfo.headers = { Authorization: `Bearer ${accessToken}` }
}
const { result: folder } = await this.request<Folder>(
const { result: folder } = await this.get<Folder>(
`${this.serverUrl}${url}`,
requestInfo
).catch((err) => {
accessToken
).catch(() => {
return { result: null }
})
@@ -1203,18 +1131,11 @@ export class SASViyaApiClient {
private async getRecycleBinUri(accessToken: string) {
const url = '/folders/folders/@myRecycleBin'
const requestInfo = {
method: 'GET',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer ' + accessToken
}
}
const { result: folder } = await this.request<Folder>(
const { result: folder } = await this.get<Folder>(
`${this.serverUrl}${url}`,
requestInfo
).catch((err) => {
accessToken
).catch(() => {
return { result: null }
})
@@ -1280,22 +1201,14 @@ export class SASViyaApiClient {
const sourceFolderId = sourceFolderUri?.split('/').pop()
const url = sourceFolderUri
const requestInfo = {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer ' + accessToken
},
body: JSON.stringify({
const { result: folder } = await this.patch<Folder>(
`${this.serverUrl}${url}`,
JSON.stringify({
id: sourceFolderId,
name: targetFolderName,
parentFolderUri: targetParentFolderUri
})
}
const { result: folder } = await this.request<Folder>(
`${this.serverUrl}${url}`,
requestInfo
}),
accessToken
).catch((err) => {
if (err.code && err.code === 'ENOTFOUND') {
const notFoundError = {
@@ -1346,32 +1259,165 @@ export class SASViyaApiClient {
this.fileUploadCsrfToken = csrfToken
}
private async request<T>(
private get<T>(
url: string,
options: RequestInit,
contentType: 'text' | 'json' = 'json',
type: 'fileUpload' | 'other' = 'other'
accessToken?: string,
contentType = 'application/json'
) {
const callback =
type === 'fileUpload'
? this.setFileUploadCsrfToken
: this.setCsrfTokenLocal
if (type === 'other') {
if (this.csrfToken) {
options.headers = {
...options.headers,
[this.csrfToken.headerName]: this.csrfToken.value
}
}
} else {
if (this.fileUploadCsrfToken) {
options.headers = {
...options.headers,
[this.fileUploadCsrfToken.headerName]: this.fileUploadCsrfToken.value
}
}
const headers: any = {
'Content-Type': contentType
}
return await makeRequest<T>(url, options, callback, contentType)
if (accessToken) {
headers.Authorization = `Bearer ${accessToken}`
}
const requestConfig: AxiosRequestConfig = {
headers,
responseType: contentType === 'text/plain' ? 'text' : 'json',
withCredentials: true
}
if (contentType === 'text/plain') {
requestConfig.headers.Accept = '*/*'
requestConfig.transformResponse = undefined
}
return this.httpClient.get<T>(url, requestConfig).then((response) => ({
result: response.data,
etag: response.headers['etag']
}))
}
private post<T>(
url: string,
data: any = {},
accessToken?: string
): Promise<{ result: T; etag: string }> {
const headers: any = {
'Content-Type': 'application/json'
}
if (accessToken) {
headers.Authorization = `Bearer ${accessToken}`
}
if (this.csrfToken?.value) {
headers[this.csrfToken.headerName] = this.csrfToken.value
}
return this.httpClient
.post<T>(url, data, { headers, withCredentials: true })
.then((response) => {
return {
result: response.data as T,
etag: response.headers['etag'] as string
}
})
.catch((e) => {
const response = e.response as AxiosResponse
if (response.status === 403 || response.status === 449) {
const tokenHeader = (response.headers[
'x-csrf-header'
] as string)?.toLowerCase()
if (tokenHeader) {
const token = response.headers[tokenHeader]
this.setCsrfTokenLocal({
headerName: tokenHeader,
value: token || ''
})
return this.post<T>(url, data, accessToken)
}
throw e
}
throw e
})
}
private delete<T>(url: string, accessToken?: string) {
const headers: any = {}
if (accessToken) {
headers.Authorization = `Bearer ${accessToken}`
}
if (this.csrfToken?.value) {
headers[this.csrfToken.headerName] = this.csrfToken.value
}
const requestConfig: AxiosRequestConfig = {
headers
}
return this.httpClient.delete<T>(url, requestConfig).then((response) => ({
result: response.data,
etag: response.headers['etag']
}))
}
private patch<T>(url: string, data: any = {}, accessToken?: string) {
const headers: any = {
'Content-Type': 'application/json'
}
if (accessToken) {
headers.Authorization = `Bearer ${accessToken}`
}
if (this.csrfToken?.value) {
headers[this.csrfToken.headerName] = this.csrfToken.value
}
return this.httpClient
.patch<T>(url, data, { headers, withCredentials: true })
.then((response) => {
return {
result: response.data as T,
etag: response.headers['etag'] as string
}
})
}
private uploadFile(
url: string,
content: string,
accessToken?: string
): Promise<any> {
const headers: any = {
'Content-Type': 'application/json'
}
if (accessToken) {
headers.Authorization = `Bearer ${accessToken}`
}
if (this.fileUploadCsrfToken?.value) {
headers[
this.fileUploadCsrfToken.headerName
] = this.fileUploadCsrfToken.value
}
return this.httpClient
.post(url, content, { headers, withCredentials: true })
.then((response) => {
return {
result: response.data,
etag: response.headers['etag'] as string
}
})
.catch((e) => {
const response = e.response as AxiosResponse
if (response.status === 403 || response.status === 449) {
const tokenHeader = (response.headers[
'x-csrf-header'
] as string)?.toLowerCase()
if (tokenHeader) {
const token = response.headers[tokenHeader]
this.setFileUploadCsrfToken({
headerName: tokenHeader,
value: token || ''
})
return this.uploadFile(url, content, accessToken)
}
throw e
}
throw e
})
}
}

View File

@@ -2,7 +2,6 @@ import {
convertToCSV,
compareTimestamps,
splitChunks,
isLogInRequired,
parseSourceCode,
parseGeneratedCode,
parseWeboutResponse,
@@ -24,7 +23,7 @@ import {
import { SASViyaApiClient } from './SASViyaApiClient'
import { SAS9ApiClient } from './SAS9ApiClient'
import { FileUploader } from './FileUploader'
import { AuthManager } from './auth/auth'
import { isLogInRequired, AuthManager } from './auth'
const defaultConfig: SASjsConfig = {
serverUrl: '',
@@ -732,7 +731,11 @@ export default class SASjs {
let responseJson
try {
responseJson = JSON.parse(response!.result)
if (typeof response!.result === 'string') {
responseJson = JSON.parse(response!.result)
} else {
responseJson = response!.result
}
} catch {
responseJson = JSON.parse(parseWeboutResponse(response!.result))
}
@@ -837,7 +840,11 @@ export default class SASjs {
let responseJson
try {
responseJson = JSON.parse(response!.result)
if (typeof response!.result === 'string') {
responseJson = JSON.parse(response!.result)
} else {
responseJson = response!.result
}
} catch {
responseJson = JSON.parse(
parseWeboutResponse(response!.result)

View File

@@ -1,11 +1,7 @@
import axios, { AxiosInstance } from 'axios'
import { isAuthorizeFormRequired, parseAndSubmitAuthorizeForm } from '.'
import { ServerType } from '../types'
import {
serialize,
isAuthorizeFormRequired,
parseAndSubmitAuthorizeForm,
isLogInSuccess
} from '../utils'
import { serialize } from '../utils'
export class AuthManager {
public userName = ''
@@ -15,7 +11,7 @@ export class AuthManager {
constructor(
private serverUrl: string,
private serverType: ServerType,
private loginCallback: Function
private loginCallback: () => Promise<void>
) {
this.httpClient = axios.create({ baseURL: this.serverUrl })
this.loginUrl = `/SASLogon/login`
@@ -41,7 +37,7 @@ export class AuthManager {
const { isLoggedIn, loginForm } = await this.checkSession()
if (isLoggedIn) {
this.loginCallback()
await this.loginCallback()
return {
isLoggedIn,
@@ -58,7 +54,10 @@ export class AuthManager {
.post<string>(this.loginUrl, loginParamsStr, {
withCredentials: true,
responseType: 'text',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Accept: '*/*'
}
})
.then((response) => response.data)
@@ -159,3 +158,6 @@ export class AuthManager {
return this.httpClient.get(this.logoutUrl).then(() => true)
}
}
const isLogInSuccess = (response: string): boolean =>
/You have signed in/gm.test(response)

6
src/auth/index.ts Normal file
View File

@@ -0,0 +1,6 @@
import { AuthManager } from './AuthManager'
export * from './AuthManager'
export * from './isAuthorizeFormRequired'
export * from './isLoginRequired'
export * from './parseAndSubmitAuthorizeForm'

View File

@@ -37,6 +37,12 @@ export const parseAndSubmitAuthorizeForm = async (
}
return await axios
.post(authUrl, formData, { withCredentials: true, responseType: 'text' })
.then((response) => response.data)
.post(authUrl, formData, {
withCredentials: true,
responseType: 'text',
headers: {
Accept: '*/*'
}
})
.then((res) => res.data)
}

View File

@@ -1,15 +1,11 @@
export * from './asyncForEach'
export * from './compareTimestamps'
export * from './convertToCsv'
export * from './isAuthorizeFormRequired'
export * from './isLoginRequired'
export * from './isLoginSuccess'
export * from './isRelativePath'
export * from './isUri'
export * from './isUrl'
export * from './makeRequest'
export * from './needsRetry'
export * from './parseAndSubmitAuthorizeForm'
export * from './parseGeneratedCode'
export * from './parseSourceCode'
export * from './parseSasViyaLog'

View File

@@ -1,2 +0,0 @@
export const isLogInSuccess = (response: string): boolean =>
/You have signed in/gm.test(response)