diff --git a/packages/main/src/mainWindow.ts b/packages/main/src/mainWindow.ts index 4355b19..4306417 100644 --- a/packages/main/src/mainWindow.ts +++ b/packages/main/src/mainWindow.ts @@ -1,4 +1,7 @@ -import {BrowserWindow} from 'electron'; +import { + BrowserWindow, + session +} from 'electron'; import {join} from 'path'; import {URL} from 'url'; @@ -10,6 +13,7 @@ async function createWindow() { webviewTag: false, // The webview tag is not recommended. Consider alternatives like iframe or Electron's BrowserView. https://www.electronjs.org/docs/latest/api/webview-tag#warning preload: join(__dirname, '../../preload/dist/index.cjs'), }, + }); browserWindow.setMenu(null); @@ -40,6 +44,11 @@ async function createWindow() { await browserWindow.loadURL(pageUrl); + // session.fromPartition('default').setPermissionRequestHandler((webContents, permission, callback) => { + // console.log('requested permission', permission); + + // }) + return browserWindow; } diff --git a/packages/main/src/security-restrictions.ts b/packages/main/src/security-restrictions.ts index eb274e6..c53a83c 100644 --- a/packages/main/src/security-restrictions.ts +++ b/packages/main/src/security-restrictions.ts @@ -6,11 +6,27 @@ import {URL} from 'url'; * * In development mode you need allow open `VITE_DEV_SERVER_URL` */ -const ALLOWED_ORIGINS_AND_PERMISSIONS = new Map>( +type PermissionScope = + 'clipboard-read' + | 'media' + | 'display-capture' + | 'mediaKeySystem' + | 'geolocation' + | 'notifications' + | 'midi' + | 'midiSysex' + | 'pointerLock' + | 'fullscreen' + | 'openExternal' + | 'unknown'; +const ALLOWED_ORIGINS = new Set( import.meta.env.DEV && import.meta.env.VITE_DEV_SERVER_URL - ? [[new URL(import.meta.env.VITE_DEV_SERVER_URL).origin, new Set]] + ? [new URL(import.meta.env.VITE_DEV_SERVER_URL).origin] : [], ); +const ALLOWED_PERMISSIONS: PermissionScope[] = [ + 'media' +] /** * List of origins that you allow open IN BROWSER. @@ -39,7 +55,7 @@ app.on('web-contents-created', (_, contents) => { */ contents.on('will-navigate', (event, url) => { const {origin} = new URL(url); - if (ALLOWED_ORIGINS_AND_PERMISSIONS.has(origin)) { + if (ALLOWED_ORIGINS.has(origin)) { return; } @@ -61,7 +77,7 @@ app.on('web-contents-created', (_, contents) => { contents.session.setPermissionRequestHandler((webContents, permission, callback) => { const {origin} = new URL(webContents.getURL()); - const permissionGranted = !!ALLOWED_ORIGINS_AND_PERMISSIONS.get(origin)?.has(permission); + const permissionGranted = !!ALLOWED_PERMISSIONS.includes(permission) callback(permissionGranted); if (!permissionGranted && import.meta.env.DEV) { @@ -106,7 +122,7 @@ app.on('web-contents-created', (_, contents) => { */ contents.on('will-attach-webview', (event, webPreferences, params) => { const {origin} = new URL(params.src); - if (!ALLOWED_ORIGINS_AND_PERMISSIONS.has(origin)) { + if (!ALLOWED_ORIGINS.has(origin)) { if (import.meta.env.DEV) { console.warn(`A webview tried to attach ${params.src}, but was blocked.`); diff --git a/packages/renderer/src/Router.tsx b/packages/renderer/src/Router.tsx index feb67a4..4c7c701 100644 --- a/packages/renderer/src/Router.tsx +++ b/packages/renderer/src/Router.tsx @@ -3,6 +3,7 @@ import ServerConnection from "./components/ServerConnection"; import Sidebar from "./components/Sidebar"; import TwoPanel from "./components/TwoPanel"; import Voice from "./components/Voice"; +import ClientsListState from "./contexts/EphemeralState/ClientsListState"; import { SettingsContext } from "./contexts/EphemeralState/EphemeralState"; import useHomeServer from "./contexts/PersistentState/useHomeServerNative"; import useChannel from "./hooks/useChannel"; diff --git a/packages/renderer/src/components/ServerConnection.tsx b/packages/renderer/src/components/ServerConnection.tsx index 30f48cf..fec52cf 100644 --- a/packages/renderer/src/components/ServerConnection.tsx +++ b/packages/renderer/src/components/ServerConnection.tsx @@ -1,4 +1,5 @@ import { createContext, PropsWithChildren, ReactNode, useEffect, useMemo } from "react"; +import ClientsListState from "../contexts/EphemeralState/ClientsListState"; import { connectApi } from "../lib/api"; interface ServerConnectionProps { @@ -28,9 +29,11 @@ export default function ServerConnection(props: ServerConnectionProps) { if(!serverConnection) return; serverConnection.destroy(); } - }, []) + }, []); return - {props.children} + + {props.children} + } \ No newline at end of file diff --git a/packages/renderer/src/contexts/EphemeralState/ClientsListState.tsx b/packages/renderer/src/contexts/EphemeralState/ClientsListState.tsx new file mode 100644 index 0000000..d48475d --- /dev/null +++ b/packages/renderer/src/contexts/EphemeralState/ClientsListState.tsx @@ -0,0 +1,47 @@ +import { createContext, useEffect, useMemo, useState } from "react"; +import { useApi } from "/@/lib/useApi"; + + + +export const ClientsListContext = createContext<{ + clientName: { [clientId: string]: string } +}>({ + clientName: {} +}); + + +// export function useClientList() { +// const +// } + +export default function ClientsListState(props: any) { + const [clients, setClients] = useState<{ + [id: string]: string + }>({}); + + const { send } = useApi({ + 'clients:list'(data: any) { + const obj: any = {}; + for(const client of data.clients) { + obj[client.clientId] = client.displayName; + } + setClients(obj); + } + }); + + useEffect(() => { + console.log(clients); + }, [clients]); + + useEffect(() => { + send('clients:list') + }, []); + + const value = useMemo(() => ({ + clientName: clients + }), [clients]); + + return + {props.children} + +} \ 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 226b777..1984bfb 100644 --- a/packages/renderer/src/contexts/EphemeralState/EphemeralState.tsx +++ b/packages/renderer/src/contexts/EphemeralState/EphemeralState.tsx @@ -1,6 +1,7 @@ import { createContext, useState, useMemo, useEffect } from "react"; import UserMediaState from "./UserMediaState"; import PeerState from "./PeerState"; +import ClientsListState from "./ClientsListState"; export type ChannelType = 'text' | 'voice'; diff --git a/packages/renderer/src/pages/Channel.tsx b/packages/renderer/src/pages/Channel.tsx index 5b96811..10df928 100644 --- a/packages/renderer/src/pages/Channel.tsx +++ b/packages/renderer/src/pages/Channel.tsx @@ -7,6 +7,7 @@ import useHover from "../hooks/useHover"; import { useApi } from "../lib/useApi"; import { useContext, useEffect, useState } from "react"; import { VoiceChannelContext } from "../contexts/EphemeralState/VoiceChannelState"; +import { ClientsListContext } from "../contexts/EphemeralState/ClientsListState"; interface ChannelProps { unread: number; @@ -16,6 +17,7 @@ interface ChannelProps { } export default function Channel(props: ChannelProps) { + const { clientName } = useContext(ClientsListContext); const { channel, setChannel } = useChannel(); const { unread, uid, name, type } = props; const [ref, hover] = useHover(); @@ -126,7 +128,7 @@ export default function Channel(props: ChannelProps) {

{participants.map(participant => (
- {participant.clientId} + {clientName[participant.clientId]}
))} diff --git a/packages/renderer/src/pages/Message.tsx b/packages/renderer/src/pages/Message.tsx index ab25af8..b602828 100644 --- a/packages/renderer/src/pages/Message.tsx +++ b/packages/renderer/src/pages/Message.tsx @@ -1,4 +1,6 @@ +import { useContext, useEffect } from 'react'; import TimeAgo from 'react-timeago'; +import { ClientsListContext } from '../contexts/EphemeralState/ClientsListState'; export interface IMessage { uid: string; @@ -19,48 +21,49 @@ const rightMessagePagging = '16px'; export function Message({ message, }: MessageProps) { - + + const { clientName } = useContext(ClientsListContext); return ( -
+ - u === 'second' ? 'Now' : ('' + t + u[0])} + > + + +
- u === 'second' ? 'Now' : ('' + t + u[0])} - > - - +
-
- {message.from} -
-
- {message.text} -
- -
+ {message.text} +
+
+
); } \ No newline at end of file diff --git a/packages/server/src/db/query.ts b/packages/server/src/db/query.ts index e6953ef..49f45ec 100644 --- a/packages/server/src/db/query.ts +++ b/packages/server/src/db/query.ts @@ -1,23 +1,15 @@ import { connection } from './migrate'; - - - -export default async function(a: any, ...opts: any[]): Promise { - const b64 = a.split('base64,')[1]; +export default function(sqlFile: any, ...args: any[]): Promise { + const b64 = sqlFile.split('base64,')[1]; const text = Buffer.from(b64, 'base64').toString(); - try { - return await new Promise((resolve, reject) => { - connection.query(text, [...opts], (err, results) => { - if(!err) return resolve(results); - console.error(err.errno, err.sqlMessage); - console.error('--- Query ---'); - console.error(err.sql); - reject(err); - }); + return new Promise((resolve, reject) => { + connection.query(text, [...args], (err, results) => { + if(!err) return resolve(results); + console.error(err.errno, err.sqlMessage); + console.error('--- Query ---'); + console.error(err.sql); + reject(err); }); - } catch(e) { - return null; - } - // console.log(...opts) + }); } \ No newline at end of file diff --git a/packages/server/src/db/snippets/message/recent.sql b/packages/server/src/db/snippets/message/recent.sql index b6d449c..dc843fe 100644 --- a/packages/server/src/db/snippets/message/recent.sql +++ b/packages/server/src/db/snippets/message/recent.sql @@ -1,7 +1,7 @@ SELECT messages.t_sent, - clients.name as 'from', + clients.uid as 'from', messages.`text` as 'text', messages.channel_uid, messages.uid as uid diff --git a/packages/server/src/lib/dbHelpers/database.ts b/packages/server/src/lib/dbHelpers/database.ts new file mode 100644 index 0000000..d211442 --- /dev/null +++ b/packages/server/src/lib/dbHelpers/database.ts @@ -0,0 +1,13 @@ + +import getAllDisplayNames from './get/all/displayNames'; + + +const database = { + get: { + all: { + displayNames: getAllDisplayNames + } + } +}; + +export default database; \ No newline at end of file diff --git a/packages/server/src/lib/dbHelpers/get/all/displayNames.sql b/packages/server/src/lib/dbHelpers/get/all/displayNames.sql new file mode 100644 index 0000000..84516ff --- /dev/null +++ b/packages/server/src/lib/dbHelpers/get/all/displayNames.sql @@ -0,0 +1,5 @@ +SELECT + uid as clientId, + name as displayName +FROM clients +WHERE totp IS NOT NULL; \ No newline at end of file diff --git a/packages/server/src/lib/dbHelpers/get/all/displayNames.ts b/packages/server/src/lib/dbHelpers/get/all/displayNames.ts new file mode 100644 index 0000000..76c24cd --- /dev/null +++ b/packages/server/src/lib/dbHelpers/get/all/displayNames.ts @@ -0,0 +1,6 @@ +import sql from './displayNames.sql'; +import query from '/@/db/query'; + +export default function() { + return query(sql) +} \ No newline at end of file diff --git a/packages/server/src/lib/get/clientId/by/username.ts b/packages/server/src/lib/dbHelpers/get/clientId/by/username.ts similarity index 100% rename from packages/server/src/lib/get/clientId/by/username.ts rename to packages/server/src/lib/dbHelpers/get/clientId/by/username.ts diff --git a/packages/server/src/lib/get/displayName/by/clientId.ts b/packages/server/src/lib/dbHelpers/get/displayName/by/clientId.ts similarity index 100% rename from packages/server/src/lib/get/displayName/by/clientId.ts rename to packages/server/src/lib/dbHelpers/get/displayName/by/clientId.ts diff --git a/packages/server/src/lib/get/totpKey/by/clientId.ts b/packages/server/src/lib/dbHelpers/get/totpKey/by/clientId.ts similarity index 100% rename from packages/server/src/lib/get/totpKey/by/clientId.ts rename to packages/server/src/lib/dbHelpers/get/totpKey/by/clientId.ts diff --git a/packages/server/src/routers/client.ts b/packages/server/src/routers/client.ts index 36e71b7..74433e4 100644 --- a/packages/server/src/routers/client.ts +++ b/packages/server/src/routers/client.ts @@ -1,10 +1,11 @@ import router from '../lib/router'; import query from '../db/query'; -import { reply } from '../lib/WebSocketServer'; +import { broadcast, reply } from '../lib/WebSocketServer'; import _new from '../db/snippets/client/new.sql'; import _get from '../db/snippets/client/get.sql'; import rename from '../db/snippets/client/rename.sql'; +import database from '../lib/dbHelpers/database'; export default router({ async 'new'(data: any) { @@ -14,7 +15,7 @@ export default router({ data.username, ); if(response === null) return; - return reply({ + return broadcast({ clientId: response[0][0].uid }); }, @@ -32,4 +33,9 @@ export default router({ const res = await query(rename, name, clientId); // silent failure O.O }, + async list() { + return reply({ + clients: await database.get.all.displayNames() + }); + } }); \ No newline at end of file diff --git a/packages/server/src/routers/message.ts b/packages/server/src/routers/message.ts index 11008a3..6b3c0c5 100644 --- a/packages/server/src/routers/message.ts +++ b/packages/server/src/routers/message.ts @@ -2,7 +2,6 @@ import query from '../db/query'; import router from '../lib/router'; import newMessage from '../db/snippets/message/new.sql'; import recentMessages from '../db/snippets/message/recent.sql'; -import getName from '../db/snippets/client/get.sql'; import { broadcast, reply } from '../lib/WebSocketServer'; export default router({ @@ -20,10 +19,8 @@ export default router({ data.channel, ); if(response === null) return; - // translate from to a real name - const nameRes = await query(getName, data.$clientId); - if(nameRes === null) return; - data.from = nameRes[0].name; + + data.from = data.$clientId; return broadcast(data); }, async recent(data: any) {