tangled
alpha
login
or
join now
leaflet.pub
/
leaflet
289
fork
atom
a tool for shared writing and social publishing
289
fork
atom
overview
issues
27
pulls
pipelines
use regular route to logout
awarm.space
9 months ago
7f2b548e
6c018bd9
+33
-39
6 changed files
expand all
collapse all
unified
split
actions
logout.ts
app
api
auth
logout
route.ts
home
AccountSettings.tsx
page.tsx
login
page.tsx
src
auth.ts
-9
actions/logout.ts
···
1
1
-
"use server";
2
2
-
3
3
-
import { cookies } from "next/headers";
4
4
-
import { removeAuthToken } from "src/auth";
5
5
-
6
6
-
export async function logout() {
7
7
-
await removeAuthToken();
8
8
-
(await cookies()).delete("identity");
9
9
-
}
+28
app/api/auth/logout/route.ts
···
1
1
+
import { NextRequest } from "next/server";
2
2
+
export const runtime = "edge";
3
3
+
export const preferredRegion = [];
4
4
+
5
5
+
export async function GET(req: NextRequest) {
6
6
+
const host = req.headers.get("host");
7
7
+
const response = new Response("Logged out successfully", {
8
8
+
status: 200,
9
9
+
headers: {
10
10
+
"Content-Type": "text/plain",
11
11
+
},
12
12
+
});
13
13
+
14
14
+
// Get the base domain from the host
15
15
+
const domain = host?.includes(":") ? host.split(":")[0] : host;
16
16
+
17
17
+
// Clear the auth_token cookie on both the base domain and the domain with a leading dot
18
18
+
response.headers.append(
19
19
+
"Set-Cookie",
20
20
+
`auth_token=; Path=/; Domain=${domain}; Max-Age=0; HttpOnly; Secure; SameSite=Strict`,
21
21
+
);
22
22
+
response.headers.append(
23
23
+
"Set-Cookie",
24
24
+
`auth_token=; Path=/; Domain=.${domain}; Max-Age=0; HttpOnly; Secure; SameSite=Strict`,
25
25
+
);
26
26
+
27
27
+
return response;
28
28
+
}
+2
-3
app/home/AccountSettings.tsx
···
2
2
3
3
import { ActionButton } from "components/ActionBar/ActionButton";
4
4
import { Menu, MenuItem } from "components/Layout";
5
5
-
import { logout } from "actions/logout";
6
5
import { mutate } from "swr";
7
6
import { AccountSmall } from "components/Icons/AccountSmall";
8
7
import { LogoutSmall } from "components/Icons/LogoutSmall";
···
16
15
>
17
16
<MenuItem
18
17
onSelect={async () => {
19
19
-
await logout();
20
20
-
mutate("identity");
18
18
+
await fetch("/api/auth/logout");
19
19
+
mutate("identity", null);
21
20
}}
22
21
>
23
22
<LogoutSmall />
+1
-3
app/home/page.tsx
···
21
21
22
22
export default async function Home() {
23
23
let cookieStore = await cookies();
24
24
-
25
25
-
let auth_token = cookieStore.get("auth_token")?.value;
26
26
-
let auth_res = auth_token ? await getIdentityData() : null;
24
24
+
let auth_res = await getIdentityData();
27
25
let identity: string | undefined;
28
26
if (auth_res) identity = auth_res.id;
29
27
else identity = cookieStore.get("identity")?.value;
-23
app/login/page.tsx
···
1
1
-
import { cookies } from "next/headers";
2
2
-
import LoginForm from "./LoginForm";
3
3
-
import { logout } from "actions/logout";
4
4
-
5
5
-
export default async function LoginPage() {
6
6
-
let cookieStore = await cookies();
7
7
-
let identity = cookieStore.get("auth_token")?.value;
8
8
-
if (!identity)
9
9
-
return (
10
10
-
<div>
11
11
-
this is a login page!
12
12
-
<LoginForm />
13
13
-
</div>
14
14
-
);
15
15
-
return (
16
16
-
<div>
17
17
-
identity: {identity}
18
18
-
<form action={logout}>
19
19
-
<button>logout</button>
20
20
-
</form>
21
21
-
</div>
22
22
-
);
23
23
-
}
+2
-1
src/auth.ts
···
3
3
4
4
export async function setAuthToken(tokenID: string) {
5
5
let c = await cookies();
6
6
+
let host = (await headers()).get("host");
6
7
c.set("auth_token", tokenID, {
7
8
maxAge: 60 * 60 * 24 * 365,
8
9
secure: process.env.NODE_ENV === "production",
9
9
-
domain: isProductionDomain() ? "leaflet.pub" : undefined,
10
10
+
domain: isProductionDomain() ? host! : undefined,
10
11
httpOnly: true,
11
12
sameSite: "lax",
12
13
});