Closed AntogamerYT closed 1 year ago
Tutte le cose che terminano con REDACTED sono censurate da me
Conducendo delle mie ricerche, ho notato che la nuova app di argo fa 4 richieste principali:
/.well-known/openid-configuration penso che sia qualcosa per l'oauth questi sono gli headers che manda e questa è la risposta che l'app riceve:
{
"issuer": "https://auth.portaleargo.it/",
"authorization_endpoint": "https://auth.portaleargo.it/oauth2/auth",
"token_endpoint": "https://auth.portaleargo.it/oauth2/token",
"jwks_uri": "https://auth.portaleargo.it/.well-known/jwks.json",
"subject_types_supported": [
"public"
],
"response_types_supported": [
"code",
"code id_token",
"id_token",
"token id_token",
"token",
"token id_token code"
],
"claims_supported": [
"sub"
],
"grant_types_supported": [
"authorization_code",
"implicit",
"client_credentials",
"refresh_token"
],
"response_modes_supported": [
"query",
"fragment"
],
"userinfo_endpoint": "https://auth.portaleargo.it/userinfo",
"scopes_supported": [
"offline_access",
"offline",
"openid"
],
"token_endpoint_auth_methods_supported": [
"client_secret_post",
"client_secret_basic",
"private_key_jwt",
"none"
],
"userinfo_signing_alg_values_supported": [
"none",
"RS256"
],
"id_token_signing_alg_values_supported": [
"RS256"
],
"request_parameter_supported": true,
"request_uri_parameter_supported": true,
"require_request_uri_registration": true,
"claims_parameter_supported": false,
"revocation_endpoint": "https://auth.portaleargo.it/oauth2/revoke",
"backchannel_logout_supported": true,
"backchannel_logout_session_supported": true,
"frontchannel_logout_supported": true,
"frontchannel_logout_session_supported": true,
"end_session_endpoint": "https://auth.portaleargo.it/oauth2/sessions/logout",
"request_object_signing_alg_values_supported": [
"RS256",
"none"
]
}
visto che sono troppo pigro, non farò una spiegazione completa degli altri endpoint visto che puoi anche arrivarci da solo:
https://auth.portaleargo.it/oauth2/token Headers richiesta Request body Risposta Response body
{
"access_token": "REDACTED",
"expires_in": 3599,
"id_token": "IDTOKEN_REDACTED",
"refresh_token": "REFRESHTOKEN_REDACTED",
"scope": "openid offline profile user.roles argo",
"token_type": "bearer"
}
https://www.portaleargo.it/appfamiglia/api/rest/dashboard/what - returna i dati dell'utente
Headers richiesta Request Body
{
"dataultimoaggiornamento": "2022-09-20 20:50:41.758101",
"opzioni": "{\"ORARIO_SCOLASTICO\":true,\"PAGELLINO_ONLINE\":true,\"VALUTAZIONI_PERIODICHE\":true,\"VALUTAZIONI_GIORNALIERE\":true,\"COMPITI_ASSEGNATI\":true,\"IGNORA_OPZIONE_VOTI_DOCENTI\":false,\"DOCENTI_CLASSE\":true,\"RENDI_VISIBILE_CURRICULUM\":true,\"RICHIESTA_CERTIFICATI\":false,\"MODIFICA_RECAPITI\":true,\"CONSIGLIO_DI_ISTITUTO\":true,\"NOTE_DISCIPLINARI\":true,\"GIUDIZI\":false,\"GIUSTIFICAZIONI_ASSENZE\":true,\"TABELLONE_PERIODI_INTERMEDI\":false,\"PAGELLE_ONLINE\":true,\"ASSENZE_PER_DATA\":true,\"ARGOMENTI_LEZIONE\":false,\"NASCONDI_DIDUP_FAMIGLIA\":true,\"ALILITA_BSMART_FAMIGLIA\":false,\"VOTI_GIUDIZI\":true,\"ABILITA_AUTOCERTIFICAZIONE_FAM\":false,\"TABELLONE_SCRUTINIO_FINALE\":false,\"PIN_VOTI\":false,\"DISABILITA_ACCESSO_FAMIGLIA\":true,\"TASSE_SCOLASTICHE\":true,\"PROMEMORIA_CLASSE\":true,\"PRENOTAZIONE_ALUNNI\":true,\"CONSIGLIO_DI_CLASSE\":true}",
"lista-x-auth-token": "[\"REDACTED\"]",
"lista-x-auth-token-account": "[\"REDACTED\",\"REDACTED\",\"REDACTED\"]"
}
Risposta Response body Questo non lo caricherò perchè dovrei censurare praticamente tutto, quindi per scoprire che cosa returna ti consiglio di usare http toolkit con un telefono rootato oppure anche bluestacks/Windows Subsystem for Android dovrebbe andare utilizzando Telerik Fiddler Classic
https://www.portaleargo.it/appfamiglia/api/rest/dashboard/aggiornadata Headers richiesta Request body:
{
"dataultimoaggiornamento": "2022-09-20 23:21:05.621460"
}
Risposta Body risposta
Spero che questi dati ti siano utili per fixare la lib, fammi sapere se ci riuscirai
ah e magari prova a decompilare l'apk di argo famiglia, che forse potresti trovare anche altre richieste
@AntogamerYT non manca la prima parte della conversazione? quella che porta all'ottenimento del refresh_token
?
@paoloantinori yep, alla fine ho capito tutti gli endpoint e appena posso faccio una repo dove documento il tutto, però puoi incominciare ad ottentere un refresh token utilizzando http toolkit debuggando le richieste che l'app fa nell'endpoint oauth2/token , così ti prendi il refresh_token e ci fai quello che vuoi
Ciao, grazie. Era giusto il mio piano per le prossime mosse. Speravo di evitarlo e di trovare un'implementazione dell auth già fatta in quanto ora come ora non ho un Android rootato comodo e Genymotion non riesce a lanciare Didup.
Se qualcuno fosse più avanti di me e cercasse un betatester, contate su di me 👍
per l'auth senza trovare il refresh token manualmente ci devo ancora lavorare, perchè quando si fa il login argo crea una login challenge da cui manda la richiesta con codice scuola, user e pass, il problema è che non capisco come generare la login challenge, per questo si usa il refresh token, che poi genera un access token che viene salvato in un object (questo è il metodo che ho utilizzato per ora, magari c'è un metodo migliore per farlo) sul disco
per ora ho giocato solo a replicare in curl
l'auth del sito. E, se stiamo parlando della stessa cosa, la challange
li', la estraggo da una prima chiamata a https://www.portaleargo.it/argoweb/famiglia/index1.jsp
. Se non ricordo male e' un parametro hidden del form.
Ma scusami, quindi tu mi dici che il refreshe token e' statico? Non viene restituito da una prima (o seconda) chiamata dei flussi standard di Oauth?
@paoloantinori il refresh token viene dato dall'enpoint oauth2/token e, come ogni sistema basato su oauth2, il refresh token non scade mai e serve per generare altri access token/nuovo refresh token
comunque, per ora questa è la mia implementazione del login:
const axios = (await import('axios')).default
import fs from 'fs'
export async function login() {
const now = handleDate(Date.now())
const creds = JSON.parse(fs.readFileSync(process.cwd()+'/creds.json', 'utf-8'))
var dataoa = qs.stringify({
'refresh_token': global.refresh || creds.refresh_token,
'grant_type': 'refresh_token',
'scope': 'openid offline profile user.roles argo',
'redirect_uri': 'it.argosoft.didup.famiglia.new://login-callback',
'client_id': '72fd6dea-d0ab-4bb9-8eaa-3ac24c84886c'
});
var configoa = {
method: 'post',
url: 'https://auth.portaleargo.it/oauth2/token',
headers: {
'accept': 'application/json',
'accept-encoding': 'gzip',
'content-type': 'application/x-www-form-urlencoded',
'user-agent': 'Dalvik/2.1.0 (Linux; U; Android 12; SM-N960F Build/SQ3A.220705.004)'
},
data : dataoa
}
try {
const resoa = await axios(configoa)
global.bearer = resoa.data.access_token
global.refresh = resoa.data.refresh_token
await fs.writeFileSync(process.cwd() + '/creds.json', JSON.stringify({
access_token: global.bearer,
refresh_token: global.refresh,
token: ""
}))
} catch (error) {
console.log(error)
}
var data = '{\r\n "clientID": "dfnW3d4STtm1_HWiXFw36t:APA91bEiQDMnZS8GAHYYMvv1gZce14bFkCa7D2ve0TEYDZIL-zCE7ZzcuV3O7V87-V50ZN3pGYkOeqZivMOtH0aU0nTyfJmV7pK6VE31mj3qb156Px1ETpgA0fGg2hqHASiVVmYPX_L9",\r\n "lista-x-auth-token": "[\\"bc26e5cb-2c4c-4ce3-ade2-9a5877fe7d76\\",\\"5b51c43c-7f15-4a60-83b3-941f4e183ae2\\",\\"2e192091-97f6-4329-9e8a-b036b1e538ff\\"]",\r\n "x-auth-token-corrente": "bc26e5cb-2c4c-4ce3-ade2-9a5877fe7d76",\r\n "lista-opzioni-notifiche": "{\\"bc26e5cb-2c4c-4ce3-ade2-9a5877fe7d76\\":\\"#BAC#CON#COM#VOT#NOT#APP#ASS#BAL#RIC#PRE#SCR#OPZ#GIU\\",\\"5b51c43c-7f15-4a60-83b3-941f4e183ae2\\":\\"#BAC#CON#COM#VOT#NOT#APP#ASS#BAL#RIC#PRE#SCR#OPZ#GIU\\",\\"2e192091-97f6-4329-9e8a-b036b1e538ff\\":\\"#BAC#CON#COM#VOT#NOT#APP#ASS#BAL#RIC#PRE#SCR#OPZ#GIU\\"}"\r\n}';
var config = {
method: 'post',
url: 'https://www.portaleargo.it/appfamiglia/api/rest/login', // serve per ottenere il token dell'account
headers: {
'accept': 'application/json',
'accept-encoding': 'gzip',
'argo-client-version': '1.9.1',
'Authorization': 'Bearer ' + global.bearer,
'content-type': 'application/json; charset=utf-8',
'os-type': 'android SQ3A.220705.004',
'user-agent': 'Dart/2.14 (dart:io)',
'x-cod-min': 'null'
},
data : data
}
try {
const loginrest = await axios(config)
global.token = loginrest.data.data[0].token
await fs.writeFileSync(process.cwd() + '/creds.json', JSON.stringify({
access_token: global.bearer,
refresh_token: global.refresh,
token: global.token
}))
} catch (error) {
console.log(error)
}
let update_data = `{\r\n "dataultimoaggiornamento": "${now.postDate} ${now.time}.002524"\r\n}`;
let update_config = {
method: 'post',
url: 'https://www.portaleargo.it/appfamiglia/api/rest/dashboard/aggiornadata',
headers: {
'accept': 'application/json',
'accept-encoding': 'gzip',
'Authorization': 'Bearer ' + global.bearer,
'content-type': 'application/json; charset=utf-8',
'os-type': 'android SQ3A.220705.004',
'user-agent': 'Dart/2.14 (dart:io)',
'x-auth-token': global.token,
'x-cod-min': process.env.CODICESCUOLA!
},
data : update_data
};
await axios(update_config)
}
const handleDate = (dataD: any) => {
let data= new Date(dataD)
const locale = data.toLocaleString('en-ZA', { timeZone: 'Europe/Rome' })
let month = data.getMonth() + 1
let day = data.getDate()
let year = data.getFullYear()
if(day<=9)
day = '0' + day
if(month<10)
month = '0' + month
const postDate = year + '-' + month + '-' + day
const time = locale.split(',')[1].split(' ')[1]
return {postDate, time}
}
grazie! mi sa che seguiro' il tuo consiglio e mi tirero' fuori un primo token valido che mi sembra il modo piu' pratico!
Ciao, ho appena scoperto questo issue ahah. Ho creato questa librearia per mettermi alla prova nella creazione di un package npm e dopo averla finita non l'ho più modificata. Comunque l'errore è causato da un aggiornamento dell'api da parte dei programmatori di Argo come detto da te. Io al momento non posso sistemarlo perché sono in Erasmus. Se vuoi potresti creare una pull request con le modifiche (ma non credo ne valga la pena perché da quello che ho notato dalle informazioni che mi hai dato, hanno cambiato quasi tutto e c'è da fare una ricerca per i nuovi endpoint) oppure potresti creare una nuova repo (e credo che tu lo stia già facendo). Se creerai una nuova repo archivierò questa e lascerò un link alla tua come "redirect".
Comunque, l'issue è scritto in modo fantastico e le informazioni che hai allegato sono molto utili a capire come sistemare, complimenti : )
@ReLoia grazie, per ora ho solo creato la repo ma molto presto incomincerò a riempirla con tutto il codice
Questo problema è aperto da circa 6 mesi. Ieri ho creato una soluzione temporanea utilizzando Puppeteer, in attesa che @AntogamerYT aggiorni la sua repository con la sua soluzione al problema.
Purtroppo, non ho un telefono con root e non ho la possibilità di cercare una soluzione utilizzando l'applicazione per ottenere le richieste necessarie. Obiettivamente, preferirei qualsiasi altra soluzione, poiché quella attuale è lenta e non molto stabile.
Comunque, con questa soluzione, posso chiudere l'issue. Tuttavia, ribadisco che se @AntogamerYT aggiornerà la sua repository, archivierò questa repository e l'aggiornerò con un link alla soluzione di @AntogamerYT.
Questo problema è aperto da circa 6 mesi. Ieri ho creato una soluzione temporanea utilizzando Puppeteer, in attesa che @AntogamerYT aggiorni la sua repository con la sua soluzione al problema.
Purtroppo, non ho un telefono con root e non ho la possibilità di cercare una soluzione utilizzando l'applicazione per ottenere le richieste necessarie. Obiettivamente, preferirei qualsiasi altra soluzione, poiché quella attuale è lenta e non molto stabile.
Comunque, con questa soluzione, posso chiudere l'issue. Tuttavia, ribadisco che se @AntogamerYT aggiornerà la sua repository, archivierò questa repository e l'aggiornerò con un link alla soluzione di @AntogamerYT.
Ciao, non ho mai avuto tempo di toccare le api di argo visto che sono abbastanza complicate, comunque l'alternativa con puppeteer sembra buona, ma sto cercando un modo per evitare di usarlo. la cosa che mi ha bloccato è la generazione del client id, penso sia uno uuid, proverò a generarne uno e vedere come reagisce se provo a fare una richiesta utilizzandolo detto questo, spero di aggiornarla al più presto possibile la repo
ho appena controllato https://www.portaleargo.it/argoweb/famiglia/index1.jsp e sembra avere sia la challenge che il client id
Buonasera, sono un amico di @AntogamerYT
Nel mentre sviluppavo un mio progetto personale (Registro elettronico material 3 per Android) ho scelto di iniziare a capire come funzionasse il login di argo.
Stamattina abbiamo chiamato direttamente argo ma a detta loro "non possono comunicarci questi dati via telefono perchè sono privati"
Questo pomeriggio mi sono messo a lavoro utilizzando dei packet capture di Anto e sono riuscito a far funzionare l'autenticazione.
Appena anto è disponibile ci muoviamo per aggiornare questa repo o altro. Non ho argo quindi non so neanche i suoi piani per come continuare.
Molto interessante, grazie! Io ho notato che and m utilizzando il refresh token ottenuto dall app , manage l'app out of sync, con il risultato di per usare o solo l'app o solo il codice esterno. Purtroppo questa limitazione era un po' troppo scomoda, motivo per cui ho messo in pausa le mie prove.
Ma una soluzione completa che possa replicare l'autenticazione completamente migliorerebbe molto le cose e sarebbe quindi ancora molto interessante, per cui se avete qualcosa da condividere mi tornerebbe molto utile!
Ciao, so che questa lib non è aggiornata da molto ma quando provo a fare l'accesso la lib da un 404, penso che il link della api sia stato cambiato