import { SessionManagerInterface } from '../session-manager/session-manager.interface'; import { SessionUsersInterface } from './session-users.interface'; import { SessionPassportInterface } from '../session-manager/interfaces/session-passport.interface'; import { MiddlewareInterface } from '../../interfaces/middleware.interface'; import { SessionPassportUserInterface } from './interfaces/session-passport-user.interface'; import { GetUsersByFilterInterface } from './interfaces/get-users-by-filter.interface'; import { UserIsMatchInterface } from './interfaces/user-is-match.interface'; import { GetByIdInterface } from '../../interfaces/get-by-id.interface'; import { GetByUsernameInterface } from './interfaces/get-by-username.interface'; import { AddUserInterface } from './interfaces/add-user.interface'; import { UpdateTokensByUserIdInterface } from './interfaces/update-tokens-by-user-id.interface'; import { SessionUsersResponseInterface } from './interfaces/session-users-response.interface'; import { SessionUserInterface } from './interfaces/session-user.interface'; import { convertUserForFrontend } from '../../utils/convert-user-for-frontend'; export class SessionUsers implements SessionUsersInterface { sessionManager: SessionManagerInterface; constructor(sessionManager: SessionManagerInterface) { this.sessionManager = sessionManager; } updateTokensByUserId(params: UpdateTokensByUserIdInterface): void { const user: SessionPassportUserInterface = this.getUserById(params); if (!user) { return; } user.idToken = params.idToken; user.idTokenDecoded = params.idTokenDecoded; user.accessToken = params.accessToken; user.accessTokenDecoded = params.accessTokenDecoded; user.username = params.idTokenDecoded.cognitoUsername; user.phone = params.idTokenDecoded.phoneNumber; user.email = params.idTokenDecoded.email; this.upsertUser({ ...params, user }); } upsertUser(params: AddUserInterface): SessionPassportUserInterface[] { const passport: SessionPassportInterface = this.sessionManager.getSessionPassport(params); if (!passport.users) { passport.users = []; } const user: SessionPassportUserInterface = this.getUserById({ ...params, id: params.user.id, }); if (user) { const index: number = passport.users.findIndex( (user) => user.id === params.user.id, ); passport.users[index] = { ...params.user }; } else { passport.users.push(params.user); } const updateActiveUser: boolean = passport?.activeUser?.id === user.id; if (updateActiveUser) { passport.activeUser = user; } const users: SessionPassportUserInterface[] = this.getUsersByFilter(params); return users; } getSessionUsers(params: MiddlewareInterface): SessionUsersResponseInterface { const rawUsers: SessionPassportUserInterface[] = this.getUsersByFilter(params); const users: SessionUserInterface[] = rawUsers.map((user) => { return convertUserForFrontend(user); }); const rawActiveUser: SessionPassportUserInterface = this.getActiveUser(params); const activeUser: SessionUserInterface = convertUserForFrontend(rawActiveUser); return { users, activeUser }; } getActiveUser(params: MiddlewareInterface): SessionPassportUserInterface { const passport: SessionPassportInterface = this.sessionManager.getSessionPassport(params); const activeUser: SessionPassportUserInterface = passport?.activeUser; return activeUser; } setActiveUserById(params: GetByIdInterface): SessionPassportUserInterface { const passport: SessionPassportInterface = this.sessionManager.getSessionPassport(params); const user: SessionPassportUserInterface = this.getUserById(params); if (!user) { throw new Error( `Failed to set active user. User with this id: ${params.id} was not found.`, ); } passport.activeUser = { ...user }; return passport.activeUser; } deleteUserById(params: GetByIdInterface): void { const passport: SessionPassportInterface = this.sessionManager.getSessionPassport(params); const index: number = passport.users.findIndex( (user) => user.id === params.id, ); if (index < 0) { throw new Error( `Failed sign out user. User with this id: ${params.id} was not found.`, ); } passport.users.splice(index, 1); const deleteActiveUser: boolean = params.id === passport?.activeUser?.id; if (deleteActiveUser) { delete passport.activeUser; if (passport.users.length) { passport.activeUser = passport.users[0]; } } } getUserById(params: GetByIdInterface): SessionPassportUserInterface { const users: SessionPassportUserInterface[] = this.getUsersByFilter(params); const user: SessionPassportUserInterface = users?.length && users[0]; return user; } getUserByUsername( params: GetByUsernameInterface, ): SessionPassportUserInterface { const users: SessionPassportUserInterface[] = this.getUsersByFilter({ ...params, username: params.username.toLowerCase(), }); const user: SessionPassportUserInterface = users?.length && users[0]; return user; } getUsersByFilter( params: GetUsersByFilterInterface, ): SessionPassportUserInterface[] { const passport: SessionPassportInterface = this.sessionManager.getSessionPassport(params); let users: SessionPassportUserInterface[] = passport?.users; const noUsers = !users?.length; if (noUsers) { return []; } users = users.filter((user) => { const isMatch: boolean = this.conditionsIsMatch({ filter: params, user }); return isMatch; }); return users; } private conditionsIsMatch(params: UserIsMatchInterface): boolean { const correctFilters: string[] = ['id', 'username', 'email', 'phone']; const filterNames: string[] = Object.keys(params.filter); for (const filterName of filterNames) { if (!correctFilters.includes(filterName)) { continue; } const conditionIsMatch: boolean = this.conditionIsMatch({ ...params, filterName, }); if (!conditionIsMatch) { return false; } } return true; } private conditionIsMatch(params: UserIsMatchInterface): boolean { const value = params.filter[params.filterName]; if (value === undefined) { return true; } const userValue = params.user[params.filterName]; const conditionIsMatch: boolean = value === userValue; return conditionIsMatch; } }