2022-02-26 16:45:39 +00:00
|
|
|
import {
|
2022-04-01 12:41:45 +00:00
|
|
|
basicAuth,
|
|
|
|
encodeBase64,
|
2022-02-26 16:45:39 +00:00
|
|
|
fetchLinesIterator,
|
|
|
|
maybeWithBasicAuth,
|
|
|
|
topicShortUrl,
|
2022-03-03 21:52:07 +00:00
|
|
|
topicUrl,
|
|
|
|
topicUrlAuth,
|
|
|
|
topicUrlJsonPoll,
|
2022-04-03 16:39:52 +00:00
|
|
|
topicUrlJsonPollWithSince, userStatsUrl
|
2022-02-26 16:45:39 +00:00
|
|
|
} from "./utils";
|
2022-03-03 21:52:07 +00:00
|
|
|
import userManager from "./UserManager";
|
2022-02-23 04:22:30 +00:00
|
|
|
|
|
|
|
class Api {
|
2022-03-02 02:23:12 +00:00
|
|
|
async poll(baseUrl, topic, since) {
|
2022-03-03 21:52:07 +00:00
|
|
|
const user = await userManager.get(baseUrl);
|
2022-02-26 16:45:39 +00:00
|
|
|
const shortUrl = topicShortUrl(baseUrl, topic);
|
2022-02-28 00:29:17 +00:00
|
|
|
const url = (since)
|
2022-02-26 16:45:39 +00:00
|
|
|
? topicUrlJsonPollWithSince(baseUrl, topic, since)
|
|
|
|
: topicUrlJsonPoll(baseUrl, topic);
|
2022-02-23 04:22:30 +00:00
|
|
|
const messages = [];
|
2022-02-26 04:25:04 +00:00
|
|
|
const headers = maybeWithBasicAuth({}, user);
|
2022-02-23 04:22:30 +00:00
|
|
|
console.log(`[Api] Polling ${url}`);
|
2022-02-26 04:25:04 +00:00
|
|
|
for await (let line of fetchLinesIterator(url, headers)) {
|
2022-02-26 16:45:39 +00:00
|
|
|
console.log(`[Api, ${shortUrl}] Received message ${line}`);
|
2022-02-23 04:22:30 +00:00
|
|
|
messages.push(JSON.parse(line));
|
|
|
|
}
|
2022-02-24 19:53:45 +00:00
|
|
|
return messages;
|
2022-02-23 04:22:30 +00:00
|
|
|
}
|
|
|
|
|
2022-03-27 13:10:47 +00:00
|
|
|
async publish(baseUrl, topic, message, options) {
|
2022-03-03 21:52:07 +00:00
|
|
|
const user = await userManager.get(baseUrl);
|
2022-03-27 13:10:47 +00:00
|
|
|
console.log(`[Api] Publishing message to ${topicUrl(baseUrl, topic)}`);
|
2022-03-11 03:58:24 +00:00
|
|
|
const headers = {};
|
2022-03-27 13:10:47 +00:00
|
|
|
const body = {
|
|
|
|
topic: topic,
|
|
|
|
message: message,
|
|
|
|
...options
|
|
|
|
};
|
|
|
|
await fetch(baseUrl, {
|
2022-02-23 04:22:30 +00:00
|
|
|
method: 'PUT',
|
2022-03-27 13:10:47 +00:00
|
|
|
body: JSON.stringify(body),
|
2022-03-11 03:58:24 +00:00
|
|
|
headers: maybeWithBasicAuth(headers, user)
|
2022-02-23 04:22:30 +00:00
|
|
|
});
|
|
|
|
}
|
2022-02-25 18:40:03 +00:00
|
|
|
|
2022-04-01 12:41:45 +00:00
|
|
|
publishXHR(baseUrl, topic, body, headers, onProgress) {
|
|
|
|
const url = topicUrl(baseUrl, topic);
|
|
|
|
const xhr = new XMLHttpRequest();
|
|
|
|
|
|
|
|
console.log(`[Api] Publishing message to ${url}`);
|
|
|
|
const send = new Promise(function (resolve, reject) {
|
|
|
|
xhr.open("PUT", url);
|
|
|
|
xhr.addEventListener('readystatechange', (ev) => {
|
2022-04-02 21:06:26 +00:00
|
|
|
console.log("read change", xhr.readyState, xhr.status, xhr.responseText, xhr)
|
2022-04-01 12:41:45 +00:00
|
|
|
if (xhr.readyState === 4 && xhr.status >= 200 && xhr.status <= 299) {
|
2022-04-02 21:06:26 +00:00
|
|
|
console.log(`[Api] Publish successful (HTTP ${xhr.status})`, xhr.response);
|
2022-04-01 12:41:45 +00:00
|
|
|
resolve(xhr.response);
|
|
|
|
} else if (xhr.readyState === 4) {
|
2022-04-02 21:06:26 +00:00
|
|
|
console.log(`[Api] Publish failed`, xhr.status, xhr.responseText, xhr);
|
2022-04-01 12:41:45 +00:00
|
|
|
xhr.abort();
|
|
|
|
reject(ev);
|
|
|
|
}
|
|
|
|
})
|
|
|
|
xhr.upload.addEventListener("progress", onProgress);
|
|
|
|
if (body.type) {
|
|
|
|
xhr.overrideMimeType(body.type);
|
|
|
|
}
|
|
|
|
for (const [key, value] of Object.entries(headers)) {
|
|
|
|
xhr.setRequestHeader(key, value);
|
|
|
|
}
|
|
|
|
xhr.send(body);
|
|
|
|
});
|
|
|
|
send.abort = () => {
|
|
|
|
console.log(`[Api] Publish aborted by user`);
|
|
|
|
xhr.abort();
|
|
|
|
}
|
|
|
|
return send;
|
|
|
|
}
|
|
|
|
|
2022-02-25 18:40:03 +00:00
|
|
|
async auth(baseUrl, topic, user) {
|
|
|
|
const url = topicUrlAuth(baseUrl, topic);
|
|
|
|
console.log(`[Api] Checking auth for ${url}`);
|
2022-02-25 21:07:25 +00:00
|
|
|
const response = await fetch(url, {
|
2022-02-26 04:25:04 +00:00
|
|
|
headers: maybeWithBasicAuth({}, user)
|
2022-02-25 21:07:25 +00:00
|
|
|
});
|
2022-02-25 18:40:03 +00:00
|
|
|
if (response.status >= 200 && response.status <= 299) {
|
|
|
|
return true;
|
|
|
|
} else if (!user && response.status === 404) {
|
|
|
|
return true; // Special case: Anonymous login to old servers return 404 since /<topic>/auth doesn't exist
|
|
|
|
} else if (response.status === 401 || response.status === 403) { // See server/server.go
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
throw new Error(`Unexpected server response ${response.status}`);
|
|
|
|
}
|
2022-04-03 16:39:52 +00:00
|
|
|
|
|
|
|
async userStats(baseUrl) {
|
|
|
|
const url = userStatsUrl(baseUrl);
|
|
|
|
console.log(`[Api] Fetching user stats ${url}`);
|
|
|
|
const response = await fetch(url);
|
|
|
|
if (response.status !== 200) {
|
|
|
|
throw new Error(`Unexpected server response ${response.status}`);
|
|
|
|
}
|
|
|
|
return response.json();
|
|
|
|
}
|
2022-02-23 04:22:30 +00:00
|
|
|
}
|
|
|
|
|
2022-02-24 01:30:12 +00:00
|
|
|
const api = new Api();
|
|
|
|
export default api;
|