blob: b49f23940cd8c05fddc0cd6793ddebce9b91a229 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import React, { useState, useCallback, useRef, useEffect } from "react";
import { useSearchParams, useNavigate } from "react-router-dom";
import { Badge, Row, Col } from "react-bootstrap";
import XATableLayout from "Components/XATableLayout";
import { fetchApi } from "Utils/fetchAPI";
import { AuthStatus, AuthType } from "../../utils/XAEnums";
import AdminModal from "./AdminModal";
import dateFormat from "dateformat";
import { AuditFilterEntries } from "Components/CommonComponents";
import moment from "moment-timezone";
import { sortBy } from "lodash";
import StructuredFilter from "../../components/structured-filter/react-typeahead/tokenizer";
import {
getTableSortBy,
getTableSortType,
fetchSearchFilterParams,
parseSearchFilter,
serverError
} from "../../utils/XAUtils";
import { Loader } from "../../components/CommonComponents";
function LoginSessions() {
const [loginSessionListingData, setLoginSessionLogs] = useState([]);
const [loader, setLoader] = useState(true);
const [sessionId, setSessionId] = useState([]);
const [showmodal, setShowModal] = useState(false);
const [pageCount, setPageCount] = React.useState(0);
const [entries, setEntries] = useState([]);
const [updateTable, setUpdateTable] = useState(moment.now());
const fetchIdRef = useRef(0);
const [contentLoader, setContentLoader] = useState(true);
const [searchFilterParams, setSearchFilterParams] = useState([]);
const [searchParams, setSearchParams] = useSearchParams();
const [defaultSearchFilterParams, setDefaultSearchFilterParams] = useState(
[]
);
const [resetPage, setResetpage] = useState({ page: null });
const handleClose = () => setShowModal(false);
const navigate = useNavigate();
const updateSessionId = (id) => {
navigate(`/reports/audit/admin?sessionId=${id}`);
};
useEffect(() => {
let { searchFilterParam, defaultSearchFilterParam, searchParam } =
fetchSearchFilterParams(
"loginSession",
searchParams,
searchFilterOptions
);
// Updating the states for search params, search filter, default search filter and localStorage
setSearchParams(searchParam, { replace: true });
if (
JSON.stringify(searchFilterParams) !== JSON.stringify(searchFilterParam)
) {
setSearchFilterParams(searchFilterParam);
}
setDefaultSearchFilterParams(defaultSearchFilterParam);
localStorage.setItem("loginSession", JSON.stringify(searchParam));
setContentLoader(false);
}, [searchParams]);
const fetchLoginSessionLogsInfo = useCallback(
async ({ pageSize, pageIndex, sortBy, gotoPage }) => {
setLoader(true);
let logsResp = [];
let logs = [];
let totalCount = 0;
const fetchId = ++fetchIdRef.current;
let params = { ...searchFilterParams };
if (fetchId === fetchIdRef.current) {
params["pageSize"] = pageSize;
params["startIndex"] = pageIndex * pageSize;
if (sortBy.length > 0) {
params["sortBy"] = getTableSortBy(sortBy);
params["sortType"] = getTableSortType(sortBy);
}
try {
logsResp = await fetchApi({
url: "xusers/authSessions",
params: params,
skipNavigate: true
});
logs = logsResp.data.vXAuthSessions;
totalCount = logsResp.data.totalCount;
} catch (error) {
serverError(error);
console.error(
`Error occurred while fetching Login Session logs! ${error}`
);
}
setLoginSessionLogs(logs);
setEntries(logsResp.data);
setPageCount(Math.ceil(totalCount / pageSize));
setResetpage({ page: gotoPage });
setLoader(false);
}
},
[updateTable, searchFilterParams]
);
const getDefaultSort = React.useMemo(
() => [
{
id: "id",
desc: true
}
],
[]
);
const refreshTable = () => {
setLoginSessionLogs([]);
setLoader(true);
setUpdateTable(moment.now());
};
const openModal = (id) => {
setShowModal(true);
setSessionId(id);
};
const columns = React.useMemo(
() => [
{
Header: "Session ID",
accessor: "id",
Cell: (rawValue) => {
var id = rawValue.value;
if (id != undefined) {
return (
<span className="text-center d-block">
<a
role="button"
className="text-primary"
onClick={() => {
openModal(id);
}}
data-id={id}
data-cy={id}
title={id}
>
{id}
</a>
</span>
);
} else {
return <span className="text-center d-block">--</span>;
}
},
width: 90
},
{
Header: "Login ID",
accessor: "loginId",
Cell: (rawValue) => {
if (rawValue.value) {
return (
<span className="text-center d-block">{rawValue.value}</span>
);
} else {
return <span className="text-center d-block">--</span>;
}
},
width: 100,
disableSortBy: true
},
{
Header: "Result",
accessor: "authStatus",
Cell: (rawValue) => {
var label = "";
var html = "";
Object.keys(AuthStatus).map((item) => {
if (rawValue.value == AuthStatus[item].value) {
label = AuthStatus[item].label;
if (AuthStatus[item].value == 1) {
html = (
<span className="text-center d-block">
<Badge variant="success">{label}</Badge>
</span>
);
} else if (AuthStatus[item].value == 2) {
html = (
<span className="text-center d-block">
<Badge variant="danger">{label}</Badge>
</span>
);
} else {
html = (
<span className="text-center d-block">
<Badge variant="secondary">{label}</Badge>
</span>
);
}
}
});
return html;
},
width: 100,
disableSortBy: true
},
{
Header: "Login Type",
accessor: "authType",
Cell: (rawValue) => {
var label = "";
Object.keys(AuthType).map((item) => {
if (rawValue.value == AuthType[item].value) {
label = AuthType[item].label;
}
});
return <span className="text-center d-block">{label}</span>;
},
disableSortBy: true
},
{
Header: "IP",
accessor: "requestIP",
Cell: (rawValue) => {
if (rawValue.value) {
return (
<span
className="text-truncate text-center d-block"
title={rawValue.value}
>
{rawValue.value}
</span>
);
} else {
return <span className="text-center d-block">--</span>;
}
},
disableSortBy: true
},
{
Header: "User Agent",
accessor: "requestUserAgent",
Cell: (rawValue) => {
if (rawValue.value) {
return (
<div className="text-truncate" title={rawValue.value}>
{rawValue.value}
</div>
);
} else {
return <div className="text-center">--</div>;
}
},
disableSortBy: true
},
{
Header: "Login Time ( India Standard Time )",
accessor: "authTime",
Cell: (rawValue) => {
let formatDateTime = dateFormat(
rawValue.value,
"mm/dd/yyyy hh:MM:ss TT"
);
return <span className="text-center d-block">{formatDateTime}</span>;
},
width: 180,
disableSortBy: true
}
],
[]
);
const updateSearchFilter = (filter) => {
let { searchFilterParam, searchParam } = parseSearchFilter(
filter,
searchFilterOptions
);
setSearchFilterParams(searchFilterParam);
setSearchParams(searchParam, { replace: true });
localStorage.setItem("loginSession", JSON.stringify(searchParam));
if (typeof resetPage?.page === "function") {
resetPage.page(0);
}
};
const searchFilterOptions = [
{
category: "endDate",
label: "End Date",
urlLabel: "endDate",
type: "date"
},
{
category: "requestIP",
label: "IP",
urlLabel: "requestIP",
type: "text"
},
{
category: "loginId",
label: "Login ID ",
urlLabel: "loginID",
type: "text"
},
{
category: "authType",
label: "Login Type",
urlLabel: "loginType",
type: "textoptions",
options: () => {
return [
{ value: "1", label: "Username/Password" },
{ value: "2", label: "Kerberos" },
{ value: "3", label: "SingleSignOn" },
{ value: "4", label: "Trusted Proxy" }
];
}
},
{
category: "authStatus",
label: "Result",
urlLabel: "result",
type: "textoptions",
options: () => {
return [
{ value: "1", label: "Success" },
{ value: "2", label: "Wrong Password" },
{ value: "3", label: "Account Disabled" },
{ value: "4", label: "Locked" },
{ value: "5", label: "Password Expired" },
{ value: "6", label: "User not found" }
];
}
},
{
category: "id",
label: "Session ID",
urlLabel: "sessionID",
type: "text"
},
{
category: "startDate",
label: "Start Date",
urlLabel: "startDate",
type: "date"
},
{
category: "requestUserAgent",
label: "User Agent",
urlLabel: "userAgent",
type: "text"
}
];
return contentLoader ? (
<Loader />
) : (
<div className="wrap">
<React.Fragment>
<Row className="mb-2">
<Col sm={12}>
<div className="searchbox-border">
<StructuredFilter
key="login-session-search-filter"
placeholder="Search for your login sessions..."
options={sortBy(searchFilterOptions, ["label"])}
onChange={updateSearchFilter}
defaultSelected={defaultSearchFilterParams}
/>
</div>
</Col>
</Row>
<AuditFilterEntries entries={entries} refreshTable={refreshTable} />
<XATableLayout
data={loginSessionListingData}
columns={columns}
fetchData={fetchLoginSessionLogsInfo}
totalCount={entries && entries.totalCount}
loading={loader}
pageCount={pageCount}
columnSort={true}
defaultSort={getDefaultSort}
/>
<AdminModal
show={showmodal}
data={sessionId}
onHide={handleClose}
updateSessionId={updateSessionId}
></AdminModal>
</React.Fragment>
</div>
);
}
export default LoginSessions;