@next-nest-auth/nextauth 0.1.9 → 0.2.1
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/auth.d.ts +2 -2
- package/dist/auth.js +40 -40
- package/dist/auth.js.map +1 -1
- package/dist/components/GoogleLogin.d.ts +4 -0
- package/dist/components/GoogleLogin.js +21 -0
- package/dist/components/GoogleLogin.js.map +1 -0
- package/dist/src/auth.d.ts +27 -0
- package/dist/src/auth.js +187 -0
- package/dist/src/auth.js.map +1 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +18 -0
- package/dist/src/index.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +50 -50
- package/src/auth.ts +192 -177
package/package.json
CHANGED
|
@@ -1,52 +1,52 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
2
|
+
"name": "@next-nest-auth/nextauth",
|
|
3
|
+
"version": "0.2.1",
|
|
4
|
+
"main": "dist/index.js",
|
|
5
|
+
"types": "dist/index.d.ts",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "tsc -w",
|
|
8
|
+
"build": "tsc"
|
|
9
|
+
},
|
|
10
|
+
"keywords": [
|
|
11
|
+
"nextjs",
|
|
12
|
+
"authentication",
|
|
13
|
+
"nextauth",
|
|
14
|
+
"auth",
|
|
15
|
+
"jwt",
|
|
16
|
+
"token authentication",
|
|
17
|
+
"refresh tokens",
|
|
18
|
+
"secure authentication",
|
|
19
|
+
"session management",
|
|
20
|
+
"nestjs integration",
|
|
21
|
+
"nextjs authentication",
|
|
22
|
+
"nextjs auth",
|
|
23
|
+
"cookie authentication",
|
|
24
|
+
"login",
|
|
25
|
+
"multi-provider authentication",
|
|
26
|
+
"nextjs login",
|
|
27
|
+
"user authentication"
|
|
28
|
+
],
|
|
29
|
+
"author": "Md Shafkat Hussain Tanvir <tanvir0604@gmail.com>",
|
|
30
|
+
"repository": "https://github.com/tanvir0604/nextauth",
|
|
31
|
+
"bugs": "https://github.com/tanvir0604/nextauth/issues",
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"type": "commonjs",
|
|
34
|
+
"description": "NextAuth is a frontend authentication package designed for Next.js applications, providing easy integration with NestJS-based backends. It supports login, session management, and token handling (including JWT and refresh tokens) to ensure secure user authentication. With customizable authentication flows and compatibility with multiple providers, NextAuth enables seamless integration between NestJS and Next.js apps.",
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"axios": "^1.13.2",
|
|
37
|
+
"js-cookie": "^3.0.5",
|
|
38
|
+
"jsonwebtoken": "^9.0.3",
|
|
39
|
+
"jwt-decode": "^4.0.0",
|
|
40
|
+
"next": "^16.1.1"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@types/js-cookie": "^3.0.6",
|
|
44
|
+
"@types/node": "^25.0.3",
|
|
45
|
+
"@types/react": "^19.2.7",
|
|
46
|
+
"typescript": "^5.9.3"
|
|
47
|
+
},
|
|
48
|
+
"files": [
|
|
49
|
+
"dist/",
|
|
50
|
+
"src/"
|
|
51
|
+
]
|
|
52
52
|
}
|
package/src/auth.ts
CHANGED
|
@@ -1,217 +1,232 @@
|
|
|
1
|
-
import axios from
|
|
2
|
-
import { jwtDecode } from
|
|
3
|
-
import { cookies } from
|
|
4
|
-
import { NextRequest, NextResponse } from
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import { jwtDecode } from "jwt-decode";
|
|
3
|
+
import { cookies } from "next/headers";
|
|
4
|
+
import { NextRequest, NextResponse } from "next/server";
|
|
5
5
|
|
|
6
6
|
const API_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_URL;
|
|
7
7
|
|
|
8
8
|
interface TokenResponse {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
accessToken: string;
|
|
10
|
+
refreshToken: string;
|
|
11
|
+
accessTokenExpiresIn: string;
|
|
12
|
+
refreshTokenExpiresIn: string;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
interface User {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
16
|
+
sub: string;
|
|
17
|
+
name: string;
|
|
18
|
+
email: string;
|
|
19
|
+
mobile: string;
|
|
20
|
+
role: string;
|
|
21
|
+
pic: string;
|
|
22
|
+
macId: string;
|
|
23
|
+
[key: string]: any;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
const convertToSeconds = (expiresIn: string) => {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
27
|
+
const match = expiresIn.match(/(\d+)([mhd])/);
|
|
28
|
+
if (!match) return 0;
|
|
29
|
+
|
|
30
|
+
const value = parseInt(match[1], 10);
|
|
31
|
+
const unit = match[2];
|
|
32
|
+
|
|
33
|
+
switch (unit) {
|
|
34
|
+
case "m":
|
|
35
|
+
return value * 60;
|
|
36
|
+
case "h":
|
|
37
|
+
return value * 60 * 60;
|
|
38
|
+
case "d":
|
|
39
|
+
return value * 60 * 60 * 24;
|
|
40
|
+
default:
|
|
41
|
+
return 0;
|
|
42
|
+
}
|
|
43
43
|
};
|
|
44
44
|
|
|
45
45
|
export async function refreshToken(req: NextRequest) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const res = NextResponse.next();
|
|
65
|
-
res.cookies.set('access_token', response.accessToken, {
|
|
66
|
-
httpOnly: true,
|
|
67
|
-
secure: process.env.NODE_ENV === 'production',
|
|
68
|
-
sameSite: 'strict',
|
|
69
|
-
path: '/',
|
|
70
|
-
maxAge: convertToSeconds(response.accessTokenExpiresIn ?? ''),
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
if (!process.env.AUTOEXPIRE_REFRESH_TOKEN) {
|
|
74
|
-
if (process.env.NODE_ENV === 'development') {
|
|
75
|
-
console.log('refresh token is not expired and updating expires in');
|
|
76
|
-
}
|
|
77
|
-
res.cookies.set('refresh_token', response.refreshToken, {
|
|
78
|
-
httpOnly: true,
|
|
79
|
-
secure: process.env.NODE_ENV === 'production',
|
|
80
|
-
sameSite: 'strict',
|
|
81
|
-
path: '/',
|
|
82
|
-
maxAge: convertToSeconds(response.refreshTokenExpiresIn ?? ''),
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
return res;
|
|
87
|
-
} catch (error) {
|
|
88
|
-
throw new Error(error);
|
|
46
|
+
try {
|
|
47
|
+
const refreshToken = req.cookies.get("refresh_token")?.value;
|
|
48
|
+
if (!refreshToken) {
|
|
49
|
+
throw new Error("Token refresh failed, no refresh token");
|
|
50
|
+
}
|
|
51
|
+
const response: TokenResponse = await post(
|
|
52
|
+
`${API_URL}/nestauth/refresh-token`,
|
|
53
|
+
{
|
|
54
|
+
refresh_token: refreshToken,
|
|
55
|
+
},
|
|
56
|
+
{},
|
|
57
|
+
false,
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
if (!response || !response.accessToken || !response.refreshToken) {
|
|
61
|
+
throw new Error("Token refresh failed, no response from api");
|
|
89
62
|
}
|
|
63
|
+
|
|
64
|
+
const res = NextResponse.next();
|
|
65
|
+
res.cookies.set("access_token", response.accessToken, {
|
|
66
|
+
httpOnly: true,
|
|
67
|
+
secure: process.env.NODE_ENV === "production",
|
|
68
|
+
sameSite: "lax",
|
|
69
|
+
path: "/",
|
|
70
|
+
maxAge: convertToSeconds(response.accessTokenExpiresIn ?? ""),
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
if (!process.env.AUTOEXPIRE_REFRESH_TOKEN) {
|
|
74
|
+
if (process.env.NODE_ENV === "development") {
|
|
75
|
+
console.log("refresh token is not expired and updating expires in");
|
|
76
|
+
}
|
|
77
|
+
res.cookies.set("refresh_token", response.refreshToken, {
|
|
78
|
+
httpOnly: true,
|
|
79
|
+
secure: process.env.NODE_ENV === "production",
|
|
80
|
+
sameSite: "lax",
|
|
81
|
+
path: "/",
|
|
82
|
+
maxAge: convertToSeconds(response.refreshTokenExpiresIn ?? ""),
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return res;
|
|
87
|
+
} catch (error: any) {
|
|
88
|
+
throw new Error(error?.message ?? "Token refresh failed");
|
|
89
|
+
}
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
export async function authenticate(params: any) {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
sameSite: 'strict',
|
|
117
|
-
path: '/',
|
|
118
|
-
maxAge: convertToSeconds(response.accessTokenExpiresIn ?? ''),
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
cookieStore.set('refresh_token', response.refreshToken, {
|
|
122
|
-
httpOnly: true,
|
|
123
|
-
secure: process.env.NODE_ENV === 'production',
|
|
124
|
-
sameSite: 'strict',
|
|
125
|
-
path: '/',
|
|
126
|
-
maxAge: convertToSeconds(response.refreshTokenExpiresIn ?? ''),
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
return response;
|
|
130
|
-
} catch (error) {
|
|
131
|
-
// console.log(error);
|
|
132
|
-
throw new Error(error);
|
|
93
|
+
try {
|
|
94
|
+
const response: TokenResponse = await post(
|
|
95
|
+
`${API_URL}/nestauth/login`,
|
|
96
|
+
params,
|
|
97
|
+
{},
|
|
98
|
+
false,
|
|
99
|
+
);
|
|
100
|
+
if (
|
|
101
|
+
!response ||
|
|
102
|
+
!response.accessToken ||
|
|
103
|
+
!response.refreshToken ||
|
|
104
|
+
!response.accessTokenExpiresIn ||
|
|
105
|
+
!response.refreshTokenExpiresIn
|
|
106
|
+
) {
|
|
107
|
+
throw new Error(
|
|
108
|
+
"Login failed" +
|
|
109
|
+
" API URL: " +
|
|
110
|
+
API_URL +
|
|
111
|
+
" params: " +
|
|
112
|
+
JSON.stringify(params) +
|
|
113
|
+
" response: " +
|
|
114
|
+
JSON.stringify(response),
|
|
115
|
+
);
|
|
133
116
|
}
|
|
117
|
+
const cookieStore = await cookies();
|
|
118
|
+
cookieStore.set("access_token", response.accessToken, {
|
|
119
|
+
httpOnly: true,
|
|
120
|
+
secure: process.env.NODE_ENV === "production",
|
|
121
|
+
sameSite: "lax",
|
|
122
|
+
path: "/",
|
|
123
|
+
maxAge: convertToSeconds(response.accessTokenExpiresIn ?? ""),
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
cookieStore.set("refresh_token", response.refreshToken, {
|
|
127
|
+
httpOnly: true,
|
|
128
|
+
secure: process.env.NODE_ENV === "production",
|
|
129
|
+
sameSite: "lax",
|
|
130
|
+
path: "/",
|
|
131
|
+
maxAge: convertToSeconds(response.refreshTokenExpiresIn ?? ""),
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
return response;
|
|
135
|
+
} catch (error: any) {
|
|
136
|
+
// console.log(error);
|
|
137
|
+
throw new Error(error?.message ?? "Login failed");
|
|
138
|
+
}
|
|
134
139
|
}
|
|
135
140
|
|
|
136
141
|
export async function getAccessToken() {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
142
|
+
const cookieStore = await cookies();
|
|
143
|
+
const access_token = cookieStore.get("access_token")?.value;
|
|
144
|
+
return access_token ?? null;
|
|
140
145
|
}
|
|
141
146
|
|
|
142
147
|
export async function getRefreshToken() {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
148
|
+
const cookieStore = await cookies();
|
|
149
|
+
const refresh_token = cookieStore.get("refresh_token")?.value;
|
|
150
|
+
return refresh_token ?? null;
|
|
146
151
|
}
|
|
147
152
|
|
|
148
153
|
export async function checkAuth() {
|
|
149
|
-
|
|
150
|
-
|
|
154
|
+
const accessToken = await getAccessToken();
|
|
155
|
+
return !!accessToken;
|
|
151
156
|
}
|
|
152
157
|
|
|
153
158
|
export async function getUserInfo() {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
159
|
+
const accessToken = await getAccessToken();
|
|
160
|
+
if (!accessToken) {
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
try {
|
|
164
|
+
const decoded = jwtDecode(accessToken) as User;
|
|
165
|
+
return decoded;
|
|
166
|
+
} catch (error) {
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
164
169
|
}
|
|
165
170
|
|
|
166
171
|
export async function logout() {
|
|
167
|
-
|
|
168
|
-
|
|
172
|
+
(await cookies()).delete("access_token");
|
|
173
|
+
(await cookies()).delete("refresh_token");
|
|
169
174
|
}
|
|
170
175
|
|
|
171
|
-
export async function get(
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
}
|
|
192
|
-
|
|
176
|
+
export async function get(
|
|
177
|
+
url: string,
|
|
178
|
+
params: any = {},
|
|
179
|
+
headers: any = {},
|
|
180
|
+
secured = true,
|
|
181
|
+
) {
|
|
182
|
+
const headerData: Record<string, string> = {
|
|
183
|
+
Authorization: "",
|
|
184
|
+
...headers,
|
|
185
|
+
};
|
|
186
|
+
if (secured) {
|
|
187
|
+
const accessToken = await getAccessToken();
|
|
188
|
+
headerData.Authorization = "Bearer " + accessToken;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
try {
|
|
192
|
+
const response = await axios.get(url, {
|
|
193
|
+
headers: headerData,
|
|
194
|
+
params: params,
|
|
195
|
+
withCredentials: true,
|
|
196
|
+
});
|
|
197
|
+
if (response.status === 200 || response.status === 201) {
|
|
198
|
+
return response.data;
|
|
193
199
|
}
|
|
200
|
+
return null;
|
|
201
|
+
} catch (error) {
|
|
202
|
+
return error;
|
|
203
|
+
}
|
|
194
204
|
}
|
|
195
205
|
|
|
196
|
-
export async function post(
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
}
|
|
215
|
-
|
|
206
|
+
export async function post(
|
|
207
|
+
url: string,
|
|
208
|
+
data: any = {},
|
|
209
|
+
headers: any = {},
|
|
210
|
+
secured = true,
|
|
211
|
+
) {
|
|
212
|
+
const headerData: Record<string, string> = {
|
|
213
|
+
Authorization: "",
|
|
214
|
+
...headers,
|
|
215
|
+
};
|
|
216
|
+
if (secured) {
|
|
217
|
+
const accessToken = await getAccessToken();
|
|
218
|
+
headerData.Authorization = "Bearer " + accessToken;
|
|
219
|
+
}
|
|
220
|
+
try {
|
|
221
|
+
const response = await axios.post(url, data, {
|
|
222
|
+
headers: headerData,
|
|
223
|
+
withCredentials: true,
|
|
224
|
+
});
|
|
225
|
+
if (response.status === 200 || response.status === 201) {
|
|
226
|
+
return response.data;
|
|
216
227
|
}
|
|
228
|
+
return null;
|
|
229
|
+
} catch (error) {
|
|
230
|
+
return error;
|
|
231
|
+
}
|
|
217
232
|
}
|