From 411053c5d03559524b6555caf85ff42842a7d755 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sarstr=C3=B6m?= <viktorsarstrom@gmail.com> Date: Thu, 2 Dec 2021 09:54:04 +0100 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20Abscense=20registrat?= =?UTF-8?q?ion=20for=20HT=20and=20Skolplattformen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libs/api-hjarntorget/lib/apiHjarntorget.ts | 18 ++++++++++++++++++ libs/api-hjarntorget/lib/features.ts | 2 ++ libs/api-hjarntorget/lib/routes.ts | 1 + libs/api-skolplattformen/lib/api.ts | 3 +++ libs/api-skolplattformen/lib/features.ts | 2 ++ libs/api/lib/api.ts | 1 + libs/api/lib/features.ts | 4 +++- 7 files changed, 30 insertions(+), 1 deletion(-) diff --git a/libs/api-hjarntorget/lib/apiHjarntorget.ts b/libs/api-hjarntorget/lib/apiHjarntorget.ts index 103c38bd4..78ee7c4d0 100644 --- a/libs/api-hjarntorget/lib/apiHjarntorget.ts +++ b/libs/api-hjarntorget/lib/apiHjarntorget.ts @@ -47,6 +47,7 @@ import { shibbolethLoginUrlBase, verifyUrlBase, wallMessagesUrl, + abscenseRegistrationUrl } from './routes' function getDateOfISOWeek(week: number, year: number) { @@ -571,6 +572,22 @@ export class ApiHjarntorget extends EventEmitter implements Api { return statusChecker } + public async registerAbscense(child: EtjanstChild, startDate: Date, endDate: Date): Promise<void> { + + const body = { + attendeeId: child.id, + startDate: startDate, + endDate: endDate, + statusId: 27433608, + _submit: 'Register+the+whole+day' + } + + this.fetch('register-abscense', abscenseRegistrationUrl, { + method: 'POST', + body: new URLSearchParams(body).toString(), + }) + } + private async fakeMode(): Promise<LoginStatusChecker> { this.isFake = true @@ -583,4 +600,5 @@ export class ApiHjarntorget extends EventEmitter implements Api { emitter.token = 'fake' return emitter } + } diff --git a/libs/api-hjarntorget/lib/features.ts b/libs/api-hjarntorget/lib/features.ts index 681f2f4b9..1a14ef95a 100644 --- a/libs/api-hjarntorget/lib/features.ts +++ b/libs/api-hjarntorget/lib/features.ts @@ -4,4 +4,6 @@ export const features: Features = { LOGIN_BANK_ID_SAME_DEVICE_WITHOUT_ID: false, FOOD_MENU: false, CLASS_LIST: false, + ABSCENE_REGISTRATION_SMS: false, + ABSCENE_REGISTRATION_FORM: true } diff --git a/libs/api-hjarntorget/lib/routes.ts b/libs/api-hjarntorget/lib/routes.ts index fbedfb120..673e91040 100644 --- a/libs/api-hjarntorget/lib/routes.ts +++ b/libs/api-hjarntorget/lib/routes.ts @@ -15,6 +15,7 @@ export const wallMessagesUrl = 'https://hjarntorget.goteborg.se/api/wall/events? export const beginLoginUrl = 'https://hjarntorget.goteborg.se' export const calendarsUrl = 'https://hjarntorget.goteborg.se/pp/system/calendar/cal_events.jsp' export const calendarEventUrl = (calendarId: string, startDate: string, endDate: string) => `${calendarsUrl}?order_by=start_date&show_cal_ids=${calendarId}&mode=separate&filter_start_date=${startDate}&filter_end_date=${endDate}&search_for=` +export const abscenseRegistrationUrl = 'https://hjarntorget.goteborg.se/attendanceParentSubmitAbsence.do' export const shibbolethLoginUrlBase = (beginLoginRedirectUrl: string) => { const returnUrlStart = beginLoginRedirectUrl.indexOf('return=') + 'return='.length diff --git a/libs/api-skolplattformen/lib/api.ts b/libs/api-skolplattformen/lib/api.ts index 66d94cede..d2dce1c0a 100644 --- a/libs/api-skolplattformen/lib/api.ts +++ b/libs/api-skolplattformen/lib/api.ts @@ -79,6 +79,9 @@ export class ApiSkolplattformen extends EventEmitter implements Api { this.cookieManager = cookieManager this.headers = {} } + registerAbscense(child: EtjanstChild, startDate: Date, endDate: Date): Promise<boolean> { + throw new Error('Method not implemented.') + } public getPersonalNumber(): string | undefined { return this.personalNumber diff --git a/libs/api-skolplattformen/lib/features.ts b/libs/api-skolplattformen/lib/features.ts index 0e9dfce49..017c3b89f 100644 --- a/libs/api-skolplattformen/lib/features.ts +++ b/libs/api-skolplattformen/lib/features.ts @@ -4,4 +4,6 @@ export const features: Features = { LOGIN_BANK_ID_SAME_DEVICE_WITHOUT_ID: true, FOOD_MENU: true, CLASS_LIST: true, + ABSCENE_REGISTRATION_SMS: true, + ABSCENE_REGISTRATION_FORM: false } diff --git a/libs/api/lib/api.ts b/libs/api/lib/api.ts index 890176b49..c940942f3 100644 --- a/libs/api/lib/api.ts +++ b/libs/api/lib/api.ts @@ -32,5 +32,6 @@ export interface Api extends EventEmitter { getSchedule(child: EtjanstChild, from: DateTime, to: DateTime): Promise<ScheduleItem[]> getSkola24Children(): Promise<Skola24Child[]> getTimetable(child: Skola24Child, week: number, year: number, lang: Language): Promise<TimetableEntry[]> + registerAbscense(child: EtjanstChild, startDate: Date, endDate: Date): Promise<void> logout(): Promise<void> } diff --git a/libs/api/lib/features.ts b/libs/api/lib/features.ts index 752066748..7791ad656 100644 --- a/libs/api/lib/features.ts +++ b/libs/api/lib/features.ts @@ -1,7 +1,9 @@ export interface Features { LOGIN_BANK_ID_SAME_DEVICE_WITHOUT_ID: boolean FOOD_MENU: boolean, - CLASS_LIST: boolean + CLASS_LIST: boolean, + ABSCENE_REGISTRATION_SMS: boolean, + ABSCENE_REGISTRATION_FORM: boolean, } export type FeatureType = keyof Features From de6aef638e02143a48e1229631a47798f40830b1 Mon Sep 17 00:00:00 2001 From: Emil Lindqvist <emil.hellman+contributions@gmail.com> Date: Wed, 15 Dec 2021 09:43:04 +0100 Subject: [PATCH 2/2] =?UTF-8?q?Make=20registerAbscence=20work=20with=20Hj?= =?UTF-8?q?=C3=A4rntorget?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This changes teh registerAbscence api to use DateTime instead of Date, mainly to be consistent with getSchedule that already used DateTime. The main fixes that was missing is properly formatting the start and end dates sent to the server and ensuring a `Referer` header is included similar to what is sent in the browser. --- libs/api-hjarntorget/lib/apiHjarntorget.ts | 34 ++++++++++++---------- libs/api-hjarntorget/lib/index.ts | 2 +- libs/api-skolplattformen/lib/api.ts | 2 +- libs/api/lib/api.ts | 2 +- 4 files changed, 22 insertions(+), 18 deletions(-) diff --git a/libs/api-hjarntorget/lib/apiHjarntorget.ts b/libs/api-hjarntorget/lib/apiHjarntorget.ts index 78ee7c4d0..fa7db06e6 100644 --- a/libs/api-hjarntorget/lib/apiHjarntorget.ts +++ b/libs/api-hjarntorget/lib/apiHjarntorget.ts @@ -5,6 +5,7 @@ import { Classmate, CookieManager, EtjanstChild, + Fetch, Fetcher, FetcherOptions, LoginStatusChecker, @@ -85,7 +86,7 @@ export class ApiHjarntorget extends EventEmitter implements Api { } constructor( - fetch: typeof global.fetch, + fetch: Fetch, cookieManager: CookieManager, options?: FetcherOptions ) { @@ -497,7 +498,7 @@ export class ApiHjarntorget extends EventEmitter implements Api { emitter.emit('OK') this.emit('login') }, 50) - return emitter; + return emitter as unknown as LoginStatusChecker; } console.log('prepping??? shibboleth') @@ -572,20 +573,23 @@ export class ApiHjarntorget extends EventEmitter implements Api { return statusChecker } - public async registerAbscense(child: EtjanstChild, startDate: Date, endDate: Date): Promise<void> { - - const body = { - attendeeId: child.id, - startDate: startDate, - endDate: endDate, - statusId: 27433608, - _submit: 'Register+the+whole+day' - } + public async registerAbscense(child: EtjanstChild, startDate: DateTime, endDate: DateTime): Promise<void> { + const body = { + attendeeId: child.id, + startDate: startDate.toFormat("yyyy-MM-dd HH:mm"), + endDate: endDate.toFormat("yyyy-MM-dd HH:mm"), + statusId: 27433608, + _submit: 'Save' + } - this.fetch('register-abscense', abscenseRegistrationUrl, { - method: 'POST', - body: new URLSearchParams(body).toString(), - }) + await this.fetch('register-abscense', abscenseRegistrationUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + 'Referer': "https://hjarntorget.goteborg.se/attendanceParentRegisterAbsence.do?attendeeId=" + child.id, + }, + body: new URLSearchParams(body).toString(), + }) } private async fakeMode(): Promise<LoginStatusChecker> { diff --git a/libs/api-hjarntorget/lib/index.ts b/libs/api-hjarntorget/lib/index.ts index c00675f89..b0bc4a929 100644 --- a/libs/api-hjarntorget/lib/index.ts +++ b/libs/api-hjarntorget/lib/index.ts @@ -19,7 +19,7 @@ const init = ( const cookieManager = ((cookieManagerImpl as RNCookieManager).get) ? wrapReactNativeCookieManager(cookieManagerImpl as RNCookieManager) : wrapToughCookie(cookieManagerImpl as ToughCookieJar) - return new ApiHjarntorget(fetchImpl as any, cookieManager, options) + return new ApiHjarntorget(fetchImpl, cookieManager, options) } export default init diff --git a/libs/api-skolplattformen/lib/api.ts b/libs/api-skolplattformen/lib/api.ts index d2dce1c0a..427cc902d 100644 --- a/libs/api-skolplattformen/lib/api.ts +++ b/libs/api-skolplattformen/lib/api.ts @@ -79,7 +79,7 @@ export class ApiSkolplattformen extends EventEmitter implements Api { this.cookieManager = cookieManager this.headers = {} } - registerAbscense(child: EtjanstChild, startDate: Date, endDate: Date): Promise<boolean> { + registerAbscense(child: EtjanstChild, startDate: DateTime, endDate: DateTime): Promise<void> { throw new Error('Method not implemented.') } diff --git a/libs/api/lib/api.ts b/libs/api/lib/api.ts index c940942f3..00c2abbb9 100644 --- a/libs/api/lib/api.ts +++ b/libs/api/lib/api.ts @@ -32,6 +32,6 @@ export interface Api extends EventEmitter { getSchedule(child: EtjanstChild, from: DateTime, to: DateTime): Promise<ScheduleItem[]> getSkola24Children(): Promise<Skola24Child[]> getTimetable(child: Skola24Child, week: number, year: number, lang: Language): Promise<TimetableEntry[]> - registerAbscense(child: EtjanstChild, startDate: Date, endDate: Date): Promise<void> + registerAbscense(child: EtjanstChild, startDate: DateTime, endDate: DateTime): Promise<void> logout(): Promise<void> }