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, | ||||
|       "navigationSidebar": true, | ||||
|       "newEventSearch": false, | ||||
|       "onboardingMetrics": false, | ||||
|       "originMiddleware": false, | ||||
|       "outdatedSdksBanner": false, | ||||
|       "personalAccessTokensKillSwitch": false, | ||||
|  | ||||
| @ -88,7 +88,7 @@ export const createStores = ( | ||||
|             config.flagResolver, | ||||
|         ), | ||||
|         settingStore: new SettingStore(db, getLogger), | ||||
|         userStore: new UserStore(db, getLogger), | ||||
|         userStore: new UserStore(db, getLogger, config.flagResolver), | ||||
|         accountStore: new AccountStore(db, getLogger), | ||||
|         projectStore: new ProjectStore( | ||||
|             db, | ||||
|  | ||||
| @ -11,6 +11,7 @@ import type { | ||||
|     IUserUpdateFields, | ||||
| } from '../types/stores/user-store'; | ||||
| import type { Db } from './db'; | ||||
| import type { IFlagResolver } from '../types'; | ||||
| 
 | ||||
| const TABLE = 'users'; | ||||
| const PASSWORD_HASH_TABLE = 'used_passwords'; | ||||
| @ -26,8 +27,6 @@ const USER_COLUMNS_PUBLIC = [ | ||||
|     'scim_id', | ||||
| ]; | ||||
| 
 | ||||
| const USED_PASSWORDS = ['user_id', 'password_hash', 'used_at']; | ||||
| 
 | ||||
| const USER_COLUMNS = [...USER_COLUMNS_PUBLIC, 'login_attempts', 'created_at']; | ||||
| 
 | ||||
| const emptify = (value) => { | ||||
| @ -69,9 +68,12 @@ class UserStore implements IUserStore { | ||||
| 
 | ||||
|     private logger: Logger; | ||||
| 
 | ||||
|     constructor(db: Db, getLogger: LogProvider) { | ||||
|     private flagResolver: IFlagResolver; | ||||
| 
 | ||||
|     constructor(db: Db, getLogger: LogProvider, flagResolver: IFlagResolver) { | ||||
|         this.db = db; | ||||
|         this.logger = getLogger('user-store.ts'); | ||||
|         this.flagResolver = flagResolver; | ||||
|     } | ||||
| 
 | ||||
|     async getPasswordsPreviouslyUsed(userId: number): Promise<string[]> { | ||||
| @ -230,10 +232,19 @@ class UserStore implements IUserStore { | ||||
|     } | ||||
| 
 | ||||
|     async successfullyLogin(user: User): Promise<void> { | ||||
|         return this.buildSelectUser(user).update({ | ||||
|         const currentDate = new Date(); | ||||
|         const updateQuery = this.buildSelectUser(user).update({ | ||||
|             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> { | ||||
|  | ||||
| @ -51,7 +51,7 @@ export const createInstanceStatsService = (db: Db, config: IUnleashConfig) => { | ||||
|         getLogger, | ||||
|         flagResolver, | ||||
|     ); | ||||
|     const userStore = new UserStore(db, getLogger); | ||||
|     const userStore = new UserStore(db, getLogger, flagResolver); | ||||
|     const projectStore = new ProjectStore( | ||||
|         db, | ||||
|         eventBus, | ||||
|  | ||||
| @ -63,7 +63,8 @@ export type IFlagKey = | ||||
|     | 'archiveProjects' | ||||
|     | 'projectListImprovements' | ||||
|     | 'useProjectReadModel' | ||||
|     | 'addonUsageMetrics'; | ||||
|     | 'addonUsageMetrics' | ||||
|     | 'onboardingMetrics'; | ||||
| 
 | ||||
| export type IFlags = Partial<{ [key in IFlagKey]: boolean | Variant }>; | ||||
| 
 | ||||
| @ -308,6 +309,10 @@ const flags: IFlags = { | ||||
|         process.env.UNLEASH_EXPERIMENTAL_ADDON_USAGE_METRICS, | ||||
|         false, | ||||
|     ), | ||||
|     onboardingMetrics: parseEnvVarBoolean( | ||||
|         process.env.UNLEASH_EXPERIMENTAL_ONBOARDING_METRICS, | ||||
|         false, | ||||
|     ), | ||||
| }; | ||||
| 
 | ||||
| export const defaultExperimentalOptions: IExperimentalOptions = { | ||||
|  | ||||
| @ -56,6 +56,7 @@ process.nextTick(async () => { | ||||
|                         projectListImprovements: true, | ||||
|                         useProjectReadModel: true, | ||||
|                         addonUsageMetrics: true, | ||||
|                         onboardingMetrics: true, | ||||
|                     }, | ||||
|                 }, | ||||
|                 authentication: { | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user