diff --git a/app/mobile/src/access/create/Create.jsx b/app/mobile/src/access/create/Create.jsx index 1b9de62e..92efebcf 100644 --- a/app/mobile/src/access/create/Create.jsx +++ b/app/mobile/src/access/create/Create.jsx @@ -19,6 +19,10 @@ export function Create() { } } + const validServer = (state.server && state.serverChecked && state.serverValid); + const validToken = (!state.tokenRequired || (state.token && state.tokenChecked && state.tokenValid)); + const validUsername = (state.username && state.usernameChecked && state.usernameValid); + return ( @@ -37,23 +41,51 @@ export function Create() { - + { (!state.server || !state.serverChecked) && ( + + )} + { state.server && state.serverChecked && !state.serverValid && ( + + )} + { state.server && state.serverChecked && state.serverValid && ( + + )} - { state.tokenRequired && ( - - - - - - )} - + + { state.tokenRequired && ( + + + + + { (!validServer || !state.token || !state.tokenChecked) && ( + + )} + { validServer && state.token && state.tokenChecked && !state.tokenValid && ( + + )} + { validServer && state.token && state.tokenChecked && state.tokenValid && ( + + )} + + + )} + + - + { (!validServer || !validToken || !state.username || !state.usernameChecked) && ( + + )} + { validServer && validToken && state.username && state.usernameChecked && !state.usernameValid && ( + + )} + { validServer && validToken && state.username && state.usernameChecked && state.usernameValid && ( + + )} { state.showPassword && ( diff --git a/app/mobile/src/access/create/Create.styled.js b/app/mobile/src/access/create/Create.styled.js index 62489f09..7460b990 100644 --- a/app/mobile/src/access/create/Create.styled.js +++ b/app/mobile/src/access/create/Create.styled.js @@ -20,7 +20,7 @@ export const styles = StyleSheet.create({ }, required: { fontSize: 12, - color: Colors.alert, + color: Colors.grey, textAlignVertical: 'center', }, container: { @@ -31,6 +31,9 @@ export const styles = StyleSheet.create({ height: '100%', display: 'flex', }, + token: { + height: 52, + }, control: { display: 'flex', flexDirection: 'row', @@ -103,6 +106,7 @@ export const styles = StyleSheet.create({ height: 28, backgroundColor: Colors.primary, borderRadius: 4, + marginBottom: 16, }, createtext: { color: Colors.formFocus, @@ -122,14 +126,14 @@ export const styles = StyleSheet.create({ nocreatetext: { color: Colors.disabled, }, - create: { + login: { marginTop: 16, marginBottom: 16, }, - createtext: { + logintext: { fontColor: 'yellow', }, - nocreatetext: { + nologintext: { color: Colors.disabled, }, diff --git a/app/mobile/src/access/create/useCreate.hook.js b/app/mobile/src/access/create/useCreate.hook.js index 4a0f85f5..3d7643b4 100644 --- a/app/mobile/src/access/create/useCreate.hook.js +++ b/app/mobile/src/access/create/useCreate.hook.js @@ -2,6 +2,8 @@ import { useState, useEffect, useContext, useRef } from 'react'; import { useWindowDimensions } from 'react-native'; import { useNavigate } from 'react-router-dom'; import { AppContext } from 'context/AppContext'; +import { getAvailable } from 'api/getAvailable'; +import { getUsername } from 'api/getUsername'; export function useCreate() { @@ -18,23 +20,26 @@ export function useCreate() { confirm: null, showPassword: false, showConfirm: false, - serverCheck: true, + serverChecked: true, serverValid: false, tokenRequired: false, - usernameCheck: true, + tokenChecked: true, + tokenValid: false, + usernameChecked: true, usernameValid: false, - }); - const debounceUsername = useRef(null); - const debounceServer = useRef(null); + const debounce = useRef(null); const updateState = (value) => { setState((s) => ({ ...s, ...value })); } useEffect(() => { - if (state.password && state.username && state.server && state.confirm && state.password === state.confirm) { + if (state.usernameChecked && state.serverChecked && state.tokenChecked && + state.password && state.username && state.server && state.confirm && + (!state.tokenRequired || state.tokenValid) && + state.serverValid && state.usernameValid && state.password === state.confirm) { if (!state.enabled) { updateState({ enabled: true }); } @@ -44,20 +49,93 @@ export function useCreate() { updateState({ enabled: false }); } } - }, [state.login, state.password]); + }, [state]); + + const check = (server, token, username) => { + if (debounce.current) { + clearTimeout(debounce.current); + } + debounce.current = setTimeout(async () => { + debounce.current = null; + if (server) { + try { + const available = await getAvailable(server); + if (available) { + if (username) { + try { + const claimable = await getUsername(username, server, null); + updateState({ usernameChecked: true, tokenChecked: true, serverChecked: true, tokenRequired: false, + usernameValid: claimable, serverValid: true }); + } + catch (err) { + updateState({ usernameChecked: true, tokenChecked: true, serverChecked: true, tokenRequired: false, + usernameValid: false, serverValid: true }); + } + } + else { + updateState({ usernameChecked: true, tokenChecked: true, serverChecked: true, tokenRequired: false, + serverValid: true }); + } + } + else { + if (token) { + try { + const accessible = await getUsername(null, server, token); + if (accessible) { + if (username) { + try { + const claimable = await getUsername(username, server, token); + updateState({ usernameChecked: true, tokenChecked: true, serverChecked: true, tokenRequired: true, + usernameValid: claimable, tokenValid: true, serverValid: true }); + } + catch (err) { + updateState({ usernameChecked: true, tokenChecked: true, serverChecked: true, tokenRequired: true, + usernameValid: false, tokenValid: true, serverValid: true }); + } + } + else { + updateState({ usernameChecked: true, tokenChecked: true, serverChecked: true, tokenRequired: true, + tokenValid: true, serverValid: true }); + } + } + else { + updateState({ usernameChecked: true, tokenChecked: true, serverChecked: true, tokenRequired: true, + tokenValid: false, serverValid: true }); + } + } + catch (err) { + updateState({ usernameChecked: true, tokenChecked: true, serverChecked: true, tokenRequired: true, + tokenValid: false, serverValid: true }); + } + } + else { + updateState({ usernameChecked: true, tokenChecked: true, serverChecked: true, tokenRequired: true, + serverValid: true }); + } + } + } + catch (err) { + updateState({ usernameChecked: true, tokenChecked: true, serverChecked: true, serverValid: false }); + } + } + }, 1000); + } const actions = { config: () => { navigate('/admin'); }, setServer: (server) => { - updateState({ server }); + updateState({ server, serverChecked: false }); + check(server, state.token, state.username); }, setToken: (token) => { - updateState({ token }); + updateState({ token, tokenChecked: false }); + check(state.server, token, state.username); }, setUsername: (username) => { - updateState({ username }); + updateState({ username, usernameChecked: false }); + check(state.server, state.token, username); }, setPassword: (password) => { updateState({ password }); diff --git a/app/mobile/src/api/getAvailable.js b/app/mobile/src/api/getAvailable.js index f16bd1a6..1fd16519 100644 --- a/app/mobile/src/api/getAvailable.js +++ b/app/mobile/src/api/getAvailable.js @@ -1,7 +1,7 @@ import { checkResponse, fetchWithTimeout } from './fetchUtil'; -export async function getAvailable() { - let available = await fetchWithTimeout("/account/available", { method: 'GET' }) +export async function getAvailable(server) { + let available = await fetchWithTimeout(`https://${server}/account/available`, { method: 'GET' }) checkResponse(available) return await available.json() } diff --git a/app/mobile/src/api/getUsername.js b/app/mobile/src/api/getUsername.js index 65854f7c..5fb322dd 100644 --- a/app/mobile/src/api/getUsername.js +++ b/app/mobile/src/api/getUsername.js @@ -1,11 +1,18 @@ import { checkResponse, fetchWithTimeout } from './fetchUtil'; -export async function getUsername(name, token) { - let access = ""; - if (token) { - access = `&token=${token}` +export async function getUsername(name, server, token) { + let query = ""; + if (token && name) { + query = `?name=${encodeURIComponent(name)}&token=${token}`; } - let available = await fetchWithTimeout('/account/username?name=' + encodeURIComponent(name) + access, { method: 'GET' }) + else if (!token && name) { + query = `?name=${encodeURIComponent(name)}` + } + else if (token && !name) { + query = `?token=${token}`; + } + + let available = await fetchWithTimeout(`https://${server}/account/username${query}`, { method: 'GET' }) checkResponse(available) return await available.json() }