jsjiit
Version:
Browser-compatible API for interacting with JIIT (Jaypee Institute of Information Technology) WebPortal. Bypasses CAPTCHA :)
889 lines (882 loc) • 32.8 kB
JavaScript
// src/exceptions.js
var APIError = class extends Error {
constructor(message) {
super(message);
this.name = "APIError";
}
};
var LoginError = class extends APIError {
constructor(message) {
super(message);
this.name = "LoginError";
}
};
var SessionError = class extends Error {
constructor(message) {
super(message);
this.name = "SessionError";
}
};
var SessionExpired = class extends SessionError {
constructor(message) {
super(message);
this.name = "SessionExpired";
}
};
var NotLoggedIn = class extends SessionError {
constructor(message) {
super(message);
this.name = "NotLoggedIn";
}
};
var AccountAPIError = class extends Error {
constructor(message) {
super(message);
this.name = "AccountAPIError";
}
};
// src/registration.js
var RegisteredSubject = class _RegisteredSubject {
/**
* Class containing registered subject info like Lecturer name, credits, etc
* @param {string} employee_name - Name of the employee/lecturer
* @param {string} employee_code - Code of the employee
* @param {string} minor_subject - Minor subject information
* @param {string} remarks - Any remarks
* @param {string} stytype - Style type
* @param {number} credits - Number of credits
* @param {string} subject_code - Code of the subject
* @param {string} subject_component_code - Component code of the subject
* @param {string} subject_desc - Description of the subject
* @param {string} subject_id - ID of the subject
* @param {string} audtsubject - Audit subject information
*/
constructor(employee_name, employee_code, minor_subject, remarks, stytype, credits, subject_code, subject_component_code, subject_desc, subject_id, audtsubject) {
this.employee_name = employee_name;
this.employee_code = employee_code;
this.minor_subject = minor_subject;
this.remarks = remarks;
this.stytype = stytype;
this.credits = credits;
this.subject_code = subject_code;
this.subject_component_code = subject_component_code;
this.subject_desc = subject_desc;
this.subject_id = subject_id;
this.audtsubject = audtsubject;
}
/**
* Static method to create a RegisteredSubject from a JSON object
* @param {object} resp - JSON object representing RegisteredSubject
* @returns {RegisteredSubject} A new RegisteredSubject instance
*/
static from_json(resp) {
return new _RegisteredSubject(
resp["employeename"],
resp["employeecode"],
resp["minorsubject"],
resp["remarks"],
resp["stytype"],
resp["credits"],
resp["subjectcode"],
resp["subjectcomponentcode"],
resp["subjectdesc"],
resp["subjectid"],
resp["audtsubject"]
);
}
};
var Registrations = class {
/**
* Class containing all registered subjects and total course credits for the semester
* @param {object} resp - JSON response object with registrations and total credits
*/
constructor(resp) {
this.raw_response = resp;
this.total_credits = resp["totalcreditpoints"];
this.subjects = resp["registrations"].map(RegisteredSubject.from_json);
}
};
// src/attendance.js
var AttendanceHeader = class _AttendanceHeader {
/**
* Class which contains header info in the Attendance API
* @param {string} branchdesc - Description of the branch
* @param {string} name - Name of the student or entity
* @param {string} programdesc - Description of the program
* @param {string} stynumber - Style number or identifier
*/
constructor(branchdesc, name, programdesc, stynumber) {
this.branchdesc = branchdesc;
this.name = name;
this.programdesc = programdesc;
this.stynumber = stynumber;
}
/**
* Static method to create an AttendanceHeader from a JSON object
* @param {object} resp - JSON object representing AttendanceHeader
* @returns {AttendanceHeader} A new AttendanceHeader instance
*/
static from_json(resp) {
return new _AttendanceHeader(resp.branchdesc, resp.name, resp.programdesc, resp.stynumber);
}
};
var Semester = class _Semester {
/**
* Class which contains Semester info
* @param {string} registration_code - Registration code of the semester
* @param {string} registration_id - Registration ID of the semester
*/
constructor(registration_code, registration_id) {
this.registration_code = registration_code;
this.registration_id = registration_id;
}
/**
* Static method to create a Semester from a JSON object
* @param {object} resp - JSON object representing Semester
* @returns {Semester} A new Semester instance
*/
static from_json(resp) {
return new _Semester(resp.registrationcode, resp.registrationid);
}
};
var AttendanceMeta = class {
/**
* Class which contains metadata for Attendance
* @param {object} resp - JSON response object with headers and semesters
*/
constructor(resp) {
this.raw_response = resp;
this.headers = resp.headerlist.map(AttendanceHeader.from_json);
this.semesters = resp.semlist.map(Semester.from_json);
}
/**
* Returns the latest AttendanceHeader
* @returns {AttendanceHeader} The first header in the list
*/
latest_header() {
return this.headers[0];
}
/**
* Returns the latest Semester
* @returns {Semester} The first semester in the list
*/
latest_semester() {
return this.semesters[0];
}
};
// src/exam.js
var ExamEvent = class _ExamEvent {
/**
* Class containing exam event info
* @param {string} exam_event_code - Code of the exam event
* @param {number} event_from - Event from timestamp
* @param {string} exam_event_desc - Description of the exam event
* @param {string} registration_id - Registration ID
* @param {string} exam_event_id - Exam event ID
*/
constructor(exam_event_code, event_from, exam_event_desc, registration_id, exam_event_id) {
this.exam_event_code = exam_event_code;
this.event_from = event_from;
this.exam_event_desc = exam_event_desc;
this.registration_id = registration_id;
this.exam_event_id = exam_event_id;
}
/**
* Static method to create an ExamEvent from a JSON object
* @param {object} resp - JSON object representing ExamEvent
* @returns {ExamEvent} A new ExamEvent instance
*/
static from_json(resp) {
return new _ExamEvent(
resp["exameventcode"],
resp["eventfrom"],
resp["exameventdesc"],
resp["registrationid"],
resp["exameventid"]
);
}
};
// src/utils.js
function generate_date_seq(date = null) {
if (date === null) {
date = /* @__PURE__ */ new Date();
}
const day = String(date.getDate()).padStart(2, "0");
const month = String(date.getMonth() + 1).padStart(2, "0");
const year = String(date.getFullYear()).slice(2);
const weekday = String(date.getDay());
return day[0] + month[0] + year[0] + weekday + day[1] + month[1] + year[1];
}
function get_random_char_seq(n) {
const charset = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
let result = "";
for (let i = 0; i < n; i++) {
const randomIndex = Math.floor(Math.random() * charset.length);
result += charset[randomIndex];
}
return result;
}
// src/encryption.js
function base64Encode(data) {
return btoa(String.fromCharCode.apply(null, new Uint8Array(data)));
}
var IV = new TextEncoder().encode("dcek9wb8frty1pnm");
async function generate_key(date = null) {
const dateSeq = generate_date_seq(date);
const keyData = new TextEncoder().encode("qa8y" + dateSeq + "ty1pn");
return window.crypto.subtle.importKey("raw", keyData, { name: "AES-CBC" }, false, ["encrypt", "decrypt"]);
}
async function generate_local_name(date = null) {
const randomCharSeq = get_random_char_seq(4);
const dateSeq = generate_date_seq(date);
const randomSuffix = get_random_char_seq(5);
const nameBytes = new TextEncoder().encode(randomCharSeq + dateSeq + randomSuffix);
const encryptedBytes = await encrypt(nameBytes);
return base64Encode(encryptedBytes);
}
async function encrypt(data) {
const key = await generate_key();
const encrypted = await window.crypto.subtle.encrypt({ name: "AES-CBC", iv: IV }, key, data);
return new Uint8Array(encrypted);
}
async function serialize_payload(payload) {
const raw = new TextEncoder().encode(JSON.stringify(payload));
const pbytes = await encrypt(raw);
return base64Encode(pbytes);
}
// src/wrapper.js
var API = "https://webportal.jiit.ac.in:6011/StudentPortalAPI";
var DEFCAPTCHA = { captcha: "phw5n", hidden: "gmBctEffdSg=" };
var WebPortalSession = class {
/**
* Creates a WebPortalSession instance from API response
* @param {Object} resp - Response object from login API
* @param {Object} resp.regdata - Registration data containing user details
* @param {Array} resp.regdata.institutelist - List of institutes user has access to
* @param {string} resp.regdata.memberid - Member ID of the user
* @param {string} resp.regdata.userid - User ID
* @param {string} resp.regdata.token - Token for authentication
* @param {string} resp.regdata.clientid - Client ID
* @param {string} resp.regdata.membertype - Type of member
* @param {string} resp.regdata.name - Name of the user
* @param {string} resp.regdata.enrollmentno - Enrollment number
*/
constructor(resp) {
this.raw_response = resp;
this.regdata = resp["regdata"];
let institute = this.regdata["institutelist"][0];
this.institute = institute["label"];
this.instituteid = institute["value"];
this.memberid = this.regdata["memberid"];
this.userid = this.regdata["userid"];
this.token = this.regdata["token"];
let expiry_timestamp = JSON.parse(atob(this.token.split(".")[1]))["exp"];
this.expiry = new Date(expiry_timestamp * 1e3);
this.clientid = this.regdata["clientid"];
this.membertype = this.regdata["membertype"];
this.name = this.regdata["name"];
this.enrollmentno = this.regdata["enrollmentno"];
}
/**
* Generates authentication headers for API requests
* @returns {Promise<Object>} Headers object containing Authorization and LocalName
*/
async get_headers() {
const localname = await generate_local_name();
return {
Authorization: `Bearer ${this.token}`,
LocalName: localname
};
}
};
var WebPortal = class {
/**
* Creates a WebPortal instance
*/
constructor() {
this.session = null;
}
/**
* Internal method to make HTTP requests to the API
* @private
* @param {string} method - HTTP method (GET, POST etc)
* @param {string} url - API endpoint URL
* @param {Object} [options={}] - Request options
* @param {Object} [options.headers] - Additional headers
* @param {Object} [options.json] - JSON payload
* @param {string} [options.body] - Raw body payload
* @param {boolean} [options.authenticated] - Whether request needs authentication
* @param {Error} [options.exception] - Custom error class to throw
* @returns {Promise<Object>} API response
* @throws {APIError} On API or network errors
*/
async __hit(method, url, options = {}) {
let exception = APIError;
if (options.exception) {
exception = options.exception;
delete options.exception;
}
console.log(options);
let header;
if (options.authenticated) {
header = await this.session.get_headers();
delete options.authenticated;
} else {
let localname = await generate_local_name();
header = { LocalName: localname };
}
if (options.headers) {
options.headers = { ...options.headers, ...header };
} else {
options.headers = header;
}
let fetchOptions = {
method,
headers: {
"Content-Type": "application/json",
...options.headers
}
};
if (options.json) {
fetchOptions.body = JSON.stringify(options.json);
} else {
fetchOptions.body = options.body;
}
try {
console.log("fetching", url, "with options", fetchOptions);
const response = await fetch(url, fetchOptions);
if (response.status === 513) {
throw new exception("JIIT Web Portal server is temporarily unavailable (HTTP 513). Please try again later.");
}
if (response.status === 401) {
throw new SessionExpired(response.error);
}
const resp = await response.json();
if (resp.status && resp.status.responseStatus !== "Success") {
throw new exception(`status:
${JSON.stringify(resp.status, null, 2)}`);
}
return resp;
} catch (error) {
if (error instanceof TypeError && error.message.includes("CORS")) {
throw new exception("JIIT Web Portal server is temporarily unavailable. Please try again later.");
}
throw new exception(error.message || "Unknown error");
}
}
/**
* Logs in a student user
* @param {string} username - Student username
* @param {string} password - Student password
* @param {{captcha: string, hidden: string}} [captcha=DEFCAPTCHA] - CAPTCHA
* @returns {Promise<WebPortalSession>} New session instance
* @throws {LoginError} On login failure
*/
async student_login(username, password, captcha = DEFCAPTCHA) {
let pretoken_endpoint = "/token/pretoken-check";
let token_endpoint = "/token/generate-token1";
let payload = { username, usertype: "S", captcha };
payload = await serialize_payload(payload);
let resp = await this.__hit("POST", API + pretoken_endpoint, { body: payload, exception: LoginError });
let payload2 = resp["response"];
delete payload2["rejectedData"];
payload2["Modulename"] = "STUDENTMODULE";
payload2["passwordotpvalue"] = password;
payload2 = await serialize_payload(payload2);
const resp2 = await this.__hit("POST", API + token_endpoint, { body: payload2, exception: LoginError });
this.session = new WebPortalSession(resp2["response"]);
return this.session;
}
/**
* Gets personal information of logged in student
* @returns {Promise<Object>} Student personal information
*/
async get_personal_info() {
const ENDPOINT = "/studentpersinfo/getstudent-personalinformation";
const payload = {
clinetid: "SOAU",
instituteid: this.session.instituteid
};
const resp = await this.__hit("POST", API + ENDPOINT, { json: payload, authenticated: true });
return resp["response"];
}
/**
* Gets bank account information of logged in student
* @returns {Promise<Object>} Student bank information
*/
async get_student_bank_info() {
const ENDPOINT = "/studentbankdetails/getstudentbankinfo";
const payload = {
instituteid: this.session.instituteid,
studentid: this.session.memberid
};
const resp = await this.__hit("POST", API + ENDPOINT, { json: payload, authenticated: true });
return resp["response"];
}
/**
* Changes password for logged in student
* @param {string} old_password - Current password
* @param {string} new_password - New password
* @returns {Promise<Object>} Response indicating success/failure
* @throws {AccountAPIError} On password change failure
*/
async change_password(old_password, new_password) {
const ENDPOINT = "/clxuser/changepassword";
const payload = {
membertype: this.session.membertype,
oldpassword: old_password,
newpassword: new_password,
confirmpassword: new_password
};
const resp = await this.__hit("POST", API + ENDPOINT, {
json: payload,
authenticated: true,
exception: AccountAPIError
});
return resp["response"];
}
/**
* Gets attendance metadata including headers and semesters
* @returns {Promise<AttendanceMeta>} Attendance metadata
*/
async get_attendance_meta() {
const ENDPOINT = "/StudentClassAttendance/getstudentInforegistrationforattendence";
const payload = {
clientid: this.session.clientid,
instituteid: this.session.instituteid,
membertype: this.session.membertype
};
const resp = await this.__hit("POST", API + ENDPOINT, { json: payload, authenticated: true });
return new AttendanceMeta(resp["response"]);
}
/**
* Gets attendance details for a semester
* @param {AttendanceHeader} header - Attendance header
* @param {Semester} semester - Semester object
* @returns {Promise<Object>} Attendance details
*/
async get_attendance(header, semester) {
const ENDPOINT = "/StudentClassAttendance/getstudentattendancedetail";
const payload = await serialize_payload({
clientid: this.session.clientid,
instituteid: this.session.instituteid,
registrationcode: semester.registration_code,
registrationid: semester.registration_id,
stynumber: header.stynumber
});
const resp = await this.__hit("POST", API + ENDPOINT, { json: payload, authenticated: true });
return resp["response"];
}
/**
* Gets attendance for every class of the subject for the semester.
* @param {Semester} semester - Semester object
* @param {string} subjectid - Subject ID
* @param {string} individualsubjectcode - Individual subject code
* @param {Array<string>} subjectcomponentids - Array of subject component IDs
* @returns {Promise<Object>} Subject attendance details
*/
async get_subject_daily_attendance(semester, subjectid, individualsubjectcode, subjectcomponentids) {
const ENDPOINT = "/StudentClassAttendance/getstudentsubjectpersentage";
const payload = await serialize_payload({
cmpidkey: subjectcomponentids.map((id) => ({ subjectcomponentid: id })),
clientid: this.session.clientid,
instituteid: this.session.instituteid,
registrationcode: semester.registration_code,
registrationid: semester.registration_id,
subjectcode: individualsubjectcode,
subjectid
});
const resp = await this.__hit("POST", API + ENDPOINT, { json: payload, authenticated: true });
return resp["response"];
}
/**
* Gets list of registered semesters
* @returns {Promise<Array<Semester>>} Array of semester objects
*/
async get_registered_semesters() {
const ENDPOINT = "/reqsubfaculty/getregistrationList";
const payload = await serialize_payload({
instituteid: this.session.instituteid,
studentid: this.session.memberid
});
const resp = await this.__hit("POST", API + ENDPOINT, { json: payload, authenticated: true });
return resp["response"]["registrations"].map((i) => Semester.from_json(i));
}
/**
* Gets registered subjects and faculty details for a semester
* @param {Semester} semester - Semester object
* @returns {Promise<Registrations>} Registration details
*/
async get_registered_subjects_and_faculties(semester) {
const ENDPOINT = "/reqsubfaculty/getfaculties";
const payload = await serialize_payload({
instituteid: this.session.instituteid,
studentid: this.session.memberid,
registrationid: semester.registration_id
});
const resp = await this.__hit("POST", API + ENDPOINT, { json: payload, authenticated: true });
return new Registrations(resp["response"]);
}
/**
* Gets semesters that have exam events
* @returns {Promise<Array<Semester>>} Array of semester objects
*/
async get_semesters_for_exam_events() {
const ENDPOINT = "/studentcommonsontroller/getsemestercode-withstudentexamevents";
const payload = await serialize_payload({
clientid: this.session.clientid,
instituteid: this.session.instituteid,
memberid: this.session.memberid
});
const resp = await this.__hit("POST", API + ENDPOINT, { json: payload, authenticated: true });
return resp["response"]["semesterCodeinfo"]["semestercode"].map((i) => Semester.from_json(i));
}
/**
* Gets exam events for a semester
* @param {Semester} semester - Semester object
* @returns {Promise<Array<ExamEvent>>} Array of exam event objects
*/
async get_exam_events(semester) {
const ENDPOINT = "/studentcommonsontroller/getstudentexamevents";
const payload = await serialize_payload({
instituteid: this.session.instituteid,
registationid: semester.registration_id
// not a typo
});
const resp = await this.__hit("POST", API + ENDPOINT, { json: payload, authenticated: true });
return resp["response"]["eventcode"]["examevent"].map((i) => ExamEvent.from_json(i));
}
/**
* Gets exam schedule for an exam event
* @param {ExamEvent} exam_event - Exam event object
* @returns {Promise<Object>} Exam schedule details
*/
async get_exam_schedule(exam_event) {
const ENDPOINT = "/studentsttattview/getstudent-examschedule";
const payload = await serialize_payload({
instituteid: this.session.instituteid,
registrationid: exam_event.registration_id,
exameventid: exam_event.exam_event_id
});
const resp = await this.__hit("POST", API + ENDPOINT, { json: payload, authenticated: true });
return resp["response"];
}
/**
* Gets semesters that have marks available
* @returns {Promise<Array<Semester>>} Array of semester objects
*/
async get_semesters_for_marks() {
const ENDPOINT = "/studentcommonsontroller/getsemestercode-exammarks";
const payload = await serialize_payload({
instituteid: this.session.instituteid,
studentid: this.session.memberid
});
const resp = await this.__hit("POST", API + ENDPOINT, { json: payload, authenticated: true });
return resp["response"]["semestercode"].map((i) => Semester.from_json(i));
}
/**
* Downloads marks PDF for a semester
* @param {Semester} semester - Semester object
* @throws {APIError} On download failure
*/
async download_marks(semester) {
const ENDPOINT = "/studentsexamview/printstudent-exammarks/" + // this.session.memberid +
// "/" +
this.session.instituteid + "/" + semester.registration_id + "/" + semester.registration_code;
const localname = await generate_local_name();
let _headers = await this.session.get_headers(localname);
const fetchOptions = {
method: "GET",
headers: _headers
};
try {
const resp = await fetch(API + ENDPOINT, fetchOptions);
const blob = await resp.blob();
const url = window.URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = `marks_${semester.registration_code}.pdf`;
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
a.remove();
} catch (error) {
throw new APIError(error);
}
}
/**
* Gets semesters that have grade cards available
* @returns {Promise<Array<Semester>>} Array of semester objects
*/
async get_semesters_for_grade_card() {
const ENDPOINT = "/studentgradecard/getregistrationList";
const payload = await serialize_payload({
instituteid: this.session.instituteid
});
const resp = await this.__hit("POST", API + ENDPOINT, { json: payload, authenticated: true });
return resp["response"]["registrations"].map((i) => Semester.from_json(i));
}
/**
* Gets program ID for grade card
* @private
* @returns {Promise<string>} Program ID
*/
async __get_program_id() {
const ENDPOINT = "/studentgradecard/getstudentinfo";
const payload = await serialize_payload({
instituteid: this.session.instituteid
});
const resp = await this.__hit("POST", API + ENDPOINT, { json: payload, authenticated: true });
return resp["response"]["programid"];
}
/**
* Gets grade card for a semester
* @param {Semester} semester - Semester object
* @returns {Promise<Object>} Grade card details
*/
async get_grade_card(semester) {
const programid = await this.__get_program_id();
const ENDPOINT = "/studentgradecard/showstudentgradecard";
const payload = await serialize_payload({
branchid: this.session.branch_id,
instituteid: this.session.instituteid,
programid,
registrationid: semester.registration_id
});
const resp = await this.__hit("POST", API + ENDPOINT, { json: payload, authenticated: true });
return resp["response"];
}
/**
* Gets current semester number
* @private
* @returns {Promise<number>} Current semester number
*/
async __get_semester_number() {
const ENDPOINT = "/studentsgpacgpa/checkIfstudentmasterexist";
const payload = await serialize_payload({
instituteid: this.session.instituteid,
studentid: this.session.memberid,
name: this.session.name,
enrollmentno: this.session.enrollmentno
});
const resp = await this.__hit("POST", API + ENDPOINT, { json: payload, authenticated: true });
return resp["response"]["studentlov"]["currentsemester"];
}
/**
* Gets SGPA and CGPA details
* @returns {Promise<Object>} SGPA and CGPA details
*/
async get_sgpa_cgpa() {
const ENDPOINT = "/studentsgpacgpa/getallsemesterdata";
const stynumber = await this.__get_semester_number();
const payload = await serialize_payload({
instituteid: this.session.instituteid,
studentid: this.session.memberid,
stynumber
});
const resp = await this.__hit("POST", API + ENDPOINT, { json: payload, authenticated: true });
return resp["response"];
}
/**
* Gets pending miscellaneous charges/fines for the logged-in student
* @returns {Promise<Object>} The raw 'response' dict from the API.
* If there are no pending payments, the API returns
* status: Failure with error "NO APPROVED REQUEST FOUND".
* @throws {APIError} On any non-Success responseStatus
*/
async get_fines_msc_charges() {
const ENDPOINT = "/collectionpendingpayments/getpendingpaymentsdata";
const payload = await serialize_payload({
instituteid: this.session.instituteid,
studentid: this.session.memberid
});
const resp = await this.__hit("POST", API + ENDPOINT, { json: payload, authenticated: true });
return resp["response"];
}
/**
* Gets the fee summary for the logged-in student
* @returns {Promise<Object>} The raw 'response' dict from the API
* @throws {APIError} On any non-Success responseStatus
*/
async get_fee_summary() {
const ENDPOINT = "/studentfeeledger/loadfeesummary";
const payload = {
instituteid: this.session.instituteid
};
const resp = await this.__hit("POST", API + ENDPOINT, { json: payload, authenticated: true });
return resp["response"];
}
/**
* Gets subject choices for a semester
* @param {Semester} semester - A Semester object
* @returns {Promise<Object>} A dictionary with subject choices data
* @throws {APIError} Raised for generic API error
*/
async get_subject_choices(semester) {
const ENDPOINT = "/studentchoiceprint/getsubjectpreference";
const payload = {
instituteid: this.session.instituteid,
studentid: this.session.memberid,
registrationid: semester.registration_id
};
const resp = await this.__hit("POST", API + ENDPOINT, { json: payload, authenticated: true });
return resp["response"];
}
async get_hostel_details() {
const ENDPOINT = "/myhostelallocationdetail/gethostelallocationdetail";
const payload = {
clientid: this.session.clientid,
instituteid: this.session.instituteid,
studentid: this.session.memberid
};
const resp = await this.__hit("POST", API + ENDPOINT, { json: payload, authenticated: true });
if (!resp?.response) {
throw new Error("Hostel details not found");
}
return resp.response;
}
async fill_feedback_form(feedback_option) {
const SEMESTER_ENDPOINT = "/feedbackformcontroller/getFeedbackEvent";
const payload = {
instituteid: this.session.instituteid
};
const resp = await this.__hit("POST", API + SEMESTER_ENDPOINT, { json: payload, authenticated: true });
let semesters = resp["response"]["eventList"];
let latest_semester = semesters[semesters.length - 1];
let latest_semester_code = latest_semester["eventcode"];
let latest_semester_event_id = latest_semester["eventid"];
let latest_semester_event_description = latest_semester["eventdescription"];
const GRID_ENDPOINT = "/feedbackformcontroller/getGriddataForFeedback";
const grid_payload = await serialize_payload({
instituteid: this.session.instituteid,
studentid: this.session.memberid,
eventid: latest_semester_event_id
});
const grid_resp = await this.__hit("POST", API + GRID_ENDPOINT, { json: grid_payload, authenticated: true });
let grid_data = grid_resp["response"]["gridData"];
let question_feedback_payload_array = grid_data.map((data) => {
return {
instituteid: this.session.instituteid,
eventid: latest_semester_event_id,
eventdescription: latest_semester_event_description,
facultyid: data["employeeid"],
facultyname: data["employeename"],
registrationid: data["registrationid"],
studentid: data["studentid"],
subjectcode: data["subjectcode"],
subjectcomponentcode: data["subjectcomponentcode"],
subjectcomponentid: data["subjectcomponentid"],
subjectdescription: data["subjectdescription"],
subjectid: data["subjectid"]
};
});
const GET_QUESTIONS_ENDPOINT = "/feedbackformcontroller/getIemQuestion";
const SAVE_ENDPOINT = "/feedbackformcontroller/savedatalist";
for (let question_feedback_payload of question_feedback_payload_array) {
try {
const questions_api_resp2 = await this.__hit("POST", API + GET_QUESTIONS_ENDPOINT, {
json: question_feedback_payload,
authenticated: true
});
} catch (error) {
continue;
}
if (!questions_api_resp || !questions_api_resp.response || !questions_api_resp.response.questionList) {
console.error(
"Failed to retrieve question list or invalid response structure for payload:",
question_feedback_payload,
"Response:",
questions_api_resp
);
continue;
}
let actual_question_list = questions_api_resp["response"]["questionList"];
let questions_to_submit = actual_question_list.map((q) => ({
...q,
// Spread existing question properties
rating: feedback_option
// Set the rating using the function's argument
}));
let save_data_payload = {
instituteid: question_feedback_payload.instituteid,
// This comes from this.session.instituteid via map
studentid: this.session.memberid,
// Logged-in user's ID
eventid: question_feedback_payload.eventid,
// This comes from latest_semester_event_id via map
subjectid: question_feedback_payload.subjectid,
// From the specific grid item
facultyid: question_feedback_payload.facultyid,
// From the specific grid item
registrationid: question_feedback_payload.registrationid,
// From the specific grid item
questionid: questions_to_submit,
// The list of questions with updated ratings
facultycomments: null,
// Defaulting to null; can be parameterized if needed
coursecomments: null
// Defaulting to null; can be parameterized if needed
};
save_data_payload = await serialize_payload(save_data_payload);
await this.__hit("POST", API + SAVE_ENDPOINT, {
json: save_data_payload,
authenticated: true
});
}
}
};
function authenticated(method) {
return function(...args) {
if (this.session == null) {
throw new NotLoggedIn();
}
return method.apply(this, args);
};
}
var authenticatedMethods = [
"get_personal_info",
"get_student_bank_info",
"change_password",
"get_attendance_meta",
"get_attendance",
"get_subject_daily_attendance",
"get_registered_semesters",
"get_registered_subjects_and_faculties",
"get_semesters_for_exam_events",
"get_exam_events",
"get_exam_schedule",
"get_semesters_for_marks",
"download_marks",
"get_semesters_for_grade_card",
"__get_program_id",
"get_grade_card",
"__get_semester_number",
"get_sgpa_cgpa",
"get_hostel_details",
"get_fines_msc_charges",
"get_fee_summary",
"get_subject_choices"
];
authenticatedMethods.forEach((methodName) => {
WebPortal.prototype[methodName] = authenticated(WebPortal.prototype[methodName]);
});
export {
API,
APIError,
AccountAPIError,
AttendanceHeader,
AttendanceMeta,
DEFCAPTCHA,
ExamEvent,
LoginError,
NotLoggedIn,
RegisteredSubject,
Registrations,
Semester,
SessionError,
SessionExpired,
WebPortal,
WebPortalSession,
generate_local_name
};
//# sourceMappingURL=jsjiit.esm.js.map