Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed sending /events requests from logged out users #7608

Merged
merged 13 commits into from
Mar 29, 2024
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
### Fixed

- Sending `/events` request from logged-out user (<https://github.com/opencv/cvat/pull/7608>)

### Added

- Redirect to login page on `401` error (<https://github.com/opencv/cvat/pull/7608>)
2 changes: 1 addition & 1 deletion cvat-core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cvat-core",
"version": "15.0.1",
"version": "15.0.2",
"type": "module",
"description": "Part of Computer Vision Tool which presents an interface for client-side integration",
"main": "src/api.ts",
Expand Down
6 changes: 6 additions & 0 deletions cvat-core/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,12 @@ function build(): CVATCore {
set onOrganizationChange(value: (orgId: number) => void) {
config.onOrganizationChange = value;
},
get onAuthenticationFailed(): () => void {
return config.onAuthenticationFailed;
},
set onAuthenticationFailed(value: () => void) {
config.onAuthenticationFailed = value;
},
set globalObjectsCounter(value: number) {
config.globalObjectsCounter = value;
},
Expand Down
1 change: 1 addition & 0 deletions cvat-core/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const config = {
onEmptyMaskOccurrence: null,
},
onOrganizationChange: null,
onAuthenticationFailed: null,
globalObjectsCounter: 0,
};

Expand Down
3 changes: 2 additions & 1 deletion cvat-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,8 @@ export default interface CVATCore {
enabled: boolean;
onEmptyMaskOccurrence: () => void | null;
};
onOrganizationChange: typeof config.onOrganizationChange;
onOrganizationChange: (newOrgId: number | null) => void | null;
onAuthenticationFailed: () => void | null;
globalObjectsCounter: typeof config.globalObjectsCounter;
},
client: {
Expand Down
5 changes: 5 additions & 0 deletions cvat-core/src/server-proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,11 @@ Axios.interceptors.response.use((response) => {
}

return response;
}, (error) => {
if (error?.response.status === 401) {
config?.onAuthenticationFailed();
}
throw error;
bsekachev marked this conversation as resolved.
Show resolved Hide resolved
});

let token = store.get('token');
Expand Down
2 changes: 1 addition & 1 deletion cvat-ui/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cvat-ui",
"version": "1.63.2",
"version": "1.63.4",
"description": "CVAT single-page application",
"main": "src/index.tsx",
"scripts": {
Expand Down
17 changes: 14 additions & 3 deletions cvat-ui/src/components/cvat-app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ class CVATApplication extends React.PureComponent<CVATAppProps & RouteComponentP
const { history, location } = this.props;
const {
HEALTH_CHECK_RETRIES, HEALTH_CHECK_PERIOD, HEALTH_CHECK_REQUEST_TIMEOUT, SERVER_UNAVAILABLE_COMPONENT,
RESET_NOTIFICATIONS_PATHS,
RESET_NOTIFICATIONS_PATHS, REDIRECT_TO_LOGIN_PAGE_TIMEOUT,
} = appConfig;

// Logger configuration
Expand All @@ -149,7 +149,6 @@ class CVATApplication extends React.PureComponent<CVATAppProps & RouteComponentP
});

core.logger.configure(() => window.document.hasFocus, userActivityCallback);
EventRecorder.initSave();

core.config.onOrganizationChange = (newOrgId: number | null) => {
if (newOrgId === null) {
Expand All @@ -167,6 +166,12 @@ class CVATApplication extends React.PureComponent<CVATAppProps & RouteComponentP
}
};

core.config.onAuthenticationFailed = () => {
if (!history.location.pathname.includes('auth')) {
setTimeout(() => history.push('/auth/login'), REDIRECT_TO_LOGIN_PAGE_TIMEOUT);
}
};

customWaViewHit(location.pathname, location.search, location.hash);
history.listen((newLocation) => {
customWaViewHit(newLocation.pathname, newLocation.search, newLocation.hash);
Expand Down Expand Up @@ -254,7 +259,7 @@ class CVATApplication extends React.PureComponent<CVATAppProps & RouteComponentP
}
}

public componentDidUpdate(): void {
public componentDidUpdate(prevProps: CVATAppProps): void {
const {
verifyAuthorized,
loadFormats,
Expand Down Expand Up @@ -302,6 +307,12 @@ class CVATApplication extends React.PureComponent<CVATAppProps & RouteComponentP
return;
}

if (user !== prevProps.user) {
EventRecorder.configure({
savingEnabled: !!user,
});
}

if (!userAgreementsInitialized && !userAgreementsFetching) {
loadUserAgreements();
return;
Expand Down
3 changes: 3 additions & 0 deletions cvat-ui/src/config.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ const OPENCV_PATH = '/assets/opencv_4.8.0.js';
const LOCAL_STORAGE_SEEN_GUIDES_MEMORY_LIMIT = 10;
const LOCAL_STORAGE_LAST_FRAME_MEMORY_LIMIT = 20;

const REDIRECT_TO_LOGIN_PAGE_TIMEOUT = 2000; // ms

export default {
UNDEFINED_ATTRIBUTE_VALUE,
NO_BREAK_SPACE,
Expand Down Expand Up @@ -171,4 +173,5 @@ export default {
OPENCV_PATH,
LOCAL_STORAGE_SEEN_GUIDES_MEMORY_LIMIT,
LOCAL_STORAGE_LAST_FRAME_MEMORY_LIMIT,
REDIRECT_TO_LOGIN_PAGE_TIMEOUT,
};
48 changes: 39 additions & 9 deletions cvat-ui/src/utils/controls-logger.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2023 CVAT.ai Corporation
// Copyright (C) 2023-2024 CVAT.ai Corporation
//
// SPDX-License-Identifier: MIT

Expand All @@ -13,10 +13,19 @@ const { CONTROLS_LOGS_INTERVAL } = config;
const classFilter = ['ant-btn'];
const parentClassFilter = ['ant-btn'];

export interface EventRecorderConfiguration {
savingEnabled: boolean;
}

class EventRecorder {
#savingTimeout: number | null;
#configuration: EventRecorderConfiguration;

public constructor() {
this.#savingTimeout = null;
this.#configuration = {
savingEnabled: false,
};
core.logger.log(EventScope.loadTool, {
location: window.location.pathname + window.location.search,
platform: platformInfo(),
Expand Down Expand Up @@ -49,14 +58,35 @@ class EventRecorder {
}
}

public initSave(): void {
if (this.#savingTimeout) return;
this.#savingTimeout = window.setTimeout(() => {
core.logger.save().finally(() => {
this.#savingTimeout = null;
this.initSave();
});
}, CONTROLS_LOGS_INTERVAL);
public configure(configuration: EventRecorderConfiguration): void {
this.onConfigurationChange(configuration);
this.#configuration = {
...this.#configuration,
...configuration,
};
}

private onConfigurationChange(newConfiguration: EventRecorderConfiguration): void {
const { savingEnabled } = newConfiguration;
if (savingEnabled !== this.#configuration.savingEnabled) {
this.setupSavingTimeout(savingEnabled);
}
}

private setupSavingTimeout(enable: boolean): void {
if (enable) {
if (this.#savingTimeout) return;

this.#savingTimeout = window.setTimeout(() => {
core.logger.save().finally(() => {
this.#savingTimeout = null;
this.setupSavingTimeout(true);
});
}, CONTROLS_LOGS_INTERVAL);
} else if (this.#savingTimeout) {
clearTimeout(this.#savingTimeout);
this.#savingTimeout = null;
}
}

private filterClassName(cls: string): string {
Expand Down
Loading