Skip to content

Instantly share code, notes, and snippets.

@vaibhavpandeyvpz
Last active August 7, 2024 21:58
Show Gist options
  • Save vaibhavpandeyvpz/1cf70f22d782fc686d90cc7f030ff21f to your computer and use it in GitHub Desktop.
Save vaibhavpandeyvpz/1cf70f22d782fc686d90cc7f030ff21f to your computer and use it in GitHub Desktop.
Complete a InfoSec institute course automatically.
function getCsrfToken() {
var parts = ('; ' + document.cookie)
.split("; csrf=");
if (parts.length === 2) {
const value = parts.pop().split(";").shift();
return decodeURIComponent(value);
}
}
function sendXhr(url, method, data = null, headers = {}) {
const xhr = new XMLHttpRequest();
xhr.open(method, url, false);
Object.keys(headers)
.forEach((key) => {
xhr.setRequestHeader(key, headers[key]);
});
xhr.send(data);
if (xhr.status === 200) {
return xhr.responseText;
}
}
const uniqueLink = window.location.pathname.split('/').pop();
const responseText1 = sendXhr(`https://securityiq.infosecinstitute.com/learner/api/course/${uniqueLink}.json`, 'GET', null, {
'x-csrf-token': getCsrfToken(),
'x-requested-with': 'XMLHttpRequest',
});
const { data: { activityGroups } } = JSON.parse(responseText1);
activityGroups.forEach(({ activities }) => {
activities.forEach(({ id, completed, type }) => {
if (type === 'assessment' && !completed) {
const responseText2 = sendXhr(`https://securityiq.infosecinstitute.com/assess/assessments/${id}/assessment-questions?lang=en-br&sessionQueryParam[uniqueLink]=${uniqueLink}`, 'GET');
const { data: { attributes: { 'assessment-stat': { assessment: { assessments_assessment_questions: questions }, questionCount: count, initialResponses } }, id: question_id } } = JSON.parse(responseText2);
const previous = [];
const max = count - (initialResponses?.length || 0);
for (let i = 0; i < max; i++) {
let url = `https://securityiq.infosecinstitute.com/assess/assessments/${id}/assessment-questions?lang=en-br&sessionQueryParam[uniqueLink]=${uniqueLink}`;
previous.forEach((x) => {
url += '&previous[]=' + x;
});
const responseText2 = sendXhr(url, 'GET');
const { data: { attributes: { 'assessment-stat': { assessment: { assessments_assessment_questions: questions }, questionCount: count } }, id: question_id } } = JSON.parse(responseText2);
const choice = questions.find((x) => (x.assessment_question.id + '') == question_id)
.assessment_question.assessment_choices.find((x) => x.is_correct);
const data = JSON.stringify({
data: {
type: 'assessment-answers',
attributes: {
id: null,
assessmentQuestionId: question_id,
assessmentId: id,
isCorrect: true,
timedOut: false,
assessment_answer_choices: [{ assessment_choice_id: choice.id + '' }],
}
},
meta: {}
});
sendXhr(`https://securityiq.infosecinstitute.com/assess/assessment-answers?sessionQueryParam=${encodeURI(JSON.stringify({ uniqueLink }))}`, 'POST', data, {
'content-type': 'application/vnd.api+json',
'x-csrf-token': getCsrfToken(),
});
previous.push(question_id);
}
}
});
});
function getCsrfToken() {
var parts = ('; ' + document.cookie)
.split("; csrf=");
if (parts.length === 2) {
const value = parts.pop().split(";").shift();
return decodeURIComponent(value);
}
}
function sendXhr(url, method, data = null, headers = {}) {
const xhr = new XMLHttpRequest();
xhr.open(method, url, false);
Object.keys(headers)
.forEach((key) => {
xhr.setRequestHeader(key, headers[key]);
});
xhr.send(data);
if (xhr.status === 200) {
return xhr.responseText;
}
}
const uniqueLink = window.location.pathname.split('/').pop();
const responseText1 = sendXhr(`https://securityiq.infosecinstitute.com/learner/api/course/${uniqueLink}.json`, 'GET', null, {
'x-csrf-token': getCsrfToken(),
'x-requested-with': 'XMLHttpRequest',
});
const { data: { activityGroups } } = JSON.parse(responseText1);
activityGroups.forEach(({ activities }) => {
activities.forEach(({ id, completed, type }) => {
if (type === 'captivate' && !completed) {
const responseText2 = sendXhr(`https://securityiq.infosecinstitute.com/learner/api/course/${uniqueLink}/module/${id}.json`, 'GET', null, {
'x-csrf-token': getCsrfToken(),
'x-requested-with': 'XMLHttpRequest',
});
const { data: { captivateUrl } } = JSON.parse(responseText2);
const url = new URL('https:' + captivateUrl);
const pathname = url.pathname.split('/');
pathname.pop();
pathname.push('assets/js/CPM.js');
url.pathname = pathname.join('/');
url.hash = '';
const responseText3 = sendXhr(url.toString(), 'GET');
const slideNames = responseText3.match(/slides:'([\w,]+)'/);
if (slideNames?.length === 2) {
const slides = slideNames[1].split(',');
const form = new FormData();
form.append('uniqueLink', uniqueLink);
form.append('id', id);
form.append('slide', slides.length);
form.append('totalSlides', slides.length);
sendXhr('https://securityiq.infosecinstitute.com/Training/trackProgress.json', 'POST', form);
}
}
});
});
@bill-transue
Copy link

bill-transue commented Aug 7, 2024

Thanks bro, what a life saver, had to add one line (if (!captivateUrl) return)to the inner forEach loop:

activityGroups.forEach(({ activities }) => {
  activities.forEach(({ id, completed, type }) => {
    if (type === 'captivate' && !completed) {
      const responseText2 = sendXhr(`https://securityiq.infosecinstitute.com/learner/api/course/${uniqueLink}/module/${id}.json`, 'GET', null, {
        'x-csrf-token': getCsrfToken(),
        'x-requested-with': 'XMLHttpRequest',
      });
      const { data: { captivateUrl } } = JSON.parse(responseText2);
      if (!captivateUrl) return; # need to skip if captiveUrl is blank
      const url = new URL('https:' + captivateUrl);
      const pathname = url.pathname.split('/');
      pathname.pop();
      pathname.push('assets/js/CPM.js');
      url.pathname = pathname.join('/');
      url.hash = '';
      const responseText3 = sendXhr(url.toString(), 'GET');
      const slideNames = responseText3.match(/slides:'([\w,]+)'/);
      if (slideNames?.length === 2) {
        const slides = slideNames[1].split(',');
        const form = new FormData();
        form.append('uniqueLink', uniqueLink);
        form.append('id', id);
        form.append('slide', slides.length);
        form.append('totalSlides', slides.length);
        sendXhr('https://securityiq.infosecinstitute.com/Training/trackProgress.json', 'POST', form);
      }
    }
  });
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment