feat: 🎸 Logga in med Freja eID+
This commit is contained in:
parent
948568dd7c
commit
d9c62a6d91
|
@ -54,6 +54,7 @@ const LoginMethods: Logins = {
|
|||
BANKID_SAME_DEVICE: 0,
|
||||
BANKID_ANOTHER_DEVICE: 2,
|
||||
TEST_USER: 3,
|
||||
|
||||
}
|
||||
|
||||
export const Login = () => {
|
||||
|
@ -86,6 +87,7 @@ export const Login = () => {
|
|||
{ id: 'thisdevice', title: t('auth.bankid.OpenOnThisDevice') },
|
||||
{ id: 'otherdevice', title: t('auth.bankid.OpenOnAnotherDevice') },
|
||||
{ id: 'testuser', title: t('auth.loginAsTestUser') },
|
||||
{ id: 'freja', title: t('auth.freja.OpenOnThisDevice') },
|
||||
] as const
|
||||
|
||||
const loginHandler = async () => {
|
||||
|
@ -120,12 +122,40 @@ export const Login = () => {
|
|||
}
|
||||
}
|
||||
|
||||
const openFreja = (token:string) => {
|
||||
try {
|
||||
const originAppScheme = encodeURIComponent(schema);
|
||||
const frejaUrl =
|
||||
Platform.OS === 'ios'
|
||||
? `${token}&originAppScheme=${originAppScheme}`
|
||||
: `${token}&originAppScheme=${originAppScheme}`
|
||||
Linking.openURL(frejaUrl)
|
||||
} catch (err) {
|
||||
setError(t('auth.freja.OpenManually'))
|
||||
}
|
||||
}
|
||||
|
||||
const isUsingPersonalIdNumber =
|
||||
loginMethodId === 'otherdevice' ||
|
||||
(loginMethodId === 'thisdevice' && !loginBankIdSameDeviceWithoutId)
|
||||
|
||||
const startLogin = async (text: string) => {
|
||||
if (loginMethodId === 'thisdevice' || loginMethodId === 'otherdevice') {
|
||||
|
||||
if(loginMethodId === 'freja'){
|
||||
showModal(true)
|
||||
const status = await api.loginFreja();
|
||||
setCancelLoginRequest(() => () => status.cancel())
|
||||
openFreja(status.token)
|
||||
status.on('STARTED', () => console.log('Freja eID app not yet opened'))
|
||||
status.on('DELIVERED_TO_MOBILE', () => console.log('Freja eID app is open'))
|
||||
status.on('CANCELLED', () => {
|
||||
console.log('User pressed cancel in Freja eID')
|
||||
showModal(false)
|
||||
})
|
||||
status.on('APPROVED', () => console.log('Freja eID ok'))
|
||||
}
|
||||
|
||||
else if (loginMethodId === 'thisdevice' || loginMethodId === 'otherdevice') {
|
||||
showModal(true)
|
||||
|
||||
let ssn
|
||||
|
|
|
@ -7,7 +7,7 @@ export type ChildPersonalNumbers = Record<string, string>
|
|||
export const settingsState = proxy({
|
||||
hydrated: false,
|
||||
settings: {
|
||||
loginMethodId: 'thisdevice' as 'thisdevice' | 'otherdevice' | 'testuser',
|
||||
loginMethodId: 'thisdevice' as 'thisdevice' | 'otherdevice' | 'testuser' | 'freja',
|
||||
usingSystemTheme: true,
|
||||
theme: 'light',
|
||||
cachedPersonalIdentityNumber: '',
|
||||
|
|
|
@ -23,6 +23,11 @@
|
|||
"OpenOnThisDevice": "Open BankID on this device",
|
||||
"Waiting": "Waiting for BankID…"
|
||||
},
|
||||
"freja": {
|
||||
"OpenManually": "Open Freja eID manually",
|
||||
"OpenOnThisDevice": "Freja eID",
|
||||
"Waiting": "Waiting for Freja eID…"
|
||||
},
|
||||
"chooseLoginMethod": "Choose login method",
|
||||
"chooseSchoolPlatform": "Choose platform",
|
||||
"loginAsTestUser": "Log in as a test user",
|
||||
|
|
|
@ -23,6 +23,11 @@
|
|||
"OpenOnThisDevice": "Logga in med BankID",
|
||||
"Waiting": "Väntar på BankID…"
|
||||
},
|
||||
"freja": {
|
||||
"OpenManually": "Öppna BankID manuellt",
|
||||
"OpenOnThisDevice": "Logga in med Freja eID",
|
||||
"Waiting": "Väntar på Freja eID…"
|
||||
},
|
||||
"chooseLoginMethod": "Välj inloggningsmetod",
|
||||
"chooseSchoolPlatform": "Välj plattform",
|
||||
"loginAsTestUser": "Logga in som testanvändare",
|
||||
|
|
|
@ -8,6 +8,7 @@ import {
|
|||
Fetch,
|
||||
Fetcher,
|
||||
FetcherOptions,
|
||||
FrejaLoginStatusChecker,
|
||||
LoginStatusChecker,
|
||||
MenuItem,
|
||||
NewsItem,
|
||||
|
@ -31,6 +32,7 @@ import { DateTime } from 'luxon'
|
|||
import * as html from 'node-html-parser'
|
||||
import * as fake from './fakeData'
|
||||
import { checkStatus, DummyStatusChecker } from './loginStatusChecker'
|
||||
import { checkStatus as checkFrejaStatus } from './frejaLoginStatusChecker'
|
||||
import * as parse from './parse/index'
|
||||
import queueFetcherWrapper from './queueFetcherWrapper'
|
||||
import * as routes from './routes'
|
||||
|
@ -166,6 +168,45 @@ export class ApiSkolplattformen extends EventEmitter implements Api {
|
|||
return status
|
||||
}
|
||||
|
||||
public async loginFreja(): Promise<FrejaLoginStatusChecker> {
|
||||
|
||||
const loginUrl = routes.frejaLogin
|
||||
const loginResponse = await this.fetch('auth-ticket', loginUrl)
|
||||
|
||||
|
||||
|
||||
// if (!ticketResponse.ok) {
|
||||
// throw new Error(
|
||||
// `Server Error [${ticketResponse.status}] [${ticketResponse.statusText}] [${ticketUrl}]`
|
||||
// )
|
||||
// }
|
||||
|
||||
const appSwitchUrl: string = await loginResponse.text()
|
||||
const cleanAppSwitchUrl = this.cleanFrejaAppSwitchUrl(appSwitchUrl)
|
||||
|
||||
console.log('getting freja login url: ' + cleanAppSwitchUrl)
|
||||
|
||||
const status = checkFrejaStatus(this.fetch, cleanAppSwitchUrl)
|
||||
status.on('APPROVED', async () => {
|
||||
//await this.retrieveFrejaSessionCookie()
|
||||
await this.retrieveXsrfToken()
|
||||
|
||||
this.isLoggedIn = true
|
||||
this.emit('login')
|
||||
})
|
||||
// status.on('ERROR', () => {
|
||||
// this.personalNumber = undefined
|
||||
// })
|
||||
|
||||
return status
|
||||
}
|
||||
|
||||
private cleanFrejaAppSwitchUrl(url: string): string {
|
||||
const parts = url.split('&')
|
||||
return parts[0]
|
||||
}
|
||||
|
||||
|
||||
public async setSessionCookie(sessionCookie: string): Promise<void> {
|
||||
// Manually set cookie in this call and let the cookieManager
|
||||
// handle it from here
|
||||
|
@ -190,10 +231,33 @@ export class ApiSkolplattformen extends EventEmitter implements Api {
|
|||
}
|
||||
|
||||
private async retrieveSessionCookie(): Promise<void> {
|
||||
|
||||
const url = routes.loginCookie
|
||||
await this.fetch('login-cookie', url)
|
||||
}
|
||||
|
||||
private async retrieveFrejaSessionCookie(): Promise<void> {
|
||||
const url = routes.frejaLoginCookie
|
||||
const session = await this.getSession(url, {
|
||||
redirect: 'manual',
|
||||
})
|
||||
//const session = this.getRequestInit()
|
||||
|
||||
|
||||
console.log(JSON.stringify(session))
|
||||
|
||||
const response = await this.fetch('freja-login-return-url', url, session)
|
||||
console.log(response.status)
|
||||
console.log(response.text())
|
||||
|
||||
console.log(JSON.stringify(response))
|
||||
|
||||
const response2 = await this.fetch('freja-login-cookie', url, session)
|
||||
console.log(response2.status)
|
||||
console.log(response2.text())
|
||||
}
|
||||
|
||||
|
||||
private async retrieveXsrfToken(): Promise<void> {
|
||||
const url = routes.hemPage
|
||||
const session = this.getRequestInit()
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
import { EventEmitter } from 'events';
|
||||
import { frejaLoginStatus } from './routes';
|
||||
import { Fetcher, FrejaLoginStatusChecker } from '@skolplattformen/api';
|
||||
export class FrejaChecker extends EventEmitter implements FrejaLoginStatusChecker {
|
||||
public token: string;
|
||||
|
||||
private fetcher: Fetcher;
|
||||
private url: string;
|
||||
|
||||
private cancelled = false;
|
||||
|
||||
constructor(fetcher: Fetcher, token: string) {
|
||||
super();
|
||||
this.fetcher = fetcher
|
||||
|
||||
this.token = token
|
||||
this.url = frejaLoginStatus;
|
||||
this.check();
|
||||
}
|
||||
|
||||
async check(): Promise<void> {
|
||||
const response = await this.fetcher('freja-login-status', this.url);
|
||||
const status = await response.text();
|
||||
this.emit(status);
|
||||
if (!this.cancelled &&
|
||||
status !== 'APPROVED' &&
|
||||
// status !== 'ERROR!' &&
|
||||
status !== 'CANCELLED'
|
||||
){
|
||||
setTimeout(() => this.check(), 1000);
|
||||
}
|
||||
else console.log('APPROVED');
|
||||
}
|
||||
|
||||
async cancel(): Promise<void> {
|
||||
this.cancelled = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export const checkStatus = (
|
||||
fetch: Fetcher,
|
||||
token: string,
|
||||
): FrejaLoginStatusChecker => new FrejaChecker(fetch, token)
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
// BankId
|
||||
export const login = (personalNumber?: string) => {
|
||||
const baseUrl = 'https://login003.stockholm.se/NECSadcmbid/authenticate/NECSadcmbid?TARGET=-SM-HTTPS%3a%2f%2flogin001%2estockholm%2ese%2fNECSadc%2fmbid%2fb64startpage%2ejsp%3fstartpage%3daHR0cHM6Ly9ldGphbnN0LnN0b2NraG9sbS5zZS92YXJkbmFkc2hhdmFyZS9pbmxvZ2dhZDIvaGVt'
|
||||
const optionalPersonalNumber = personalNumber === undefined ? '' : `&personalNumber=${personalNumber}`
|
||||
|
@ -7,9 +8,17 @@ export const login = (personalNumber?: string) => {
|
|||
export const loginStatus = (order: string) =>
|
||||
`https://login003.stockholm.se/NECSadcmbid/authenticate/NECSadcmbid?TARGET=-SM-HTTPS%3a%2f%2flogin001%2estockholm%2ese%2fNECSadc%2fmbid%2fb64startpage%2ejsp%3fstartpage%3daHR0cHM6Ly9ldGphbnN0LnN0b2NraG9sbS5zZS92YXJkbmFkc2hhdmFyZS9pbmxvZ2dhZDIvaGVt&verifyorder=${order}&_=${Date.now()}`
|
||||
|
||||
export const loginCookie =
|
||||
export const loginCookie =
|
||||
'https://login003.stockholm.se/NECSadcmbid/authenticate/SiteMinderAuthADC?TYPE=33554433&REALMOID=06-42f40edd-0c5b-4dbc-b714-1be1e907f2de&GUID=&SMAUTHREASON=0&METHOD=GET&SMAGENTNAME=IfNE0iMOtzq2TcxFADHylR6rkmFtwzoxRKh5nRMO9NBqIxHrc38jFyt56FASdxk1&TARGET=-SM-HTTPS%3a%2f%2flogin001%2estockholm%2ese%2fNECSadc%2fmbid%2fb64startpage%2ejsp%3fstartpage%3daHR0cHM6Ly9ldGphbnN0LnN0b2NraG9sbS5zZS92YXJkbmFkc2hhdmFyZS9pbmxvZ2dhZDIvR2V0Q2hpbGRyZW4%3d'
|
||||
|
||||
|
||||
// Freja
|
||||
export const frejaLogin = 'https://login003.stockholm.se/NECSadcfreja/authenticate/NECSadcfreja?action=init&return_url=https%3A%2F%2Flogin003.stockholm.se%2FNECSadcfreja%2Fauthenticate%2FNECSadcfreja'
|
||||
export const frejaLoginStatus = 'https://login003.stockholm.se/NECSadcfreja/authenticate/NECSadcfreja?TYPE=33554433&REALMOID=06-89cf916c-9764-45fa-8690-eaf3fe9282bc&GUID=1&SMAUTHREASON=0&METHOD=GET&SMAGENTNAME=IfNE0iMOtzq2TcxFADHylR6rkmFtwzoxRKh5nRMO9NBqIxHrc38jFyt56FASdxk1&TARGET=-SM-HTTPS%3a%2f%2flogin001%2estockholm%2ese%2fNECSadc%2ffreja%2fb64startpage%2ejsp%3fstartpage%3daHR0cHM6Ly9ldGphbnN0LnN0b2NraG9sbS5zZS92YXJkbmFkc2hhdmFyZS9pbmxvZ2dhZDIvaGVt&action=checkstatus'
|
||||
export const frejaReturnUrl = 'https://login003.stockholm.se/NECSadcfreja/authenticate/NECSadcfreja?TYPE=33554433&REALMOID=06-89cf916c-9764-45fa-8690-eaf3fe9282bc&GUID=&SMAUTHREASON=0&METHOD=GET&SMAGENTNAME=IfNE0iMOtzq2TcxFADHylR6rkmFtwzoxRKh5nRMO9NBqIxHrc38jFyt56FASdxk1&TARGET=-SM-HTTPS%3a%2f%2flogin001%2estockholm%2ese%2fNECSadc%2ffreja%2fb64startpage%2ejsp%3fstartpage%3daHR0cHM6Ly9ldGphbnN0LnN0b2NraG9sbS5zZS92YXJkbmFkc2hhdmFyZS9pbmxvZ2dhZDIvT3ZlcnNpa3Q%3d'
|
||||
export const frejaLoginCookie = 'https://login003.stockholm.se/NECSadcfreja/authenticate/SiteMinderAuthADCFREJA?TYPE=33554433&REALMOID=06-89cf916c-9764-45fa-8690-eaf3fe9282bc&GUID=&SMAUTHREASON=0&METHOD=GET&SMAGENTNAME=IfNE0iMOtzq2TcxFADHylR6rkmFtwzoxRKh5nRMO9NBqIxHrc38jFyt56FASdxk1&TARGET=-SM-HTTPS%3a%2f%2flogin001%2estockholm%2ese%2fNECSadc%2ffreja%2fb64startpage%2ejsp%3fstartpage%3daHR0cHM6Ly9ldGphbnN0LnN0b2NraG9sbS5zZS92YXJkbmFkc2hhdmFyZS9pbmxvZ2dhZDIvT3ZlcnNpa3Q%3d'
|
||||
|
||||
|
||||
const urlLoggedIn = `https://etjanst.stockholm.se/vardnadshavare/inloggad2`
|
||||
|
||||
export const children = `${urlLoggedIn}/GetChildren`
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Language } from '@skolplattformen/curriculum'
|
||||
import { EventEmitter } from 'events'
|
||||
import { DateTime } from 'luxon'
|
||||
import { LoginStatusChecker } from './loginStatus'
|
||||
import { LoginStatusChecker, FrejaLoginStatusChecker } from './loginStatus'
|
||||
import {
|
||||
CalendarItem,
|
||||
Classmate,
|
||||
|
@ -22,6 +22,7 @@ export interface Api extends EventEmitter {
|
|||
isLoggedIn: boolean
|
||||
getPersonalNumber(): string | undefined
|
||||
login(personalNumber?: string): Promise<LoginStatusChecker>
|
||||
loginFreja(): Promise<FrejaLoginStatusChecker>
|
||||
setSessionCookie(sessionCookie: string): Promise<void>
|
||||
getSessionHeaders(url: string): Promise<{ [index: string]: string }>
|
||||
getUser(): Promise<User>
|
||||
|
|
|
@ -2,7 +2,7 @@ import wrap from './fetcher'
|
|||
|
||||
export { toMarkdown } from './parseHtml'
|
||||
export * from './types'
|
||||
export { LoginStatusChecker } from './loginStatus'
|
||||
export { LoginStatusChecker, FrejaLoginStatusChecker } from './loginStatus'
|
||||
export { Api } from './api'
|
||||
export { FetcherOptions, Fetcher } from './fetcher'
|
||||
export {
|
||||
|
|
|
@ -15,3 +15,12 @@ export interface LoginStatusChecker {
|
|||
) => LoginStatusChecker
|
||||
cancel: () => Promise<void>
|
||||
}
|
||||
|
||||
export interface FrejaLoginStatusChecker {
|
||||
token: string
|
||||
on: (
|
||||
event: 'APPROVED' | 'STARTED' | 'DELIVERED_TO_MOBILE' | 'CANCELLED',
|
||||
listener: (...args: any[]) => void
|
||||
) => FrejaLoginStatusChecker
|
||||
cancel: () => Promise<void>
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue