Merge branch 'main' of https://github.com/Amudieshwar-AG/Freshers-Hub
This commit is contained in:
@@ -176,6 +176,20 @@ export default function StudentDashboard() {
|
|||||||
);
|
);
|
||||||
if (firstActive) setSelectedDay(firstActive);
|
if (firstActive) setSelectedDay(firstActive);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Auto-load Attendance, Internal Marks, and Grades for immediate Overview KPI display
|
||||||
|
const [attData, catData, assignData, labData, gData] = await Promise.all([
|
||||||
|
fetchImsAttendance(token, p.registerNumber, force),
|
||||||
|
fetchImsCatMarks(token, p.registerNumber, force),
|
||||||
|
fetchImsAssignmentMarks(p.departmentCode || p.department, p.semester),
|
||||||
|
fetchImsLabMarks(p.departmentCode || p.department, p.semester),
|
||||||
|
fetchImsSemesterResults(token, p.registerNumber, p.semester, force)
|
||||||
|
]);
|
||||||
|
setAttendance(attData);
|
||||||
|
setCatMarks(catData);
|
||||||
|
setAssignmentMarks(assignData);
|
||||||
|
setLabMarks(labData);
|
||||||
|
setGradesData(gData);
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
console.error('Error loading initial IMS data:', err);
|
console.error('Error loading initial IMS data:', err);
|
||||||
setError(err.message || 'Failed to load timetable.');
|
setError(err.message || 'Failed to load timetable.');
|
||||||
@@ -187,10 +201,10 @@ export default function StudentDashboard() {
|
|||||||
// ─── Lazy On-Demand Fetchers ────────────────────────────────────────
|
// ─── Lazy On-Demand Fetchers ────────────────────────────────────────
|
||||||
|
|
||||||
const ensureAttendanceLoaded = async (force = false) => {
|
const ensureAttendanceLoaded = async (force = false) => {
|
||||||
if ((attendance && !force) || !session?.token || !profile) return;
|
if ((attendance && attendance.subjects.length > 0 && !force) || !profile) return;
|
||||||
setIsTabLoading(true);
|
setIsTabLoading(true);
|
||||||
try {
|
try {
|
||||||
const data = await fetchImsAttendance(session.token, profile.registerNumber, force);
|
const data = await fetchImsAttendance(session?.token || '', profile.registerNumber, force);
|
||||||
setAttendance(data);
|
setAttendance(data);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.warn('Attendance load notice:', err);
|
console.warn('Attendance load notice:', err);
|
||||||
@@ -200,13 +214,13 @@ export default function StudentDashboard() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const ensureCatMarksLoaded = async (force = false) => {
|
const ensureCatMarksLoaded = async (force = false) => {
|
||||||
if ((catMarks && assignmentMarks && labMarks && !force) || !session?.token || !profile) return;
|
if ((catMarks && catMarks.subjects.length > 0 && assignmentMarks && labMarks && !force) || !profile) return;
|
||||||
setIsTabLoading(true);
|
setIsTabLoading(true);
|
||||||
try {
|
try {
|
||||||
const [cat, assign, lab] = await Promise.all([
|
const [cat, assign, lab] = await Promise.all([
|
||||||
fetchImsCatMarks(session.token, profile.registerNumber, force),
|
fetchImsCatMarks(session?.token || '', profile.registerNumber, force),
|
||||||
fetchImsAssignmentMarks(),
|
fetchImsAssignmentMarks(profile.departmentCode || profile.department, profile.semester),
|
||||||
fetchImsLabMarks(),
|
fetchImsLabMarks(profile.departmentCode || profile.department, profile.semester),
|
||||||
]);
|
]);
|
||||||
setCatMarks(cat);
|
setCatMarks(cat);
|
||||||
setAssignmentMarks(assign);
|
setAssignmentMarks(assign);
|
||||||
@@ -219,10 +233,10 @@ export default function StudentDashboard() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const ensureGradesLoaded = async (force = false) => {
|
const ensureGradesLoaded = async (force = false) => {
|
||||||
if ((gradesData && !force) || !session?.token || !profile) return;
|
if ((gradesData && gradesData.results.length > 0 && !force) || !profile) return;
|
||||||
setIsTabLoading(true);
|
setIsTabLoading(true);
|
||||||
try {
|
try {
|
||||||
const data = await fetchImsSemesterResults(session.token, profile.registerNumber, profile.semester, force);
|
const data = await fetchImsSemesterResults(session?.token || '', profile.registerNumber, profile.semester, force);
|
||||||
setGradesData(data);
|
setGradesData(data);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.warn('Grades load notice:', err);
|
console.warn('Grades load notice:', err);
|
||||||
|
|||||||
@@ -241,7 +241,7 @@ export function deduceStudentDetails(regNumber: string): { department: string; d
|
|||||||
|
|
||||||
export function parseDepartmentCode(rawDept: string = ''): string {
|
export function parseDepartmentCode(rawDept: string = ''): string {
|
||||||
const d = rawDept.toLowerCase();
|
const d = rawDept.toLowerCase();
|
||||||
if (d.includes('artificial intelligence') && d.includes('data')) return 'AI&DS';
|
if (d.includes('artificial intelligence') && d.includes('data')) return 'AIDS';
|
||||||
if (d.includes('artificial intelligence') || d.includes('machine learning') || d.includes('aiml')) return 'AIML';
|
if (d.includes('artificial intelligence') || d.includes('machine learning') || d.includes('aiml')) return 'AIML';
|
||||||
if (d.includes('computer science and business') || d.includes('csbs')) return 'CSBS';
|
if (d.includes('computer science and business') || d.includes('csbs')) return 'CSBS';
|
||||||
if (d.includes('computer science') || d.includes('cse')) return 'CSE';
|
if (d.includes('computer science') || d.includes('cse')) return 'CSE';
|
||||||
@@ -251,7 +251,7 @@ export function parseDepartmentCode(rawDept: string = ''): string {
|
|||||||
if (d.includes('civil')) return 'CIVIL';
|
if (d.includes('civil')) return 'CIVIL';
|
||||||
if (d.includes('biotech')) return 'BIOTECH';
|
if (d.includes('biotech')) return 'BIOTECH';
|
||||||
if (d.includes('information technology') || d.includes('it')) return 'IT';
|
if (d.includes('information technology') || d.includes('it')) return 'IT';
|
||||||
return rawDept ? rawDept.slice(0, 4).toUpperCase() : 'AI&DS';
|
return rawDept ? rawDept.slice(0, 4).toUpperCase() : 'AIDS';
|
||||||
}
|
}
|
||||||
|
|
||||||
export function generateCurriculumSchedule(deptCode: string, semester: number): WeeklySchedule {
|
export function generateCurriculumSchedule(deptCode: string, semester: number): WeeklySchedule {
|
||||||
@@ -460,7 +460,7 @@ export async function loginWithIms(regNumber: string, password: string): Promise
|
|||||||
// Step B: Get fresh CSRF token from login page
|
// Step B: Get fresh CSRF token from login page
|
||||||
const loginPageRes = await fetch('/ims/login', { credentials: 'same-origin' });
|
const loginPageRes = await fetch('/ims/login', { credentials: 'same-origin' });
|
||||||
if (!loginPageRes.ok) {
|
if (!loginPageRes.ok) {
|
||||||
return { success: false, message: 'RIT IMS Portal is currently unavailable.' };
|
return { success: false, message: 'RIT IMS Portal is currently unreachable from server proxy.' };
|
||||||
}
|
}
|
||||||
const loginHtml = await loginPageRes.text();
|
const loginHtml = await loginPageRes.text();
|
||||||
const loginDoc = new DOMParser().parseFromString(loginHtml, 'text/html');
|
const loginDoc = new DOMParser().parseFromString(loginHtml, 'text/html');
|
||||||
@@ -469,7 +469,7 @@ export async function loginWithIms(regNumber: string, password: string): Promise
|
|||||||
csrfToken = loginDoc.querySelector('input[name="_token"]')?.getAttribute('value') || '';
|
csrfToken = loginDoc.querySelector('input[name="_token"]')?.getAttribute('value') || '';
|
||||||
}
|
}
|
||||||
if (!csrfToken) {
|
if (!csrfToken) {
|
||||||
return { success: false, message: 'Could not initialize IMS session (CSRF missing).' };
|
return { success: false, message: 'Could not initialize IMS session (CSRF missing from /ims/login).' };
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step C: POST login credentials
|
// Step C: POST login credentials
|
||||||
@@ -868,7 +868,7 @@ export async function fetchImsTimetable(_token: string, regNumber: string, _forc
|
|||||||
/**
|
/**
|
||||||
* 4. Lazy Fetch Attendance — Direct scraping of /ims/admin/student-personal-attendance/report
|
* 4. Lazy Fetch Attendance — Direct scraping of /ims/admin/student-personal-attendance/report
|
||||||
*/
|
*/
|
||||||
export async function fetchImsAttendance(_token: string, _regNumber: string, _forceRefresh = false): Promise<AttendanceReport> {
|
export async function fetchImsAttendance(_token: string, regNumber: string, _forceRefresh = false): Promise<AttendanceReport> {
|
||||||
const subjects: SubjectAttendance[] = [];
|
const subjects: SubjectAttendance[] = [];
|
||||||
let totalCond = 0, totalPres = 0, totalAbs = 0;
|
let totalCond = 0, totalPres = 0, totalAbs = 0;
|
||||||
|
|
||||||
@@ -1064,7 +1064,7 @@ export function getExactSubjectCredits(deptCodeOrName: string, _semester: number
|
|||||||
*/
|
*/
|
||||||
export async function fetchImsSemesterResults(_token: string, regNumber: string, currentSem = 4, _forceRefresh = false): Promise<{ results: SemesterResult[]; cgpa: number; totalCredits: number; activeArrears: number }> {
|
export async function fetchImsSemesterResults(_token: string, regNumber: string, currentSem = 4, _forceRefresh = false): Promise<{ results: SemesterResult[]; cgpa: number; totalCredits: number; activeArrears: number }> {
|
||||||
const deduced = deduceStudentDetails(regNumber);
|
const deduced = deduceStudentDetails(regNumber);
|
||||||
const deptCode = deduced.departmentCode || 'AIDS';
|
const deptCode = DEPARTMENT_CODE_MAP[deduced.department] || parseDepartmentCode(deduced.departmentCode) || 'AIDS';
|
||||||
const results: SemesterResult[] = [];
|
const results: SemesterResult[] = [];
|
||||||
const maxSemToCheck = Math.max(2, currentSem || 4);
|
const maxSemToCheck = Math.max(2, currentSem || 4);
|
||||||
|
|
||||||
@@ -1133,50 +1133,6 @@ export async function fetchImsSemesterResults(_token: string, regNumber: string,
|
|||||||
} catch {}
|
} catch {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If results were empty or fewer than previous semesters, generate exact curriculum results for finished semesters
|
|
||||||
if (results.length === 0 && DEPARTMENT_CURRICULUM[deptCode]) {
|
|
||||||
const completedSems = Math.min(4, Math.max(1, (currentSem || 5) - 1));
|
|
||||||
const gradeTemplates = ['O', 'A+', 'O', 'A+', 'O', 'A', 'A+', 'O', 'A+'];
|
|
||||||
|
|
||||||
for (let s = 1; s <= completedSems; s++) {
|
|
||||||
const semSubjects = DEPARTMENT_CURRICULUM[deptCode][s] || [];
|
|
||||||
let semCredits = 0;
|
|
||||||
let semPoints = 0;
|
|
||||||
|
|
||||||
const grades: SemesterGrade[] = semSubjects.map((sub, idx) => {
|
|
||||||
const matchCode = sub.name.match(/\(([A-Z0-9]+)\)/i)?.[1] || sub.code || `SUB${s}0${idx+1}`;
|
|
||||||
const cleanTitle = sub.name.replace(/\([A-Z0-9]+\)/gi, '').trim();
|
|
||||||
const credits = sub.credits;
|
|
||||||
const grade = sub.credits === 0 ? 'PASS' : (gradeTemplates[idx % gradeTemplates.length] || 'A+');
|
|
||||||
const gp = GRADE_POINTS[grade] ?? 9;
|
|
||||||
|
|
||||||
if (credits > 0) {
|
|
||||||
semCredits += credits;
|
|
||||||
semPoints += (gp * credits);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
code: matchCode,
|
|
||||||
name: cleanTitle,
|
|
||||||
credits,
|
|
||||||
internalMark: credits > 0 ? 38 + (idx % 3) * 3 : undefined,
|
|
||||||
externalMark: credits > 0 ? 52 + (idx % 3) * 3 : undefined,
|
|
||||||
totalMark: credits > 0 ? 90 + (idx % 3) * 3 : undefined,
|
|
||||||
grade,
|
|
||||||
result: 'PASS',
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
const sgpa = semCredits > 0 ? Number((semPoints / semCredits).toFixed(2)) : 0;
|
|
||||||
results.push({
|
|
||||||
semester: s,
|
|
||||||
gpa: sgpa,
|
|
||||||
totalCredits: semCredits,
|
|
||||||
subjects: grades,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate Cumulative CGPA & Active Arrears strictly according to Anna University Regulations
|
// Calculate Cumulative CGPA & Active Arrears strictly according to Anna University Regulations
|
||||||
let cumCredits = 0;
|
let cumCredits = 0;
|
||||||
let cumPoints = 0;
|
let cumPoints = 0;
|
||||||
@@ -1229,109 +1185,94 @@ export async function fetchStudentDashboard(regNumber?: string): Promise<{ resul
|
|||||||
/**
|
/**
|
||||||
* Fetch Assignment Marks from /ims/admin/assignment/student/mark/report
|
* Fetch Assignment Marks from /ims/admin/assignment/student/mark/report
|
||||||
*/
|
*/
|
||||||
export async function fetchImsAssignmentMarks(): Promise<AssignmentMarkItem[]> {
|
export async function fetchImsAssignmentMarks(_deptCodeOrName?: string, _semester?: number): Promise<AssignmentMarkItem[]> {
|
||||||
|
const items: AssignmentMarkItem[] = [];
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/ims/admin/assignment/student/mark/report', {
|
const response = await fetch('/ims/admin/assignment/student/mark/report', {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
credentials: 'same-origin',
|
credentials: 'same-origin',
|
||||||
});
|
});
|
||||||
if (!response.ok) return [];
|
if (response.ok) {
|
||||||
|
const html = await response.text();
|
||||||
|
const doc = new DOMParser().parseFromString(html, 'text/html');
|
||||||
|
const table = doc.querySelector('table');
|
||||||
|
if (table) {
|
||||||
|
const rows = Array.from(table.querySelectorAll('tr'));
|
||||||
|
rows.forEach((row) => {
|
||||||
|
const tds = Array.from(row.querySelectorAll('td')).map(td => td.textContent?.trim() || '');
|
||||||
|
if (tds.length >= 4) {
|
||||||
|
let subjectName = tds[0];
|
||||||
|
let subjectCode = tds[1];
|
||||||
|
let facultyName = tds[2];
|
||||||
|
|
||||||
const html = await response.text();
|
if (/^[A-Z]{2,4}\d{2,5}$/i.test(tds[0])) {
|
||||||
const doc = new DOMParser().parseFromString(html, 'text/html');
|
subjectCode = tds[0];
|
||||||
const table = doc.querySelector('table');
|
subjectName = tds[1];
|
||||||
if (!table) return [];
|
}
|
||||||
|
|
||||||
const rows = Array.from(table.querySelectorAll('tr'));
|
const a1 = tds[3] || '-';
|
||||||
const items: AssignmentMarkItem[] = [];
|
const a2 = tds[4] || '-';
|
||||||
|
const a3 = tds[5] || '-';
|
||||||
|
const a4 = tds[6] || '-';
|
||||||
|
const a5 = tds[7] || '-';
|
||||||
|
const total = tds[8] || tds[tds.length - 1] || '-';
|
||||||
|
|
||||||
rows.forEach((row) => {
|
if (subjectName || subjectCode) {
|
||||||
const tds = Array.from(row.querySelectorAll('td')).map(td => td.textContent?.trim() || '');
|
items.push({ subjectName, subjectCode, facultyName, a1, a2, a3, a4, a5, total });
|
||||||
if (tds.length >= 4) {
|
}
|
||||||
let subjectName = tds[0];
|
}
|
||||||
let subjectCode = tds[1];
|
});
|
||||||
let facultyName = tds[2];
|
|
||||||
|
|
||||||
if (/^[A-Z]{2,4}\d{2,5}$/i.test(tds[0])) {
|
|
||||||
subjectCode = tds[0];
|
|
||||||
subjectName = tds[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
const a1 = tds[3] || '-';
|
|
||||||
const a2 = tds[4] || '-';
|
|
||||||
const a3 = tds[5] || '-';
|
|
||||||
const a4 = tds[6] || '-';
|
|
||||||
const a5 = tds[7] || '-';
|
|
||||||
const total = tds[8] || tds[tds.length - 1] || '-';
|
|
||||||
|
|
||||||
if (subjectName || subjectCode) {
|
|
||||||
items.push({
|
|
||||||
subjectName,
|
|
||||||
subjectCode,
|
|
||||||
facultyName,
|
|
||||||
a1, a2, a3, a4, a5,
|
|
||||||
total,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
return items;
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.warn('Failed to fetch assignment marks:', err);
|
console.warn('Failed to fetch assignment marks:', err);
|
||||||
return [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch LAB Marks from /ims/admin/student_lab_mark/report
|
* Fetch LAB Marks from /ims/admin/student_lab_mark/report
|
||||||
*/
|
*/
|
||||||
export async function fetchImsLabMarks(): Promise<LabMarkItem[]> {
|
export async function fetchImsLabMarks(_deptCodeOrName?: string, _semester?: number): Promise<LabMarkItem[]> {
|
||||||
|
const items: LabMarkItem[] = [];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/ims/admin/student_lab_mark/report', {
|
const response = await fetch('/ims/admin/student_lab_mark/report', {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
credentials: 'same-origin',
|
credentials: 'same-origin',
|
||||||
});
|
});
|
||||||
if (!response.ok) return [];
|
if (response.ok) {
|
||||||
|
const html = await response.text();
|
||||||
|
const doc = new DOMParser().parseFromString(html, 'text/html');
|
||||||
|
const table = doc.querySelector('table');
|
||||||
|
if (table) {
|
||||||
|
const rows = Array.from(table.querySelectorAll('tr'));
|
||||||
|
rows.forEach((row) => {
|
||||||
|
const tds = Array.from(row.querySelectorAll('td')).map(td => td.textContent?.trim() || '');
|
||||||
|
if (tds.length >= 3) {
|
||||||
|
let subjectName = tds[0];
|
||||||
|
let subjectCode = tds[1];
|
||||||
|
let facultyName = tds[2];
|
||||||
|
|
||||||
const html = await response.text();
|
if (/^[A-Z]{2,4}\d{2,5}$/i.test(tds[0])) {
|
||||||
const doc = new DOMParser().parseFromString(html, 'text/html');
|
subjectCode = tds[0];
|
||||||
const table = doc.querySelector('table');
|
subjectName = tds[1];
|
||||||
if (!table) return [];
|
}
|
||||||
|
|
||||||
const rows = Array.from(table.querySelectorAll('tr'));
|
const marks = tds[3] || '-';
|
||||||
const items: LabMarkItem[] = [];
|
const total = tds[tds.length - 1] || '-';
|
||||||
|
|
||||||
rows.forEach((row) => {
|
if (subjectName || subjectCode) {
|
||||||
const tds = Array.from(row.querySelectorAll('td')).map(td => td.textContent?.trim() || '');
|
items.push({ subjectName, subjectCode, facultyName, marks, total });
|
||||||
if (tds.length >= 3) {
|
}
|
||||||
let subjectName = tds[0];
|
}
|
||||||
let subjectCode = tds[1];
|
});
|
||||||
let facultyName = tds[2];
|
|
||||||
|
|
||||||
if (/^[A-Z]{2,4}\d{2,5}$/i.test(tds[0])) {
|
|
||||||
subjectCode = tds[0];
|
|
||||||
subjectName = tds[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
const marks = tds[3] || '-';
|
|
||||||
const total = tds[tds.length - 1] || '-';
|
|
||||||
|
|
||||||
if (subjectName || subjectCode) {
|
|
||||||
items.push({
|
|
||||||
subjectName,
|
|
||||||
subjectCode,
|
|
||||||
facultyName,
|
|
||||||
marks,
|
|
||||||
total,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
return items;
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.warn('Failed to fetch lab marks:', err);
|
console.warn('Failed to fetch lab marks:', err);
|
||||||
return [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return items;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,25 +87,24 @@ export default defineConfig({
|
|||||||
secure: false,
|
secure: false,
|
||||||
configure: (proxy) => {
|
configure: (proxy) => {
|
||||||
proxy.on('proxyRes', (proxyRes) => {
|
proxy.on('proxyRes', (proxyRes) => {
|
||||||
// Rewrite Location header to keep redirects through local proxy
|
// Rewrite Location header to keep redirects through local / VPS proxy
|
||||||
const location = proxyRes.headers['location'];
|
const location = proxyRes.headers['location'];
|
||||||
if (location) {
|
if (location) {
|
||||||
let rewritten = location;
|
let rewritten = location;
|
||||||
if (rewritten.includes('ims.ritchennai.edu.in')) {
|
if (rewritten.includes('ims.ritchennai.edu.in')) {
|
||||||
rewritten = rewritten.replace(/https?:\/\/ims\.ritchennai\.edu\.in/gi, 'http://localhost:5173/ims');
|
rewritten = rewritten.replace(/https?:\/\/ims\.ritchennai\.edu\.in/gi, '/ims');
|
||||||
} else if (rewritten.startsWith('/')) {
|
} else if (rewritten.startsWith('/') && !rewritten.startsWith('/ims')) {
|
||||||
rewritten = '/ims' + rewritten;
|
rewritten = '/ims' + rewritten;
|
||||||
}
|
}
|
||||||
proxyRes.headers['location'] = rewritten;
|
proxyRes.headers['location'] = rewritten;
|
||||||
}
|
}
|
||||||
// Tweak cookies for localhost
|
// Strip domain from cookies so session cookies bind to current host (localhost or VPS domain)
|
||||||
const setCookie = proxyRes.headers['set-cookie'];
|
const setCookie = proxyRes.headers['set-cookie'];
|
||||||
if (setCookie) {
|
if (setCookie) {
|
||||||
proxyRes.headers['set-cookie'] = (Array.isArray(setCookie) ? setCookie : [setCookie]).map((cookie: string) =>
|
proxyRes.headers['set-cookie'] = (Array.isArray(setCookie) ? setCookie : [setCookie]).map((cookie: string) =>
|
||||||
cookie
|
cookie
|
||||||
.replace(/Secure/gi, '')
|
|
||||||
.replace(/samesite=none/gi, 'SameSite=Lax')
|
|
||||||
.replace(/domain=[^;]+/gi, '')
|
.replace(/domain=[^;]+/gi, '')
|
||||||
|
.replace(/path=[^;]+/gi, 'Path=/')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user