@civic/auth 0.0.1-beta.19 → 0.0.1-beta.2
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/README.md +0 -26
- package/dist/chunk-5NUJ7LFF.mjs +17 -0
- package/dist/chunk-5NUJ7LFF.mjs.map +1 -0
- package/dist/chunk-CRTRMMJ7.js.map +1 -1
- package/dist/chunk-KS7ERXGZ.js +481 -0
- package/dist/chunk-KS7ERXGZ.js.map +1 -0
- package/dist/chunk-NINRO7GS.js +209 -0
- package/dist/chunk-NINRO7GS.js.map +1 -0
- package/dist/chunk-NXBKSUKI.mjs +481 -0
- package/dist/chunk-NXBKSUKI.mjs.map +1 -0
- package/dist/chunk-T7HUHQ3J.mjs +209 -0
- package/dist/chunk-T7HUHQ3J.mjs.map +1 -0
- package/dist/chunk-WZLC5B4C.js +17 -0
- package/dist/chunk-WZLC5B4C.js.map +1 -0
- package/dist/index-DoDoIY_K.d.mts +79 -0
- package/dist/index-DoDoIY_K.d.ts +79 -0
- package/dist/index.css +70 -63
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +1 -3
- package/dist/index.d.ts +1 -3
- package/dist/index.js +1 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +0 -1
- package/dist/nextjs.d.mts +15 -42
- package/dist/nextjs.d.ts +15 -42
- package/dist/nextjs.js +180 -156
- package/dist/nextjs.js.map +1 -1
- package/dist/nextjs.mjs +177 -153
- package/dist/nextjs.mjs.map +1 -1
- package/dist/react.d.mts +81 -31
- package/dist/react.d.ts +81 -31
- package/dist/react.js +634 -35
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +664 -65
- package/dist/react.mjs.map +1 -1
- package/dist/server.d.mts +34 -14
- package/dist/server.d.ts +34 -14
- package/dist/server.js +185 -4
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +191 -10
- package/dist/server.mjs.map +1 -1
- package/package.json +17 -26
- package/dist/AuthProvider-Bj_Prt1x.d.ts +0 -21
- package/dist/AuthProvider-DUAoX4G9.d.mts +0 -21
- package/dist/UserProvider-CMLaYOUD.d.ts +0 -16
- package/dist/UserProvider-Cbm8MZkJ.d.mts +0 -16
- package/dist/chunk-5UQQYXCX.js +0 -1
- package/dist/chunk-5UQQYXCX.js.map +0 -1
- package/dist/chunk-BFESCRFK.mjs +0 -118
- package/dist/chunk-BFESCRFK.mjs.map +0 -1
- package/dist/chunk-CBQ3HKRV.mjs +0 -599
- package/dist/chunk-CBQ3HKRV.mjs.map +0 -1
- package/dist/chunk-CZ3AVCKD.js +0 -171
- package/dist/chunk-CZ3AVCKD.js.map +0 -1
- package/dist/chunk-DJFTZS4P.js +0 -118
- package/dist/chunk-DJFTZS4P.js.map +0 -1
- package/dist/chunk-HTTTZ2BP.mjs +0 -223
- package/dist/chunk-HTTTZ2BP.mjs.map +0 -1
- package/dist/chunk-O2SODTR3.js +0 -599
- package/dist/chunk-O2SODTR3.js.map +0 -1
- package/dist/chunk-O6DPCPRH.js +0 -223
- package/dist/chunk-O6DPCPRH.js.map +0 -1
- package/dist/chunk-PMJAV4JJ.mjs +0 -1
- package/dist/chunk-PMJAV4JJ.mjs.map +0 -1
- package/dist/chunk-UADVRCHY.mjs +0 -710
- package/dist/chunk-UADVRCHY.mjs.map +0 -1
- package/dist/chunk-VJVRFKDH.js +0 -710
- package/dist/chunk-VJVRFKDH.js.map +0 -1
- package/dist/chunk-X3FQBE22.mjs +0 -171
- package/dist/chunk-X3FQBE22.mjs.map +0 -1
- package/dist/nextjs/client.css +0 -335
- package/dist/nextjs/client.css.map +0 -1
- package/dist/nextjs/client.d.mts +0 -12
- package/dist/nextjs/client.d.ts +0 -12
- package/dist/nextjs/client.js +0 -179
- package/dist/nextjs/client.js.map +0 -1
- package/dist/nextjs/client.mjs +0 -179
- package/dist/nextjs/client.mjs.map +0 -1
- package/dist/storage-B2eAQNdv.d.ts +0 -25
- package/dist/storage-BJPUpxhm.d.mts +0 -25
- package/dist/types-Bqm9OCZN.d.mts +0 -22
- package/dist/types-Bqm9OCZN.d.ts +0 -22
- package/dist/types-HdCjGldB.d.mts +0 -58
- package/dist/types-HdCjGldB.d.ts +0 -58
package/dist/nextjs.js
CHANGED
|
@@ -4,26 +4,10 @@
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
7
|
+
var _chunkKS7ERXGZjs = require('./chunk-KS7ERXGZ.js');
|
|
7
8
|
|
|
8
|
-
var _chunkDJFTZS4Pjs = require('./chunk-DJFTZS4P.js');
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
var _chunkCZ3AVCKDjs = require('./chunk-CZ3AVCKD.js');
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
var _chunkO6DPCPRHjs = require('./chunk-O6DPCPRH.js');
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
var _chunkO2SODTR3js = require('./chunk-O2SODTR3.js');
|
|
10
|
+
var _chunkNINRO7GSjs = require('./chunk-NINRO7GS.js');
|
|
27
11
|
|
|
28
12
|
|
|
29
13
|
|
|
@@ -31,18 +15,12 @@ var _chunkO2SODTR3js = require('./chunk-O2SODTR3.js');
|
|
|
31
15
|
var _chunkCRTRMMJ7js = require('./chunk-CRTRMMJ7.js');
|
|
32
16
|
|
|
33
17
|
// src/nextjs/GetUser.ts
|
|
34
|
-
var
|
|
18
|
+
var _headersjs = require('next/headers.js');
|
|
19
|
+
var getUser = () => {
|
|
35
20
|
var _a;
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const user = userSession.get();
|
|
40
|
-
if (!user || !tokens) return null;
|
|
41
|
-
return _chunkCRTRMMJ7js.__spreadProps.call(void 0, _chunkCRTRMMJ7js.__spreadValues.call(void 0, {}, user), {
|
|
42
|
-
idToken: tokens.id_token,
|
|
43
|
-
accessToken: tokens.access_token,
|
|
44
|
-
refreshToken: (_a = tokens.refresh_token) != null ? _a : ""
|
|
45
|
-
});
|
|
21
|
+
const user = (_a = _headersjs.cookies.call(void 0, ).get("user")) == null ? void 0 : _a.value;
|
|
22
|
+
if (!user) return null;
|
|
23
|
+
return JSON.parse(user);
|
|
46
24
|
};
|
|
47
25
|
|
|
48
26
|
// src/nextjs/middleware.ts
|
|
@@ -62,9 +40,9 @@ var matchesGlobs = (pathname, patterns) => patterns.some((pattern) => {
|
|
|
62
40
|
return matchGlob(pathname, pattern);
|
|
63
41
|
});
|
|
64
42
|
var applyAuth = (authConfig, request) => _chunkCRTRMMJ7js.__async.call(void 0, void 0, null, function* () {
|
|
65
|
-
const authConfigWithDefaults =
|
|
43
|
+
const authConfigWithDefaults = _chunkKS7ERXGZjs.resolveAuthConfig.call(void 0, authConfig);
|
|
66
44
|
const isAuthenticated = !!request.cookies.get("id_token");
|
|
67
|
-
if (request.nextUrl.pathname === authConfigWithDefaults.loginUrl
|
|
45
|
+
if (request.nextUrl.pathname === authConfigWithDefaults.loginUrl) {
|
|
68
46
|
console.log("\u2192 Skipping auth check - this is the login URL");
|
|
69
47
|
return void 0;
|
|
70
48
|
}
|
|
@@ -77,14 +55,14 @@ var applyAuth = (authConfig, request) => _chunkCRTRMMJ7js.__async.call(void 0, v
|
|
|
77
55
|
return void 0;
|
|
78
56
|
}
|
|
79
57
|
if (!isAuthenticated) {
|
|
58
|
+
console.log("\u2192 No valid token found - redirecting to login");
|
|
80
59
|
const loginUrl = new URL(authConfigWithDefaults.loginUrl, request.url);
|
|
81
|
-
console.log("\u2192 No valid token found - redirecting to login", loginUrl);
|
|
82
60
|
return _serverjs.NextResponse.redirect(loginUrl);
|
|
83
61
|
}
|
|
84
62
|
console.log("\u2192 Auth check passed");
|
|
85
63
|
return void 0;
|
|
86
64
|
});
|
|
87
|
-
var authMiddleware = (authConfig =
|
|
65
|
+
var authMiddleware = (authConfig = _chunkKS7ERXGZjs.defaultAuthConfig) => (request) => _chunkCRTRMMJ7js.__async.call(void 0, void 0, null, function* () {
|
|
88
66
|
const response = yield applyAuth(authConfig, request);
|
|
89
67
|
if (response) return response;
|
|
90
68
|
return _serverjs.NextResponse.next();
|
|
@@ -109,8 +87,130 @@ function auth(authConfig = {}) {
|
|
|
109
87
|
// src/nextjs/routeHandler.ts
|
|
110
88
|
|
|
111
89
|
var _cachejs = require('next/cache.js');
|
|
112
|
-
|
|
113
|
-
|
|
90
|
+
|
|
91
|
+
// src/nextjs/NextJSSessionService.ts
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
// src/nextjs/cookies.ts
|
|
95
|
+
var createTokenCookies = (response, sessionData, config) => {
|
|
96
|
+
var _a, _b;
|
|
97
|
+
const maxAge = (_a = sessionData.expiresIn) != null ? _a : 3600;
|
|
98
|
+
const cookieOptions = _chunkCRTRMMJ7js.__spreadProps.call(void 0, _chunkCRTRMMJ7js.__spreadValues.call(void 0, {}, (_b = config.cookies) == null ? void 0 : _b.tokens), {
|
|
99
|
+
maxAge
|
|
100
|
+
});
|
|
101
|
+
if (sessionData.accessToken) {
|
|
102
|
+
response.cookies.set("access_token", sessionData.accessToken, _chunkCRTRMMJ7js.__spreadProps.call(void 0, _chunkCRTRMMJ7js.__spreadValues.call(void 0, {}, cookieOptions), {
|
|
103
|
+
httpOnly: true
|
|
104
|
+
}));
|
|
105
|
+
}
|
|
106
|
+
if (sessionData.idToken) {
|
|
107
|
+
response.cookies.set("id_token", sessionData.idToken, _chunkCRTRMMJ7js.__spreadProps.call(void 0, _chunkCRTRMMJ7js.__spreadValues.call(void 0, {}, cookieOptions), {
|
|
108
|
+
httpOnly: true
|
|
109
|
+
}));
|
|
110
|
+
}
|
|
111
|
+
if (sessionData.refreshToken) {
|
|
112
|
+
response.cookies.set("refresh_token", sessionData.refreshToken, _chunkCRTRMMJ7js.__spreadProps.call(void 0, _chunkCRTRMMJ7js.__spreadValues.call(void 0, {}, cookieOptions), {
|
|
113
|
+
httpOnly: true
|
|
114
|
+
}));
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
var createUserInfoCookie = (response, user, sessionData, config) => {
|
|
118
|
+
var _a, _b, _c;
|
|
119
|
+
if (!user) {
|
|
120
|
+
response.cookies.set("user", "", _chunkCRTRMMJ7js.__spreadProps.call(void 0, _chunkCRTRMMJ7js.__spreadValues.call(void 0, {}, (_a = config.cookies) == null ? void 0 : _a.user), {
|
|
121
|
+
maxAge: 0
|
|
122
|
+
}));
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
const maxAge = (_b = sessionData.expiresIn) != null ? _b : 3600;
|
|
126
|
+
const frontendUser = _chunkCRTRMMJ7js.__spreadValues.call(void 0, {}, user);
|
|
127
|
+
response.cookies.set("user", JSON.stringify(frontendUser), _chunkCRTRMMJ7js.__spreadProps.call(void 0, _chunkCRTRMMJ7js.__spreadValues.call(void 0, {}, (_c = config.cookies) == null ? void 0 : _c.user), {
|
|
128
|
+
maxAge
|
|
129
|
+
}));
|
|
130
|
+
};
|
|
131
|
+
var clearAuthCookies = (response, config) => {
|
|
132
|
+
var _a, _b;
|
|
133
|
+
const clearOptions = _chunkCRTRMMJ7js.__spreadProps.call(void 0, _chunkCRTRMMJ7js.__spreadValues.call(void 0, {}, (_a = config.cookies) == null ? void 0 : _a.tokens), {
|
|
134
|
+
maxAge: 0
|
|
135
|
+
});
|
|
136
|
+
response.cookies.set("access_token", "", clearOptions);
|
|
137
|
+
response.cookies.set("id_token", "", clearOptions);
|
|
138
|
+
response.cookies.set("refresh_token", "", clearOptions);
|
|
139
|
+
response.cookies.set("codeVerifier", "", clearOptions);
|
|
140
|
+
response.cookies.set("user", "", _chunkCRTRMMJ7js.__spreadProps.call(void 0, _chunkCRTRMMJ7js.__spreadValues.call(void 0, {}, (_b = config.cookies) == null ? void 0 : _b.user), {
|
|
141
|
+
maxAge: 0
|
|
142
|
+
}));
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
// src/nextjs/NextJSSessionService.ts
|
|
146
|
+
var NextJSAuthSessionServiceImpl = class extends _chunkKS7ERXGZjs.AuthSessionServiceImpl {
|
|
147
|
+
constructor(authConfig, request, response, inputEndpoints) {
|
|
148
|
+
super(
|
|
149
|
+
authConfig.clientId,
|
|
150
|
+
authConfig.callbackUrl,
|
|
151
|
+
authConfig.oauthServer,
|
|
152
|
+
inputEndpoints
|
|
153
|
+
);
|
|
154
|
+
this.authConfig = authConfig;
|
|
155
|
+
this.request = request;
|
|
156
|
+
this.response = response;
|
|
157
|
+
this.inputEndpoints = inputEndpoints;
|
|
158
|
+
}
|
|
159
|
+
getCodeVerifier() {
|
|
160
|
+
const codeVerifier = _headersjs.cookies.call(void 0, ).get("codeVerifier");
|
|
161
|
+
if (!codeVerifier) {
|
|
162
|
+
throw new Error("Code verifier not found in cookies");
|
|
163
|
+
}
|
|
164
|
+
return codeVerifier.value;
|
|
165
|
+
}
|
|
166
|
+
getSessionData() {
|
|
167
|
+
var _a, _b, _c, _d;
|
|
168
|
+
const authenticated = _headersjs.cookies.call(void 0, ).get("access_token") !== void 0;
|
|
169
|
+
return {
|
|
170
|
+
authenticated,
|
|
171
|
+
codeVerifier: (_a = _headersjs.cookies.call(void 0, ).get("codeVerifier")) == null ? void 0 : _a.value,
|
|
172
|
+
accessToken: (_b = _headersjs.cookies.call(void 0, ).get("access_token")) == null ? void 0 : _b.value,
|
|
173
|
+
idToken: (_c = _headersjs.cookies.call(void 0, ).get("id_token")) == null ? void 0 : _c.value,
|
|
174
|
+
refreshToken: (_d = _headersjs.cookies.call(void 0, ).get("refresh_token")) == null ? void 0 : _d.value
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
updateSessionData(data) {
|
|
178
|
+
createTokenCookies(
|
|
179
|
+
this.response,
|
|
180
|
+
data,
|
|
181
|
+
this.authConfig
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
getUser() {
|
|
185
|
+
const userCookie = _headersjs.cookies.call(void 0, ).get("user");
|
|
186
|
+
if (!userCookie) return null;
|
|
187
|
+
return JSON.parse(userCookie.value);
|
|
188
|
+
}
|
|
189
|
+
setUser(user) {
|
|
190
|
+
createUserInfoCookie(
|
|
191
|
+
this.response,
|
|
192
|
+
user,
|
|
193
|
+
{ authenticated: true },
|
|
194
|
+
this.authConfig
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
clearSessionData() {
|
|
198
|
+
clearAuthCookies(this.response, this.authConfig);
|
|
199
|
+
}
|
|
200
|
+
// TODO fix the Window reference
|
|
201
|
+
loadAuthorizationUrl() {
|
|
202
|
+
throw new Error("Not implemented");
|
|
203
|
+
}
|
|
204
|
+
logout() {
|
|
205
|
+
return _chunkCRTRMMJ7js.__async.call(void 0, this, null, function* () {
|
|
206
|
+
this.updateSessionData({ authenticated: false });
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
// src/nextjs/routeHandler.ts
|
|
212
|
+
var _oauth2 = require('oslo/oauth2');
|
|
213
|
+
var logger = _chunkKS7ERXGZjs.loggers.nextjs.handlers.auth;
|
|
114
214
|
var AuthError = class extends Error {
|
|
115
215
|
constructor(message, status = 401) {
|
|
116
216
|
super(message);
|
|
@@ -118,123 +218,49 @@ var AuthError = class extends Error {
|
|
|
118
218
|
this.name = "AuthError";
|
|
119
219
|
}
|
|
120
220
|
};
|
|
121
|
-
function handleChallenge(
|
|
221
|
+
function handleChallenge() {
|
|
122
222
|
return _chunkCRTRMMJ7js.__async.call(void 0, this, null, function* () {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
const
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
const cookieStorage = new (0, _chunkDJFTZS4Pjs.NextjsCookieStorage)(resolvedConfigs.cookies.tokens);
|
|
134
|
-
const callbackUrl = _chunkDJFTZS4Pjs.resolveCallbackUrl.call(void 0, resolvedConfigs, request.url);
|
|
135
|
-
try {
|
|
136
|
-
yield _chunkO6DPCPRHjs.resolveOAuthAccessCode.call(void 0, code, state, cookieStorage, _chunkCRTRMMJ7js.__spreadProps.call(void 0, _chunkCRTRMMJ7js.__spreadValues.call(void 0, {}, resolvedConfigs), {
|
|
137
|
-
redirectUrl: callbackUrl
|
|
138
|
-
}));
|
|
139
|
-
} catch (error) {
|
|
140
|
-
logger.error("Token exchange failed:", error);
|
|
141
|
-
throw new AuthError("Failed to authenticate user", 401);
|
|
142
|
-
}
|
|
143
|
-
const user = yield _chunkO2SODTR3js.getUser.call(void 0, cookieStorage);
|
|
144
|
-
if (!user) {
|
|
145
|
-
throw new AuthError("Failed to get user info", 401);
|
|
146
|
-
}
|
|
147
|
-
const clientStorage = new (0, _chunkDJFTZS4Pjs.NextjsClientStorage)();
|
|
148
|
-
const userSession = new (0, _chunkO2SODTR3js.GenericUserSession)(clientStorage);
|
|
149
|
-
userSession.set(user);
|
|
223
|
+
const codeVerifier = _oauth2.generateCodeVerifier.call(void 0, );
|
|
224
|
+
console.log("handleChallenge codeVerifier", codeVerifier);
|
|
225
|
+
const challenge = yield _chunkNINRO7GSjs.deriveCodeChallenge.call(void 0, codeVerifier);
|
|
226
|
+
const response = _serverjs.NextResponse.json({ status: "success", challenge });
|
|
227
|
+
response.cookies.set("codeVerifier", codeVerifier, {
|
|
228
|
+
httpOnly: true,
|
|
229
|
+
secure: true,
|
|
230
|
+
sameSite: "strict"
|
|
231
|
+
});
|
|
232
|
+
return response;
|
|
150
233
|
});
|
|
151
234
|
}
|
|
152
235
|
function handleCallback(request, config) {
|
|
153
236
|
return _chunkCRTRMMJ7js.__async.call(void 0, this, null, function* () {
|
|
154
|
-
const resolvedConfigs = _chunkCZ3AVCKDjs.resolveAuthConfig.call(void 0, config);
|
|
155
|
-
console.log("handleCallback", { request, resolvedConfigs });
|
|
156
237
|
const code = request.nextUrl.searchParams.get("code");
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
requestUrl: request.url,
|
|
173
|
-
configCallbackUrl: resolvedConfigs.callbackUrl
|
|
174
|
-
}
|
|
175
|
-
);
|
|
176
|
-
const requestUrl = new URL(request.url);
|
|
177
|
-
const fetchUrl = `${resolvedConfigs.callbackUrl}?${requestUrl.searchParams.toString()}&sameDomainServerTokenExchange=true`;
|
|
178
|
-
response2 = new (0, _serverjs.NextResponse)(
|
|
179
|
-
`<html>
|
|
180
|
-
<body>
|
|
181
|
-
<span style="display:none">
|
|
182
|
-
<script>
|
|
183
|
-
window.onload = function () {
|
|
184
|
-
fetch('${fetchUrl}').then((response) => {
|
|
185
|
-
response.json().then((jsonResponse) => {
|
|
186
|
-
console.log('fetch jsonResponse', jsonResponse);
|
|
187
|
-
if (jsonResponse.redirectUrl) {
|
|
188
|
-
console.log('handleCallback serverTokenExchangeFromState, redirecting');
|
|
189
|
-
window.location.href = jsonResponse.redirectUrl;
|
|
190
|
-
}
|
|
191
|
-
});
|
|
192
|
-
});
|
|
193
|
-
};
|
|
194
|
-
</script>
|
|
195
|
-
</span>
|
|
196
|
-
</body>
|
|
197
|
-
</html>
|
|
198
|
-
`
|
|
199
|
-
);
|
|
200
|
-
}
|
|
201
|
-
response2.headers.set("Content-Type", "text/html; charset=utf-8");
|
|
202
|
-
console.log(
|
|
203
|
-
`handleCallback no code_verifier found, returning ${_chunkO2SODTR3js.TOKEN_EXCHANGE_TRIGGER_TEXT}`
|
|
204
|
-
);
|
|
205
|
-
return response2;
|
|
206
|
-
}
|
|
207
|
-
yield performTokenExchangeAndSetCookies(
|
|
208
|
-
request,
|
|
209
|
-
resolvedConfigs,
|
|
210
|
-
code,
|
|
211
|
-
state
|
|
212
|
-
);
|
|
213
|
-
if (request.url.includes("sameDomainServerTokenExchange=true")) {
|
|
214
|
-
console.log(
|
|
215
|
-
"handleCallback sameDomainServerTokenExchange = true, returnining redirectUrl",
|
|
216
|
-
resolvedConfigs.appUrl
|
|
217
|
-
);
|
|
218
|
-
return _serverjs.NextResponse.json({
|
|
219
|
-
status: "success",
|
|
220
|
-
redirectUrl: resolvedConfigs.appUrl
|
|
221
|
-
});
|
|
222
|
-
}
|
|
223
|
-
if (_chunkO2SODTR3js.serverTokenExchangeFromState.call(void 0, state)) {
|
|
224
|
-
console.log(
|
|
225
|
-
"handleCallback serverTokenExchangeFromState, redirect to config.appUrl",
|
|
226
|
-
resolvedConfigs.appUrl
|
|
238
|
+
if (!code) throw new AuthError("Missing authorization code");
|
|
239
|
+
try {
|
|
240
|
+
const response = new (0, _serverjs.NextResponse)(`<html></html>`);
|
|
241
|
+
response.headers.set("Content-Type", "text/html; charset=utf-8");
|
|
242
|
+
const resolvedConfigs = _chunkKS7ERXGZjs.resolveAuthConfig.call(void 0, config);
|
|
243
|
+
const callbackUrl = new URL(
|
|
244
|
+
resolvedConfigs == null ? void 0 : resolvedConfigs.callbackUrl,
|
|
245
|
+
request.url
|
|
246
|
+
).toString();
|
|
247
|
+
const authService = getDefaultAuthSessionService(
|
|
248
|
+
_chunkCRTRMMJ7js.__spreadProps.call(void 0, _chunkCRTRMMJ7js.__spreadValues.call(void 0, {}, resolvedConfigs), {
|
|
249
|
+
callbackUrl
|
|
250
|
+
}),
|
|
251
|
+
request,
|
|
252
|
+
response
|
|
227
253
|
);
|
|
228
|
-
|
|
229
|
-
|
|
254
|
+
console.log("handleCallback authService", authService);
|
|
255
|
+
const tokens = yield authService.tokenExchange(request.nextUrl.toString());
|
|
256
|
+
if (!tokens.accessToken) {
|
|
257
|
+
throw new AuthError("Missing access token");
|
|
230
258
|
}
|
|
231
|
-
return
|
|
259
|
+
return response;
|
|
260
|
+
} catch (error) {
|
|
261
|
+
logger.error("Token exchange failed:", error);
|
|
262
|
+
throw new AuthError("Failed to authenticate user", 401);
|
|
232
263
|
}
|
|
233
|
-
const response = new (0, _serverjs.NextResponse)(
|
|
234
|
-
`<html><span style="display:none">${_chunkO2SODTR3js.TOKEN_EXCHANGE_SUCCESS_TEXT}</span></html>`
|
|
235
|
-
);
|
|
236
|
-
response.headers.set("Content-Type", "text/html; charset=utf-8");
|
|
237
|
-
return response;
|
|
238
264
|
});
|
|
239
265
|
}
|
|
240
266
|
var getAbsoluteRedirectPath = (redirectPath, currentBasePath) => {
|
|
@@ -245,17 +271,17 @@ var getAbsoluteRedirectPath = (redirectPath, currentBasePath) => {
|
|
|
245
271
|
};
|
|
246
272
|
function handleLogout(request, config) {
|
|
247
273
|
return _chunkCRTRMMJ7js.__async.call(void 0, this, null, function* () {
|
|
248
|
-
var _a
|
|
249
|
-
const resolvedConfigs =
|
|
274
|
+
var _a;
|
|
275
|
+
const resolvedConfigs = _chunkKS7ERXGZjs.resolveAuthConfig.call(void 0, config);
|
|
250
276
|
const defaultRedirectPath = (_a = resolvedConfigs.loginUrl) != null ? _a : "/";
|
|
251
277
|
const redirectTarget = new URL(request.url).searchParams.get("redirect") || defaultRedirectPath;
|
|
252
278
|
const isAbsoluteRedirect = /^(https?:\/\/|www\.).+/i.test(redirectTarget);
|
|
253
279
|
const finalRedirectUrl = getAbsoluteRedirectPath(
|
|
254
280
|
redirectTarget,
|
|
255
|
-
new URL(
|
|
281
|
+
new URL(request.url).origin
|
|
256
282
|
);
|
|
257
283
|
const response = _serverjs.NextResponse.redirect(finalRedirectUrl);
|
|
258
|
-
|
|
284
|
+
clearAuthCookies(response, resolvedConfigs);
|
|
259
285
|
try {
|
|
260
286
|
_cachejs.revalidatePath.call(void 0, isAbsoluteRedirect ? finalRedirectUrl : redirectTarget);
|
|
261
287
|
} catch (error) {
|
|
@@ -264,15 +290,18 @@ function handleLogout(request, config) {
|
|
|
264
290
|
return response;
|
|
265
291
|
});
|
|
266
292
|
}
|
|
293
|
+
var getDefaultAuthSessionService = (authConfig, request, response) => {
|
|
294
|
+
return new NextJSAuthSessionServiceImpl(authConfig, request, response);
|
|
295
|
+
};
|
|
267
296
|
var handler = (authConfig = {}) => (request) => _chunkCRTRMMJ7js.__async.call(void 0, void 0, null, function* () {
|
|
268
|
-
const config =
|
|
297
|
+
const config = _chunkKS7ERXGZjs.resolveAuthConfig.call(void 0, authConfig);
|
|
269
298
|
try {
|
|
270
299
|
const pathname = request.nextUrl.pathname;
|
|
271
300
|
const pathSegments = pathname.split("/");
|
|
272
301
|
const lastSegment = pathSegments[pathSegments.length - 1];
|
|
273
302
|
switch (lastSegment) {
|
|
274
303
|
case "challenge":
|
|
275
|
-
return yield handleChallenge(
|
|
304
|
+
return yield handleChallenge();
|
|
276
305
|
case "callback":
|
|
277
306
|
return yield handleCallback(request, config);
|
|
278
307
|
case "logout":
|
|
@@ -285,7 +314,7 @@ var handler = (authConfig = {}) => (request) => _chunkCRTRMMJ7js.__async.call(vo
|
|
|
285
314
|
const status = error instanceof AuthError ? error.status : 500;
|
|
286
315
|
const message = error instanceof Error ? error.message : "Authentication failed";
|
|
287
316
|
const response = _serverjs.NextResponse.json({ error: message }, { status });
|
|
288
|
-
|
|
317
|
+
clearAuthCookies(response, config);
|
|
289
318
|
return response;
|
|
290
319
|
}
|
|
291
320
|
});
|
|
@@ -296,10 +325,5 @@ var handler = (authConfig = {}) => (request) => _chunkCRTRMMJ7js.__async.call(vo
|
|
|
296
325
|
|
|
297
326
|
|
|
298
327
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
exports.NextjsClientStorage = _chunkDJFTZS4Pjs.NextjsClientStorage; exports.NextjsCookieStorage = _chunkDJFTZS4Pjs.NextjsCookieStorage; exports.auth = auth; exports.authMiddleware = authMiddleware; exports.clearAuthCookies = _chunkDJFTZS4Pjs.clearAuthCookies; exports.createCivicAuthPlugin = _chunkCZ3AVCKDjs.createCivicAuthPlugin; exports.createTokenCookies = _chunkDJFTZS4Pjs.createTokenCookies; exports.createUserInfoCookie = _chunkDJFTZS4Pjs.createUserInfoCookie; exports.getUser = getUser2; exports.handler = handler; exports.withAuth = withAuth;
|
|
328
|
+
exports.auth = auth; exports.authMiddleware = authMiddleware; exports.createCivicAuthPlugin = _chunkKS7ERXGZjs.createCivicAuthPlugin; exports.getUser = getUser; exports.handler = handler; exports.withAuth = withAuth;
|
|
305
329
|
//# sourceMappingURL=nextjs.js.map
|
package/dist/nextjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevincolgan/code/civic-auth/packages/civic-auth-client/dist/nextjs.js","../src/nextjs/GetUser.ts","../src/nextjs/middleware.ts","../src/nextjs/routeHandler.ts"],"names":["getUser","NextResponse","response"],"mappings":"AAAA;AACE;AACA;AACA;AACA;AACA;AACA;AACF,sDAA4B;AAC5B;AACE;AACA;AACA;AACA;AACF,sDAA4B;AAC5B;AACE;AACF,sDAA4B;AAC5B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACF,sDAA4B;AAC5B;AACE;AACA;AACA;AACF,sDAA4B;AAC5B;AACA;ACxBO,IAAMA,SAAAA,EAAU,CAAA,EAAA,GAAmB;AAR1C,EAAA,IAAA,EAAA;AASE,EAAA,MAAM,cAAA,EAAgB,IAAI,yCAAA,CAAoB,CAAA;AAC9C,EAAA,MAAM,YAAA,EAAc,IAAI,wCAAA,CAAmB,aAAa,CAAA;AACxD,EAAA,MAAM,OAAA,EAAS,6CAAA,aAA4B,CAAA;AAC3C,EAAA,MAAM,KAAA,EAAO,WAAA,CAAY,GAAA,CAAI,CAAA;AAC7B,EAAA,GAAA,CAAI,CAAC,KAAA,GAAQ,CAAC,MAAA,EAAQ,OAAO,IAAA;AAE7B,EAAA,OAAO,4CAAA,6CAAA,CAAA,CAAA,EACF,IAAA,CAAA,EADE;AAAA,IAEL,OAAA,EAAS,MAAA,CAAO,QAAA;AAAA,IAChB,WAAA,EAAa,MAAA,CAAO,YAAA;AAAA,IACpB,YAAA,EAAA,CAAc,GAAA,EAAA,MAAA,CAAO,aAAA,EAAA,GAAP,KAAA,EAAA,GAAA,EAAwB;AAAA,EACxC,CAAA,CAAA;AACF,CAAA;ADyBA;AACA;AE1BA,0CAA0C;AAC1C,4FAAsB;AAgBtB,IAAM,UAAA,EAAY,CAAC,QAAA,EAAkB,WAAA,EAAA,GAAwB;AAC3D,EAAA,MAAM,QAAA,EAAU,iCAAA,WAAqB,CAAA;AACrC,EAAA,OAAO,OAAA,CAAQ,QAAQ,CAAA;AACzB,CAAA;AAOA,IAAM,aAAA,EAAe,CAAC,QAAA,EAAkB,QAAA,EAAA,GACtC,QAAA,CAAS,IAAA,CAAK,CAAC,OAAA,EAAA,GAAY;AACzB,EAAA,GAAA,CAAI,CAAC,OAAA,EAAS,OAAO,KAAA;AACrB,EAAA,OAAA,CAAQ,GAAA,CAAI,UAAA,EAAY;AAAA,IACtB,OAAA;AAAA,IACA,QAAA;AAAA,IACA,KAAA,EAAO,SAAA,CAAU,QAAA,EAAU,OAAO;AAAA,EACpC,CAAC,CAAA;AACD,EAAA,OAAO,SAAA,CAAU,QAAA,EAAU,OAAO,CAAA;AACpC,CAAC,CAAA;AAGH,IAAM,UAAA,EAAY,CAChB,UAAA,EACA,OAAA,EAAA,GACsC,sCAAA,KAAA,CAAA,EAAA,IAAA,EAAA,QAAA,EAAA,CAAA,EAAA;AACtC,EAAA,MAAM,uBAAA,EAAyB,gDAAA,UAA4B,CAAA;AAE3D,EAAA,MAAM,gBAAA,EAAkB,CAAC,CAAC,OAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,UAAU,CAAA;AAGxD,EAAA,GAAA,CACE,OAAA,CAAQ,OAAA,CAAQ,SAAA,IAAa,sBAAA,CAAuB,SAAA,GACpD,OAAA,CAAQ,OAAA,IAAW,KAAA,EACnB;AACA,IAAA,OAAA,CAAQ,GAAA,CAAI,oDAA+C,CAAA;AAC3D,IAAA,OAAO,KAAA,CAAA;AAAA,EACT;AAEA,EAAA,GAAA,CAAI,CAAC,YAAA,CAAa,OAAA,CAAQ,OAAA,CAAQ,QAAA,EAAU,sBAAA,CAAuB,OAAO,CAAA,EAAG;AAC3E,IAAA,OAAA,CAAQ,GAAA,CAAI,2DAAsD,CAAA;AAClE,IAAA,OAAO,KAAA,CAAA;AAAA,EACT;AAEA,EAAA,GAAA,CAAI,YAAA,CAAa,OAAA,CAAQ,OAAA,CAAQ,QAAA,EAAU,sBAAA,CAAuB,OAAO,CAAA,EAAG;AAC1E,IAAA,OAAA,CAAQ,GAAA,CAAI,uDAAkD,CAAA;AAC9D,IAAA,OAAO,KAAA,CAAA;AAAA,EACT;AAGA,EAAA,GAAA,CAAI,CAAC,eAAA,EAAiB;AACpB,IAAA,MAAM,SAAA,EAAW,IAAI,GAAA,CAAI,sBAAA,CAAuB,QAAA,EAAU,OAAA,CAAQ,GAAG,CAAA;AACrE,IAAA,OAAA,CAAQ,GAAA,CAAI,oDAAA,EAAiD,QAAQ,CAAA;AACrE,IAAA,OAAO,sBAAA,CAAa,QAAA,CAAS,QAAQ,CAAA;AAAA,EACvC;AAEA,EAAA,OAAA,CAAQ,GAAA,CAAI,0BAAqB,CAAA;AACjC,EAAA,OAAO,KAAA,CAAA;AACT,CAAA,CAAA;AAUO,IAAM,eAAA,EACX,CAAC,WAAA,EAAa,kCAAA,EAAA,GACd,CAAO,OAAA,EAAA,GAAgD,sCAAA,KAAA,CAAA,EAAA,IAAA,EAAA,QAAA,EAAA,CAAA,EAAA;AACrD,EAAA,MAAM,SAAA,EAAW,MAAM,SAAA,CAAU,UAAA,EAAY,OAAO,CAAA;AACpD,EAAA,GAAA,CAAI,QAAA,EAAU,OAAO,QAAA;AAIrB,EAAA,OAAO,sBAAA,CAAa,IAAA,CAAK,CAAA;AAC3B,CAAA,CAAA;AAWK,SAAS,QAAA,CACd,UAAA,EACiD;AACjD,EAAA,OAAO,CAAO,OAAA,EAAA,GAAgD,sCAAA,IAAA,EAAA,IAAA,EAAA,QAAA,EAAA,CAAA,EAAA;AAC5D,IAAA,MAAM,SAAA,EAAW,MAAM,SAAA,CAAU,CAAC,CAAA,EAAG,OAAO,CAAA;AAC5C,IAAA,GAAA,CAAI,QAAA,EAAU,OAAO,QAAA;AAErB,IAAA,OAAO,UAAA,CAAW,OAAO,CAAA;AAAA,EAC3B,CAAA,CAAA;AACF;AAeO,SAAS,IAAA,CAAK,WAAA,EAAyB,CAAC,CAAA,EAAG;AAChD,EAAA,OAAO,CACL,UAAA,EAAA,GACsD;AACtD,IAAA,OAAO,CAAO,OAAA,EAAA,GAAgD,sCAAA,IAAA,EAAA,IAAA,EAAA,QAAA,EAAA,CAAA,EAAA;AAC5D,MAAA,MAAM,SAAA,EAAW,MAAM,SAAA,CAAU,UAAA,EAAY,OAAO,CAAA;AACpD,MAAA,GAAA,CAAI,QAAA,EAAU,OAAO,QAAA;AAErB,MAAA,OAAO,UAAA,CAAW,OAAO,CAAA;AAAA,IAC3B,CAAA,CAAA;AAAA,EACF,CAAA;AACF;AFtDA;AACA;AG5GA;AACA,wCAA+B;AAkB/B,4CAAwB;AAGxB,IAAM,OAAA,EAAS,wBAAA,CAAQ,MAAA,CAAO,QAAA,CAAS,IAAA;AAEvC,IAAM,UAAA,EAAN,MAAA,QAAwB,MAAM;AAAA,EAC5B,WAAA,CACE,OAAA,EACgB,OAAA,EAAiB,GAAA,EACjC;AACA,IAAA,KAAA,CAAM,OAAO,CAAA;AAFG,IAAA,IAAA,CAAA,OAAA,EAAA,MAAA;AAGhB,IAAA,IAAA,CAAK,KAAA,EAAO,WAAA;AAAA,EACd;AACF,CAAA;AAOA,SAAe,eAAA,CAAgB,MAAA,EAA2C;AAAA,EAAA,OAAA,sCAAA,IAAA,EAAA,IAAA,EAAA,QAAA,EAAA,CAAA,EAAA;AAvC1E,IAAA,IAAA,EAAA,EAAA,EAAA;AAwCE,IAAA,MAAM,cAAA,EAAgB,IAAI,yCAAA,CAAA,CAAoB,GAAA,EAAA,CAAA,GAAA,EAAA,MAAA,CAAO,OAAA,EAAA,GAAP,KAAA,EAAA,KAAA,EAAA,EAAA,EAAA,CAAgB,MAAA,EAAA,GAAhB,KAAA,EAAA,GAAA,EAA0B,CAAC,CAAC,CAAA;AAC1E,IAAA,MAAM,aAAA,EAAe,IAAI,qDAAA,CAAgC,aAAa,CAAA;AAEtE,IAAA,MAAM,UAAA,EAAY,MAAM,YAAA,CAAa,gBAAA,CAAiB,CAAA;AAEtD,IAAA,OAAOC,sBAAAA,CAAa,IAAA,CAAK,EAAE,MAAA,EAAQ,SAAA,EAAW,UAAU,CAAC,CAAA;AAAA,EAC3D,CAAA,CAAA;AAAA;AAEA,SAAe,iCAAA,CACb,OAAA,EACA,MAAA,EACA,IAAA,EACA,KAAA,EACA;AAAA,EAAA,OAAA,sCAAA,IAAA,EAAA,IAAA,EAAA,QAAA,EAAA,CAAA,EAAA;AACA,IAAA,MAAM,gBAAA,EAAkB,gDAAA,MAAwB,CAAA;AAChD,IAAA,MAAM,cAAA,EAAgB,IAAI,yCAAA,CAAoB,eAAA,CAAgB,OAAA,CAAQ,MAAM,CAAA;AAE5E,IAAA,MAAM,YAAA,EAAc,iDAAA,eAAmB,EAAiB,OAAA,CAAQ,GAAG,CAAA;AACnE,IAAA,IAAI;AACF,MAAA,MAAM,qDAAA,IAAuB,EAAM,KAAA,EAAO,aAAA,EAAe,4CAAA,6CAAA,CAAA,CAAA,EACpD,eAAA,CAAA,EADoD;AAAA,QAEvD,WAAA,EAAa;AAAA,MACf,CAAA,CAAC,CAAA;AAAA,IACH,EAAA,MAAA,CAAS,KAAA,EAAO;AACd,MAAA,MAAA,CAAO,KAAA,CAAM,wBAAA,EAA0B,KAAK,CAAA;AAC5C,MAAA,MAAM,IAAI,SAAA,CAAU,6BAAA,EAA+B,GAAG,CAAA;AAAA,IACxD;AAEA,IAAA,MAAM,KAAA,EAAO,MAAM,sCAAA,aAAqB,CAAA;AACxC,IAAA,GAAA,CAAI,CAAC,IAAA,EAAM;AACT,MAAA,MAAM,IAAI,SAAA,CAAU,yBAAA,EAA2B,GAAG,CAAA;AAAA,IACpD;AAEA,IAAA,MAAM,cAAA,EAAgB,IAAI,yCAAA,CAAoB,CAAA;AAC9C,IAAA,MAAM,YAAA,EAAc,IAAI,wCAAA,CAAmB,aAAa,CAAA;AACxD,IAAA,WAAA,CAAY,GAAA,CAAI,IAAI,CAAA;AAAA,EACtB,CAAA,CAAA;AAAA;AACA,SAAe,cAAA,CACb,OAAA,EACA,MAAA,EACuB;AAAA,EAAA,OAAA,sCAAA,IAAA,EAAA,IAAA,EAAA,QAAA,EAAA,CAAA,EAAA;AACvB,IAAA,MAAM,gBAAA,EAAkB,gDAAA,MAAwB,CAAA;AAChD,IAAA,OAAA,CAAQ,GAAA,CAAI,gBAAA,EAAkB,EAAE,OAAA,EAAS,gBAAgB,CAAC,CAAA;AAC1D,IAAA,MAAM,KAAA,EAAO,OAAA,CAAQ,OAAA,CAAQ,YAAA,CAAa,GAAA,CAAI,MAAM,CAAA;AACpD,IAAA,MAAM,MAAA,EAAQ,OAAA,CAAQ,OAAA,CAAQ,YAAA,CAAa,GAAA,CAAI,OAAO,EAAA,GAAK,EAAA;AAC3D,IAAA,GAAA,CAAI,CAAC,KAAA,GAAQ,CAAC,KAAA,EAAO,MAAM,IAAI,SAAA,CAAU,gBAAA,EAAkB,GAAG,CAAA;AAM9D,IAAA,OAAA,CAAQ,GAAA,CAAI,gBAAA,EAAkB,EAAE,IAAA,EAAM,KAAA,EAAO,OAAA,EAAS,gCAAA,EAAU,CAAC,CAAA;AACjE,IAAA,GAAA,CAAI,CAAC,OAAA,CAAQ,OAAA,CAAQ,GAAA,CAAA,iCAA4B,CAAA,EAAG;AAClD,MAAA,OAAA,CAAQ,GAAA,CAAI,uCAAA,EAAyC;AAAA,QACnD,KAAA;AAAA,QACA,mBAAA,EAAqB,2DAAA,CAA6B,EAAA;AACnD,MAAA;AACkBA,MAAAA;AACyB,QAAA;AAC5C,MAAA;AAKkD,MAAA;AACxC,QAAA;AACN,UAAA;AACA,UAAA;AACsB,YAAA;AACe,YAAA;AACrC,UAAA;AACF,QAAA;AAGsC,QAAA;AACa,QAAA;AACpCA,QAAAA;AACb,UAAA;AAAA;AAAA;AAAA;AAAA;AAKqC,mCAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAAA;AAevC,QAAA;AACF,MAAA;AACqC,MAAA;AAC7B,MAAA;AACN,QAAA;AACF,MAAA;AACOC,MAAAA;AACT,IAAA;AAEM,IAAA;AACJ,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACF,IAAA;AAEyB,IAAA;AACf,MAAA;AACN,QAAA;AACgB,QAAA;AAClB,MAAA;AACyB,MAAA;AACf,QAAA;AACqB,QAAA;AAC9B,MAAA;AACH,IAAA;AAGyC,IAAA;AAC/B,MAAA;AACN,QAAA;AACgB,QAAA;AAClB,MAAA;AAC6B,MAAA;AACX,QAAA;AAClB,MAAA;AACgD,MAAA;AAClD,IAAA;AAIqBD,IAAAA;AACiB,MAAA;AACtC,IAAA;AACqC,IAAA;AAC9B,IAAA;AACT,EAAA;AAAA;AAUE;AAGkD,EAAA;AACzC,IAAA;AACT,EAAA;AAC8C,EAAA;AAChD;AAKyB;AAAA,EAAA;AA7MzB,IAAA;AA8MkD,IAAA;AACJ,IAAA;AAErB,IAAA;AAC8B,IAAA;AAC5B,IAAA;AACvB,MAAA;AACkC,MAAA;AACpC,IAAA;AAEuC,IAAA;AAEhB,IAAA;AAEnB,IAAA;AACkC,MAAA;AACtB,IAAA;AACF,MAAA;AACd,IAAA;AAEO,IAAA;AACT,EAAA;AAAA;AAgByD;AACV,EAAA;AAEvC,EAAA;AAC+B,IAAA;AACM,IAAA;AACgB,IAAA;AAElC,IAAA;AACd,MAAA;AACgC,QAAA;AAChC,MAAA;AACwC,QAAA;AACxC,MAAA;AACsC,QAAA;AAC3C,MAAA;AACqD,QAAA;AACvD,IAAA;AACc,EAAA;AAC2B,IAAA;AAES,IAAA;AAEjB,IAAA;AAEmB,IAAA;AAE7B,IAAA;AAChB,IAAA;AACT,EAAA;AACF;AHkByD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"/Users/kevincolgan/code/civic-auth/packages/civic-auth-client/dist/nextjs.js","sourcesContent":[null,"/**\n * Used on the server-side to get the user object from the cookie\n */\nimport { User } from \"@/types\";\nimport { GenericUserSession } from \"@/shared/UserSession\";\nimport { NextjsClientStorage } from \"@/nextjs/cookies\";\nimport { retrieveTokens } from \"@/shared/util\";\n\nexport const getUser = (): User | null => {\n const clientStorage = new NextjsClientStorage();\n const userSession = new GenericUserSession(clientStorage);\n const tokens = retrieveTokens(clientStorage);\n const user = userSession.get();\n if (!user || !tokens) return null;\n\n return {\n ...user!,\n idToken: tokens.id_token,\n accessToken: tokens.access_token,\n refreshToken: tokens.refresh_token ?? \"\",\n } as User;\n};\n","/**\n * Authenticates the user on all requests by checking the token cookie\n *\n * Usage:\n * Option 1: use if no other middleware (e.g. no next-intl etc)\n * export default authMiddleware();\n *\n * Option 2: use if other middleware is needed - default auth config\n * export default withAuth((request) => {\n * console.log('in custom middleware', request.nextUrl.pathname);\n * return NextResponse.next();\n * })\n *\n * Option 3: use if other middleware is needed - specifying auth config\n * const withCivicAuth = auth({ loginUrl: '/login', include: ['/[.*]/user'] })\n * export default withCivicAuth((request) => {\n * console.log('in custom middleware', request.url);\n * return NextResponse.next();\n * })\n *\n */\nimport { NextRequest, NextResponse } from \"next/server.js\";\nimport picomatch from \"picomatch\";\nimport {\n AuthConfig,\n defaultAuthConfig,\n resolveAuthConfig,\n} from \"@/nextjs/config.js\";\n\ntype Middleware = (\n request: NextRequest,\n) => Promise<NextResponse> | NextResponse;\n\n// Matches globs:\n// Examples:\n// /user\n// /user/*\n// /user/**/info\nconst matchGlob = (pathname: string, globPattern: string) => {\n const matches = picomatch(globPattern);\n return matches(pathname);\n};\n\n// Matches globs:\n// Examples:\n// /user\n// /user/*\n// /user/**/info\nconst matchesGlobs = (pathname: string, patterns: string[]) =>\n patterns.some((pattern) => {\n if (!pattern) return false;\n console.log(\"matching\", {\n pattern,\n pathname,\n match: matchGlob(pathname, pattern),\n });\n return matchGlob(pathname, pattern);\n });\n\n// internal - used by all exported functions\nconst applyAuth = async (\n authConfig: AuthConfig,\n request: NextRequest,\n): Promise<NextResponse | undefined> => {\n const authConfigWithDefaults = resolveAuthConfig(authConfig);\n // Check for any valid auth token\n const isAuthenticated = !!request.cookies.get(\"id_token\");\n\n // skip auth check for redirect to login url\n if (\n request.nextUrl.pathname === authConfigWithDefaults.loginUrl &&\n request.method === \"GET\"\n ) {\n console.log(\"→ Skipping auth check - this is the login URL\");\n return undefined;\n }\n\n if (!matchesGlobs(request.nextUrl.pathname, authConfigWithDefaults.include)) {\n console.log(\"→ Skipping auth check - path not in include patterns\");\n return undefined;\n }\n\n if (matchesGlobs(request.nextUrl.pathname, authConfigWithDefaults.exclude)) {\n console.log(\"→ Skipping auth check - path in exclude patterns\");\n return undefined;\n }\n\n // Check for either token type\n if (!isAuthenticated) {\n const loginUrl = new URL(authConfigWithDefaults.loginUrl, request.url);\n console.log(\"→ No valid token found - redirecting to login\", loginUrl);\n return NextResponse.redirect(loginUrl);\n }\n\n console.log(\"→ Auth check passed\");\n return undefined;\n};\n\n/**\n *\n * Use this when auth is the only middleware you need.\n * Usage:\n *\n * export default authMiddleware({ loginUrl = '/login' }); // or just authMiddleware();\n *\n */\nexport const authMiddleware =\n (authConfig = defaultAuthConfig) =>\n async (request: NextRequest): Promise<NextResponse> => {\n const response = await applyAuth(authConfig, request);\n if (response) return response;\n\n // NextJS doesn't do middleware chaining yet, so this does not mean\n // \"call the next middleware\" - it means \"continue to the route handler\"\n return NextResponse.next();\n };\n\n/**\n * Usage:\n *\n * export default withAuth(async (request) => {\n * console.log('my middleware');\n * return NextResponse.next();\n * })\n */\n// use this when you have your own middleware to chain\nexport function withAuth(\n middleware: Middleware,\n): (request: NextRequest) => Promise<NextResponse> {\n return async (request: NextRequest): Promise<NextResponse> => {\n const response = await applyAuth({}, request);\n if (response) return response;\n\n return middleware(request);\n };\n}\n\n/**\n * Use this when you want to configure the middleware here (an alternative is to do it in the next.config file)\n *\n * Usage:\n *\n * const withAuth = auth({ loginUrl = '/login' }); // or just auth();\n *\n * export default withAuth(async (request) => {\n * console.log('my middleware');\n * return NextResponse.next();\n * })\n *\n */\nexport function auth(authConfig: AuthConfig = {}) {\n return (\n middleware: Middleware,\n ): ((request: NextRequest) => Promise<NextResponse>) => {\n return async (request: NextRequest): Promise<NextResponse> => {\n const response = await applyAuth(authConfig, request);\n if (response) return response;\n\n return middleware(request);\n };\n };\n}\n","import { NextRequest, NextResponse } from \"next/server.js\";\nimport { revalidatePath } from \"next/cache.js\";\nimport { AuthConfig, resolveAuthConfig } from \"@/nextjs/config.js\";\nimport { loggers } from \"@/lib/logger.js\";\nimport {\n clearAuthCookies,\n NextjsClientStorage,\n NextjsCookieStorage,\n} from \"@/nextjs/cookies.js\";\nimport { GenericPublicClientPKCEProducer } from \"@/services/PKCE.js\";\nimport { resolveOAuthAccessCode } from \"@/server/login.js\";\nimport { getUser } from \"@/shared/session.js\";\nimport { resolveCallbackUrl } from \"@/nextjs/utils.js\";\nimport { GenericUserSession } from \"@/shared/UserSession.js\";\nimport {\n TOKEN_EXCHANGE_SUCCESS_TEXT,\n TOKEN_EXCHANGE_TRIGGER_TEXT,\n} from \"@/constants.js\";\nimport { serverTokenExchangeFromState } from \"@/lib/oauth.js\";\nimport { cookies } from \"next/headers.js\";\nimport { CodeVerifier } from \"@/shared/types\";\n\nconst logger = loggers.nextjs.handlers.auth;\n\nclass AuthError extends Error {\n constructor(\n message: string,\n public readonly status: number = 401,\n ) {\n super(message);\n this.name = \"AuthError\";\n }\n}\n\n/**\n * create a code verifier and challenge for PKCE\n * saving the verifier in a cookie for later use\n * @returns {Promise<NextResponse>}\n */\nasync function handleChallenge(config: AuthConfig): Promise<NextResponse> {\n const cookieStorage = new NextjsCookieStorage(config.cookies?.tokens ?? {});\n const pkceProducer = new GenericPublicClientPKCEProducer(cookieStorage);\n\n const challenge = await pkceProducer.getCodeChallenge();\n\n return NextResponse.json({ status: \"success\", challenge });\n}\n\nasync function performTokenExchangeAndSetCookies(\n request: NextRequest,\n config: AuthConfig,\n code: string,\n state: string,\n) {\n const resolvedConfigs = resolveAuthConfig(config);\n const cookieStorage = new NextjsCookieStorage(resolvedConfigs.cookies.tokens);\n\n const callbackUrl = resolveCallbackUrl(resolvedConfigs, request.url);\n try {\n await resolveOAuthAccessCode(code, state, cookieStorage, {\n ...resolvedConfigs,\n redirectUrl: callbackUrl,\n });\n } catch (error) {\n logger.error(\"Token exchange failed:\", error);\n throw new AuthError(\"Failed to authenticate user\", 401);\n }\n\n const user = await getUser(cookieStorage);\n if (!user) {\n throw new AuthError(\"Failed to get user info\", 401);\n }\n\n const clientStorage = new NextjsClientStorage();\n const userSession = new GenericUserSession(clientStorage);\n userSession.set(user);\n}\nasync function handleCallback(\n request: NextRequest,\n config: AuthConfig,\n): Promise<NextResponse> {\n const resolvedConfigs = resolveAuthConfig(config);\n console.log(\"handleCallback\", { request, resolvedConfigs });\n const code = request.nextUrl.searchParams.get(\"code\");\n const state = request.nextUrl.searchParams.get(\"state\") || \"\";\n if (!code || !state) throw new AuthError(\"Bad parameters\", 400);\n\n // If we have a code_verifier cookie, we can do a token exchange.\n // Otherwise, just render an empty page.\n // The initial redirect back from the auth server does not send cookies, because the redirect is from a 3rd-party domain.\n // The client will make an additional call to this route with cookies included, at which point we do the token exchange.\n console.log(\"handleCallback\", { code, state, cookies: cookies() });\n if (!request.cookies.get(CodeVerifier.COOKIE_NAME)) {\n console.log(\"handleCallback no code_verifier found\", {\n state,\n serverTokenExchange: serverTokenExchangeFromState(`${state}`),\n });\n let response = new NextResponse(\n `<html><body><span style=\"display:none\">${TOKEN_EXCHANGE_TRIGGER_TEXT}</span></body></html>`,\n );\n // in server-side token exchange mode we need to launch a page that will trigger the token exchange\n // from the same domain, allowing it access to the code_verifier cookie\n // we only need to do this in redirect mode, as the iframe already triggers a client-side token exchange\n // if no code-verifier cookie is found\n if (state && serverTokenExchangeFromState(state)) {\n console.log(\n \"handleCallback serverTokenExchangeFromState, launching redirect page...\",\n {\n requestUrl: request.url,\n configCallbackUrl: resolvedConfigs.callbackUrl,\n },\n );\n // we need to replace the URL with resolved config in case the server is hosted\n // behind a reverse proxy or load balancer\n const requestUrl = new URL(request.url);\n const fetchUrl = `${resolvedConfigs.callbackUrl}?${requestUrl.searchParams.toString()}&sameDomainServerTokenExchange=true`;\n response = new NextResponse(\n `<html>\n <body>\n <span style=\"display:none\">\n <script>\n window.onload = function () {\n fetch('${fetchUrl}').then((response) => {\n response.json().then((jsonResponse) => {\n console.log('fetch jsonResponse', jsonResponse);\n if (jsonResponse.redirectUrl) {\n console.log('handleCallback serverTokenExchangeFromState, redirecting');\n window.location.href = jsonResponse.redirectUrl;\n }\n });\n });\n };\n </script>\n </span>\n </body>\n </html>\n `,\n );\n }\n response.headers.set(\"Content-Type\", \"text/html; charset=utf-8\");\n console.log(\n `handleCallback no code_verifier found, returning ${TOKEN_EXCHANGE_TRIGGER_TEXT}`,\n );\n return response;\n }\n\n await performTokenExchangeAndSetCookies(\n request,\n resolvedConfigs,\n code,\n state,\n );\n\n if (request.url.includes(\"sameDomainServerTokenExchange=true\")) {\n console.log(\n \"handleCallback sameDomainServerTokenExchange = true, returnining redirectUrl\",\n resolvedConfigs.appUrl,\n );\n return NextResponse.json({\n status: \"success\",\n redirectUrl: resolvedConfigs.appUrl,\n });\n }\n\n // this is the case where a 'normal' redirect is happening\n if (serverTokenExchangeFromState(state)) {\n console.log(\n \"handleCallback serverTokenExchangeFromState, redirect to config.appUrl\",\n resolvedConfigs.appUrl,\n );\n if (!resolvedConfigs.appUrl) {\n throw new Error(\"appUrl not defined in config. Cannot redirect.\");\n }\n return NextResponse.redirect(`${resolvedConfigs.appUrl}`);\n }\n // return an empty HTML response so the iframe doesn't show any response\n // in the short moment between the redirect and the parent window\n // acknowledging the redirect and closing the iframe\n const response = new NextResponse(\n `<html><span style=\"display:none\">${TOKEN_EXCHANGE_SUCCESS_TEXT}</span></html>`,\n );\n response.headers.set(\"Content-Type\", \"text/html; charset=utf-8\");\n return response;\n}\n\n/**\n * If redirectPath is an absolute path, return it as-is.\n * Otherwise for relative paths, append it to the current domain.\n * @param redirectPath\n * @returns\n */\nconst getAbsoluteRedirectPath = (\n redirectPath: string,\n currentBasePath: string,\n) => {\n // Check if the redirectPath is an absolute URL\n if (/^(https?:\\/\\/|www\\.).+/i.test(redirectPath)) {\n return redirectPath; // Return as-is if it's an absolute URL\n }\n return new URL(redirectPath, currentBasePath).href;\n};\n\nexport async function handleLogout(\n request: NextRequest,\n config: AuthConfig,\n): Promise<NextResponse> {\n const resolvedConfigs = resolveAuthConfig(config);\n const defaultRedirectPath = resolvedConfigs.loginUrl ?? \"/\";\n const redirectTarget =\n new URL(request.url).searchParams.get(\"redirect\") || defaultRedirectPath;\n const isAbsoluteRedirect = /^(https?:\\/\\/|www\\.).+/i.test(redirectTarget);\n const finalRedirectUrl = getAbsoluteRedirectPath(\n redirectTarget,\n new URL(resolvedConfigs.appUrl ?? request.url).origin,\n );\n\n const response = NextResponse.redirect(finalRedirectUrl);\n\n clearAuthCookies(config);\n\n try {\n revalidatePath(isAbsoluteRedirect ? finalRedirectUrl : redirectTarget);\n } catch (error) {\n logger.warn(\"Failed to revalidate path after logout:\", error);\n }\n\n return response;\n}\n\n/**\n * Creates an authentication handler for Next.js API routes\n *\n * Usage:\n * ```ts\n * // app/api/auth/[...civicauth]/route.ts\n * import { handler } from '@civic/auth/nextjs'\n * export const GET = handler({\n * // optional config overrides\n * })\n * ```\n */\nexport const handler =\n (authConfig = {}) =>\n async (request: NextRequest): Promise<NextResponse> => {\n const config = resolveAuthConfig(authConfig);\n\n try {\n const pathname = request.nextUrl.pathname;\n const pathSegments = pathname.split(\"/\");\n const lastSegment = pathSegments[pathSegments.length - 1];\n\n switch (lastSegment) {\n case \"challenge\":\n return await handleChallenge(config);\n case \"callback\":\n return await handleCallback(request, config);\n case \"logout\":\n return await handleLogout(request, config);\n default:\n throw new AuthError(`Invalid auth route: ${pathname}`, 404);\n }\n } catch (error) {\n logger.error(\"Auth handler error:\", error);\n\n const status = error instanceof AuthError ? error.status : 500;\n const message =\n error instanceof Error ? error.message : \"Authentication failed\";\n\n const response = NextResponse.json({ error: message }, { status });\n\n clearAuthCookies(config);\n return response;\n }\n };\n"]}
|
|
1
|
+
{"version":3,"sources":["/Users/lucas/dev/civic/civic-auth/packages/civic-auth-client/dist/nextjs.js","../src/nextjs/GetUser.ts","../src/nextjs/middleware.ts","../src/nextjs/routeHandler.ts","../src/nextjs/NextJSSessionService.ts","../src/nextjs/cookies.ts"],"names":["cookies","NextResponse"],"mappings":"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","file":"/Users/lucas/dev/civic/civic-auth/packages/civic-auth-client/dist/nextjs.js","sourcesContent":[null,"/**\n * Used on the server-side to get the user object from the cookie\n */\nimport { cookies } from \"next/headers.js\";\nimport { UnknownObject, User } from \"../types\";\n\nexport const getUser = (): User<UnknownObject> | null => {\n // TODO validate the token?\n const user = cookies().get(\"user\")?.value;\n if (!user) return null;\n return JSON.parse(user);\n};\n","/**\n * Authenticates the user on all requests by checking the token cookie\n *\n * Usage:\n * Option 1: use if no other middleware (e.g. no next-intl etc)\n * export default authMiddleware();\n *\n * Option 2: use if other middleware is needed - default auth config\n * export default withAuth((request) => {\n * console.log('in custom middleware', request.nextUrl.pathname);\n * return NextResponse.next();\n * })\n *\n * Option 3: use if other middleware is needed - specifying auth config\n * const withCivicAuth = auth({ loginUrl: '/login', include: ['/[.*]/user'] })\n * export default withCivicAuth((request) => {\n * console.log('in custom middleware', request.url);\n * return NextResponse.next();\n * })\n *\n */\nimport { NextRequest, NextResponse } from \"next/server.js\";\nimport picomatch from \"picomatch\";\nimport {\n AuthConfig,\n defaultAuthConfig,\n resolveAuthConfig,\n} from \"@/nextjs/config.js\";\n\ntype Middleware = (\n request: NextRequest,\n) => Promise<NextResponse> | NextResponse;\n\n// Matches globs:\n// Examples:\n// /user\n// /user/*\n// /user/**/info\nconst matchGlob = (pathname: string, globPattern: string) => {\n const matches = picomatch(globPattern);\n return matches(pathname);\n};\n\n// Matches globs:\n// Examples:\n// /user\n// /user/*\n// /user/**/info\nconst matchesGlobs = (pathname: string, patterns: string[]) =>\n patterns.some((pattern) => {\n if (!pattern) return false;\n console.log(\"matching\", {\n pattern,\n pathname,\n match: matchGlob(pathname, pattern),\n });\n return matchGlob(pathname, pattern);\n });\n\n// internal - used by all exported functions\nconst applyAuth = async (\n authConfig: AuthConfig,\n request: NextRequest,\n): Promise<NextResponse | undefined> => {\n const authConfigWithDefaults = resolveAuthConfig(authConfig);\n\n // Check for any valid auth token\n const isAuthenticated = !!request.cookies.get(\"id_token\");\n\n // skip auth check for login url\n if (request.nextUrl.pathname === authConfigWithDefaults.loginUrl) {\n console.log(\"→ Skipping auth check - this is the login URL\");\n return undefined;\n }\n\n if (!matchesGlobs(request.nextUrl.pathname, authConfigWithDefaults.include)) {\n console.log(\"→ Skipping auth check - path not in include patterns\");\n return undefined;\n }\n\n if (matchesGlobs(request.nextUrl.pathname, authConfigWithDefaults.exclude)) {\n console.log(\"→ Skipping auth check - path in exclude patterns\");\n return undefined;\n }\n\n // Check for either token type\n if (!isAuthenticated) {\n console.log(\"→ No valid token found - redirecting to login\");\n const loginUrl = new URL(authConfigWithDefaults.loginUrl, request.url);\n return NextResponse.redirect(loginUrl);\n }\n\n console.log(\"→ Auth check passed\");\n return undefined;\n};\n\n/**\n *\n * Use this when auth is the only middleware you need.\n * Usage:\n *\n * export default authMiddleware({ loginUrl = '/login' }); // or just authMiddleware();\n *\n */\nexport const authMiddleware =\n (authConfig = defaultAuthConfig) =>\n async (request: NextRequest): Promise<NextResponse> => {\n const response = await applyAuth(authConfig, request);\n if (response) return response;\n\n // NextJS doesn't do middleware chaining yet, so this does not mean\n // \"call the next middleware\" - it means \"continue to the route handler\"\n return NextResponse.next();\n };\n\n/**\n * Usage:\n *\n * export default withAuth(async (request) => {\n * console.log('my middleware');\n * return NextResponse.next();\n * })\n */\n// use this when you have your own middleware to chain\nexport function withAuth(\n middleware: Middleware,\n): (request: NextRequest) => Promise<NextResponse> {\n return async (request: NextRequest): Promise<NextResponse> => {\n const response = await applyAuth({}, request);\n if (response) return response;\n return middleware(request);\n };\n}\n\n/**\n * Use this when you want to configure the middleware here (an alternative is to do it in the next.config file)\n *\n * Usage:\n *\n * const withAuth = auth({ loginUrl = '/login' }); // or just auth();\n *\n * export default withAuth(async (request) => {\n * console.log('my middleware');\n * return NextResponse.next();\n * })\n *\n */\nexport function auth(authConfig: AuthConfig = {}) {\n return (\n middleware: Middleware,\n ): ((request: NextRequest) => Promise<NextResponse>) => {\n return async (request: NextRequest): Promise<NextResponse> => {\n const response = await applyAuth(authConfig, request);\n if (response) return response;\n return middleware(request);\n };\n };\n}\n","import { NextRequest, NextResponse } from \"next/server.js\";\nimport { revalidatePath } from \"next/cache.js\";\nimport {\n AuthConfig,\n DefinedAuthConfig,\n resolveAuthConfig,\n} from \"@/nextjs/config.js\";\nimport { loggers } from \"@/lib/logger.js\";\nimport { AuthSessionService } from \"@/types\";\nimport { NextJSAuthSessionServiceImpl } from \"./NextJSSessionService.js\";\nimport { clearAuthCookies } from \"./cookies.js\";\nimport { generateCodeVerifier } from \"oslo/oauth2\";\nimport { deriveCodeChallenge } from \"@/shared/util.js\";\n\nconst logger = loggers.nextjs.handlers.auth;\n\nclass AuthError extends Error {\n constructor(\n message: string,\n public readonly status: number = 401,\n ) {\n super(message);\n this.name = \"AuthError\";\n }\n}\n\n/**\n * create a code verifier and challenge for PKCE\n * saving the verifier in a cookie for later use\n * @returns {Promise<NextResponse>}\n */\nasync function handleChallenge(): Promise<NextResponse> {\n const codeVerifier = generateCodeVerifier();\n console.log(\"handleChallenge codeVerifier\", codeVerifier);\n const challenge = await deriveCodeChallenge(codeVerifier);\n const response = NextResponse.json({ status: \"success\", challenge });\n response.cookies.set(\"codeVerifier\", codeVerifier, {\n httpOnly: true,\n secure: true,\n sameSite: \"strict\",\n });\n return response;\n}\nasync function handleCallback(\n request: NextRequest,\n config: AuthConfig,\n): Promise<NextResponse> {\n const code = request.nextUrl.searchParams.get(\"code\");\n if (!code) throw new AuthError(\"Missing authorization code\");\n\n try {\n // return an empty HTML response so the iframe doesn't show any response\n // in the short moment between the redirect and the parent window\n // acknowledging the redirect and closing the iframe\n const response = new NextResponse(`<html></html>`);\n response.headers.set(\"Content-Type\", \"text/html; charset=utf-8\");\n\n const resolvedConfigs = resolveAuthConfig(config);\n const callbackUrl = new URL(\n resolvedConfigs?.callbackUrl,\n request.url,\n ).toString();\n\n const authService = getDefaultAuthSessionService(\n {\n ...resolvedConfigs,\n callbackUrl,\n },\n request,\n response,\n );\n console.log(\"handleCallback authService\", authService);\n const tokens = await authService.tokenExchange(request.nextUrl.toString());\n\n if (!tokens.accessToken) {\n throw new AuthError(\"Missing access token\");\n }\n\n return response;\n } catch (error) {\n logger.error(\"Token exchange failed:\", error);\n throw new AuthError(\"Failed to authenticate user\", 401);\n }\n}\n\n/**\n * If redirectPath is an absolute path, return it as-is.\n * Otherwise for relative paths, append it to the current domain.\n * @param redirectPath\n * @returns\n */\nconst getAbsoluteRedirectPath = (\n redirectPath: string,\n currentBasePath: string,\n) => {\n // Check if the redirectPath is an absolute URL\n if (/^(https?:\\/\\/|www\\.).+/i.test(redirectPath)) {\n return redirectPath; // Return as-is if it's an absolute URL\n }\n return new URL(redirectPath, currentBasePath).href;\n};\n\nasync function handleLogout(\n request: NextRequest,\n config: AuthConfig,\n): Promise<NextResponse> {\n const resolvedConfigs = resolveAuthConfig(config);\n const defaultRedirectPath = resolvedConfigs.loginUrl ?? \"/\";\n const redirectTarget =\n new URL(request.url).searchParams.get(\"redirect\") || defaultRedirectPath;\n const isAbsoluteRedirect = /^(https?:\\/\\/|www\\.).+/i.test(redirectTarget);\n const finalRedirectUrl = getAbsoluteRedirectPath(\n redirectTarget,\n new URL(request.url).origin,\n );\n\n const response = NextResponse.redirect(finalRedirectUrl);\n clearAuthCookies(response, resolvedConfigs);\n\n try {\n revalidatePath(isAbsoluteRedirect ? finalRedirectUrl : redirectTarget);\n } catch (error) {\n logger.warn(\"Failed to revalidate path after logout:\", error);\n }\n\n return response;\n}\n\nconst getDefaultAuthSessionService = (\n authConfig: DefinedAuthConfig,\n request?: NextRequest,\n response?: NextResponse,\n): AuthSessionService => {\n return new NextJSAuthSessionServiceImpl(authConfig, request, response);\n};\n\n/**\n * Creates an authentication handler for Next.js API routes\n *\n * Usage:\n * ```ts\n * // app/api/auth/[...civicauth]/route.ts\n * import { handler } from '@civic/auth/nextjs'\n * export const GET = handler({\n * // optional config overrides\n * })\n * ```\n */\nexport const handler =\n (authConfig: {} = {}) =>\n async (request: NextRequest): Promise<NextResponse> => {\n const config = resolveAuthConfig(authConfig);\n\n try {\n const pathname = request.nextUrl.pathname;\n const pathSegments = pathname.split(\"/\");\n const lastSegment = pathSegments[pathSegments.length - 1];\n\n switch (lastSegment) {\n case \"challenge\":\n return await handleChallenge();\n case \"callback\":\n return await handleCallback(request, config);\n case \"logout\":\n return await handleLogout(request, config);\n default:\n throw new AuthError(`Invalid auth route: ${pathname}`, 404);\n }\n } catch (error) {\n logger.error(\"Auth handler error:\", error);\n\n const status = error instanceof AuthError ? error.status : 500;\n const message =\n error instanceof Error ? error.message : \"Authentication failed\";\n\n const response = NextResponse.json({ error: message }, { status });\n\n clearAuthCookies(response, config);\n return response;\n }\n };\n","import { cookies } from \"next/headers.js\";\nimport { SessionData, UnknownObject, Endpoints, User } from \"../types.js\";\nimport { NextRequest, NextResponse } from \"next/server.js\";\nimport { AuthConfigWithDefaults } from \"./config.js\";\nimport { AuthSessionServiceImpl } from \"@/services\";\nimport {\n clearAuthCookies,\n createTokenCookies,\n createUserInfoCookie,\n} from \"./cookies.js\";\n\nexport type StorageInterface = {\n get(): SessionData;\n getUser(): User<UnknownObject> | null;\n set(data: Partial<SessionData>): void;\n setUser(data: User<UnknownObject> | null): void;\n clear(): void;\n};\n\nexport class NextJSAuthSessionServiceImpl extends AuthSessionServiceImpl {\n constructor(\n readonly authConfig: AuthConfigWithDefaults,\n readonly request: NextRequest | undefined,\n readonly response: NextResponse | undefined,\n readonly inputEndpoints?: Endpoints | undefined,\n ) {\n super(\n authConfig.clientId,\n authConfig.callbackUrl,\n authConfig.oauthServer,\n inputEndpoints,\n );\n }\n\n protected getCodeVerifier(): string {\n const codeVerifier = cookies().get(\"codeVerifier\");\n if (!codeVerifier) {\n throw new Error(\"Code verifier not found in cookies\");\n }\n return codeVerifier.value;\n }\n\n getSessionData(): SessionData {\n const authenticated = cookies().get(\"access_token\") !== undefined;\n return {\n authenticated,\n codeVerifier: cookies().get(\"codeVerifier\")?.value,\n accessToken: cookies().get(\"access_token\")?.value,\n idToken: cookies().get(\"id_token\")?.value,\n refreshToken: cookies().get(\"refresh_token\")?.value,\n };\n }\n\n updateSessionData(data: Partial<SessionData>): void {\n createTokenCookies(\n this.response as NextResponse,\n data as SessionData,\n this.authConfig,\n );\n }\n\n getUser(): User<UnknownObject> | null {\n const userCookie = cookies().get(\"user\");\n if (!userCookie) return null;\n return JSON.parse(userCookie.value);\n }\n\n setUser(user: User<UnknownObject> | null): void {\n createUserInfoCookie(\n this.response as NextResponse,\n user,\n { authenticated: true },\n this.authConfig,\n );\n }\n\n clearSessionData(): void {\n clearAuthCookies(this.response as NextResponse, this.authConfig);\n }\n\n // TODO fix the Window reference\n loadAuthorizationUrl() {\n throw new Error(\"Not implemented\");\n }\n\n async logout(): Promise<void> {\n this.updateSessionData({ authenticated: false });\n }\n}\n","import { SessionData, UnknownObject, User } from \"@/types\";\nimport { NextResponse } from \"next/server\";\nimport { AuthConfig } from \"./config\";\n\n/**\n * Creates HTTP-only cookies for authentication tokens\n */\nconst createTokenCookies = (\n response: NextResponse,\n sessionData: SessionData,\n config: AuthConfig,\n) => {\n const maxAge = sessionData.expiresIn ?? 3600;\n const cookieOptions = {\n ...config.cookies?.tokens,\n maxAge,\n };\n\n if (sessionData.accessToken) {\n response.cookies.set(\"access_token\", sessionData.accessToken, {\n ...cookieOptions,\n httpOnly: true,\n });\n }\n\n if (sessionData.idToken) {\n response.cookies.set(\"id_token\", sessionData.idToken, {\n ...cookieOptions,\n httpOnly: true,\n });\n }\n\n if (sessionData.refreshToken) {\n response.cookies.set(\"refresh_token\", sessionData.refreshToken, {\n ...cookieOptions,\n httpOnly: true,\n });\n }\n};\n\n/**\n * Creates a client-readable cookie with user info\n */\nconst createUserInfoCookie = (\n response: NextResponse,\n user: User<UnknownObject> | null,\n sessionData: SessionData,\n config: AuthConfig,\n) => {\n if (!user) {\n response.cookies.set(\"user\", \"\", {\n ...config.cookies?.user,\n maxAge: 0,\n });\n return;\n }\n const maxAge = sessionData.expiresIn ?? 3600;\n\n // TODO select fields to include in the user cookie\n const frontendUser = {\n ...user,\n };\n\n // TODO make call to get user info from the\n // auth server /userinfo endpoint when it's available\n // then add to the default claims above\n\n response.cookies.set(\"user\", JSON.stringify(frontendUser), {\n ...config.cookies?.user,\n maxAge,\n });\n};\n\n/**\n * Clears all authentication cookies\n */\nconst clearAuthCookies = (response: NextResponse, config: AuthConfig) => {\n const clearOptions = {\n ...config.cookies?.tokens,\n maxAge: 0,\n };\n\n response.cookies.set(\"access_token\", \"\", clearOptions);\n response.cookies.set(\"id_token\", \"\", clearOptions);\n response.cookies.set(\"refresh_token\", \"\", clearOptions);\n response.cookies.set(\"codeVerifier\", \"\", clearOptions);\n response.cookies.set(\"user\", \"\", {\n ...config.cookies?.user,\n maxAge: 0,\n });\n};\n\nexport { createTokenCookies, createUserInfoCookie, clearAuthCookies };\n"]}
|