@sasjs/adapter 3.1.0 → 3.2.0
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.
- package/SASViyaApiClient.d.ts +2 -8
- package/SASjs.d.ts +16 -10
- package/SASjsApiClient.d.ts +22 -0
- package/auth/AuthManager.d.ts +12 -4
- package/auth/getAccessTokenForSasjs.d.ts +11 -0
- package/auth/{getAccessToken.d.ts → getAccessTokenForViya.d.ts} +1 -1
- package/auth/getAuthCodeForSasjs.d.ts +9 -0
- package/auth/getTokens.d.ts +3 -2
- package/auth/refreshTokensForSasjs.d.ts +10 -0
- package/auth/{refreshTokens.d.ts → refreshTokensForViya.d.ts} +2 -2
- package/auth/spec/{getAccessToken.spec.d.ts → getAccessTokenForSasjs.spec.d.ts} +0 -0
- package/auth/spec/{refreshTokens.spec.d.ts → getAccessTokenForViya.spec.d.ts} +0 -0
- package/auth/spec/mockResponses.d.ts +4 -0
- package/auth/spec/refreshTokensForSasjs.spec.d.ts +1 -0
- package/auth/spec/refreshTokensForViya.spec.d.ts +1 -0
- package/index.js +2 -2
- package/node/SASViyaApiClient.d.ts +2 -8
- package/node/SASjs.d.ts +15 -9
- package/node/SASjsApiClient.d.ts +22 -0
- package/node/auth/AuthManager.d.ts +11 -3
- package/node/auth/getAccessTokenForSasjs.d.ts +11 -0
- package/node/auth/{getAccessToken.d.ts → getAccessTokenForViya.d.ts} +1 -1
- package/node/auth/getAuthCodeForSasjs.d.ts +9 -0
- package/node/auth/getTokens.d.ts +3 -2
- package/node/auth/refreshTokensForSasjs.d.ts +10 -0
- package/node/auth/{refreshTokens.d.ts → refreshTokensForViya.d.ts} +2 -2
- package/node/index.js +2 -2
- package/node/request/RequestClient.d.ts +4 -0
- package/node/request/SasjsRequestClient.d.ts +8 -0
- package/package.json +1 -1
- package/request/RequestClient.d.ts +4 -0
- package/request/SasjsRequestClient.d.ts +8 -0
- package/src/SASViyaApiClient.ts +10 -5
- package/src/SASjs.ts +83 -47
- package/src/SASjsApiClient.ts +43 -0
- package/src/auth/AuthManager.ts +65 -10
- package/src/auth/getAccessTokenForSasjs.ts +36 -0
- package/src/auth/{getAccessToken.ts → getAccessTokenForViya.ts} +1 -1
- package/src/auth/getAuthCodeForSasjs.ts +31 -0
- package/src/auth/getTokens.ts +16 -9
- package/src/auth/refreshTokensForSasjs.ts +35 -0
- package/src/auth/{refreshTokens.ts → refreshTokensForViya.ts} +2 -2
- package/src/auth/spec/mockResponses.ts +5 -0
- package/src/job-execution/WebJobExecutor.ts +0 -1
- package/src/request/RequestClient.ts +11 -0
- package/src/request/Sas9RequestClient.ts +1 -1
- package/src/request/SasjsRequestClient.ts +23 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { prefixMessage } from '@sasjs/utils/error'
|
|
2
|
+
import { RequestClient } from '../request/RequestClient'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Exchanges the auth code for an access token for the given client.
|
|
6
|
+
* @param requestClient - the pre-configured HTTP request client
|
|
7
|
+
* @param clientId - the client ID to authenticate with.
|
|
8
|
+
* @param authCode - the auth code received from the server.
|
|
9
|
+
*/
|
|
10
|
+
export async function getAccessTokenForSasjs(
|
|
11
|
+
requestClient: RequestClient,
|
|
12
|
+
clientId: string,
|
|
13
|
+
authCode: string
|
|
14
|
+
) {
|
|
15
|
+
const url = '/SASjsApi/auth/token'
|
|
16
|
+
const data = {
|
|
17
|
+
clientId,
|
|
18
|
+
code: authCode
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return await requestClient
|
|
22
|
+
.post(url, data, undefined)
|
|
23
|
+
.then((res) => {
|
|
24
|
+
const sasAuth = res.result as {
|
|
25
|
+
accessToken: string
|
|
26
|
+
refreshToken: string
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
access_token: sasAuth.accessToken,
|
|
30
|
+
refresh_token: sasAuth.refreshToken
|
|
31
|
+
}
|
|
32
|
+
})
|
|
33
|
+
.catch((err) => {
|
|
34
|
+
throw prefixMessage(err, 'Error while getting access token. ')
|
|
35
|
+
})
|
|
36
|
+
}
|
|
@@ -10,7 +10,7 @@ import { RequestClient } from '../request/RequestClient'
|
|
|
10
10
|
* @param clientSecret - the client secret to authenticate with.
|
|
11
11
|
* @param authCode - the auth code received from the server.
|
|
12
12
|
*/
|
|
13
|
-
export async function
|
|
13
|
+
export async function getAccessTokenForViya(
|
|
14
14
|
requestClient: RequestClient,
|
|
15
15
|
clientId: string,
|
|
16
16
|
clientSecret: string,
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { prefixMessage } from '@sasjs/utils/error'
|
|
2
|
+
import { RequestClient } from '../request/RequestClient'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Performs a login authenticate and returns an auth code for the given client.
|
|
6
|
+
* @param requestClient - the pre-configured HTTP request client
|
|
7
|
+
* @param username - a string representing the username.
|
|
8
|
+
* @param password - a string representing the password.
|
|
9
|
+
* @param clientId - the client ID to authenticate with.
|
|
10
|
+
*/
|
|
11
|
+
export const getAuthCodeForSasjs = async (
|
|
12
|
+
requestClient: RequestClient,
|
|
13
|
+
username: string,
|
|
14
|
+
password: string,
|
|
15
|
+
clientId: string
|
|
16
|
+
) => {
|
|
17
|
+
const url = '/SASjsApi/auth/authorize'
|
|
18
|
+
const data = { username, password, clientId }
|
|
19
|
+
|
|
20
|
+
const { code: authCode } = await requestClient
|
|
21
|
+
.post<{ code: string }>(url, data, undefined)
|
|
22
|
+
.then((res) => res.result)
|
|
23
|
+
.catch((err) => {
|
|
24
|
+
throw prefixMessage(
|
|
25
|
+
err,
|
|
26
|
+
'Error while authenticating with provided username, password and clientId. '
|
|
27
|
+
)
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
return authCode
|
|
31
|
+
}
|
package/src/auth/getTokens.ts
CHANGED
|
@@ -3,18 +3,21 @@ import {
|
|
|
3
3
|
isRefreshTokenExpiring,
|
|
4
4
|
hasTokenExpired
|
|
5
5
|
} from '@sasjs/utils/auth'
|
|
6
|
-
import { AuthConfig } from '@sasjs/utils/types'
|
|
6
|
+
import { AuthConfig, ServerType } from '@sasjs/utils/types'
|
|
7
7
|
import { RequestClient } from '../request/RequestClient'
|
|
8
|
-
import {
|
|
8
|
+
import { refreshTokensForViya } from './refreshTokensForViya'
|
|
9
|
+
import { refreshTokensForSasjs } from './refreshTokensForSasjs'
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Returns the auth configuration, refreshing the tokens if necessary.
|
|
12
13
|
* @param requestClient - the pre-configured HTTP request client
|
|
13
14
|
* @param authConfig - an object containing a client ID, secret, access token and refresh token
|
|
15
|
+
* @param serverType - server type for which refreshing the tokens, defaults to SASVIYA
|
|
14
16
|
*/
|
|
15
17
|
export async function getTokens(
|
|
16
18
|
requestClient: RequestClient,
|
|
17
|
-
authConfig: AuthConfig
|
|
19
|
+
authConfig: AuthConfig,
|
|
20
|
+
serverType: ServerType = ServerType.SasViya
|
|
18
21
|
): Promise<AuthConfig> {
|
|
19
22
|
const logger = process.logger || console
|
|
20
23
|
let { access_token, refresh_token, client, secret } = authConfig
|
|
@@ -29,12 +32,16 @@ export async function getTokens(
|
|
|
29
32
|
throw new Error(error)
|
|
30
33
|
}
|
|
31
34
|
logger.info('Refreshing access and refresh tokens.')
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
const tokens =
|
|
36
|
+
serverType === ServerType.SasViya
|
|
37
|
+
? await refreshTokensForViya(
|
|
38
|
+
requestClient,
|
|
39
|
+
client,
|
|
40
|
+
secret,
|
|
41
|
+
refresh_token
|
|
42
|
+
)
|
|
43
|
+
: await refreshTokensForSasjs(requestClient, refresh_token)
|
|
44
|
+
;({ access_token, refresh_token } = tokens)
|
|
38
45
|
}
|
|
39
46
|
return { access_token, refresh_token, client, secret }
|
|
40
47
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { prefixMessage } from '@sasjs/utils/error'
|
|
2
|
+
import { RequestClient } from '../request/RequestClient'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Exchanges the refresh token for an access token for the given client.
|
|
6
|
+
* @param requestClient - the pre-configured HTTP request client
|
|
7
|
+
* @param refreshToken - the refresh token received from the server.
|
|
8
|
+
*/
|
|
9
|
+
export async function refreshTokensForSasjs(
|
|
10
|
+
requestClient: RequestClient,
|
|
11
|
+
refreshToken: string
|
|
12
|
+
) {
|
|
13
|
+
const url = '/SASjsApi/auth/refresh'
|
|
14
|
+
const headers = {
|
|
15
|
+
Authorization: 'Bearer ' + refreshToken
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const authResponse = await requestClient
|
|
19
|
+
.post(url, undefined, undefined, undefined, headers)
|
|
20
|
+
.then((res) => {
|
|
21
|
+
const sasAuth = res.result as {
|
|
22
|
+
accessToken: string
|
|
23
|
+
refreshToken: string
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
access_token: sasAuth.accessToken,
|
|
27
|
+
refresh_token: sasAuth.refreshToken
|
|
28
|
+
}
|
|
29
|
+
})
|
|
30
|
+
.catch((err) => {
|
|
31
|
+
throw prefixMessage(err, 'Error while refreshing tokens')
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
return authResponse
|
|
35
|
+
}
|
|
@@ -8,9 +8,9 @@ import { RequestClient } from '../request/RequestClient'
|
|
|
8
8
|
* @param requestClient - the pre-configured HTTP request client
|
|
9
9
|
* @param clientId - the client ID to authenticate with.
|
|
10
10
|
* @param clientSecret - the client secret to authenticate with.
|
|
11
|
-
* @param
|
|
11
|
+
* @param refreshToken - the refresh token received from the server.
|
|
12
12
|
*/
|
|
13
|
-
export async function
|
|
13
|
+
export async function refreshTokensForViya(
|
|
14
14
|
requestClient: RequestClient,
|
|
15
15
|
clientId: string,
|
|
16
16
|
clientSecret: string,
|
|
@@ -13,6 +13,11 @@ export const mockAuthResponse: SasAuthResponse = {
|
|
|
13
13
|
jti: 'test'
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
export const mockSasjsAuthResponse = {
|
|
17
|
+
access_token: 'acc355',
|
|
18
|
+
refresh_token: 'r3fr35h'
|
|
19
|
+
}
|
|
20
|
+
|
|
16
21
|
export const generateToken = (timeToLiveSeconds: number): string => {
|
|
17
22
|
const exp =
|
|
18
23
|
new Date(new Date().getTime() + timeToLiveSeconds * 1000).getTime() / 1000
|
|
@@ -144,7 +144,6 @@ export class WebJobExecutor extends BaseJobExecutor {
|
|
|
144
144
|
}
|
|
145
145
|
|
|
146
146
|
const requestPromise = new Promise((resolve, reject) => {
|
|
147
|
-
// Access token is required for server type `SASjs`
|
|
148
147
|
this.requestClient!.post(apiUrl, formData, authConfig?.access_token)
|
|
149
148
|
.then(async (res: any) => {
|
|
150
149
|
const resObj =
|
|
@@ -48,7 +48,9 @@ export interface HttpClient {
|
|
|
48
48
|
): Promise<{ result: T; etag: string }>
|
|
49
49
|
|
|
50
50
|
getCsrfToken(type: 'general' | 'file'): CsrfToken | undefined
|
|
51
|
+
saveLocalStorageToken(accessToken: string, refreshToken: string): void
|
|
51
52
|
clearCsrfTokens(): void
|
|
53
|
+
clearLocalStorageTokens(): void
|
|
52
54
|
getBaseUrl(): string
|
|
53
55
|
}
|
|
54
56
|
|
|
@@ -70,6 +72,11 @@ export class RequestClient implements HttpClient {
|
|
|
70
72
|
this.createHttpClient(baseUrl, httpsAgentOptions)
|
|
71
73
|
}
|
|
72
74
|
|
|
75
|
+
public saveLocalStorageToken(accessToken: string, refreshToken: string) {
|
|
76
|
+
localStorage.setItem('accessToken', accessToken)
|
|
77
|
+
localStorage.setItem('refreshToken', refreshToken)
|
|
78
|
+
}
|
|
79
|
+
|
|
73
80
|
public getCsrfToken(type: 'general' | 'file' = 'general') {
|
|
74
81
|
return type === 'file' ? this.fileUploadCsrfToken : this.csrfToken
|
|
75
82
|
}
|
|
@@ -78,6 +85,10 @@ export class RequestClient implements HttpClient {
|
|
|
78
85
|
this.csrfToken = { headerName: '', value: '' }
|
|
79
86
|
this.fileUploadCsrfToken = { headerName: '', value: '' }
|
|
80
87
|
}
|
|
88
|
+
public clearLocalStorageTokens() {
|
|
89
|
+
localStorage.setItem('accessToken', '')
|
|
90
|
+
localStorage.setItem('refreshToken', '')
|
|
91
|
+
}
|
|
81
92
|
|
|
82
93
|
public getBaseUrl() {
|
|
83
94
|
return this.httpClient.defaults.baseURL || ''
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { RequestClient } from './RequestClient'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Specific request client for SASJS.
|
|
5
|
+
* Append tokens in headers.
|
|
6
|
+
*/
|
|
7
|
+
export class SasjsRequestClient extends RequestClient {
|
|
8
|
+
getHeaders = (accessToken: string | undefined, contentType: string) => {
|
|
9
|
+
const headers: any = {}
|
|
10
|
+
|
|
11
|
+
if (contentType !== 'application/x-www-form-urlencoded')
|
|
12
|
+
headers['Content-Type'] = contentType
|
|
13
|
+
|
|
14
|
+
headers.Accept = contentType === 'application/json' ? contentType : '*/*'
|
|
15
|
+
|
|
16
|
+
if (!accessToken)
|
|
17
|
+
accessToken = localStorage.getItem('accessToken') ?? undefined
|
|
18
|
+
|
|
19
|
+
if (accessToken) headers.Authorization = `Bearer ${accessToken}`
|
|
20
|
+
|
|
21
|
+
return headers
|
|
22
|
+
}
|
|
23
|
+
}
|