adding access token options

This commit is contained in:
balzack 2024-08-11 01:50:23 +02:00
parent 1861f1acb2
commit 961216ac29
8 changed files with 228 additions and 22 deletions

View File

@ -51,11 +51,40 @@ const theme = createTheme({
'#777777',
'#666666',
],
'dark-text': [
'#ffffff',
'#eeeeee',
'#dddddd',
'#cccccc',
'#bbbbbb',
'#aaaaaa',
'#999999',
'#888888',
'#777777',
'#666666',
],
'light-text': [
'#000000',
'#111111',
'#222222',
'#333333',
'#444444',
'#555555',
'#666666',
'#777777',
'#888888',
'#999999',
],
surface: virtualColor({
name: 'surface',
dark: 'dark-surface',
light: 'light-surface',
}),
text: virtualColor({
name: 'text',
dark: 'dark-text',
light: 'light-text',
}),
},
})

View File

@ -10,10 +10,11 @@
justify-content: center;
align-items: center;
padding: 16px;
gap: 16px;
gap: 8px;
.input {
width: 50%;
margin: 4px;
}
.title {

View File

@ -7,14 +7,19 @@ import {
Title,
Image,
Button,
Modal,
PasswordInput,
TextInput,
} from '@mantine/core'
import { useDisclosure } from '@mantine/hooks';
import login from '../images/login.png'
import { IconLock, IconUser, IconSettings } from '@tabler/icons-react'
import { IconLock, IconUser, IconSettings, IconServer, IconKey } from '@tabler/icons-react'
export function Access() {
const { state, actions } = useAccess()
const [opened, { open, close }] = useDisclosure(false);
console.log("AVAILABLE: ", state.availableSet);
return (
<div className={classes.split}>
@ -48,6 +53,11 @@ export function Access() {
<>
<Title order={3}>{state.strings.login}</Title>
<Space h="md" />
<Button
size="compact-sm"
variant="transparent"
onClick={open}
>{ state.hostname }</Button>
<TextInput
className={classes.input}
size="md"
@ -72,17 +82,77 @@ export function Access() {
{state.strings.login}
</Button>
<Button
size="compact-sm"
variant="subtle"
onClick={() => actions.setMode('create')}
>
{state.strings.createAccount}
</Button>
<Button
size="compact-sm"
variant="subtle"
onClick={() => actions.setMode('access')}
>
{state.strings.forgotPassword}
</Button>
</>
)}
{state.mode === 'access' && (
<>
<Title order={3}>{state.strings.accessAccount}</Title>
<Space h="md" />
<Button
size="compact-sm"
variant="transparent"
onClick={open}
>{ state.hostname }</Button>
<TextInput
className={classes.input}
size="md"
leftSectionPointerEvents="none"
leftSection={<IconKey />}
placeholder={state.strings.accessCode}
onChange={(event) =>
actions.setToken(event.currentTarget.value)
}
/>
<Space h="md" />
<Button variant="filled" className={classes.submit}>
{state.strings.login}
</Button>
<Button
size="compact-sm"
variant="subtle"
onClick={() => actions.setMode('login')}
>
{state.strings.accountLogin}
</Button>
</>
)}
{state.mode === 'create' && (
<>
<Title order={3}>{state.strings.createAccount}</Title>
<Space h="md" />
<Button
size="compact-sm"
variant="transparent"
onClick={open}
>{ state.hostname }</Button>
{ (state.available === 0 || !state.availableSet) && (
<TextInput
className={classes.input}
size="md"
disabled={!state.availableSet}
leftSectionPointerEvents="none"
leftSection={<IconKey />}
placeholder={state.strings.accessCode}
onChange={(event) =>
actions.setToken(event.currentTarget.value)
}
/>
)}
<TextInput
className={classes.input}
size="md"
@ -115,7 +185,7 @@ export function Access() {
<Button variant="filled" className={classes.submit}>
{state.strings.create}
</Button>
<Button variant="subtle" onClick={() => actions.setMode('login')}>
<Button variant="subtle" onClick={() => actions.setMode('login')} size="compact-sm">
{state.strings.accountLogin}
</Button>
</>
@ -124,6 +194,11 @@ export function Access() {
<>
<Title order={3}>{state.strings.admin}</Title>
<Space h="md" />
<Button
size="compact-sm"
variant="transparent"
onClick={open}
>{ state.hostname }</Button>
<PasswordInput
className={classes.input}
size="md"
@ -155,6 +230,18 @@ export function Access() {
</div>
</div>
)}
<Modal opened={opened} onClose={close} withCloseButton={false} centered>
<TextInput
size="md"
leftSectionPointerEvents="none"
leftSection={<IconServer />}
placeholder={state.strings.host}
value={state.node}
onChange={(event) =>
actions.setNode(event.currentTarget.value)
}
/>
</Modal>
</div>
)
}

View File

@ -1,8 +1,11 @@
import { useState, useContext, useEffect } from 'react'
import { useRef, useState, useContext, useEffect } from 'react'
import { SettingsContext } from '../context/SettingsContext'
import { AppContext } from '../context/AppContext'
import { ContextType } from '../context/ContextType'
export function useAccess() {
const debounce = useRef(null);
const app = useContext(AppContext) as ContextType
const settings = useContext(SettingsContext) as ContextType
const [state, setState] = useState({
display: null,
@ -11,8 +14,13 @@ export function useAccess() {
username: '',
password: '',
confirm: '',
token: '',
theme: '',
language: '',
node: '',
hostname: '',
available: 0,
availableSet: false,
themes: settings.state.themes,
languages: settings.state.languages,
})
@ -22,6 +30,44 @@ export function useAccess() {
setState((s) => ({ ...s, ...value }))
}
useEffect(() => {
const { protocol, hostname, port } = location
setUrl(`${protocol}//${hostname}:${port}`);
}, [])
const setUrl = (node: string) => {
try {
const url = new URL(node);
const { protocol, hostname, port } = url;
getAvailable(`${hostname}:${port}`, protocol === 'https:');
updateState({ node, hostname: hostname });
}
catch(err) {
console.log(err);
const { protocol, hostname, port } = location;
getAvailable(`${hostname}:${port}`, protocol === 'https:');
updateState({ node, hostname: location.hostname });
}
}
const getAvailable = (node: string, secure: boolean) => {
updateState({ availableSet: false });
clearTimeout(debounce.current);
debounce.current = setTimeout(async () => {
try {
const available = await app.actions.getAvailable(node, secure);
console.log("AVAILABLE: ", available);
updateState({ available, availableSet: true });
}
catch (err) {
console.log(err);
}
}, 1000);
}
useEffect(() => {
const { display, strings, themes, theme, languages, language } =
settings.state
@ -48,12 +94,20 @@ export function useAccess() {
setConfirm: (confirm: string) => {
updateState({ confirm })
},
setToken: (token: string) => {
updateState({ token })
},
setNode: (node: string) => {
setUrl(node);
},
setLanguage: (code: string) => {
settings.actions.setLanguage(code)
},
setTheme: (theme: string) => {
settings.actions.setTheme(theme)
},
login: () => {
},
}
return { state, actions }

View File

@ -10,6 +10,8 @@ export const en = {
ok: 'OK',
cancel: 'Cancel',
enableNotifications: 'Push Notifications',
accessCode: 'Access Code',
forgotPassword: 'Forgot Password',
new: 'New',
newMessage: 'New Message',
@ -220,6 +222,8 @@ export const fr = {
ok: 'OK',
cancel: 'Annuler',
enableNotifications: 'Notifications Push',
accessCode: 'Code d\'Accès',
forgotPassword: 'Mot de Passe Oublié',
new: 'Nouveau',
newMessage: 'Nouveau Message',
@ -433,6 +437,8 @@ export const sp = {
ok: 'Aceptar',
cancel: 'Cancelar',
enableNotifications: 'Notificaciones Push',
accessCode: 'Código de Acceso',
forgotPassword: 'Contraseña Olvidada',
new: 'Nuevo',
newMessage: 'Nuevo mensaje',
@ -644,6 +650,8 @@ export const pt = {
ok: 'OK',
cancel: 'Cancelar',
enableNotifications: 'Notificações Push',
accessCode: 'Código de Acesso',
forgotPassword: 'Senha Esquecida',
new: 'Novo',
newMessage: 'Nova mensagem',
@ -855,6 +863,8 @@ export const de = {
ok: 'OK',
cancel: 'Abbrechen',
enableNotifications: 'Mitteilungen',
accessCode: 'Zugangscode',
forgotPassword: 'Passwort Vergessen',
new: 'Neu',
newMessage: 'Neue Nachricht',
@ -1067,6 +1077,8 @@ export const ru = {
ok: 'OK',
cancel: 'Отмена',
enableNotifications: 'Уведомления',
accessCode: 'Код доступа',
forgotPassword: 'Пароль забыт',
new: 'Новый',
newMessage: 'Новое сообщение',

View File

@ -1,9 +1,12 @@
import { useState, useEffect } from 'react'
import { useState, useEffect, useRef } from 'react'
import { DatabagSDK, Session } from 'databag-client-sdk'
import { SessionStore } from '../SessionStore'
export function useAppContext() {
const [state, setState] = useState({})
const sdk = useRef(new DatabagSDK(null))
const [state, setState] = useState({
session: null as null | Session,
})
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const updateState = (value: any) => {
@ -11,16 +14,19 @@ export function useAppContext() {
}
useEffect(() => {
//init()
init()
}, [])
const init = async () => {
const sdk = new DatabagSDK(null)
const store = new SessionStore()
const session: Session | null = await sdk.initOnlineStore(store)
const session: Session | null = await sdk.current.initOnlineStore(store)
if (session) {
updateState({ sdk, session })
} else {
updateState({ session })
}
}
const actions = {
accountLogin: async () => {
const params = {
topicBatch: 16,
tagBatch: 16,
@ -32,8 +38,7 @@ export function useAppContext() {
version: '0.0.1',
appName: 'databag',
}
console.log('-----> SDK LOGIN')
const login = await sdk.login(
const login = await sdk.current.login(
'asdf',
'asdf',
'balzack.coredb.org',
@ -41,12 +46,22 @@ export function useAppContext() {
null,
params
)
console.log(login)
updateState({ sdk, session: login })
}
updateState({ session: login })
},
accountLogout: async () => {
if (state.session) {
await sdk.current.logout(state.session, false);
updateState({ session: null })
}
},
getAvailable: async (node: string, secure: boolean) => {
return await sdk.current.available(node, secure);
},
adminLogin: async () => {
},
adminLogout: async () => {
},
}
const actions = {}
return { state, actions }
}

View File

@ -1,9 +1,12 @@
import React from 'react'
import React, { useContext } from 'react'
import { Button } from '@mantine/core'
import { AppContext } from '../context/AppContext';
import { ContextType } from '../context/ContextType';
export function Session() {
const app = useContext(AppContext) as ContextType;
return (
<div>
<span>Session</span>
</div>
<Button onClick={app.actions.accountLogout}>Session Logout</Button>
)
}

View File

@ -8,6 +8,7 @@ import { clearLogin } from './net/clearLogin';
import { setAccess } from './net/setAccess';
import { addAccount } from './net/addAccount';
import { setAdmin } from './net/setAdmin';
import { getAvailable } from './net/getAvailable';
import type { Session, Node, Bot, SqlStore, WebStore, Crypto, Logging } from './api';
import type { SessionParams } from './types';
import type { Login } from './entities';
@ -40,6 +41,10 @@ export class DatabagSDK {
return login ? new SessionModule(this.store, this.crypto, this.log, login.token, login.node, login.secure, login.timestamp) : null
}
public async available(node: string, secure: boolean): Promise<number> {
return await getAvailable(node, secure);
}
public async login(handle: string, password: string, node: string, secure: boolean, mfaCode: string | null, params: SessionParams): Promise<Session> {
const { appName, version, deviceId, deviceToken, pushType, notifications } = params;
const { guid, appToken, created, pushSupported } = await setLogin(node, secure, handle, password, mfaCode, appName, version, deviceId, deviceToken, pushType, notifications);