1 import { c } from 'ttag';
3 import Alert from '@proton/components/components/alert/Alert';
4 import Info from '@proton/components/components/link/Info';
5 import Table from '@proton/components/components/table/Table';
6 import TableBody from '@proton/components/components/table/TableBody';
7 import TableCell from '@proton/components/components/table/TableCell';
8 import TableHeader from '@proton/components/components/table/TableHeader';
9 import TableRow from '@proton/components/components/table/TableRow';
10 import Time from '@proton/components/components/time/Time';
11 import type { AuthLog } from '@proton/shared/lib/authlog';
12 import { SETTINGS_LOG_AUTH_STATE, SETTINGS_PROTON_SENTINEL_STATE } from '@proton/shared/lib/interfaces';
13 import isTruthy from '@proton/utils/isTruthy';
15 import AppVersionCell from './AppVersionCell';
16 import DeviceCell from './DeviceCell';
17 import EventCell from './EventCell';
18 import IPCell from './IPCell';
19 import LocationCell from './LocationCell';
20 import ProtectionCell from './ProtectionCell';
22 const { ADVANCED, DISABLE } = SETTINGS_LOG_AUTH_STATE;
23 const { ENABLED } = SETTINGS_PROTON_SENTINEL_STATE;
27 logAuth: SETTINGS_LOG_AUTH_STATE;
28 protonSentinel: SETTINGS_PROTON_SENTINEL_STATE;
33 const LogsTable = ({ logs, logAuth, protonSentinel, loading, error }: Props) => {
34 const isAuthLogAdvanced = logAuth === ADVANCED;
35 const isProtonSentinelEnabled = protonSentinel === ENABLED;
37 if (logAuth === DISABLE) {
39 <Alert className="mb-4">{c('Info')
40 .t`You can enable authentication logs to see when your account is accessed, and from which IP. We will record the IP address that accesses the account and the time, as well as failed attempts.`}</Alert>
44 if (!loading && !logs.length) {
45 return <Alert className="mb-4">{c('Info').t`No logs yet.`}</Alert>;
48 if (!loading && error) {
49 return <Alert className="mb-4" type="error">{c('Info').t`Failed to fetch logs.`}</Alert>;
52 const isUnavailableClass = (isAdvancedLogOnly = true) => {
53 if ((isAdvancedLogOnly && !isAuthLogAdvanced) || !isProtonSentinelEnabled) {
61 className: 'text-left',
62 header: c('Header').t`Time`,
65 className: isAuthLogAdvanced || isProtonSentinelEnabled ? 'w-1/6' : 'w-1/5',
66 header: c('Header').t`Event`,
69 header: c('Header').t`App version`,
72 className: isAuthLogAdvanced ? 'w-1/6' : 'bg-weak w-custom',
73 style: { '--w-custom': '5%' },
77 className: isUnavailableClass(),
78 header: c('Header').t`Location`,
79 info: c('Tooltip').t`An approximate location of the IP address`,
83 isAuthLogAdvanced && isProtonSentinelEnabled
84 ? `${isUnavailableClass()}`
85 : `${isUnavailableClass()} w-1/10`,
87 info: c('Tooltip').t`The Internet Service Provider of the IP address`,
90 className: isProtonSentinelEnabled ? isUnavailableClass(false) : `${isUnavailableClass(false)} w-5`,
91 header: c('Header').t`Device`,
92 info: c('Tooltip').t`Device information such as operating system`,
95 className: isUnavailableClass(false),
96 header: c('Header').t`Protection`,
97 info: c('Tooltip').t`Any protection applied to suspicious activity`,
102 <Table responsive="cards">
105 {headerCells.map(({ className, header, info }) => (
106 <TableCell key={header} className={className} type="header">
107 <div className="flex items-center flex-nowrap">
109 {info && <Info className="ml-2 shrink-0" title={info} />}
115 <TableBody loading={loading} colSpan={headerCells.length}>
132 const key = index.toString();
135 label: c('Header').t`Time`,
136 className: 'text-left',
138 <Time key={key} format="PPp">
144 label: c('Header').t`Event`,
145 content: <EventCell description={Description} status={Status} />,
148 label: c('Header').t`App version`,
149 content: <AppVersionCell appVersion={AppVersion} />,
153 className: isAuthLogAdvanced ? '' : 'bg-weak hidden lg:table-cell text-center',
155 if (!isAuthLogAdvanced) {
156 if (isProtonSentinelEnabled) {
165 isAuthLogAdvanced={isAuthLogAdvanced}
166 isProtonSentinelEnabled={isProtonSentinelEnabled}
168 firstRow={index === 0}
172 isAuthLogAdvanced && {
173 label: c('Header').t`Location`,
174 className: `${isUnavailableClass()} ${
175 !isAuthLogAdvanced || !isProtonSentinelEnabled ? 'text-left lg:text-center' : ''
177 colSpan: isProtonSentinelEnabled ? 1 : 4,
180 isProtonSentinelEnabled={isProtonSentinelEnabled}
182 firstRow={index === 0}
187 isProtonSentinelEnabled && {
189 content: <span className="flex-1">{InternetProvider || '-'}</span>,
191 isProtonSentinelEnabled && {
192 label: c('Header').t`Device`,
193 content: <DeviceCell device={Device} />,
195 isProtonSentinelEnabled && {
196 label: c('Header').t`Protection`,
197 content: <ProtectionCell protection={Protection} protectionDesc={ProtectionDesc} />,
203 {cells.map(({ label, className, colSpan, content }) => (
204 <TableCell key={label} label={label} className={className} colSpan={colSpan}>
216 export default LogsTable;