1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
const errors = require('./errors');
const cas = require('./cas');
const { decipher, getLoginKey } = require('./cipher');
const getAccountType = require('./accounts');
const PronoteSession = require('./session');
const getParams = require('./fetch/pronote/params');
const { getId, getAuthKey } = require('./fetch/pronote/auth');
const getUser = require('./fetch/pronote/user');
function loginFor(type)
{
return (url, username, password, cas = 'none') => login(url, username, password, cas, getAccountType(type));
}
async function login(url, username, password, cas, account)
{
const server = getServer(url);
const start = await getStart(server, username, password, cas, account);
const session = new PronoteSession({
serverURL: server,
sessionID: start.h,
type: account,
disableAES: !!start.sCrA,
disableCompress: !!start.sCoA,
keyModulus: start.MR,
keyExponent: start.ER
})
session.params = await getParams(session);
if (!session.params) {
throw errors.WRONG_CREDENTIALS.drop();
}
if (cas === 'none') {
await auth(session, username, password, false);
} else {
await auth(session, start.e, start.f, true);
}
session.user = await getUser(session);
return session;
}
function getServer(url)
{
if (url.endsWith('.html')) {
return url.substring(0, url.lastIndexOf('/') + 1);
}
if (!url.endsWith('/')) {
url += '/';
}
return url;
}
async function getStart(url, username, password, casName, type)
{
if (casName === 'names' || casName === 'getCAS' || !cas[casName]) {
throw errors.UNKNOWN_CAS.drop(casName);
}
const account = typeof type === 'string' ? getAccountType(type) : type;
return await cas[casName](url, account, username, password);
}
async function auth(session, username, password, fromCas)
{
const id = await getId(session, username, fromCas);
const key = getLoginKey(username, password, id.scramble, fromCas);
let challenge;
try {
challenge = decipher(session, id.challenge, { scrambled: true, key });
} catch (e) {
throw errors.WRONG_CREDENTIALS.drop();
}
const userKey = await getAuthKey(session, challenge, key);
if (!userKey) {
throw errors.WRONG_CREDENTIALS.drop();
}
session.aesKey = decipher(session, userKey, { key, asBytes: true });
}
module.exports = {
loginStudent: loginFor('student'),
loginParent: loginFor('parent'),
getStart,
auth
};
|