Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 1 addition & 9 deletions src/services/assignment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import type {
import { debug } from "@/utils/debug";
import {
getQueryParamValue,
isLoginHtml,
parseAssignmentIdFromMoodleUrl,
} from "@/utils/moodle-url";
import {
Expand Down Expand Up @@ -158,15 +159,6 @@ const parseNumberValue = (
return null;
};

const isLoginHtml = (html: string): boolean => {
const normalized = html.replace(/\s+/g, " ");
return (
normalized.includes('name="logintoken"') ||
normalized.includes('id="login"') ||
normalized.includes("/login/index.php")
);
};

const ensureAuthenticatedSession = async (): Promise<boolean> => {
const hasSession = await checkSession();
if (hasSession) return true;
Expand Down
5 changes: 4 additions & 1 deletion src/services/cookie-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,10 @@ class CookieStore {
if (keyLower === "domain") cookie.domain = val?.trim();
if (keyLower === "path") cookie.path = val?.trim();
if (keyLower === "expires" && val) {
cookie.expires = new Date(val.trim());
const parsed = new Date(val.trim());
if (!Number.isNaN(parsed.getTime())) {
cookie.expires = parsed;
}
}
}

Expand Down
12 changes: 1 addition & 11 deletions src/services/dashboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { TimelineEvent } from "@/types";
import { debug } from "@/utils/debug";
import { api } from "./api";
import { dedupeTimelineEvents } from "./dashboard-event-utils";
import { getSesskey } from "./sesskey";

interface MoodleTimelineResponse {
error: boolean;
Expand All @@ -13,17 +14,6 @@ interface MoodleTimelineResponse {
};
}

const getSesskey = async (): Promise<string | null> => {
const response = await api.get<string>("/my/");
const match = response.data.match(/"sesskey":"([^"]+)"/);
if (match) {
debug.scraper(`Found sesskey: ${match[1]}`);
return match[1];
}
debug.scraper("Sesskey not found");
return null;
};

type ActionEventsByTimesortArgs = {
limitnum: number;
timesortfrom: number;
Expand Down
10 changes: 1 addition & 9 deletions src/services/feedback-autofill.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
querySelectorAll,
} from "@/utils/html-parser";
import { debug } from "@/utils/debug";
import { isLoginHtml } from "@/utils/moodle-url";
import type { Element } from "domhandler";

type FeedbackAutofillOptions = {
Expand Down Expand Up @@ -60,15 +61,6 @@ type FillResult = {
textFieldsFilled: number;
};

const isLoginHtml = (html: string): boolean => {
const normalized = html.replace(/\s+/g, " ");
return (
normalized.includes('name="logintoken"') ||
normalized.includes('id="login"') ||
normalized.includes("/login/index.php")
);
};

const toAbsoluteUrl = (href: string): string => {
const baseUrl = getCurrentBaseUrl();
try {
Expand Down
9 changes: 1 addition & 8 deletions src/services/lms-download.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type {
LmsDownloadSuccess,
} from "@/types";
import { debug } from "@/utils/debug";
import { isLoginHtml } from "@/utils/moodle-url";
import { File, Paths } from "expo-file-system";
import { fetch as expoFetch } from "expo/fetch";

Expand Down Expand Up @@ -83,14 +84,6 @@ const toAbsoluteLmsUrl = (url: string): string => {
return `${baseUrl}/${url.replace(/^\.?\//, "")}`;
};

const isLoginHtml = (html: string): boolean => {
const condensed = html.replace(/\s+/g, " ");
return (
condensed.includes('name="logintoken"') ||
condensed.includes('id="login"') ||
condensed.includes("/login/index.php")
);
};

const buildFailure = (
reason: LmsDownloadFailureReason,
Expand Down
10 changes: 1 addition & 9 deletions src/services/resources-scraper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,13 @@ import {
querySelector,
querySelectorAll,
} from "@/utils/html-parser";
import { isLoginHtml } from "@/utils/moodle-url";
import type { Element } from "domhandler";
import { api, BASE_URL } from "./api";

const normalizeText = (value: string): string =>
value.replace(/\s+/g, " ").trim();

const isLoginHtml = (html: string): boolean => {
const normalized = html.replace(/\s+/g, " ");
return (
normalized.includes('name="logintoken"') ||
normalized.includes('id="login"') ||
normalized.includes("/login/index.php")
);
};

const toAbsoluteUrl = (href: string): string => {
if (href.startsWith("http://") || href.startsWith("https://")) {
return href;
Expand Down
17 changes: 1 addition & 16 deletions src/services/scraper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,7 @@ import {
querySelectorAll,
} from "@/utils/html-parser";
import { api, BASE_URL } from "./api";

// Get sesskey from page for API calls
const getSesskey = async (): Promise<string | null> => {
const response = await api.get<string>("/my/");

// Find sesskey in page - it's in M.cfg.sesskey in a script tag
const match = response.data.match(/"sesskey":"([^"]+)"/);

if (match) {
debug.scraper(`Found sesskey: ${match[1]}`);
return match[1];
}

debug.scraper("Sesskey not found");
return null;
};
import { getSesskey } from "./sesskey";

// Fetch courses using Moodle's AJAX API (only "in progress" courses)
export const fetchCourses = async (): Promise<Course[]> => {
Expand Down
14 changes: 14 additions & 0 deletions src/services/sesskey.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { debug } from "@/utils/debug";
import { api } from "./api";

/** Extract sesskey from the Moodle dashboard page (M.cfg.sesskey). */
export const getSesskey = async (): Promise<string | null> => {
const response = await api.get<string>("/my/");
const match = response.data.match(/"sesskey":"([^"]+)"/);
if (match) {
debug.scraper(`Found sesskey: ${match[1]}`);
return match[1];
Comment thread
adi3433 marked this conversation as resolved.
}
debug.scraper("Sesskey not found");
return null;
};
10 changes: 10 additions & 0 deletions src/utils/moodle-url.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
const ASSIGNMENT_VIEW_PATH = "/mod/assign/view.php";

/** Check if HTML response is a Moodle login page (session expired). */
export const isLoginHtml = (html: string): boolean => {
const normalized = html.replace(/\s+/g, " ");
return (
normalized.includes('name="logintoken"') ||
normalized.includes('id="login"') ||
normalized.includes("/login/index.php")
);
};

export const getQueryParamValue = (url: string, key: string): string | null => {
if (!url) return null;

Expand Down
Loading