LCOV - code coverage report
Current view: top level - pkg/users - account-logs-panel.jsx Coverage Total Hit
Test: cockpit Lines: 98.0 % 51 50
Test Date: 2026-06-16 14:09:37

            Line data    Source code
       1              : /*
       2              :  * Copyright (C) 2021 Red Hat, Inc.
       3              :  * SPDX-License-Identifier: LGPL-2.1-or-later
       4              :  */
       5              : 
       6           15 : import cockpit from 'cockpit';
       7           15 : import React, { useState } from 'react';
       8              : 
       9              : import { Card, CardBody, CardTitle } from "@patternfly/react-core/dist/esm/components/Card/index.js";
      10              : import { ListingTable } from 'cockpit-components-table.jsx';
      11              : 
      12              : import * as timeformat from "timeformat";
      13              : import { useInit } from "hooks";
      14              : 
      15           15 : const _ = cockpit.gettext;
      16              : 
      17           10 : export function AccountLogs({ name }) {
      18           10 :     const [logins, setLogins] = useState([]);
      19           10 :     useInit(() => {
      20           10 :         cockpit.spawn(["last", "--time-format", "iso", "-n25", "--fullnames", name], { environ: ["LC_ALL=C"] })
      21           10 :                 .then(data => {
      22           10 :                     let logins = [];
      23           10 :                     data.split('\n').forEach(line => {
      24              :                         // Exclude still logged in and non user lines
      25            7 :                         if (!line.includes(name) || line.includes('still')) {
      26           10 :                             return;
      27           10 :                         }
      28              :                         // Exclude tmux/screen lines
      29            2 :                         if (line.includes('tmux') || line.includes('screen')) {
      30            2 :                             return;
      31            2 :                         }
      32              : 
      33              :                         // format:
      34              :                         // admin    web console  ::ffff:172.27.0. 2021-09-24T09:02:13+00:00 - 2021-09-24T09:04:20+00:00  (00:02)
      35            6 :                         const lines = line.split(/ +/);
      36            6 :                         const ended = new Date(lines[lines.length - 2]);
      37            6 :                         const started = new Date(lines[lines.length - 4]);
      38            6 :                         const from = lines[lines.length - 5];
      39            2 :                         if (isNaN(started.getTime()) || isNaN(ended.getTime())) {
      40            2 :                             return;
      41            2 :                         }
      42              : 
      43            6 :                         logins.push({
      44            6 :                             started,
      45            6 :                             ended,
      46            6 :                             from
      47            6 :                         });
      48           10 :                     });
      49              : 
      50              :                     // Only show 15 login lines
      51           10 :                     logins = logins.slice(0, 15);
      52           10 :                     setLogins(logins);
      53           10 :                 })
      54            0 :                 .catch(ex => console.error("Failed to call last:", ex)); // not-covered: OS error
      55           10 :     }, [name]);
      56              : 
      57           10 :     return (
      58           10 :         <Card isPlain id="account-logs">
      59           10 :             <CardTitle component="h2">{_("Login history")}</CardTitle>
      60           10 :             <CardBody className="contains-list">
      61           10 :                 <ListingTable variant="compact" aria-label={ _("Login history list") }
      62           10 :                     columns={ [
      63           10 :                         { title: _("Started") },
      64           10 :                         { title: _("Ended") },
      65           10 :                         { title: _("From") },
      66           10 :                     ] }
      67            5 :                     rows={ logins.map((line, index) => ({
      68            5 :                         props: { key: index },
      69            5 :                         columns: [timeformat.dateTime(line.started), timeformat.dateTime(line.ended), line.from]
      70            5 :                     }))} />
      71           10 :             </CardBody>
      72           10 :         </Card>
      73              :     );
      74           10 : }
        

Generated by: LCOV version 2.0-1