feat: 🎸 Remove all obsolete login obstacles (#146)
This commit is contained in:
parent
7f93285554
commit
befb073a32
|
@ -49,7 +49,7 @@ async function run() {
|
|||
console.log('user')
|
||||
const user = await api.getUser()
|
||||
console.log(user)
|
||||
/*
|
||||
|
||||
console.log('children')
|
||||
const children = await api.getChildren()
|
||||
console.log(children)
|
||||
|
@ -115,7 +115,7 @@ async function Login(api) {
|
|||
console.log('Login with old cookie succeeded')
|
||||
} catch (error) {
|
||||
console.log('Could not login with old session cookie. Reverting to BankId')
|
||||
console.error(error)
|
||||
// console.error(error)
|
||||
}
|
||||
|
||||
if (useBankId) {
|
||||
|
|
137
lib/api.ts
137
lib/api.ts
|
@ -3,7 +3,6 @@ import { EventEmitter } from 'events'
|
|||
import { decode } from 'he'
|
||||
import * as html from 'node-html-parser'
|
||||
import { Language } from '@skolplattformen/curriculum/dist/translations'
|
||||
import * as base64 from 'base-64'
|
||||
import { URLSearchParams } from './URLSearchParams'
|
||||
import { checkStatus, LoginStatusChecker } from './loginStatus'
|
||||
import {
|
||||
|
@ -60,8 +59,6 @@ export class Api extends EventEmitter {
|
|||
|
||||
public isFake: boolean = false
|
||||
|
||||
public childControllerUrl?: string
|
||||
|
||||
private authorizedSystems: SSOSystems = {}
|
||||
|
||||
constructor(
|
||||
|
@ -136,7 +133,6 @@ export class Api extends EventEmitter {
|
|||
status.on('OK', async () => {
|
||||
await this.retrieveSessionCookie()
|
||||
await this.retrieveXsrfToken()
|
||||
// await this.retrieveApiKey()
|
||||
|
||||
this.isLoggedIn = true
|
||||
this.emit('login')
|
||||
|
@ -166,7 +162,6 @@ export class Api extends EventEmitter {
|
|||
}
|
||||
|
||||
await this.retrieveXsrfToken()
|
||||
await this.retrieveApiKey()
|
||||
|
||||
this.isLoggedIn = true
|
||||
this.emit('login')
|
||||
|
@ -187,110 +182,10 @@ export class Api extends EventEmitter {
|
|||
doc
|
||||
.querySelector('input[name="__RequestVerificationToken"]')
|
||||
?.getAttribute('value') || ''
|
||||
const scriptTags = doc.querySelectorAll('script')
|
||||
const childControllerScriptTag = scriptTags.find((elem) => {
|
||||
const srcAttr = elem.getAttribute('src')
|
||||
return srcAttr?.startsWith('/vardnadshavare/bundles/childcontroller')
|
||||
})
|
||||
this.childControllerUrl =
|
||||
routes.baseEtjanst + childControllerScriptTag?.getAttribute('src')
|
||||
|
||||
this.addHeader('x-xsrf-token', xsrfToken)
|
||||
}
|
||||
|
||||
private async retrieveApiKey(): Promise<void> {
|
||||
const url = routes.childcontrollerScript
|
||||
const session = this.getRequestInit()
|
||||
const response = await this.fetch('startBundle', url, session)
|
||||
const text = await response.text()
|
||||
|
||||
const apiKeyRegex = /"API-Key": "([\w\d]+)"/gm
|
||||
const apiKeyMatches = apiKeyRegex.exec(text)
|
||||
const apiKey =
|
||||
apiKeyMatches && apiKeyMatches.length > 1 ? apiKeyMatches[1] : ''
|
||||
|
||||
this.addHeader('API-Key', apiKey)
|
||||
}
|
||||
|
||||
private async retrieveCdnUrl(): Promise<string> {
|
||||
const url = routes.cdn
|
||||
const session = this.getRequestInit()
|
||||
const response = await this.fetch('cdn', url, session)
|
||||
const cdnUrl = await response.text()
|
||||
return cdnUrl
|
||||
}
|
||||
|
||||
private async retrieveAuthBody(): Promise<string> {
|
||||
const url = routes.auth
|
||||
const session = this.getRequestInit()
|
||||
const response = await this.fetch('auth', url, session)
|
||||
const authBody = await response.text()
|
||||
return authBody
|
||||
}
|
||||
|
||||
private async getTopologyConfig(): Promise<Record<string, any>> {
|
||||
|
||||
const response = await this.fetch('topologyConfigUrl', routes.topologyConfigUrl)
|
||||
|
||||
const json = await response.json()
|
||||
|
||||
return json
|
||||
}
|
||||
|
||||
private async retrieveCreateItemHeaders() {
|
||||
const response = await this.fetch(
|
||||
'createItemConfig',
|
||||
routes.createItemConfig
|
||||
)
|
||||
const json = await response.json()
|
||||
return json
|
||||
}
|
||||
|
||||
private async retrieveAuthToken(
|
||||
url: string,
|
||||
authBody: string
|
||||
): Promise<string> {
|
||||
const session = this.getRequestInit({
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Accept: 'text/plain',
|
||||
Origin: 'https://etjanst.stockholm.se',
|
||||
Referer: 'https://etjanst.stockholm.se/',
|
||||
Connection: 'keep-alive',
|
||||
},
|
||||
body: authBody,
|
||||
})
|
||||
delete session.headers['API-Key']
|
||||
|
||||
// Temporarily remove cookies
|
||||
const cookies = await this.cookieManager.getCookies(url)
|
||||
this.cookieManager.clearAll()
|
||||
|
||||
// Perform request
|
||||
let scriptUrl = this.childControllerUrl
|
||||
if (!scriptUrl) {
|
||||
scriptUrl = routes.childcontrollerScript
|
||||
}
|
||||
const createItemHeaders = await this.retrieveCreateItemHeaders()
|
||||
const response = await this.fetch('createItem', url, {
|
||||
method: 'POST',
|
||||
...createItemHeaders,
|
||||
body: authBody,
|
||||
})
|
||||
// Restore cookies
|
||||
cookies.forEach((cookie) => {
|
||||
this.cookieManager.setCookie(cookie, url)
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(
|
||||
`Server Error [${response.status}] [${response.statusText}] [${url}]`
|
||||
)
|
||||
}
|
||||
|
||||
const authData = await response.json()
|
||||
return authData.token
|
||||
}
|
||||
|
||||
private async fakeMode(): Promise<LoginStatusChecker> {
|
||||
this.isFake = true
|
||||
|
||||
|
@ -314,43 +209,13 @@ export class Api extends EventEmitter {
|
|||
return parse.user(data)
|
||||
}
|
||||
|
||||
private async getTopology (): Promise<string> {
|
||||
|
||||
const configTopology = await this.getTopologyConfig()
|
||||
|
||||
const currentTime = new Date().getTime() + 600000
|
||||
|
||||
let topo = `${configTopology.topologyLongKey}${currentTime}`
|
||||
|
||||
const secretNumberString = configTopology.topologyShortKey
|
||||
const numberOfBase64Iterations = configTopology.topologyBase64Iterations
|
||||
|
||||
for (let i = 0; i < numberOfBase64Iterations; i += 1) {
|
||||
topo = base64.encode(topo)
|
||||
};
|
||||
|
||||
const part1 = topo.substring(0, 1)
|
||||
const part2 = secretNumberString.charAt(numberOfBase64Iterations)
|
||||
const part3 = topo.substring(1, topo.length)
|
||||
|
||||
const finalTopology = part1 + part2 + part3
|
||||
|
||||
return finalTopology
|
||||
}
|
||||
|
||||
public async getChildren(): Promise<EtjanstChild[]> {
|
||||
if (this.isFake) return fakeResponse(fake.children())
|
||||
|
||||
// const cdnUrl = await this.retrieveCdnUrl()
|
||||
// const authBody = await this.retrieveAuthBody()
|
||||
// const token = await this.retrieveAuthToken(cdnUrl, authBody)
|
||||
|
||||
const url = routes.children
|
||||
const session = this.getRequestInit({
|
||||
headers: {
|
||||
Accept: 'application/json;odata=verbose',
|
||||
// Auth: token,
|
||||
topology: await this.getTopology(),
|
||||
Host: 'etjanst.stockholm.se',
|
||||
Referer: 'https://etjanst.stockholm.se/vardnadshavare/inloggad2/hem',
|
||||
},
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@react-native-cookies/cookies": "^6.0.7",
|
||||
"@skolplattformen/curriculum": "^1.3.0",
|
||||
"@skolplattformen/curriculum": "^1.4.1",
|
||||
"@types/base-64": "^1.0.0",
|
||||
"@types/he": "^1.1.1",
|
||||
"@types/jest": "^26.0.22",
|
||||
|
@ -49,7 +49,6 @@
|
|||
"typescript": "^4.2.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"base-64": "^1.0.0",
|
||||
"camelcase-keys": "^6.2.2",
|
||||
"change-case": "^4.1.2",
|
||||
"events": "^3.3.0",
|
||||
|
|
13
yarn.lock
13
yarn.lock
|
@ -522,10 +522,10 @@
|
|||
dependencies:
|
||||
"@sinonjs/commons" "^1.7.0"
|
||||
|
||||
"@skolplattformen/curriculum@^1.3.0":
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@skolplattformen/curriculum/-/curriculum-1.3.0.tgz#841e2ff0095e39e174cffdd0b8a81a17956de7ed"
|
||||
integrity sha512-nuwZX45gHe5JaiYfygDP1HmbhAJOEXuuWwR04tNAnl/PaDGqJscfzKt8YD2SL+MHqi3LARjSKLa4ms4SxVQFyw==
|
||||
"@skolplattformen/curriculum@^1.4.1":
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/@skolplattformen/curriculum/-/curriculum-1.4.1.tgz#f60b82276d61f731bf6c169826a4fb2a82e0a574"
|
||||
integrity sha512-tKJjB2KsOXhNGvtBTp3DsTVchdQbSU08AwAfK1KbmIGFUQLAz8Su3T6RqYsxXEpCcFKRV6poscBnUZrdgZQy3w==
|
||||
|
||||
"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.7":
|
||||
version "7.1.12"
|
||||
|
@ -991,11 +991,6 @@ balanced-match@^1.0.0:
|
|||
resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz"
|
||||
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
|
||||
|
||||
base-64@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/base-64/-/base-64-1.0.0.tgz#09d0f2084e32a3fd08c2475b973788eee6ae8f4a"
|
||||
integrity sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==
|
||||
|
||||
base@^0.11.1:
|
||||
version "0.11.2"
|
||||
resolved "https://registry.npmjs.org/base/-/base-0.11.2.tgz"
|
||||
|
|
Loading…
Reference in New Issue