197 lines
4.9 KiB
JavaScript

class Network {
/**
* Load envelope json data
* @param {any} envelopeKey
*/
async getEnvelope(envelopeKey) {
return this.getRequest(`/api/envelope/${envelopeKey}`)
.then(this.wrapJsonResponse.bind(this))
}
/**
* Save signature data to server
* @param {any} envelopeKey
* @param {any} documentId
* @param {any} json
*/
async postEnvelope(envelopeKey, documentId, json) {
return this.postRequest(`/api/envelope/${envelopeKey}?index=${documentId}`, json)
.then(this.wrapJsonResponse.bind(this))
}
/**
* Load document binary data
* @param {any} envelopeKey
* @param {any} documentId
*/
async getDocument(envelopeKey, documentId) {
return this.getRequest(`/api/document/${envelopeKey}?index=${documentId}`)
.then(this.wrapBinaryResponse.bind(this))
}
/**
* Tell the server that document has been seen
* @param {any} envelopeKey
*/
async openDocument(envelopeKey) {
return this.postRequest(`/api/document/${envelopeKey}`, {})
.then(this.wrapJsonResponse.bind(this))
}
/**
* Add CSRF Token to request headers
* @param {any} options
* @returns
*/
withCSRFToken(options) {
const token = getCSRFToken
let headers = options.headers
options.headers = {
...headers,
...token
}
return options
}
/**
* Fetches CSRF Token from page
* @returns
*/
getCSRFToken() {
const token = document.getElementsByName('__RequestVerificationToken')[0].value
return { 'X-XSRF-TOKEN': token }
}
/**
* Creates a GET HTTP request to `url`
* @param {any} url
*/
getRequest(url, body) {
const token = this.getCSRFToken()
const options = {
credentials: 'include',
method: 'GET',
headers: {
...token
}
}
if (body !== undefined) {
options.body = JSON.stringify(body);
}
return fetch(url, options)
}
/**
* Creates a POST HTTP request for url
* @param {any} url
* @param {any} json
* @returns
*/
postRequest(url, json) {
const token = this.getCSRFToken()
const options = {
credentials: 'include',
method: 'POST',
headers: {
...token,
'Content-Type': 'application/json; charset=utf-8'
},
body: JSON.stringify(json)
}
return fetch(url, options)
}
/**
* Reads and wraps a json response
* @param {any} response
* @returns
*/
async wrapJsonResponse(response) {
return await this.wrapResponse(
response,
async (res) => await res.json())
}
/**
* Reads and wraps a binary response
* @param {any} response
* @returns
*/
async wrapBinaryResponse(response) {
return await this.wrapResponse(
response,
async (res) => await res.arrayBuffer())
}
/**
* Wraps a fetch response depending on status code
* @param {any} response
* @param {any} responseHandler
* @returns
*/
async wrapResponse(response, responseHandler) {
let wrappedResponse
if (response.status === 200) {
const data = await responseHandler(response)
wrappedResponse = new WrappedResponse(data, null)
} else if (response.status === 403) {
const error = await response.json()
wrappedResponse = new WrappedResponse(null, error)
} else {
wrappedResponse = new WrappedResponse(null, null)
}
return wrappedResponse
}
}
class WrappedResponse {
constructor(data, error) {
this.data = data
this.error = error
this.fatal = (data === null && error === null)
}
}
async function setLangAsync(language, flagCode) {
document.getElementById('selectedFlag').className = 'fi ' + flagCode + ' me-2';
await fetch(`/lang/${language}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
}
})
}
async function setLanguage(language) {
const hasLang = await fetch('/lang', {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
})
.then(res => res.json())
.then(langs => langs.includes(language))
.catch(err => false);
if(hasLang)
return await fetch(`/lang/${language}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' }
})
.then(response => {
if (response.redirected)
window.location.href = response.url;
else if (!response.ok)
return Promise.reject('Failed to set language');
});
}