Newer
Older
import ClientOAuth2 from 'client-oauth2';
import { apiUrl, ownUrl, oAuthID } from 'networkConfig';
import * as localStorage from './localStorage';
import config from './resourceConfig.json';
// Object which stores the current login-state
const APISession = {
authenticated: false,
token: '',
const amivapi = axios.create({
baseURL: apiUrl,
headers: { 'Content-Type': 'application/json' },
});
// OAuth Handler
const oauth = new ClientOAuth2({
clientId: oAuthID,
authorizationUri: `${apiUrl}/oauth`,
redirectUri: `${ownUrl}/oauthcallback`,
APISession.authenticated = false;
APISession.token = '';
localStorage.remove('token');
window.location.replace(oauth.token.getUri());
function checkToken(token) {
// check if a token is still valid
return new Promise((resolve, reject) => {
headers: { 'Content-Type': 'application/json', Authorization: token },
if (response.status === 200) resolve(response.data);
else reject();
}).catch(reject);
});
}
export function checkAuthenticated() {
// return a promise that resolves always, with a bool that shows whether
// the user is authenticated
return new Promise((resolve) => {
if (APISession.authenticated) resolve();
else {
// let's see if we have a stored token
const token = localStorage.get('token');
console.log(`found this token: ${token}`);
if (token !== '') {
// check of token is valid
APISession.token = token;
APISession.authenticated = true;
resolve();
}).catch(resetSession);
} else resetSession();
}
});
}
export function getSession() {
// Promise resolves with authenticated axios-session or fails
return new Promise((resolve) => {
checkAuthenticated().then(() => {
const authenticatedSession = axios.create({
baseURL: apiUrl,
headers: {
'Content-Type': 'application/json',
Authorization: APISession.token,
},
});
resolve(authenticatedSession);
}).catch(resetSession);
export function deleteSession() {
return new Promise((resolve, reject) => {
getSession().then((api) => {
api.get(`sessions/${APISession.token}`).then((response) => {
if (response.status === 200) {
api.delete(
`sessions/${response.data._id}`,
{ headers: { 'If-Match': response.data._etag } },
).then((deleteResponse) => {
if (deleteResponse.status === 204) {
resetSession();
resolve(deleteResponse.data);
} else reject();
}).catch(reject);
} else reject();
}).catch(reject);
});
});
}
export function getCurrentUser() {
return APISession.userID;
}
/* Handler to get and manipulate resource items
*
* resource: String of the resource to accessm e,g, 'events'
* searchKeys: keys in the resource item on which to perform search, i.e.
* when search is set, any of these keys may match the search pattern
* E.g. for an event, this may be ['title_de', 'title_en', 'location']
*/
constructor(resource, searchKeys = false) {
// special case for users
if (resource === 'users') this.searchKeys = ['firstname', 'lastname', 'nethz'];
else this.searchKeys = searchKeys || config[resource].searchKeys;

Hermann
committed
this.noPatchKeys = [
'_etag', '_id', '_created', '_links', '_updated',
...(config[resource].notPatchableKeys || [])];
checkAuthenticated().then(() => {
// again special case for users
if (resource === 'users' && APISession.isUserAdmin) {
this.searchKeys = searchKeys || config[resource].searchKeys;
}
});
/*
* query is a dictionary of different queries
* Additional to anything specified from eve
* (http://python-eve.org/features.html#filtering)
* we support the key `search`, which is translated into a `where` filter
*/
buildQuerystring(query) {
const queryKeys = Object.keys(query);
if (queryKeys.length === 0) return '';
const fullQuery = {};
if ('search' in query && query.search && query.search.length > 0 && this.searchKeys) {
// translate search into where, we just look if any field contains search
// The search-string may match any of the keys in the object specified in the
// constructor
const searchQuery = {
$or: this.searchKeys.map((key) => {
const fieldQuery = {};
fieldQuery[key] = {
$regex: `${query.search}`,
return fieldQuery;
}),
};
// if there exists already a where-filter, AND them together
if ('where' in query) {
fullQuery.where = JSON.stringify({ $and: [searchQuery, query.where] });
} else {
fullQuery.where = JSON.stringify(searchQuery);
}
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
}
// add all other keys
queryKeys.filter(key => (key !== 'where' && key !== 'search'))
.forEach((key) => { fullQuery[key] = JSON.stringify(query[key]); });
// now we can acutally build the query string
return `?${m.buildQueryString(fullQuery)}`;
}
get(query) {
return new Promise((resolve, reject) => {
getSession().then((api) => {
let url = this.resource;
if (Object.keys(query).length > 0) url += this.buildQuerystring(query);
api.get(url).then((response) => {
if (response.status >= 400) {
resetSession();
reject();
} else {
resolve(response.data);
}
}).catch((e) => {
console.log(e);
reject(e);
});
});
});
}
getItem(id, embedded = {}) {
return new Promise((resolve, reject) => {
getSession().then((api) => {
let url = `${this.resource}/${id}`;
// in case embedded is specified, append to url
if (Object.keys(embedded).length > 0) {
url += `?${m.buildQueryString({
})}`;
}
api.get(url).then((response) => {
if (response.status >= 400) {
resetSession();
reject();
} else {
resolve(response.data);
}
}).catch((e) => {
console.log(e);
reject(e);
});
});
});
}
post(item) {
return new Promise((resolve, reject) => {
getSession().then((api) => {
api.post(this.resource, item).then((response) => {
if (response.code === 201) {
resolve({});
} else if (response.status === 422) {
reject(response.data);
} else if (response.status >= 400) {
resetSession();
reject();
} else {
resolve(response.data);
}
}).catch((e) => {
console.log(e);
reject(e);
});
});
});
}
return new Promise((resolve, reject) => {
getSession().then((api) => {
// not all fields in the item can be patched. We filter out the fields
// we are allowed to send
let submitData;
if (formData) {
submitData = new FormData();
Object.keys(item).forEach((key) => {
if (!this.noPatchKeys.includes(key)) {
submitData.append(key, item[key]);
}
});
} else {
submitData = Object.assign({}, item);
this.noPatchKeys.forEach((key) => { delete submitData[key]; });
}

Hermann
committed
api.patch(`${this.resource}/${item._id}`, submitData, {
headers: { 'If-Match': item._etag },
}).then((response) => {
if (response.status === 422) {
reject(response.data);
} else if (response.status >= 400) {
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
resetSession();
reject();
} else {
resolve(response.data);
}
}).catch((e) => {
console.log(e);
reject(e);
});
});
});
}
delete(item) {
return new Promise((resolve, reject) => {
getSession().then((api) => {
api.delete(`${this.resource}/${item._id}`, {
headers: { 'If-Match': item._etag },
}).then((response) => {
if (response.status >= 400) {
resetSession();
reject();
} else {
resolve();
}
}).catch((e) => {
console.log(e);
reject(e);
});
});
});
}
}
export class OauthRedirect {
view() {
oauth.token.getToken(m.route.get()).then((response) => {
APISession.authenticated = true;
APISession.token = response.accessToken;
localStorage.set('token', response.accessToken);
amivapi.get(`sessions/${response.accessToken}`, {
headers: { 'Content-Type': 'application/json', Authorization: APISession.token },
}).then((response) => {
console.log(response);
APISession.userID = response.data.user;
m.route.set('/');
}).catch(() => {
resetSession();
});