diff --git a/src/lib/server/ap/homepage.js b/src/lib/server/ap/homepage.js
new file mode 100644
index 0000000..75ad395
--- /dev/null
+++ b/src/lib/server/ap/homepage.js
@@ -0,0 +1,87 @@
+/* Private functions dealing with parsing the homepage of a Vervis instance.
+ * Copyright (C) 2024 André Jaenisch
+ * SPDX-FileCopyrightText: 2024 André Jaenisch
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ *
+ * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License along with this program. If not, see .
+ */
+
+import { AxiosHeaders } from 'axios';
+import * as cheerio from 'cheerio';
+
+import { getRemoteLogin, postRemoteLogin } from './login.js';
+
+export async function getHomepage({ account, passphrase, server }) {
+ const vervis =
+ {
+ 1: 'https://fig.fr33domlover.site',
+ 2: 'https://grape.fr33domlover.site',
+ 3: 'https://walnut.fr33domlover.site'
+ }[server] || null;
+
+ const loginFormData = await getRemoteLogin(vervis);
+ const loggedInResponse = await postRemoteLogin({
+ username: account,
+ password: passphrase,
+ loginFormData
+ });
+
+ if (loggedInResponse.status === 200) {
+ const headers = new AxiosHeaders();
+ headers.set({ Cookie: loggedInResponse.headers['set-cookie'].join(';') });
+
+ const response = await loginFormData.instance.get('/', {
+ headers
+ });
+
+ const patches = [];
+ const projects = [];
+ const repos = [];
+ const teams = [];
+ const tickets = [];
+
+ const dom = cheerio.load(response.data);
+ if (dom('h2:contains("Your teams") + p').text().includes("aren't a member")) {
+ console.log('No teams');
+ }
+
+ if (dom('h2:contains("Your repos") + ul').text() === '') {
+ console.log('No repos');
+ }
+
+ if (dom('h2:contains("Your ticket trackers") + ul').text() === '') {
+ console.log('No ticket trackers');
+ }
+
+ if (dom('h2:contains("Your patch trackers") + ul').text() === '') {
+ console.log('No patch trackers');
+ }
+
+ if (dom('h2:contains("Your projects") + ul').text() === '') {
+ console.log('No projects');
+ } else {
+ dom('h2:contains("Your projects") + ul li a')
+ .get()
+ .map((a) => {
+ projects.push(dom(a).text());
+ });
+ }
+
+ return {
+ cookies: response.headers['set-cookie'].join(';'),
+ patches,
+ projects,
+ repos,
+ teams,
+ tickets,
+ username: account,
+ vervis
+ };
+ }
+
+ return null;
+}
diff --git a/src/lib/server/ap/index.js b/src/lib/server/ap/index.js
index 4ace98a..c454041 100644
--- a/src/lib/server/ap/index.js
+++ b/src/lib/server/ap/index.js
@@ -16,6 +16,7 @@ import axios, { AxiosHeaders } from 'axios';
import * as cheerio from 'cheerio';
import pkg from '../../../../package.json';
+import { getHomepage } from './homepage.js';
const loginResponse = {
id: '87bcb6de-bb70-11ee-b719-6756da82e80f',
@@ -68,118 +69,3 @@ export const requests = {
return Promise.reject(new Error('Invalid Login'));
}
};
-
-async function getRemoteLogin(vervis) {
- const httpsAgent = new Agent({ rejectUnauthorized: false });
- const headers = new AxiosHeaders();
- headers.setUserAgent(`Anvil/${pkg.version}`);
- const instance = axios.create({
- baseURL: vervis,
- headers,
- httpsAgent,
- withCredentials: true
- });
- const response = await instance.get('/auth/login');
-
- const dom = cheerio.load(response.data);
- const form = dom('form');
-
- return {
- instance,
- action: form.attr('action'),
- csrf: dom('form input[name="_token"]').attr('value'),
- enctype: form.attr('enctype'),
- method: form.attr('method'),
- cookies: response.headers['set-cookie']
- };
-}
-
-async function postRemoteLogin({ username, password, loginFormData }) {
- const headers = new AxiosHeaders();
- headers.setContentType(loginFormData.enctype);
- headers.set({ Cookie: loginFormData.cookies.join(';') });
-
- const data = {
- _token: loginFormData.csrf,
- f1: username,
- f2: password
- };
-
- return loginFormData.instance({
- method: loginFormData.method,
- url: loginFormData.action,
- headers,
- data
- });
-}
-
-async function getHomepage({ account, passphrase, server }) {
- const vervis =
- {
- 1: 'https://fig.fr33domlover.site',
- 2: 'https://grape.fr33domlover.site',
- 3: 'https://walnut.fr33domlover.site'
- }[server] || null;
-
- const loginFormData = await getRemoteLogin(vervis);
- const loggedInResponse = await postRemoteLogin({
- username: account,
- password: passphrase,
- loginFormData
- });
-
- if (loggedInResponse.status === 200) {
- const headers = new AxiosHeaders();
- headers.set({ Cookie: loggedInResponse.headers['set-cookie'].join(';') });
-
- const response = await loginFormData.instance.get('/', {
- headers
- });
-
- const patches = [];
- const projects = [];
- const repos = [];
- const teams = [];
- const tickets = [];
-
- const dom = cheerio.load(response.data);
- if (dom('h2:contains("Your teams") + p').text().includes("aren't a member")) {
- console.log('No teams');
- }
-
- if (dom('h2:contains("Your repos") + ul').text() === '') {
- console.log('No repos');
- }
-
- if (dom('h2:contains("Your ticket trackers") + ul').text() === '') {
- console.log('No ticket trackers');
- }
-
- if (dom('h2:contains("Your patch trackers") + ul').text() === '') {
- console.log('No patch trackers');
- }
-
- if (dom('h2:contains("Your projects") + ul').text() === '') {
- console.log('No projects');
- } else {
- dom('h2:contains("Your projects") + ul li a')
- .get()
- .map((a) => {
- projects.push(dom(a).text());
- });
- }
-
- return {
- cookies: response.headers['set-cookie'].join(';'),
- patches,
- projects,
- repos,
- teams,
- tickets,
- username: account,
- vervis
- };
- }
-
- return null;
-}
diff --git a/src/lib/server/ap/login.js b/src/lib/server/ap/login.js
new file mode 100644
index 0000000..423c8b9
--- /dev/null
+++ b/src/lib/server/ap/login.js
@@ -0,0 +1,63 @@
+/* Private functions dealing with the login into a Vervis instance.
+ * Copyright (C) 2024 André Jaenisch
+ * SPDX-FileCopyrightText: 2024 André Jaenisch
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ *
+ * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License along with this program. If not, see .
+ */
+import { Agent } from 'node:https';
+
+import axios, { AxiosHeaders } from 'axios';
+import * as cheerio from 'cheerio';
+
+import pkg from '../../../../package.json';
+
+export async function getRemoteLogin(vervis) {
+ const httpsAgent = new Agent({ rejectUnauthorized: false });
+ const headers = new AxiosHeaders();
+ headers.setUserAgent(`Anvil/${pkg.version}`);
+ const instance = axios.create({
+ baseURL: vervis,
+ headers,
+ httpsAgent,
+ withCredentials: true
+ });
+ const response = await instance.get('/auth/login');
+
+ const dom = cheerio.load(response.data);
+ const form = dom('form');
+
+ return {
+ instance,
+ action: form.attr('action'),
+ csrf: dom('form input[name="_token"]').attr('value'),
+ enctype: form.attr('enctype'),
+ method: form.attr('method'),
+ cookies: response.headers['set-cookie']
+ };
+}
+
+export async function postRemoteLogin({ username, password, loginFormData }) {
+ const headers = new AxiosHeaders();
+ headers.setContentType(loginFormData.enctype);
+ headers.set({ Cookie: loginFormData.cookies.join(';') });
+
+ const data = {
+ _token: loginFormData.csrf,
+ f1: username,
+ f2: password
+ };
+
+ return loginFormData.instance({
+ method: loginFormData.method,
+ url: loginFormData.action,
+ headers,
+ data
+ });
+}
+
+