From 512ec455a982c3b3b33c914d7acffd2b8608bf7c Mon Sep 17 00:00:00 2001 From: DTrombett Date: Mon, 17 Apr 2023 16:20:14 +0200 Subject: [PATCH] feat: translate descriptions and add dataPath --- src/Client.ts | 239 ++++++++++++----------- src/api/aggiornaData.ts | 4 +- src/api/downloadAllegato.ts | 9 +- src/api/downloadAllegatoStudente.ts | 11 +- src/api/getCode.ts | 73 +++---- src/api/getCorsiRecupero.ts | 11 +- src/api/getCurriculum.ts | 9 +- src/api/getDashboard.ts | 11 +- src/api/getDettagliProfilo.ts | 3 +- src/api/getOrarioGiornaliero.ts | 5 +- src/api/getPCTOData.ts | 9 +- src/api/getProfilo.ts | 6 +- src/api/getRicevimenti.ts | 4 +- src/api/getStoricoBacheca.ts | 9 +- src/api/getStoricoBachecaAlunno.ts | 9 +- src/api/getTasse.ts | 11 +- src/api/getToken.ts | 13 +- src/api/getVotiScrutinio.ts | 3 +- src/api/logToken.ts | 6 +- src/api/login.ts | 9 +- src/api/refreshToken.ts | 9 +- src/api/rimuoviProfilo.ts | 7 +- src/api/what.ts | 7 +- src/index.ts | 21 +- src/structures/Allegato.ts | 6 +- src/structures/Alunno.ts | 2 +- src/structures/Base.ts | 14 +- src/structures/BaseProfilo.ts | 2 +- src/structures/CorsiRecupero.ts | 4 +- src/structures/Curriculum.ts | 2 +- src/structures/Dashboard.ts | 4 +- src/structures/DettagliMateria.ts | 2 +- src/structures/DettagliProfilo.ts | 4 +- "src/structures/Disponibilit\303\240.ts" | 2 +- src/structures/Docente.ts | 2 +- src/structures/EsitoAnno.ts | 2 +- src/structures/EventoAppello.ts | 2 +- src/structures/EventoBacheca.ts | 2 +- src/structures/EventoBachecaAlunno.ts | 2 +- src/structures/EventoRegistro.ts | 2 +- src/structures/FuoriClasse.ts | 2 +- src/structures/Genitore.ts | 2 +- src/structures/Login.ts | 2 +- src/structures/Materia.ts | 2 +- src/structures/MediaMateria.ts | 22 ++- src/structures/MediaPeriodo.ts | 2 +- src/structures/Orario.ts | 2 +- src/structures/Periodo.ts | 2 +- src/structures/Prenotazione.ts | 2 +- src/structures/Profilo.ts | 2 +- src/structures/Promemoria.ts | 2 +- src/structures/Ricevimenti.ts | 4 +- src/structures/Scrutinio.ts | 2 +- src/structures/Tassa.ts | 2 +- src/structures/Token.ts | 2 +- src/structures/Voto.ts | 2 +- src/structures/What.ts | 2 +- src/types/general.ts | 34 ++-- src/util/apiRequest.ts | 10 +- src/util/arrayToObject.ts | 26 --- src/util/encryptCodeVerifier.ts | 6 +- src/util/formatDate.ts | 6 +- src/util/generateLoginLink.ts | 37 ++++ src/util/handleOperation.ts | 9 +- src/util/importData.ts | 11 +- src/util/index.ts | 6 +- src/util/randomString.ts | 6 +- src/util/writeToFile.ts | 10 +- 68 files changed, 420 insertions(+), 349 deletions(-) delete mode 100644 src/util/arrayToObject.ts create mode 100644 src/util/generateLoginLink.ts diff --git a/src/Client.ts b/src/Client.ts index aa04419..39c5b52 100644 --- a/src/Client.ts +++ b/src/Client.ts @@ -6,6 +6,7 @@ import { request } from "undici"; import type { ClientOptions, CorsiRecupero, + Credentials, DettagliProfilo, Ricevimenti, } from "."; @@ -18,7 +19,6 @@ import { aggiornaData, downloadAllegato, downloadAllegatoStudente, - encryptCodeVerifier, getCode, getCorsiRecupero, getCurriculum, @@ -36,7 +36,6 @@ import { importData, logToken, login, - randomString, refreshToken, rimuoviProfilo, what, @@ -44,94 +43,99 @@ import { } from "."; /** - * A client to interact with the API + * Un client per interagire con l'API */ export class Client { /** - * The school code - */ - schoolCode?: string; - /** - * The username - */ - username?: string; - /** - * The password - */ - password?: string; - /** - * The token data + * I dati del token */ token?: Token; + /** - * The login data + * I dati del login */ loginData?: Login; + /** - * The profile data + * I dati del profilo */ profile?: Profilo; + /** - * The dashboard data + * I dati della dashboard */ dashboard?: Dashboard; + /** - * Whether to log some useful data + * Se scrivere nella console alcuni dati utili per il debug */ debug: boolean; + /** - * Additional HTTP headers for the request + * Headers aggiuntivi per ogni richiesta API */ headers?: IncomingHttpHeaders; + /** - * Whether the client is ready + * Il percorso della cartella dove salvare i dati */ - private ready = false; + dataPath?: string; + + #credentials?: Partial; + #ready = false; /** - * @param options - The options for the client + * @param options - Le opzioni per il client */ constructor(options?: ClientOptions) { - this.schoolCode = options?.schoolCode ?? env.CODICE_SCUOLA; - this.password = options?.password ?? env.PASSWORD; - this.username = options?.username ?? env.NOME_UTENTE; + this.#credentials = { + schoolCode: options?.schoolCode ?? env.CODICE_SCUOLA, + password: options?.password ?? env.PASSWORD, + username: options?.username ?? env.NOME_UTENTE, + }; this.token = options?.token; this.loginData = options?.loginData; this.profile = options?.profile; this.dashboard = options?.dashboard; this.debug = options?.debug ?? false; this.headers = options?.headers; + if (options?.dataPath !== null) + this.dataPath = options?.dataPath ?? AuthFolder; } /** - * Check if the client is ready. - * @returns Whether the client is ready + * Controlla se il client è pronto */ isReady(): this is { token: Token; loginData: Login; profile: Profilo; } { - return this.ready; + return this.#ready; } /** - * Login to the API. - * @returns The dashboard data + * Effettua il login. + * @returns I dati della dashboard */ async login() { - await Promise.all([ - this.token ? undefined : importData("token"), - this.loginData ? undefined : importData("login"), - this.profile ? undefined : importData("profile"), - this.dashboard ? undefined : importData("dashboard"), - existsSync(AuthFolder) || mkdir(AuthFolder), - ]).then(([token, loginData, profile, dashboard]) => { - if (token) this.token = new Token(token, this); - if (loginData) this.loginData = new Login(loginData, this); - if (profile) this.profile = new Profilo(profile, this); - if (dashboard) this.dashboard = new Dashboard(dashboard, this); - }); + if (this.dataPath !== undefined) + await Promise.all([ + this.token ? undefined : importData("token", this.dataPath), + this.loginData ? undefined : importData("login", this.dataPath), + this.profile + ? undefined + : importData("profile", this.dataPath), + this.dashboard + ? undefined + : importData("dashboard", this.dataPath), + existsSync(this.dataPath) || mkdir(this.dataPath), + ]).then(([token, loginData, profile, dashboard]) => { + if (token) this.token = new Token(token, this); + if (loginData) this.loginData = new Login(loginData, this); + if (profile) this.profile = new Profilo(profile, this); + if (dashboard) this.dashboard = new Dashboard(dashboard, this); + }); const oldToken = this.token; this.token = await this.refreshToken(); @@ -142,28 +146,34 @@ export class Client { isWhat: this.profile !== undefined, }); if (this.profile) { - this.ready = true; + this.#ready = true; const whatData = await what(this, { lastUpdate: this.dashboard?.dataAggiornamento ?? this.profile.anno.dataInizio, }); - if (whatData.profiloModificato || whatData.differenzaSchede) - void writeToFile("profile", { ...this.profile, ...whatData.profilo }); + if ( + (whatData.profiloModificato || whatData.differenzaSchede) && + this.dataPath !== undefined + ) + void writeToFile( + "profile", + { ...this.profile, ...whatData.profilo }, + this.dataPath + ); if (whatData.aggiornato || !this.dashboard) await this.getDashboard(); aggiornaData(this).catch(console.error); return this.dashboard!; } } this.profile = this.profile ?? (await getProfilo(this)); - this.ready = true; + this.#ready = true; return this.getDashboard(); } /** - * Refresh a token if needed. - * @param token - The token to check - * @returns The new token + * Aggiorna il client, se necessario. + * @returns Il nuovo token */ async refreshToken() { if (!this.loginData || !this.token) return this.getToken(); @@ -173,25 +183,23 @@ export class Client { } /** - * Get a token from the API. - * @returns The token + * Ottieni il token tramite l'API. + * @returns I dati del token */ async getToken() { if ( - this.password === undefined || - this.schoolCode === undefined || - this.username === undefined + [ + this.#credentials?.password, + this.#credentials?.schoolCode, + this.#credentials?.username, + ].includes(undefined) ) - throw new TypeError("School code, username or password are missing!"); - const codeVerifier = randomString(43); + throw new TypeError("Password, school code, or username missing"); + const code = await getCode(this.#credentials as Credentials); return getToken(this, { - code: await getCode(encryptCodeVerifier(codeVerifier), { - password: this.password, - schoolCode: this.schoolCode, - username: this.username, - }), - codeVerifier, + code: code.code, + codeVerifier: code.codeVerifier, }); } @@ -210,7 +218,7 @@ export class Client { /** * Ottieni i dettagli del profilo dello studente. - * @returns The data + * @returns I dati */ async getDettagliProfilo(old?: T) { if (!this.isReady()) throw new Error("Client is not logged in!"); @@ -221,8 +229,8 @@ export class Client { /** * Ottieni l'orario giornaliero. - * @param date - The date of the timetable - * @returns The data + * @param date - Il giorno dell'orario + * @returns I dati */ async getOrarioGiornaliero(date?: { year?: number; @@ -239,58 +247,60 @@ export class Client { /** * Ottieni il link per scaricare un allegato della bacheca. - * @param uid - The uid of the attachment - * @returns The url + * @param id - L'id dell'allegato + * @returns L'url */ - async getLinkAllegato(uid: string) { + async getLinkAllegato(id: string) { if (!this.isReady()) throw new Error("Client is not logged in!"); return downloadAllegato(this, { - uid, + id, }); } /** * Scarica un allegato. - * @param uid - The uid of the attachment - * @param file - The path where the file should be saved + * @param id - L'id dell'allegato + * @param file - Il percorso dove salvare il file */ - async downloadAllegato(uid: string, file: string) { + async downloadAllegato(id: string, file: string) { if (!this.isReady()) throw new Error("Client is not logged in!"); - const { body } = await request(await this.getLinkAllegato(uid)); + const { body } = await request(await this.getLinkAllegato(id)); await writeFile(file, body); } /** * Ottieni il link per scaricare un allegato della bacheca alunno. - * @param uid - The uid of the attachment - * @param id - The profile id - * @returns The url + * @param id - l'id dell'allegato + * @param profileId - L'id del profilo + * @returns L'url */ - async getLinkAllegatoStudente(uid: string, id?: string) { + async getLinkAllegatoStudente(id: string, profileId?: string) { if (!this.isReady()) throw new Error("Client is not logged in!"); return downloadAllegatoStudente(this, { - uid, - id: id ?? this.profile.id, + id, + profileId: profileId ?? this.profile.id, }); } /** * Scarica un allegato dello studente. - * @param uid - The uid of the attachment - * @param file - The path where the file should be saved - * @param id - The profile id + * @param id - L'id dell'allegato + * @param file - Il percorso dove salvare il file + * @param profileId - L'id del profilo */ - async downloadAllegatoStudente(uid: string, file: string, id?: string) { + async downloadAllegatoStudente(id: string, file: string, profileId?: string) { if (!this.isReady()) throw new Error("Client is not logged in!"); - const { body } = await request(await this.getLinkAllegatoStudente(uid, id)); + const { body } = await request( + await this.getLinkAllegatoStudente(id, profileId) + ); await writeFile(file, body); } /** * Ottieni i voti dello scrutinio dello studente. - * @returns The data + * @returns I dati */ async getVotiScrutinio() { if (!this.isReady()) throw new Error("Client is not logged in!"); @@ -299,7 +309,7 @@ export class Client { /** * Ottieni i dati riguardo i ricevimenti dello studente. - * @returns The data + * @returns I dati */ async getRicevimenti(old?: T) { if (!this.isReady()) throw new Error("Client is not logged in!"); @@ -308,81 +318,80 @@ export class Client { /** * Ottieni le tasse dello studente. - * @param id - The profile id - * @returns The data + * @param profileId - L'id del profilo + * @returns I dati */ - async getTasse(id?: string) { + async getTasse(profileId?: string) { if (!this.isReady()) throw new Error("Client is not logged in!"); return getTasse(this, { - id: id ?? this.profile.id, + profileId: profileId ?? this.profile.id, }); } /** * Ottieni i dati del PCTO dello studente. - * @param id - The profile id - * @returns The data + * @param profileId - L'id del profilo + * @returns I dati */ - async getPCTOData(id?: string) { + async getPCTOData(profileId?: string) { if (!this.isReady()) throw new Error("Client is not logged in!"); return getPCTOData(this, { - id: id ?? this.profile.id, + profileId: profileId ?? this.profile.id, }); } /** * Ottieni i dati dei corsi di recupero dello studente. - * @param id - The profile id - * @returns The data + * @param profileId - L'id del profilo + * @returns I dati */ - async getCorsiRecupero(id?: string, old?: T) { + async getCorsiRecupero(profileId?: string, old?: T) { if (!this.isReady()) throw new Error("Client is not logged in!"); return getCorsiRecupero(this, { - id: id ?? this.profile.id, + profileId: profileId ?? this.profile.id, old, }); } /** * Ottieni il curriculum dello studente. - * @param id - The profile id - * @returns The data + * @param profileId - L'id del profilo + * @returns I dati */ - async getCurriculum(id?: string) { + async getCurriculum(profileId?: string) { if (!this.isReady()) throw new Error("Client is not logged in!"); return getCurriculum(this, { - id: id ?? this.profile.id, + profileId: profileId ?? this.profile.id, }); } /** * Ottieni lo storico della bacheca. - * @param id - The profile id - * @returns The data + * @param profileId - L'id del profilo + * @returns I dati */ - async getStoricoBacheca(id: string) { + async getStoricoBacheca(profileId: string) { if (!this.isReady()) throw new Error("Client is not logged in!"); return getStoricoBacheca(this, { - id, + profileId, }); } /** * Ottieni lo storico della bacheca alunno. - * @param id - The profile id - * @returns The data + * @param profileId - L'id del profilo + * @returns I dati */ - async getStoricoBachecaAlunno(id: string) { + async getStoricoBachecaAlunno(profileId: string) { if (!this.isReady()) throw new Error("Client is not logged in!"); return getStoricoBachecaAlunno(this, { - id, + profileId, }); } /** - * Get the dashboard data from the API. - * @private Use `client.dashboard` instead - * @returns The dashboard data + * Ottieni i dati della dashboard. + * @returns La dashboard */ private async getDashboard() { if (!this.isReady()) throw new Error("Client is not logged in!"); diff --git a/src/api/aggiornaData.ts b/src/api/aggiornaData.ts index ba1fc88..068fef3 100644 --- a/src/api/aggiornaData.ts +++ b/src/api/aggiornaData.ts @@ -2,8 +2,8 @@ import type { APIResponse, Client } from ".."; import { apiRequest, formatDate } from ".."; /** - * Aggiorna la data dell'ultimo aggiornamento. - * @param client - The client + * Aggiorna la data per la dashboard. + * @param client - Il client */ export const aggiornaData = async (client: Client) => { const { body } = await apiRequest( diff --git a/src/api/downloadAllegato.ts b/src/api/downloadAllegato.ts index 111512f..61adf92 100644 --- a/src/api/downloadAllegato.ts +++ b/src/api/downloadAllegato.ts @@ -3,13 +3,14 @@ import { apiRequest } from ".."; /** * Ottieni il link per scaricare un allegato della bacheca. - * @param client - The client - * @param options - Additional options for the request + * @param client - Il client + * @param options - Altre opzioni della richiesta + * @returns Il link */ export const downloadAllegato = async ( client: Client, options: { - uid: string; + id: string; } ) => { const { body } = await apiRequest( @@ -18,7 +19,7 @@ export const downloadAllegato = async ( { method: "POST", body: { - uid: options.uid, + uid: options.id, }, } ); diff --git a/src/api/downloadAllegatoStudente.ts b/src/api/downloadAllegatoStudente.ts index ed9d421..05316a0 100644 --- a/src/api/downloadAllegatoStudente.ts +++ b/src/api/downloadAllegatoStudente.ts @@ -3,14 +3,15 @@ import { apiRequest } from ".."; /** * Ottieni il link per scaricare un allegato della bacheca alunno. - * @param client - The client - * @param options - Additional options for the request + * @param client - Il client + * @param options - Altre opzioni della richiesta + * @returns Il link */ export const downloadAllegatoStudente = async ( client: Client, options: { - uid: string; id: string; + profileId: string; } ) => { const { body } = await apiRequest( @@ -19,8 +20,8 @@ export const downloadAllegatoStudente = async ( { method: "POST", body: { - uid: options.uid, - pkScheda: options.id, + uid: options.id, + pkScheda: options.profileId, }, } ); diff --git a/src/api/getCode.ts b/src/api/getCode.ts index 297607c..6a88ea0 100644 --- a/src/api/getCode.ts +++ b/src/api/getCode.ts @@ -1,10 +1,10 @@ import { URL } from "node:url"; import { request } from "undici"; -import type { BasicCredentials } from ".."; -import { clientId, randomString } from ".."; +import type { Credentials } from ".."; +import { clientId, generateLoginLink } from ".."; const baseHeaders = { - "accept": + accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "accept-encoding": "gzip, deflate, br", "sec-fetch-dest": "document", @@ -14,45 +14,32 @@ const baseHeaders = { "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.5615.29 Safari/537.36", } as const; -const redirectUri = encodeURIComponent( - "it.argosoft.didup.famiglia.new://login-callback" -); -const scopes = encodeURIComponent("openid offline profile user.roles argo"); /** - * Get the code for the login. - * @param codeChallenge - The code challenge to use - * @returns The code to use for the login + * Ottieni il codice per il login. + * @param credentials - Le credenziali per l'accesso + * @returns I dati del codice da usare */ -export const getCode = async ( - codeChallenge: string, - credentials: BasicCredentials -) => { - const { headers, statusCode } = await request( - `https://auth.portaleargo.it/oauth2/auth?redirect_uri=${redirectUri}&client_id=${clientId}&response_type=code&prompt=login&state=${randomString( - 22 - )}&nonce=${randomString( - 22 - )}&scope=${scopes}&code_challenge=${codeChallenge}&code_challenge_method=S256`, - { - headers: { - ...baseHeaders, - "sec-fetch-site": "none", - }, - method: "GET", - } - ); - const url = headers.location; +export const getCode = async (credentials: Credentials) => { + const url = generateLoginLink(); + const { headers, statusCode } = await request(url.url, { + headers: { + ...baseHeaders, + "sec-fetch-site": "none", + }, + method: "GET", + }); + const link = headers.location; const cookies: string[] = []; let cookieHeaders = headers["set-cookie"]; - if (typeof url !== "string") + if (typeof link !== "string") throw new TypeError( `Auth request returned an invalid redirect url with status code ${statusCode}` ); if (typeof cookieHeaders === "string") cookieHeaders = [cookieHeaders]; for (const c of cookieHeaders ?? []) cookies.push(c.split(";")[0]); - const challenge = new URL(url).searchParams.get("login_challenge")!; + const challenge = new URL(link).searchParams.get("login_challenge")!; const { headers: { location }, statusCode: status, @@ -61,11 +48,11 @@ export const getCode = async ( headers: { ...baseHeaders, "cache-control": "max-age=0", - "connection": "keep-alive", + connection: "keep-alive", "content-type": "application/x-www-form-urlencoded", - "host": "www.portaleargo.it", - "origin": "https://www.portaleargo.it", - "referer": url, + host: "www.portaleargo.it", + origin: "https://www.portaleargo.it", + referer: link, "sec-fetch-site": "same-origin", }, method: "POST", @@ -81,8 +68,8 @@ export const getCode = async ( headers: { ...baseHeaders, "cache-control": "max-age=0", - "cookie": cookies.join("; "), - "referer": "https://www.portaleargo.it/", + cookie: cookies.join("; "), + referer: "https://www.portaleargo.it/", "sec-fetch-site": "same-site", }, method: "GET", @@ -103,9 +90,9 @@ export const getCode = async ( headers: { ...baseHeaders, "cache-control": "max-age=0", - "connection": "keep-alive", - "host": "www.portaleargo.it", - "referer": "https://www.portaleargo.it/", + connection: "keep-alive", + host: "www.portaleargo.it", + referer: "https://www.portaleargo.it/", "sec-fetch-site": "same-site", }, method: "GET", @@ -122,8 +109,8 @@ export const getCode = async ( headers: { ...baseHeaders, "cache-control": "max-age=0", - "cookie": cookies.join("; "), - "referer": "https://www.portaleargo.it/", + cookie: cookies.join("; "), + referer: "https://www.portaleargo.it/", "sec-fetch-site": "same-site", }, method: "GET", @@ -137,5 +124,5 @@ export const getCode = async ( if (code == null) throw new TypeError(`Invalid code returned by API: ${finalRedirect}`); - return code; + return { ...url, code }; }; diff --git a/src/api/getCorsiRecupero.ts b/src/api/getCorsiRecupero.ts index aaf51b3..b7bbec9 100644 --- a/src/api/getCorsiRecupero.ts +++ b/src/api/getCorsiRecupero.ts @@ -3,24 +3,25 @@ import { CorsiRecupero, apiRequest } from ".."; /** * Ottieni i dati dei corsi di recupero dello studente. - * @param client - The client - * @param options - Additional options for the request + * @param client - Il client + * @param options - Altre opzioni della richiesta + * @returns I dati */ export const getCorsiRecupero = async ( client: Client, options: { - id: string; + profileId: string; old?: T; } ) => { const { body } = await apiRequest("corsirecupero", client, { method: "POST", body: { - pkScheda: options.id, + pkScheda: options.profileId, }, }); if (!body.success) throw new Error(body.msg!); return (options.old?.patch(body.data) ?? - new CorsiRecupero(body.data, client, options.id)) as T; + new CorsiRecupero(body.data, client, options.profileId)) as T; }; diff --git a/src/api/getCurriculum.ts b/src/api/getCurriculum.ts index c9c6bca..161651e 100644 --- a/src/api/getCurriculum.ts +++ b/src/api/getCurriculum.ts @@ -3,19 +3,20 @@ import { Curriculum, apiRequest } from ".."; /** * Ottieni il curriculum dello studente. - * @param client - The client - * @param options - Additional options for the request + * @param client - Il client + * @param options - Altre opzioni della richiesta + * @returns I dati */ export const getCurriculum = async ( client: Client, options: { - id: string; + profileId: string; } ) => { const { body } = await apiRequest("curriculumalunno", client, { method: "POST", body: { - pkScheda: options.id, + pkScheda: options.profileId, }, }); diff --git a/src/api/getDashboard.ts b/src/api/getDashboard.ts index 9c0794f..f190ee7 100644 --- a/src/api/getDashboard.ts +++ b/src/api/getDashboard.ts @@ -2,10 +2,10 @@ import type { APIDashboard, Client } from ".."; import { Dashboard, apiRequest, formatDate, writeToFile } from ".."; /** - * Fetch all the data for the authenticated user. - * @param client - The client - * @param options - Additional options for the request - * @returns All the data for the user + * Ottieni la dashboard dello studente. + * @param client - Il client + * @param options - Altre opzioni della richiesta + * @returns I dati */ export const getDashboard = async ( client: Client, @@ -30,6 +30,7 @@ export const getDashboard = async ( client.dashboard?.patch(body.data.dati[0]) ?? new Dashboard(body.data.dati[0], client); - void writeToFile("dashboard", value); + if (client.dataPath !== undefined) + void writeToFile("dashboard", value, client.dataPath); return value; }; diff --git a/src/api/getDettagliProfilo.ts b/src/api/getDettagliProfilo.ts index 825bfcb..f9e9965 100644 --- a/src/api/getDettagliProfilo.ts +++ b/src/api/getDettagliProfilo.ts @@ -3,7 +3,8 @@ import { DettagliProfilo, apiRequest } from ".."; /** * Ottieni i dettagli del profilo dello studente. - * @param client - The client + * @param client - Il client + * @returns I dati */ export const getDettagliProfilo = async ( client: Client, diff --git a/src/api/getOrarioGiornaliero.ts b/src/api/getOrarioGiornaliero.ts index 693c92a..f05c921 100644 --- a/src/api/getOrarioGiornaliero.ts +++ b/src/api/getOrarioGiornaliero.ts @@ -3,8 +3,9 @@ import { Orario, apiRequest, formatDate } from ".."; /** * Ottieni l'orario giornaliero. - * @param client - The client - * @param options - Additional options for the request + * @param client - Il client + * @param options - Altre opzioni della richiesta + * @returns I dati */ export const getOrarioGiornaliero = async ( client: Client, diff --git a/src/api/getPCTOData.ts b/src/api/getPCTOData.ts index 8461e73..fe5eeed 100644 --- a/src/api/getPCTOData.ts +++ b/src/api/getPCTOData.ts @@ -3,19 +3,20 @@ import { apiRequest } from ".."; /** * Ottieni i dati del PCTO dello studente. - * @param client - The client - * @param options - Additional options for the request + * @param client - Il client + * @param options - Altre opzioni della richiesta + * @returns I dati */ export const getPCTOData = async ( client: Client, options: { - id: string; + profileId: string; } ) => { const { body } = await apiRequest("pcto", client, { method: "POST", body: { - pkScheda: options.id, + pkScheda: options.profileId, }, }); diff --git a/src/api/getProfilo.ts b/src/api/getProfilo.ts index 439ebdd..1f8297a 100644 --- a/src/api/getProfilo.ts +++ b/src/api/getProfilo.ts @@ -3,7 +3,8 @@ import { Profilo, apiRequest, writeToFile } from ".."; /** * Ottieni i dati riguardo il profilo dell'utente. - * @param client - The client + * @param client - Il client + * @returns I dati */ export const getProfilo = async (client: Client) => { const { body } = await apiRequest("profilo", client, {}); @@ -12,6 +13,7 @@ export const getProfilo = async (client: Client) => { const value = client.profile?.patch(body.data) ?? new Profilo(body.data, client); - void writeToFile("profile", value); + if (client.dataPath !== undefined) + void writeToFile("profile", value, client.dataPath); return value; }; diff --git a/src/api/getRicevimenti.ts b/src/api/getRicevimenti.ts index d9e407c..dc04239 100644 --- a/src/api/getRicevimenti.ts +++ b/src/api/getRicevimenti.ts @@ -3,7 +3,9 @@ import { Ricevimenti, apiRequest } from ".."; /** * Ottieni i dati riguardo i ricevimenti dello studente. - * @param client - The client + * @param client - Il client + * @param options - Altre opzioni della richiesta + * @returns I dati */ export const getRicevimenti = async ( client: Client, diff --git a/src/api/getStoricoBacheca.ts b/src/api/getStoricoBacheca.ts index c2fcaa9..e86fd29 100644 --- a/src/api/getStoricoBacheca.ts +++ b/src/api/getStoricoBacheca.ts @@ -3,19 +3,20 @@ import { EventoBacheca, apiRequest, handleOperation } from ".."; /** * Ottieni lo storico della bacheca. - * @param client - The client - * @param options - Additional options for the request + * @param client - Il client + * @param options - Altre opzioni della richiesta + * @returns I dati */ export const getStoricoBacheca = async ( client: Client, options: { - id: string; + profileId: string; } ) => { const { body } = await apiRequest("storicobacheca", client, { method: "POST", body: { - pkScheda: options.id, + pkScheda: options.profileId, }, }); diff --git a/src/api/getStoricoBachecaAlunno.ts b/src/api/getStoricoBachecaAlunno.ts index d51a956..17cd14e 100644 --- a/src/api/getStoricoBachecaAlunno.ts +++ b/src/api/getStoricoBachecaAlunno.ts @@ -3,13 +3,14 @@ import { EventoBachecaAlunno, apiRequest, handleOperation } from ".."; /** * Ottieni lo storico della bacheca alunno. - * @param client - The client - * @param options - Additional options for the request + * @param client - Il client + * @param options - Altre opzioni della richiesta + * @returns I dati */ export const getStoricoBachecaAlunno = async ( client: Client, options: { - id: string; + profileId: string; } ) => { const { body } = await apiRequest( @@ -18,7 +19,7 @@ export const getStoricoBachecaAlunno = async ( { method: "POST", body: { - pkScheda: options.id, + pkScheda: options.profileId, }, } ); diff --git a/src/api/getTasse.ts b/src/api/getTasse.ts index 509e7e1..b0b035b 100644 --- a/src/api/getTasse.ts +++ b/src/api/getTasse.ts @@ -2,20 +2,21 @@ import type { APITasse, Client } from ".."; import { Tassa, apiRequest } from ".."; /** - * Ottieni le tasse dello studente. - * @param client - The client - * @param options - Additional options for the request + * Ottieni i dati delle tasse dello studente. + * @param client - Il client + * @param options - Altre opzioni della richiesta + * @returns I dati */ export const getTasse = async ( client: Client, options: { - id: string; + profileId: string; } ) => { const { body } = await apiRequest("listatassealunni", client, { method: "POST", body: { - pkScheda: options.id, + pkScheda: options.profileId, }, }); diff --git a/src/api/getToken.ts b/src/api/getToken.ts index a83830e..b0de1b7 100644 --- a/src/api/getToken.ts +++ b/src/api/getToken.ts @@ -4,11 +4,11 @@ import type { Client } from ".."; import { Token, clientId, writeToFile } from ".."; /** - * Get the token from the API. - * @param code - The code to use - * @param codeVerifier - The code verifier to use - * @param client - The client - * @returns The data for the login + * Ottieni il token tramite l'API. + * @param code - Il codice da usare + * @param codeVerifier - Il code verifier + * @param client - Il client + * @returns I dati */ export const getToken = async ( client: Client, @@ -35,6 +35,7 @@ export const getToken = async ( const value = client.token?.patch(data, date) ?? new Token(data, client, date); - void writeToFile("token", value); + if (client.dataPath !== undefined) + void writeToFile("token", value, client.dataPath); return value; }; diff --git a/src/api/getVotiScrutinio.ts b/src/api/getVotiScrutinio.ts index 6e8a54c..707be2f 100644 --- a/src/api/getVotiScrutinio.ts +++ b/src/api/getVotiScrutinio.ts @@ -3,7 +3,8 @@ import { Scrutinio, apiRequest } from ".."; /** * Ottieni i voti dello scrutinio dello studente. - * @param client - The client + * @param client - Il client + * @returns I dati */ export const getVotiScrutinio = async (client: Client) => { const { body } = await apiRequest("votiscrutinio", client, { diff --git a/src/api/logToken.ts b/src/api/logToken.ts index 615df36..6232888 100644 --- a/src/api/logToken.ts +++ b/src/api/logToken.ts @@ -2,9 +2,9 @@ import type { APIResponse, Client, Token } from ".."; import { apiRequest, formatDate } from ".."; /** - * Log the token. - * @param client - The client - * @param options - Additional options for the request + * Registra il token + * @param client - Il client + * @param options - Altre opzioni della richiesta */ export const logToken = async ( client: Client, diff --git a/src/api/login.ts b/src/api/login.ts index ca711a5..2352132 100644 --- a/src/api/login.ts +++ b/src/api/login.ts @@ -2,9 +2,9 @@ import type { APILogin, Client } from ".."; import { Login, apiRequest, randomString, writeToFile } from ".."; /** - * Login to the API. - * @param client - The client - * @returns The login data + * Effettua il login tramite l'API. + * @param client - Il client + * @returns I dati */ export const login = async (client: Client) => { const { body } = await apiRequest("login", client, { @@ -20,6 +20,7 @@ export const login = async (client: Client) => { const value = client.loginData?.patch(body.data[0]) ?? new Login(body.data[0], client); - void writeToFile("login", value); + if (client.dataPath !== undefined) + void writeToFile("login", value, client.dataPath); return value; }; diff --git a/src/api/refreshToken.ts b/src/api/refreshToken.ts index ea3b1d5..c2fcd2c 100644 --- a/src/api/refreshToken.ts +++ b/src/api/refreshToken.ts @@ -2,9 +2,9 @@ import type { APIToken, Client } from ".."; import { Token, apiRequest, clientId, formatDate, writeToFile } from ".."; /** - * Refresh the token. - * @param client - The client - * @returns The token data + * Aggiorna il token. + * @param client - Il client + * @returns I dati */ export const refreshToken = async (client: Client) => { const { res, body } = await apiRequest( @@ -31,6 +31,7 @@ export const refreshToken = async (client: Client) => { const value = client.token?.patch(body, date) ?? new Token(body, client, date); - void writeToFile("token", value); + if (client.dataPath !== undefined) + void writeToFile("token", value, client.dataPath); return value; }; diff --git a/src/api/rimuoviProfilo.ts b/src/api/rimuoviProfilo.ts index ddcbc51..ffc9e8f 100644 --- a/src/api/rimuoviProfilo.ts +++ b/src/api/rimuoviProfilo.ts @@ -1,10 +1,10 @@ import { rm } from "node:fs/promises"; import type { APIResponse, Client } from ".."; -import { AuthFolder, apiRequest } from ".."; +import { apiRequest } from ".."; /** * Rimuovi il profilo. - * @param client - The client + * @param client - Il client */ export const rimuoviProfilo = async (client: Client) => { const { body } = await apiRequest("rimuoviprofilo", client, { @@ -13,5 +13,6 @@ export const rimuoviProfilo = async (client: Client) => { }); if (!body.success) throw new Error(body.msg!); - await rm(AuthFolder, { recursive: true, force: true }); + if (client.dataPath !== undefined) + await rm(client.dataPath, { recursive: true, force: true }); }; diff --git a/src/api/what.ts b/src/api/what.ts index e5f5478..78b1602 100644 --- a/src/api/what.ts +++ b/src/api/what.ts @@ -2,9 +2,10 @@ import type { APIWhat, Client } from ".."; import { What, apiRequest, formatDate } from ".."; /** - * Get the what data. - * @param client - The client - * @param options - Additional options for the request + * Richiedi i dati generali. + * @param client - Il client + * @param options - Altre opzioni della richiesta + * @returns I dati */ export const what = async ( client: Client, diff --git a/src/index.ts b/src/index.ts index 92a49be..a912179 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,20 +1,17 @@ // import { config } from "dotenv"; // import { Client } from "."; +// +// config(); +// const now = performance.now(); +// const client = new Client({ +// debug: true, +// }); +// +// await client.login(); +// console.log(await client.getDettagliProfilo(), performance.now() - now); export * from "./Client"; export * from "./api"; export * from "./structures"; export * from "./types"; export * from "./util"; - -// const now = performance.now(); -// config(); -// const client = new Client({ -// debug: true, -// }); - -// await client.login(); -// console.log(await client.getDettagliProfilo(), performance.now() - now); -// TODO: Translate everything -// TODO: Create utility to generate a code link -// TODO: Add option to not save local data diff --git a/src/structures/Allegato.ts b/src/structures/Allegato.ts index 34fa6e9..ad2bb17 100644 --- a/src/structures/Allegato.ts +++ b/src/structures/Allegato.ts @@ -18,7 +18,7 @@ export class Allegato extends Base { url!: string; /** - * @param data - The API data + * @param data - I dati ricevuti tramite l'API */ constructor(data: Data, client: Client) { super(client); @@ -39,7 +39,7 @@ export class Allegato extends Base { /** * Scarica questo allegato. - * @param file - The path where the file should be saved + * @param file - Il percorso dove salvare il file */ download(file: string) { return this.client.downloadAllegato(this.id, file); @@ -47,7 +47,7 @@ export class Allegato extends Base { /** * Ottieni il link per scaricare questo allegato. - * @returns The url + * @returns L'url */ getLink() { return this.client.getLinkAllegato(this.id); diff --git a/src/structures/Alunno.ts b/src/structures/Alunno.ts index e3842b1..4ec4e46 100644 --- a/src/structures/Alunno.ts +++ b/src/structures/Alunno.ts @@ -26,7 +26,7 @@ export class Alunno extends Base { comune!: string; /** - * @param data - The API data + * @param data - I dati ricevuti tramite l'API */ constructor(data: Data, client: Client) { super(client); diff --git a/src/structures/Base.ts b/src/structures/Base.ts index 58e8d75..f84b31a 100644 --- a/src/structures/Base.ts +++ b/src/structures/Base.ts @@ -8,11 +8,15 @@ const identifierName = "class name"; */ export class Base { /** - * The client that instantiated this + * Il client */ client: Client; + protected readonly [identifierName] = this.constructor.name; + /** + * @param client - Il client + */ constructor(client: Client) { Object.defineProperty(this, identifierName, { writable: false, @@ -28,6 +32,10 @@ export class Base { return Object.hasOwn(object, key); } + /** + * Converti questa struttura in JSON. + * @returns La rappresentazione JSON di questa struttura + */ toJSON() { const self: Omit = { ...this, client: undefined }; @@ -46,6 +54,10 @@ export class Base { return self; } + protected patch(_data: T) { + return this; + } + protected isJson(data: O | T): data is O { return data[identifierName] === this.constructor.name; } diff --git a/src/structures/BaseProfilo.ts b/src/structures/BaseProfilo.ts index 0b94639..e39a54e 100644 --- a/src/structures/BaseProfilo.ts +++ b/src/structures/BaseProfilo.ts @@ -42,7 +42,7 @@ export class BaseProfilo extends Base { profiloStorico!: boolean; /** - * @param data - The API data + * @param data - I dati ricevuti tramite l'API */ constructor(data: Data, client: Client) { super(client); diff --git a/src/structures/CorsiRecupero.ts b/src/structures/CorsiRecupero.ts index 4c101fa..1f3d384 100644 --- a/src/structures/CorsiRecupero.ts +++ b/src/structures/CorsiRecupero.ts @@ -13,7 +13,7 @@ export class CorsiRecupero extends Base { id: string; /** - * @param data - The API data + * @param data - I dati ricevuti tramite l'API */ constructor(data: Data, client: Client, id: string) { super(client); @@ -32,7 +32,7 @@ export class CorsiRecupero extends Base { /** * Aggiorna questi dati. - * @returns The updated data + * @returns I dati aggiornati */ refresh() { return this.client.getCorsiRecupero(this.id, this); diff --git a/src/structures/Curriculum.ts b/src/structures/Curriculum.ts index 02dbe39..33bd17e 100644 --- a/src/structures/Curriculum.ts +++ b/src/structures/Curriculum.ts @@ -22,7 +22,7 @@ export class Curriculum extends Base { ordine!: string; /** - * @param data - The API data + * @param data - I dati ricevuti tramite l'API */ constructor(data: Data, client: Client) { super(client); diff --git a/src/structures/Dashboard.ts b/src/structures/Dashboard.ts index 0eb4ecd..065c720 100644 --- a/src/structures/Dashboard.ts +++ b/src/structures/Dashboard.ts @@ -52,7 +52,7 @@ export class Dashboard extends Base { classiExtra!: boolean; /** - * @param data - The API data + * @param data - I dati ricevuti tramite l'API */ constructor(data: Data, client: Client) { super(client); @@ -166,7 +166,7 @@ export class Dashboard extends Base { /** * Aggiorna questi dati. - * @returns The updated data + * @returns I dati aggiornati */ refresh() { return this.client.login() as Promise; diff --git a/src/structures/DettagliMateria.ts b/src/structures/DettagliMateria.ts index dc38a91..bc22a67 100644 --- a/src/structures/DettagliMateria.ts +++ b/src/structures/DettagliMateria.ts @@ -36,7 +36,7 @@ export class DettagliMateria extends Base { id!: string; /** - * @param data - The API data + * @param data - I dati ricevuti tramite l'API */ constructor(data: Data, client: Client) { super(client); diff --git a/src/structures/DettagliProfilo.ts b/src/structures/DettagliProfilo.ts index 14efd89..eafd8c5 100644 --- a/src/structures/DettagliProfilo.ts +++ b/src/structures/DettagliProfilo.ts @@ -13,7 +13,7 @@ export class DettagliProfilo extends Base { alunno!: Alunno; /** - * @param data - The API data + * @param data - I dati ricevuti tramite l'API */ constructor(data: Data, client: Client) { super(client); @@ -32,7 +32,7 @@ export class DettagliProfilo extends Base { /** * Aggiorna questi dati. - * @returns The updated data + * @returns I dati aggiornati */ refresh() { return this.client.getDettagliProfilo(this); diff --git "a/src/structures/Disponibilit\303\240.ts" "b/src/structures/Disponibilit\303\240.ts" index 8d120b9..9a8e4cf 100644 --- "a/src/structures/Disponibilit\303\240.ts" +++ "b/src/structures/Disponibilit\303\240.ts" @@ -29,7 +29,7 @@ export class Disponibilità extends Base { data!: string; /** - * @param data - The API data + * @param data - I dati ricevuti tramite l'API */ constructor(data: DisponibilitàData, client: Client, date: string); constructor(data: Jsonify, client: Client); diff --git a/src/structures/Docente.ts b/src/structures/Docente.ts index 868b76f..f9105fc 100644 --- a/src/structures/Docente.ts +++ b/src/structures/Docente.ts @@ -16,7 +16,7 @@ export class Docente extends Base { email!: string; /** - * @param data - The API data + * @param data - I dati ricevuti tramite l'API */ constructor(data: Data, client: Client) { super(client); diff --git a/src/structures/EsitoAnno.ts b/src/structures/EsitoAnno.ts index f755168..145c936 100644 --- a/src/structures/EsitoAnno.ts +++ b/src/structures/EsitoAnno.ts @@ -20,7 +20,7 @@ export class EsitoAnno extends Base { particolarità!: string; /** - * @param data - The API data + * @param data - I dati ricevuti tramite l'API */ constructor(data: Data, client: Client) { super(client); diff --git a/src/structures/EventoAppello.ts b/src/structures/EventoAppello.ts index 8f54f8d..afae658 100644 --- a/src/structures/EventoAppello.ts +++ b/src/structures/EventoAppello.ts @@ -24,7 +24,7 @@ export class EventoAppello extends Base { nota!: string; /** - * @param data - The API data + * @param data - I dati ricevuti tramite l'API */ constructor(data: Data, client: Client) { super(client); diff --git a/src/structures/EventoBacheca.ts b/src/structures/EventoBacheca.ts index 2d518d5..3c335d1 100644 --- a/src/structures/EventoBacheca.ts +++ b/src/structures/EventoBacheca.ts @@ -26,7 +26,7 @@ export class EventoBacheca extends Base { dataScadenzaAdesione?: string; /** - * @param data - The API data + * @param data - I dati ricevuti tramite l'API */ constructor(data: Data, client: Client) { super(client); diff --git a/src/structures/EventoBachecaAlunno.ts b/src/structures/EventoBachecaAlunno.ts index 03df6a9..a7e49a1 100644 --- a/src/structures/EventoBachecaAlunno.ts +++ b/src/structures/EventoBachecaAlunno.ts @@ -19,7 +19,7 @@ export class EventoBachecaAlunno extends Base { id!: string; /** - * @param data - The API data + * @param data - I dati ricevuti tramite l'API */ constructor(data: Data, client: Client) { super(client); diff --git a/src/structures/EventoRegistro.ts b/src/structures/EventoRegistro.ts index 3d8f465..a75b6ea 100644 --- a/src/structures/EventoRegistro.ts +++ b/src/structures/EventoRegistro.ts @@ -26,7 +26,7 @@ export class EventoRegistro extends Base { ora!: number; /** - * @param data - The API data + * @param data - I dati ricevuti tramite l'API */ constructor(data: Data, client: Client) { super(client); diff --git a/src/structures/FuoriClasse.ts b/src/structures/FuoriClasse.ts index 2ef7136..cf33175 100644 --- a/src/structures/FuoriClasse.ts +++ b/src/structures/FuoriClasse.ts @@ -21,7 +21,7 @@ export class FuoriClasse extends Base { frequenzaOnline!: boolean; /** - * @param data - The API data + * @param data - I dati ricevuti tramite l'API */ constructor(data: Data, client: Client) { super(client); diff --git a/src/structures/Genitore.ts b/src/structures/Genitore.ts index 1702292..59e2dcd 100644 --- a/src/structures/Genitore.ts +++ b/src/structures/Genitore.ts @@ -17,7 +17,7 @@ export class Genitore extends Base { dataNascita!: string; /** - * @param data - The API data + * @param data - I dati ricevuti tramite l'API */ constructor(data: Data, client: Client) { super(client); diff --git a/src/structures/Login.ts b/src/structures/Login.ts index 7a475e3..4de36e9 100644 --- a/src/structures/Login.ts +++ b/src/structures/Login.ts @@ -18,7 +18,7 @@ export class Login extends Base { username!: string; /** - * @param data - The API data + * @param data - I dati ricevuti tramite l'API */ constructor(data: Data, client: Client) { super(client); diff --git a/src/structures/Materia.ts b/src/structures/Materia.ts index 02f1349..cd839a8 100644 --- a/src/structures/Materia.ts +++ b/src/structures/Materia.ts @@ -16,7 +16,7 @@ export class Materia extends Base { id!: string; /** - * @param data - The API data + * @param data - I dati ricevuti tramite l'API */ constructor(data: Data, client: Client) { super(client); diff --git a/src/structures/MediaMateria.ts b/src/structures/MediaMateria.ts index b04b712..c2e39c1 100644 --- a/src/structures/MediaMateria.ts +++ b/src/structures/MediaMateria.ts @@ -15,7 +15,7 @@ export class MediaMateria extends Base { idMateria: string; /** - * @param data - The API data + * @param data - I dati ricevuti tramite l'API */ constructor(data: Jsonify, client: Client); constructor(data: MediaMateriaData, client: Client, idMateria: string); @@ -25,6 +25,26 @@ export class MediaMateria extends Base { this.patch(data); } + get mediaOrale() { + return this.sommaVotiOrali / this.votiOrali; + } + + get mediaScritto() { + return this.sommaVotiScritti / this.votiScritti; + } + + get sommaVoti() { + return this.sommaVotiScritti + this.sommaVotiOrali; + } + + get voti() { + return this.votiOrali + this.votiScritti; + } + + get media() { + return this.sommaVoti / this.voti; + } + patch(data: Data) { if (this.isJson(data)) this.handleJson(data); else { diff --git a/src/structures/MediaPeriodo.ts b/src/structures/MediaPeriodo.ts index 8fe6eed..e1389fa 100644 --- a/src/structures/MediaPeriodo.ts +++ b/src/structures/MediaPeriodo.ts @@ -14,7 +14,7 @@ export class MediaPeriodo extends Base { mediaMensile!: Record<`${number}`, number>; /** - * @param data - The API data + * @param data - I dati ricevuti tramite l'API */ constructor(data: Data, client: Client) { super(client); diff --git a/src/structures/Orario.ts b/src/structures/Orario.ts index 0a9e8b3..1351857 100644 --- a/src/structures/Orario.ts +++ b/src/structures/Orario.ts @@ -22,7 +22,7 @@ export class Orario extends Base { ora!: null; /** - * @param data - The API data + * @param data - I dati ricevuti tramite l'API */ constructor(data: Data, client: Client) { super(client); diff --git a/src/structures/Periodo.ts b/src/structures/Periodo.ts index 69390b3..e2e9053 100644 --- a/src/structures/Periodo.ts +++ b/src/structures/Periodo.ts @@ -19,7 +19,7 @@ export class Periodo extends Base { scrutinioFinale!: boolean; /** - * @param data - The API data + * @param data - I dati ricevuti tramite l'API */ constructor(data: Data, client: Client) { super(client); diff --git a/src/structures/Prenotazione.ts b/src/structures/Prenotazione.ts index 4e6fd25..6b7f3ab 100644 --- a/src/structures/Prenotazione.ts +++ b/src/structures/Prenotazione.ts @@ -40,7 +40,7 @@ export class Prenotazione extends Base { idDocente!: string; /** - * @param data - The API data + * @param data - I dati ricevuti tramite l'API */ constructor(data: Data, client: Client) { super(client); diff --git a/src/structures/Profilo.ts b/src/structures/Profilo.ts index 8ba6ea1..b33236c 100644 --- a/src/structures/Profilo.ts +++ b/src/structures/Profilo.ts @@ -48,7 +48,7 @@ export class Profilo extends Base { profiloStorico!: boolean; /** - * @param data - The API data + * @param data - I dati ricevuti tramite l'API */ constructor(data: Data, client: Client) { super(client); diff --git a/src/structures/Promemoria.ts b/src/structures/Promemoria.ts index a6f2925..72bda7c 100644 --- a/src/structures/Promemoria.ts +++ b/src/structures/Promemoria.ts @@ -20,7 +20,7 @@ export class Promemoria extends Base { oraFine!: string; /** - * @param data - The API data + * @param data - I dati ricevuti tramite l'API */ constructor(data: Data, client: Client) { super(client); diff --git a/src/structures/Ricevimenti.ts b/src/structures/Ricevimenti.ts index a9464b3..4064332 100644 --- a/src/structures/Ricevimenti.ts +++ b/src/structures/Ricevimenti.ts @@ -17,7 +17,7 @@ export class Ricevimenti extends Base { prenotazioni: Prenotazione[] = []; /** - * @param data - The API data + * @param data - I dati ricevuti tramite l'API */ constructor(data: Data, client: Client) { super(client); @@ -52,7 +52,7 @@ export class Ricevimenti extends Base { /** * Aggiorna questi dati. - * @returns The updated data + * @returns I dati aggiornati */ refresh() { return this.client.getRicevimenti(this); diff --git a/src/structures/Scrutinio.ts b/src/structures/Scrutinio.ts index ca660ba..1f5330b 100644 --- a/src/structures/Scrutinio.ts +++ b/src/structures/Scrutinio.ts @@ -16,7 +16,7 @@ export class Scrutinio extends Base { scrutinioFinale!: boolean; /** - * @param data - The API data + * @param data - I dati ricevuti tramite l'API */ constructor(data: Data, client: Client) { super(client); diff --git a/src/structures/Tassa.ts b/src/structures/Tassa.ts index 0596645..593845b 100644 --- a/src/structures/Tassa.ts +++ b/src/structures/Tassa.ts @@ -31,7 +31,7 @@ export class Tassa extends Base { pagOnLine!: boolean; /** - * @param data - The API data + * @param data - I dati ricevuti tramite l'API */ constructor(data: Data, client: Client) { super(client); diff --git a/src/structures/Token.ts b/src/structures/Token.ts index c900cdc..f692380 100644 --- a/src/structures/Token.ts +++ b/src/structures/Token.ts @@ -15,7 +15,7 @@ export class Token extends Base { tokenType!: string; /** - * @param data - The API data + * @param data - I dati ricevuti tramite l'API */ constructor(data: APIToken, client: Client, date: Date); constructor(data: Jsonify, client: Client); diff --git a/src/structures/Voto.ts b/src/structures/Voto.ts index 65150e9..1e47150 100644 --- a/src/structures/Voto.ts +++ b/src/structures/Voto.ts @@ -30,7 +30,7 @@ export class Voto extends Base { commento!: string; /** - * @param data - The API data + * @param data - I dati ricevuti tramite l'API */ constructor(data: Data, client: Client) { super(client); diff --git a/src/structures/What.ts b/src/structures/What.ts index 7c66157..ffad71f 100644 --- a/src/structures/What.ts +++ b/src/structures/What.ts @@ -16,7 +16,7 @@ export class What extends Base { profilo!: BaseProfilo; /** - * @param data - The API data + * @param data - I dati ricevuti tramite l'API */ constructor(data: Data, client: Client) { super(client); diff --git a/src/types/general.ts b/src/types/general.ts index e38b2f5..6a6722c 100644 --- a/src/types/general.ts +++ b/src/types/general.ts @@ -22,46 +22,58 @@ export type HttpMethod = | "POST" | "PUT" | "TRACE"; -export type BasicCredentials = { +export type Credentials = { /** - * The school code + * Il codice scuola */ schoolCode: string; + /** - * The username + * L'username */ username: string; + /** - * The password + * La password */ password: string; }; export type ClientOptions = Partial< - BasicCredentials & { + Credentials & { /** - * The token data + * I dati del token */ token: Token; + /** - * The login data + * I dati del login */ loginData: Login; + /** - * The profile data + * I dati del profilo */ profile: Profilo; + /** - * The dashboard data + * I dati della dashboard */ dashboard: Dashboard; + /** - * Whether to log some useful data + * Se scrivere nella console alcuni dati utili per il debug */ debug: boolean; + /** - * Additional http headers for the requests + * Headers aggiuntivi per ogni richiesta API */ headers: IncomingHttpHeaders; + + /** + * Il percorso della cartella dove salvare i dati + */ + dataPath: string | null; } >; export type Jsonify = [ diff --git a/src/util/apiRequest.ts b/src/util/apiRequest.ts index e0805e6..c8d10e5 100644 --- a/src/util/apiRequest.ts +++ b/src/util/apiRequest.ts @@ -3,11 +3,11 @@ import type { Client, HttpMethod, Json } from ".."; import { formatDate } from ".."; /** - * Perform an API request. - * @param path - The path for the request - * @param client - The client - * @param options - Other options - * @returns The JSON response + * Effettua una richiesta API. + * @param path - Il percorso della richiesta + * @param client - Il client + * @param options - Altre opzioni + * @returns La risposta */ export const apiRequest = async ( path: string, diff --git a/src/util/arrayToObject.ts b/src/util/arrayToObject.ts deleted file mode 100644 index 971a5c6..0000000 --- a/src/util/arrayToObject.ts +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Convert an API array to an object. - * @param array - The array to convert - * @param map - The function to convert an element - * @returns The new object - */ -export const arrayToObject = < - T, - A extends { - [key in N]: string; - }, - N extends keyof A | "pk" = "pk" ->( - array: A[], - map: (d: A) => T, - pk = "pk" as N -): Record => - Object.fromEntries( - array.map((d) => [ - d[pk], - { - id: d[pk], - ...map(d), - }, - ]) - ); diff --git a/src/util/encryptCodeVerifier.ts b/src/util/encryptCodeVerifier.ts index 2c50a5e..5f714d8 100644 --- a/src/util/encryptCodeVerifier.ts +++ b/src/util/encryptCodeVerifier.ts @@ -1,9 +1,9 @@ import CryptoJS from "crypto-js"; /** - * Encrypt a code verifier. - * @param codeVerifier - The code to encrypt - * @returns The encrypted code + * Crittografa un codice. + * @param codeVerifier - Il codice + * @returns Il codice crittografato */ export const encryptCodeVerifier = (codeVerifier: string) => CryptoJS.SHA256(codeVerifier).toString(CryptoJS.enc.Base64url); diff --git a/src/util/formatDate.ts b/src/util/formatDate.ts index 4299ed7..2c22303 100644 --- a/src/util/formatDate.ts +++ b/src/util/formatDate.ts @@ -1,7 +1,7 @@ /** - * Format a date for the API. - * @param date - The date to format - * @returns The formatted date + * Formatta una data dell'API + * @param date - La data + * @returns La data formattata */ export const formatDate = (date: Date | number | string) => { date = new Date(date); diff --git a/src/util/generateLoginLink.ts b/src/util/generateLoginLink.ts new file mode 100644 index 0000000..bb19f94 --- /dev/null +++ b/src/util/generateLoginLink.ts @@ -0,0 +1,37 @@ +import { clientId, encryptCodeVerifier, randomString } from ".."; + +/** + * Genera un link per il login tramite browser. + * @param param0 - Le opzioni per generare il link + * @returns L'url generato con gli altri dati utilizzati + */ +export const generateLoginLink = ({ + redirectUri = "it.argosoft.didup.famiglia.new://login-callback", + scopes = ["openid", "offline", "profile", "user.roles", "argo"], + codeVerifier = randomString(43), + challenge = encryptCodeVerifier(codeVerifier), + id = clientId, + state = randomString(22), + nonce = randomString(22), +}: { + redirectUri?: string; + scopes?: string[]; + codeVerifier?: string; + challenge?: string; + id?: string; + state?: string; + nonce?: string; +} = {}) => ({ + url: `https://auth.portaleargo.it/oauth2/auth?redirect_uri=${encodeURIComponent( + redirectUri + )}&client_id=${id}&response_type=code&prompt=login&state=${state}&nonce=${nonce}&scope=${encodeURIComponent( + scopes.join(" ") + )}&code_challenge=${challenge}&code_challenge_method=S256`, + redirectUri, + scopes, + codeVerifier, + challenge, + clientId: id, + state, + nonce, +}); diff --git a/src/util/handleOperation.ts b/src/util/handleOperation.ts index 7eca173..a671891 100644 --- a/src/util/handleOperation.ts +++ b/src/util/handleOperation.ts @@ -1,10 +1,11 @@ import type { APIOperation, Json } from ".."; /** - * Handle an array of operations from the API. - * @param array - The array from the API - * @param old - The array to modify - * @param map - A function to convert the API type + * Gestisci dei dati dell'API contenenti un'operazione. + * @param array - L'array ricevuto + * @param old - L'eventuale array da modificare + * @param map - Una funzione per convertire l'array + * @returns Il nuovo array */ export const handleOperation = < P extends { diff --git a/src/util/importData.ts b/src/util/importData.ts index b99ed67..9902e93 100644 --- a/src/util/importData.ts +++ b/src/util/importData.ts @@ -4,14 +4,15 @@ import type { Jsonify } from ".."; import { AuthFolder } from ".."; /** - * Import a data file. - * @param name - The file name without the extension - * @returns The imported json + * Importa dei dati salvati in un file. + * @param name - Il nome del file, escludendo l'estensione + * @returns I dati importati */ export const importData = async ( - name: string + name: string, + path = AuthFolder ): Promise | undefined> => - readFile(join(AuthFolder, `${name}.json`), { + readFile(join(path, `${name}.json`), { encoding: "utf8", }) .then(async (content) => JSON.parse(content) as Jsonify) diff --git a/src/util/index.ts b/src/util/index.ts index 57a0bb8..f9f12cf 100644 --- a/src/util/index.ts +++ b/src/util/index.ts @@ -1,9 +1,9 @@ -export * from "./apiRequest"; -export * from "./arrayToObject"; export * from "./Constants"; +export * from "./apiRequest"; export * from "./encryptCodeVerifier"; export * from "./formatDate"; +export * from "./generateLoginLink"; +export * from "./handleOperation"; export * from "./importData"; export * from "./randomString"; export * from "./writeToFile"; -export * from "./handleOperation"; diff --git a/src/util/randomString.ts b/src/util/randomString.ts index b022d84..c62778b 100644 --- a/src/util/randomString.ts +++ b/src/util/randomString.ts @@ -2,9 +2,9 @@ const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; /** - * Generate a random string of `length` characters. - * @param length - The length of the string to generate - * @returns The generated random string + * Genera una stringa casuale. + * @param length - La lunghezza della stringa + * @returns La stringa generata */ export const randomString = (length: number) => { let result = ""; diff --git a/src/util/writeToFile.ts b/src/util/writeToFile.ts index 718ac48..ee241c5 100644 --- a/src/util/writeToFile.ts +++ b/src/util/writeToFile.ts @@ -3,11 +3,11 @@ import { join } from "node:path"; import { AuthFolder } from ".."; /** - * Write the response of a request to a json file. - * @param name - The file name without the extension - * @param value - The content to write + * Salva dei dati in un file JSON. + * @param name - Il nome del file, escludendo l'estensione + * @param value - I dati da scrivere */ -export const writeToFile = (name: string, value: unknown) => - writeFile(`${join(AuthFolder, name)}.json`, JSON.stringify(value)).catch( +export const writeToFile = (name: string, value: unknown, path = AuthFolder) => + writeFile(`${join(path, name)}.json`, JSON.stringify(value)).catch( console.error );