mirror of
https://github.com/sasjs/adapter.git
synced 2026-01-07 12:30:06 +00:00
feat(login): add redirected login mechanism
This commit is contained in:
28
src/SASjs.ts
28
src/SASjs.ts
@@ -1,5 +1,11 @@
|
|||||||
import { compareTimestamps, asyncForEach } from './utils'
|
import { compareTimestamps, asyncForEach } from './utils'
|
||||||
import { SASjsConfig, UploadFile, EditContextInput, PollOptions } from './types'
|
import {
|
||||||
|
SASjsConfig,
|
||||||
|
UploadFile,
|
||||||
|
EditContextInput,
|
||||||
|
PollOptions,
|
||||||
|
LoginMechanism
|
||||||
|
} from './types'
|
||||||
import { SASViyaApiClient } from './SASViyaApiClient'
|
import { SASViyaApiClient } from './SASViyaApiClient'
|
||||||
import { SAS9ApiClient } from './SAS9ApiClient'
|
import { SAS9ApiClient } from './SAS9ApiClient'
|
||||||
import { FileUploader } from './FileUploader'
|
import { FileUploader } from './FileUploader'
|
||||||
@@ -29,7 +35,8 @@ const defaultConfig: SASjsConfig = {
|
|||||||
debug: false,
|
debug: false,
|
||||||
contextName: 'SAS Job Execution compute context',
|
contextName: 'SAS Job Execution compute context',
|
||||||
useComputeApi: null,
|
useComputeApi: null,
|
||||||
allowInsecureRequests: false
|
allowInsecureRequests: false,
|
||||||
|
loginMechanism: LoginMechanism.Default
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -526,10 +533,25 @@ export default class SASjs {
|
|||||||
* @param username - a string representing the username.
|
* @param username - a string representing the username.
|
||||||
* @param password - a string representing the password.
|
* @param password - a string representing the password.
|
||||||
*/
|
*/
|
||||||
public async logIn(username: string, password: string) {
|
public async logIn(username?: string, password?: string) {
|
||||||
|
if (this.sasjsConfig.loginMechanism === LoginMechanism.Default) {
|
||||||
|
if (!username || !password) {
|
||||||
|
throw new Error(
|
||||||
|
'A username and password are required when using the default login mechanism.'
|
||||||
|
)
|
||||||
|
}
|
||||||
return this.authManager!.logIn(username, password)
|
return this.authManager!.logIn(username, password)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (typeof window === typeof undefined) {
|
||||||
|
throw new Error(
|
||||||
|
'The redirected login mechanism is only available for use in the browser.'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.authManager!.redirectedLogIn()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs out of the configured SAS server.
|
* Logs out of the configured SAS server.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { getTokens } from '../../auth/getTokens'
|
|||||||
import { RequestClient } from '../../request/RequestClient'
|
import { RequestClient } from '../../request/RequestClient'
|
||||||
import { JobStatePollError } from '../../types/errors'
|
import { JobStatePollError } from '../../types/errors'
|
||||||
import { Link, WriteStream } from '../../types'
|
import { Link, WriteStream } from '../../types'
|
||||||
import { isNode } from '../../utils'
|
import { delay, isNode } from '../../utils'
|
||||||
|
|
||||||
export async function pollJobState(
|
export async function pollJobState(
|
||||||
requestClient: RequestClient,
|
requestClient: RequestClient,
|
||||||
@@ -246,5 +246,3 @@ const doPoll = async (
|
|||||||
|
|
||||||
return { state, pollCount }
|
return { state, pollCount }
|
||||||
}
|
}
|
||||||
|
|
||||||
const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms))
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { ServerType } from '@sasjs/utils/types'
|
import { ServerType } from '@sasjs/utils/types'
|
||||||
import { RequestClient } from '../request/RequestClient'
|
import { RequestClient } from '../request/RequestClient'
|
||||||
import { serialize } from '../utils'
|
import { delay, serialize } from '../utils'
|
||||||
|
|
||||||
export class AuthManager {
|
export class AuthManager {
|
||||||
public userName = ''
|
public userName = ''
|
||||||
@@ -19,6 +19,37 @@ export class AuthManager {
|
|||||||
: '/SASLogon/logout.do?'
|
: '/SASLogon/logout.do?'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async redirectedLogIn() {
|
||||||
|
await this.logOut()
|
||||||
|
const loginPopup = window.open(
|
||||||
|
this.loginUrl.replace('.do', ''),
|
||||||
|
'_blank',
|
||||||
|
'toolbar=0,location=0,menubar=0,width=500,height=500'
|
||||||
|
)
|
||||||
|
let isLoggedIn = false
|
||||||
|
let startTime = new Date()
|
||||||
|
let elapsedSeconds = 0
|
||||||
|
do {
|
||||||
|
await delay(1000)
|
||||||
|
isLoggedIn =
|
||||||
|
document.cookie.includes('Current-User') &&
|
||||||
|
document.cookie.includes('userId')
|
||||||
|
elapsedSeconds = (new Date().valueOf() - startTime.valueOf()) / 1000
|
||||||
|
} while (!isLoggedIn && elapsedSeconds < 5 * 60)
|
||||||
|
|
||||||
|
let isAuthorized = false
|
||||||
|
startTime = new Date()
|
||||||
|
do {
|
||||||
|
await delay(1000)
|
||||||
|
isAuthorized = !loginPopup?.window.location.href.includes('SASLogon')
|
||||||
|
elapsedSeconds = (new Date().valueOf() - startTime.valueOf()) / 1000
|
||||||
|
} while (!isAuthorized && elapsedSeconds < 5 * 60)
|
||||||
|
|
||||||
|
loginPopup?.close()
|
||||||
|
|
||||||
|
return { isLoggedIn: isLoggedIn && isAuthorized, userName: 'test' }
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs into the SAS server with the supplied credentials.
|
* Logs into the SAS server with the supplied credentials.
|
||||||
* @param username - a string representing the username.
|
* @param username - a string representing the username.
|
||||||
|
|||||||
@@ -59,4 +59,13 @@ export class SASjsConfig {
|
|||||||
* Changing this setting is not recommended.
|
* Changing this setting is not recommended.
|
||||||
*/
|
*/
|
||||||
allowInsecureRequests = false
|
allowInsecureRequests = false
|
||||||
|
/**
|
||||||
|
* Supported login mechanisms are - Redirected and Default
|
||||||
|
*/
|
||||||
|
loginMechanism: LoginMechanism = LoginMechanism.Default
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum LoginMechanism {
|
||||||
|
Default = 'Default',
|
||||||
|
Redirected = 'Redirected'
|
||||||
}
|
}
|
||||||
|
|||||||
2
src/utils/delay.ts
Normal file
2
src/utils/delay.ts
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
export const delay = (ms: number) =>
|
||||||
|
new Promise((resolve) => setTimeout(resolve, ms))
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
export * from './asyncForEach'
|
export * from './asyncForEach'
|
||||||
export * from './compareTimestamps'
|
export * from './compareTimestamps'
|
||||||
export * from './convertToCsv'
|
export * from './convertToCsv'
|
||||||
|
export * from './delay'
|
||||||
export * from './isNode'
|
export * from './isNode'
|
||||||
export * from './isRelativePath'
|
export * from './isRelativePath'
|
||||||
export * from './isUri'
|
export * from './isUri'
|
||||||
|
|||||||
Reference in New Issue
Block a user