@vistagenic/vista 0.3.2 → 0.3.3
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/bin/vista.js +79 -109
- package/dist/ai/embeddings.d.ts +11 -11
- package/dist/ai/embeddings.js +71 -71
- package/dist/ai/index.d.ts +10 -10
- package/dist/ai/index.js +26 -26
- package/dist/ai/providers/base.js +85 -85
- package/dist/ai/react/react-server.d.ts +1 -1
- package/dist/ai/react/react-server.js +17 -17
- package/dist/ai/react/use-agent.js +138 -138
- package/dist/auth/core.d.ts +140 -140
- package/dist/auth/core.js +165 -165
- package/dist/auth/index.d.ts +20 -20
- package/dist/auth/index.js +369 -369
- package/dist/auth/react-server.d.ts +1 -1
- package/dist/auth/react-server.js +10 -10
- package/dist/auth/react.d.ts +18 -18
- package/dist/auth/react.js +71 -71
- package/dist/bin/build-rsc-flashpack.js +6 -0
- package/dist/bin/build-rsc.js +537 -492
- package/dist/bin/build.js +355 -353
- package/dist/bin/generate.js +513 -510
- package/dist/bin/webpack.config.js +4 -3
- package/dist/build/manifest.d.ts +169 -169
- package/dist/build/manifest.js +423 -423
- package/dist/build/rsc/client-manifest.d.ts +62 -62
- package/dist/build/rsc/client-manifest.js +295 -295
- package/dist/build/rsc/compiler.js +5 -4
- package/dist/build/rsc/native-scanner.d.ts +135 -135
- package/dist/build/rsc/native-scanner.js +203 -203
- package/dist/build/rsc/react-client-reference-manifest.d.ts +28 -28
- package/dist/build/rsc/react-client-reference-manifest.js +240 -240
- package/dist/build/standalone.js +260 -254
- package/dist/client/dynamic.react-server.d.ts +2 -2
- package/dist/client/dynamic.react-server.js +23 -23
- package/dist/client/link.react-server.d.ts +2 -2
- package/dist/client/link.react-server.js +11 -11
- package/dist/client/navigation.react-server.d.ts +1 -1
- package/dist/client/navigation.react-server.js +17 -17
- package/dist/client/router.react-server.d.ts +1 -1
- package/dist/client/router.react-server.js +17 -17
- package/dist/client/rsc-router.react-server.d.ts +1 -1
- package/dist/client/rsc-router.react-server.js +17 -17
- package/dist/client/script.react-server.d.ts +2 -2
- package/dist/client/script.react-server.js +23 -23
- package/dist/config.d.ts +1 -1
- package/dist/config.js +1 -7
- package/dist/deploy/adapters/cloudflare.js +43 -19
- package/dist/deploy/adapters/docker.d.ts +1 -0
- package/dist/deploy/adapters/docker.js +5 -4
- package/dist/deploy/adapters/netlify.js +62 -17
- package/dist/deploy/adapters/vercel.js +80 -50
- package/dist/deploy/preflight.js +4 -3
- package/dist/deploy/runtime-pack.d.ts +11 -0
- package/dist/deploy/runtime-pack.js +300 -0
- package/dist/deploy/utils.d.ts +1 -1
- package/dist/deploy/utils.js +31 -2
- package/dist/flashpack/command.js +1 -0
- package/dist/flashpack/runtime.js +2 -1
- package/dist/index.d.ts +23 -23
- package/dist/index.js +61 -61
- package/dist/server/app-dir.d.ts +22 -0
- package/dist/server/app-dir.js +77 -0
- package/dist/server/cookie-parse.d.ts +4 -4
- package/dist/server/cookie-parse.js +14 -14
- package/dist/server/engine.js +5 -5
- package/dist/server/image-optimizer.js +2 -1
- package/dist/server/index.d.ts +109 -109
- package/dist/server/index.js +315 -315
- package/dist/server/middleware-runner.d.ts +125 -125
- package/dist/server/middleware-runner.js +607 -615
- package/dist/server/middleware-security.d.ts +36 -36
- package/dist/server/middleware-security.js +183 -183
- package/dist/server/module-compile-hook.js +695 -695
- package/dist/server/root-resolver.js +6 -5
- package/dist/server/rsc-engine-flashpack.d.ts +3 -1
- package/dist/server/rsc-engine-flashpack.js +12 -1
- package/dist/server/rsc-engine.d.ts +6 -1
- package/dist/server/rsc-engine.js +203 -219
- package/dist/server/rsc-upstream.js +893 -892
- package/dist/server/static-generator.js +4 -3
- package/dist/server/structure-validator.js +2 -1
- package/dist/server/structure-watch.js +2 -0
- package/dist/server/typed-api-runtime.js +639 -635
- package/dist/server/vista-import-map.js +134 -134
- package/dist/stack/index.d.ts +34 -34
- package/dist/stack/index.js +49 -49
- package/dist/stack/server/caller.d.ts +13 -13
- package/dist/stack/server/caller.js +42 -42
- package/dist/stack/server/executor.d.ts +40 -40
- package/dist/stack/server/executor.js +222 -222
- package/dist/stack/server/index.d.ts +11 -11
- package/dist/stack/server/index.js +24 -24
- package/dist/stack/server/procedure.d.ts +20 -20
- package/dist/stack/server/procedure.js +66 -66
- package/dist/stack/server/types.d.ts +113 -113
- package/dist/theme/react-server.d.ts +10 -10
- package/dist/theme/react-server.js +16 -16
- package/package.json +1 -1
package/dist/auth/index.js
CHANGED
|
@@ -1,369 +1,369 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.VistaAuth = VistaAuth;
|
|
18
|
-
const request_context_1 = require("../server/request-context");
|
|
19
|
-
const middleware_security_1 = require("../server/middleware-security");
|
|
20
|
-
const core_1 = require("./core");
|
|
21
|
-
__exportStar(require("./core"), exports);
|
|
22
|
-
const CSRF_COOKIE = 'vista.csrf-token';
|
|
23
|
-
const STATE_COOKIE = 'vista.oauth-state';
|
|
24
|
-
const PKCE_COOKIE = 'vista.pkce';
|
|
25
|
-
const CALLBACK_COOKIE = 'vista.oauth-callback';
|
|
26
|
-
function cookie(name, value, options = {}) {
|
|
27
|
-
const parts = [`${name}=${encodeURIComponent(value)}`, 'Path=/', 'SameSite=Lax'];
|
|
28
|
-
if (options.httpOnly !== false)
|
|
29
|
-
parts.push('HttpOnly');
|
|
30
|
-
if (process.env.NODE_ENV === 'production')
|
|
31
|
-
parts.push('Secure');
|
|
32
|
-
if (options.maxAge != null)
|
|
33
|
-
parts.push(`Max-Age=${options.maxAge}`);
|
|
34
|
-
return parts.join('; ');
|
|
35
|
-
}
|
|
36
|
-
function expiredCookie(name, options = {}) {
|
|
37
|
-
return cookie(name, '', { maxAge: 0, httpOnly: options.httpOnly });
|
|
38
|
-
}
|
|
39
|
-
function readCookies(request) {
|
|
40
|
-
const map = new Map();
|
|
41
|
-
const header = request.headers.get('cookie') || '';
|
|
42
|
-
for (const segment of header.split(';')) {
|
|
43
|
-
const [rawName, ...rest] = segment.split('=');
|
|
44
|
-
const name = rawName?.trim();
|
|
45
|
-
if (!name)
|
|
46
|
-
continue;
|
|
47
|
-
try {
|
|
48
|
-
map.set(name, decodeURIComponent(rest.join('=').trim()));
|
|
49
|
-
}
|
|
50
|
-
catch {
|
|
51
|
-
map.set(name, rest.join('=').trim());
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
return map;
|
|
55
|
-
}
|
|
56
|
-
function requestToUrl(request) {
|
|
57
|
-
return new URL(request.url);
|
|
58
|
-
}
|
|
59
|
-
function json(data, init = {}, extraCookies = []) {
|
|
60
|
-
const headers = new Headers(init.headers);
|
|
61
|
-
headers.set('Content-Type', 'application/json');
|
|
62
|
-
for (const item of extraCookies) {
|
|
63
|
-
headers.append('Set-Cookie', item);
|
|
64
|
-
}
|
|
65
|
-
return new Response(JSON.stringify(data), { ...init, headers });
|
|
66
|
-
}
|
|
67
|
-
function redirect(location, cookies = []) {
|
|
68
|
-
const headers = new Headers({ Location: location });
|
|
69
|
-
for (const item of cookies)
|
|
70
|
-
headers.append('Set-Cookie', item);
|
|
71
|
-
return new Response(null, { status: 302, headers });
|
|
72
|
-
}
|
|
73
|
-
async function resolveRedirect(config, target, requestUrl) {
|
|
74
|
-
const baseUrl = new URL(requestUrl).origin;
|
|
75
|
-
let location = (0, middleware_security_1.isSafeRedirectLocation)(target, requestUrl) ? target : '/';
|
|
76
|
-
if (config.callbacks?.redirect) {
|
|
77
|
-
location = await config.callbacks.redirect({ url: location, baseUrl });
|
|
78
|
-
if (!(0, middleware_security_1.isSafeRedirectLocation)(location, requestUrl)) {
|
|
79
|
-
location = '/';
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
return location;
|
|
83
|
-
}
|
|
84
|
-
async function createSessionCookie(config, user) {
|
|
85
|
-
const now = Math.floor(Date.now() / 1000);
|
|
86
|
-
let payload = {
|
|
87
|
-
user,
|
|
88
|
-
expires: new Date((now + config.session.maxAge) * 1000).toISOString(),
|
|
89
|
-
iat: now,
|
|
90
|
-
exp: now + config.session.maxAge,
|
|
91
|
-
};
|
|
92
|
-
if (config.callbacks?.jwt) {
|
|
93
|
-
payload = await config.callbacks.jwt({ token: payload, user });
|
|
94
|
-
}
|
|
95
|
-
let session = { user: payload.user, expires: payload.expires };
|
|
96
|
-
if (config.callbacks?.session) {
|
|
97
|
-
session = await config.callbacks.session({ session, token: payload });
|
|
98
|
-
}
|
|
99
|
-
const token = (0, core_1.encryptJwt)(payload, config.secret);
|
|
100
|
-
return {
|
|
101
|
-
session,
|
|
102
|
-
cookie: cookie(config.session.cookieName, token, { maxAge: config.session.maxAge }),
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
async function readSessionFromRequest(request, config) {
|
|
106
|
-
const token = readCookies(request).get(config.session.cookieName);
|
|
107
|
-
if (!token)
|
|
108
|
-
return null;
|
|
109
|
-
const payload = (0, core_1.decryptJwt)(token, config.secret);
|
|
110
|
-
if (!payload?.user)
|
|
111
|
-
return null;
|
|
112
|
-
let session = { user: payload.user, expires: payload.expires };
|
|
113
|
-
if (config.callbacks?.session) {
|
|
114
|
-
session = await config.callbacks.session({ session, token: payload });
|
|
115
|
-
}
|
|
116
|
-
return session;
|
|
117
|
-
}
|
|
118
|
-
async function exchangeOAuth(provider, code, redirectUri, verifier) {
|
|
119
|
-
const body = new URLSearchParams({
|
|
120
|
-
client_id: provider.clientId,
|
|
121
|
-
client_secret: provider.clientSecret,
|
|
122
|
-
code,
|
|
123
|
-
redirect_uri: redirectUri,
|
|
124
|
-
grant_type: 'authorization_code',
|
|
125
|
-
code_verifier: verifier,
|
|
126
|
-
});
|
|
127
|
-
const tokenResponse = await fetch(provider.token, {
|
|
128
|
-
method: 'POST',
|
|
129
|
-
headers: { Accept: 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
130
|
-
body,
|
|
131
|
-
});
|
|
132
|
-
const tokenJson = (await tokenResponse.json());
|
|
133
|
-
if (!tokenJson.access_token) {
|
|
134
|
-
throw new Error(`${provider.id} token exchange failed`);
|
|
135
|
-
}
|
|
136
|
-
const profileResponse = await fetch(provider.userinfo, {
|
|
137
|
-
headers: { Authorization: `Bearer ${tokenJson.access_token}`, Accept: 'application/json' },
|
|
138
|
-
});
|
|
139
|
-
const profile = await profileResponse.json();
|
|
140
|
-
return provider.profile(profile);
|
|
141
|
-
}
|
|
142
|
-
function findProvider(config, id) {
|
|
143
|
-
return config.providers.find((provider) => provider.id === id);
|
|
144
|
-
}
|
|
145
|
-
async function handleAuthRequest(request, config) {
|
|
146
|
-
const url = requestToUrl(request);
|
|
147
|
-
const basePath = config.basePath.replace(/\/$/, '');
|
|
148
|
-
let rest = url.pathname.startsWith(basePath) ? url.pathname.slice(basePath.length) : url.pathname;
|
|
149
|
-
if (rest.startsWith('/'))
|
|
150
|
-
rest = rest.slice(1);
|
|
151
|
-
const [action, providerId] = rest.split('/');
|
|
152
|
-
const origin = url.origin;
|
|
153
|
-
const cookies = readCookies(request);
|
|
154
|
-
const method = request.method.toUpperCase();
|
|
155
|
-
if (action === 'session' && method === 'GET') {
|
|
156
|
-
const session = await readSessionFromRequest(request, config);
|
|
157
|
-
return json(session ? { user: session.user, expires: session.expires } : { user: null });
|
|
158
|
-
}
|
|
159
|
-
if (action === 'csrf' && method === 'GET') {
|
|
160
|
-
const token = cookies.get(CSRF_COOKIE) || (0, core_1.randomToken)(24);
|
|
161
|
-
return json({ csrfToken: token }, {}, [cookie(CSRF_COOKIE, token, { httpOnly: false, maxAge: 60 * 60 })]);
|
|
162
|
-
}
|
|
163
|
-
if (action === 'providers' && method === 'GET') {
|
|
164
|
-
const providers = Object.fromEntries(config.providers.map((provider) => [provider.id, { id: provider.id, name: provider.name, type: provider.type }]));
|
|
165
|
-
return json(providers);
|
|
166
|
-
}
|
|
167
|
-
if (action === 'signout' && (method === 'POST' || method === 'GET')) {
|
|
168
|
-
return redirect(config.pages?.signIn || '/', [
|
|
169
|
-
expiredCookie(config.session.cookieName),
|
|
170
|
-
expiredCookie(CSRF_COOKIE, { httpOnly: false }),
|
|
171
|
-
]);
|
|
172
|
-
}
|
|
173
|
-
if (action === 'signin' && method === 'GET' && !providerId) {
|
|
174
|
-
const page = config.pages?.signIn;
|
|
175
|
-
if (page)
|
|
176
|
-
return redirect(page);
|
|
177
|
-
const buttons = config.providers
|
|
178
|
-
.map((provider) => `<p><a href="${basePath}/signin/${provider.id}">Continue with ${provider.name}</a></p>`)
|
|
179
|
-
.join('');
|
|
180
|
-
return new Response(`<!doctype html><html><body><h1>Sign in</h1>${buttons}</body></html>`, { headers: { 'Content-Type': 'text/html; charset=utf-8' } });
|
|
181
|
-
}
|
|
182
|
-
if (action === 'signin' && providerId) {
|
|
183
|
-
const provider = findProvider(config, providerId);
|
|
184
|
-
if (!provider) {
|
|
185
|
-
return json({ error: 'Unknown provider' }, { status: 400 });
|
|
186
|
-
}
|
|
187
|
-
if (provider.type === 'credentials') {
|
|
188
|
-
if (method !== 'POST') {
|
|
189
|
-
return json({ error: 'Credentials sign-in requires POST' }, { status: 405 });
|
|
190
|
-
}
|
|
191
|
-
const contentType = request.headers.get('content-type') || '';
|
|
192
|
-
let credentials = {};
|
|
193
|
-
try {
|
|
194
|
-
if (contentType.includes('application/json')) {
|
|
195
|
-
credentials = (await request.json()) || {};
|
|
196
|
-
}
|
|
197
|
-
else {
|
|
198
|
-
const form = await request.formData();
|
|
199
|
-
credentials = Object.fromEntries(Array.from(form.entries()).map(([key, value]) => [key, String(value)]));
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
catch {
|
|
203
|
-
return json({ error: 'Invalid credentials payload' }, { status: 400 });
|
|
204
|
-
}
|
|
205
|
-
const csrfHeader = request.headers.get('x-csrf-token') ||
|
|
206
|
-
url.searchParams.get('csrfToken') ||
|
|
207
|
-
credentials.csrfToken ||
|
|
208
|
-
'';
|
|
209
|
-
const csrfCookie = cookies.get(CSRF_COOKIE) || '';
|
|
210
|
-
if (!csrfCookie || csrfHeader !== csrfCookie) {
|
|
211
|
-
return json({ error: 'Invalid CSRF token' }, { status: 403 });
|
|
212
|
-
}
|
|
213
|
-
const user = await provider.authorize(credentials);
|
|
214
|
-
if (!user) {
|
|
215
|
-
return json({ error: 'Invalid credentials' }, { status: 401 });
|
|
216
|
-
}
|
|
217
|
-
if (config.callbacks?.signIn && !(await config.callbacks.signIn({ user }))) {
|
|
218
|
-
return json({ error: 'Access denied' }, { status: 403 });
|
|
219
|
-
}
|
|
220
|
-
const created = await createSessionCookie(config, user);
|
|
221
|
-
const redirectTo = credentials.callbackUrl || url.searchParams.get('callbackUrl') || '/';
|
|
222
|
-
const safeRedirect = await resolveRedirect(config, redirectTo, url.toString());
|
|
223
|
-
return redirect(safeRedirect, [created.cookie]);
|
|
224
|
-
}
|
|
225
|
-
const { verifier, challenge } = (0, core_1.pkcePair)();
|
|
226
|
-
const state = (0, core_1.randomToken)(16);
|
|
227
|
-
const callbackUrl = url.searchParams.get('callbackUrl') || '/';
|
|
228
|
-
const redirectUri = `${origin}${basePath}/callback/${provider.id}`;
|
|
229
|
-
const params = new URLSearchParams({
|
|
230
|
-
client_id: provider.clientId,
|
|
231
|
-
redirect_uri: redirectUri,
|
|
232
|
-
response_type: 'code',
|
|
233
|
-
state,
|
|
234
|
-
code_challenge: challenge,
|
|
235
|
-
code_challenge_method: 'S256',
|
|
236
|
-
...provider.authorization.params,
|
|
237
|
-
});
|
|
238
|
-
return redirect(`${provider.authorization.url}?${params.toString()}`, [
|
|
239
|
-
cookie(STATE_COOKIE, state, { maxAge: 600 }),
|
|
240
|
-
cookie(PKCE_COOKIE, verifier, { maxAge: 600 }),
|
|
241
|
-
cookie(CALLBACK_COOKIE, callbackUrl, { maxAge: 600 }),
|
|
242
|
-
]);
|
|
243
|
-
}
|
|
244
|
-
if (action === 'callback' && providerId) {
|
|
245
|
-
const provider = findProvider(config, providerId);
|
|
246
|
-
if (!provider || provider.type !== 'oauth') {
|
|
247
|
-
return json({ error: 'Unknown provider' }, { status: 400 });
|
|
248
|
-
}
|
|
249
|
-
const state = url.searchParams.get('state');
|
|
250
|
-
if (!state || state !== cookies.get(STATE_COOKIE)) {
|
|
251
|
-
return json({ error: 'Invalid OAuth state' }, { status: 403 });
|
|
252
|
-
}
|
|
253
|
-
const code = url.searchParams.get('code');
|
|
254
|
-
const verifier = cookies.get(PKCE_COOKIE);
|
|
255
|
-
if (!code || !verifier) {
|
|
256
|
-
return json({ error: 'Missing OAuth code' }, { status: 400 });
|
|
257
|
-
}
|
|
258
|
-
const redirectUri = `${origin}${basePath}/callback/${provider.id}`;
|
|
259
|
-
const user = await exchangeOAuth(provider, code, redirectUri, verifier);
|
|
260
|
-
if (config.adapter?.getUserByAccount) {
|
|
261
|
-
const existing = await config.adapter.getUserByAccount(provider.id, user.id);
|
|
262
|
-
if (existing) {
|
|
263
|
-
user.id = existing.id;
|
|
264
|
-
}
|
|
265
|
-
else {
|
|
266
|
-
await config.adapter.createUser?.(user);
|
|
267
|
-
await config.adapter.linkAccount?.(user.id, {
|
|
268
|
-
provider: provider.id,
|
|
269
|
-
type: 'oauth',
|
|
270
|
-
providerAccountId: user.id,
|
|
271
|
-
});
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
if (config.callbacks?.signIn && !(await config.callbacks.signIn({ user }))) {
|
|
275
|
-
return json({ error: 'Access denied' }, { status: 403 });
|
|
276
|
-
}
|
|
277
|
-
const created = await createSessionCookie(config, user);
|
|
278
|
-
const callbackUrl = cookies.get(CALLBACK_COOKIE) || '/';
|
|
279
|
-
const safeRedirect = await resolveRedirect(config, callbackUrl, url.toString());
|
|
280
|
-
return redirect(safeRedirect, [
|
|
281
|
-
created.cookie,
|
|
282
|
-
expiredCookie(STATE_COOKIE),
|
|
283
|
-
expiredCookie(PKCE_COOKIE),
|
|
284
|
-
expiredCookie(CALLBACK_COOKIE),
|
|
285
|
-
]);
|
|
286
|
-
}
|
|
287
|
-
return json({ error: 'Not found' }, { status: 404 });
|
|
288
|
-
}
|
|
289
|
-
function VistaAuth(config) {
|
|
290
|
-
const resolved = (0, core_1.resolveAuthConfig)(config);
|
|
291
|
-
const handlers = {
|
|
292
|
-
GET: (request) => handleAuthRequest(request, resolved),
|
|
293
|
-
POST: (request) => handleAuthRequest(request, resolved),
|
|
294
|
-
};
|
|
295
|
-
async function auth(request) {
|
|
296
|
-
if (request) {
|
|
297
|
-
return readSessionFromRequest(request, resolved);
|
|
298
|
-
}
|
|
299
|
-
const context = (0, request_context_1.getRequestContext)();
|
|
300
|
-
if (!context?.req)
|
|
301
|
-
return null;
|
|
302
|
-
const host = context.req.get?.('host') || context.req.headers?.host || 'localhost';
|
|
303
|
-
const protocol = context.req.protocol || 'http';
|
|
304
|
-
const headers = new Headers();
|
|
305
|
-
if (context.req.headers?.cookie)
|
|
306
|
-
headers.set('cookie', String(context.req.headers.cookie));
|
|
307
|
-
const fake = new Request(`${protocol}://${host}${context.req.originalUrl || context.req.url || '/'}`, {
|
|
308
|
-
headers,
|
|
309
|
-
});
|
|
310
|
-
return readSessionFromRequest(fake, resolved);
|
|
311
|
-
}
|
|
312
|
-
async function signIn(providerId, options = {}) {
|
|
313
|
-
const context = (0, request_context_1.getRequestContext)();
|
|
314
|
-
const host = context?.req?.get?.('host') || 'localhost';
|
|
315
|
-
const protocol = context?.req?.protocol || 'http';
|
|
316
|
-
if (providerId) {
|
|
317
|
-
const provider = findProvider(resolved, providerId);
|
|
318
|
-
if (provider?.type === 'credentials') {
|
|
319
|
-
const user = await provider.authorize(options);
|
|
320
|
-
if (!user) {
|
|
321
|
-
return json({ error: 'Invalid credentials' }, { status: 401 });
|
|
322
|
-
}
|
|
323
|
-
if (resolved.callbacks?.signIn && !(await resolved.callbacks.signIn({ user }))) {
|
|
324
|
-
return json({ error: 'Access denied' }, { status: 403 });
|
|
325
|
-
}
|
|
326
|
-
const created = await createSessionCookie(resolved, user);
|
|
327
|
-
const requestUrl = `${protocol}://${host}/`;
|
|
328
|
-
const safeRedirect = await resolveRedirect(resolved, options.callbackUrl || '/', requestUrl);
|
|
329
|
-
return redirect(safeRedirect, [created.cookie]);
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
const url = new URL(`${protocol}://${host}${resolved.basePath}/signin${providerId ? `/${providerId}` : ''}`);
|
|
333
|
-
for (const [key, value] of Object.entries(options)) {
|
|
334
|
-
url.searchParams.set(key, value);
|
|
335
|
-
}
|
|
336
|
-
const headers = new Headers();
|
|
337
|
-
if (context?.req?.headers?.cookie)
|
|
338
|
-
headers.set('cookie', String(context.req.headers.cookie));
|
|
339
|
-
return handleAuthRequest(new Request(url, { method: 'GET', headers }), resolved);
|
|
340
|
-
}
|
|
341
|
-
async function signOut() {
|
|
342
|
-
const context = (0, request_context_1.getRequestContext)();
|
|
343
|
-
const host = context?.req?.get?.('host') || 'localhost';
|
|
344
|
-
const protocol = context?.req?.protocol || 'http';
|
|
345
|
-
return handleAuthRequest(new Request(`${protocol}://${host}${resolved.basePath}/signout`, { method: 'POST' }), resolved);
|
|
346
|
-
}
|
|
347
|
-
function authMiddleware(authorized) {
|
|
348
|
-
const callback = authorized || resolved.callbacks?.authorized;
|
|
349
|
-
return async ({ request, next }) => {
|
|
350
|
-
const webRequest = request instanceof Request
|
|
351
|
-
? request
|
|
352
|
-
: new Request(request.url, { headers: request.headers, method: request.method });
|
|
353
|
-
const session = await readSessionFromRequest(webRequest, resolved);
|
|
354
|
-
if (!callback) {
|
|
355
|
-
return next();
|
|
356
|
-
}
|
|
357
|
-
const result = await callback({ auth: session, request: webRequest });
|
|
358
|
-
if (result instanceof Response)
|
|
359
|
-
return result;
|
|
360
|
-
if (result === false) {
|
|
361
|
-
const signInPage = resolved.pages?.signIn || `${resolved.basePath}/signin`;
|
|
362
|
-
return new Response(null, { status: 307, headers: { Location: signInPage } });
|
|
363
|
-
}
|
|
364
|
-
return next();
|
|
365
|
-
};
|
|
366
|
-
}
|
|
367
|
-
return { handlers, auth, signIn, signOut, authMiddleware, config: resolved };
|
|
368
|
-
}
|
|
369
|
-
exports.default = VistaAuth;
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.VistaAuth = VistaAuth;
|
|
18
|
+
const request_context_1 = require("../server/request-context");
|
|
19
|
+
const middleware_security_1 = require("../server/middleware-security");
|
|
20
|
+
const core_1 = require("./core");
|
|
21
|
+
__exportStar(require("./core"), exports);
|
|
22
|
+
const CSRF_COOKIE = 'vista.csrf-token';
|
|
23
|
+
const STATE_COOKIE = 'vista.oauth-state';
|
|
24
|
+
const PKCE_COOKIE = 'vista.pkce';
|
|
25
|
+
const CALLBACK_COOKIE = 'vista.oauth-callback';
|
|
26
|
+
function cookie(name, value, options = {}) {
|
|
27
|
+
const parts = [`${name}=${encodeURIComponent(value)}`, 'Path=/', 'SameSite=Lax'];
|
|
28
|
+
if (options.httpOnly !== false)
|
|
29
|
+
parts.push('HttpOnly');
|
|
30
|
+
if (process.env.NODE_ENV === 'production')
|
|
31
|
+
parts.push('Secure');
|
|
32
|
+
if (options.maxAge != null)
|
|
33
|
+
parts.push(`Max-Age=${options.maxAge}`);
|
|
34
|
+
return parts.join('; ');
|
|
35
|
+
}
|
|
36
|
+
function expiredCookie(name, options = {}) {
|
|
37
|
+
return cookie(name, '', { maxAge: 0, httpOnly: options.httpOnly });
|
|
38
|
+
}
|
|
39
|
+
function readCookies(request) {
|
|
40
|
+
const map = new Map();
|
|
41
|
+
const header = request.headers.get('cookie') || '';
|
|
42
|
+
for (const segment of header.split(';')) {
|
|
43
|
+
const [rawName, ...rest] = segment.split('=');
|
|
44
|
+
const name = rawName?.trim();
|
|
45
|
+
if (!name)
|
|
46
|
+
continue;
|
|
47
|
+
try {
|
|
48
|
+
map.set(name, decodeURIComponent(rest.join('=').trim()));
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
map.set(name, rest.join('=').trim());
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return map;
|
|
55
|
+
}
|
|
56
|
+
function requestToUrl(request) {
|
|
57
|
+
return new URL(request.url);
|
|
58
|
+
}
|
|
59
|
+
function json(data, init = {}, extraCookies = []) {
|
|
60
|
+
const headers = new Headers(init.headers);
|
|
61
|
+
headers.set('Content-Type', 'application/json');
|
|
62
|
+
for (const item of extraCookies) {
|
|
63
|
+
headers.append('Set-Cookie', item);
|
|
64
|
+
}
|
|
65
|
+
return new Response(JSON.stringify(data), { ...init, headers });
|
|
66
|
+
}
|
|
67
|
+
function redirect(location, cookies = []) {
|
|
68
|
+
const headers = new Headers({ Location: location });
|
|
69
|
+
for (const item of cookies)
|
|
70
|
+
headers.append('Set-Cookie', item);
|
|
71
|
+
return new Response(null, { status: 302, headers });
|
|
72
|
+
}
|
|
73
|
+
async function resolveRedirect(config, target, requestUrl) {
|
|
74
|
+
const baseUrl = new URL(requestUrl).origin;
|
|
75
|
+
let location = (0, middleware_security_1.isSafeRedirectLocation)(target, requestUrl) ? target : '/';
|
|
76
|
+
if (config.callbacks?.redirect) {
|
|
77
|
+
location = await config.callbacks.redirect({ url: location, baseUrl });
|
|
78
|
+
if (!(0, middleware_security_1.isSafeRedirectLocation)(location, requestUrl)) {
|
|
79
|
+
location = '/';
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return location;
|
|
83
|
+
}
|
|
84
|
+
async function createSessionCookie(config, user) {
|
|
85
|
+
const now = Math.floor(Date.now() / 1000);
|
|
86
|
+
let payload = {
|
|
87
|
+
user,
|
|
88
|
+
expires: new Date((now + config.session.maxAge) * 1000).toISOString(),
|
|
89
|
+
iat: now,
|
|
90
|
+
exp: now + config.session.maxAge,
|
|
91
|
+
};
|
|
92
|
+
if (config.callbacks?.jwt) {
|
|
93
|
+
payload = await config.callbacks.jwt({ token: payload, user });
|
|
94
|
+
}
|
|
95
|
+
let session = { user: payload.user, expires: payload.expires };
|
|
96
|
+
if (config.callbacks?.session) {
|
|
97
|
+
session = await config.callbacks.session({ session, token: payload });
|
|
98
|
+
}
|
|
99
|
+
const token = (0, core_1.encryptJwt)(payload, config.secret);
|
|
100
|
+
return {
|
|
101
|
+
session,
|
|
102
|
+
cookie: cookie(config.session.cookieName, token, { maxAge: config.session.maxAge }),
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
async function readSessionFromRequest(request, config) {
|
|
106
|
+
const token = readCookies(request).get(config.session.cookieName);
|
|
107
|
+
if (!token)
|
|
108
|
+
return null;
|
|
109
|
+
const payload = (0, core_1.decryptJwt)(token, config.secret);
|
|
110
|
+
if (!payload?.user)
|
|
111
|
+
return null;
|
|
112
|
+
let session = { user: payload.user, expires: payload.expires };
|
|
113
|
+
if (config.callbacks?.session) {
|
|
114
|
+
session = await config.callbacks.session({ session, token: payload });
|
|
115
|
+
}
|
|
116
|
+
return session;
|
|
117
|
+
}
|
|
118
|
+
async function exchangeOAuth(provider, code, redirectUri, verifier) {
|
|
119
|
+
const body = new URLSearchParams({
|
|
120
|
+
client_id: provider.clientId,
|
|
121
|
+
client_secret: provider.clientSecret,
|
|
122
|
+
code,
|
|
123
|
+
redirect_uri: redirectUri,
|
|
124
|
+
grant_type: 'authorization_code',
|
|
125
|
+
code_verifier: verifier,
|
|
126
|
+
});
|
|
127
|
+
const tokenResponse = await fetch(provider.token, {
|
|
128
|
+
method: 'POST',
|
|
129
|
+
headers: { Accept: 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
130
|
+
body,
|
|
131
|
+
});
|
|
132
|
+
const tokenJson = (await tokenResponse.json());
|
|
133
|
+
if (!tokenJson.access_token) {
|
|
134
|
+
throw new Error(`${provider.id} token exchange failed`);
|
|
135
|
+
}
|
|
136
|
+
const profileResponse = await fetch(provider.userinfo, {
|
|
137
|
+
headers: { Authorization: `Bearer ${tokenJson.access_token}`, Accept: 'application/json' },
|
|
138
|
+
});
|
|
139
|
+
const profile = await profileResponse.json();
|
|
140
|
+
return provider.profile(profile);
|
|
141
|
+
}
|
|
142
|
+
function findProvider(config, id) {
|
|
143
|
+
return config.providers.find((provider) => provider.id === id);
|
|
144
|
+
}
|
|
145
|
+
async function handleAuthRequest(request, config) {
|
|
146
|
+
const url = requestToUrl(request);
|
|
147
|
+
const basePath = config.basePath.replace(/\/$/, '');
|
|
148
|
+
let rest = url.pathname.startsWith(basePath) ? url.pathname.slice(basePath.length) : url.pathname;
|
|
149
|
+
if (rest.startsWith('/'))
|
|
150
|
+
rest = rest.slice(1);
|
|
151
|
+
const [action, providerId] = rest.split('/');
|
|
152
|
+
const origin = url.origin;
|
|
153
|
+
const cookies = readCookies(request);
|
|
154
|
+
const method = request.method.toUpperCase();
|
|
155
|
+
if (action === 'session' && method === 'GET') {
|
|
156
|
+
const session = await readSessionFromRequest(request, config);
|
|
157
|
+
return json(session ? { user: session.user, expires: session.expires } : { user: null });
|
|
158
|
+
}
|
|
159
|
+
if (action === 'csrf' && method === 'GET') {
|
|
160
|
+
const token = cookies.get(CSRF_COOKIE) || (0, core_1.randomToken)(24);
|
|
161
|
+
return json({ csrfToken: token }, {}, [cookie(CSRF_COOKIE, token, { httpOnly: false, maxAge: 60 * 60 })]);
|
|
162
|
+
}
|
|
163
|
+
if (action === 'providers' && method === 'GET') {
|
|
164
|
+
const providers = Object.fromEntries(config.providers.map((provider) => [provider.id, { id: provider.id, name: provider.name, type: provider.type }]));
|
|
165
|
+
return json(providers);
|
|
166
|
+
}
|
|
167
|
+
if (action === 'signout' && (method === 'POST' || method === 'GET')) {
|
|
168
|
+
return redirect(config.pages?.signIn || '/', [
|
|
169
|
+
expiredCookie(config.session.cookieName),
|
|
170
|
+
expiredCookie(CSRF_COOKIE, { httpOnly: false }),
|
|
171
|
+
]);
|
|
172
|
+
}
|
|
173
|
+
if (action === 'signin' && method === 'GET' && !providerId) {
|
|
174
|
+
const page = config.pages?.signIn;
|
|
175
|
+
if (page)
|
|
176
|
+
return redirect(page);
|
|
177
|
+
const buttons = config.providers
|
|
178
|
+
.map((provider) => `<p><a href="${basePath}/signin/${provider.id}">Continue with ${provider.name}</a></p>`)
|
|
179
|
+
.join('');
|
|
180
|
+
return new Response(`<!doctype html><html><body><h1>Sign in</h1>${buttons}</body></html>`, { headers: { 'Content-Type': 'text/html; charset=utf-8' } });
|
|
181
|
+
}
|
|
182
|
+
if (action === 'signin' && providerId) {
|
|
183
|
+
const provider = findProvider(config, providerId);
|
|
184
|
+
if (!provider) {
|
|
185
|
+
return json({ error: 'Unknown provider' }, { status: 400 });
|
|
186
|
+
}
|
|
187
|
+
if (provider.type === 'credentials') {
|
|
188
|
+
if (method !== 'POST') {
|
|
189
|
+
return json({ error: 'Credentials sign-in requires POST' }, { status: 405 });
|
|
190
|
+
}
|
|
191
|
+
const contentType = request.headers.get('content-type') || '';
|
|
192
|
+
let credentials = {};
|
|
193
|
+
try {
|
|
194
|
+
if (contentType.includes('application/json')) {
|
|
195
|
+
credentials = (await request.json()) || {};
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
const form = await request.formData();
|
|
199
|
+
credentials = Object.fromEntries(Array.from(form.entries()).map(([key, value]) => [key, String(value)]));
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
catch {
|
|
203
|
+
return json({ error: 'Invalid credentials payload' }, { status: 400 });
|
|
204
|
+
}
|
|
205
|
+
const csrfHeader = request.headers.get('x-csrf-token') ||
|
|
206
|
+
url.searchParams.get('csrfToken') ||
|
|
207
|
+
credentials.csrfToken ||
|
|
208
|
+
'';
|
|
209
|
+
const csrfCookie = cookies.get(CSRF_COOKIE) || '';
|
|
210
|
+
if (!csrfCookie || csrfHeader !== csrfCookie) {
|
|
211
|
+
return json({ error: 'Invalid CSRF token' }, { status: 403 });
|
|
212
|
+
}
|
|
213
|
+
const user = await provider.authorize(credentials);
|
|
214
|
+
if (!user) {
|
|
215
|
+
return json({ error: 'Invalid credentials' }, { status: 401 });
|
|
216
|
+
}
|
|
217
|
+
if (config.callbacks?.signIn && !(await config.callbacks.signIn({ user }))) {
|
|
218
|
+
return json({ error: 'Access denied' }, { status: 403 });
|
|
219
|
+
}
|
|
220
|
+
const created = await createSessionCookie(config, user);
|
|
221
|
+
const redirectTo = credentials.callbackUrl || url.searchParams.get('callbackUrl') || '/';
|
|
222
|
+
const safeRedirect = await resolveRedirect(config, redirectTo, url.toString());
|
|
223
|
+
return redirect(safeRedirect, [created.cookie]);
|
|
224
|
+
}
|
|
225
|
+
const { verifier, challenge } = (0, core_1.pkcePair)();
|
|
226
|
+
const state = (0, core_1.randomToken)(16);
|
|
227
|
+
const callbackUrl = url.searchParams.get('callbackUrl') || '/';
|
|
228
|
+
const redirectUri = `${origin}${basePath}/callback/${provider.id}`;
|
|
229
|
+
const params = new URLSearchParams({
|
|
230
|
+
client_id: provider.clientId,
|
|
231
|
+
redirect_uri: redirectUri,
|
|
232
|
+
response_type: 'code',
|
|
233
|
+
state,
|
|
234
|
+
code_challenge: challenge,
|
|
235
|
+
code_challenge_method: 'S256',
|
|
236
|
+
...provider.authorization.params,
|
|
237
|
+
});
|
|
238
|
+
return redirect(`${provider.authorization.url}?${params.toString()}`, [
|
|
239
|
+
cookie(STATE_COOKIE, state, { maxAge: 600 }),
|
|
240
|
+
cookie(PKCE_COOKIE, verifier, { maxAge: 600 }),
|
|
241
|
+
cookie(CALLBACK_COOKIE, callbackUrl, { maxAge: 600 }),
|
|
242
|
+
]);
|
|
243
|
+
}
|
|
244
|
+
if (action === 'callback' && providerId) {
|
|
245
|
+
const provider = findProvider(config, providerId);
|
|
246
|
+
if (!provider || provider.type !== 'oauth') {
|
|
247
|
+
return json({ error: 'Unknown provider' }, { status: 400 });
|
|
248
|
+
}
|
|
249
|
+
const state = url.searchParams.get('state');
|
|
250
|
+
if (!state || state !== cookies.get(STATE_COOKIE)) {
|
|
251
|
+
return json({ error: 'Invalid OAuth state' }, { status: 403 });
|
|
252
|
+
}
|
|
253
|
+
const code = url.searchParams.get('code');
|
|
254
|
+
const verifier = cookies.get(PKCE_COOKIE);
|
|
255
|
+
if (!code || !verifier) {
|
|
256
|
+
return json({ error: 'Missing OAuth code' }, { status: 400 });
|
|
257
|
+
}
|
|
258
|
+
const redirectUri = `${origin}${basePath}/callback/${provider.id}`;
|
|
259
|
+
const user = await exchangeOAuth(provider, code, redirectUri, verifier);
|
|
260
|
+
if (config.adapter?.getUserByAccount) {
|
|
261
|
+
const existing = await config.adapter.getUserByAccount(provider.id, user.id);
|
|
262
|
+
if (existing) {
|
|
263
|
+
user.id = existing.id;
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
await config.adapter.createUser?.(user);
|
|
267
|
+
await config.adapter.linkAccount?.(user.id, {
|
|
268
|
+
provider: provider.id,
|
|
269
|
+
type: 'oauth',
|
|
270
|
+
providerAccountId: user.id,
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
if (config.callbacks?.signIn && !(await config.callbacks.signIn({ user }))) {
|
|
275
|
+
return json({ error: 'Access denied' }, { status: 403 });
|
|
276
|
+
}
|
|
277
|
+
const created = await createSessionCookie(config, user);
|
|
278
|
+
const callbackUrl = cookies.get(CALLBACK_COOKIE) || '/';
|
|
279
|
+
const safeRedirect = await resolveRedirect(config, callbackUrl, url.toString());
|
|
280
|
+
return redirect(safeRedirect, [
|
|
281
|
+
created.cookie,
|
|
282
|
+
expiredCookie(STATE_COOKIE),
|
|
283
|
+
expiredCookie(PKCE_COOKIE),
|
|
284
|
+
expiredCookie(CALLBACK_COOKIE),
|
|
285
|
+
]);
|
|
286
|
+
}
|
|
287
|
+
return json({ error: 'Not found' }, { status: 404 });
|
|
288
|
+
}
|
|
289
|
+
function VistaAuth(config) {
|
|
290
|
+
const resolved = (0, core_1.resolveAuthConfig)(config);
|
|
291
|
+
const handlers = {
|
|
292
|
+
GET: (request) => handleAuthRequest(request, resolved),
|
|
293
|
+
POST: (request) => handleAuthRequest(request, resolved),
|
|
294
|
+
};
|
|
295
|
+
async function auth(request) {
|
|
296
|
+
if (request) {
|
|
297
|
+
return readSessionFromRequest(request, resolved);
|
|
298
|
+
}
|
|
299
|
+
const context = (0, request_context_1.getRequestContext)();
|
|
300
|
+
if (!context?.req)
|
|
301
|
+
return null;
|
|
302
|
+
const host = context.req.get?.('host') || context.req.headers?.host || 'localhost';
|
|
303
|
+
const protocol = context.req.protocol || 'http';
|
|
304
|
+
const headers = new Headers();
|
|
305
|
+
if (context.req.headers?.cookie)
|
|
306
|
+
headers.set('cookie', String(context.req.headers.cookie));
|
|
307
|
+
const fake = new Request(`${protocol}://${host}${context.req.originalUrl || context.req.url || '/'}`, {
|
|
308
|
+
headers,
|
|
309
|
+
});
|
|
310
|
+
return readSessionFromRequest(fake, resolved);
|
|
311
|
+
}
|
|
312
|
+
async function signIn(providerId, options = {}) {
|
|
313
|
+
const context = (0, request_context_1.getRequestContext)();
|
|
314
|
+
const host = context?.req?.get?.('host') || 'localhost';
|
|
315
|
+
const protocol = context?.req?.protocol || 'http';
|
|
316
|
+
if (providerId) {
|
|
317
|
+
const provider = findProvider(resolved, providerId);
|
|
318
|
+
if (provider?.type === 'credentials') {
|
|
319
|
+
const user = await provider.authorize(options);
|
|
320
|
+
if (!user) {
|
|
321
|
+
return json({ error: 'Invalid credentials' }, { status: 401 });
|
|
322
|
+
}
|
|
323
|
+
if (resolved.callbacks?.signIn && !(await resolved.callbacks.signIn({ user }))) {
|
|
324
|
+
return json({ error: 'Access denied' }, { status: 403 });
|
|
325
|
+
}
|
|
326
|
+
const created = await createSessionCookie(resolved, user);
|
|
327
|
+
const requestUrl = `${protocol}://${host}/`;
|
|
328
|
+
const safeRedirect = await resolveRedirect(resolved, options.callbackUrl || '/', requestUrl);
|
|
329
|
+
return redirect(safeRedirect, [created.cookie]);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
const url = new URL(`${protocol}://${host}${resolved.basePath}/signin${providerId ? `/${providerId}` : ''}`);
|
|
333
|
+
for (const [key, value] of Object.entries(options)) {
|
|
334
|
+
url.searchParams.set(key, value);
|
|
335
|
+
}
|
|
336
|
+
const headers = new Headers();
|
|
337
|
+
if (context?.req?.headers?.cookie)
|
|
338
|
+
headers.set('cookie', String(context.req.headers.cookie));
|
|
339
|
+
return handleAuthRequest(new Request(url, { method: 'GET', headers }), resolved);
|
|
340
|
+
}
|
|
341
|
+
async function signOut() {
|
|
342
|
+
const context = (0, request_context_1.getRequestContext)();
|
|
343
|
+
const host = context?.req?.get?.('host') || 'localhost';
|
|
344
|
+
const protocol = context?.req?.protocol || 'http';
|
|
345
|
+
return handleAuthRequest(new Request(`${protocol}://${host}${resolved.basePath}/signout`, { method: 'POST' }), resolved);
|
|
346
|
+
}
|
|
347
|
+
function authMiddleware(authorized) {
|
|
348
|
+
const callback = authorized || resolved.callbacks?.authorized;
|
|
349
|
+
return async ({ request, next }) => {
|
|
350
|
+
const webRequest = request instanceof Request
|
|
351
|
+
? request
|
|
352
|
+
: new Request(request.url, { headers: request.headers, method: request.method });
|
|
353
|
+
const session = await readSessionFromRequest(webRequest, resolved);
|
|
354
|
+
if (!callback) {
|
|
355
|
+
return next();
|
|
356
|
+
}
|
|
357
|
+
const result = await callback({ auth: session, request: webRequest });
|
|
358
|
+
if (result instanceof Response)
|
|
359
|
+
return result;
|
|
360
|
+
if (result === false) {
|
|
361
|
+
const signInPage = resolved.pages?.signIn || `${resolved.basePath}/signin`;
|
|
362
|
+
return new Response(null, { status: 307, headers: { Location: signInPage } });
|
|
363
|
+
}
|
|
364
|
+
return next();
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
return { handlers, auth, signIn, signOut, authMiddleware, config: resolved };
|
|
368
|
+
}
|
|
369
|
+
exports.default = VistaAuth;
|