diff --git a/pkg/server/accounts_api.go b/pkg/server/accounts_api.go index 69029e1..0360358 100644 --- a/pkg/server/accounts_api.go +++ b/pkg/server/accounts_api.go @@ -38,6 +38,10 @@ func getUserinfo(c *fiber.Ctx) error { resp["email"] = data.GetPrimaryEmail().Content resp["preferred_username"] = data.Nick + if len(data.Avatar) > 0 { + resp["picture"] = fmt.Sprintf("https://%s/api/avatar/%s", viper.GetString("domain"), data.Avatar) + } + return c.JSON(resp) } diff --git a/pkg/view/src/index.tsx b/pkg/view/src/index.tsx index 3af80ee..39f65ad 100644 --- a/pkg/view/src/index.tsx +++ b/pkg/view/src/index.tsx @@ -19,6 +19,7 @@ render(() => ( import("./pages/dashboard.tsx"))} /> + import("./pages/security.tsx"))} /> import("./pages/personalise.tsx"))} /> import("./pages/auth/login.tsx"))} /> import("./pages/auth/register.tsx"))} /> diff --git a/pkg/view/src/layouts/shared/Navbar.tsx b/pkg/view/src/layouts/shared/Navbar.tsx index 30b490b..50fd0ba 100644 --- a/pkg/view/src/layouts/shared/Navbar.tsx +++ b/pkg/view/src/layouts/shared/Navbar.tsx @@ -11,6 +11,7 @@ interface MenuItem { export default function Navbar() { const nav: MenuItem[] = [ { label: "Dashboard", href: "/" }, + { label: "Security", href: "/security" }, { label: "Personalise", href: "/personalise" } ]; diff --git a/pkg/view/src/pages/dashboard.tsx b/pkg/view/src/pages/dashboard.tsx index d245445..1f68a1f 100644 --- a/pkg/view/src/pages/dashboard.tsx +++ b/pkg/view/src/pages/dashboard.tsx @@ -1,5 +1,5 @@ -import { getAtk, readProfiles, useUserinfo } from "../stores/userinfo.tsx"; -import { createSignal, For, Show } from "solid-js"; +import { useUserinfo } from "../stores/userinfo.tsx"; +import { Show } from "solid-js"; export default function DashboardPage() { const userinfo = useUserinfo(); @@ -16,46 +16,10 @@ export default function DashboardPage() { } } - const [events, setEvents] = createSignal([]); - const [eventCount, setEventCount] = createSignal(0); - - const [error, setError] = createSignal(null); - const [submitting, setSubmitting] = createSignal(false); - - async function readEvents() { - const res = await fetch("/api/users/me/events?take=10", { - headers: { Authorization: `Bearer ${getAtk()}` } - }); - if (res.status !== 200) { - setError(await res.text()); - } else { - const data = await res.json(); - setEvents(data["data"]); - setEventCount(data["count"]); - } - } - - async function killSession(item: any) { - setSubmitting(true); - const res = await fetch(`/api/users/me/sessions/${item.id}`, { - method: "DELETE", - headers: { Authorization: `Bearer ${getAtk()}` } - }); - if (res.status !== 200) { - setError(await res.text()); - } else { - await readProfiles(); - setError(null); - } - setSubmitting(false); - } - - readEvents(); - return (
-

Welcome, {userinfo?.displayName}

+

{userinfo?.displayName}

{getGreeting()}

@@ -73,176 +37,20 @@ export default function DashboardPage() {
- - - -
-
-
-
- - - -
-
Challenges
-
{userinfo?.meta?.challenges?.length}
-
- -
-
- - - -
-
Sessions
-
{userinfo?.meta?.sessions?.length}
-
- -
-
- - - -
-
Events
-
{eventCount()}
-
+
+
+

Recommendations

+
    +
  1. 1. Turn on the notification of us.
  2. +
  3. 2. Download passport mobile application.
  4. +
  5. 3. Add more factor to keep your account in safe.
  6. +
  7. 4. Subscribe to Project Hydrogen to get following updates.
  8. +
-
-
- -
- - Challenges - -
-
- - - - - - - - - - - - - {item => - - - - - - } - - -
StateIP AddressUser AgentDate
{item.id}{item.state}{item.ip_address} - - {item.user_agent.substring(0, 10) + "..."} - - {new Date(item.created_at).toLocaleString()}
-
-
-
- -
- - Sessions - -
- - - - - - - - - - - - - {item => - - - - - - } - - -
Third ClientAudiencesDate
{item.id}{item.client_id ? "Linked" : "Non-linked"}{item.audiences?.join(", ")}{new Date(item.created_at).toLocaleString()} - -
-
-
- -
- - Events - -
-
- - - - - - - - - - - - - - {item => - - - - - - - } - - -
TypeTargetIP AddressUser AgentDate
{item.id}{item.type}{item.target}{item.ip_address} - - {item.user_agent.substring(0, 10) + "..."} - - {new Date(item.created_at).toLocaleString()}
-
-
-
- -
-
); } \ No newline at end of file diff --git a/pkg/view/src/pages/personalise.tsx b/pkg/view/src/pages/personalise.tsx index 0cd32ec..f9a926f 100644 --- a/pkg/view/src/pages/personalise.tsx +++ b/pkg/view/src/pages/personalise.tsx @@ -57,8 +57,8 @@ export default function PersonalPage() { return (
-

{userinfo?.displayName}

-

Joined at {new Date(userinfo?.meta?.created_at).toLocaleString()}

+

Personalize

+

Customize your account and let us provide a better service to you.

diff --git a/pkg/view/src/pages/security.tsx b/pkg/view/src/pages/security.tsx new file mode 100644 index 0000000..6efb470 --- /dev/null +++ b/pkg/view/src/pages/security.tsx @@ -0,0 +1,223 @@ +import { getAtk, readProfiles, useUserinfo } from "../stores/userinfo.tsx"; +import { createSignal, For, Show } from "solid-js"; + +export default function DashboardPage() { + const userinfo = useUserinfo(); + + const [events, setEvents] = createSignal([]); + const [eventCount, setEventCount] = createSignal(0); + + const [error, setError] = createSignal(null); + const [submitting, setSubmitting] = createSignal(false); + + async function readEvents() { + const res = await fetch("/api/users/me/events?take=10", { + headers: { Authorization: `Bearer ${getAtk()}` } + }); + if (res.status !== 200) { + setError(await res.text()); + } else { + const data = await res.json(); + setEvents(data["data"]); + setEventCount(data["count"]); + } + } + + async function killSession(item: any) { + setSubmitting(true); + const res = await fetch(`/api/users/me/sessions/${item.id}`, { + method: "DELETE", + headers: { Authorization: `Bearer ${getAtk()}` } + }); + if (res.status !== 200) { + setError(await res.text()); + } else { + await readProfiles(); + setError(null); + } + setSubmitting(false); + } + + readEvents(); + + return ( +
+
+

Security

+

Here is your account status of security.

+
+ +
+ + + +
+ +
+
+
+
+ + + +
+
Challenges
+
{userinfo?.meta?.challenges?.length}
+
+ +
+
+ + + +
+
Sessions
+
{userinfo?.meta?.sessions?.length}
+
+ +
+
+ + + +
+
Events
+
{eventCount()}
+
+
+
+ +
+
+ +
+ + Challenges + +
+
+ + + + + + + + + + + + + {item => + + + + + + } + + +
StateIP AddressUser AgentDate
{item.id}{item.state}{item.ip_address} + + {item.user_agent.substring(0, 10) + "..."} + + {new Date(item.created_at).toLocaleString()}
+
+
+
+ +
+ + Sessions + +
+ + + + + + + + + + + + + {item => + + + + + + } + + +
Third ClientAudiencesDate
{item.id}{item.client_id ? "Linked" : "Non-linked"}{item.audiences?.join(", ")}{new Date(item.created_at).toLocaleString()} + +
+
+
+ +
+ + Events + +
+
+ + + + + + + + + + + + + + {item => + + + + + + + } + + +
TypeTargetIP AddressUser AgentDate
{item.id}{item.type}{item.target}{item.ip_address} + + {item.user_agent.substring(0, 10) + "..."} + + {new Date(item.created_at).toLocaleString()}
+
+
+
+ +
+
+
+ ); +} \ No newline at end of file