diff --git a/frontend/src/component/signOnLog/SignOnLog.tsx b/frontend/src/component/loginHistory/LoginHistory.tsx
similarity index 78%
rename from frontend/src/component/signOnLog/SignOnLog.tsx
rename to frontend/src/component/loginHistory/LoginHistory.tsx
index 98b3080e15..1f2de73458 100644
--- a/frontend/src/component/signOnLog/SignOnLog.tsx
+++ b/frontend/src/component/loginHistory/LoginHistory.tsx
@@ -3,16 +3,16 @@ import AccessContext from 'contexts/AccessContext';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import { ADMIN } from 'component/providers/AccessProvider/permissions';
import { AdminAlert } from 'component/common/AdminAlert/AdminAlert';
-import { SignOnLogTable } from './SignOnLogTable/SignOnLogTable';
+import { LoginHistoryTable } from './LoginHistoryTable/LoginHistoryTable';
-export const SignOnLog = () => {
+export const LoginHistory = () => {
const { hasAccess } = useContext(AccessContext);
return (
}
+ show={
}
elseShow={
}
/>
diff --git a/frontend/src/component/signOnLog/SignOnLogTable/SignOnLogActionsCell/SignOnLogActionsCell.tsx b/frontend/src/component/loginHistory/LoginHistoryTable/LoginHistoryActionsCell/LoginHistoryActionsCell.tsx
similarity index 86%
rename from frontend/src/component/signOnLog/SignOnLogTable/SignOnLogActionsCell/SignOnLogActionsCell.tsx
rename to frontend/src/component/loginHistory/LoginHistoryTable/LoginHistoryActionsCell/LoginHistoryActionsCell.tsx
index 9d395670a7..52d2c9a411 100644
--- a/frontend/src/component/signOnLog/SignOnLogTable/SignOnLogActionsCell/SignOnLogActionsCell.tsx
+++ b/frontend/src/component/loginHistory/LoginHistoryTable/LoginHistoryActionsCell/LoginHistoryActionsCell.tsx
@@ -8,13 +8,13 @@ const StyledBox = styled(Box)(() => ({
justifyContent: 'center',
}));
-interface ISignOnLogActionsCellProps {
+interface ILoginHistoryActionsCellProps {
onDelete: (event: React.SyntheticEvent) => void;
}
-export const SignOnLogActionsCell = ({
+export const LoginHistoryActionsCell = ({
onDelete,
-}: ISignOnLogActionsCellProps) => {
+}: ILoginHistoryActionsCellProps) => {
return (
>;
onConfirm: () => void;
}
-export const SignOnLogDeleteAllDialog = ({
+export const LoginHistoryDeleteAllDialog = ({
open,
setOpen,
onConfirm,
-}: IServiceAccountDeleteAllDialogProps) => (
+}: ILoginHistoryDeleteAllDialogProps) => (
{
setOpen(false);
}}
>
- You are about to clear the sign-on log.
+ You are about to clear the login history.
- This will delete all the sign-on events.
+ This will delete all the login events.
);
diff --git a/frontend/src/component/signOnLog/SignOnLogTable/SignOnLogDeleteDialog/SignOnLogDeleteDialog.tsx b/frontend/src/component/loginHistory/LoginHistoryTable/LoginHistoryDeleteDialog/LoginHistoryDeleteDialog.tsx
similarity index 67%
rename from frontend/src/component/signOnLog/SignOnLogTable/SignOnLogDeleteDialog/SignOnLogDeleteDialog.tsx
rename to frontend/src/component/loginHistory/LoginHistoryTable/LoginHistoryDeleteDialog/LoginHistoryDeleteDialog.tsx
index b0e30da0aa..4fea356c97 100644
--- a/frontend/src/component/signOnLog/SignOnLogTable/SignOnLogDeleteDialog/SignOnLogDeleteDialog.tsx
+++ b/frontend/src/component/loginHistory/LoginHistoryTable/LoginHistoryDeleteDialog/LoginHistoryDeleteDialog.tsx
@@ -1,19 +1,19 @@
import { Dialogue } from 'component/common/Dialogue/Dialogue';
-import { ISignOnEvent } from 'interfaces/signOnEvent';
+import { ILoginEvent } from 'interfaces/loginEvent';
-interface IServiceAccountDeleteDialogProps {
- event?: ISignOnEvent;
+interface ILoginHistoryDeleteDialogProps {
+ event?: ILoginEvent;
open: boolean;
setOpen: React.Dispatch>;
- onConfirm: (event: ISignOnEvent) => void;
+ onConfirm: (event: ILoginEvent) => void;
}
-export const SignOnLogDeleteDialog = ({
+export const LoginHistoryDeleteDialog = ({
event,
open,
setOpen,
onConfirm,
-}: IServiceAccountDeleteDialogProps) => (
+}: ILoginHistoryDeleteDialogProps) => (
({
justifyContent: 'center',
}));
-interface ISignOnLogSuccessfulCellProps {
+interface ILoginHistorySuccessfulCellProps {
row: {
- original: ISignOnEvent;
+ original: ILoginEvent;
};
value: boolean;
}
-export const SignOnLogSuccessfulCell: VFC = ({
- row,
- value,
-}) => {
+export const LoginHistorySuccessfulCell: VFC<
+ ILoginHistorySuccessfulCellProps
+> = ({ row, value }) => {
const { searchQuery } = useSearchHighlightContext();
if (value)
diff --git a/frontend/src/component/signOnLog/SignOnLogTable/SignOnLogTable.tsx b/frontend/src/component/loginHistory/LoginHistoryTable/LoginHistoryTable.tsx
similarity index 87%
rename from frontend/src/component/signOnLog/SignOnLogTable/SignOnLogTable.tsx
rename to frontend/src/component/loginHistory/LoginHistoryTable/LoginHistoryTable.tsx
index f3ae723a26..17906b85a5 100644
--- a/frontend/src/component/signOnLog/SignOnLogTable/SignOnLogTable.tsx
+++ b/frontend/src/component/loginHistory/LoginHistoryTable/LoginHistoryTable.tsx
@@ -16,17 +16,17 @@ import { Search } from 'component/common/Search/Search';
import { useConditionallyHiddenColumns } from 'hooks/useConditionallyHiddenColumns';
import { useSearch } from 'hooks/useSearch';
import { TimeAgoCell } from 'component/common/Table/cells/TimeAgoCell/TimeAgoCell';
-import { useSignOnLog } from 'hooks/api/getters/useSignOnLog/useSignOnLog';
-import { SignOnLogSuccessfulCell } from './SignOnLogSuccessfulCell/SignOnLogSuccessfulCell';
-import { ISignOnEvent } from 'interfaces/signOnEvent';
-import { SignOnLogActionsCell } from './SignOnLogActionsCell/SignOnLogActionsCell';
-import { SignOnLogDeleteDialog } from './SignOnLogDeleteDialog/SignOnLogDeleteDialog';
-import { useSignOnLogApi } from 'hooks/api/actions/useSignOnLogApi/useSignOnLogApi';
+import { useLoginHistory } from 'hooks/api/getters/useLoginHistory/useLoginHistory';
+import { LoginHistorySuccessfulCell } from './LoginHistorySuccessfulCell/LoginHistorySuccessfulCell';
+import { ILoginEvent } from 'interfaces/loginEvent';
+import { LoginHistoryActionsCell } from './LoginHistoryActionsCell/LoginHistoryActionsCell';
+import { LoginHistoryDeleteDialog } from './LoginHistoryDeleteDialog/LoginHistoryDeleteDialog';
+import { useLoginHistoryApi } from 'hooks/api/actions/useLoginHistoryApi/useLoginHistoryApi';
import { formatDateYMDHMS } from 'utils/formatDate';
import { useSearchParams } from 'react-router-dom';
import { createLocalStorage } from 'utils/createLocalStorage';
import { Delete, Download } from '@mui/icons-material';
-import { SignOnLogDeleteAllDialog } from './SignOnLogDeleteAllDialog/SignOnLogDeleteAllDialog';
+import { LoginHistoryDeleteAllDialog } from './LoginHistoryDeleteAllDialog/LoginHistoryDeleteAllDialog';
export type PageQueryType = Partial<
Record<'sort' | 'order' | 'search', string>
@@ -35,7 +35,7 @@ export type PageQueryType = Partial<
const defaultSort: SortingRule = { id: 'created_at' };
const { value: storedParams, setValue: setStoredParams } = createLocalStorage(
- 'SignOnLogTable:v1',
+ 'LoginHistoryTable:v1',
defaultSort
);
@@ -46,11 +46,11 @@ const AUTH_TYPE_LABEL: { [key: string]: string } = {
google: 'Google',
};
-export const SignOnLogTable = () => {
+export const LoginHistoryTable = () => {
const { setToastData, setToastApiError } = useToast();
- const { events, loading, refetch } = useSignOnLog();
- const { removeEvent, removeAllEvents, downloadCSV } = useSignOnLogApi();
+ const { events, loading, refetch } = useLoginHistory();
+ const { removeEvent, removeAllEvents, downloadCSV } = useLoginHistoryApi();
const [searchParams, setSearchParams] = useSearchParams();
const [initialState] = useState(() => ({
@@ -67,11 +67,11 @@ export const SignOnLogTable = () => {
}));
const [searchValue, setSearchValue] = useState(initialState.globalFilter);
- const [selectedEvent, setSelectedEvent] = useState();
+ const [selectedEvent, setSelectedEvent] = useState();
const [deleteOpen, setDeleteOpen] = useState(false);
const [deleteAllOpen, setDeleteAllOpen] = useState(false);
- const onDeleteConfirm = async (event: ISignOnEvent) => {
+ const onDeleteConfirm = async (event: ILoginEvent) => {
try {
await removeEvent(event.id);
setToastData({
@@ -89,7 +89,7 @@ export const SignOnLogTable = () => {
try {
await removeAllEvents();
setToastData({
- title: `Log has been cleared`,
+ title: `History has been cleared`,
type: 'success',
});
refetch();
@@ -122,7 +122,7 @@ export const SignOnLogTable = () => {
},
{
Header: 'Authentication',
- accessor: (event: ISignOnEvent) =>
+ accessor: (event: ILoginEvent) =>
AUTH_TYPE_LABEL[event.auth_type] || event.auth_type,
width: 150,
maxWidth: 150,
@@ -140,7 +140,7 @@ export const SignOnLogTable = () => {
Header: 'Success',
accessor: 'successful',
align: 'center',
- Cell: SignOnLogSuccessfulCell,
+ Cell: LoginHistorySuccessfulCell,
filterName: 'success',
filterParsing: (value: boolean) => value.toString(),
},
@@ -149,7 +149,7 @@ export const SignOnLogTable = () => {
id: 'Actions',
align: 'center',
Cell: ({ row: { original: event } }: any) => (
- {
setSelectedEvent(event);
setDeleteOpen(true);
@@ -238,7 +238,7 @@ export const SignOnLogTable = () => {
isLoading={loading}
header={
{
show={}
/>
@@ -269,7 +269,7 @@ export const SignOnLogTable = () => {
{
condition={searchValue?.length > 0}
show={
- No sign-on events found matching “
+ No login events found matching “
{searchValue}
”
}
elseShow={
- No sign-on events available.
+ No login events available.
}
/>
}
/>
-
- {
+export const useLoginHistoryApi = () => {
const { loading, makeRequest, createRequest, errors } = useAPI({
propagateErrors: true,
});
@@ -8,7 +8,7 @@ export const useSignOnLogApi = () => {
const downloadCSV = async () => {
const requestId = 'downloadCSV';
const req = createRequest(
- 'api/admin/signons',
+ 'api/admin/logins',
{
method: 'GET',
responseType: 'blob',
@@ -25,7 +25,7 @@ export const useSignOnLogApi = () => {
const removeEvent = async (eventId: number) => {
const requestId = 'removeEvent';
const req = createRequest(
- `api/admin/signons/${eventId}`,
+ `api/admin/logins/${eventId}`,
{ method: 'DELETE' },
requestId
);
@@ -36,7 +36,7 @@ export const useSignOnLogApi = () => {
const removeAllEvents = async () => {
const requestId = 'removeAllEvents';
const req = createRequest(
- 'api/admin/signons',
+ 'api/admin/logins',
{ method: 'DELETE' },
requestId
);
diff --git a/frontend/src/hooks/api/getters/useSignOnLog/useSignOnLog.ts b/frontend/src/hooks/api/getters/useLoginHistory/useLoginHistory.ts
similarity index 68%
rename from frontend/src/hooks/api/getters/useSignOnLog/useSignOnLog.ts
rename to frontend/src/hooks/api/getters/useLoginHistory/useLoginHistory.ts
index 812f078bdd..ab66c8060e 100644
--- a/frontend/src/hooks/api/getters/useSignOnLog/useSignOnLog.ts
+++ b/frontend/src/hooks/api/getters/useLoginHistory/useLoginHistory.ts
@@ -1,25 +1,25 @@
-import { ISignOnEvent } from 'interfaces/signOnEvent';
+import { ILoginEvent } from 'interfaces/loginEvent';
import { useMemo } from 'react';
import { formatApiPath } from 'utils/formatPath';
import handleErrorResponses from '../httpErrorResponseHandler';
import { useConditionalSWR } from '../useConditionalSWR/useConditionalSWR';
import useUiConfig from '../useUiConfig/useUiConfig';
-export const useSignOnLog = () => {
+export const useLoginHistory = () => {
const { uiConfig, isEnterprise } = useUiConfig();
- const { signOnLog } = uiConfig.flags;
+ const { loginHistory } = uiConfig.flags;
const { data, error, mutate } = useConditionalSWR(
- signOnLog && isEnterprise(),
+ loginHistory && isEnterprise(),
{ events: [] },
- formatApiPath(`api/admin/signons`),
+ formatApiPath(`api/admin/logins`),
fetcher
);
return useMemo(
() => ({
- events: (data?.events ?? []) as ISignOnEvent[],
+ events: (data?.events ?? []) as ILoginEvent[],
loading: !error && !data,
refetch: () => mutate(),
error,
@@ -30,6 +30,6 @@ export const useSignOnLog = () => {
const fetcher = (path: string) => {
return fetch(path)
- .then(handleErrorResponses('Sign-On Log'))
+ .then(handleErrorResponses('Login History'))
.then(res => res.json());
};
diff --git a/frontend/src/interfaces/signOnEvent.ts b/frontend/src/interfaces/loginEvent.ts
similarity index 82%
rename from frontend/src/interfaces/signOnEvent.ts
rename to frontend/src/interfaces/loginEvent.ts
index 285709ac5c..c543829b30 100644
--- a/frontend/src/interfaces/signOnEvent.ts
+++ b/frontend/src/interfaces/loginEvent.ts
@@ -1,4 +1,4 @@
-export interface ISignOnEvent {
+export interface ILoginEvent {
id: number;
username: string;
auth_type: string;
diff --git a/frontend/src/interfaces/uiConfig.ts b/frontend/src/interfaces/uiConfig.ts
index e9f32e352c..945d3addd5 100644
--- a/frontend/src/interfaces/uiConfig.ts
+++ b/frontend/src/interfaces/uiConfig.ts
@@ -47,7 +47,7 @@ export interface IFlags {
showProjectApiAccess?: boolean;
proPlanAutoCharge?: boolean;
notifications?: boolean;
- signOnLog?: boolean;
+ loginHistory?: boolean;
}
export interface IVersionInfo {
diff --git a/src/lib/__snapshots__/create-config.test.ts.snap b/src/lib/__snapshots__/create-config.test.ts.snap
index ccd38d593a..2c650e6b8a 100644
--- a/src/lib/__snapshots__/create-config.test.ts.snap
+++ b/src/lib/__snapshots__/create-config.test.ts.snap
@@ -74,6 +74,7 @@ exports[`should create default config 1`] = `
"embedProxy": true,
"embedProxyFrontend": true,
"featuresExportImport": false,
+ "loginHistory": false,
"maintenanceMode": false,
"messageBanner": false,
"newProjectOverview": false,
@@ -83,7 +84,6 @@ exports[`should create default config 1`] = `
"proxyReturnAllToggles": false,
"responseTimeWithAppNameKillSwitch": false,
"showProjectApiAccess": false,
- "signOnLog": false,
"strictSchemaValidation": false,
},
},
@@ -96,6 +96,7 @@ exports[`should create default config 1`] = `
"embedProxy": true,
"embedProxyFrontend": true,
"featuresExportImport": false,
+ "loginHistory": false,
"maintenanceMode": false,
"messageBanner": false,
"newProjectOverview": false,
@@ -105,7 +106,6 @@ exports[`should create default config 1`] = `
"proxyReturnAllToggles": false,
"responseTimeWithAppNameKillSwitch": false,
"showProjectApiAccess": false,
- "signOnLog": false,
"strictSchemaValidation": false,
},
"externalResolver": {
diff --git a/src/lib/types/experimental.ts b/src/lib/types/experimental.ts
index 87addfaa88..2bafbb3fc1 100644
--- a/src/lib/types/experimental.ts
+++ b/src/lib/types/experimental.ts
@@ -63,7 +63,7 @@ const flags = {
false,
),
notifications: parseEnvVarBoolean(process.env.NOTIFICATIONS, false),
- signOnLog: parseEnvVarBoolean(process.env.UNLEASH_SIGN_ON_LOG, false),
+ loginHistory: parseEnvVarBoolean(process.env.UNLEASH_LOGIN_HISTORY, false),
};
export const defaultExperimentalOptions: IExperimentalOptions = {
diff --git a/src/migrations/20230302133740-rename-sign-on-log-table-to-login-history.js b/src/migrations/20230302133740-rename-sign-on-log-table-to-login-history.js
new file mode 100644
index 0000000000..dc061955d9
--- /dev/null
+++ b/src/migrations/20230302133740-rename-sign-on-log-table-to-login-history.js
@@ -0,0 +1,20 @@
+exports.up = function (db, cb) {
+ db.runSql(`ALTER TABLE sign_on_log RENAME TO login_history`, cb);
+ db.runSql(`DELETE FROM settings WHERE name = 'sign_on_log_retention'`, cb);
+ db.runSql(
+ `INSERT INTO settings(name, content) VALUES ('login_history_retention', '{"hours": 336}')`,
+ cb,
+ );
+};
+
+exports.down = function (db, cb) {
+ db.runSql(`ALTER TABLE login_history RENAME TO sign_on_log`, cb);
+ db.runSql(
+ `DELETE FROM settings WHERE name = 'login_history_retention'`,
+ cb,
+ );
+ db.runSql(
+ `INSERT INTO settings(name, content) VALUES ('sign_on_log_retention', '{"hours": 336}')`,
+ cb,
+ );
+};