mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	feat: store first seen for users
This commit is contained in:
		
							parent
							
								
									515d49aefe
								
							
						
					
					
						commit
						c16bcbd6c5
					
				| @ -22,6 +22,7 @@ const USER_COLUMNS_PUBLIC = [ | |||||||
|     'email', |     'email', | ||||||
|     'image_url', |     'image_url', | ||||||
|     'seen_at', |     'seen_at', | ||||||
|  |     'first_seen_at', | ||||||
|     'is_service', |     'is_service', | ||||||
|     'scim_id', |     'scim_id', | ||||||
| ]; | ]; | ||||||
| @ -58,6 +59,7 @@ const rowToUser = (row) => { | |||||||
|         imageUrl: emptify(row.image_url), |         imageUrl: emptify(row.image_url), | ||||||
|         loginAttempts: row.login_attempts, |         loginAttempts: row.login_attempts, | ||||||
|         seenAt: row.seen_at, |         seenAt: row.seen_at, | ||||||
|  |         firstSeenAt: row.first_seen_at, | ||||||
|         createdAt: row.created_at, |         createdAt: row.created_at, | ||||||
|         isService: row.is_service, |         isService: row.is_service, | ||||||
|         scimId: row.scim_id, |         scimId: row.scim_id, | ||||||
| @ -233,6 +235,9 @@ class UserStore implements IUserStore { | |||||||
|         return this.buildSelectUser(user).update({ |         return this.buildSelectUser(user).update({ | ||||||
|             login_attempts: 0, |             login_attempts: 0, | ||||||
|             seen_at: new Date(), |             seen_at: new Date(), | ||||||
|  |             first_seen_at: this.db.raw('COALESCE(first_seen_at, ?)', [ | ||||||
|  |                 new Date(), | ||||||
|  |             ]), | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -11,6 +11,7 @@ export interface UserData { | |||||||
|     email?: string; |     email?: string; | ||||||
|     imageUrl?: string; |     imageUrl?: string; | ||||||
|     seenAt?: Date; |     seenAt?: Date; | ||||||
|  |     firstSeenAt?: Date; | ||||||
|     loginAttempts?: number; |     loginAttempts?: number; | ||||||
|     createdAt?: Date; |     createdAt?: Date; | ||||||
|     isService?: boolean; |     isService?: boolean; | ||||||
| @ -24,6 +25,7 @@ export interface IUser { | |||||||
|     email?: string; |     email?: string; | ||||||
|     inviteLink?: string; |     inviteLink?: string; | ||||||
|     seenAt?: Date; |     seenAt?: Date; | ||||||
|  |     firstSeenAt?: Date; | ||||||
|     createdAt?: Date; |     createdAt?: Date; | ||||||
|     permissions: string[]; |     permissions: string[]; | ||||||
|     loginAttempts?: number; |     loginAttempts?: number; | ||||||
| @ -75,6 +77,7 @@ export default class User implements IUser { | |||||||
|         username, |         username, | ||||||
|         imageUrl, |         imageUrl, | ||||||
|         seenAt, |         seenAt, | ||||||
|  |         firstSeenAt, | ||||||
|         loginAttempts, |         loginAttempts, | ||||||
|         createdAt, |         createdAt, | ||||||
|         isService, |         isService, | ||||||
| @ -93,6 +96,7 @@ export default class User implements IUser { | |||||||
|         this.email = email!; |         this.email = email!; | ||||||
|         this.imageUrl = imageUrl || this.generateImageUrl(); |         this.imageUrl = imageUrl || this.generateImageUrl(); | ||||||
|         this.seenAt = seenAt; |         this.seenAt = seenAt; | ||||||
|  |         this.firstSeenAt = firstSeenAt; | ||||||
|         this.loginAttempts = loginAttempts; |         this.loginAttempts = loginAttempts; | ||||||
|         this.createdAt = createdAt; |         this.createdAt = createdAt; | ||||||
|         this.accountType = isService ? 'Service Account' : 'User'; |         this.accountType = isService ? 'Service Account' : 'User'; | ||||||
|  | |||||||
| @ -108,6 +108,22 @@ test('should reset user after successful login', async () => { | |||||||
|     expect(storedUser.seenAt! >= user.seenAt!).toBe(true); |     expect(storedUser.seenAt! >= user.seenAt!).toBe(true); | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
|  | test('should track and keep first login', async () => { | ||||||
|  |     const store = stores.userStore; | ||||||
|  |     const user = await store.insert({ email: 'firstlogin@mail.com' }); | ||||||
|  |     await store.successfullyLogin(user); | ||||||
|  | 
 | ||||||
|  |     const storedUser = await store.getByQuery(user); | ||||||
|  | 
 | ||||||
|  |     expect(storedUser.seenAt).toEqual(storedUser.firstSeenAt); | ||||||
|  | 
 | ||||||
|  |     await store.successfullyLogin(user); | ||||||
|  | 
 | ||||||
|  |     const newLoginUser = await store.getByQuery(user); | ||||||
|  | 
 | ||||||
|  |     expect(storedUser.seenAt).toEqual(newLoginUser.firstSeenAt); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
| test('should only update specified fields on user', async () => { | test('should only update specified fields on user', async () => { | ||||||
|     const store = stores.userStore; |     const store = stores.userStore; | ||||||
|     const email = 'usertobeupdated@mail.com'; |     const email = 'usertobeupdated@mail.com'; | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user