@alepha/react 0.5.0 → 0.5.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/dist/index.browser.cjs +34 -0
- package/dist/index.browser.js +17 -0
- package/dist/index.cjs +499 -0
- package/dist/index.d.ts +872 -0
- package/dist/index.js +476 -0
- package/dist/useRouterState-BlKHWZwk.cjs +944 -0
- package/dist/useRouterState-CvFCmaq7.js +926 -0
- package/package.json +15 -19
- package/src/providers/ReactServerProvider.ts +1 -1
- package/test/$page.spec.tsx +0 -42
- package/test/Router.spec.tsx +0 -138
- package/tsconfig.json +0 -6
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var core = require('@alepha/core');
|
|
4
|
+
var useRouterState = require('./useRouterState-BlKHWZwk.cjs');
|
|
5
|
+
require('react');
|
|
6
|
+
require('@alepha/server');
|
|
7
|
+
require('react-dom/client');
|
|
8
|
+
require('path-to-regexp');
|
|
9
|
+
|
|
10
|
+
class ReactModule {
|
|
11
|
+
alepha = core.$inject(core.Alepha);
|
|
12
|
+
constructor() {
|
|
13
|
+
this.alepha.with(useRouterState.PageDescriptorProvider).with(useRouterState.ReactBrowserProvider);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
core.autoInject(useRouterState.$page, ReactModule);
|
|
17
|
+
|
|
18
|
+
exports.$page = useRouterState.$page;
|
|
19
|
+
exports.NestedView = useRouterState.NestedView;
|
|
20
|
+
exports.ReactBrowserProvider = useRouterState.ReactBrowserProvider;
|
|
21
|
+
exports.RedirectException = useRouterState.RedirectException;
|
|
22
|
+
exports.Router = useRouterState.Router;
|
|
23
|
+
exports.RouterContext = useRouterState.RouterContext;
|
|
24
|
+
exports.RouterHookApi = useRouterState.RouterHookApi;
|
|
25
|
+
exports.RouterLayerContext = useRouterState.RouterLayerContext;
|
|
26
|
+
exports.pageDescriptorKey = useRouterState.pageDescriptorKey;
|
|
27
|
+
exports.useActive = useRouterState.useActive;
|
|
28
|
+
exports.useClient = useRouterState.useClient;
|
|
29
|
+
exports.useInject = useRouterState.useInject;
|
|
30
|
+
exports.useQueryParams = useRouterState.useQueryParams;
|
|
31
|
+
exports.useRouter = useRouterState.useRouter;
|
|
32
|
+
exports.useRouterEvents = useRouterState.useRouterEvents;
|
|
33
|
+
exports.useRouterState = useRouterState.useRouterState;
|
|
34
|
+
exports.ReactModule = ReactModule;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { autoInject, $inject, Alepha } from '@alepha/core';
|
|
2
|
+
import { $ as $page, P as PageDescriptorProvider, k as ReactBrowserProvider } from './useRouterState-CvFCmaq7.js';
|
|
3
|
+
export { N as NestedView, j as RedirectException, R as Router, a as RouterContext, f as RouterHookApi, b as RouterLayerContext, p as pageDescriptorKey, u as useActive, c as useClient, d as useInject, e as useQueryParams, g as useRouter, h as useRouterEvents, i as useRouterState } from './useRouterState-CvFCmaq7.js';
|
|
4
|
+
import 'react';
|
|
5
|
+
import '@alepha/server';
|
|
6
|
+
import 'react-dom/client';
|
|
7
|
+
import 'path-to-regexp';
|
|
8
|
+
|
|
9
|
+
class ReactModule {
|
|
10
|
+
alepha = $inject(Alepha);
|
|
11
|
+
constructor() {
|
|
12
|
+
this.alepha.with(PageDescriptorProvider).with(ReactBrowserProvider);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
autoInject($page, ReactModule);
|
|
16
|
+
|
|
17
|
+
export { $page, ReactBrowserProvider, ReactModule };
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,499 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var core = require('@alepha/core');
|
|
4
|
+
var server = require('@alepha/server');
|
|
5
|
+
var useRouterState = require('./useRouterState-BlKHWZwk.cjs');
|
|
6
|
+
var node_fs = require('node:fs');
|
|
7
|
+
var promises = require('node:fs/promises');
|
|
8
|
+
var node_path = require('node:path');
|
|
9
|
+
var server$1 = require('react-dom/server');
|
|
10
|
+
var crypto = require('node:crypto');
|
|
11
|
+
var cache = require('@alepha/cache');
|
|
12
|
+
var security = require('@alepha/security');
|
|
13
|
+
var openidClient = require('openid-client');
|
|
14
|
+
require('react');
|
|
15
|
+
require('react-dom/client');
|
|
16
|
+
require('path-to-regexp');
|
|
17
|
+
|
|
18
|
+
const envSchema$1 = core.t.object({
|
|
19
|
+
REACT_SERVER_DIST: core.t.string({ default: "client" }),
|
|
20
|
+
REACT_SERVER_PREFIX: core.t.string({ default: "" }),
|
|
21
|
+
REACT_SSR_ENABLED: core.t.boolean({ default: false }),
|
|
22
|
+
REACT_SSR_OUTLET: core.t.string({ default: "<!--ssr-outlet-->" })
|
|
23
|
+
});
|
|
24
|
+
class ReactServerProvider {
|
|
25
|
+
log = core.$logger();
|
|
26
|
+
alepha = core.$inject(core.Alepha);
|
|
27
|
+
router = core.$inject(useRouterState.Router);
|
|
28
|
+
server = core.$inject(server.ServerProvider);
|
|
29
|
+
env = core.$inject(envSchema$1);
|
|
30
|
+
configure = core.$hook({
|
|
31
|
+
name: "configure",
|
|
32
|
+
handler: async () => {
|
|
33
|
+
await this.configureRoutes();
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
async configureRoutes() {
|
|
37
|
+
if (this.alepha.isTest()) {
|
|
38
|
+
this.processDescriptors();
|
|
39
|
+
}
|
|
40
|
+
if (this.router.empty()) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (process.env.VITE_ALEPHA_DEV === "true") {
|
|
44
|
+
this.log.info("SSR starting in development mode");
|
|
45
|
+
const templateUrl = `${this.server.hostname}/index.html`;
|
|
46
|
+
this.log.debug(`Fetch template from ${templateUrl}`);
|
|
47
|
+
const route2 = this.createHandler(
|
|
48
|
+
() => fetch(templateUrl).then((it) => it.text()).catch(() => void 0)
|
|
49
|
+
);
|
|
50
|
+
await this.server.route(route2);
|
|
51
|
+
await this.server.route({
|
|
52
|
+
url: "*",
|
|
53
|
+
handler: route2.handler
|
|
54
|
+
});
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const maybe = [
|
|
58
|
+
node_path.join(process.cwd(), this.env.REACT_SERVER_DIST),
|
|
59
|
+
node_path.join(process.cwd(), "..", this.env.REACT_SERVER_DIST),
|
|
60
|
+
node_path.join(process.cwd(), "dist", this.env.REACT_SERVER_DIST)
|
|
61
|
+
];
|
|
62
|
+
let root = "";
|
|
63
|
+
for (const it of maybe) {
|
|
64
|
+
if (node_fs.existsSync(it)) {
|
|
65
|
+
root = it;
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (!root) {
|
|
70
|
+
this.log.warn("Missing static files, SSR will be disabled");
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
await this.server.serve(this.createStaticHandler(root));
|
|
74
|
+
const template = await promises.readFile(node_path.join(root, "index.html"), "utf-8");
|
|
75
|
+
const route = this.createHandler(async () => template);
|
|
76
|
+
await this.server.route(route);
|
|
77
|
+
await this.server.route({
|
|
78
|
+
url: "/*",
|
|
79
|
+
// alias for "not found handler"
|
|
80
|
+
handler: route.handler
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
*
|
|
85
|
+
* @param root
|
|
86
|
+
* @protected
|
|
87
|
+
*/
|
|
88
|
+
createStaticHandler(root) {
|
|
89
|
+
return {
|
|
90
|
+
root,
|
|
91
|
+
prefix: this.env.REACT_SERVER_PREFIX,
|
|
92
|
+
logLevel: "warn",
|
|
93
|
+
cacheControl: true,
|
|
94
|
+
immutable: true,
|
|
95
|
+
preCompressed: true,
|
|
96
|
+
maxAge: "30d",
|
|
97
|
+
index: false
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
*
|
|
102
|
+
* @param templateLoader
|
|
103
|
+
* @protected
|
|
104
|
+
*/
|
|
105
|
+
createHandler(templateLoader) {
|
|
106
|
+
return {
|
|
107
|
+
url: "/",
|
|
108
|
+
handler: async ({ url, user }) => {
|
|
109
|
+
const template = await templateLoader();
|
|
110
|
+
if (!template) {
|
|
111
|
+
return new Response("Not found", { status: 404 });
|
|
112
|
+
}
|
|
113
|
+
const response = this.notFoundHandler(url);
|
|
114
|
+
if (response) {
|
|
115
|
+
return response;
|
|
116
|
+
}
|
|
117
|
+
return await this.ssr(url, template, user);
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
processDescriptors() {
|
|
122
|
+
const pages = this.alepha.getDescriptorValues(useRouterState.$page);
|
|
123
|
+
for (const { key, instance, value } of pages) {
|
|
124
|
+
instance[key].render = async (options = {}) => {
|
|
125
|
+
const name = value.options.name ?? key;
|
|
126
|
+
const page = this.router.page(name);
|
|
127
|
+
const layers = await this.router.createLayers(
|
|
128
|
+
"",
|
|
129
|
+
page,
|
|
130
|
+
options.params ?? {},
|
|
131
|
+
options.query ?? {},
|
|
132
|
+
[]
|
|
133
|
+
);
|
|
134
|
+
return server$1.renderToString(
|
|
135
|
+
this.router.root({
|
|
136
|
+
layers,
|
|
137
|
+
pathname: "",
|
|
138
|
+
search: ""
|
|
139
|
+
})
|
|
140
|
+
);
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
*
|
|
146
|
+
* @param url
|
|
147
|
+
* @protected
|
|
148
|
+
*/
|
|
149
|
+
notFoundHandler(url) {
|
|
150
|
+
if (url.match(/\.\w+$/)) {
|
|
151
|
+
return new Response("Not found", { status: 404 });
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
*
|
|
156
|
+
* @param url
|
|
157
|
+
* @param template
|
|
158
|
+
* @param user
|
|
159
|
+
*/
|
|
160
|
+
async ssr(url, template = this.env.REACT_SSR_OUTLET, user) {
|
|
161
|
+
const { element, layers, redirect } = await this.router.render(url, {
|
|
162
|
+
user
|
|
163
|
+
});
|
|
164
|
+
if (redirect) {
|
|
165
|
+
return new Response("", {
|
|
166
|
+
status: 302,
|
|
167
|
+
headers: {
|
|
168
|
+
Location: redirect
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
const appHtml = server$1.renderToString(element);
|
|
173
|
+
const script = `<script>window.__ssr=${JSON.stringify({
|
|
174
|
+
layers: layers.map((it) => ({
|
|
175
|
+
...it,
|
|
176
|
+
index: void 0,
|
|
177
|
+
path: void 0,
|
|
178
|
+
element: void 0
|
|
179
|
+
})),
|
|
180
|
+
session: {
|
|
181
|
+
user: user ? {
|
|
182
|
+
id: user.id,
|
|
183
|
+
name: user.name
|
|
184
|
+
} : void 0
|
|
185
|
+
}
|
|
186
|
+
})}<\/script>`;
|
|
187
|
+
const index = template.indexOf("</body>");
|
|
188
|
+
if (index !== -1) {
|
|
189
|
+
template = template.slice(0, index) + script + template.slice(index);
|
|
190
|
+
}
|
|
191
|
+
return new Response(template.replace(this.env.REACT_SSR_OUTLET, appHtml), {
|
|
192
|
+
headers: { "Content-Type": "text/html" }
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const sessionUserSchema = core.t.object({
|
|
198
|
+
id: core.t.string(),
|
|
199
|
+
name: core.t.optional(core.t.string())
|
|
200
|
+
});
|
|
201
|
+
const sessionSchema = core.t.object({
|
|
202
|
+
user: core.t.optional(sessionUserSchema)
|
|
203
|
+
});
|
|
204
|
+
const envSchema = core.t.object({
|
|
205
|
+
REACT_OIDC_ISSUER: core.t.optional(core.t.string()),
|
|
206
|
+
REACT_OIDC_CLIENT_ID: core.t.optional(core.t.string()),
|
|
207
|
+
REACT_OIDC_CLIENT_SECRET: core.t.optional(core.t.string()),
|
|
208
|
+
REACT_OIDC_REDIRECT_URI: core.t.optional(core.t.string())
|
|
209
|
+
});
|
|
210
|
+
class ReactSessionProvider {
|
|
211
|
+
SSID = "ssid";
|
|
212
|
+
log = core.$logger();
|
|
213
|
+
env = core.$inject(envSchema);
|
|
214
|
+
serverProvider = core.$inject(server.ServerProvider);
|
|
215
|
+
securityProvider = core.$inject(security.SecurityProvider);
|
|
216
|
+
sessions = cache.$cache();
|
|
217
|
+
clients = [];
|
|
218
|
+
get redirectUri() {
|
|
219
|
+
return this.env.REACT_OIDC_REDIRECT_URI ?? `${this.serverProvider.hostname}/api/callback`;
|
|
220
|
+
}
|
|
221
|
+
configure = core.$hook({
|
|
222
|
+
name: "configure",
|
|
223
|
+
priority: 100,
|
|
224
|
+
handler: async () => {
|
|
225
|
+
const issuer = this.env.REACT_OIDC_ISSUER;
|
|
226
|
+
const clientId = this.env.REACT_OIDC_CLIENT_ID;
|
|
227
|
+
if (!issuer || !clientId) {
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
const client = await openidClient.discovery(
|
|
231
|
+
new URL(issuer),
|
|
232
|
+
clientId,
|
|
233
|
+
{
|
|
234
|
+
client_secret: this.env.REACT_OIDC_CLIENT_SECRET
|
|
235
|
+
},
|
|
236
|
+
void 0,
|
|
237
|
+
{
|
|
238
|
+
execute: [openidClient.allowInsecureRequests]
|
|
239
|
+
}
|
|
240
|
+
);
|
|
241
|
+
this.clients = [client];
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
/**
|
|
245
|
+
*
|
|
246
|
+
* @param sessionId
|
|
247
|
+
* @param session
|
|
248
|
+
* @protected
|
|
249
|
+
*/
|
|
250
|
+
async setSession(sessionId, session) {
|
|
251
|
+
await this.sessions.set(sessionId, session, {
|
|
252
|
+
days: 1
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
*
|
|
257
|
+
* @param sessionId
|
|
258
|
+
* @protected
|
|
259
|
+
*/
|
|
260
|
+
async getSession(sessionId) {
|
|
261
|
+
const session = await this.sessions.get(sessionId);
|
|
262
|
+
if (!session) {
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
const now = Date.now();
|
|
266
|
+
if (session.expires_in && session.issued_at) {
|
|
267
|
+
const expiresAt = session.issued_at + (session.expires_in - 10) * 1e3;
|
|
268
|
+
if (expiresAt < now) {
|
|
269
|
+
if (session.refresh_token) {
|
|
270
|
+
try {
|
|
271
|
+
const newTokens = await openidClient.refreshTokenGrant(
|
|
272
|
+
this.clients[0],
|
|
273
|
+
session.refresh_token
|
|
274
|
+
);
|
|
275
|
+
await this.setSession(sessionId, {
|
|
276
|
+
...newTokens,
|
|
277
|
+
issued_at: Date.now()
|
|
278
|
+
});
|
|
279
|
+
return newTokens;
|
|
280
|
+
} catch (e) {
|
|
281
|
+
this.log.error(e, "Failed to refresh token");
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
await this.sessions.invalidate(sessionId);
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
if (!session.issued_at && session.access_token) {
|
|
289
|
+
await this.sessions.invalidate(sessionId);
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
return session;
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
*
|
|
296
|
+
* @protected
|
|
297
|
+
*/
|
|
298
|
+
beforeRequest = core.$hook({
|
|
299
|
+
name: "configure:fastify",
|
|
300
|
+
priority: 100,
|
|
301
|
+
handler: async (app) => {
|
|
302
|
+
app.decorateRequest("session");
|
|
303
|
+
app.addHook("onRequest", async (req) => {
|
|
304
|
+
const sessionId = req.cookies[this.SSID];
|
|
305
|
+
if (sessionId && !isViteFile(req.url)) {
|
|
306
|
+
const session = await this.getSession(sessionId);
|
|
307
|
+
if (session) {
|
|
308
|
+
req.session = session;
|
|
309
|
+
if (session.access_token) {
|
|
310
|
+
req.headers.authorization = `Bearer ${session.access_token}`;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
/**
|
|
318
|
+
*
|
|
319
|
+
*/
|
|
320
|
+
login = server.$route({
|
|
321
|
+
security: false,
|
|
322
|
+
url: "/login",
|
|
323
|
+
method: "GET",
|
|
324
|
+
schema: {
|
|
325
|
+
query: core.t.object({
|
|
326
|
+
redirect: core.t.optional(core.t.string())
|
|
327
|
+
})
|
|
328
|
+
},
|
|
329
|
+
handler: async ({ query }) => {
|
|
330
|
+
const client = this.clients[0];
|
|
331
|
+
const codeVerifier = openidClient.randomPKCECodeVerifier();
|
|
332
|
+
const codeChallenge = await openidClient.calculatePKCECodeChallenge(codeVerifier);
|
|
333
|
+
const scope = "openid profile email";
|
|
334
|
+
const parameters = {
|
|
335
|
+
redirect_uri: this.redirectUri,
|
|
336
|
+
scope,
|
|
337
|
+
code_challenge: codeChallenge,
|
|
338
|
+
code_challenge_method: "S256"
|
|
339
|
+
};
|
|
340
|
+
const sessionId = crypto.randomUUID();
|
|
341
|
+
await this.setSession(sessionId, {
|
|
342
|
+
authorizationCodeGrant: {
|
|
343
|
+
codeVerifier,
|
|
344
|
+
redirectUri: query.redirect ?? "/"
|
|
345
|
+
// TODO: add nonce, max_age, state
|
|
346
|
+
}
|
|
347
|
+
});
|
|
348
|
+
return new Response("", {
|
|
349
|
+
status: 302,
|
|
350
|
+
headers: {
|
|
351
|
+
"Set-Cookie": `${this.SSID}=${sessionId}; HttpOnly; Path=/; SameSite=Lax;`,
|
|
352
|
+
Location: openidClient.buildAuthorizationUrl(client, parameters).toString()
|
|
353
|
+
}
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
});
|
|
357
|
+
/**
|
|
358
|
+
*
|
|
359
|
+
*/
|
|
360
|
+
callback = server.$route({
|
|
361
|
+
security: false,
|
|
362
|
+
url: "/callback",
|
|
363
|
+
method: "GET",
|
|
364
|
+
schema: {
|
|
365
|
+
headers: core.t.record(core.t.string(), core.t.string()),
|
|
366
|
+
cookies: core.t.object({
|
|
367
|
+
ssid: core.t.string()
|
|
368
|
+
})
|
|
369
|
+
},
|
|
370
|
+
handler: async ({ cookies, url }) => {
|
|
371
|
+
const sessionId = cookies.ssid;
|
|
372
|
+
const session = await this.getSession(sessionId);
|
|
373
|
+
if (!session) {
|
|
374
|
+
throw new server.BadRequestError("Missing session");
|
|
375
|
+
}
|
|
376
|
+
if (!session.authorizationCodeGrant) {
|
|
377
|
+
throw new server.BadRequestError("Invalid session - missing code verifier");
|
|
378
|
+
}
|
|
379
|
+
const [, search] = url.split("?");
|
|
380
|
+
const tokens = await openidClient.authorizationCodeGrant(
|
|
381
|
+
this.clients[0],
|
|
382
|
+
new URL(`${this.redirectUri}?${search}`),
|
|
383
|
+
{
|
|
384
|
+
pkceCodeVerifier: session.authorizationCodeGrant.codeVerifier,
|
|
385
|
+
expectedNonce: session.authorizationCodeGrant.nonce,
|
|
386
|
+
expectedState: session.authorizationCodeGrant.state,
|
|
387
|
+
maxAge: session.authorizationCodeGrant.max_age
|
|
388
|
+
}
|
|
389
|
+
);
|
|
390
|
+
await this.setSession(sessionId, {
|
|
391
|
+
...tokens,
|
|
392
|
+
issued_at: Date.now()
|
|
393
|
+
});
|
|
394
|
+
return new Response("", {
|
|
395
|
+
status: 302,
|
|
396
|
+
headers: {
|
|
397
|
+
Location: session.authorizationCodeGrant.redirectUri ?? "/"
|
|
398
|
+
}
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
});
|
|
402
|
+
logout = server.$route({
|
|
403
|
+
security: false,
|
|
404
|
+
url: "/logout",
|
|
405
|
+
method: "GET",
|
|
406
|
+
schema: {
|
|
407
|
+
query: core.t.object({
|
|
408
|
+
redirect: core.t.optional(core.t.string())
|
|
409
|
+
}),
|
|
410
|
+
cookies: core.t.object({
|
|
411
|
+
ssid: core.t.string()
|
|
412
|
+
})
|
|
413
|
+
},
|
|
414
|
+
handler: async ({ query, cookies }, { fastify }) => {
|
|
415
|
+
const session = fastify?.req.session;
|
|
416
|
+
await this.sessions.invalidate(cookies.ssid);
|
|
417
|
+
const redirect = query.redirect ?? "/";
|
|
418
|
+
const params = new URLSearchParams();
|
|
419
|
+
params.set("post_logout_redirect_uri", redirect);
|
|
420
|
+
if (session?.id_token) {
|
|
421
|
+
params.set("id_token_hint", session.id_token);
|
|
422
|
+
}
|
|
423
|
+
return new Response("", {
|
|
424
|
+
status: 302,
|
|
425
|
+
headers: {
|
|
426
|
+
"Set-Cookie": `${this.SSID}=; HttpOnly; Path=/; SameSite=Lax;`,
|
|
427
|
+
Location: openidClient.buildEndSessionUrl(this.clients[0], params).toString()
|
|
428
|
+
}
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
});
|
|
432
|
+
session = server.$route({
|
|
433
|
+
security: false,
|
|
434
|
+
url: "/_session",
|
|
435
|
+
method: "GET",
|
|
436
|
+
schema: {
|
|
437
|
+
headers: core.t.object({
|
|
438
|
+
authorization: core.t.string()
|
|
439
|
+
}),
|
|
440
|
+
response: sessionSchema
|
|
441
|
+
},
|
|
442
|
+
handler: async ({ headers }) => {
|
|
443
|
+
try {
|
|
444
|
+
return {
|
|
445
|
+
user: await this.securityProvider.createUserFromToken(
|
|
446
|
+
headers.authorization
|
|
447
|
+
)
|
|
448
|
+
};
|
|
449
|
+
} catch (e) {
|
|
450
|
+
return {};
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
});
|
|
454
|
+
}
|
|
455
|
+
const isViteFile = (file) => {
|
|
456
|
+
const [pathname] = file.split("?");
|
|
457
|
+
if (pathname.startsWith("/docs")) {
|
|
458
|
+
return false;
|
|
459
|
+
}
|
|
460
|
+
if (pathname.match(/\.\w{2,5}$/)) {
|
|
461
|
+
return true;
|
|
462
|
+
}
|
|
463
|
+
if (pathname.startsWith("/@")) {
|
|
464
|
+
return true;
|
|
465
|
+
}
|
|
466
|
+
return false;
|
|
467
|
+
};
|
|
468
|
+
|
|
469
|
+
class ReactModule {
|
|
470
|
+
alepha = core.$inject(core.Alepha);
|
|
471
|
+
constructor() {
|
|
472
|
+
this.alepha.with(server.ServerModule).with(server.ServerLinksProvider).with(ReactServerProvider).with(ReactSessionProvider).with(useRouterState.PageDescriptorProvider);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
core.autoInject(useRouterState.$page, ReactModule);
|
|
476
|
+
|
|
477
|
+
exports.$page = useRouterState.$page;
|
|
478
|
+
exports.NestedView = useRouterState.NestedView;
|
|
479
|
+
exports.PageDescriptorProvider = useRouterState.PageDescriptorProvider;
|
|
480
|
+
exports.ReactBrowserProvider = useRouterState.ReactBrowserProvider;
|
|
481
|
+
exports.RedirectException = useRouterState.RedirectException;
|
|
482
|
+
exports.Router = useRouterState.Router;
|
|
483
|
+
exports.RouterContext = useRouterState.RouterContext;
|
|
484
|
+
exports.RouterHookApi = useRouterState.RouterHookApi;
|
|
485
|
+
exports.RouterLayerContext = useRouterState.RouterLayerContext;
|
|
486
|
+
exports.pageDescriptorKey = useRouterState.pageDescriptorKey;
|
|
487
|
+
exports.useActive = useRouterState.useActive;
|
|
488
|
+
exports.useClient = useRouterState.useClient;
|
|
489
|
+
exports.useInject = useRouterState.useInject;
|
|
490
|
+
exports.useQueryParams = useRouterState.useQueryParams;
|
|
491
|
+
exports.useRouter = useRouterState.useRouter;
|
|
492
|
+
exports.useRouterEvents = useRouterState.useRouterEvents;
|
|
493
|
+
exports.useRouterState = useRouterState.useRouterState;
|
|
494
|
+
exports.ReactModule = ReactModule;
|
|
495
|
+
exports.ReactServerProvider = ReactServerProvider;
|
|
496
|
+
exports.ReactSessionProvider = ReactSessionProvider;
|
|
497
|
+
exports.envSchema = envSchema$1;
|
|
498
|
+
exports.sessionSchema = sessionSchema;
|
|
499
|
+
exports.sessionUserSchema = sessionUserSchema;
|