diff --git a/packages/renderer/assets/pfp.jpg b/packages/renderer/assets/pfp.jpg new file mode 100644 index 0000000..ab4a037 Binary files /dev/null and b/packages/renderer/assets/pfp.jpg differ diff --git a/packages/renderer/index.html b/packages/renderer/index.html index 557725c..d1dbb1a 100644 --- a/packages/renderer/index.html +++ b/packages/renderer/index.html @@ -7,13 +7,14 @@ default-src 'self' data: https://ssl.gstatic.com https://fonts.gstatic.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; media-src *; - img-src 'self' data: content:; + img-src 'self' data: content: http://tinygraphs.com; connect-src *;"> Vite App
+
diff --git a/packages/renderer/src/App.tsx b/packages/renderer/src/App.tsx index 41762bd..63e8a4d 100644 --- a/packages/renderer/src/App.tsx +++ b/packages/renderer/src/App.tsx @@ -1,7 +1,7 @@ import { createContext, useCallback, useEffect, useState, useMemo } from 'react'; import Channels from './pages/Channels'; import Chat from './pages/Chat'; -import Sidebar from './components/Sidebar'; +import Sidebar from './components/TwoPanel'; import NewAccount from './pages/NewAccount'; import ServerConnection from './components/ServerConnection'; import EphemeralState from './contexts/EphemeralState/EphemeralState'; @@ -23,7 +23,7 @@ export default function App() { <> - +
- - - - + {isSettingsOpen ? ( + + ) : ( + + + + + )} ) : ( diff --git a/packages/renderer/src/components/Portal.tsx b/packages/renderer/src/components/Portal.tsx new file mode 100644 index 0000000..d513e83 --- /dev/null +++ b/packages/renderer/src/components/Portal.tsx @@ -0,0 +1,19 @@ +import { useEffect } from "react"; +import { createPortal } from "react-dom"; + +const Portal = ({children}: {children: React.ReactNode}) => { + const mount = document.getElementById("portal-root"); + const el = document.createElement("div"); + + useEffect(() => { + if(mount === null) return; + mount.appendChild(el); + return () => { + mount.removeChild(el); + } + }, [el, mount]); + + return createPortal(children, el) +}; + +export default Portal; \ No newline at end of file diff --git a/packages/renderer/src/components/Sidebar.tsx b/packages/renderer/src/components/Sidebar.tsx index b6d3767..edf497a 100644 --- a/packages/renderer/src/components/Sidebar.tsx +++ b/packages/renderer/src/components/Sidebar.tsx @@ -1,89 +1,116 @@ -import { useCallback, useEffect, useRef, useState } from 'react'; -import useMediaQuery from '../lib/useMediaQueries'; +import useHomeServer from "../hooks/useHomeServer"; +import Channels from "../pages/Channels"; +import pfp from '../../assets/pfp.jpg'; +import { IoMdSettings } from 'react-icons/io'; +import useHover from "../hooks/useHover"; +import { useContext } from "react"; +import { SettingsContext } from "../contexts/EphemeralState/EphemeralState"; + +export default function Sidebar() { -export default function Sidebar(props: { - threshold: number, - sidebar: number, - children: any[] -}) { - const bigScreen = useMediaQuery('(min-width:' + props.threshold + 'px)'); - const [screenRef, setScreenRef] = useState(null); - const [startDrag, setStartDrag] = useState(0); - const [currentDrag, setCurrentDrag] = useState(0); - const [dragging, setDragging] = useState(false); - const [opened, setOpened] = useState(false); + return ( +
+ + + +
+ ) +} - const difference = opened ? - Math.min(currentDrag - startDrag, 0) : - Math.max(currentDrag - startDrag, 0); +function TopSidebar() { - const pointerDown = useCallback((e: any) => { - setDragging(true); - setStartDrag(e.touches[0].clientX); - setCurrentDrag(e.touches[0].clientX); - }, [dragging, startDrag, currentDrag]); + const { homeServer } = useHomeServer(); - const pointerUp = useCallback(() => { - setDragging(false); - if(difference > 0) { - setOpened(true); - } else if (difference < 0) { - setOpened(false); - } - }, [dragging, currentDrag, startDrag, opened]); + return ( +
+ {homeServer && new URL(homeServer).hostname.toLocaleLowerCase()} +
+ ) +} - const pointerMove = useCallback((e: any) => { - setCurrentDrag(e.touches[0].clientX); - }, [dragging, currentDrag]); +function MiniProfile() { + return ( +
+ +
+
+
Valerie
+
dev.valnet.xyz
+
+
+
+ + {/* + */} +
+
+ ) +} - useEffect(() => { - if(screenRef === null) return; - screenRef.addEventListener('touchstart', pointerDown, { passive: true }); - screenRef.addEventListener('touchend', pointerUp, { passive: true }); - screenRef.addEventListener('touchmove', pointerMove, { passive: true }); - // screenRef.addEventListener('pointercancel', pointerUp); - return () => { - screenRef.removeEventListener('touchstart', pointerDown); - screenRef.removeEventListener('touchend', pointerUp); - screenRef.removeEventListener('touchmove', pointerMove); - // screenRef.removeEventListener('pointercancel', pointerUp); - }; - }, [screenRef, pointerUp, pointerDown]); +function SettingsButton() { + const [ref, hover] = useHover(); + const { openSettings } = useContext(SettingsContext); - return
-
{props.children[0]}
-
{props.children[1]}
-
; + return
+ +
+} + +function ProfilePicture() { + const name = 'Val'; + return
} \ No newline at end of file diff --git a/packages/renderer/src/components/TwoPanel.tsx b/packages/renderer/src/components/TwoPanel.tsx new file mode 100644 index 0000000..a12d15b --- /dev/null +++ b/packages/renderer/src/components/TwoPanel.tsx @@ -0,0 +1,91 @@ +import { useCallback, useEffect, useRef, useState } from 'react'; +import useMediaQuery from '../lib/useMediaQueries'; + + + +export default function TwoPanel(props: { + threshold: number, + sidebar: number, + children: any +}) { + const bigScreen = useMediaQuery('(min-width:' + props.threshold + 'px)'); + const [screenRef, setScreenRef] = useState(null); + const [startDrag, setStartDrag] = useState(0); + const [currentDrag, setCurrentDrag] = useState(0); + const [dragging, setDragging] = useState(false); + const [opened, setOpened] = useState(false); + + const difference = opened ? + Math.min(currentDrag - startDrag, 0) : + Math.max(currentDrag - startDrag, 0); + + const pointerDown = useCallback((e: any) => { + setDragging(true); + setStartDrag(e.touches[0].clientX); + setCurrentDrag(e.touches[0].clientX); + }, [dragging, startDrag, currentDrag]); + + const pointerUp = useCallback(() => { + setDragging(false); + if(difference > 0) { + setOpened(true); + } else if (difference < 0) { + setOpened(false); + } + }, [dragging, currentDrag, startDrag, opened]); + + const pointerMove = useCallback((e: any) => { + setCurrentDrag(e.touches[0].clientX); + }, [dragging, currentDrag]); + + useEffect(() => { + if(screenRef === null) return; + screenRef.addEventListener('touchstart', pointerDown, { passive: true }); + screenRef.addEventListener('touchend', pointerUp, { passive: true }); + screenRef.addEventListener('touchmove', pointerMove, { passive: true }); + // screenRef.addEventListener('pointercancel', pointerUp); + return () => { + screenRef.removeEventListener('touchstart', pointerDown); + screenRef.removeEventListener('touchend', pointerUp); + screenRef.removeEventListener('touchmove', pointerMove); + // screenRef.removeEventListener('pointercancel', pointerUp); + }; + }, [screenRef, pointerUp, pointerDown]); + + return
+
{props.children[0]}
+
{props.children[1]}
+
; +} \ No newline at end of file diff --git a/packages/renderer/src/contexts/EphemeralState/EphemeralState.tsx b/packages/renderer/src/contexts/EphemeralState/EphemeralState.tsx index bc0c253..922aa7a 100644 --- a/packages/renderer/src/contexts/EphemeralState/EphemeralState.tsx +++ b/packages/renderer/src/contexts/EphemeralState/EphemeralState.tsx @@ -8,7 +8,15 @@ export const ChannelContext = createContext<{ setChannel: () => {}, }); export const TransparencyContext = createContext<(transparent: boolean) => void>(() => {}); - +export const SettingsContext = createContext<{ + openSettings: () => void, + closeSettings: () => void, + isSettingsOpen: boolean +}>({ + openSettings() {}, + closeSettings() {}, + isSettingsOpen: false +}); export default function EphemeralState(props: { onTransparencyChange: (value: boolean) => void, @@ -18,6 +26,8 @@ export default function EphemeralState(props: { const [channel, setChannel] = useState(null); const [transparent, setTransparent] = useState(false); + const [settings, setSettings] = useState(true); + const channelContextValue = useMemo(() => { return { channel, setChannel }; }, [channel, setChannel]); @@ -31,7 +41,13 @@ export default function EphemeralState(props: { return ( - {props.children} + setSettings(true), + closeSettings: () => setSettings(false), + isSettingsOpen: settings, + }}> + {props.children} + ); diff --git a/packages/renderer/src/index.tsx b/packages/renderer/src/index.tsx index ac3fbc1..ef829ea 100644 --- a/packages/renderer/src/index.tsx +++ b/packages/renderer/src/index.tsx @@ -1,11 +1,13 @@ import React from 'react'; import ReactDOM from 'react-dom/client'; -import Sidebar from './components/Sidebar'; +import Sidebar from './components/TwoPanel'; import App from './App'; +import { createPortal } from 'react-dom'; const container = document.getElementById('app'); if(container !== null) { - const root = ReactDOM.createRoot(container) + const root = ReactDOM.createRoot(container); + // const portal = createPortal() root.render(); } else { throw new Error('Failed to initialize app, container not found!'); diff --git a/packages/renderer/src/lib/useApi.tsx b/packages/renderer/src/lib/useApi.tsx index 17cffd7..a1e867c 100644 --- a/packages/renderer/src/lib/useApi.tsx +++ b/packages/renderer/src/lib/useApi.tsx @@ -3,7 +3,7 @@ import { ServerConnectionContext } from '../components/ServerConnection'; import useSessionToken from '../hooks/useSessionToken'; import { Router, router, RouterObject } from './api'; -export function useApi(actions: Router | RouterObject, deps: any[]) { +export function useApi(actions: Router | RouterObject = {}, deps: any[] = []) { const connection = useContext(ServerConnectionContext); const _router = typeof actions === 'object' ? router(actions) : actions; const { sessionToken } = useSessionToken(); diff --git a/packages/renderer/src/pages/BigButton.tsx b/packages/renderer/src/pages/BigButton.tsx new file mode 100644 index 0000000..d2b9b96 --- /dev/null +++ b/packages/renderer/src/pages/BigButton.tsx @@ -0,0 +1,70 @@ +import useHover from "../hooks/useHover"; + +export function BigButton(props: any) { + const [ref, hover] = useHover(); + + const angle = props.angle ?? 20; + const width = props.width ?? 'auto'; + const display = !!props.inline ? 'inline-grid' : 'grid'; + + return ( +
{ })} style={{ + cursor: 'pointer', + width: width, + // margin: '4px', + display: display, + padding: '8px', + borderRadius: '8px', + gridAutoFlow: 'column', + gridTemplateColumns: 'min-content 1fr', + background: (!!props.bright) ? ( + props.selected ? 'var(--neutral-6)' : + hover ? 'var(--neutral-6)' : + 'var(--neutral-5)' + ) : ( + props.selected ? 'var(--neutral-5)' : + hover ? 'var(--neutral-4)' : + 'inherit' + ), + transform: `skew(-${angle}deg, 0deg)`, + boxSizing: 'border-box', + }}> +
+ {props.icon({ + size: 16, + color: !!props.color ? props.color : (!!props.bright) ? ( + props.selected ? 'var(--neutral-9)' : + hover ? 'var(--neutral-8)' : + 'var(--neutral-8)' + ) : ( + props.selected ? 'var(--neutral-9)' : + hover ? 'var(--neutral-7)' : + 'var(--neutral-7)' + ), + })} +
+ + + {props.text} + +
+ ); +} diff --git a/packages/renderer/src/pages/Channel.tsx b/packages/renderer/src/pages/Channel.tsx index b95e3e0..9f4539e 100644 --- a/packages/renderer/src/pages/Channel.tsx +++ b/packages/renderer/src/pages/Channel.tsx @@ -22,12 +22,12 @@ export default function Channel(props: ChannelProps) { gridTemplateColumns: 'min-content 1fr', color: selected ? 'cyan' : 'inherit', cursor: 'pointer', - background: selected ? 'var(--neutral-4)' : - hover ? 'var(--neutral-3)' : + background: selected ? 'var(--neutral-5)' : + hover ? 'var(--neutral-4)' : 'inherit', borderRadius: '8px', - // placeItems: 'left center', - // border: '1px solid white' + transform:'skew(-20deg, 0deg)', + transition: 'background 300ms, color 300ms', }} onClick={() => { setChannel(uid); @@ -35,17 +35,21 @@ export default function Channel(props: ChannelProps) { ref={ref} >
{name.toLowerCase().replaceAll(' ', '-').trim()}
diff --git a/packages/renderer/src/pages/Channels.tsx b/packages/renderer/src/pages/Channels.tsx index 65f9a7f..b6044e7 100644 --- a/packages/renderer/src/pages/Channels.tsx +++ b/packages/renderer/src/pages/Channels.tsx @@ -24,7 +24,7 @@ export default function Channels() { const [channels, setChannels] = useState([]); const [unreads, setUnreads] = useState({}); - + const { channel, setChannel } = useChannel() const { clientId } = useClientId() @@ -44,10 +44,6 @@ export default function Channels() { }, }, [channels, unreads]); - useEffect(() => { - // console.log('unreads', unreads); - }, [unreads]); - useEffect(() => { if(channels.length === 0) { send('channels:list'); @@ -55,10 +51,8 @@ export default function Channels() { }, [channels]); useEffect(() => { - // console.log(channel, channels); if(channels.length === 0) return; if(channel !== null) return; - // console.log('this is what setChannel is', setChannel); setChannel(channels[0].uid); }, [channel, channels]); @@ -86,8 +80,10 @@ export default function Channels() { return (


{channels.map(c => ( diff --git a/packages/renderer/src/pages/Chat.tsx b/packages/renderer/src/pages/Chat.tsx index ee3a44e..49a94c3 100644 --- a/packages/renderer/src/pages/Chat.tsx +++ b/packages/renderer/src/pages/Chat.tsx @@ -75,6 +75,7 @@ export default () => { height: '100%', width: '100%', display: 'grid', + background: 'var(--neutral-4)', gridTemplateColumns: `1fr ${CHATBOX_SIZE}px`, gridTemplateRows: `1fr ${CHATBOX_SIZE}px`, gridTemplateAreas: '"content content" "message send"', @@ -102,7 +103,7 @@ export default () => { margin: PADDING + 'px', marginRight: '0px', borderRadius: ((CHATBOX_SIZE - PADDING*2) / 2) + 'px', - background: '#343746', + background: 'var(--neutral-5)', gridArea: 'message', display: 'grid', placeItems: 'center center', diff --git a/packages/renderer/src/pages/Message.tsx b/packages/renderer/src/pages/Message.tsx index 0af1832..ab25af8 100644 --- a/packages/renderer/src/pages/Message.tsx +++ b/packages/renderer/src/pages/Message.tsx @@ -30,7 +30,7 @@ export function Message({ }}>
(null); - // const { setHomeServer } = useContext(HomeServerContext); // const { setClientId } = useContext(ClientIdContext); // const setTransparent = useContext(TransparencyContext); @@ -62,12 +66,26 @@ export default function NewAccount() { // } // }, [data, scanning]) + // const [homeServer, setHomeServer] = useState(null); + // const homeServerInputRef = useRef(null); + const { setHomeServer, homeServer } = useHomeServer(); + const [homeServerInput, setHomeServerInput] = useState(homeServer ?? ''); + const [usernameInput, setUsernameInput] = useState(''); + const [authCodeInput, setAuthCodeInput] = useState(''); const [returning, setReturning] = useState(true); - const homeServerInputRef = useRef(null); - const [homeServer, setHomeServer] = useState(null); const [connection, setConnection] = useState(null); const [connecting, setConnecting] = useState(false); const [connectionError, setConnectionError] = useState(''); + const [edittingHomeServer, setEdittingHomeServer] = useState(false); + const [homeServerInputRef, homeServerHovered] = useHover(); + + useEffect(() => { + if(homeServer === null) { + setEdittingHomeServer(true) + } else { + setEdittingHomeServer(false) + } + }, [homeServer]); const connect = useCallback((url: string) => { if(connecting) return; @@ -91,133 +109,240 @@ export default function NewAccount() { ws.addEventListener('error', (e) => { setConnectionError('Connection failed') }); - }, [connecting]) + }, [connecting]); + + // return ( + //
+ // {returning ? ( + //
+ // + // Login + // + //   + //   + //   + // setReturning(false)}>Sign up + //
+ // ) : ( + // <> + //
+ // setReturning(true)}> + // Login + // + //   + //   + //   + // + // Sign up + // + //
+ //

+ // + // + // + // {connecting ? `Connecting...` : connectionError} + //

+ // {connection !== null && ( + // + // + // + // + // )} + // {/* Create New Account!!
+ // Enter Home Server URL
+ //
+ //
+ //
+ // or scan a QR!
+ //

+ //
+  //           {data}
+  //           {scanning ? 'SCANNING' : 'NOT SCANNING'}
+  //         
*/} + // + // )} + //
+ // ); + + return (
- {returning ? ( -
- - Login - -   -   -   - setReturning(false)}>Sign up -
- ) : ( - <> -
- setReturning(true)}> - Login - -   -   -   - - Sign up - +
+
+
+ setReturning(true)} + >
-

- - - - {connecting ? `Connecting...` : connectionError} -

- {connection !== null && ( - - - - - )} - {/* Create New Account!!
- Enter Home Server URL
-
-
-
- or scan a QR!
-

-
-            {data}
-            {scanning ? 'SCANNING' : 'NOT SCANNING'}
-          
*/} - - )} +
+ setReturning(false)} + > +
+
+ +
+ + e.code === 'Enter' && (setHomeServer(homeServerInput))} + > +
+ +
+ +
+ +
+ +
+
+ {}} + > +
+
- ); + ) } -const SignUp = (props: any) => { +function Label(props: any) { + return +} - const usernameRef = useRef(null); - const displayNameRef = useRef(null); - const totpRef = useRef(null); - const [clientId, setClientId] = useState(null); - // const [totpToken, setTotpToken] = useState(null); - const [qr, setQr] = useState(null); - const { setSessionToken } = useSessionToken(); +interface InputProps { + value: string; + setValue: (s: string) => void; + default?: string; + onKeyPress?: (e: any) => void; + disabled?: boolean; + hoverRef?: React.LegacyRef +} - const { send } = useApi({ - 'client:new'(data: any) { - setClientId(data); - }, - async 'totp:propose'(data: any) { - setQr(await QR.toDataURL( - 'otpauth://totp/' + - (usernameRef.current?.value ?? '') + - '?secret=' + - data + - '&issuer=valnet-corner' - )); - }, - 'totp:confirm'(data: any) { - setSessionToken(data.token); - console.log(data); - } - }, [setSessionToken]); +const Input = (props: InputProps) => { - const createAccount = useCallback(() => { - send('client:new', { - username: usernameRef.current?.value, - displayName: displayNameRef.current?.value, - }) - }, []); - - useEffect(() => { - if(clientId === null) return; - send('totp:propose', clientId); - }, [clientId]); - - const changeTotp = useCallback(() => { - const value = totpRef.current?.value ?? ''; - if(!(/[0-9]{6}/.test(value))) return; - send('totp:confirm', { - clientId, - code: value - }) - }, [clientId]); + const _default = props.default ?? ''; + const [focused, setFocused] = useState(false); + const disabled = props.disabled ?? false; return ( - <> - - - - - - {clientId && ( - <> -

- -

- - - - )} - +
+ {})} + onFocus={(e) => !!props.disabled ? e.target.blur() : setFocused(true)} + onBlur={() => setFocused(false)} + disabled={disabled} + style={{ + height: '40px', + width: '100%', + padding: '0px', + margin: '0px', + border: focused ? '1px solid var(--neutral-7)' : '1px solid rgba(0, 0, 0, 0)', + transform: 'skew(-6deg, 0deg)', + borderRadius: '8px', + outline: 'none', + fontSize: '20px', + paddingLeft: '12px', + paddingRight: '12px', + boxSizing: 'border-box', + background: disabled ? 'var(--neutral-3)' : focused ? 'var(--neutral-2)' : 'var(--neutral-1)', + color: disabled ? 'var(--neutral-6)' : 'var(--neutral-8)' + }} + spellCheck="false" + onChange={(e) => props.setValue(e.target.value)} + value={props.value} + > +
) } \ No newline at end of file diff --git a/packages/renderer/src/pages/Settings.tsx b/packages/renderer/src/pages/Settings.tsx new file mode 100644 index 0000000..72b7756 --- /dev/null +++ b/packages/renderer/src/pages/Settings.tsx @@ -0,0 +1,108 @@ +import { useCallback, useContext, useState } from "react"; +import { MdManageAccounts } from "react-icons/md"; +import TwoPanel from "../components/TwoPanel"; +import { SettingsContext } from "../contexts/EphemeralState/EphemeralState"; +import { AiOutlineCloseCircle } from 'react-icons/ai'; +import { BiLogOut } from 'react-icons/bi'; +import { useApi } from "../lib/useApi"; +import useSessionToken from "../hooks/useSessionToken"; +import { BigButton } from "./BigButton"; + +const pages = [ + ['General', MdManageAccounts], + ['Appearance', MdManageAccounts], + ['Voice & Video', MdManageAccounts], + ['Notifications', MdManageAccounts], +]; + +export default function Settings() { + + const [page, setPage] = useState(0); + const { closeSettings } = useContext(SettingsContext); + const { setSessionToken } = useSessionToken() + + const { send } = useApi(); + + const logout = useCallback(() => { + send('session:invalidate'); + setSessionToken(null); + }, [send]) + + return <> +
+ +
+ +
+

+

+

+

+ {pages.map((v, i) => ( + setPage(i)} + > + ))} +

+ +
+
+

+

+ {/*

*/} +
+ {pages[page][0].toString().toUpperCase()} +
+

+ {(() => { + switch(page) { + case 0: return + default: return + } + })()} +
+
+ +} + +function GeneralSettings() { + return ( +
THIS IS A PAGE THIS IS A PAGE THIS IS A PAGE THIS IS A PAGE THIS IS A PAGE THIS IS A PAGE THIS IS A PAGE THIS IS A PAGE THIS IS A PAGE THIS IS A PAGE THIS IS A PAGE THIS IS A PAGE THIS IS A PAGE THIS IS A PAGE THIS IS A PAGE THIS IS A PAGE THIS IS A PAGE THIS IS A PAGE
+ ) +} + diff --git a/packages/renderer/src/pages/SignUp.tsx b/packages/renderer/src/pages/SignUp.tsx new file mode 100644 index 0000000..0055a82 --- /dev/null +++ b/packages/renderer/src/pages/SignUp.tsx @@ -0,0 +1,77 @@ +import { useEffect, useState } from "react"; +import { useCallback, useRef } from "react"; +import { useApi } from "../lib/useApi"; +import QR from 'qrcode'; +import useSessionToken from "../hooks/useSessionToken"; + +export const SignUp = (props: any) => { + + const usernameRef = useRef(null); + const displayNameRef = useRef(null); + const totpRef = useRef(null); + const [clientId, setClientId] = useState(null); + // const [totpToken, setTotpToken] = useState(null); + const [qr, setQr] = useState(null); + const { setSessionToken } = useSessionToken(); + + const { send } = useApi({ + 'client:new'(data: any) { + setClientId(data); + }, + async 'totp:propose'(data: any) { + setQr(await QR.toDataURL( + 'otpauth://totp/' + + (usernameRef.current?.value ?? '') + + '?secret=' + + data + + '&issuer=valnet-corner' + )); + }, + 'totp:confirm'(data: any) { + setSessionToken(data.token); + console.log(data); + } + }, [setSessionToken]); + + const createAccount = useCallback(() => { + send('client:new', { + username: usernameRef.current?.value, + displayName: displayNameRef.current?.value, + }); + }, []); + + useEffect(() => { + if (clientId === null) + return; + send('totp:propose', clientId); + }, [clientId]); + + const changeTotp = useCallback(() => { + const value = totpRef.current?.value ?? ''; + if (!(/[0-9]{6}/.test(value))) + return; + send('totp:confirm', { + clientId, + code: value + }); + }, [clientId]); + + return ( + <> + + + + + + {clientId && ( + <> +

+ +

+ + + + )} + + ); +}; diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index 6045357..1ddb084 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -17,6 +17,8 @@ const api = router({ client: client, clients: client, totp: totp, + session: session, + sessions: session, }); expose(api, 3000); @@ -24,6 +26,7 @@ expose(api, 3000); // ------------- import { update } from './db/migrate'; +import session from './routers/session'; try { update(); diff --git a/packages/server/src/lib/WebSocketServer.ts b/packages/server/src/lib/WebSocketServer.ts index e6fe83b..b586959 100644 --- a/packages/server/src/lib/WebSocketServer.ts +++ b/packages/server/src/lib/WebSocketServer.ts @@ -21,6 +21,7 @@ export function expose(router: Function, port: number) { try { if(typeof data === 'object' && 'sessionToken' in data) { const auth = await validateSessionToken(data.sessionToken); + data.$sessionToken = data.sessionToken; delete data['sessionToken']; if(auth === null) return; data.$clientId = auth; diff --git a/packages/server/src/routers/session.ts b/packages/server/src/routers/session.ts index ab69fa9..6f298fe 100644 --- a/packages/server/src/routers/session.ts +++ b/packages/server/src/routers/session.ts @@ -6,8 +6,8 @@ import _get from '../db/snippets/session/get.sql' import query from "../db/query"; export default router({ - async 'invalidate'(token: string) { - await query(invalidate, token); + async 'invalidate'(data: any) { + await query(invalidate, data.$sessionToken); return reply({ err: null })