Skip to content

Commit

Permalink
feat(node): logout button
Browse files Browse the repository at this point in the history
  • Loading branch information
justmoon committed Sep 5, 2023
1 parent 67799bb commit a69e725
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,13 @@ export const sessionsStore = (reactor: Reactor) => {
token: sessionToken,
})
}),
removeSession: (sessionToken: SessionToken) =>
produce((draft) => {
draft.delete(sessionToken)
database.tables.sessions
.select()
.where({ equals: { token: sessionToken } })
.delete()
}),
})
}
32 changes: 32 additions & 0 deletions packages/app-node/src/backend/authentication/http-routes/logout.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { parse } from "cookie"

import { respondJson } from "@dassie/lib-http-server"
import { createActor } from "@dassie/lib-reactive"

import { SESSION_COOKIE_NAME } from "../../../common/constants/cookie-name"
import { restApiService } from "../../http-server/serve-rest-api"
import { sessionsStore } from "../database-stores/sessions"
import { SessionToken } from "../types/session-token"

export const registerLogoutRoute = () =>
createActor((sig) => {
const api = sig.get(restApiService)
const sessions = sig.use(sessionsStore)
if (!api) return

api.post("/api/logout").handler((request, response) => {
const cookies = parse(request.headers.cookie ?? "")
const currentSessionToken = cookies[SESSION_COOKIE_NAME]
if (currentSessionToken) {
sessions.removeSession(currentSessionToken as SessionToken)
}
response.cookie(SESSION_COOKIE_NAME, "", {
httpOnly: true,
secure: true,
sameSite: "strict",
expires: new Date(0),
})

respondJson(response, 200, {})
})
})
2 changes: 2 additions & 0 deletions packages/app-node/src/backend/authentication/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ import { createActor } from "@dassie/lib-reactive"

import { registerDevelopmentSetSessionRoute } from "./http-routes/development-set-session"
import { registerLoginRoute } from "./http-routes/login"
import { registerLogoutRoute } from "./http-routes/logout"

export const startAuthenticationFeature = () =>
createActor((sig) => {
sig.run(registerLoginRoute)
sig.run(registerLogoutRoute)

if (import.meta.env.DEV) sig.run(registerDevelopmentSetSessionRoute)
})
2 changes: 2 additions & 0 deletions packages/app-node/src/frontend/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { LoginPage } from "./pages/login/login"
import { Open } from "./pages/open/open"
import { PaymentStatus } from "./pages/payment-status/payment-status"
import { Send } from "./pages/send/send"
import { Settings } from "./pages/settings/settings"
import { trpc } from "./utils/trpc"

const App = () => {
Expand Down Expand Up @@ -40,6 +41,7 @@ const App = () => {
<Route path="/debug/ledger" component={Ledger} />
<Route path="/debug/nodes" component={Nodes} />
<Route path="/debug/routing" component={Routing} />
<Route path="/settings" component={Settings} />
<Route component={Account} />
</Switch>
</div>
Expand Down
7 changes: 7 additions & 0 deletions packages/app-node/src/frontend/layout/main-navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ export function MainNavigation() {
</ul>
</NavigationMenuContent>
</NavigationMenuItem>
<NavigationMenuItem>
<Link href="/settings">
<NavigationMenuLink className={navigationMenuTriggerStyle()}>
Settings
</NavigationMenuLink>
</Link>
</NavigationMenuItem>
</NavigationMenuList>
</NavigationMenu>
)
Expand Down
20 changes: 20 additions & 0 deletions packages/app-node/src/frontend/pages/settings/settings.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { useMutation } from "@tanstack/react-query"

import { Button } from "../../components/ui/button"
import { logout } from "../../utils/authentication"
import { queryClientReactContext } from "../../utils/trpc"

export const Settings = () => {
const logoutMutation = useMutation({
mutationFn: logout,
onSuccess: () => {
window.location.reload()
},
context: queryClientReactContext,
})
return (
<div>
<Button onClick={() => logoutMutation.mutate()}>Logout</Button>
</div>
)
}
13 changes: 13 additions & 0 deletions packages/app-node/src/frontend/utils/authentication.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,16 @@ export const login = async (binarySeed: Uint8Array) => {
throw new Error(`Login failed with status ${response.status}`)
}
}

export const logout = async () => {
const response = await fetch("/api/logout", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
})

if (!response.ok) {
throw new Error(`Logout failed with status ${response.status}`)
}
}

1 comment on commit a69e725

@vercel
Copy link

@vercel vercel bot commented on a69e725 Sep 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.