import { Chrome, Android, Apple, Windows } from "@styled-icons/boxicons-logos"; import { HelpCircle, Desktop, LogOut } from "@styled-icons/boxicons-regular"; import { Safari, Firefoxbrowser, Microsoftedge, Linux, Macos, Opera, Samsung, } from "@styled-icons/simple-icons"; import relativeTime from "dayjs/plugin/relativeTime"; import { useHistory } from "react-router-dom"; import { API } from "revolt.js"; import { decodeTime } from "ulid"; import styles from "./Panes.module.scss"; import { Text } from "preact-i18n"; import { useContext, useEffect, useState } from "preact/hooks"; import { Button, LineDivider, Preloader, Tip } from "@revoltchat/ui"; import { dayjs } from "../../../context/Locale"; import { useIntermediate } from "../../../context/intermediate/Intermediate"; import { AppContext } from "../../../context/revoltjs/RevoltClient"; import CategoryButton from "../../../components/ui/fluent/CategoryButton"; dayjs.extend(relativeTime); export function Sessions() { const client = useContext(AppContext); const deviceId = typeof client.session === "object" ? client.session._id : undefined; const [sessions, setSessions] = useState( undefined, ); const [attemptingDelete, setDelete] = useState([]); const history = useHistory(); const { openScreen } = useIntermediate(); function switchPage(to: string) { history.replace(`/settings/${to}`); } useEffect(() => { client.api.get("/auth/session/all").then((data) => { data.sort( (a, b) => (b._id === deviceId ? 1 : 0) - (a._id === deviceId ? 1 : 0), ); setSessions(data); }); }, [client, setSessions, deviceId]); if (typeof sessions === "undefined") { return (
); } function getIcon(session: API.SessionInfo) { const name = session.name; switch (true) { case /firefox/i.test(name): return ; case /chrome/i.test(name): return ; case /safari/i.test(name): return ; case /edge/i.test(name): return ; case /opera/i.test(name): return ; case /samsung/i.test(name): return ; case /desktop/i.test(name): return ; default: return ; } } function getSystemIcon(session: API.SessionInfo) { const name = session.name; switch (true) { case /linux/i.test(name): return ; case /android/i.test(name): return ; case /mac.*os/i.test(name): return ; case /i(Pad)?os/i.test(name): return ; case /windows/i.test(name): return ; default: return null; } } const mapped = sessions.map((session) => { return { ...session, timestamp: decodeTime(session._id), }; }); mapped.sort((a, b) => b.timestamp - a.timestamp); const id = mapped.findIndex((x) => x._id === deviceId); const render = [ mapped[id], ...mapped.slice(0, id), ...mapped.slice(id + 1, mapped.length), ]; return (

{render.map((session) => { const systemIcon = getSystemIcon(session); return (
-1 }> {deviceId === session._id && ( {" "} )}
{getIcon(session)} {systemIcon}
{deviceId !== session._id && ( )}
); })}
{ openScreen({ id: "sessions", confirm: async () => { // ! FIXME: add to rAuth const del: string[] = []; render.forEach((session) => { if (deviceId !== session._id) { del.push(session._id); } }); setDelete(del); for (const id of del) { await client.api.delete( `/auth/session/${id as ""}`, ); } setSessions( sessions.filter((x) => x._id === deviceId), ); }, }); }} icon={} action={"chevron"} description={ "Logs you out of all sessions except this device." }> {" "} switchPage("account")}>
); }