api-service.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. const decode = require('jsonwebtoken/decode')
  2. const app = require('./app')
  3. app.service('api', function($http, $location, $mdToast) {
  4. window.api = this
  5. this.opts = {
  6. headers: {},
  7. withCredentials: true
  8. }
  9. this.claims = {}
  10. this.postProcess = (res) => res.data
  11. this.get = (path, opts = {}) => $http.get(path, Object.assign({}, opts, this.opts)).then(this.postProcess)
  12. this.post = (path, data, opts = {}) => $http.post(path, data, Object.assign({}, opts, this.opts)).then(this.postProcess)
  13. this.put = (path, data, opts = {}) => $http.put(path, data, Object.assign({}, opts, this.opts)).then(this.postProcess)
  14. this.patch = (path, data, opts = {}) => $http.patch(path, data, Object.assign({}, opts, this.opts)).then(this.postProcess)
  15. this.delete = (path, opts = {}) => $http.delete(path, Object.assign({}, opts, this.opts)).then(this.postProcess)
  16. const setUser = (user, token) => {
  17. const decoded = decode(token)
  18. this.token = token
  19. this.user = user
  20. this.claims = decoded
  21. this.opts.headers.authentication = `Bearer ${token}`
  22. localStorage.setItem('token', token)
  23. localStorage.setItem('user', JSON.stringify(user))
  24. }
  25. const clearUser = () => {
  26. this.token = null
  27. this.user = null
  28. this.claims = {}
  29. delete this.opts.headers.authentication
  30. localStorage.removeItem('token')
  31. localStorage.removeItem('user')
  32. }
  33. this.login = async data => {
  34. const res = await this.post('/api/auth/login', data)
  35. setUser(res.user, res.token)
  36. }
  37. this.logout = async () => {
  38. clearUser()
  39. }
  40. this.renew = async () => {
  41. console.info('Renewing session...')
  42. const res = await this.post('/api/auth/renew', {})
  43. setUser(res.user, res.token)
  44. }
  45. this.checkRenew = async () => {
  46. if (!this.user) {
  47. throw new Error('Not logged in')
  48. }
  49. try {
  50. await this.renew()
  51. } catch (e) {
  52. clearUser()
  53. throw e
  54. }
  55. }
  56. this.restore = () => {
  57. const token = localStorage.getItem('token')
  58. const userJson = localStorage.getItem('user')
  59. if (token && userJson) {
  60. try {
  61. const user = JSON.parse(userJson)
  62. setUser(user, token)
  63. } catch (err) {
  64. console.warn(`Unable to restore login:`, err)
  65. }
  66. }
  67. }
  68. this.restore()
  69. const renewTimer = () => {
  70. if (this.user) {
  71. this.renew().catch(err => {
  72. console.warn('Login session could not be renewed:', err)
  73. $mdToast.show(
  74. $mdToast.simple()
  75. .textContent(`You are not logged in: ${err.statusText || err.message}.`)
  76. .action('Return to login page')
  77. .hideDelay(60000)
  78. .position('top middle')
  79. .highlightAction(true)
  80. .highlightClass('md-warn')
  81. )
  82. .then(res => {
  83. if (res === 'ok') {
  84. clearUser()
  85. $location.url('/login')
  86. }
  87. })
  88. })
  89. }
  90. }
  91. setInterval(renewTimer, 15000)
  92. renewTimer()
  93. this.crud = (apiPrefix) => ({
  94. list: () => this.get(apiPrefix),
  95. create: data => this.post(apiPrefix, data),
  96. read: id => this.get(`${apiPrefix}/${id}`),
  97. update: (id, data) => this.patch(`${apiPrefix}/${id}`, data),
  98. delete: (id) => this.delete(`${apiPrefix}/${id}`),
  99. trash: () => this.get(`${apiPrefix}/trash`),
  100. undelete: (id) => this.delete(`${apiPrefix}/trash/${id}`),
  101. autocomplete: (searchText) => this.get(apiPrefix, { params: { q: searchText } }),
  102. lookup: (ids) => this.get(apiPrefix, { params: { ids: ids.join(',')}})
  103. })
  104. })