Skip to content
This repository has been archived by the owner on Nov 29, 2021. It is now read-only.

Commit

Permalink
feat: finish loginStatistics
Browse files Browse the repository at this point in the history
  • Loading branch information
YanceyOfficial committed Apr 3, 2020
1 parent d6f77a8 commit 69e6536
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 7 deletions.
15 changes: 15 additions & 0 deletions schema.gql
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ type BestAlbumModel {
updatedAt: DateTime!
}

type Browser {
name: String!
version: String!
major: String!
}

input ChangePasswordInput {
oldPassword: String!
newPassword: String!
Expand Down Expand Up @@ -120,6 +126,9 @@ type IPModel {
latitude: Float!
longitude: Float!
location: Location!
browser: Browser!
os: OS!
loginTime: String!
}

type Language {
Expand Down Expand Up @@ -203,6 +212,11 @@ type OpenSourceModel {
updatedAt: DateTime!
}

type OS {
name: String!
version: String!
}

type PlayerModel {
_id: ID!
title: String!
Expand Down Expand Up @@ -392,6 +406,7 @@ type UserModel {
isTOTP: Boolean!
totpSecret: String!
recoveryCodes: [String!]!
loginStatistics: [IPModel!]!
createdAt: DateTime!
updatedAt: DateTime!
}
Expand Down
28 changes: 21 additions & 7 deletions src/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import { Injectable, HttpService } from '@nestjs/common'
import { ForbiddenError, AuthenticationError } from 'apollo-server-express'
import { JwtService } from '@nestjs/jwt'
import { Request } from 'express'
import uaParser from 'ua-parser-js'
import { UAParser } from 'ua-parser-js'
import requestIP from 'request-ip'
import speakeasy from 'speakeasy'
import { map } from 'rxjs/operators'
import { IPModel, Browser, OS } from './models/ip-model'
import { ConfigService } from '../config/config.service'
import { UsersService } from '../users/users.service'
import { Roles, User } from '../users/interfaces/user.interface'
Expand Down Expand Up @@ -154,21 +155,34 @@ export class AuthService {
const { sub: userId } = decodeJwt(token)

const network = {
// ip: requestIP.getClientIp(req),
ip: '123.118.72.95',
ip: requestIP.getClientIp(req),
userAgent,
}

const ipInfo = this.httpService
.get(`${IP_STACK_URL}${network.ip}`, {
const uaParser = new UAParser(userAgent)

const ipInfo = await this.httpService
.get<IPModel>(`${IP_STACK_URL}${network.ip}`, {
params: {
access_key: IP_STACK_ACCESS_KEY,
},
})
.pipe(map((response) => response.data))
.toPromise()

const loginInfo = {
...ipInfo,
browser: uaParser.getBrowser(),
os: uaParser.getOS(),
loginTime: new Date().toISOString(),
}

return ipInfo
const user = await this.usersService.findOneById(userId)
await this.usersService.updateUser({
id: userId,
loginStatistics: [...user.loginStatistics, loginInfo],
})

// const user = await this.usersService.findOneById(userId)
return loginInfo
}
}
30 changes: 30 additions & 0 deletions src/auth/models/ip-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,27 @@ export class Location {
public readonly is_eu: boolean
}

@ObjectType()
export class Browser {
@Field()
public readonly name: string

@Field()
public readonly version: string

@Field()
public readonly major: string
}

@ObjectType()
export class OS {
@Field()
public readonly name: string

@Field()
public readonly version: string
}

@ObjectType()
export class IPModel {
@Field()
Expand Down Expand Up @@ -78,4 +99,13 @@ export class IPModel {

@Field(() => Location)
public readonly location: Location

@Field(() => Browser)
public readonly browser: Browser

@Field(() => OS)
public readonly os: OS

@Field()
public readonly loginTime: string
}
4 changes: 4 additions & 0 deletions src/users/dtos/update-user.input.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { InputType, Field } from '@nestjs/graphql'
import { IsNotEmpty, IsUUID } from 'class-validator'
import { IPModel } from '../../auth/models/ip-model'

@InputType()
export class UpdateUserInput {
Expand All @@ -19,4 +20,7 @@ export class UpdateUserInput {

@Field({ nullable: true })
public readonly password?: string

@Field({ nullable: true })
public readonly loginStatistics?: IPModel[]
}
2 changes: 2 additions & 0 deletions src/users/interfaces/user.interface.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Document } from 'mongoose'
import { IPModel } from '../../auth/models/ip-model'

export enum TwoFactorAuthentications {
TOTP,
Expand All @@ -23,6 +24,7 @@ export interface User extends Document {
isTOTP: boolean
totpSecret: string
recoveryCodes: string[]
loginStatistics: IPModel[]
createdAt: Date
updatedAt: Date
isValidPassword(plainPwd: string, encryptedPwd: string): boolean
Expand Down
4 changes: 4 additions & 0 deletions src/users/models/User.model.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Field, ID, ObjectType } from '@nestjs/graphql'
import { IPModel } from '../../auth/models/ip-model'

@ObjectType()
export class UserModel {
Expand Down Expand Up @@ -35,6 +36,9 @@ export class UserModel {
@Field(() => [String])
public readonly recoveryCodes: string[]

@Field(() => [IPModel])
public readonly loginStatistics: IPModel[]

@Field()
public readonly createdAt: Date

Expand Down
5 changes: 5 additions & 0 deletions src/users/schemas/users.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ export const UserSchema = new mongoose.Schema(
type: Array,
required: false,
},
loginStatistics: {
type: Array,
required: false,
default: [],
},
},
{
collection: 'user',
Expand Down

0 comments on commit 69e6536

Please sign in to comment.