mirror of
https://github.com/sasjs/adapter.git
synced 2026-01-04 03:00:05 +00:00
feat(auth): added utils to get and check login header
This commit is contained in:
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"cSpell.words": ["SASVIYA"]
|
||||||
|
}
|
||||||
@@ -2,11 +2,12 @@ import { ServerType } from '@sasjs/utils/types'
|
|||||||
import { RequestClient } from '../request/RequestClient'
|
import { RequestClient } from '../request/RequestClient'
|
||||||
import { NotFoundError } from '../types/errors'
|
import { NotFoundError } from '../types/errors'
|
||||||
import { LoginOptions, LoginResult, LoginResultInternal } from '../types/Login'
|
import { LoginOptions, LoginResult, LoginResultInternal } from '../types/Login'
|
||||||
import { serialize, getUserLanguage } from '../utils'
|
import { serialize } from '../utils'
|
||||||
import { extractUserLongNameSas9 } from '../utils/sas9/extractUserLongNameSas9'
|
import { extractUserLongNameSas9 } from '../utils/sas9/extractUserLongNameSas9'
|
||||||
import { openWebPage } from './openWebPage'
|
import { openWebPage } from './openWebPage'
|
||||||
import { verifySas9Login } from './verifySas9Login'
|
import { verifySas9Login } from './verifySas9Login'
|
||||||
import { verifySasViyaLogin } from './verifySasViyaLogin'
|
import { verifySasViyaLogin } from './verifySasViyaLogin'
|
||||||
|
import { isLogInSuccessHeaderPresent } from './'
|
||||||
|
|
||||||
export class AuthManager {
|
export class AuthManager {
|
||||||
public userName = ''
|
public userName = ''
|
||||||
@@ -14,46 +15,6 @@ export class AuthManager {
|
|||||||
private loginUrl: string
|
private loginUrl: string
|
||||||
private logoutUrl: string
|
private logoutUrl: string
|
||||||
private redirectedLoginUrl = `/SASLogon` //SAS 9 M8 no longer redirects from `/SASLogon/home` to the login page. `/SASLogon` seems to be stable enough across SAS versions
|
private redirectedLoginUrl = `/SASLogon` //SAS 9 M8 no longer redirects from `/SASLogon/home` to the login page. `/SASLogon` seems to be stable enough across SAS versions
|
||||||
private defaultSuccessHeaderKey = 'default'
|
|
||||||
|
|
||||||
// The following headers provided by https://github.com/sasjs/adapter/issues/835#issuecomment-2177818601
|
|
||||||
private loginSuccessHeaders: { [key: string]: string } = {
|
|
||||||
es: `Ya se ha iniciado la sesi\u00f3n.`,
|
|
||||||
th: `\u0e04\u0e38\u0e13\u0e25\u0e07\u0e0a\u0e37\u0e48\u0e2d\u0e40\u0e02\u0e49\u0e32\u0e43\u0e0a\u0e49\u0e41\u0e25\u0e49\u0e27`,
|
|
||||||
ja: `\u30b5\u30a4\u30f3\u30a4\u30f3\u3057\u307e\u3057\u305f\u3002`,
|
|
||||||
nb: `Du har logget deg p\u00e5.`,
|
|
||||||
sl: `Prijavili ste se.`,
|
|
||||||
ar: `\u0644\u0642\u062f \u0642\u0645\u062a `,
|
|
||||||
sk: `Prihl\u00e1sili ste sa.`,
|
|
||||||
zh_HK: `\u60a8\u5df2\u767b\u5165\u3002`,
|
|
||||||
zh_CN: `\u60a8\u5df2\u767b\u5f55\u3002`,
|
|
||||||
it: `L'utente si \u00e8 connesso.`,
|
|
||||||
sv: `Du har loggat in.`,
|
|
||||||
he: `\u05e0\u05db\u05e0\u05e1\u05ea `,
|
|
||||||
nl: `U hebt zich aangemeld.`,
|
|
||||||
pl: `Zosta\u0142e\u015b zalogowany.`,
|
|
||||||
ko: `\ub85c\uadf8\uc778\ud588\uc2b5\ub2c8\ub2e4.`,
|
|
||||||
zh_TW: `\u60a8\u5df2\u767b\u5165\u3002`,
|
|
||||||
tr: `Oturum a\u00e7t\u0131n\u0131z.`,
|
|
||||||
iw: `\u05e0\u05db\u05e0\u05e1\u05ea `,
|
|
||||||
fr: `Vous \u00eates connect\u00e9.`,
|
|
||||||
uk: `\u0412\u0438 \u0432\u0432\u0456\u0439\u0448\u043b\u0438 \u0432 \u043e\u0431\u043b\u0456\u043a\u043e\u0432\u0438\u0439 \u0437\u0430\u043f\u0438\u0441.`,
|
|
||||||
pt_BR: `Voc\u00ea se conectou.`,
|
|
||||||
no: `Du har logget deg p\u00e5.`,
|
|
||||||
cs: `Jste p\u0159ihl\u00e1\u0161eni.`,
|
|
||||||
fi: `Olet kirjautunut sis\u00e4\u00e4n.`,
|
|
||||||
ru: `\u0412\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u043b\u0438 \u0432\u0445\u043e\u0434 \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0443.`,
|
|
||||||
el: `\u0388\u03c7\u03b5\u03c4\u03b5 \u03c3\u03c5\u03bd\u03b4\u03b5\u03b8\u03b5\u03af.`,
|
|
||||||
hr: `Prijavili ste se.`,
|
|
||||||
da: `Du er logget p\u00e5.`,
|
|
||||||
de: `Sie sind jetzt angemeldet.`,
|
|
||||||
sh: `Prijavljeni ste.`,
|
|
||||||
pt: `Iniciou sess\u00e3o.`,
|
|
||||||
hu: `Bejelentkezett.`,
|
|
||||||
sr: `Prijavljeni ste.`,
|
|
||||||
en: enLoginSuccessHeader,
|
|
||||||
[this.defaultSuccessHeaderKey]: enLoginSuccessHeader
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private serverUrl: string,
|
private serverUrl: string,
|
||||||
@@ -172,10 +133,7 @@ export class AuthManager {
|
|||||||
|
|
||||||
let loginResponse = await this.sendLoginRequest(loginForm, loginParams)
|
let loginResponse = await this.sendLoginRequest(loginForm, loginParams)
|
||||||
|
|
||||||
let isLoggedIn = this.isLogInSuccessHeaderPresent(
|
let isLoggedIn = isLogInSuccessHeaderPresent(this.serverType, loginResponse)
|
||||||
this.serverType,
|
|
||||||
loginResponse
|
|
||||||
)
|
|
||||||
|
|
||||||
if (!isLoggedIn) {
|
if (!isLoggedIn) {
|
||||||
if (isCredentialsVerifyError(loginResponse)) {
|
if (isCredentialsVerifyError(loginResponse)) {
|
||||||
@@ -209,50 +167,6 @@ export class AuthManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if Login success header is present in the response based on language settings of the browser
|
|
||||||
* @param serverType - server type
|
|
||||||
* @param response - response object
|
|
||||||
* @returns - return boolean indicating if Login success header is present
|
|
||||||
*/
|
|
||||||
private isLogInSuccessHeaderPresent(
|
|
||||||
serverType: ServerType,
|
|
||||||
response: any
|
|
||||||
): boolean {
|
|
||||||
if (serverType === ServerType.Sasjs) return response?.loggedin
|
|
||||||
|
|
||||||
// get default success header
|
|
||||||
let successHeader = this.loginSuccessHeaders[this.defaultSuccessHeaderKey]
|
|
||||||
|
|
||||||
// get user language based on language settings of the browser
|
|
||||||
const userLang = getUserLanguage()
|
|
||||||
|
|
||||||
if (userLang) {
|
|
||||||
// get success header on exact match of the language code
|
|
||||||
let userLangSuccessHeader = this.loginSuccessHeaders[userLang]
|
|
||||||
|
|
||||||
// handle case when there is no exact match of the language code
|
|
||||||
if (!userLangSuccessHeader) {
|
|
||||||
// get all supported language codes
|
|
||||||
const headerLanguages = Object.keys(this.loginSuccessHeaders)
|
|
||||||
|
|
||||||
// find language code on partial match
|
|
||||||
const headerLanguage = headerLanguages.find((language) =>
|
|
||||||
new RegExp(language, 'i').test(userLang)
|
|
||||||
)
|
|
||||||
|
|
||||||
// reassign success header if partial match was found
|
|
||||||
if (headerLanguage) {
|
|
||||||
successHeader = this.loginSuccessHeaders[headerLanguage]
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
successHeader = userLangSuccessHeader
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new RegExp(successHeader, 'gm').test(response)
|
|
||||||
}
|
|
||||||
|
|
||||||
private async performCASSecurityCheck() {
|
private async performCASSecurityCheck() {
|
||||||
const casAuthenticationUrl = `${this.serverUrl}/SASStoredProcess/j_spring_cas_security_check`
|
const casAuthenticationUrl = `${this.serverUrl}/SASStoredProcess/j_spring_cas_security_check`
|
||||||
|
|
||||||
@@ -304,7 +218,7 @@ export class AuthManager {
|
|||||||
* - a boolean `isLoggedIn`
|
* - a boolean `isLoggedIn`
|
||||||
* - a string `userName`,
|
* - a string `userName`,
|
||||||
* - a string `userFullName` and
|
* - a string `userFullName` and
|
||||||
* - a form `loginForm` if not loggedin.
|
* - a form `loginForm` if not loggedIn.
|
||||||
*/
|
*/
|
||||||
public async checkSession(): Promise<LoginResultInternal> {
|
public async checkSession(): Promise<LoginResultInternal> {
|
||||||
const { isLoggedIn, userName, userLongName } = await this.fetchUserName()
|
const { isLoggedIn, userName, userLongName } = await this.fetchUserName()
|
||||||
@@ -471,5 +385,3 @@ const isCredentialsVerifyError = (response: string): boolean =>
|
|||||||
/An error occurred while the system was verifying your credentials. Please enter your credentials again./gm.test(
|
/An error occurred while the system was verifying your credentials. Please enter your credentials again./gm.test(
|
||||||
response
|
response
|
||||||
)
|
)
|
||||||
|
|
||||||
export const enLoginSuccessHeader = 'You have signed in.'
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
export * from './AuthManager'
|
export * from './AuthManager'
|
||||||
export * from './isAuthorizeFormRequired'
|
export * from './isAuthorizeFormRequired'
|
||||||
export * from './isLoginRequired'
|
export * from './isLoginRequired'
|
||||||
|
export * from './loginHeader'
|
||||||
|
|||||||
97
src/auth/loginHeader.ts
Normal file
97
src/auth/loginHeader.ts
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
import { ServerType } from '@sasjs/utils/types'
|
||||||
|
import { getUserLanguage } from '../utils'
|
||||||
|
|
||||||
|
const enLoginSuccessHeader = 'You have signed in.'
|
||||||
|
|
||||||
|
export const defaultSuccessHeaderKey = 'default'
|
||||||
|
|
||||||
|
// The following headers provided by https://github.com/sasjs/adapter/issues/835#issuecomment-2177818601
|
||||||
|
export const loginSuccessHeaders: { [key: string]: string } = {
|
||||||
|
es: `Ya se ha iniciado la sesi\u00f3n.`,
|
||||||
|
th: `\u0e04\u0e38\u0e13\u0e25\u0e07\u0e0a\u0e37\u0e48\u0e2d\u0e40\u0e02\u0e49\u0e32\u0e43\u0e0a\u0e49\u0e41\u0e25\u0e49\u0e27`,
|
||||||
|
ja: `\u30b5\u30a4\u30f3\u30a4\u30f3\u3057\u307e\u3057\u305f\u3002`,
|
||||||
|
nb: `Du har logget deg p\u00e5.`,
|
||||||
|
sl: `Prijavili ste se.`,
|
||||||
|
ar: `\u0644\u0642\u062f \u0642\u0645\u062a `,
|
||||||
|
sk: `Prihl\u00e1sili ste sa.`,
|
||||||
|
zh_HK: `\u60a8\u5df2\u767b\u5165\u3002`,
|
||||||
|
zh_CN: `\u60a8\u5df2\u767b\u5f55\u3002`,
|
||||||
|
it: `L'utente si \u00e8 connesso.`,
|
||||||
|
sv: `Du har loggat in.`,
|
||||||
|
he: `\u05e0\u05db\u05e0\u05e1\u05ea `,
|
||||||
|
nl: `U hebt zich aangemeld.`,
|
||||||
|
pl: `Zosta\u0142e\u015b zalogowany.`,
|
||||||
|
ko: `\ub85c\uadf8\uc778\ud588\uc2b5\ub2c8\ub2e4.`,
|
||||||
|
zh_TW: `\u60a8\u5df2\u767b\u5165\u3002`,
|
||||||
|
tr: `Oturum a\u00e7t\u0131n\u0131z.`,
|
||||||
|
iw: `\u05e0\u05db\u05e0\u05e1\u05ea `,
|
||||||
|
fr: `Vous \u00eates connect\u00e9.`,
|
||||||
|
uk: `\u0412\u0438 \u0432\u0432\u0456\u0439\u0448\u043b\u0438 \u0432 \u043e\u0431\u043b\u0456\u043a\u043e\u0432\u0438\u0439 \u0437\u0430\u043f\u0438\u0441.`,
|
||||||
|
pt_BR: `Voc\u00ea se conectou.`,
|
||||||
|
no: `Du har logget deg p\u00e5.`,
|
||||||
|
cs: `Jste p\u0159ihl\u00e1\u0161eni.`,
|
||||||
|
fi: `Olet kirjautunut sis\u00e4\u00e4n.`,
|
||||||
|
ru: `\u0412\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u043b\u0438 \u0432\u0445\u043e\u0434 \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0443.`,
|
||||||
|
el: `\u0388\u03c7\u03b5\u03c4\u03b5 \u03c3\u03c5\u03bd\u03b4\u03b5\u03b8\u03b5\u03af.`,
|
||||||
|
hr: `Prijavili ste se.`,
|
||||||
|
da: `Du er logget p\u00e5.`,
|
||||||
|
de: `Sie sind jetzt angemeldet.`,
|
||||||
|
sh: `Prijavljeni ste.`,
|
||||||
|
pt: `Iniciou sess\u00e3o.`,
|
||||||
|
hu: `Bejelentkezett.`,
|
||||||
|
sr: `Prijavljeni ste.`,
|
||||||
|
en: enLoginSuccessHeader,
|
||||||
|
[defaultSuccessHeaderKey]: enLoginSuccessHeader
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides expected login header based on language settings of the browser.
|
||||||
|
* @returns - expected header as a string.
|
||||||
|
*/
|
||||||
|
export const getExpectedLogInSuccessHeader = (): string => {
|
||||||
|
// get default success header
|
||||||
|
let successHeader = loginSuccessHeaders[defaultSuccessHeaderKey]
|
||||||
|
|
||||||
|
// get user language based on language settings of the browser
|
||||||
|
const userLang = getUserLanguage()
|
||||||
|
|
||||||
|
if (userLang) {
|
||||||
|
// get success header on exact match of the language code
|
||||||
|
let userLangSuccessHeader = loginSuccessHeaders[userLang]
|
||||||
|
|
||||||
|
// handle case when there is no exact match of the language code
|
||||||
|
if (!userLangSuccessHeader) {
|
||||||
|
// get all supported language codes
|
||||||
|
const headerLanguages = Object.keys(loginSuccessHeaders)
|
||||||
|
|
||||||
|
// find language code on partial match
|
||||||
|
const headerLanguage = headerLanguages.find((language) =>
|
||||||
|
new RegExp(language, 'i').test(userLang)
|
||||||
|
)
|
||||||
|
|
||||||
|
// reassign success header if partial match was found
|
||||||
|
if (headerLanguage) {
|
||||||
|
successHeader = loginSuccessHeaders[headerLanguage]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
successHeader = userLangSuccessHeader
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return successHeader
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if Login success header is present in the response based on language settings of the browser.
|
||||||
|
* @param serverType - server type.
|
||||||
|
* @param response - response object.
|
||||||
|
* @returns - boolean indicating if Login success header is present.
|
||||||
|
*/
|
||||||
|
export const isLogInSuccessHeaderPresent = (
|
||||||
|
serverType: ServerType,
|
||||||
|
response: any
|
||||||
|
): boolean => {
|
||||||
|
if (serverType === ServerType.Sasjs) return response?.loggedIn
|
||||||
|
|
||||||
|
return new RegExp(getExpectedLogInSuccessHeader(), 'gm').test(response)
|
||||||
|
}
|
||||||
@@ -8,14 +8,15 @@ import { ServerType } from '@sasjs/utils/types'
|
|||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import {
|
import {
|
||||||
mockedCurrentUserApi,
|
mockedCurrentUserApi,
|
||||||
mockLoginAuthoriseRequiredResponse,
|
mockLoginAuthoriseRequiredResponse
|
||||||
mockLoginSuccessResponse
|
|
||||||
} from './mockResponses'
|
} from './mockResponses'
|
||||||
import { serialize } from '../../utils'
|
import { serialize } from '../../utils'
|
||||||
import * as openWebPageModule from '../openWebPage'
|
import * as openWebPageModule from '../openWebPage'
|
||||||
import * as verifySasViyaLoginModule from '../verifySasViyaLogin'
|
import * as verifySasViyaLoginModule from '../verifySasViyaLogin'
|
||||||
import * as verifySas9LoginModule from '../verifySas9Login'
|
import * as verifySas9LoginModule from '../verifySas9Login'
|
||||||
import { RequestClient } from '../../request/RequestClient'
|
import { RequestClient } from '../../request/RequestClient'
|
||||||
|
import { getExpectedLogInSuccessHeader } from '../'
|
||||||
|
|
||||||
jest.mock('axios')
|
jest.mock('axios')
|
||||||
const mockedAxios = axios as jest.Mocked<typeof axios>
|
const mockedAxios = axios as jest.Mocked<typeof axios>
|
||||||
|
|
||||||
@@ -135,6 +136,7 @@ describe('AuthManager', () => {
|
|||||||
requestClient,
|
requestClient,
|
||||||
authCallback
|
authCallback
|
||||||
)
|
)
|
||||||
|
|
||||||
jest.spyOn(authManager, 'checkSession').mockImplementation(() =>
|
jest.spyOn(authManager, 'checkSession').mockImplementation(() =>
|
||||||
Promise.resolve({
|
Promise.resolve({
|
||||||
isLoggedIn: false,
|
isLoggedIn: false,
|
||||||
@@ -143,8 +145,9 @@ describe('AuthManager', () => {
|
|||||||
loginForm: { name: 'test' }
|
loginForm: { name: 'test' }
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
mockedAxios.post.mockImplementation(() =>
|
mockedAxios.post.mockImplementation(() =>
|
||||||
Promise.resolve({ data: mockLoginSuccessResponse })
|
Promise.resolve({ data: getExpectedLogInSuccessHeader() })
|
||||||
)
|
)
|
||||||
|
|
||||||
const loginResponse = await authManager.logIn(userName, password)
|
const loginResponse = await authManager.logIn(userName, password)
|
||||||
@@ -180,6 +183,7 @@ describe('AuthManager', () => {
|
|||||||
requestClient,
|
requestClient,
|
||||||
authCallback
|
authCallback
|
||||||
)
|
)
|
||||||
|
|
||||||
jest.spyOn(authManager, 'checkSession').mockImplementation(() =>
|
jest.spyOn(authManager, 'checkSession').mockImplementation(() =>
|
||||||
Promise.resolve({
|
Promise.resolve({
|
||||||
isLoggedIn: false,
|
isLoggedIn: false,
|
||||||
@@ -188,8 +192,9 @@ describe('AuthManager', () => {
|
|||||||
loginForm: { name: 'test' }
|
loginForm: { name: 'test' }
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
mockedAxios.post.mockImplementation(() =>
|
mockedAxios.post.mockImplementation(() =>
|
||||||
Promise.resolve({ data: mockLoginSuccessResponse })
|
Promise.resolve({ data: getExpectedLogInSuccessHeader() })
|
||||||
)
|
)
|
||||||
mockedAxios.get.mockImplementation(() => Promise.resolve({ status: 200 }))
|
mockedAxios.get.mockImplementation(() => Promise.resolve({ status: 200 }))
|
||||||
|
|
||||||
@@ -304,56 +309,6 @@ describe('AuthManager', () => {
|
|||||||
mockLoginAuthoriseRequiredResponse
|
mockLoginAuthoriseRequiredResponse
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should check login success header based on language preferences of the browser', () => {
|
|
||||||
const authManager = new AuthManager(
|
|
||||||
serverUrl,
|
|
||||||
serverType,
|
|
||||||
requestClient,
|
|
||||||
authCallback
|
|
||||||
)
|
|
||||||
|
|
||||||
// test built in language codes
|
|
||||||
Object.keys(authManager['successHeaders']).forEach((key) => {
|
|
||||||
languageGetter.mockReturnValue(key)
|
|
||||||
|
|
||||||
expect(
|
|
||||||
authManager['isLogInSuccessHeaderPresent'](
|
|
||||||
serverType,
|
|
||||||
authManager['successHeaders'][key]
|
|
||||||
)
|
|
||||||
).toBeTruthy()
|
|
||||||
})
|
|
||||||
|
|
||||||
// test possible longer language codes
|
|
||||||
const possibleLanguageCodes = [
|
|
||||||
{ short: 'en', long: 'en-US' },
|
|
||||||
{ short: 'fr', long: 'fr-FR' },
|
|
||||||
{ short: 'es', long: 'es-ES' }
|
|
||||||
]
|
|
||||||
|
|
||||||
possibleLanguageCodes.forEach((key) => {
|
|
||||||
const { short, long } = key
|
|
||||||
languageGetter.mockReturnValue(long)
|
|
||||||
|
|
||||||
expect(
|
|
||||||
authManager['isLogInSuccessHeaderPresent'](
|
|
||||||
serverType,
|
|
||||||
authManager['successHeaders'][short]
|
|
||||||
)
|
|
||||||
).toBeTruthy()
|
|
||||||
})
|
|
||||||
|
|
||||||
// test falling back to default language code
|
|
||||||
languageGetter.mockReturnValue('WRONG-LANGUAGE')
|
|
||||||
|
|
||||||
expect(
|
|
||||||
authManager['isLogInSuccessHeaderPresent'](
|
|
||||||
serverType,
|
|
||||||
authManager['successHeaders'][authManager['defaultSuccessHeaderKey']]
|
|
||||||
)
|
|
||||||
).toBeTruthy()
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('login - redirect mechanism', () => {
|
describe('login - redirect mechanism', () => {
|
||||||
|
|||||||
82
src/auth/spec/loginHeader.spec.ts
Normal file
82
src/auth/spec/loginHeader.spec.ts
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
/**
|
||||||
|
* @jest-environment jsdom
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { ServerType } from '@sasjs/utils/types'
|
||||||
|
import {
|
||||||
|
loginSuccessHeaders,
|
||||||
|
isLogInSuccessHeaderPresent,
|
||||||
|
defaultSuccessHeaderKey
|
||||||
|
} from '../'
|
||||||
|
|
||||||
|
describe('isLogInSuccessHeaderPresent', () => {
|
||||||
|
let languageGetter: any
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
languageGetter = jest.spyOn(window.navigator, 'language', 'get')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should check SASVIYA and SAS9 login success header based on language preferences of the browser', () => {
|
||||||
|
// test SASVIYA server type
|
||||||
|
Object.keys(loginSuccessHeaders).forEach((key) => {
|
||||||
|
languageGetter.mockReturnValue(key)
|
||||||
|
|
||||||
|
expect(
|
||||||
|
isLogInSuccessHeaderPresent(
|
||||||
|
ServerType.SasViya,
|
||||||
|
loginSuccessHeaders[key]
|
||||||
|
)
|
||||||
|
).toBeTruthy()
|
||||||
|
})
|
||||||
|
|
||||||
|
// test SAS9 server type
|
||||||
|
Object.keys(loginSuccessHeaders).forEach((key) => {
|
||||||
|
languageGetter.mockReturnValue(key)
|
||||||
|
|
||||||
|
expect(
|
||||||
|
isLogInSuccessHeaderPresent(ServerType.Sas9, loginSuccessHeaders[key])
|
||||||
|
).toBeTruthy()
|
||||||
|
})
|
||||||
|
|
||||||
|
// test possible longer language codes
|
||||||
|
const possibleLanguageCodes = [
|
||||||
|
{ short: 'en', long: 'en-US' },
|
||||||
|
{ short: 'fr', long: 'fr-FR' },
|
||||||
|
{ short: 'es', long: 'es-ES' }
|
||||||
|
]
|
||||||
|
|
||||||
|
possibleLanguageCodes.forEach((key) => {
|
||||||
|
const { short, long } = key
|
||||||
|
languageGetter.mockReturnValue(long)
|
||||||
|
|
||||||
|
expect(
|
||||||
|
isLogInSuccessHeaderPresent(
|
||||||
|
ServerType.SasViya,
|
||||||
|
loginSuccessHeaders[short]
|
||||||
|
)
|
||||||
|
).toBeTruthy()
|
||||||
|
})
|
||||||
|
|
||||||
|
// test falling back to default language code
|
||||||
|
languageGetter.mockReturnValue('WRONG-LANGUAGE')
|
||||||
|
|
||||||
|
expect(
|
||||||
|
isLogInSuccessHeaderPresent(
|
||||||
|
ServerType.Sas9,
|
||||||
|
loginSuccessHeaders[defaultSuccessHeaderKey]
|
||||||
|
)
|
||||||
|
).toBeTruthy()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should check SASVJS login success header', () => {
|
||||||
|
expect(
|
||||||
|
isLogInSuccessHeaderPresent(ServerType.Sasjs, { loggedIn: true })
|
||||||
|
).toBeTruthy()
|
||||||
|
|
||||||
|
expect(
|
||||||
|
isLogInSuccessHeaderPresent(ServerType.Sasjs, { loggedIn: false })
|
||||||
|
).toBeFalsy()
|
||||||
|
|
||||||
|
expect(isLogInSuccessHeaderPresent(ServerType.Sasjs, undefined)).toBeFalsy()
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
import { SasAuthResponse } from '@sasjs/utils/types'
|
import { SasAuthResponse } from '@sasjs/utils/types'
|
||||||
import { enLoginSuccessHeader } from '../AuthManager'
|
|
||||||
|
|
||||||
export const mockLoginAuthoriseRequiredResponse = `<form id="application_authorization" action="/SASLogon/oauth/authorize" method="POST"><input type="hidden" name="X-Uaa-Csrf" value="2nfuxIn6WaOURWL7tzTXCe"/>`
|
export const mockLoginAuthoriseRequiredResponse = `<form id="application_authorization" action="/SASLogon/oauth/authorize" method="POST"><input type="hidden" name="X-Uaa-Csrf" value="2nfuxIn6WaOURWL7tzTXCe"/>`
|
||||||
export const mockLoginSuccessResponse = enLoginSuccessHeader
|
|
||||||
|
|
||||||
export const mockAuthResponse: SasAuthResponse = {
|
export const mockAuthResponse: SasAuthResponse = {
|
||||||
access_token: 'acc355',
|
access_token: 'acc355',
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
import { verifySas9Login } from '../verifySas9Login'
|
import { verifySas9Login } from '../verifySas9Login'
|
||||||
import * as delayModule from '../../utils/delay'
|
import * as delayModule from '../../utils/delay'
|
||||||
import { enLoginSuccessHeader } from '../AuthManager'
|
import { getExpectedLogInSuccessHeader } from '../'
|
||||||
|
|
||||||
describe('verifySas9Login', () => {
|
describe('verifySas9Login', () => {
|
||||||
const serverUrl = 'http://test-server.com'
|
const serverUrl = 'http://test-server.com'
|
||||||
@@ -19,7 +19,9 @@ describe('verifySas9Login', () => {
|
|||||||
const popup = {
|
const popup = {
|
||||||
window: {
|
window: {
|
||||||
location: { href: serverUrl + `/SASLogon` },
|
location: { href: serverUrl + `/SASLogon` },
|
||||||
document: { body: { innerText: `<h3>${enLoginSuccessHeader}</h3>` } }
|
document: {
|
||||||
|
body: { innerText: `<h3>${getExpectedLogInSuccessHeader()}</h3>` }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} as unknown as Window
|
} as unknown as Window
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
import { verifySasViyaLogin } from '../verifySasViyaLogin'
|
import { verifySasViyaLogin } from '../verifySasViyaLogin'
|
||||||
import * as delayModule from '../../utils/delay'
|
import * as delayModule from '../../utils/delay'
|
||||||
import { enLoginSuccessHeader } from '../AuthManager'
|
import { getExpectedLogInSuccessHeader } from '../'
|
||||||
|
|
||||||
describe('verifySasViyaLogin', () => {
|
describe('verifySasViyaLogin', () => {
|
||||||
const serverUrl = 'http://test-server.com'
|
const serverUrl = 'http://test-server.com'
|
||||||
@@ -20,7 +20,9 @@ describe('verifySasViyaLogin', () => {
|
|||||||
const popup = {
|
const popup = {
|
||||||
window: {
|
window: {
|
||||||
location: { href: serverUrl + `/SASLogon` },
|
location: { href: serverUrl + `/SASLogon` },
|
||||||
document: { body: { innerText: `<h3>${enLoginSuccessHeader}</h3>` } }
|
document: {
|
||||||
|
body: { innerText: `<h3>${getExpectedLogInSuccessHeader()}</h3>` }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} as unknown as Window
|
} as unknown as Window
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { delay } from '../utils'
|
import { delay } from '../utils'
|
||||||
import { enLoginSuccessHeader } from './AuthManager'
|
import { getExpectedLogInSuccessHeader } from './'
|
||||||
|
|
||||||
export async function verifySas9Login(loginPopup: Window): Promise<{
|
export async function verifySas9Login(loginPopup: Window): Promise<{
|
||||||
isLoggedIn: boolean
|
isLoggedIn: boolean
|
||||||
@@ -7,13 +7,17 @@ export async function verifySas9Login(loginPopup: Window): Promise<{
|
|||||||
let isLoggedIn = false
|
let isLoggedIn = false
|
||||||
let startTime = new Date()
|
let startTime = new Date()
|
||||||
let elapsedSeconds = 0
|
let elapsedSeconds = 0
|
||||||
|
|
||||||
do {
|
do {
|
||||||
await delay(1000)
|
await delay(1000)
|
||||||
if (loginPopup.closed) break
|
if (loginPopup.closed) break
|
||||||
|
|
||||||
isLoggedIn =
|
isLoggedIn =
|
||||||
loginPopup.window.location.href.includes('SASLogon') &&
|
loginPopup.window.location.href.includes('SASLogon') &&
|
||||||
loginPopup.window.document.body.innerText.includes(enLoginSuccessHeader)
|
loginPopup.window.document.body.innerText.includes(
|
||||||
|
getExpectedLogInSuccessHeader()
|
||||||
|
)
|
||||||
|
|
||||||
elapsedSeconds = (new Date().valueOf() - startTime.valueOf()) / 1000
|
elapsedSeconds = (new Date().valueOf() - startTime.valueOf()) / 1000
|
||||||
} while (!isLoggedIn && elapsedSeconds < 5 * 60)
|
} while (!isLoggedIn && elapsedSeconds < 5 * 60)
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { delay } from '../utils'
|
import { delay } from '../utils'
|
||||||
import { enLoginSuccessHeader } from './AuthManager'
|
import { getExpectedLogInSuccessHeader } from './'
|
||||||
|
|
||||||
export async function verifySasViyaLogin(loginPopup: Window): Promise<{
|
export async function verifySasViyaLogin(loginPopup: Window): Promise<{
|
||||||
isLoggedIn: boolean
|
isLoggedIn: boolean
|
||||||
@@ -7,21 +7,32 @@ export async function verifySasViyaLogin(loginPopup: Window): Promise<{
|
|||||||
let isLoggedIn = false
|
let isLoggedIn = false
|
||||||
let startTime = new Date()
|
let startTime = new Date()
|
||||||
let elapsedSeconds = 0
|
let elapsedSeconds = 0
|
||||||
|
|
||||||
do {
|
do {
|
||||||
await delay(1000)
|
await delay(1000)
|
||||||
|
|
||||||
if (loginPopup.closed) break
|
if (loginPopup.closed) break
|
||||||
|
|
||||||
isLoggedIn = isLoggedInSASVIYA()
|
isLoggedIn = isLoggedInSASVIYA()
|
||||||
|
|
||||||
elapsedSeconds = (new Date().valueOf() - startTime.valueOf()) / 1000
|
elapsedSeconds = (new Date().valueOf() - startTime.valueOf()) / 1000
|
||||||
} while (!isLoggedIn && elapsedSeconds < 5 * 60)
|
} while (!isLoggedIn && elapsedSeconds < 5 * 60)
|
||||||
|
|
||||||
let isAuthorized = false
|
let isAuthorized = false
|
||||||
|
|
||||||
startTime = new Date()
|
startTime = new Date()
|
||||||
|
|
||||||
do {
|
do {
|
||||||
await delay(1000)
|
await delay(1000)
|
||||||
|
|
||||||
if (loginPopup.closed) break
|
if (loginPopup.closed) break
|
||||||
|
|
||||||
isAuthorized =
|
isAuthorized =
|
||||||
loginPopup.window.location.href.includes('SASLogon') ||
|
loginPopup.window.location.href.includes('SASLogon') ||
|
||||||
loginPopup.window.document.body?.innerText?.includes(enLoginSuccessHeader)
|
loginPopup.window.document.body?.innerText?.includes(
|
||||||
|
getExpectedLogInSuccessHeader()
|
||||||
|
)
|
||||||
|
|
||||||
elapsedSeconds = (new Date().valueOf() - startTime.valueOf()) / 1000
|
elapsedSeconds = (new Date().valueOf() - startTime.valueOf()) / 1000
|
||||||
} while (!isAuthorized && elapsedSeconds < 5 * 60)
|
} while (!isAuthorized && elapsedSeconds < 5 * 60)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user