finki-auth 2.0.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -6
- package/dist/authentication.d.ts +7 -1
- package/dist/authentication.js +136 -16
- package/dist/constants.d.ts +16 -1
- package/dist/constants.js +18 -1
- package/dist/lib/Service.d.ts +4 -0
- package/dist/lib/Service.js +4 -0
- package/dist/utils.d.ts +8 -0
- package/dist/utils.js +11 -7
- package/package.json +8 -9
package/README.md
CHANGED
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
# FINKI Hub / FINKI Auth
|
|
2
2
|
|
|
3
|
-
Node.js package for managing authentication and cookies for FCSE's services
|
|
3
|
+
Node.js package for managing authentication and cookies for FCSE's services.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
7
|
Currently supports the following services:
|
|
8
8
|
|
|
9
|
+
- [Anketi](https://anketi.ukim.mk/)
|
|
9
10
|
- [CAS](https://cas.finki.ukim.mk/)
|
|
11
|
+
- [Consultations](https://consultations.finki.ukim.mk/)
|
|
10
12
|
- [Courses](https://courses.finki.ukim.mk/)
|
|
11
13
|
- [Diplomas](https://diplomski.finki.ukim.mk/)
|
|
12
|
-
- [
|
|
13
|
-
- [
|
|
14
|
+
- [GitLab](https://gitlab.finki.ukim.mk/)
|
|
15
|
+
- [iKnow](https://www.iknow.ukim.mk/)
|
|
14
16
|
- [Internships](https://internships.finki.ukim.mk/)
|
|
15
|
-
- [
|
|
17
|
+
- [Ispiti](https://ispiti.finki.ukim.mk/)
|
|
18
|
+
- [Masters](https://magisterski.finki.ukim.mk/)
|
|
19
|
+
- [Old Courses](https://oldcourses.finki.ukim.mk/)
|
|
16
20
|
|
|
17
21
|
## Installation
|
|
18
22
|
|
|
@@ -44,9 +48,9 @@ const cookies = await auth.getCookie(Service.COURSES);
|
|
|
44
48
|
const cookieHeader = await auth.buildCookieHeader(Service.COURSES);
|
|
45
49
|
|
|
46
50
|
// Check if the cookie is still valid, and if not, call `authenticate` again
|
|
47
|
-
const
|
|
51
|
+
const valid = await auth.isCookieValid(Service.COURSES);
|
|
48
52
|
|
|
49
|
-
if (!
|
|
53
|
+
if (!valid) await auth.authenticate(Service.COURSES);
|
|
50
54
|
|
|
51
55
|
// There are also some utility functions available:
|
|
52
56
|
const isCookieValidStandalone = await isCookieValid({
|
package/dist/authentication.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Service } from './lib/Service.js';
|
|
2
2
|
export declare class CasAuthentication {
|
|
3
3
|
private readonly cookieJar;
|
|
4
|
-
private readonly fetchWithCookies;
|
|
5
4
|
private readonly password;
|
|
6
5
|
private readonly username;
|
|
7
6
|
constructor({ password, username }: {
|
|
@@ -9,9 +8,16 @@ export declare class CasAuthentication {
|
|
|
9
8
|
username: string;
|
|
10
9
|
});
|
|
11
10
|
private static readonly getFullLoginUrl;
|
|
11
|
+
private static readonly submitOidcFormPost;
|
|
12
12
|
readonly authenticate: (service: Service) => Promise<void>;
|
|
13
13
|
readonly buildCookieHeader: (service: Service) => Promise<string>;
|
|
14
14
|
readonly getCookie: (service: Service) => Promise<import("tough-cookie").Cookie[]>;
|
|
15
15
|
readonly isCookieValid: (service: Service) => Promise<boolean>;
|
|
16
|
+
private readonly authenticateAnketi;
|
|
17
|
+
private readonly authenticateCas;
|
|
18
|
+
private readonly authenticateGitlab;
|
|
19
|
+
private readonly authenticateIknow;
|
|
20
|
+
private readonly authenticateService;
|
|
16
21
|
private readonly getFormData;
|
|
22
|
+
private readonly getGitlabFormData;
|
|
17
23
|
}
|
package/dist/authentication.js
CHANGED
|
@@ -1,19 +1,17 @@
|
|
|
1
1
|
import * as cheerio from 'cheerio';
|
|
2
2
|
import makeFetchCookie from 'fetch-cookie';
|
|
3
3
|
import { CookieJar } from 'tough-cookie';
|
|
4
|
-
import { SERVICE_LOGIN_URLS,
|
|
4
|
+
import { ANKETI_SIGN_IN_URL, GITLAB_LDAP_CALLBACK_URL, IKNOW_CAS_SERVICE_URL, SERVICE_LOGIN_URLS, } from './constants.js';
|
|
5
5
|
import { Service } from './lib/Service.js';
|
|
6
|
-
import { getCookieValidity } from './utils.js';
|
|
6
|
+
import { formatCookieHeader, getCookieValidity } from './utils.js';
|
|
7
7
|
export class CasAuthentication {
|
|
8
8
|
cookieJar;
|
|
9
|
-
fetchWithCookies;
|
|
10
9
|
password;
|
|
11
10
|
username;
|
|
12
11
|
constructor({ password, username }) {
|
|
13
12
|
this.username = username;
|
|
14
13
|
this.password = password;
|
|
15
14
|
this.cookieJar = new CookieJar();
|
|
16
|
-
this.fetchWithCookies = makeFetchCookie(fetch, this.cookieJar);
|
|
17
15
|
}
|
|
18
16
|
static getFullLoginUrl = (service) => {
|
|
19
17
|
if (service === Service.CAS) {
|
|
@@ -21,33 +19,145 @@ export class CasAuthentication {
|
|
|
21
19
|
}
|
|
22
20
|
return `${SERVICE_LOGIN_URLS[Service.CAS]}?service=${encodeURIComponent(SERVICE_LOGIN_URLS[service])}`;
|
|
23
21
|
};
|
|
24
|
-
|
|
25
|
-
const fullUrl = CasAuthentication.getFullLoginUrl(service);
|
|
26
|
-
const initialResponse = await this.fetchWithCookies(fullUrl);
|
|
27
|
-
const html = await initialResponse.text();
|
|
22
|
+
static submitOidcFormPost = async (fetchWithCookies, html) => {
|
|
28
23
|
const $ = cheerio.load(html);
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
24
|
+
const form = $('form[action*="/signin-oidc"]').first();
|
|
25
|
+
if (form.length === 0) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const action = form.attr('action');
|
|
29
|
+
if (!action) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const params = new URLSearchParams();
|
|
33
|
+
form.find('input[type="hidden"]').each((_i, input) => {
|
|
34
|
+
const name = $(input).attr('name');
|
|
35
|
+
const value = $(input).attr('value');
|
|
36
|
+
if (name) {
|
|
37
|
+
params.append(name, value ?? '');
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
const response = await fetchWithCookies(action, {
|
|
41
|
+
body: params,
|
|
32
42
|
method: 'POST',
|
|
33
43
|
});
|
|
44
|
+
await response.body?.cancel();
|
|
45
|
+
};
|
|
46
|
+
authenticate = async (service) => {
|
|
47
|
+
await this.authenticateService(service);
|
|
48
|
+
const cookies = await this.getCookie(service);
|
|
49
|
+
if (cookies.length === 0) {
|
|
50
|
+
throw new Error(`Authentication for "${service}" produced no cookies; the credentials may be invalid or the service may be unavailable`);
|
|
51
|
+
}
|
|
34
52
|
};
|
|
35
53
|
buildCookieHeader = async (service) => {
|
|
36
54
|
const cookies = await this.getCookie(service);
|
|
37
|
-
return cookies
|
|
55
|
+
return formatCookieHeader(cookies);
|
|
38
56
|
};
|
|
39
57
|
getCookie = async (service) => {
|
|
40
58
|
const serviceLoginUrl = SERVICE_LOGIN_URLS[service];
|
|
41
|
-
return
|
|
59
|
+
return this.cookieJar.getCookies(serviceLoginUrl);
|
|
42
60
|
};
|
|
43
61
|
isCookieValid = async (service) => {
|
|
44
|
-
const
|
|
62
|
+
const serviceLoginUrl = SERVICE_LOGIN_URLS[service];
|
|
45
63
|
const cookies = await this.getCookie(service);
|
|
46
64
|
const jar = new CookieJar();
|
|
47
65
|
for (const cookie of cookies) {
|
|
48
|
-
await jar.setCookie(cookie,
|
|
66
|
+
await jar.setCookie(cookie, serviceLoginUrl);
|
|
49
67
|
}
|
|
50
|
-
return
|
|
68
|
+
return getCookieValidity({ cookieJar: jar, service });
|
|
69
|
+
};
|
|
70
|
+
authenticateAnketi = async () => {
|
|
71
|
+
const jar = new CookieJar();
|
|
72
|
+
const fetchWithCookies = makeFetchCookie(fetch, jar);
|
|
73
|
+
const casLoginUrl = `${SERVICE_LOGIN_URLS[Service.CAS]}?service=${encodeURIComponent(IKNOW_CAS_SERVICE_URL)}`;
|
|
74
|
+
const initialResponse = await fetchWithCookies(casLoginUrl);
|
|
75
|
+
const html = await initialResponse.text();
|
|
76
|
+
const $ = cheerio.load(html);
|
|
77
|
+
const urlSearchParams = this.getFormData($);
|
|
78
|
+
const postResponse = await fetchWithCookies(casLoginUrl, {
|
|
79
|
+
body: urlSearchParams,
|
|
80
|
+
method: 'POST',
|
|
81
|
+
});
|
|
82
|
+
await postResponse.body?.cancel();
|
|
83
|
+
const signInResponse = await fetchWithCookies(ANKETI_SIGN_IN_URL);
|
|
84
|
+
await CasAuthentication.submitOidcFormPost(fetchWithCookies, await signInResponse.text());
|
|
85
|
+
const serviceUrl = SERVICE_LOGIN_URLS[Service.ANKETI];
|
|
86
|
+
const serviceCookies = await jar.getCookies(serviceUrl);
|
|
87
|
+
for (const cookie of serviceCookies) {
|
|
88
|
+
await this.cookieJar.setCookie(cookie, serviceUrl);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
authenticateCas = async (service) => {
|
|
92
|
+
const jar = new CookieJar();
|
|
93
|
+
const fetchWithCookies = makeFetchCookie(fetch, jar);
|
|
94
|
+
const casLoginUrl = CasAuthentication.getFullLoginUrl(service);
|
|
95
|
+
const initialResponse = await fetchWithCookies(casLoginUrl);
|
|
96
|
+
const html = await initialResponse.text();
|
|
97
|
+
const $ = cheerio.load(html);
|
|
98
|
+
const urlSearchParams = this.getFormData($);
|
|
99
|
+
const postResponse = await fetchWithCookies(casLoginUrl, {
|
|
100
|
+
body: urlSearchParams,
|
|
101
|
+
method: 'POST',
|
|
102
|
+
});
|
|
103
|
+
await postResponse.body?.cancel();
|
|
104
|
+
const serviceLoginUrl = SERVICE_LOGIN_URLS[service];
|
|
105
|
+
const serviceCookies = await jar.getCookies(serviceLoginUrl);
|
|
106
|
+
for (const cookie of serviceCookies) {
|
|
107
|
+
await this.cookieJar.setCookie(cookie, serviceLoginUrl);
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
authenticateGitlab = async () => {
|
|
111
|
+
const jar = new CookieJar();
|
|
112
|
+
const fetchWithCookies = makeFetchCookie(fetch, jar);
|
|
113
|
+
const signInUrl = SERVICE_LOGIN_URLS[Service.GITLAB];
|
|
114
|
+
const initialResponse = await fetchWithCookies(signInUrl);
|
|
115
|
+
const html = await initialResponse.text();
|
|
116
|
+
const $ = cheerio.load(html);
|
|
117
|
+
const urlSearchParams = this.getGitlabFormData($);
|
|
118
|
+
const postResponse = await fetchWithCookies(GITLAB_LDAP_CALLBACK_URL, {
|
|
119
|
+
body: urlSearchParams,
|
|
120
|
+
method: 'POST',
|
|
121
|
+
});
|
|
122
|
+
await postResponse.body?.cancel();
|
|
123
|
+
const serviceCookies = await jar.getCookies(signInUrl);
|
|
124
|
+
for (const cookie of serviceCookies) {
|
|
125
|
+
await this.cookieJar.setCookie(cookie, signInUrl);
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
authenticateIknow = async () => {
|
|
129
|
+
const jar = new CookieJar();
|
|
130
|
+
const fetchWithCookies = makeFetchCookie(fetch, jar);
|
|
131
|
+
const casLoginUrl = `${SERVICE_LOGIN_URLS[Service.CAS]}?service=${encodeURIComponent(IKNOW_CAS_SERVICE_URL)}`;
|
|
132
|
+
const initialResponse = await fetchWithCookies(casLoginUrl);
|
|
133
|
+
const html = await initialResponse.text();
|
|
134
|
+
const $ = cheerio.load(html);
|
|
135
|
+
const urlSearchParams = this.getFormData($);
|
|
136
|
+
const postResponse = await fetchWithCookies(casLoginUrl, {
|
|
137
|
+
body: urlSearchParams,
|
|
138
|
+
method: 'POST',
|
|
139
|
+
});
|
|
140
|
+
await CasAuthentication.submitOidcFormPost(fetchWithCookies, await postResponse.text());
|
|
141
|
+
const serviceUrl = SERVICE_LOGIN_URLS[Service.IKNOW];
|
|
142
|
+
const serviceCookies = await jar.getCookies(serviceUrl);
|
|
143
|
+
for (const cookie of serviceCookies) {
|
|
144
|
+
await this.cookieJar.setCookie(cookie, serviceUrl);
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
authenticateService = async (service) => {
|
|
148
|
+
if (service === Service.GITLAB) {
|
|
149
|
+
await this.authenticateGitlab();
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
if (service === Service.IKNOW) {
|
|
153
|
+
await this.authenticateIknow();
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
if (service === Service.ANKETI) {
|
|
157
|
+
await this.authenticateAnketi();
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
await this.authenticateCas(service);
|
|
51
161
|
};
|
|
52
162
|
getFormData = ($) => {
|
|
53
163
|
const urlSearchParams = new URLSearchParams();
|
|
@@ -63,4 +173,14 @@ export class CasAuthentication {
|
|
|
63
173
|
urlSearchParams.append('submit', 'LOGIN');
|
|
64
174
|
return urlSearchParams;
|
|
65
175
|
};
|
|
176
|
+
getGitlabFormData = ($) => {
|
|
177
|
+
const urlSearchParams = new URLSearchParams();
|
|
178
|
+
const ldapForm = $('form[action="/users/auth/ldapmain/callback"]').first();
|
|
179
|
+
const authenticityToken = ldapForm.find('input[name="authenticity_token"]').attr('value') ?? '';
|
|
180
|
+
urlSearchParams.append('authenticity_token', authenticityToken);
|
|
181
|
+
urlSearchParams.append('username', this.username);
|
|
182
|
+
urlSearchParams.append('password', this.password);
|
|
183
|
+
urlSearchParams.append('remember_me', '0');
|
|
184
|
+
return urlSearchParams;
|
|
185
|
+
};
|
|
66
186
|
}
|
package/dist/constants.d.ts
CHANGED
|
@@ -1,27 +1,42 @@
|
|
|
1
1
|
export declare const SERVICE_URLS: {
|
|
2
|
+
readonly anketi: "https://anketi.ukim.mk";
|
|
2
3
|
readonly cas: "https://cas.finki.ukim.mk/cas";
|
|
3
4
|
readonly consultations: "https://consultations.finki.ukim.mk";
|
|
4
5
|
readonly courses: "https://courses.finki.ukim.mk";
|
|
5
|
-
readonly diplomas: "
|
|
6
|
+
readonly diplomas: "https://diplomski.finki.ukim.mk";
|
|
7
|
+
readonly gitlab: "https://gitlab.finki.ukim.mk";
|
|
8
|
+
readonly iknow: "https://www.iknow.ukim.mk";
|
|
6
9
|
readonly internships: "https://internships.finki.ukim.mk";
|
|
10
|
+
readonly ispiti: "https://ispiti.finki.ukim.mk";
|
|
7
11
|
readonly masters: "https://magisterski.finki.ukim.mk";
|
|
8
12
|
readonly old_courses: "https://oldcourses.finki.ukim.mk";
|
|
9
13
|
};
|
|
10
14
|
export declare const SERVICE_LOGIN_URLS: {
|
|
15
|
+
readonly anketi: "https://anketi.ukim.mk";
|
|
11
16
|
readonly cas: "https://cas.finki.ukim.mk/cas/login";
|
|
12
17
|
readonly consultations: "https://consultations.finki.ukim.mk/consultations";
|
|
13
18
|
readonly courses: "https://courses.finki.ukim.mk/login/index.php";
|
|
14
19
|
readonly diplomas: "http://diplomski.finki.ukim.mk/Account/LoginCAS";
|
|
20
|
+
readonly gitlab: "https://gitlab.finki.ukim.mk/users/sign_in";
|
|
21
|
+
readonly iknow: "https://www.iknow.ukim.mk";
|
|
15
22
|
readonly internships: "https://internships.finki.ukim.mk/login";
|
|
23
|
+
readonly ispiti: "https://ispiti.finki.ukim.mk/login/index.php";
|
|
16
24
|
readonly masters: "https://magisterski.finki.ukim.mk/login";
|
|
17
25
|
readonly old_courses: "https://oldcourses.finki.ukim.mk/login/index.php";
|
|
18
26
|
};
|
|
19
27
|
export declare const SERVICE_SUCCESS_SELECTORS: {
|
|
28
|
+
readonly anketi: "a[href=\"/MicrosoftIdentity/Account/SignOut\"]";
|
|
20
29
|
readonly cas: "div.success";
|
|
21
30
|
readonly consultations: "a#username";
|
|
22
31
|
readonly courses: "span.usertext.me-1";
|
|
23
32
|
readonly diplomas: "#logoutForm > ul > li:nth-child(1) > a";
|
|
33
|
+
readonly gitlab: "aside.super-sidebar";
|
|
34
|
+
readonly iknow: "a#ctl00_ctl00_lnkLogOut";
|
|
24
35
|
readonly internships: "span.text-white";
|
|
36
|
+
readonly ispiti: "span.usertext.me-1";
|
|
25
37
|
readonly masters: "li > a > span";
|
|
26
38
|
readonly old_courses: "span.usertext.mr-1";
|
|
27
39
|
};
|
|
40
|
+
export declare const GITLAB_LDAP_CALLBACK_URL = "https://gitlab.finki.ukim.mk/users/auth/ldapmain/callback";
|
|
41
|
+
export declare const IKNOW_CAS_SERVICE_URL = "https://is.iknow.ukim.mk/account/logincas";
|
|
42
|
+
export declare const ANKETI_SIGN_IN_URL = "https://anketi.ukim.mk/MicrosoftIdentity/Account/SignIn";
|
package/dist/constants.js
CHANGED
|
@@ -1,28 +1,45 @@
|
|
|
1
1
|
import { Service } from './lib/Service.js';
|
|
2
2
|
export const SERVICE_URLS = {
|
|
3
|
+
[Service.ANKETI]: 'https://anketi.ukim.mk',
|
|
3
4
|
[Service.CAS]: 'https://cas.finki.ukim.mk/cas',
|
|
4
5
|
[Service.CONSULTATIONS]: 'https://consultations.finki.ukim.mk',
|
|
5
6
|
[Service.COURSES]: 'https://courses.finki.ukim.mk',
|
|
6
|
-
[Service.DIPLOMAS]: '
|
|
7
|
+
[Service.DIPLOMAS]: 'https://diplomski.finki.ukim.mk',
|
|
8
|
+
[Service.GITLAB]: 'https://gitlab.finki.ukim.mk',
|
|
9
|
+
[Service.IKNOW]: 'https://www.iknow.ukim.mk',
|
|
7
10
|
[Service.INTERNSHIPS]: 'https://internships.finki.ukim.mk',
|
|
11
|
+
[Service.ISPITI]: 'https://ispiti.finki.ukim.mk',
|
|
8
12
|
[Service.MASTERS]: 'https://magisterski.finki.ukim.mk',
|
|
9
13
|
[Service.OLD_COURSES]: 'https://oldcourses.finki.ukim.mk',
|
|
10
14
|
};
|
|
11
15
|
export const SERVICE_LOGIN_URLS = {
|
|
16
|
+
[Service.ANKETI]: 'https://anketi.ukim.mk',
|
|
12
17
|
[Service.CAS]: 'https://cas.finki.ukim.mk/cas/login',
|
|
13
18
|
[Service.CONSULTATIONS]: 'https://consultations.finki.ukim.mk/consultations',
|
|
14
19
|
[Service.COURSES]: 'https://courses.finki.ukim.mk/login/index.php',
|
|
20
|
+
// CAS only authorises this service under its http URL; an https `service`
|
|
21
|
+
// param is rejected and no ticket is issued. The server upgrades to https.
|
|
15
22
|
[Service.DIPLOMAS]: 'http://diplomski.finki.ukim.mk/Account/LoginCAS',
|
|
23
|
+
[Service.GITLAB]: 'https://gitlab.finki.ukim.mk/users/sign_in',
|
|
24
|
+
[Service.IKNOW]: 'https://www.iknow.ukim.mk',
|
|
16
25
|
[Service.INTERNSHIPS]: 'https://internships.finki.ukim.mk/login',
|
|
26
|
+
[Service.ISPITI]: 'https://ispiti.finki.ukim.mk/login/index.php',
|
|
17
27
|
[Service.MASTERS]: 'https://magisterski.finki.ukim.mk/login',
|
|
18
28
|
[Service.OLD_COURSES]: 'https://oldcourses.finki.ukim.mk/login/index.php',
|
|
19
29
|
};
|
|
20
30
|
export const SERVICE_SUCCESS_SELECTORS = {
|
|
31
|
+
[Service.ANKETI]: 'a[href="/MicrosoftIdentity/Account/SignOut"]',
|
|
21
32
|
[Service.CAS]: 'div.success',
|
|
22
33
|
[Service.CONSULTATIONS]: 'a#username',
|
|
23
34
|
[Service.COURSES]: 'span.usertext.me-1',
|
|
24
35
|
[Service.DIPLOMAS]: '#logoutForm > ul > li:nth-child(1) > a',
|
|
36
|
+
[Service.GITLAB]: 'aside.super-sidebar',
|
|
37
|
+
[Service.IKNOW]: 'a#ctl00_ctl00_lnkLogOut',
|
|
25
38
|
[Service.INTERNSHIPS]: 'span.text-white',
|
|
39
|
+
[Service.ISPITI]: 'span.usertext.me-1',
|
|
26
40
|
[Service.MASTERS]: 'li > a > span',
|
|
27
41
|
[Service.OLD_COURSES]: 'span.usertext.mr-1',
|
|
28
42
|
};
|
|
43
|
+
export const GITLAB_LDAP_CALLBACK_URL = 'https://gitlab.finki.ukim.mk/users/auth/ldapmain/callback';
|
|
44
|
+
export const IKNOW_CAS_SERVICE_URL = 'https://is.iknow.ukim.mk/account/logincas';
|
|
45
|
+
export const ANKETI_SIGN_IN_URL = 'https://anketi.ukim.mk/MicrosoftIdentity/Account/SignIn';
|
package/dist/lib/Service.d.ts
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
export declare enum Service {
|
|
3
|
+
ANKETI = "anketi",
|
|
3
4
|
CAS = "cas",
|
|
4
5
|
CONSULTATIONS = "consultations",
|
|
5
6
|
COURSES = "courses",
|
|
6
7
|
DIPLOMAS = "diplomas",
|
|
8
|
+
GITLAB = "gitlab",
|
|
9
|
+
IKNOW = "iknow",
|
|
7
10
|
INTERNSHIPS = "internships",
|
|
11
|
+
ISPITI = "ispiti",
|
|
8
12
|
MASTERS = "masters",
|
|
9
13
|
OLD_COURSES = "old_courses"
|
|
10
14
|
}
|
package/dist/lib/Service.js
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
export var Service;
|
|
3
3
|
(function (Service) {
|
|
4
|
+
Service["ANKETI"] = "anketi";
|
|
4
5
|
Service["CAS"] = "cas";
|
|
5
6
|
Service["CONSULTATIONS"] = "consultations";
|
|
6
7
|
Service["COURSES"] = "courses";
|
|
7
8
|
Service["DIPLOMAS"] = "diplomas";
|
|
9
|
+
Service["GITLAB"] = "gitlab";
|
|
10
|
+
Service["IKNOW"] = "iknow";
|
|
8
11
|
Service["INTERNSHIPS"] = "internships";
|
|
12
|
+
Service["ISPITI"] = "ispiti";
|
|
9
13
|
Service["MASTERS"] = "masters";
|
|
10
14
|
Service["OLD_COURSES"] = "old_courses";
|
|
11
15
|
})(Service || (Service = {}));
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { type Cookie, CookieJar } from 'tough-cookie';
|
|
2
2
|
import type { Service } from './lib/Service.js';
|
|
3
|
+
export declare const parseCookieHeader: (cookieHeader: string) => Array<{
|
|
4
|
+
key: string;
|
|
5
|
+
value: string;
|
|
6
|
+
}>;
|
|
7
|
+
export declare const formatCookieHeader: (cookies: ReadonlyArray<{
|
|
8
|
+
key: string;
|
|
9
|
+
value: string;
|
|
10
|
+
}>) => string;
|
|
3
11
|
export declare const getCookieValidity: ({ cookieJar, service, }: {
|
|
4
12
|
cookieJar: CookieJar;
|
|
5
13
|
service: Service;
|
package/dist/utils.js
CHANGED
|
@@ -2,6 +2,16 @@ import * as cheerio from 'cheerio';
|
|
|
2
2
|
import makeFetchCookie from 'fetch-cookie';
|
|
3
3
|
import { CookieJar } from 'tough-cookie';
|
|
4
4
|
import { SERVICE_SUCCESS_SELECTORS, SERVICE_URLS } from './constants.js';
|
|
5
|
+
export const parseCookieHeader = (cookieHeader) => {
|
|
6
|
+
if (!cookieHeader) {
|
|
7
|
+
return [];
|
|
8
|
+
}
|
|
9
|
+
return cookieHeader.split('; ').map((cookie) => {
|
|
10
|
+
const [key = '', ...valueParts] = cookie.split('=');
|
|
11
|
+
return { key, value: valueParts.join('=') };
|
|
12
|
+
});
|
|
13
|
+
};
|
|
14
|
+
export const formatCookieHeader = (cookies) => cookies.map(({ key, value }) => `${key}=${value}`).join('; ');
|
|
5
15
|
export const getCookieValidity = async ({ cookieJar, service, }) => {
|
|
6
16
|
const url = SERVICE_URLS[service];
|
|
7
17
|
const userElementSelector = SERVICE_SUCCESS_SELECTORS[service];
|
|
@@ -30,13 +40,7 @@ export const isCookieValid = async ({ cookies, service, }) => {
|
|
|
30
40
|
export const isCookieHeaderValid = async ({ cookieHeader, service, }) => {
|
|
31
41
|
const url = SERVICE_URLS[service];
|
|
32
42
|
const jar = new CookieJar();
|
|
33
|
-
const cookies = cookieHeader
|
|
34
|
-
? cookieHeader.split('; ').map((cookie) => {
|
|
35
|
-
const [key, ...valParts] = cookie.split('=');
|
|
36
|
-
const value = valParts.join('=');
|
|
37
|
-
return { key, value };
|
|
38
|
-
})
|
|
39
|
-
: [];
|
|
43
|
+
const cookies = parseCookieHeader(cookieHeader);
|
|
40
44
|
for (const { key, value } of cookies) {
|
|
41
45
|
await jar.setCookie(`${key}=${value}`, url);
|
|
42
46
|
}
|
package/package.json
CHANGED
|
@@ -20,21 +20,20 @@
|
|
|
20
20
|
},
|
|
21
21
|
"description": "Authentication for FCSE services",
|
|
22
22
|
"devDependencies": {
|
|
23
|
-
"@commitlint/cli": "^
|
|
24
|
-
"@commitlint/config-conventional": "^
|
|
25
|
-
"commitizen": "^4.3.
|
|
23
|
+
"@commitlint/cli": "^21.0.0",
|
|
24
|
+
"@commitlint/config-conventional": "^21.0.0",
|
|
25
|
+
"commitizen": "^4.3.2",
|
|
26
26
|
"cz-conventional-changelog": "^3.3.0",
|
|
27
|
-
"
|
|
28
|
-
"eslint": "^
|
|
29
|
-
"eslint-config-imperium": "^3.4.0",
|
|
27
|
+
"eslint": "^10.5.0",
|
|
28
|
+
"eslint-config-imperium": "^4.1.1",
|
|
30
29
|
"husky": "^9.1.7",
|
|
31
30
|
"rimraf": "^6.1.3",
|
|
32
31
|
"semantic-release": "^25.0.2",
|
|
33
|
-
"typescript": "~
|
|
32
|
+
"typescript": "~6.0.2",
|
|
34
33
|
"vitest": "^4.0.18"
|
|
35
34
|
},
|
|
36
35
|
"engines": {
|
|
37
|
-
"node": "^22 || ^24"
|
|
36
|
+
"node": "^22 || ^24 || ^26"
|
|
38
37
|
},
|
|
39
38
|
"files": [
|
|
40
39
|
"dist",
|
|
@@ -68,5 +67,5 @@
|
|
|
68
67
|
},
|
|
69
68
|
"type": "module",
|
|
70
69
|
"types": "dist/index.d.ts",
|
|
71
|
-
"version": "
|
|
70
|
+
"version": "3.0.0"
|
|
72
71
|
}
|