From 16020a3d3c9e378c2f3aec64a59d288673058473 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20=C3=96brink?= Date: Thu, 11 Mar 2021 17:27:26 +0100 Subject: [PATCH] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Adjusted=20cookie=20handl?= =?UTF-8?q?ing=20(#79)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/api.ts | 93 ++++++++++++++++++++++++++++-------------------------- run.js | 16 +++++----- 2 files changed, 57 insertions(+), 52 deletions(-) diff --git a/lib/api.ts b/lib/api.ts index 29295a07b..21ff7d2e5 100644 --- a/lib/api.ts +++ b/lib/api.ts @@ -49,32 +49,42 @@ export class Api extends EventEmitter { this.headers = {} } - getPersonalNumber() { + public getPersonalNumber(): string | undefined { return this.personalNumber } - async getSession(url: string, options: RequestInit = {}): Promise { - const cookie = await this.cookieManager.getCookieString(url) + private getRequestInit(options: RequestInit = {}): RequestInit { return { ...options, headers: { ...this.headers, ...options.headers, + }, + } + } + + public async getSession(url: string, options?: RequestInit): Promise { + const init = this.getRequestInit(options) + const cookie = await this.cookieManager.getCookieString(url) + return { + ...init, + headers: { + ...init.headers, cookie, }, } } - async clearSession(): Promise { + private async clearSession(): Promise { this.headers = {} await this.cookieManager.clearAll() } - addHeader(name: string, value: string): void { + private addHeader(name: string, value: string): void { this.headers[name] = value } - async login(personalNumber: string): Promise { + public async login(personalNumber: string): Promise { if (personalNumber.endsWith('1212121212')) return this.fakeMode() this.isFake = false @@ -105,14 +115,14 @@ export class Api extends EventEmitter { return status } - async retrieveSessionCookie(): Promise { + private async retrieveSessionCookie(): Promise { const url = routes.loginCookie await this.fetch('login-cookie', url) } - async retrieveXsrfToken(): Promise { + private async retrieveXsrfToken(): Promise { const url = routes.hemPage - const session = await this.getSession(url) + const session = this.getRequestInit() const response = await this.fetch('hemPage', url, session) const text = await response.text() const doc = html.parse(decode(text)) @@ -120,9 +130,9 @@ export class Api extends EventEmitter { this.addHeader('X-XSRF-Token', xsrfToken) } - async retrieveApiKey(): Promise { + private async retrieveApiKey(): Promise { const url = routes.startBundle - const session = await this.getSession(url) + const session = this.getRequestInit() const response = await this.fetch('startBundle', url, session) const text = await response.text() @@ -133,29 +143,27 @@ export class Api extends EventEmitter { this.addHeader('API-Key', apiKey) } - async retrieveCdnUrl(): Promise { + private async retrieveCdnUrl(): Promise { const url = routes.cdn - const session = await this.getSession(url) + const session = this.getRequestInit() const response = await this.fetch('cdn', url, session) const cdnUrl = await response.text() return cdnUrl } - async retrieveAuthBody(): Promise { + private async retrieveAuthBody(): Promise { const url = routes.auth - const session = await this.getSession(url) + const session = this.getRequestInit() const response = await this.fetch('auth', url, session) const authBody = await response.text() return authBody } - async retrieveAuthToken(url: string, authBody: string): Promise { - const cdnHost = new URL(url).host - const session = await this.getSession(url, { + private async retrieveAuthToken(url: string, authBody: string): Promise { + const session = this.getRequestInit({ method: 'POST', headers: { Accept: 'text/plain', - Host: cdnHost, Origin: 'https://etjanst.stockholm.se', Referer: 'https://etjanst.stockholm.se/', Connection: 'keep-alive', @@ -163,15 +171,14 @@ export class Api extends EventEmitter { body: authBody, }) - // Delete cookies from session and empty cookie manager - delete session.headers.cookie + // Temporarily remove cookies const cookies = await this.cookieManager.getCookies(url) this.cookieManager.clearAll() // Perform request const response = await this.fetch('createItem', url, session) - // Refill cookie manager + // Restore cookies cookies.forEach((cookie) => { this.cookieManager.setCookie(cookie, url) }) @@ -184,7 +191,7 @@ export class Api extends EventEmitter { return authData.token } - async fakeMode(): Promise { + private async fakeMode(): Promise { this.isFake = true setTimeout(() => { @@ -197,17 +204,17 @@ export class Api extends EventEmitter { return emitter } - async getUser(): Promise { + public async getUser(): Promise { if (this.isFake) return fakeResponse(fake.user()) const url = routes.user - const session = await this.getSession(url) + const session = this.getRequestInit() const response = await this.fetch('user', url, session) const data = await response.json() return parse.user(data) } - async getChildren(): Promise { + public async getChildren(): Promise { if (this.isFake) return fakeResponse(fake.children()) const cdnUrl = await this.retrieveCdnUrl() @@ -215,7 +222,7 @@ export class Api extends EventEmitter { const token = await this.retrieveAuthToken(cdnUrl, authBody) const url = routes.children - const session = await this.getSession(url, { + const session = this.getRequestInit({ headers: { Accept: 'application/json;odata=verbose', Auth: token, @@ -225,8 +232,6 @@ export class Api extends EventEmitter { }) const response = await this.fetch('children', url, session) - console.log(session.headers) - console.log('children response', response) if (!response.ok) { throw new Error(`Server Error [${response.status}] [${response.statusText}] [${url}]`) } @@ -235,78 +240,78 @@ export class Api extends EventEmitter { return parse.children(data) } - async getCalendar(child: Child): Promise { + public async getCalendar(child: Child): Promise { if (this.isFake) return fakeResponse(fake.calendar(child)) const url = routes.calendar(child.id) - const session = await this.getSession(url) + const session = this.getRequestInit() const response = await this.fetch('calendar', url, session) const data = await response.json() return parse.calendar(data) } - async getClassmates(child: Child): Promise { + public async getClassmates(child: Child): Promise { if (this.isFake) return fakeResponse(fake.classmates(child)) const url = routes.classmates(child.sdsId) - const session = await this.getSession(url) + const session = this.getRequestInit() const response = await this.fetch('classmates', url, session) const data = await response.json() return parse.classmates(data) } - async getSchedule(child: Child, from: DateTime, to: DateTime): Promise { + public async getSchedule(child: Child, from: DateTime, to: DateTime): Promise { if (this.isFake) return fakeResponse(fake.schedule(child)) const url = routes.schedule(child.sdsId, from.toISODate(), to.toISODate()) - const session = await this.getSession(url) + const session = this.getRequestInit() const response = await this.fetch('schedule', url, session) const data = await response.json() return parse.schedule(data) } - async getNews(child: Child): Promise { + public async getNews(child: Child): Promise { if (this.isFake) return fakeResponse(fake.news(child)) const url = routes.news(child.id) - const session = await this.getSession(url) + const session = this.getRequestInit() const response = await this.fetch('news', url, session) const data = await response.json() return parse.news(data) } - async getNewsDetails(child: Child, item: NewsItem): Promise { + public async getNewsDetails(child: Child, item: NewsItem): Promise { if (this.isFake) { return fakeResponse(fake.news(child).find((ni) => ni.id === item.id)) } const url = routes.newsDetails(child.id, item.id) - const session = await this.getSession(url) + const session = this.getRequestInit() const response = await this.fetch(`news_${item.id}`, url, session) const data = await response.json() return parse.newsItemDetails(data) } - async getMenu(child: Child): Promise { + public async getMenu(child: Child): Promise { if (this.isFake) return fakeResponse(fake.menu(child)) const url = routes.menu(child.id) - const session = await this.getSession(url) + const session = this.getRequestInit() const response = await this.fetch('menu', url, session) const data = await response.json() return parse.menu(data) } - async getNotifications(child: Child): Promise { + public async getNotifications(child: Child): Promise { if (this.isFake) return fakeResponse(fake.notifications(child)) const url = routes.notifications(child.sdsId) - const session = await this.getSession(url) + const session = this.getRequestInit() const response = await this.fetch('notifications', url, session) const data = await response.json() return parse.notifications(data) } - async logout() { + public async logout() { this.isFake = false this.personalNumber = undefined this.isLoggedIn = false diff --git a/run.js b/run.js index 0ad412e3f..2eece35db 100644 --- a/run.js +++ b/run.js @@ -91,14 +91,14 @@ async function run() { api.on('login', async () => { console.log('Logged in') - console.log('user') - const user = await api.getUser() - console.log(user) + // console.log('user') + // const user = await api.getUser() + // console.log(user) console.log('children') const children = await api.getChildren() console.log(children) - +/* console.log('calendar') const calendar = await api.getCalendar(children[0]) console.log(calendar) @@ -113,7 +113,7 @@ async function run() { console.log('news') const news = await api.getNews(children[0]) - +*/ /*console.log('news details') const newsItems = await Promise.all( news.map((newsItem) => @@ -127,9 +127,9 @@ async function run() { const menu = await api.getMenu(children[0]) console.log(menu)*/ - console.log('notifications') - const notifications = await api.getNotifications(children[0]) - console.log(notifications) + // console.log('notifications') + // const notifications = await api.getNotifications(children[0]) + // console.log(notifications) await api.logout() })