skolplattformen-backup/packages/app/components/login.component.js

237 lines
6.6 KiB
JavaScript
Raw Normal View History

import { useApi } from '@skolplattformen/api-hooks'
import {
Button,
ButtonGroup,
Card,
Input,
Modal,
Text,
} from '@ui-kitten/components'
import Personnummer from 'personnummer'
import React, { useEffect, useState } from 'react'
import {
Image,
Linking,
Platform,
StyleSheet,
TouchableWithoutFeedback,
View,
Dimensions,
} from 'react-native'
import { useAsyncStorage } from 'use-async-storage'
2021-02-20 08:38:08 +00:00
import { schema } from '../app.json'
import {
CloseOutlineIcon,
PersonIcon,
SecureIcon,
SelectIcon,
2021-02-20 08:38:08 +00:00
} from './icon.component'
import ActionSheet from 'rn-actionsheet-module'
2020-12-18 12:45:09 +00:00
const { width } = Dimensions.get('window')
2020-12-16 22:07:15 +00:00
export const Login = ({ navigation }) => {
const { api, isLoggedIn } = useApi()
const [visible, showModal] = useState(false)
const [error, setError] = useState(null)
const [cachedSsn, setCachedSsn] = useAsyncStorage('socialSecurityNumber', '')
const [socialSecurityNumber, setSocialSecurityNumber] = useState('')
const [valid, setValid] = useState(false)
const [loginMethodIndex, setLoginMethodIndex] = useState(0)
const [cachedLoginMethodIndex, setCachedLoginMethodIndex] = useAsyncStorage(
'loginMethodIndex',
'0'
)
const loginMethods = [
'Öppna BankID på denna enhet',
'Öppna BankID på annan enhet',
'Logga in som testanvändare',
]
const selectLoginMethod = () => {
const options = {
title: 'Välj inloggningsmetod',
optionsIOS: loginMethods,
optionsAndroid: loginMethods,
onCancelAndroidIndex: loginMethodIndex,
}
ActionSheet(options, (index) => setLoginMethodIndex(index))
}
useEffect(() => {
if (loginMethodIndex !== parseInt(cachedLoginMethodIndex, 10)) {
setCachedLoginMethodIndex(loginMethodIndex)
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [loginMethodIndex])
useEffect(() => {
if (loginMethodIndex !== parseInt(cachedLoginMethodIndex, 10)) {
setLoginMethodIndex(parseInt(cachedLoginMethodIndex, 10))
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [cachedLoginMethodIndex])
2020-12-18 12:45:09 +00:00
/* Initial load functions */
useEffect(() => {
2021-02-15 07:36:25 +00:00
setValid(Personnummer.valid(socialSecurityNumber))
}, [socialSecurityNumber])
useEffect(() => {
2021-02-15 07:36:25 +00:00
if (cachedSsn && socialSecurityNumber !== cachedSsn) {
setSocialSecurityNumber(cachedSsn)
}
// eslint-disable-next-line react-hooks/exhaustive-deps
2021-02-15 07:36:25 +00:00
}, [cachedSsn])
2020-12-16 22:07:15 +00:00
const loginHandler = async () => {
showModal(false)
navigateToChildren()
}
useEffect(() => {
api.on('login', loginHandler)
return () => api.off('login', loginHandler)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
2021-01-04 11:01:03 +00:00
/* Helpers */
2020-12-18 12:45:09 +00:00
const handleInput = (text) => {
setValid(Personnummer.valid(text))
setCachedSsn(text)
setSocialSecurityNumber(text)
2020-12-18 12:45:09 +00:00
}
const openBankId = (token) => {
2020-12-18 12:45:09 +00:00
try {
const redirect = loginMethodIndex === 0 ? encodeURIComponent(schema) : ''
const bankIdUrl =
Platform.OS === 'ios'
? `https://app.bankid.com/?autostarttoken=${token}&redirect=${redirect}`
: `bankid:///?autostarttoken=${token}&redirect=null`
Linking.openURL(bankIdUrl)
2020-12-27 09:37:21 +00:00
} catch (err) {
setError('Öppna BankID manuellt')
}
}
2020-12-21 15:42:41 +00:00
/* Navigation actions */
const navigateToChildren = () => {
navigation.navigate('Children')
}
const startLogin = async (text) => {
if (loginMethodIndex < 2) {
showModal(true)
const ssn = Personnummer.parse(text).format(true)
setCachedSsn(ssn)
setSocialSecurityNumber(ssn)
const status = await api.login(ssn)
if (status.token !== 'fake' && loginMethodIndex === 0) {
openBankId(status.token)
}
status.on('PENDING', () => console.log('BankID app not yet opened'))
status.on('USER_SIGN', () => console.log('BankID app is open'))
status.on(
'ERROR',
() =>
setError('Inloggningen misslyckades, försök igen!') &&
showModal(false)
)
status.on('OK', () => console.log('BankID ok'))
} else {
await api.login('201212121212')
2020-12-31 00:05:06 +00:00
}
2020-12-18 12:45:09 +00:00
}
const clearInput = (props) => (
<TouchableWithoutFeedback onPress={() => handleInput('')}>
2021-02-20 08:38:08 +00:00
<CloseOutlineIcon {...props} />
</TouchableWithoutFeedback>
)
2020-12-16 22:07:15 +00:00
return (
<>
<Image source={require('../assets/boys.png')} style={styles.image} />
<View style={styles.loginForm}>
{loginMethodIndex !== 2 && (
<Input
label="Personnummer"
autoFocus
value={socialSecurityNumber}
style={styles.pnrInput}
accessoryLeft={PersonIcon}
accessoryRight={clearInput}
keyboardType="numeric"
onSubmitEditing={(event) => startLogin(event.nativeEvent.text)}
caption={error?.message || ''}
onChangeText={(text) => handleInput(text)}
placeholder="Ditt personnr"
/>
)}
<ButtonGroup style={styles.loginButtonGroup}>
<Button
onPress={() => startLogin(socialSecurityNumber)}
style={styles.loginButton}
appearence="ghost"
disabled={loginMethodIndex !== 2 && !valid}
status="primary"
accessoryLeft={SecureIcon}
size="medium"
>
2021-03-25 11:31:38 +00:00
<Text adjustsFontSizeToFit style={styles.loginButtonText}>
{loginMethods[loginMethodIndex]}
</Text>
</Button>
<Button
onPress={selectLoginMethod}
style={styles.loginMethodButton}
appearence="ghost"
status="primary"
accessoryLeft={SelectIcon}
size="medium"
/>
</ButtonGroup>
</View>
<Modal
visible={visible}
style={styles.modal}
backdropStyle={styles.modalBackdrop}
onBackdropPress={() => showModal(false)}
>
<Card disabled>
<Text style={styles.bankIdLoading}>Väntar BankID...</Text>
<Button visible={!isLoggedIn} onPress={() => showModal(false)}>
Avbryt
</Button>
</Card>
</Modal>
</>
)
}
2020-12-18 12:45:09 +00:00
const styles = StyleSheet.create({
image: {
height: ((width * 0.9) / 4) * 3,
marginVertical: 16,
width: width * 0.9,
2020-12-18 12:45:09 +00:00
},
loginForm: {
justifyContent: 'flex-end',
alignItems: 'flex-start',
paddingHorizontal: 20,
},
pnrInput: { minHeight: 70 },
loginButtonGroup: {
minHeight: 45,
},
loginButton: { flex: 1 },
2021-03-25 11:31:38 +00:00
loginButtonText: { color: '#fff' },
loginMethodButton: { width: 45 },
modal: {
width: '80%',
},
modalBackdrop: {
backgroundColor: 'rgba(0, 0, 0, 0.5)',
},
bankIdLoading: { margin: 10 },
2020-12-27 09:37:21 +00:00
})