-
- } />
- } />
- } />
- } />
-
+
+
+
+
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+
+
>
);
}
-export function Stats({ api }: AppProps) {
- const [stats, setStats] = useState
([]);
- const [statsType, setStatsType] = useState("password")
+export interface StatsProps {
+ api: ApiaryAPI
+ type: StatsType
+}
- const activeMenu = (name: string): boolean => {
- if (statsType === name) {
- return true
- }
- return false
- }
- const subMenuItems: SubMenuProps = {
- items: [
- {
- name: "Passwords",
- active: () => { return activeMenu("password") },
- onClick: () => setStatsType("password")
- },
- {
- name: "Usernames",
- active: () => { return activeMenu("username") },
- onClick: () => setStatsType("username")
- },
- {
- name: "IPs",
- active: () => { return activeMenu("ip") },
- onClick: () => setStatsType("ip")
- },
- ]
- }
+export function Stats({ api, type }: StatsProps) {
+ const [stats, setStats] = useState(null)
+ const [currentType, setCurrentType] = useState(type)
useEffect(() => {
async function getStats() {
try {
- let newStats = await api.stats(statsType, 10);
+ let newStats = await api.stats(type, 10);
if (JSON.stringify(newStats) !== JSON.stringify(stats)) {
setStats(newStats)
}
@@ -95,7 +128,14 @@ export function Stats({ api }: AppProps) {
}
}
- getStats()
+ if (currentType !== type) {
+ setCurrentType(type)
+ getStats()
+ }
+
+ if (stats === null) {
+ getStats()
+ }
const interval = setInterval(() => {
getStats()
@@ -104,11 +144,11 @@ export function Stats({ api }: AppProps) {
return () => {
clearInterval(interval);
}
- }, [stats, statsType])
+ }, [stats, type])
+
return (
<>
-
- {stats.length > 0 ? : Loading...
}
+ {(stats != null && stats.length > 0) ? : Loading...
}
>
);
}
@@ -193,7 +233,7 @@ export function Live({ api }: AppProps) {
useEffect(() => {
const cleanup = api.live((a) => {
setLiveList((list) => {
- return [...list, a];
+ return [a, ...list];
});
});
@@ -210,30 +250,67 @@ export function Live({ api }: AppProps) {
export interface LiveListProps {
list: LoginAttempt[]
-};
+};
+
+export interface DateTDProps {
+ date: Date
+ now: Date
+}
+
+export function DateTD({ date, now}: DateTDProps) {
+ const [displayDate, setDisplayDate] = useState(date.toLocaleString());
+
+ useEffect(() => {
+ if (now.getTime() - date.getTime() < 14400000) {
+ const newDate = humanizeDuration(now.getTime() - date.getTime(), { largest: 1, round: true }) + " ago";
+ if (newDate !== displayDate) {
+ setDisplayDate(newDate);
+ }
+ }
+ }, [displayDate, now])
+
+ return (
+ {displayDate} |
+ )
+}
export function LiveList({ list }: LiveListProps) {
+ const [now, setNow] = useState(new Date())
+
let items = list.map((a) => {
+ const attemptDate = new Date(a.date);
+ const key = `${a.username}-${a.password}-${a.remoteIP}-${a.date}`;
return (
- {a.date} |
- {a.username} |
- {a.password} |
- {a.remoteIP} |
- {a.country} |
+
+ {a.username} |
+ {a.password} |
+ {a.remoteIP} |
+ {a.country} |
)
})
+
+ useEffect(() => {
+ const interval = setInterval(() => {
+ setNow(new Date())
+ }, 1000)
+
+ return () => {
+ clearInterval(interval)
+ }
+ }, [now])
+
return (
<>
- Date |
- Username |
- Password |
- IP |
- Country |
+ Date |
+ Username |
+ Password |
+ IP |
+ Country |
@@ -296,7 +373,7 @@ export function Header() {