TypeScript
65 lines · 2,137 bytes
export default class LibreAuth {
name: string;
ownerId: string;
version: string;
apiUrl: string;
sessionId: string | null = null;
enckey: string | null = null;
hash: string = '';
constructor(name: string, ownerId: string, version: string, apiUrl: string) {
this.name = name;
this.ownerId = ownerId;
this.version = version;
this.apiUrl = apiUrl.replace(/\/$/, '') + '/';
}
async init(enckey?: string) {
this.enckey = (enckey || this.randEnc()).substring(0, 35);
const res = await this.req({ type: 'init', ver: this.version, enckey: this.enckey, hash: this.hash || '' });
if (!res.success) throw new Error(res.message);
this.sessionId = res.sessionid;
return res;
}
randEnc() {
const a = new Uint8Array(18);
crypto.getRandomValues(a);
return Array.from(a, b => b.toString(16).padStart(2, '0')).join('').substring(0, 35);
}
async login(user: string, pass: string, hwid = '') {
return this.auth({ type: 'login', username: user, pass, hwid });
}
async license(key: string, hwid = '') {
return this.auth({ type: 'license', key, hwid });
}
async register(user: string, pass: string, key: string, hwid = '') {
return this.auth({ type: 'register', username: user, pass, key, hwid });
}
private async auth(extra: Record<string, string>) {
const res = await this.req(extra);
if (!res.success) throw new Error(res.message);
return res.info ?? res;
}
private async req(extra: Record<string, string>) {
const body = new URLSearchParams({
name: this.name,
ownerid: this.ownerId,
...extra,
});
if (this.sessionId) body.set('sessionid', this.sessionId);
const res = await fetch(this.apiUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: body.toString(),
});
if (res.status === 429) throw new Error('Rate limited');
return res.json();
}
}