mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01: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