mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-25 00:07:47 +01:00
feat: ability to configure when users are considered inactive (#8454)
Give the ability to change when users are considered inactive via an environment variable `USER_INACTIVITY_THRESHOLD_IN_DAYS` or configuration option: `userInactivityThresholdInDays`. Default remains 180 days
This commit is contained in:
parent
6b56f8ff89
commit
7fb9308b3e
@ -154,6 +154,7 @@ exports[`should create default config 1`] = `
|
|||||||
"ui": {
|
"ui": {
|
||||||
"environment": "Open Source",
|
"environment": "Open Source",
|
||||||
},
|
},
|
||||||
|
"userInactivityThresholdInDays": 180,
|
||||||
"versionCheck": {
|
"versionCheck": {
|
||||||
"enable": true,
|
"enable": true,
|
||||||
"url": "https://version.unleash.run",
|
"url": "https://version.unleash.run",
|
||||||
|
@ -713,6 +713,14 @@ export function createConfig(options: IUnleashOptions): IUnleashConfig {
|
|||||||
|
|
||||||
const openAIAPIKey = process.env.OPENAI_API_KEY;
|
const openAIAPIKey = process.env.OPENAI_API_KEY;
|
||||||
|
|
||||||
|
const defaultDaysToBeConsideredInactive = 180;
|
||||||
|
const userInactivityThresholdInDays =
|
||||||
|
options.userInactivityThresholdInDays ??
|
||||||
|
parseEnvVarNumber(
|
||||||
|
process.env.USER_INACTIVITY_THRESHOLD_IN_DAYS,
|
||||||
|
defaultDaysToBeConsideredInactive,
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
db,
|
db,
|
||||||
session,
|
session,
|
||||||
@ -752,6 +760,7 @@ export function createConfig(options: IUnleashOptions): IUnleashConfig {
|
|||||||
feedbackUriPath,
|
feedbackUriPath,
|
||||||
dailyMetricsStorageDays,
|
dailyMetricsStorageDays,
|
||||||
openAIAPIKey,
|
openAIAPIKey,
|
||||||
|
userInactivityThresholdInDays,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,6 +156,7 @@ export interface IUnleashOptions {
|
|||||||
| 'segments'
|
| 'segments'
|
||||||
>
|
>
|
||||||
>;
|
>;
|
||||||
|
userInactivityThresholdInDays?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IEmailOption {
|
export interface IEmailOption {
|
||||||
@ -274,4 +275,5 @@ export interface IUnleashConfig {
|
|||||||
rateLimiting: IRateLimiting;
|
rateLimiting: IRateLimiting;
|
||||||
feedbackUriPath?: string;
|
feedbackUriPath?: string;
|
||||||
openAIAPIKey?: string;
|
openAIAPIKey?: string;
|
||||||
|
userInactivityThresholdInDays: number;
|
||||||
}
|
}
|
||||||
|
@ -5,30 +5,32 @@ import { InactiveUsersStore } from './inactive-users-store';
|
|||||||
import { FakeInactiveUsersStore } from './fakes/fake-inactive-users-store';
|
import { FakeInactiveUsersStore } from './fakes/fake-inactive-users-store';
|
||||||
import type { UserService } from '../../services';
|
import type { UserService } from '../../services';
|
||||||
|
|
||||||
export const DAYS_TO_BE_COUNTED_AS_INACTIVE = 180;
|
|
||||||
export const createInactiveUsersService = (
|
export const createInactiveUsersService = (
|
||||||
db: Db,
|
db: Db,
|
||||||
config: IUnleashConfig,
|
config: IUnleashConfig,
|
||||||
userService: UserService,
|
userService: UserService,
|
||||||
): InactiveUsersService => {
|
): InactiveUsersService => {
|
||||||
const { eventBus, getLogger } = config;
|
const { eventBus, getLogger, userInactivityThresholdInDays } = config;
|
||||||
const inactiveUsersStore = new InactiveUsersStore(db, eventBus, getLogger);
|
const inactiveUsersStore = new InactiveUsersStore(db, eventBus, getLogger);
|
||||||
|
|
||||||
return new InactiveUsersService(
|
return new InactiveUsersService(
|
||||||
{ inactiveUsersStore },
|
{ inactiveUsersStore },
|
||||||
{ getLogger },
|
{ getLogger, userInactivityThresholdInDays },
|
||||||
{ userService },
|
{ userService },
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const createFakeInactiveUsersService = (
|
export const createFakeInactiveUsersService = (
|
||||||
{ getLogger, eventBus }: Pick<IUnleashConfig, 'getLogger' | 'eventBus'>,
|
{
|
||||||
|
getLogger,
|
||||||
|
userInactivityThresholdInDays,
|
||||||
|
}: Pick<IUnleashConfig, 'getLogger' | 'userInactivityThresholdInDays'>,
|
||||||
userService: UserService,
|
userService: UserService,
|
||||||
): InactiveUsersService => {
|
): InactiveUsersService => {
|
||||||
const fakeStore = new FakeInactiveUsersStore();
|
const fakeStore = new FakeInactiveUsersStore();
|
||||||
return new InactiveUsersService(
|
return new InactiveUsersService(
|
||||||
{ inactiveUsersStore: fakeStore },
|
{ inactiveUsersStore: fakeStore },
|
||||||
{ getLogger },
|
{ getLogger, userInactivityThresholdInDays },
|
||||||
{ userService },
|
{ userService },
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -20,7 +20,6 @@ import {
|
|||||||
import type { IAuthRequest } from '../../routes/unleash-types';
|
import type { IAuthRequest } from '../../routes/unleash-types';
|
||||||
import type { Response } from 'express';
|
import type { Response } from 'express';
|
||||||
import type { OpenApiService } from '../../services';
|
import type { OpenApiService } from '../../services';
|
||||||
import { DAYS_TO_BE_COUNTED_AS_INACTIVE } from './createInactiveUsersService';
|
|
||||||
import { anonymise } from '../../util';
|
import { anonymise } from '../../util';
|
||||||
export class InactiveUsersController extends Controller {
|
export class InactiveUsersController extends Controller {
|
||||||
private readonly logger: Logger;
|
private readonly logger: Logger;
|
||||||
@ -30,6 +29,8 @@ export class InactiveUsersController extends Controller {
|
|||||||
private openApiService: OpenApiService;
|
private openApiService: OpenApiService;
|
||||||
|
|
||||||
private flagResolver: IFlagResolver;
|
private flagResolver: IFlagResolver;
|
||||||
|
|
||||||
|
private readonly userInactivityThresholdInDays: number;
|
||||||
constructor(
|
constructor(
|
||||||
config: IUnleashConfig,
|
config: IUnleashConfig,
|
||||||
{
|
{
|
||||||
@ -44,6 +45,8 @@ export class InactiveUsersController extends Controller {
|
|||||||
this.inactiveUsersService = inactiveUsersService;
|
this.inactiveUsersService = inactiveUsersService;
|
||||||
this.openApiService = openApiService;
|
this.openApiService = openApiService;
|
||||||
this.flagResolver = config.flagResolver;
|
this.flagResolver = config.flagResolver;
|
||||||
|
this.userInactivityThresholdInDays =
|
||||||
|
config.userInactivityThresholdInDays;
|
||||||
|
|
||||||
this.route({
|
this.route({
|
||||||
method: 'get',
|
method: 'get',
|
||||||
@ -54,7 +57,7 @@ export class InactiveUsersController extends Controller {
|
|||||||
openApiService.validPath({
|
openApiService.validPath({
|
||||||
operationId: 'getInactiveUsers',
|
operationId: 'getInactiveUsers',
|
||||||
summary: 'Gets inactive users',
|
summary: 'Gets inactive users',
|
||||||
description: `Gets all inactive users. An inactive user is a user that has not logged in in the last ${DAYS_TO_BE_COUNTED_AS_INACTIVE} days`,
|
description: `Gets all inactive users. An inactive user is a user that has not logged in in the last ${this.userInactivityThresholdInDays} days`,
|
||||||
tags: ['Users'],
|
tags: ['Users'],
|
||||||
responses: {
|
responses: {
|
||||||
200: createResponseSchema('inactiveUsersSchema'),
|
200: createResponseSchema('inactiveUsersSchema'),
|
||||||
@ -71,7 +74,7 @@ export class InactiveUsersController extends Controller {
|
|||||||
openApiService.validPath({
|
openApiService.validPath({
|
||||||
operationId: 'deleteInactiveUsers',
|
operationId: 'deleteInactiveUsers',
|
||||||
summary: 'Deletes inactive users',
|
summary: 'Deletes inactive users',
|
||||||
description: `Deletes all inactive users. An inactive user is a user that has not logged in in the last ${DAYS_TO_BE_COUNTED_AS_INACTIVE} days`,
|
description: `Deletes all inactive users. An inactive user is a user that has not logged in in the last ${this.userInactivityThresholdInDays} days`,
|
||||||
tags: ['Users'],
|
tags: ['Users'],
|
||||||
requestBody: createRequestSchema('idsSchema'),
|
requestBody: createRequestSchema('idsSchema'),
|
||||||
responses: {
|
responses: {
|
||||||
|
@ -8,15 +8,18 @@ import type { IInactiveUsersStore } from './types/inactive-users-store-type';
|
|||||||
import type { Logger } from '../../logger';
|
import type { Logger } from '../../logger';
|
||||||
import type { InactiveUserSchema } from '../../openapi';
|
import type { InactiveUserSchema } from '../../openapi';
|
||||||
import type { UserService } from '../../services';
|
import type { UserService } from '../../services';
|
||||||
import { DAYS_TO_BE_COUNTED_AS_INACTIVE } from './createInactiveUsersService';
|
|
||||||
|
|
||||||
export class InactiveUsersService {
|
export class InactiveUsersService {
|
||||||
private inactiveUsersStore: IInactiveUsersStore;
|
private inactiveUsersStore: IInactiveUsersStore;
|
||||||
private readonly logger: Logger;
|
private readonly logger: Logger;
|
||||||
private userService: UserService;
|
private userService: UserService;
|
||||||
|
private readonly userInactivityThresholdInDays: number;
|
||||||
constructor(
|
constructor(
|
||||||
{ inactiveUsersStore }: Pick<IUnleashStores, 'inactiveUsersStore'>,
|
{ inactiveUsersStore }: Pick<IUnleashStores, 'inactiveUsersStore'>,
|
||||||
{ getLogger }: Pick<IUnleashConfig, 'getLogger'>,
|
{
|
||||||
|
getLogger,
|
||||||
|
userInactivityThresholdInDays,
|
||||||
|
}: Pick<IUnleashConfig, 'getLogger' | 'userInactivityThresholdInDays'>,
|
||||||
services: {
|
services: {
|
||||||
userService: UserService;
|
userService: UserService;
|
||||||
},
|
},
|
||||||
@ -24,11 +27,12 @@ export class InactiveUsersService {
|
|||||||
this.logger = getLogger('services/client-feature-toggle-service.ts');
|
this.logger = getLogger('services/client-feature-toggle-service.ts');
|
||||||
this.inactiveUsersStore = inactiveUsersStore;
|
this.inactiveUsersStore = inactiveUsersStore;
|
||||||
this.userService = services.userService;
|
this.userService = services.userService;
|
||||||
|
this.userInactivityThresholdInDays = userInactivityThresholdInDays;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getInactiveUsers(): Promise<InactiveUserSchema[]> {
|
async getInactiveUsers(): Promise<InactiveUserSchema[]> {
|
||||||
const users = await this.inactiveUsersStore.getInactiveUsers(
|
const users = await this.inactiveUsersStore.getInactiveUsers(
|
||||||
DAYS_TO_BE_COUNTED_AS_INACTIVE,
|
this.userInactivityThresholdInDays,
|
||||||
);
|
);
|
||||||
if (users.length > 0) {
|
if (users.length > 0) {
|
||||||
return users.map((user) => {
|
return users.map((user) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user