0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-03-10 22:22:45 -05:00

fix(console): fix impersonation tag in audit log (#6463)

This commit is contained in:
wangsijie 2024-08-19 11:43:38 +08:00 committed by GitHub
parent 1817eafe77
commit e4b028847f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 38 additions and 7 deletions

View file

@ -1,3 +1,4 @@
import { type Log } from '@logto/schemas';
import classNames from 'classnames';
import { Link } from 'react-router-dom';
@ -8,14 +9,16 @@ import Tag from '@/ds-components/Tag';
import useTenantPathname from '@/hooks/use-tenant-pathname';
import styles from './index.module.scss';
import { isImpersonationLog } from './utils';
type Props = {
readonly eventKey: string;
readonly isSuccess: boolean;
readonly payload: Log['payload'];
readonly to?: string;
};
function EventName({ eventKey, isSuccess, to }: Props) {
function EventName({ eventKey, payload, isSuccess, to }: Props) {
const title = logEventTitle[eventKey] ?? eventKey;
const { getTo } = useTenantPathname();
@ -36,7 +39,10 @@ function EventName({ eventKey, isSuccess, to }: Props) {
</Link>
)}
{!to && <div className={styles.title}>{title}</div>}
{eventKey === 'ExchangeTokenBy.TokenExchange' && <Tag status="alert">Impersonation</Tag>}
{isImpersonationLog({
key: eventKey,
payload,
}) && <Tag status="alert">Impersonation</Tag>}
</div>
);
}

View file

@ -0,0 +1,21 @@
import { type Log } from '@logto/schemas';
/**
* Check if the log (token exchange) is an impersonation log.
*
* @param log - The log object.
* @returns Whether the log is an impersonation log.
*/
export const isImpersonationLog = (
log: Pick<Log, 'key'> & { payload: Pick<Log['payload'], 'params'> }
) => {
if (log.key !== 'ExchangeTokenBy.TokenExchange') {
return false;
}
if (log.payload.params?.subject_token_type === 'urn:ietf:params:oauth:token-type:access_token') {
return true;
}
return false;
};

View file

@ -70,8 +70,12 @@ function AuditLogTable({ applicationId, userId, className }: Props) {
title: t('logs.event'),
dataIndex: 'event',
colSpan: isUserColumnVisible ? 5 : 6,
render: ({ key, payload: { result } }) => (
<EventName eventKey={key} isSuccess={result === LogResult.Success} />
render: ({ key, payload }) => (
<EventName
eventKey={key}
isSuccess={payload.result === LogResult.Success}
payload={payload}
/>
),
};

View file

@ -7,6 +7,7 @@ import { useLocation, useParams } from 'react-router-dom';
import useSWR from 'swr';
import ApplicationName from '@/components/ApplicationName';
import { isImpersonationLog } from '@/components/AuditLogTable/components/EventName/utils';
import DetailsPage from '@/components/DetailsPage';
import PageMeta from '@/components/PageMeta';
import UserName from '@/components/UserName';
@ -87,9 +88,7 @@ function AuditLogDetails() {
<div className={styles.content}>
<div className={styles.eventName}>
{logEventTitle[data.key]}
{data.key === 'ExchangeTokenBy.TokenExchange' && (
<Tag status="alert">Impersonation</Tag>
)}
{isImpersonationLog(data) && <Tag status="alert">Impersonation</Tag>}
</div>
<div className={styles.basicInfo}>
<div className={styles.infoItem}>

View file

@ -17,6 +17,7 @@ export const logContextPayloadGuard = z
userId: z.string().optional(),
applicationId: z.string().optional(),
sessionId: z.string().optional(),
params: z.record(z.string(), z.unknown()).optional(),
})
.catchall(z.unknown());