2021-02-15 12:33:47 +00:00
|
|
|
import { useApi } from '@skolplattformen/api-hooks'
|
2021-02-23 08:11:27 +00:00
|
|
|
import {
|
|
|
|
Button,
|
|
|
|
ButtonGroup,
|
|
|
|
Card,
|
|
|
|
Input,
|
|
|
|
Modal,
|
|
|
|
Text,
|
|
|
|
} from '@ui-kitten/components'
|
2021-02-15 12:33:47 +00:00
|
|
|
import Personnummer from 'personnummer'
|
2021-02-23 08:11:27 +00:00
|
|
|
import React, { useEffect, useState } from 'react'
|
2021-02-07 16:14:45 +00:00
|
|
|
import {
|
2021-02-15 12:33:47 +00:00
|
|
|
Image,
|
|
|
|
Linking,
|
2021-02-07 16:14:45 +00:00
|
|
|
Platform,
|
|
|
|
StyleSheet,
|
2021-02-10 17:33:52 +00:00
|
|
|
TouchableWithoutFeedback,
|
2021-02-07 16:14:45 +00:00
|
|
|
View,
|
2021-02-23 08:11:27 +00:00
|
|
|
Dimensions,
|
2021-02-07 16:14:45 +00:00
|
|
|
} from 'react-native'
|
2021-02-11 08:20:41 +00:00
|
|
|
import { useAsyncStorage } from 'use-async-storage'
|
2021-02-20 08:38:08 +00:00
|
|
|
import { schema } from '../app.json'
|
|
|
|
import {
|
|
|
|
CloseOutlineIcon,
|
|
|
|
PersonIcon,
|
|
|
|
SecureIcon,
|
2021-02-23 08:11:27 +00:00
|
|
|
SelectIcon,
|
2021-02-20 08:38:08 +00:00
|
|
|
} from './icon.component'
|
2021-02-23 08:11:27 +00:00
|
|
|
import ActionSheet from 'rn-actionsheet-module'
|
2020-12-18 12:45:09 +00:00
|
|
|
|
2021-02-23 08:11:27 +00:00
|
|
|
const { width } = Dimensions.get('window')
|
2020-12-16 22:07:15 +00:00
|
|
|
|
2021-02-11 08:20:41 +00:00
|
|
|
export const Login = ({ navigation }) => {
|
|
|
|
const { api, isLoggedIn } = useApi()
|
2021-02-23 08:11:27 +00:00
|
|
|
const [visible, showModal] = useState(false)
|
|
|
|
const [error, setError] = useState(null)
|
2021-02-15 06:20:41 +00:00
|
|
|
const [cachedSsn, setCachedSsn] = useAsyncStorage('socialSecurityNumber', '')
|
2021-02-23 08:11:27 +00:00
|
|
|
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)
|
|
|
|
}
|
2021-02-23 08:38:01 +00:00
|
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
2021-02-23 08:11:27 +00:00
|
|
|
}, [loginMethodIndex])
|
|
|
|
useEffect(() => {
|
|
|
|
if (loginMethodIndex !== parseInt(cachedLoginMethodIndex, 10)) {
|
|
|
|
setLoginMethodIndex(parseInt(cachedLoginMethodIndex, 10))
|
|
|
|
}
|
2021-02-23 08:38:01 +00:00
|
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
2021-02-23 08:11:27 +00:00
|
|
|
}, [cachedLoginMethodIndex])
|
2020-12-18 12:45:09 +00:00
|
|
|
|
2021-01-04 10:56:20 +00:00
|
|
|
/* Initial load functions */
|
2021-02-23 08:11:27 +00:00
|
|
|
useEffect(() => {
|
2021-02-15 07:36:25 +00:00
|
|
|
setValid(Personnummer.valid(socialSecurityNumber))
|
|
|
|
}, [socialSecurityNumber])
|
2021-02-23 08:11:27 +00:00
|
|
|
|
|
|
|
useEffect(() => {
|
2021-02-15 07:36:25 +00:00
|
|
|
if (cachedSsn && socialSecurityNumber !== cachedSsn) {
|
|
|
|
setSocialSecurityNumber(cachedSsn)
|
|
|
|
}
|
2021-02-21 15:43:24 +00:00
|
|
|
// 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
|
|
|
|
2021-01-15 09:17:58 +00:00
|
|
|
const loginHandler = async () => {
|
2021-01-04 10:56:20 +00:00
|
|
|
showModal(false)
|
|
|
|
navigateToChildren()
|
2021-01-15 09:17:58 +00:00
|
|
|
}
|
|
|
|
|
2021-02-23 08:11:27 +00:00
|
|
|
useEffect(() => {
|
2021-02-07 16:14:45 +00:00
|
|
|
api.on('login', loginHandler)
|
|
|
|
return () => api.off('login', loginHandler)
|
2021-02-23 08:38:01 +00:00
|
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
2021-01-15 09:17:58 +00:00
|
|
|
}, [])
|
2021-01-04 11:01:03 +00:00
|
|
|
|
2021-01-04 10:56:20 +00:00
|
|
|
/* Helpers */
|
2020-12-18 12:45:09 +00:00
|
|
|
const handleInput = (text) => {
|
2021-02-15 06:20:41 +00:00
|
|
|
setValid(Personnummer.valid(text))
|
|
|
|
setCachedSsn(text)
|
|
|
|
setSocialSecurityNumber(text)
|
2020-12-18 12:45:09 +00:00
|
|
|
}
|
|
|
|
|
2020-12-21 00:45:43 +00:00
|
|
|
const openBankId = (token) => {
|
2020-12-18 12:45:09 +00:00
|
|
|
try {
|
2021-02-23 08:11:27 +00:00
|
|
|
const redirect = loginMethodIndex === 0 ? encodeURIComponent(schema) : ''
|
2021-02-07 16:14:45 +00:00
|
|
|
const bankIdUrl =
|
|
|
|
Platform.OS === 'ios'
|
2021-03-03 19:46:21 +00:00
|
|
|
? `https://app.bankid.com/?autostarttoken=${token}&redirect=${redirect}`
|
|
|
|
: `bankid:///?autostarttoken=${token}&redirect=null`
|
2020-12-21 00:45:43 +00:00
|
|
|
Linking.openURL(bankIdUrl)
|
2020-12-27 09:37:21 +00:00
|
|
|
} catch (err) {
|
2020-12-21 00:45:43 +00:00
|
|
|
setError('Öppna BankID manuellt')
|
|
|
|
}
|
|
|
|
}
|
2020-12-21 15:42:41 +00:00
|
|
|
|
2021-01-04 10:56:20 +00:00
|
|
|
/* Navigation actions */
|
|
|
|
const navigateToChildren = () => {
|
|
|
|
navigation.navigate('Children')
|
|
|
|
}
|
|
|
|
|
2021-02-15 06:20:41 +00:00
|
|
|
const startLogin = async (text) => {
|
2021-02-23 08:11:27 +00:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2021-02-15 12:33:47 +00:00
|
|
|
const clearInput = (props) => (
|
|
|
|
<TouchableWithoutFeedback onPress={() => handleInput('')}>
|
2021-02-20 08:38:08 +00:00
|
|
|
<CloseOutlineIcon {...props} />
|
2021-02-15 12:33:47 +00:00
|
|
|
</TouchableWithoutFeedback>
|
|
|
|
)
|
2021-02-15 07:28:12 +00:00
|
|
|
|
2020-12-16 22:07:15 +00:00
|
|
|
return (
|
2021-02-23 08:11:27 +00:00
|
|
|
<>
|
|
|
|
<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>
|
2021-02-23 08:11:27 +00:00
|
|
|
</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 på BankID...</Text>
|
|
|
|
|
|
|
|
<Button visible={!isLoggedIn} onPress={() => showModal(false)}>
|
|
|
|
Avbryt
|
|
|
|
</Button>
|
|
|
|
</Card>
|
|
|
|
</Modal>
|
|
|
|
</>
|
2020-12-21 00:45:43 +00:00
|
|
|
)
|
|
|
|
}
|
2020-12-18 12:45:09 +00:00
|
|
|
|
|
|
|
const styles = StyleSheet.create({
|
2021-02-23 08:11:27 +00:00
|
|
|
image: {
|
|
|
|
height: ((width * 0.9) / 4) * 3,
|
|
|
|
marginVertical: 16,
|
|
|
|
width: width * 0.9,
|
2020-12-18 12:45:09 +00:00
|
|
|
},
|
2021-02-23 08:11:27 +00:00
|
|
|
loginForm: {
|
2021-02-21 15:43:24 +00:00
|
|
|
justifyContent: 'flex-end',
|
|
|
|
alignItems: 'flex-start',
|
|
|
|
paddingHorizontal: 20,
|
|
|
|
},
|
2021-02-23 08:11:27 +00:00
|
|
|
pnrInput: { minHeight: 70 },
|
|
|
|
loginButtonGroup: {
|
|
|
|
minHeight: 45,
|
2021-02-21 15:43:24 +00:00
|
|
|
},
|
2021-02-23 08:11:27 +00:00
|
|
|
loginButton: { flex: 1 },
|
2021-03-25 11:31:38 +00:00
|
|
|
loginButtonText: { color: '#fff' },
|
2021-02-23 08:11:27 +00:00
|
|
|
loginMethodButton: { width: 45 },
|
|
|
|
modal: {
|
|
|
|
width: '80%',
|
2021-02-21 15:43:24 +00:00
|
|
|
},
|
2021-02-23 08:11:27 +00:00
|
|
|
modalBackdrop: {
|
|
|
|
backgroundColor: 'rgba(0, 0, 0, 0.5)',
|
2021-02-21 15:43:24 +00:00
|
|
|
},
|
2021-02-23 08:11:27 +00:00
|
|
|
bankIdLoading: { margin: 10 },
|
2020-12-27 09:37:21 +00:00
|
|
|
})
|