1
0
Fork 0
mirror of https://github.com/classchartsapi/classcharts-api-js.git synced 2026-05-14 19:59:37 +00:00

fix: revalidate auth token

This commit is contained in:
James Cook 2023-04-07 12:43:46 +01:00
parent 91e956b642
commit 797c43ed56
6 changed files with 523 additions and 487 deletions

View file

@ -25,7 +25,7 @@
"author": "James Cook", "author": "James Cook",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"axios": "^1.2.0" "axios": "^1.3.5"
}, },
"files": [ "files": [
"dist/**" "dist/**"
@ -47,5 +47,13 @@
"types": "./dist/index.d.ts", "types": "./dist/index.d.ts",
"volta": { "volta": {
"node": "18.12.1" "node": "18.12.1"
},
"exports": {
".": {
"import": "./dist/index.js",
"require": "./dist/index.js"
},
"./types": "./dist/index.d.ts",
"./package.json": "./package.json"
} }
} }

940
pnpm-lock.yaml generated

File diff suppressed because it is too large Load diff

View file

@ -18,14 +18,16 @@ import type {
LessonsResponse, LessonsResponse,
Student, Student,
} from "./types"; } from "./types";
import { PING_INTERVAL } from "./consts";
/** /**
* The base client * The base client
*/ */
export class ClasschartsClient { export class ClasschartsClient {
protected studentId = 0; public studentId = 0;
protected studentName = "";
public authCookies: Array<string> | undefined; public authCookies: Array<string> | undefined;
public sessionId = ""; public sessionId = "";
public lastPing = 0;
protected API_BASE = ""; protected API_BASE = "";
protected axios: AxiosInstance; protected axios: AxiosInstance;
/** /**
@ -42,21 +44,49 @@ export class ClasschartsClient {
validateStatus: () => true, validateStatus: () => true,
}); });
} }
public async getNewSessionId() {
const pingFormData = new URLSearchParams();
pingFormData.append("include_data", "true");
const pingData = await this.makeAuthedRequest(
this.API_BASE + "/ping",
{
method: "POST",
data: pingFormData.toString(),
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
},
{ includeMeta: true, revalidateToken: false }
);
this.sessionId = pingData.meta.session_id;
this.lastPing = Date.now();
}
public async makeAuthedRequest( public async makeAuthedRequest(
path: string, path: string,
axiosOptions: Omit<AxiosRequestConfig, "path">, axiosOptions: Omit<AxiosRequestConfig, "path">,
options?: { includeMeta?: boolean } options?: { includeMeta?: boolean; revalidateToken?: boolean }
) { ) {
if (!this.authCookies) throw new Error("Not authenticated"); if (!this.sessionId) throw new Error("No session ID");
if (!options) {
options = {};
}
if (typeof options?.revalidateToken == "undefined") {
options.revalidateToken = true;
}
const requestOptions: AxiosRequestConfig = { const requestOptions: AxiosRequestConfig = {
...axiosOptions, ...axiosOptions,
url: path, url: path,
headers: { headers: {
Cookie: this.authCookies.join(";"), Cookie: this?.authCookies?.join(";") ?? [],
authorization: "Basic " + this.sessionId, authorization: "Basic " + this.sessionId,
...axiosOptions.headers, ...axiosOptions.headers,
}, },
}; };
if (options?.revalidateToken === true && this.lastPing) {
if (Date.now() - this.lastPing + 5000 > PING_INTERVAL) {
await this.getNewSessionId();
}
}
const request = await this.axios.request(requestOptions); const request = await this.axios.request(requestOptions);
const responseJSON = request.data; const responseJSON = request.data;
if (responseJSON.success == 0) { if (responseJSON.success == 0) {

View file

@ -1,3 +1,5 @@
export const BASE_URL = "https://www.classcharts.com"; export const BASE_URL = "https://www.classcharts.com";
export const API_BASE_STUDENT = `${BASE_URL}/apiv2student`; export const API_BASE_STUDENT = `${BASE_URL}/apiv2student`;
export const API_BASE_PARENT = `${BASE_URL}/apiv2parent`; export const API_BASE_PARENT = `${BASE_URL}/apiv2parent`;
export const PING_INTERVAL = 180 * 1000; // 3 minutes

View file

@ -61,7 +61,6 @@ export class ClasschartsParentClient extends ClasschartsClient {
this.pupils = await this.getPupils(); this.pupils = await this.getPupils();
if (!this.pupils) throw new Error("Account has no pupils attached"); if (!this.pupils) throw new Error("Account has no pupils attached");
this.studentId = this.pupils[0].id; this.studentId = this.pupils[0].id;
this.studentName = this.pupils[0].name;
} }
/** /**
* Get Pupil details * Get Pupil details
@ -83,7 +82,6 @@ export class ClasschartsParentClient extends ClasschartsClient {
const pupil = pupils[i]; const pupil = pupils[i];
if (pupil.id == pupilId) { if (pupil.id == pupilId) {
this.studentId = pupil.id; this.studentId = pupil.id;
this.studentName = pupil.name;
return; return;
} }
} }

View file

@ -55,22 +55,8 @@ export class ClasschartsStudentClient extends ClasschartsClient {
String(sessionCookies["student_session_credentials"]) String(sessionCookies["student_session_credentials"])
); );
this.sessionId = sessionID.session_id; this.sessionId = sessionID.session_id;
await this.getNewSessionId();
const user = await this.getStudentInfo(); const user = await this.getStudentInfo();
this.studentId = user.id; this.studentId = user.id;
this.studentName = user.name;
const pingFormData = new URLSearchParams();
pingFormData.append("include_data", "true");
const pingData = await this.makeAuthedRequest(
this.API_BASE + "/ping",
{
method: "POST",
data: pingFormData.toString(),
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
},
{ includeMeta: true }
);
this.sessionId = pingData.meta.session_id;
} }
} }