1
0
mirror of https://github.com/sasjs/adapter.git synced 2025-12-11 01:14:36 +00:00

fix(auth): login and check session returns username + user full name

This commit is contained in:
Saad Jutt
2022-09-25 01:11:22 +05:00
parent 2cbba38af5
commit a1c09ec802
4 changed files with 79 additions and 58 deletions

View File

@@ -1,14 +1,15 @@
import { ServerType } from '@sasjs/utils/types' import { ServerType } from '@sasjs/utils/types'
import { RequestClient } from '../request/RequestClient' import { RequestClient } from '../request/RequestClient'
import { LoginOptions, LoginResult } from '../types/Login' import { LoginOptions, LoginResult, LoginResultInternal } from '../types/Login'
import { serialize } from '../utils' import { serialize } from '../utils'
import { extractUserNameSas9 } from '../utils/sas9/extractUserNameSas9' 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'
export class AuthManager { export class AuthManager {
public userName = '' public userName = ''
public userLongName = ''
private loginUrl: string private loginUrl: string
private logoutUrl: string private logoutUrl: string
private redirectedLoginUrl = `/SASLogon/home` private redirectedLoginUrl = `/SASLogon/home`
@@ -34,15 +35,19 @@ export class AuthManager {
public async redirectedLogIn({ public async redirectedLogIn({
onLoggedOut onLoggedOut
}: LoginOptions): Promise<LoginResult> { }: LoginOptions): Promise<LoginResult> {
const { isLoggedIn: isLoggedInAlready, userName: currentSessionUsername } = const {
await this.fetchUserName() isLoggedIn: isLoggedInAlready,
userName: currentSessionUserName,
userLongName: currentSessionUserLongName
} = await this.fetchUserName()
if (isLoggedInAlready) { if (isLoggedInAlready) {
await this.loginCallback() await this.loginCallback()
return { return {
isLoggedIn: true, isLoggedIn: true,
userName: currentSessionUsername userName: currentSessionUserName,
userLongName: currentSessionUserLongName
} }
} }
@@ -57,7 +62,7 @@ export class AuthManager {
) )
if (!loginPopup) { if (!loginPopup) {
return { isLoggedIn: false, userName: '' } return { isLoggedIn: false, userName: '', userLongName: '' }
} }
const { isLoggedIn } = const { isLoggedIn } =
@@ -72,14 +77,14 @@ export class AuthManager {
await this.performCASSecurityCheck() await this.performCASSecurityCheck()
} }
const { userName } = await this.fetchUserName() const { userName, userLongName } = await this.fetchUserName()
await this.loginCallback() await this.loginCallback()
return { isLoggedIn: true, userName } return { isLoggedIn: true, userName, userLongName }
} }
return { isLoggedIn: false, userName: '' } return { isLoggedIn: false, userName: '', userLongName: '' }
} }
/** /**
@@ -94,27 +99,26 @@ export class AuthManager {
username, username,
password password
} }
this.userName = ''
this.userLongName = ''
let { let {
isLoggedIn: isLoggedInAlready, isLoggedIn: isLoggedInAlready,
loginForm, loginForm,
userName: currentSessionUsername userLongName: currentSessionUserLongName
} = await this.checkSession() } = await this.checkSession()
if (isLoggedInAlready) { if (isLoggedInAlready) {
if (currentSessionUsername === loginParams.username) { await this.loginCallback()
await this.loginCallback()
this.userName = currentSessionUsername! this.userName = loginParams.username
return { this.userLongName = currentSessionUserLongName
isLoggedIn: true, return {
userName: this.userName isLoggedIn: true,
} userName: this.userName,
} else { userLongName: this.userLongName
await this.logOut()
loginForm = await this.getNewLoginForm()
} }
} else this.userName = '' }
let loginResponse = await this.sendLoginRequest(loginForm, loginParams) let loginResponse = await this.sendLoginRequest(loginForm, loginParams)
@@ -129,10 +133,7 @@ export class AuthManager {
const res = await this.checkSession() const res = await this.checkSession()
isLoggedIn = res.isLoggedIn isLoggedIn = res.isLoggedIn
this.userLongName = res.userLongName
if (isLoggedIn) this.userName = res.userName
} else {
this.userName = loginParams.username
} }
if (isLoggedIn) { if (isLoggedIn) {
@@ -141,11 +142,13 @@ export class AuthManager {
} }
this.loginCallback() this.loginCallback()
} else this.userName = '' this.userName = loginParams.username
}
return { return {
isLoggedIn, isLoggedIn,
userName: this.userName userName: this.userName,
userLongName: this.userLongName
} }
} }
@@ -196,15 +199,12 @@ export class AuthManager {
* Checks whether a session is active, or login is required. * Checks whether a session is active, or login is required.
* @returns - a promise which resolves with an object containing three values * @returns - a promise which resolves with an object containing three values
* - a boolean `isLoggedIn` * - a boolean `isLoggedIn`
* - a string `userName` and * - a string `userName`,
* - a string `userFullName` and
* - a form `loginForm` if not loggedin. * - a form `loginForm` if not loggedin.
*/ */
public async checkSession(): Promise<{ public async checkSession(): Promise<LoginResultInternal> {
isLoggedIn: boolean const { isLoggedIn, userName, userLongName } = await this.fetchUserName()
userName: string
loginForm?: any
}> {
const { isLoggedIn, userName } = await this.fetchUserName()
let loginForm = null let loginForm = null
if (!isLoggedIn) { if (!isLoggedIn) {
@@ -217,7 +217,8 @@ export class AuthManager {
return Promise.resolve({ return Promise.resolve({
isLoggedIn, isLoggedIn,
userName: userName.toLowerCase(), userName,
userLongName,
loginForm loginForm
}) })
} }
@@ -246,10 +247,7 @@ export class AuthManager {
return await this.getLoginForm(formResponse) return await this.getLoginForm(formResponse)
} }
private async fetchUserName(): Promise<{ private async fetchUserName(): Promise<LoginResult> {
isLoggedIn: boolean
userName: string
}> {
const url = const url =
this.serverType === ServerType.SasViya this.serverType === ServerType.SasViya
? `${this.serverUrl}/identities/users/@currentUser` ? `${this.serverUrl}/identities/users/@currentUser`
@@ -264,15 +262,19 @@ export class AuthManager {
}) })
const isLoggedIn = loginResponse !== 'authErr' const isLoggedIn = loginResponse !== 'authErr'
const userName = isLoggedIn ? this.extractUserName(loginResponse) : ''
if (!isLoggedIn) { if (!isLoggedIn) {
//We will logout to make sure cookies are removed and login form is presented //We will logout to make sure cookies are removed and login form is presented
//Residue can happen in case of session expiration //Residue can happen in case of session expiration
await this.logOut() await this.logOut()
return { isLoggedIn, userName: '', userLongName: '' }
} }
return { isLoggedIn, userName } return {
isLoggedIn,
userName: this.extractUserName(loginResponse),
userLongName: this.extractUserLongName(loginResponse)
}
} }
private extractUserName = (response: any): string => { private extractUserName = (response: any): string => {
@@ -281,7 +283,7 @@ export class AuthManager {
return response?.id return response?.id
case ServerType.Sas9: case ServerType.Sas9:
return extractUserNameSas9(response) return ''
case ServerType.Sasjs: case ServerType.Sasjs:
return response?.username return response?.username
@@ -292,6 +294,23 @@ export class AuthManager {
} }
} }
private extractUserLongName = (response: any): string => {
switch (this.serverType) {
case ServerType.SasViya:
return response?.name
case ServerType.Sas9:
return extractUserLongNameSas9(response)
case ServerType.Sasjs:
return response?.displayName
default:
console.error('Server Type not found in extractUserName function')
return ''
}
}
private getLoginForm(response: any) { private getLoginForm(response: any) {
const pattern: RegExp = /<form.+action="(.*Logon[^"]*).*>/ const pattern: RegExp = /<form.+action="(.*Logon[^"]*).*>/
const matches = pattern.exec(response) const matches = pattern.exec(response)

View File

@@ -20,6 +20,7 @@ describe('AuthManager', () => {
const serverUrl = 'http://test-server.com' const serverUrl = 'http://test-server.com'
const serverType = ServerType.SasViya const serverType = ServerType.SasViya
const userName = 'test-username' const userName = 'test-username'
const userLongName = 'test-user long name'
const password = 'test-password' const password = 'test-password'
const requestClient = new RequestClient(serverUrl) const requestClient = new RequestClient(serverUrl)
@@ -73,6 +74,7 @@ describe('AuthManager', () => {
Promise.resolve({ Promise.resolve({
isLoggedIn: true, isLoggedIn: true,
userName, userName,
userLongName,
loginForm: 'test' loginForm: 'test'
}) })
) )
@@ -95,6 +97,7 @@ describe('AuthManager', () => {
Promise.resolve({ Promise.resolve({
isLoggedIn: true, isLoggedIn: true,
userName: 'someOtherUsername', userName: 'someOtherUsername',
userLongName: 'someOtherUser Long name',
loginForm: null loginForm: null
}) })
) )
@@ -152,6 +155,7 @@ describe('AuthManager', () => {
Promise.resolve({ Promise.resolve({
isLoggedIn: false, isLoggedIn: false,
userName: '', userName: '',
userLongName: '',
loginForm: { name: 'test' } loginForm: { name: 'test' }
}) })
) )
@@ -196,6 +200,7 @@ describe('AuthManager', () => {
Promise.resolve({ Promise.resolve({
isLoggedIn: false, isLoggedIn: false,
userName: '', userName: '',
userLongName: '',
loginForm: { name: 'test' } loginForm: { name: 'test' }
}) })
) )
@@ -245,6 +250,7 @@ describe('AuthManager', () => {
Promise.resolve({ Promise.resolve({
isLoggedIn: false, isLoggedIn: false,
userName: '', userName: '',
userLongName: '',
loginForm: { name: 'test' } loginForm: { name: 'test' }
}) })
) )
@@ -290,6 +296,7 @@ describe('AuthManager', () => {
Promise.resolve({ Promise.resolve({
isLoggedIn: false, isLoggedIn: false,
userName: 'test', userName: 'test',
userLongName: 'test Long name',
loginForm: { name: 'test' } loginForm: { name: 'test' }
}) })
) )

View File

@@ -5,4 +5,11 @@ export interface LoginOptions {
export interface LoginResult { export interface LoginResult {
isLoggedIn: boolean isLoggedIn: boolean
userName: string userName: string
userLongName: string
}
export interface LoginResultInternal {
isLoggedIn: boolean
userName: string
userLongName: string
loginForm?: any
} }

View File

@@ -5,11 +5,11 @@
const dictionary = ['Log Off'] const dictionary = ['Log Off']
/** /**
* Extracts username assuming the first word after "title" means log off if not found otherwise in the dictionary * Extracts user full name assuming the first word after "title" means log off if not found otherwise in the dictionary
* @param response SAS response content * @param response SAS response content
* @returns username * @returns user full name
*/ */
export const extractUserNameSas9 = (response: string) => { export const extractUserLongNameSas9 = (response: string) => {
const regex = /"title":\s?".*?"/ const regex = /"title":\s?".*?"/
const matched = response?.match(regex) const matched = response?.match(regex)
@@ -27,17 +27,5 @@ export const extractUserNameSas9 = (response: string) => {
}) })
//Cut only name //Cut only name
let username = fullName.slice(breakIndex, -1).trim() return fullName.slice(breakIndex, -1).trim()
//Create username by SAS method - first 3 chars of every word lowercase
const usernameSplit = username.split(' ')
username = usernameSplit
.map((name: string) =>
usernameSplit.length > 1
? name.slice(0, 3).toLowerCase()
: name.toLowerCase()
)
.join('')
return username
} }