mirror of
https://github.com/Unleash/unleash.git
synced 2025-04-24 01:18:01 +02:00
feat: start populating user first seen column (#8010)
Co-authored-by: kwasniew <kwasniewski.mateusz@gmail.com>
This commit is contained in:
parent
8923e28d83
commit
5fe811ca3e
@ -135,6 +135,7 @@ exports[`should create default config 1`] = `
|
|||||||
"migrationLock": true,
|
"migrationLock": true,
|
||||||
"navigationSidebar": true,
|
"navigationSidebar": true,
|
||||||
"newEventSearch": false,
|
"newEventSearch": false,
|
||||||
|
"onboardingMetrics": false,
|
||||||
"originMiddleware": false,
|
"originMiddleware": false,
|
||||||
"outdatedSdksBanner": false,
|
"outdatedSdksBanner": false,
|
||||||
"personalAccessTokensKillSwitch": false,
|
"personalAccessTokensKillSwitch": false,
|
||||||
|
@ -88,7 +88,7 @@ export const createStores = (
|
|||||||
config.flagResolver,
|
config.flagResolver,
|
||||||
),
|
),
|
||||||
settingStore: new SettingStore(db, getLogger),
|
settingStore: new SettingStore(db, getLogger),
|
||||||
userStore: new UserStore(db, getLogger),
|
userStore: new UserStore(db, getLogger, config.flagResolver),
|
||||||
accountStore: new AccountStore(db, getLogger),
|
accountStore: new AccountStore(db, getLogger),
|
||||||
projectStore: new ProjectStore(
|
projectStore: new ProjectStore(
|
||||||
db,
|
db,
|
||||||
|
@ -11,6 +11,7 @@ import type {
|
|||||||
IUserUpdateFields,
|
IUserUpdateFields,
|
||||||
} from '../types/stores/user-store';
|
} from '../types/stores/user-store';
|
||||||
import type { Db } from './db';
|
import type { Db } from './db';
|
||||||
|
import type { IFlagResolver } from '../types';
|
||||||
|
|
||||||
const TABLE = 'users';
|
const TABLE = 'users';
|
||||||
const PASSWORD_HASH_TABLE = 'used_passwords';
|
const PASSWORD_HASH_TABLE = 'used_passwords';
|
||||||
@ -26,8 +27,6 @@ const USER_COLUMNS_PUBLIC = [
|
|||||||
'scim_id',
|
'scim_id',
|
||||||
];
|
];
|
||||||
|
|
||||||
const USED_PASSWORDS = ['user_id', 'password_hash', 'used_at'];
|
|
||||||
|
|
||||||
const USER_COLUMNS = [...USER_COLUMNS_PUBLIC, 'login_attempts', 'created_at'];
|
const USER_COLUMNS = [...USER_COLUMNS_PUBLIC, 'login_attempts', 'created_at'];
|
||||||
|
|
||||||
const emptify = (value) => {
|
const emptify = (value) => {
|
||||||
@ -69,9 +68,12 @@ class UserStore implements IUserStore {
|
|||||||
|
|
||||||
private logger: Logger;
|
private logger: Logger;
|
||||||
|
|
||||||
constructor(db: Db, getLogger: LogProvider) {
|
private flagResolver: IFlagResolver;
|
||||||
|
|
||||||
|
constructor(db: Db, getLogger: LogProvider, flagResolver: IFlagResolver) {
|
||||||
this.db = db;
|
this.db = db;
|
||||||
this.logger = getLogger('user-store.ts');
|
this.logger = getLogger('user-store.ts');
|
||||||
|
this.flagResolver = flagResolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getPasswordsPreviouslyUsed(userId: number): Promise<string[]> {
|
async getPasswordsPreviouslyUsed(userId: number): Promise<string[]> {
|
||||||
@ -230,10 +232,19 @@ class UserStore implements IUserStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async successfullyLogin(user: User): Promise<void> {
|
async successfullyLogin(user: User): Promise<void> {
|
||||||
return this.buildSelectUser(user).update({
|
const currentDate = new Date();
|
||||||
|
const updateQuery = this.buildSelectUser(user).update({
|
||||||
login_attempts: 0,
|
login_attempts: 0,
|
||||||
seen_at: new Date(),
|
seen_at: currentDate,
|
||||||
});
|
});
|
||||||
|
if (this.flagResolver.isEnabled('onboardingMetrics')) {
|
||||||
|
updateQuery.update({
|
||||||
|
first_seen_at: this.db.raw('COALESCE(first_seen_at, ?)', [
|
||||||
|
currentDate,
|
||||||
|
]),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return updateQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
async deleteAll(): Promise<void> {
|
async deleteAll(): Promise<void> {
|
||||||
|
@ -51,7 +51,7 @@ export const createInstanceStatsService = (db: Db, config: IUnleashConfig) => {
|
|||||||
getLogger,
|
getLogger,
|
||||||
flagResolver,
|
flagResolver,
|
||||||
);
|
);
|
||||||
const userStore = new UserStore(db, getLogger);
|
const userStore = new UserStore(db, getLogger, flagResolver);
|
||||||
const projectStore = new ProjectStore(
|
const projectStore = new ProjectStore(
|
||||||
db,
|
db,
|
||||||
eventBus,
|
eventBus,
|
||||||
|
@ -63,7 +63,8 @@ export type IFlagKey =
|
|||||||
| 'archiveProjects'
|
| 'archiveProjects'
|
||||||
| 'projectListImprovements'
|
| 'projectListImprovements'
|
||||||
| 'useProjectReadModel'
|
| 'useProjectReadModel'
|
||||||
| 'addonUsageMetrics';
|
| 'addonUsageMetrics'
|
||||||
|
| 'onboardingMetrics';
|
||||||
|
|
||||||
export type IFlags = Partial<{ [key in IFlagKey]: boolean | Variant }>;
|
export type IFlags = Partial<{ [key in IFlagKey]: boolean | Variant }>;
|
||||||
|
|
||||||
@ -308,6 +309,10 @@ const flags: IFlags = {
|
|||||||
process.env.UNLEASH_EXPERIMENTAL_ADDON_USAGE_METRICS,
|
process.env.UNLEASH_EXPERIMENTAL_ADDON_USAGE_METRICS,
|
||||||
false,
|
false,
|
||||||
),
|
),
|
||||||
|
onboardingMetrics: parseEnvVarBoolean(
|
||||||
|
process.env.UNLEASH_EXPERIMENTAL_ONBOARDING_METRICS,
|
||||||
|
false,
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
export const defaultExperimentalOptions: IExperimentalOptions = {
|
export const defaultExperimentalOptions: IExperimentalOptions = {
|
||||||
|
@ -56,6 +56,7 @@ process.nextTick(async () => {
|
|||||||
projectListImprovements: true,
|
projectListImprovements: true,
|
||||||
useProjectReadModel: true,
|
useProjectReadModel: true,
|
||||||
addonUsageMetrics: true,
|
addonUsageMetrics: true,
|
||||||
|
onboardingMetrics: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
authentication: {
|
authentication: {
|
||||||
|
Loading…
Reference in New Issue
Block a user