{"size": 1243, "ext": "js", "max_stars_repo_path": "server/src/services/session.js", "max_stars_repo_name": "MediaNetwork/media-on-demand-webapp", "max_stars_repo_stars_event_min_datetime": null, "max_stars_repo_stars_event_max_datetime": null, "max_issues_repo_path": "server/src/services/session.js", "max_issues_repo_name": "MediaNetwork/media-on-demand-webapp", "max_issues_repo_issues_event_min_datetime": "2018-06-19T02:29:16.000Z", "max_issues_repo_issues_event_max_datetime": "2018-11-14T03:50:50.000Z", "max_forks_repo_path": "server/src/services/session.js", "max_forks_repo_name": "MediaNetwork/media-on-demand-webapp", "max_forks_repo_forks_event_min_datetime": "2018-06-01T06:53:46.000Z", "max_forks_repo_forks_event_max_datetime": "2018-09-19T17:33:07.000Z"}
{"max_stars_count": null, "max_issues_count": 5, "max_forks_count": 2, "avg_line_length": 21.8070175439, "max_line_length": 87, "alphanum_fraction": 0.6572807723}
import jwt from 'jsonwebtoken'
import ms from 'ms'

import config from 'infrastructure/config'
import createAccountService from 'services/account'
import ApiService from 'services/api'

class SessionService extends ApiService {
  issueJWT(account) {
    const payload = {
      identifier: account.identifier
    }

    const token = jwt.sign(payload, config.session.secret, {
      expiresIn: config.session.ttl
    })

    return {
      token,
      ttl: ms(config.session.ttl),
      account
    }
  }

  async verify(token, { refresh } = { refresh: false }) {
    const decoded = jwt.verify(token, config.session.secret)

    const accountService = createAccountService()
    const account = await accountService.get(decoded.identifier)

    if (!account) {
      throw new Error('Invalid or expired JWT')
    }

    return refresh ? this.issueJWT(account) : {
      token,
      ttl: ms(config.session.ttl),
      account
    }
  }

  async create({ email, password }) {
    const sessionAccount = await this.callApi('post', '/sessions', { email, password })

    if (!sessionAccount) {
      throw new Error('Invalid email')
    }

    return this.issueJWT(sessionAccount)
  }

}

export default () => {
  return new SessionService()
}
