const decode = require('jsonwebtoken/decode') const app = require('./app') app.service('api', function($http) { window.api = this this.opts = { headers: {}, withCredentials: true } this.claims = {} this.postProcess = (res) => res.data this.get = (path, opts = {}) => $http.get(path, Object.assign({}, opts, this.opts)).then(this.postProcess) this.post = (path, data, opts = {}) => $http.post(path, data, Object.assign({}, opts, this.opts)).then(this.postProcess) this.put = (path, data, opts = {}) => $http.put(path, data, Object.assign({}, opts, this.opts)).then(this.postProcess) this.patch = (path, data, opts = {}) => $http.patch(path, data, Object.assign({}, opts, this.opts)).then(this.postProcess) this.delete = (path, opts = {}) => $http.delete(path, Object.assign({}, opts, this.opts)).then(this.postProcess) const setUser = (user, token) => { const decoded = decode(token) this.token = token this.user = user this.claims = decoded this.opts.headers.authentication = `Bearer ${token}` localStorage.setItem('token', token) localStorage.setItem('user', JSON.stringify(user)) } const clearUser = () => { this.token = null this.user = null this.claims = {} delete this.opts.headers.authentication localStorage.removeItem('token') localStorage.removeItem('user') } this.login = async data => { const res = await this.post('/api/auth/login', data) setUser(res.user, res.token) } this.logout = async () => { clearUser() } this.restore = () => { const token = localStorage.getItem('token') const userJson = localStorage.getItem('user') if (token && userJson) { try { const user = JSON.parse(userJson) setUser(user, token) } catch (err) { console.warn(`Unable to restore login:`, err) } } } this.restore() this.crud = (apiPrefix) => ({ list: () => this.get(apiPrefix), create: data => this.post(apiPrefix, data), read: id => this.get(`${apiPrefix}/${id}`), update: (id, data) => this.patch(`${apiPrefix}/${id}`, data), delete: (id) => this.delete(`${apiPrefix}/${id}`), trash: () => this.get(`${apiPrefix}/trash`), undelete: (id) => this.delete(`${apiPrefix}/trash/${id}`), autocomplete: (searchText) => this.get(apiPrefix, { params: { q: searchText } }), lookup: (ids) => this.get(apiPrefix, { params: { ids: ids.join(',')}}) }) })