CB-4990 feat: add authentication timeout (#2829)

* CB-4990 feat: add authentication timeout

* CB-4990 fix: review

---------

Co-authored-by: Evgenia Bezborodova <139753579+EvgeniaBzzz@users.noreply.github.com>
This commit is contained in:
Alexey
2024-08-07 19:16:57 +03:00
committed by GitHub
co-authored by Evgenia Bezborodova
parent 5d071e5dfd
commit f059daf693
3 changed files with 48 additions and 8 deletions
@@ -140,6 +140,8 @@ export class UserInfoResource extends CachedDataResource<UserInfo | null, void,
return authInfo as AuthInfo;
},
1000,
undefined,
5 * 60 * 1000,
);
const authInfo = await activeTask;
@@ -0,0 +1,15 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2024 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
export class TimeoutError extends Error {
constructor(message?: string, options?: ErrorOptions) {
super(message, options);
this.name = 'Timeout Error';
}
}
+31 -8
View File
@@ -6,35 +6,54 @@
* you may not use this file except in compliance with the License.
*/
import { AutoRunningTask } from './TaskScheduler/AutoRunningTask';
import { CancelError } from './TaskScheduler/CancelError';
import type { ITask } from './TaskScheduler/ITask';
import { Task } from './TaskScheduler/Task';
import { TimeoutError } from './TaskScheduler/TimeoutError';
export function whileTask<T>(
callback: (value: T) => Promise<boolean> | boolean,
task: () => Promise<T>,
interval: number,
cancelMessage?: string,
timeout?: number,
): ITask<T> {
let resolve: (value: T | PromiseLike<T>) => void;
let reject: (reason?: any) => void;
let fulfilled = false;
let intervalTimeoutId: NodeJS.Timeout | null = null;
let timeoutId: NodeJS.Timeout | null = null;
let activeTask: Promise<T> | null = null;
let stopped = false;
const lockPromise = new Promise<T>((_resolve, _reject) => {
resolve = _resolve;
reject = _reject;
}).finally(() => {
if (intervalTimeoutId !== null) {
clearTimeout(intervalTimeoutId);
}
if (timeoutId !== null) {
clearTimeout(timeoutId);
}
fulfilled = true;
});
let timeoutId: NodeJS.Timeout | null;
let activeTask: Promise<T> | null;
let stopped = false;
function stop() {
if (timeoutId) {
clearTimeout(timeoutId);
if (intervalTimeoutId !== null) {
clearTimeout(intervalTimeoutId);
}
stopped = true;
}
async function cancelTask(exception?: any) {
if (fulfilled) {
return;
}
stop();
if (activeTask instanceof Task) {
@@ -44,6 +63,10 @@ export function whileTask<T>(
reject(exception);
}
if (timeout !== undefined) {
timeoutId = setTimeout(() => cancelTask(new TimeoutError('Task timeout exceeded')), timeout);
}
function runTask() {
activeTask = task();
activeTask
@@ -56,7 +79,7 @@ export function whileTask<T>(
if (state) {
resolve(value);
} else if (!stopped) {
timeoutId = setTimeout(runTask, interval);
intervalTimeoutId = setTimeout(runTask, interval);
}
})
.catch(cancelTask);
@@ -67,6 +90,6 @@ export function whileTask<T>(
runTask();
return lockPromise;
},
() => cancelTask(new Error(cancelMessage ?? 'Task was cancelled')),
() => cancelTask(new CancelError(cancelMessage ?? 'Task was cancelled')),
);
}