@mikandev/next-discord-auth 1.0.7 → 1.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client.js +47 -0
- package/dist/redirect.js +8 -5
- package/dist/server-actions.js +15 -7
- package/dist/types/client.d.ts +21 -0
- package/dist/types/redirect.d.ts +1 -5
- package/dist/types/server-actions.d.ts +2 -3
- package/package.json +16 -13
package/dist/client.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import {} from "./index";
|
|
4
|
+
import { getSession } from "./server-actions";
|
|
5
|
+
import { createContext, useContext } from "react";
|
|
6
|
+
import useSWR from "swr";
|
|
7
|
+
import { NextRequest, NextResponse } from "next/server";
|
|
8
|
+
const UserInfoContext = createContext(undefined);
|
|
9
|
+
const fetcher = async (url) => {
|
|
10
|
+
const res = await fetch(url);
|
|
11
|
+
const data = (await res.json());
|
|
12
|
+
if ("error" in data && data.error) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
return data;
|
|
16
|
+
};
|
|
17
|
+
export function UserInfoProvider({ children, path, }) {
|
|
18
|
+
const { data, error, isLoading, mutate } = useSWR(path, fetcher, {
|
|
19
|
+
revalidateOnFocus: false,
|
|
20
|
+
revalidateOnReconnect: true,
|
|
21
|
+
});
|
|
22
|
+
return (_jsx(UserInfoContext.Provider, { value: {
|
|
23
|
+
session: data ?? null,
|
|
24
|
+
isLoading,
|
|
25
|
+
isError: !!error,
|
|
26
|
+
mutate,
|
|
27
|
+
}, children: children }));
|
|
28
|
+
}
|
|
29
|
+
export function useUserInfo() {
|
|
30
|
+
const context = useContext(UserInfoContext);
|
|
31
|
+
if (context === undefined) {
|
|
32
|
+
throw new Error("useUserInfo must be used within a UserInfoProvider");
|
|
33
|
+
}
|
|
34
|
+
return context;
|
|
35
|
+
}
|
|
36
|
+
export const createSessionProviderRoute = () => {
|
|
37
|
+
return async (_request) => {
|
|
38
|
+
const session = await getSession();
|
|
39
|
+
if (!session) {
|
|
40
|
+
return NextResponse.json({ error: "Not logged in" });
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
const { accessToken, refreshToken, ...clientSession } = session;
|
|
44
|
+
return NextResponse.json(clientSession);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
};
|
package/dist/redirect.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { NextResponse } from "next/server";
|
|
2
1
|
import { redirect } from "next/navigation";
|
|
3
2
|
import { getGlobalConfig } from "./index";
|
|
4
3
|
import { cookies } from "next/headers";
|
|
@@ -10,7 +9,7 @@ export const handleRedirect = async (req) => {
|
|
|
10
9
|
const params = new URL(req.url).searchParams;
|
|
11
10
|
const code = params.get("code");
|
|
12
11
|
if (!code) {
|
|
13
|
-
return
|
|
12
|
+
return Response.json({ error: "Authorization code not found" }, { status: 400 });
|
|
14
13
|
}
|
|
15
14
|
const response = await ExchangeCodeForTokens(config, code);
|
|
16
15
|
const sessionData = await fetch("https://discord.com/api/users/@me", {
|
|
@@ -20,7 +19,7 @@ export const handleRedirect = async (req) => {
|
|
|
20
19
|
});
|
|
21
20
|
if (!sessionData.ok) {
|
|
22
21
|
const error = (await sessionData.json());
|
|
23
|
-
return
|
|
22
|
+
return Response.json({ error: error.message || "Failed to fetch user data" }, { status: 500 });
|
|
24
23
|
}
|
|
25
24
|
const userData = (await sessionData.json());
|
|
26
25
|
const session = {
|
|
@@ -28,7 +27,7 @@ export const handleRedirect = async (req) => {
|
|
|
28
27
|
id: userData.id,
|
|
29
28
|
name: `${userData.username}`,
|
|
30
29
|
email: userData.email,
|
|
31
|
-
avatar: `https://cdn.discordapp.com/avatars/${userData.id}/${userData.avatar}.png
|
|
30
|
+
avatar: `https://cdn.discordapp.com/avatars/${userData.id}/${userData.avatar}.png`,
|
|
32
31
|
},
|
|
33
32
|
expires: new Date(Date.now() + response.expiresIn * 1000).toISOString(),
|
|
34
33
|
accessToken: response.accessToken,
|
|
@@ -38,7 +37,11 @@ export const handleRedirect = async (req) => {
|
|
|
38
37
|
expiresIn: response.expiresIn,
|
|
39
38
|
});
|
|
40
39
|
const redirectUri = cookieStore.get("REDIRECT_AFTER")?.value || "/";
|
|
41
|
-
cookieStore.set("AUTH_SESSION", token, {
|
|
40
|
+
cookieStore.set("AUTH_SESSION", token, {
|
|
41
|
+
sameSite: "lax",
|
|
42
|
+
httpOnly: true,
|
|
43
|
+
secure: true,
|
|
44
|
+
});
|
|
42
45
|
cookieStore.delete("REDIRECT_AFTER");
|
|
43
46
|
return redirect(redirectUri);
|
|
44
47
|
};
|
package/dist/server-actions.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { NextRequest, NextResponse } from "next/server";
|
|
2
1
|
import { headers } from "next/headers";
|
|
3
2
|
import { cookies } from "next/headers";
|
|
4
3
|
import { redirect } from "next/navigation";
|
|
@@ -21,14 +20,19 @@ export const getSession = async () => {
|
|
|
21
20
|
}
|
|
22
21
|
else {
|
|
23
22
|
const timeUntilExpiration = expiresAt.getTime() - Date.now();
|
|
24
|
-
if (timeUntilExpiration < 5 * 60 * 1000) {
|
|
23
|
+
if (timeUntilExpiration < 5 * 60 * 1000) {
|
|
24
|
+
// less than 5 minutes
|
|
25
25
|
const refreshedSession = await RefreshAccessToken(config, session.refreshToken || "");
|
|
26
26
|
if (refreshedSession) {
|
|
27
27
|
session.accessToken = refreshedSession.accessToken;
|
|
28
28
|
session.refreshToken = refreshedSession.refreshToken;
|
|
29
29
|
session.expires = new Date(Date.now() + refreshedSession.expiresIn * 1000).toISOString();
|
|
30
30
|
const newToken = jwt.sign(session, config.jwtSecret);
|
|
31
|
-
cookieStore.set("AUTH_SESSION", newToken, {
|
|
31
|
+
cookieStore.set("AUTH_SESSION", newToken, {
|
|
32
|
+
sameSite: "lax",
|
|
33
|
+
httpOnly: true,
|
|
34
|
+
secure: true,
|
|
35
|
+
});
|
|
32
36
|
}
|
|
33
37
|
}
|
|
34
38
|
return session;
|
|
@@ -47,9 +51,13 @@ export const signIn = async (redirectTo) => {
|
|
|
47
51
|
const cookieStore = await cookies();
|
|
48
52
|
const headersList = await headers();
|
|
49
53
|
const redirectUri = redirectTo ?? headersList.get("Referer") ?? "/";
|
|
50
|
-
await cookieStore.set("REDIRECT_AFTER", redirectUri, {
|
|
54
|
+
await cookieStore.set("REDIRECT_AFTER", redirectUri, {
|
|
55
|
+
sameSite: "lax",
|
|
56
|
+
httpOnly: true,
|
|
57
|
+
secure: true,
|
|
58
|
+
});
|
|
51
59
|
if (session) {
|
|
52
|
-
return
|
|
60
|
+
return Response.json({ message: "Already signed in" }, { status: 200 });
|
|
53
61
|
}
|
|
54
62
|
const signInURL = `https://discord.com/api/oauth2/authorize?client_id=${config.clientId}&redirect_uri=${encodeURIComponent(config.redirectUri)}&response_type=code&scope=${config.scopes.join(" ")}`;
|
|
55
63
|
return redirect(signInURL);
|
|
@@ -58,8 +66,8 @@ export const signOut = async () => {
|
|
|
58
66
|
const cookieStore = await cookies();
|
|
59
67
|
const token = cookieStore.get("AUTH_SESSION")?.value;
|
|
60
68
|
if (!token) {
|
|
61
|
-
return
|
|
69
|
+
return Response.json({ message: "Not signed in" }, { status: 401 });
|
|
62
70
|
}
|
|
63
71
|
cookieStore.delete("AUTH_SESSION");
|
|
64
|
-
return
|
|
72
|
+
return Response.json({ message: "Signed out successfully" }, { status: 200 });
|
|
65
73
|
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ClientSession } from "./index";
|
|
2
|
+
import type { ReactNode } from "react";
|
|
3
|
+
import type { NextRequest } from "next/server";
|
|
4
|
+
|
|
5
|
+
interface UserInfoContextType {
|
|
6
|
+
session: ClientSession | null;
|
|
7
|
+
isLoading: boolean;
|
|
8
|
+
isError: boolean;
|
|
9
|
+
mutate: () => void;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export declare function UserInfoProvider(props: {
|
|
13
|
+
children: ReactNode;
|
|
14
|
+
path: string;
|
|
15
|
+
}): JSX.Element;
|
|
16
|
+
|
|
17
|
+
export declare function useUserInfo(): UserInfoContextType;
|
|
18
|
+
|
|
19
|
+
export declare function createSessionProviderRoute(
|
|
20
|
+
request: NextRequest,
|
|
21
|
+
): Promise<Response>;
|
package/dist/types/redirect.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import type { NextResponse } from "next/server";
|
|
2
1
|
import type { Session } from "./index";
|
|
3
2
|
|
|
4
3
|
export declare function getSession(): Promise<Session | null>;
|
|
5
4
|
|
|
6
|
-
export declare function signIn(): Promise<
|
|
5
|
+
export declare function signIn(): Promise<Response>;
|
|
7
6
|
|
|
8
|
-
export declare function signOut(): Promise<
|
|
7
|
+
export declare function signOut(): Promise<Response>;
|
package/package.json
CHANGED
|
@@ -4,11 +4,9 @@
|
|
|
4
4
|
"module": "dist/index.ts",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
|
-
"files": [
|
|
8
|
-
"dist"
|
|
9
|
-
],
|
|
7
|
+
"files": ["dist"],
|
|
10
8
|
"license": "WTFPL",
|
|
11
|
-
"version": "1.0.
|
|
9
|
+
"version": "1.0.9",
|
|
12
10
|
"type": "module",
|
|
13
11
|
"keywords": [
|
|
14
12
|
"auth",
|
|
@@ -31,16 +29,19 @@
|
|
|
31
29
|
"lintfix": "biome lint --fix"
|
|
32
30
|
},
|
|
33
31
|
"devDependencies": {
|
|
32
|
+
"@types/react": "^19",
|
|
34
33
|
"@biomejs/biome": "^1.9.4",
|
|
35
|
-
"@types/bun": "
|
|
34
|
+
"@types/bun": "^1.3.11",
|
|
36
35
|
"@types/jsonwebtoken": "^9.0.9"
|
|
37
36
|
},
|
|
38
37
|
"peerDependencies": {
|
|
39
38
|
"typescript": "^5"
|
|
40
39
|
},
|
|
41
40
|
"dependencies": {
|
|
42
|
-
"jsonwebtoken": "^9.0.
|
|
43
|
-
"next": "^16.
|
|
41
|
+
"jsonwebtoken": "^9.0.3",
|
|
42
|
+
"next": "^16.2.1",
|
|
43
|
+
"react": "^19",
|
|
44
|
+
"swr": "^2.4.1"
|
|
44
45
|
},
|
|
45
46
|
"exports": {
|
|
46
47
|
".": {
|
|
@@ -57,16 +58,18 @@
|
|
|
57
58
|
"import": "./dist/server-actions.js",
|
|
58
59
|
"require": "./dist/server-actions.js",
|
|
59
60
|
"types": "./dist/types/server-actions.d.ts"
|
|
61
|
+
},
|
|
62
|
+
"./client": {
|
|
63
|
+
"import": "./dist/client.js",
|
|
64
|
+
"require": "./dist/client.js",
|
|
65
|
+
"types": "./dist/types/client.d.ts"
|
|
60
66
|
}
|
|
61
67
|
},
|
|
62
68
|
"typesVersions": {
|
|
63
69
|
"*": {
|
|
64
|
-
"redirect": [
|
|
65
|
-
|
|
66
|
-
]
|
|
67
|
-
"server-actions": [
|
|
68
|
-
"dist/types/server-actions.d.ts"
|
|
69
|
-
]
|
|
70
|
+
"redirect": ["dist/types/redirect.d.ts"],
|
|
71
|
+
"server-actions": ["dist/types/server-actions.d.ts"],
|
|
72
|
+
"client": ["dist/types/client.d.ts"]
|
|
70
73
|
}
|
|
71
74
|
}
|
|
72
75
|
}
|