Skip to content

Commit

Permalink
[Bugfix] Bug fixes
Browse files Browse the repository at this point in the history
Removing the subscribe feature from application.
  • Loading branch information
lucasrochagit committed Feb 4, 2020
1 parent e2c0df1 commit b982291
Show file tree
Hide file tree
Showing 14 changed files with 5 additions and 504 deletions.
10 changes: 0 additions & 10 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -86,16 +86,6 @@ FITBIT_CLIENT_ID=CIENT_ID_HERE
# default value: CIENT_SECRET_HERE
FITBIT_CLIENT_SECRET=CIENT_SECRET_HERE

# FITBIT_CLIENT_SUBSCRIBER: Client Subscriber code for automatically get notification from new
# sync data.
# default value: CLIENT_SUBSCRIBER_HERE
FITBIT_CLIENT_SUBSCRIBER=CLIENT_SUBSCRIBER_HERE

# FITBIT_SUBSCRIBER_ID: Customer Subscriber ID, used to manage the subscriber who will
# receive notification of a user resource.
# default value: SUBSCRIBER_ID_HERE
FITBIT_SUBSCRIBER_ID=SUBSCRIBER_ID_HERE

#################################################################################################
################################# DATA SYNC ENVIRONMENT SETUP ###################################
#################################################################################################
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { DIContainer } from '../../../di/di'
import { ValidationException } from '../../domain/exception/validation.exception'
import { IUserAuthDataRepository } from '../../port/user.auth.data.repository.interface'
import { Query } from '../../../infrastructure/repository/query/query'
import { IFitbitDataRepository } from '../../port/fitbit.auth.data.repository.interface'
import { UserAuthData } from '../../domain/model/user.auth.data'
import { IResourceRepository } from '../../port/resource.repository.interface'

Expand All @@ -19,8 +18,6 @@ export const userDeleteEventHandler = async (event: any) => {
const logger: ILogger = DIContainer.get<ILogger>(Identifier.LOGGER)
const userAuthDataRepo: IUserAuthDataRepository =
DIContainer.get<IUserAuthDataRepository>(Identifier.USER_AUTH_DATA_REPOSITORY)
const fitbitAuthDataRepo: IFitbitDataRepository =
DIContainer.get<IFitbitDataRepository>(Identifier.FITBIT_DATA_REPOSITORY)
const resourceRepo: IResourceRepository = DIContainer.get<IResourceRepository>(Identifier.RESOURCE_REPOSITORY)

try {
Expand All @@ -37,21 +34,6 @@ export const userDeleteEventHandler = async (event: any) => {
const query: Query = new Query().fromJSON({ filters: { user_id: childId } })
const userAuthData: UserAuthData = await userAuthDataRepo.findOne(query)
if (userAuthData) {
if (userAuthData.fitbit!.scope!) {
const payload: any = await fitbitAuthDataRepo.getTokenPayload(userAuthData.fitbit!.access_token!)
if (payload || payload.scopes) {
const scopes: Array<string> = payload.scopes.split(' ')
if (scopes.includes('rwei')) { // Scope reference from fitbit to weight data is rwei
await fitbitAuthDataRepo.unsubscribeUserEvent(userAuthData.fitbit!, 'body', 'BODY')
}
if (scopes.includes('ract')) { // Scope reference from fitbit to activity data is ract
await fitbitAuthDataRepo.unsubscribeUserEvent(userAuthData.fitbit!, 'activities', 'ACTIVITIES')
}
if (scopes.includes('rsle')) { // Scope reference from fitbit to sleep data is rsle
await fitbitAuthDataRepo.unsubscribeUserEvent(userAuthData.fitbit!, 'sleep', 'SLEEP')
}
}
}
await userAuthDataRepo.deleteByQuery(query)
await resourceRepo.deleteByQuery(query)
// 3. If got here, it's because the action was successful.
Expand Down
6 changes: 0 additions & 6 deletions src/application/port/fitbit.auth.data.repository.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,5 @@ export interface IFitbitDataRepository {

syncFitbitData(data: FitbitAuthData, userId: string): Promise<DataSync>

syncLastFitbitData(data: FitbitAuthData, userId: string, type: string, date: string): Promise<void>

subscribeUserEvent(data: FitbitAuthData, resource: string, subscriptionId: string): Promise<void>

unsubscribeUserEvent(data: FitbitAuthData, resource: string, subscriptionId: string): Promise<void>

getTokenPayload(token: string): Promise<any>
}
6 changes: 0 additions & 6 deletions src/application/port/fitbit.client.repository.interface.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
import { FitbitAuthData } from '../domain/model/fitbit.auth.data'

export interface IFitbitClientRepository {
revokeToken(accessToken: string): Promise<boolean>

refreshToken(accessToken: string, refreshToken: string, expiresIn?: number): Promise<any>

getDataFromPath(path: string, accessToken: string): Promise<any>

subscribeUserEvent(data: FitbitAuthData, resource: string, subscriptionId: string): Promise<void>

unsubscribeUserEvent(data: FitbitAuthData, resource: string, subscriptionId: string): Promise<void>
}
2 changes: 0 additions & 2 deletions src/application/port/user.auth.data.service.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,4 @@ export interface IUserAuthDataService extends IService<UserAuthData> {
revokeFitbitAccessToken(userId: string): Promise<void>

syncFitbitDataFromUser(userId: string): Promise<DataSync>

syncLastFitbitUserData(fitbitUserId: string, type: string, date: string): Promise<void>
}
113 changes: 4 additions & 109 deletions src/application/service/user.auth.data.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,9 @@ export class UserAuthDataService implements IUserAuthDataService {
try {
const authData: UserAuthData = await this.manageFitbitAuthData(item)
CreateUserAuthDataValidator.validate(item)
let result: UserAuthData = new UserAuthData()
let result: UserAuthData

authData.fitbit!.status = 'valid_token'
await this.subscribeFitbitEvents(item)

const alreadySaved: UserAuthData = await this._userAuthDataRepo
.findOne(new Query().fromJSON({ filters: { user_id: authData.user_id! } }))
Expand Down Expand Up @@ -94,16 +93,13 @@ export class UserAuthDataService implements IUserAuthDataService {
return resolve()
}

// 2. Unsubscribe from Fitbit events.
await this.unsubscribeFitbitEvents(authData)

// 3. Revokes Fitbit access token.
// 2. Revokes Fitbit access token.

const isRevoked: boolean = await this._fitbitAuthDataRepo.revokeToken(authData.fitbit.access_token)
// 4. Remove Fitbit authorization data from local database.
// 3. Remove Fitbit authorization data from local database.
const isRemoved: boolean = await this._fitbitAuthDataRepo.removeFitbitAuthData(userId)

// 5. Publish the Fitbit revoke event on the bus.
// 4. Publish the Fitbit revoke event on the bus.
if (isRevoked && isRemoved) {
this._eventBus.bus
.pubFitbitRevoke({ child_id: userId })
Expand Down Expand Up @@ -191,107 +187,6 @@ export class UserAuthDataService implements IUserAuthDataService {
})
}

public async syncLastFitbitUserData(fitbitUserId: string, type: string, date: string): Promise<void> {
try {
const authData: UserAuthData =
await this._userAuthDataRepo
.findOne(new Query().fromJSON({ filters: { 'fitbit.user_id': fitbitUserId } }))
if (!authData) return await Promise.resolve()
this.syncLastFitbitData(authData.fitbit!, authData.user_id!, type, date)
.then()
.catch(err => this._logger.error(`The resource ${type} from ${authData.user_id} could note be sync: ` +
err.message))
return await Promise.resolve()
} catch (err) {
return await Promise.reject(err)
}
}

private async syncLastFitbitData(data: FitbitAuthData, userId: string, type: string, date: string): Promise<void> {
try {
VerifyFitbitAuthValidator.validate(data)
await this._fitbitAuthDataRepo.syncLastFitbitData(data, userId, type, date)
return Promise.resolve()
} catch (err) {
if (err.type) {
if (err.type === 'expired_token') {
try {
const newToken: FitbitAuthData =
await this._fitbitAuthDataRepo.refreshToken(userId, data.access_token!, data.refresh_token!)
this.syncLastFitbitData(newToken, userId, type, date)
.then()
.catch(err => {
this.updateTokenStatus(userId, err.type)
this.publishFitbitAuthError(err, userId)
return Promise.reject(err)
})
} catch (err) {
if (err.type !== 'system') this.updateTokenStatus(userId, err.type)
this.publishFitbitAuthError(err, userId)
return Promise.reject(err)
}
} else if (err.type === 'client_error') {
try {
await this.syncFitbitData(data, userId)
} catch (err) {
return Promise.reject(err)
}
} else {
if (err.type !== 'system') this.updateTokenStatus(userId, err.type)
this.publishFitbitAuthError(err, userId)
return Promise.reject(err)
}
} else {
return await Promise.reject(err)
}
}
}

private async subscribeFitbitEvents(data: UserAuthData): Promise<void> {
return new Promise<void>(async (resolve, reject) => {
try {
if (!data || !data.fitbit || !data.fitbit.scope) return

const scopes: Array<string> = data.fitbit.scope.split(' ')

if (scopes.includes('rwei')) { // Scope reference from fitbit to weight data is rwei
await this._fitbitAuthDataRepo.subscribeUserEvent(data.fitbit!, 'body', 'BODY')
}
if (scopes.includes('ract')) { // Scope reference from fitbit to activity data is ract
await this._fitbitAuthDataRepo.subscribeUserEvent(data.fitbit!, 'activities', 'ACTIVITIES')
}
if (scopes.includes('rsle')) { // Scope reference from fitbit to sleep data is rsle
await this._fitbitAuthDataRepo.subscribeUserEvent(data.fitbit!, 'sleep', 'SLEEP')
}
return resolve()
} catch (err) {
return reject(err)
}
})
}

private async unsubscribeFitbitEvents(data: UserAuthData): Promise<void> {
return new Promise(async (resolve, reject) => {
try {
if (!data || !data.fitbit || !data.fitbit.scope) return

const scopes: Array<string> = data.fitbit.scope.split(' ')
if (scopes.includes('rwei')) { // Scope reference from fitbit to weight data is rwei
await this._fitbitAuthDataRepo.unsubscribeUserEvent(data.fitbit!, 'body', 'BODY')
}
if (scopes.includes('ract')) { // Scope reference from fitbit to activity data is ract
await this._fitbitAuthDataRepo.unsubscribeUserEvent(data.fitbit!, 'activities', 'ACTIVITIES')
}
if (scopes.includes('rsle')) { // Scope reference from fitbit to sleep data is rsle
await this._fitbitAuthDataRepo.unsubscribeUserEvent(data.fitbit!, 'sleep', 'SLEEP')
}
return resolve()
} catch (err) {
return reject(err)
}
})
}

private async manageFitbitAuthData(data: UserAuthData): Promise<UserAuthData> {
return new Promise(async (resolve, reject) => {
try {
Expand Down
3 changes: 0 additions & 3 deletions src/di/di.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import { IEntityMapper } from '../infrastructure/port/entity.mapper.interface'
import { UserAuthDataService } from '../application/service/user.auth.data.service'
import { IBackgroundTask } from '../application/port/background.task.interface'
import { SyncFitbitDataTask } from '../background/task/sync.fitbit.data.task'
import { FitbitSubscriberController } from '../ui/controllers/fitbit.subscriber.controller'
import { FitbitAuthDataEntityMapper } from '../infrastructure/entity/mapper/fitbit.auth.data.entity.mapper'
import { UserAuthData } from '../application/domain/model/user.auth.data'
import { UserAuthDataEntity } from '../infrastructure/entity/user.auth.data.entity'
Expand Down Expand Up @@ -76,8 +75,6 @@ class IoC {
// Controllers
this._container.bind<HomeController>(Identifier.HOME_CONTROLLER).to(HomeController).inSingletonScope()
this._container.bind<FitbitController>(Identifier.FITBIT_CONTROLLER).to(FitbitController).inSingletonScope()
this._container.bind<FitbitSubscriberController>(Identifier.FITBIT_SUBSCRIBER_CONTROLLER)
.to(FitbitSubscriberController).inSingletonScope()
this._container.bind<UserFitbitAuthController>(Identifier.USER_FITBIT_AUTH_CONTROLLER)
.to(UserFitbitAuthController).inSingletonScope()
this._container.bind<UserFitbitSyncController>(Identifier.USER_FITBIT_SYNC_CONTROLLER)
Expand Down
1 change: 0 additions & 1 deletion src/di/identifiers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ export abstract class Identifier {

// Controllers
public static readonly HOME_CONTROLLER: any = Symbol.for('HomeController')
public static readonly FITBIT_SUBSCRIBER_CONTROLLER: any = Symbol.for('FitbitSubscriberController')
public static readonly FITBIT_CONTROLLER: any = Symbol.for('FitbitController')
public static readonly USER_FITBIT_AUTH_CONTROLLER: any = Symbol.for('UserFitbitAuthController')
public static readonly USER_FITBIT_SYNC_CONTROLLER: any = Symbol.for('UserFitbitSyncController')
Expand Down
37 changes: 0 additions & 37 deletions src/infrastructure/repository/fitbit.client.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,43 +47,6 @@ export class FitbitClientRepository implements IFitbitClientRepository {
})
}

public async subscribeUserEvent(data: FitbitAuthData, resource: string, subscriptionId: string): Promise<void> {
return new Promise<void>((resolve, reject) => {
this.fitbit_client
.post(
`/${resource}/apiSubscriptions/${subscriptionId}-${data.user_id}.json`, // Path
data.access_token, // Access Token
null, // Form Data
null, // User Id
{ 'X-Fitbit-Subscriber-Id': process.env.FITBIT_SUBSCRIBER_ID } // Extra Header
)
.then(res => {
if (res[0].errors) {
return reject(this.fitbitClientErrorListener(res[0].errors[0]))
}
return resolve()
}).catch(err => reject(this.fitbitClientErrorListener(err)))
})
}

public async unsubscribeUserEvent(data: FitbitAuthData, resource: string, subscriptionId: string): Promise<void> {
return new Promise<void>((resolve, reject) => {
this.fitbit_client
.delete(
`/${resource}/apiSubscriptions/${subscriptionId}-${data.user_id}.json`, // Path
data.access_token, // Access Token
null, // User Id
{ 'X-Fitbit-Subscriber-Id': process.env.FITBIT_SUBSCRIBER_ID } // Extra Header
)
.then(res => {
if (res[0] && res[0].errors) {
return reject(this.fitbitClientErrorListener(res[0].errors[0]))
}
return resolve()
}).catch(err => reject(this.fitbitClientErrorListener(err)))
})
}

private fitbitClientErrorListener(err: any): OAuthException | FitbitClientException | undefined {
if (err.context) return new OAuthException(err.context.errors[0].errorType, err.context.errors[0].message)
else if (err.code === 'EAI_AGAIN') return new FitbitClientException('client_error', err.message)
Expand Down
Loading

0 comments on commit b982291

Please sign in to comment.