+156
-44
@@ -1,56 +1,168 @@
|
||||
import WebSocket from "ws";
|
||||
|
||||
export default class Trimlog {
|
||||
constructor({username, password}) {
|
||||
this.token = null;
|
||||
this.tokenExpiry = new Date(0);
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
this.socket = null;
|
||||
this.inbox = [];
|
||||
}
|
||||
|
||||
async getLooseActivities() {
|
||||
return this.fetch("GET", "activities");
|
||||
}
|
||||
|
||||
async getWorkouts() {
|
||||
return this.fetch("GET", `workouts?from=${new Date(Date.now() - 86400000 * 3).toISOString().slice(0, 10)}`);
|
||||
}
|
||||
|
||||
async postWorkout(data) {
|
||||
return this.fetch("POST", "workouts", data);
|
||||
}
|
||||
|
||||
async fetch(method, path, body) {
|
||||
if (new Date() > this.tokenExpiry) {
|
||||
await this.refreshToken();
|
||||
}
|
||||
|
||||
const res = await fetch("https://i.stifred.dev/api/"+path, {
|
||||
method: method,
|
||||
headers: {
|
||||
"content-type": body ? "application/json" : void(0),
|
||||
"authorization": `Bearer ${this.token}`
|
||||
send(key, data) {
|
||||
this.socket.send(JSON.stringify({
|
||||
[key]: data,
|
||||
register: {
|
||||
clientId: this.username,
|
||||
clientSecret: this.password,
|
||||
},
|
||||
body: body ? JSON.stringify(body) : void(0),
|
||||
})
|
||||
|
||||
if (!res.ok) {
|
||||
throw new Error(res.statusText);
|
||||
}
|
||||
|
||||
return (await res.json()).data;
|
||||
}));
|
||||
}
|
||||
|
||||
async refreshToken() {
|
||||
const res = await fetch("https://stifred.auth.eu-west-1.amazoncognito.com/oauth2/token", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"content-type": "application/x-www-form-urlencoded",
|
||||
"authorization": `Basic ${Buffer.from(`${this.username}:${this.password}`).toString("base64")}`
|
||||
},
|
||||
body: "grant_type=client_credentials&scope=indigo/api",
|
||||
})
|
||||
const data = await res.json();
|
||||
waitFor(key) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const ws = this.socket;
|
||||
setInterval(() => {
|
||||
if (ws !== this.socket) {
|
||||
reject("disconnected");
|
||||
}
|
||||
|
||||
this.token = data.access_token;
|
||||
this.tokenExpiry = new Date(Date.now() + (data.expires_in * 1000 * 0.95));
|
||||
for (const [i, data] of this.inbox.entries()) {
|
||||
if (!!data[key]) {
|
||||
this.inbox.splice(i, 1);
|
||||
return data[key];
|
||||
}
|
||||
}
|
||||
}, 100)
|
||||
})
|
||||
}
|
||||
|
||||
connect() {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (this.socket != null) {
|
||||
this.socket.close();
|
||||
}
|
||||
|
||||
let answered = false;
|
||||
const ws = new WebSocket("wss://i.stifred.dev/");
|
||||
|
||||
ws.on("open", () => {
|
||||
ws.send(JSON.stringify({register: {
|
||||
clientId: this.username,
|
||||
clientSecret: this.password,
|
||||
}}));
|
||||
|
||||
const interval = setInterval(() => {
|
||||
if (this.socket !== ws) {
|
||||
clearInterval(interval);
|
||||
}
|
||||
|
||||
ws.send(JSON.stringify({ping: {
|
||||
reference: "ping:" + new Date().toISOString(),
|
||||
register: {
|
||||
clientId: this.username,
|
||||
clientSecret: this.password,
|
||||
},
|
||||
}}))
|
||||
}, 60000)
|
||||
|
||||
this.socket = ws;
|
||||
})
|
||||
|
||||
ws.on("message", (data) => {
|
||||
data = JSON.parse(data);
|
||||
if (data.signal) {
|
||||
return
|
||||
}
|
||||
|
||||
console.log(JSON.stringify(data, 0, 4));
|
||||
|
||||
if (!answered) {
|
||||
if (data.connection?.active) {
|
||||
answered = true;
|
||||
return resolve();
|
||||
} else if (data.error != null) {
|
||||
return reject(data.error.message);
|
||||
}
|
||||
}
|
||||
|
||||
this.inbox.push(data);
|
||||
})
|
||||
|
||||
ws.on("error", (err) => {
|
||||
if (!answered) {
|
||||
answered = true;
|
||||
return reject(err);
|
||||
}
|
||||
})
|
||||
|
||||
ws.on("close", () => {
|
||||
if (this.socket === ws) {
|
||||
this.socket = null;
|
||||
|
||||
console.log("Socket closed")
|
||||
this.connect().then(() => {
|
||||
console.log("Socket reconnected")
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
submit(message) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const reference = Date.now().toString(36) + Math.random().toString(36).replace(".", "");
|
||||
|
||||
let answered = false;
|
||||
let sent = false;
|
||||
const ws = new WebSocket("wss://i.stifred.dev/");
|
||||
|
||||
ws.on("open", () => {
|
||||
ws.send(JSON.stringify({register: {
|
||||
clientId: this.username,
|
||||
clientSecret: this.password,
|
||||
}}));
|
||||
})
|
||||
|
||||
ws.on("message", (data) => {
|
||||
data = JSON.parse(data);
|
||||
console.log(JSON.stringify(data, 0, 4));
|
||||
|
||||
if (data.signal?.reference === reference) {
|
||||
if (!answered) {
|
||||
answered = true;
|
||||
resolve();
|
||||
ws.close();
|
||||
}
|
||||
}
|
||||
|
||||
if (!answered && !sent) {
|
||||
if (data.connection?.active) {
|
||||
ws.send(JSON.stringify({
|
||||
...message,
|
||||
ping: { reference },
|
||||
register: {
|
||||
clientId: this.username,
|
||||
clientSecret: this.password,
|
||||
}
|
||||
}));
|
||||
|
||||
sent = true;
|
||||
}
|
||||
}
|
||||
|
||||
this.inbox.push(data);
|
||||
})
|
||||
|
||||
ws.on("error", (err) => {
|
||||
if (!answered) {
|
||||
answered = true;
|
||||
return reject(err);
|
||||
}
|
||||
})
|
||||
|
||||
ws.on("close", () => {
|
||||
console.log("Socket closed")
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user