From 961216ac299534b7087d361b4d159b79eef854b6 Mon Sep 17 00:00:00 2001 From: balzack Date: Sun, 11 Aug 2024 01:50:23 +0200 Subject: [PATCH] adding access token options --- app/client/web/src/App.tsx | 29 ++++++ app/client/web/src/access/Access.module.css | 3 +- app/client/web/src/access/Access.tsx | 91 ++++++++++++++++++- app/client/web/src/access/useAccess.hook.ts | 56 +++++++++++- app/client/web/src/constants/Strings.ts | 12 +++ .../web/src/context/useAppContext.hook.ts | 43 ++++++--- app/client/web/src/session/Session.tsx | 11 ++- app/sdk/src/index.ts | 5 + 8 files changed, 228 insertions(+), 22 deletions(-) diff --git a/app/client/web/src/App.tsx b/app/client/web/src/App.tsx index 200f99ee..7931c614 100644 --- a/app/client/web/src/App.tsx +++ b/app/client/web/src/App.tsx @@ -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', + }), }, }) diff --git a/app/client/web/src/access/Access.module.css b/app/client/web/src/access/Access.module.css index 0719df47..dedda211 100644 --- a/app/client/web/src/access/Access.module.css +++ b/app/client/web/src/access/Access.module.css @@ -10,10 +10,11 @@ justify-content: center; align-items: center; padding: 16px; - gap: 16px; + gap: 8px; .input { width: 50%; + margin: 4px; } .title { diff --git a/app/client/web/src/access/Access.tsx b/app/client/web/src/access/Access.tsx index 99230e58..7148abb1 100644 --- a/app/client/web/src/access/Access.tsx +++ b/app/client/web/src/access/Access.tsx @@ -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 (
@@ -48,6 +53,11 @@ export function Access() { <> {state.strings.login} + + )} + {state.mode === 'access' && ( + <> + {state.strings.accessAccount} + + + } + placeholder={state.strings.accessCode} + onChange={(event) => + actions.setToken(event.currentTarget.value) + } + /> + + + + + )} + + {state.mode === 'create' && ( <> {state.strings.createAccount} + + { (state.available === 0 || !state.availableSet) && ( + } + placeholder={state.strings.accessCode} + onChange={(event) => + actions.setToken(event.currentTarget.value) + } + /> + )} {state.strings.create} - @@ -124,6 +194,11 @@ export function Access() { <> {state.strings.admin} +
)} + + } + placeholder={state.strings.host} + value={state.node} + onChange={(event) => + actions.setNode(event.currentTarget.value) + } + /> + ) } diff --git a/app/client/web/src/access/useAccess.hook.ts b/app/client/web/src/access/useAccess.hook.ts index 752b8fb0..cf0ed5bf 100644 --- a/app/client/web/src/access/useAccess.hook.ts +++ b/app/client/web/src/access/useAccess.hook.ts @@ -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 } diff --git a/app/client/web/src/constants/Strings.ts b/app/client/web/src/constants/Strings.ts index a65e3c6c..96063e09 100644 --- a/app/client/web/src/constants/Strings.ts +++ b/app/client/web/src/constants/Strings.ts @@ -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: 'Новое сообщение', diff --git a/app/client/web/src/context/useAppContext.hook.ts b/app/client/web/src/context/useAppContext.hook.ts index dfae7c18..52797ae3 100644 --- a/app/client/web/src/context/useAppContext.hook.ts +++ b/app/client/web/src/context/useAppContext.hook.ts @@ -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 } } diff --git a/app/client/web/src/session/Session.tsx b/app/client/web/src/session/Session.tsx index f500f6a8..8400f693 100644 --- a/app/client/web/src/session/Session.tsx +++ b/app/client/web/src/session/Session.tsx @@ -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 ( -
- Session -
+ ) } diff --git a/app/sdk/src/index.ts b/app/sdk/src/index.ts index 741e679c..0fb324ca 100644 --- a/app/sdk/src/index.ts +++ b/app/sdk/src/index.ts @@ -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 { + return await getAvailable(node, secure); + } + public async login(handle: string, password: string, node: string, secure: boolean, mfaCode: string | null, params: SessionParams): Promise { 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);