✨ Kill Sessions
This commit is contained in:
parent
2a32c8b2f6
commit
e87da59026
@ -55,6 +55,20 @@ func getEvents(c *fiber.Ctx) error {
|
||||
})
|
||||
}
|
||||
|
||||
func killSession(c *fiber.Ctx) error {
|
||||
user := c.Locals("principal").(models.Account)
|
||||
id, _ := c.ParamsInt("sessionId", 0)
|
||||
|
||||
if err := database.C.Delete(&models.AuthSession{}, &models.AuthSession{
|
||||
BaseModel: models.BaseModel{ID: uint(id)},
|
||||
AccountID: user.ID,
|
||||
}).Error; err != nil {
|
||||
return fiber.NewError(fiber.StatusNotFound, err.Error())
|
||||
}
|
||||
|
||||
return c.SendStatus(fiber.StatusOK)
|
||||
}
|
||||
|
||||
func doRegister(c *fiber.Ctx) error {
|
||||
var data struct {
|
||||
Name string `json:"name"`
|
||||
|
@ -26,6 +26,7 @@ func NewServer() {
|
||||
{
|
||||
api.Get("/users/me", auth, getPrincipal)
|
||||
api.Get("/users/me/events", auth, getEvents)
|
||||
api.Delete("/users/me/sessions/:sessionId", auth, killSession)
|
||||
|
||||
api.Post("/users", doRegister)
|
||||
api.Post("/users/me/confirm", doRegisterConfirm)
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { getAtk, useUserinfo } from "../stores/userinfo.tsx";
|
||||
import { getAtk, readProfiles, useUserinfo } from "../stores/userinfo.tsx";
|
||||
import { createSignal, For, Show } from "solid-js";
|
||||
|
||||
export default function DashboardPage() {
|
||||
@ -20,6 +20,7 @@ export default function DashboardPage() {
|
||||
const [eventCount, setEventCount] = createSignal(0);
|
||||
|
||||
const [error, setError] = createSignal<string | null>(null);
|
||||
const [submitting, setSubmitting] = createSignal(false);
|
||||
|
||||
async function readEvents() {
|
||||
const res = await fetch("/api/users/me/events?take=10", {
|
||||
@ -34,6 +35,21 @@ export default function DashboardPage() {
|
||||
}
|
||||
}
|
||||
|
||||
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 (
|
||||
@ -160,6 +176,7 @@ export default function DashboardPage() {
|
||||
<th>Third Client</th>
|
||||
<th>Audiences</th>
|
||||
<th>Date</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -169,6 +186,16 @@ export default function DashboardPage() {
|
||||
<td>{item.client_id ? "Linked" : "Non-linked"}</td>
|
||||
<td>{item.audiences?.join(", ")}</td>
|
||||
<td>{new Date(item.created_at).toLocaleString()}</td>
|
||||
<td class="py-0">
|
||||
<button class="btn btn-sm btn-square btn-error" disabled={submitting()}
|
||||
onClick={() => killSession(item)}>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="h-5 w-5">
|
||||
<path
|
||||
d="M256 48C141.31 48 48 141.31 48 256s93.31 208 208 208s208-93.31 208-208S370.69 48 256 48zm80 224H176a16 16 0 0 1 0-32h160a16 16 0 0 1 0 32z"
|
||||
fill="currentColor"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</td>
|
||||
</tr>}
|
||||
</For>
|
||||
</tbody>
|
||||
|
@ -36,7 +36,7 @@ export async function refreshAtk() {
|
||||
})
|
||||
});
|
||||
if (res.status !== 200) {
|
||||
throw new Error(await res.text());
|
||||
console.error(await res.text())
|
||||
} else {
|
||||
const data = await res.json();
|
||||
new Cookie().set("access_token", data["access_token"], { path: "/" });
|
||||
@ -48,7 +48,7 @@ function checkLoggedIn(): boolean {
|
||||
return new Cookie().get("access_token");
|
||||
}
|
||||
|
||||
export async function readProfiles() {
|
||||
export async function readProfiles(recovering = true) {
|
||||
if (!checkLoggedIn()) return;
|
||||
|
||||
const res = await fetch("/api/users/me", {
|
||||
@ -56,9 +56,14 @@ export async function readProfiles() {
|
||||
});
|
||||
|
||||
if (res.status !== 200) {
|
||||
// Auto retry after refresh access token
|
||||
await refreshAtk();
|
||||
return await readProfiles();
|
||||
if (recovering) {
|
||||
// Auto retry after refresh access token
|
||||
await refreshAtk();
|
||||
return await readProfiles(false);
|
||||
} else {
|
||||
clearUserinfo();
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
||||
|
||||
const data = await res.json();
|
||||
|
Loading…
Reference in New Issue
Block a user