@server/next 0.47.2 → 0.48.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.ts +4 -9
- package/index.js +116 -91
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -203,7 +203,7 @@ type RedirectOption = string | ((user: any, ctx: Context) => Awaitable<string>)
|
|
|
203
203
|
};
|
|
204
204
|
type AuthConfig<U = AuthProfile> = {
|
|
205
205
|
providers: string | readonly string[] | Record<string, string | ProviderOptions>;
|
|
206
|
-
strategy?: Strategy
|
|
206
|
+
strategy?: Strategy;
|
|
207
207
|
expires?: string;
|
|
208
208
|
redirect?: RedirectOption;
|
|
209
209
|
onLogin?: (profile: AuthProfile, ctx: Context) => Awaitable<string | number | undefined>;
|
|
@@ -224,8 +224,8 @@ type AuthInstance = {
|
|
|
224
224
|
user?: (ctx: Context) => Awaitable<any>;
|
|
225
225
|
};
|
|
226
226
|
type AuthFunction<U = any> = (ctx: Context<any>) => Awaitable<U>;
|
|
227
|
-
type AuthOption = string | AuthFunction | AuthConfig<any> | AuthVerify<any> | AuthInstance
|
|
228
|
-
type UserOf<A> = A extends
|
|
227
|
+
type AuthOption = string | AuthFunction | AuthConfig<any> | AuthVerify<any> | AuthInstance;
|
|
228
|
+
type UserOf<A> = A extends (...args: any[]) => infer R ? NonNullable<Awaited<R>> : A extends {
|
|
229
229
|
getUser: (...args: any[]) => infer R;
|
|
230
230
|
} ? NonNullable<Awaited<R>> : A extends {
|
|
231
231
|
issuer: any;
|
|
@@ -237,7 +237,7 @@ type AuthEntry = {
|
|
|
237
237
|
user: (ctx: Context) => Promise<any>;
|
|
238
238
|
routes?: (app: Server) => void;
|
|
239
239
|
};
|
|
240
|
-
type AuthSettings = AuthEntry
|
|
240
|
+
type AuthSettings = AuthEntry;
|
|
241
241
|
type LogLevel = "info";
|
|
242
242
|
type Logger = {
|
|
243
243
|
level?: LogLevel;
|
|
@@ -596,11 +596,6 @@ declare function server<U>(options: Omit<Options, "auth"> & {
|
|
|
596
596
|
}): Server<{
|
|
597
597
|
user: NonNullable<Awaited<U>>;
|
|
598
598
|
}>;
|
|
599
|
-
declare function server<A extends readonly AuthOption[]>(options: Omit<Options, "auth"> & {
|
|
600
|
-
auth: A;
|
|
601
|
-
}): Server<{
|
|
602
|
-
user: UserOf<A[number]>;
|
|
603
|
-
}>;
|
|
604
599
|
declare function server<C extends ContextTypes = {}>(options?: Options): Server<C>;
|
|
605
600
|
|
|
606
601
|
export { type AuthClaims, type AuthConfig, type AuthEntry, type AuthFunction, type AuthInstance, type AuthMeta, type AuthOption, type AuthProfile, type AuthSettings, type AuthVerify, type BasicValue, type Body, type BodyMode, type Bucket, type BucketFile, type BunEnv, type CacheOption, type Context, type ContextExtension, type ContextTypes, type Cookie, type CorsSettings, type ExtractPathParams, type FileInfo, type InferParamType, type InlineReply, type LogLevel, type Logger, type Method, type Middleware, type Options, type ParamTypeMap, type ParamsToObject, type PathToParams, type Platform, type ProviderOptions, type RedirectOption, type Route, type RouteOptions, type RouteSchema, type RouterMethod, type SchemaOutput, type SecurityOptions, type SecuritySettings, type SerializableValue, Server, TypedServerError as ServerError, type Settings, type StandardIssue, type StandardSchemaV1, type Strategy, type Time, type UploadOptions, type UploadedFile, type UserOf, ValidationError, cache, cookies, server as default, download, file, headers, json, redirect, router, send, status, type };
|
package/index.js
CHANGED
|
@@ -1016,29 +1016,43 @@ async function verifyJwt(token, secret) {
|
|
|
1016
1016
|
var NAME = "session";
|
|
1017
1017
|
var inCookie = (s) => s === "session" || s === "cookie";
|
|
1018
1018
|
var isSigned = (s) => s === "cookie" || s === "jwt";
|
|
1019
|
-
var UNITS2 = { s: 1, m: 60, h: 3600, d: 86400, w: 604800 };
|
|
1020
1019
|
function seconds(expires) {
|
|
1021
|
-
const
|
|
1022
|
-
if (!
|
|
1023
|
-
return
|
|
1020
|
+
const ms = parse(expires);
|
|
1021
|
+
if (!ms) throw new Error(`Invalid \`expires\`: "${expires}"`);
|
|
1022
|
+
return Math.round(ms / 1e3);
|
|
1024
1023
|
}
|
|
1024
|
+
var looksLikeOurs = (token) => {
|
|
1025
|
+
const parts = token.split(".");
|
|
1026
|
+
if (parts.length !== 3) return false;
|
|
1027
|
+
try {
|
|
1028
|
+
const header = JSON.parse(atob(parts[0].replace(/-/g, "+").replace(/_/g, "/")));
|
|
1029
|
+
return header?.alg === "HS256";
|
|
1030
|
+
} catch {
|
|
1031
|
+
return false;
|
|
1032
|
+
}
|
|
1033
|
+
};
|
|
1025
1034
|
var bearer = (ctx) => {
|
|
1026
1035
|
const header = ctx.headers.authorization;
|
|
1027
1036
|
if (!header) return;
|
|
1028
1037
|
const [type2, token] = header.trim().split(" ");
|
|
1029
|
-
if (type2?.toLowerCase() !== "bearer"
|
|
1030
|
-
|
|
1031
|
-
}
|
|
1038
|
+
if (type2?.toLowerCase() !== "bearer") return;
|
|
1039
|
+
if (!token) throw ServerError_default.AUTH_INVALID_HEADER({ type: type2 });
|
|
1032
1040
|
return token;
|
|
1033
1041
|
};
|
|
1034
|
-
async function read(ctx,
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
if (!
|
|
1040
|
-
|
|
1042
|
+
async function read(ctx, strategy) {
|
|
1043
|
+
const token = inCookie(strategy) ? ctx.cookies[NAME] : bearer(ctx);
|
|
1044
|
+
if (!token) return;
|
|
1045
|
+
const payload = await verifyJwt(token, ctx.options.secrets);
|
|
1046
|
+
if (!payload) {
|
|
1047
|
+
if (!inCookie(strategy)) throw ServerError_default.AUTH_INVALID_TOKEN();
|
|
1048
|
+
ctx.clearCookie = NAME;
|
|
1049
|
+
ctx.options.log?.message(
|
|
1050
|
+
"auth",
|
|
1051
|
+
looksLikeOurs(token) ? "discarded a session cookie signed with a key that is not in SECRETS. If you rotated it, keep the previous value: secrets: [current, previous]" : "discarded a session cookie that was not issued by this app"
|
|
1052
|
+
);
|
|
1053
|
+
return;
|
|
1041
1054
|
}
|
|
1055
|
+
return payload;
|
|
1042
1056
|
}
|
|
1043
1057
|
var meta = (payload, strategy) => ({
|
|
1044
1058
|
issuedAt: new Date(payload.iat * 1e3),
|
|
@@ -1395,31 +1409,28 @@ function parseProviders(given) {
|
|
|
1395
1409
|
var target = async (where, fallback, user, ctx) => typeof where === "function" ? where(user, ctx) : where ?? fallback;
|
|
1396
1410
|
function entry(config2) {
|
|
1397
1411
|
const list = parseProviders(config2.providers);
|
|
1398
|
-
const
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
);
|
|
1404
|
-
}
|
|
1412
|
+
const strategy = config2.strategy ?? "session";
|
|
1413
|
+
if (!["session", "cookie", "token", "jwt"].includes(strategy)) {
|
|
1414
|
+
throw new Error(
|
|
1415
|
+
`Unknown strategy "${strategy}"; it takes 'session', 'cookie', 'token' or 'jwt'.`
|
|
1416
|
+
);
|
|
1405
1417
|
}
|
|
1406
1418
|
const expires = config2.expires ?? "30d";
|
|
1419
|
+
seconds(expires);
|
|
1407
1420
|
const { onLogin, getUser, toPublicUser, onLogout } = config2;
|
|
1408
1421
|
if (onLogin && !getUser) {
|
|
1409
1422
|
throw new Error("`onLogin` needs a `getUser`: something has to resolve the id it returns.");
|
|
1410
1423
|
}
|
|
1411
|
-
|
|
1412
|
-
if (
|
|
1413
|
-
if (getUser && !toPublicUser) {
|
|
1414
|
-
throw new Error(
|
|
1415
|
-
`The \`${strategy}\` strategy signs the user into the credential, so it needs a \`toPublicUser\` to say what goes in. Signing the whole row would publish whatever else is on it.`
|
|
1416
|
-
);
|
|
1417
|
-
}
|
|
1418
|
-
} else if (!getUser) {
|
|
1424
|
+
if (isSigned(strategy)) {
|
|
1425
|
+
if (getUser && !toPublicUser) {
|
|
1419
1426
|
throw new Error(
|
|
1420
|
-
`The \`${strategy}\` strategy
|
|
1427
|
+
`The \`${strategy}\` strategy signs the user into the credential, so it needs a \`toPublicUser\` to say what goes in. Signing the whole row would publish whatever else is on it.`
|
|
1421
1428
|
);
|
|
1422
1429
|
}
|
|
1430
|
+
} else if (!getUser) {
|
|
1431
|
+
throw new Error(
|
|
1432
|
+
`The \`${strategy}\` strategy puts an id in the credential, so it needs a \`getUser\` to resolve it. With no database, use \`cookie\` or \`jwt\`.`
|
|
1433
|
+
);
|
|
1423
1434
|
}
|
|
1424
1435
|
const publicProfile = ({ id, email, name, avatar }) => ({
|
|
1425
1436
|
id,
|
|
@@ -1431,19 +1442,28 @@ function entry(config2) {
|
|
|
1431
1442
|
const loginTo = typeof config2.redirect === "object" ? redirects.login : config2.redirect;
|
|
1432
1443
|
const finish = async (ctx, profile) => {
|
|
1433
1444
|
const payload = getUser ? await (async () => {
|
|
1434
|
-
|
|
1445
|
+
let id;
|
|
1446
|
+
try {
|
|
1447
|
+
id = await onLogin(profile, ctx);
|
|
1448
|
+
} catch (error) {
|
|
1449
|
+
error.expose = true;
|
|
1450
|
+
throw error;
|
|
1451
|
+
}
|
|
1435
1452
|
if (id === void 0 || id === null) {
|
|
1436
1453
|
throw new Error("`onLogin` must return the id the credential points at");
|
|
1437
1454
|
}
|
|
1438
|
-
if (!isSigned(
|
|
1455
|
+
if (!isSigned(strategy)) return { sub: String(id) };
|
|
1439
1456
|
const user2 = await getUser(String(id), ctx);
|
|
1457
|
+
if (user2 === void 0 || user2 === null) {
|
|
1458
|
+
throw new Error(`getUser returned nothing for the id "${id}" that onLogin just returned`);
|
|
1459
|
+
}
|
|
1440
1460
|
return { user: await toPublicUser(user2) };
|
|
1441
1461
|
})() : { user: publicProfile(profile) };
|
|
1442
1462
|
const signed = { ...payload, provider: profile.provider };
|
|
1443
1463
|
const token = await issue(ctx, signed, expires);
|
|
1444
1464
|
const user = signed.user ?? await getUser(signed.sub, ctx);
|
|
1445
1465
|
const to = await target(loginTo, "/", user, ctx);
|
|
1446
|
-
if (inCookie(
|
|
1466
|
+
if (inCookie(strategy)) {
|
|
1447
1467
|
return cookies("session", {
|
|
1448
1468
|
value: token,
|
|
1449
1469
|
path: "/",
|
|
@@ -1458,9 +1478,8 @@ function entry(config2) {
|
|
|
1458
1478
|
return {
|
|
1459
1479
|
name: "flow",
|
|
1460
1480
|
async user(ctx) {
|
|
1461
|
-
const
|
|
1462
|
-
if (!
|
|
1463
|
-
const { payload, strategy } = found;
|
|
1481
|
+
const payload = await read(ctx, strategy);
|
|
1482
|
+
if (!payload) return;
|
|
1464
1483
|
ctx.auth = meta(payload, strategy);
|
|
1465
1484
|
if (payload.user) return payload.user;
|
|
1466
1485
|
if (!payload.sub) return;
|
|
@@ -1495,8 +1514,10 @@ function entry(config2) {
|
|
|
1495
1514
|
res = await finish(ctx, profile);
|
|
1496
1515
|
} catch (error) {
|
|
1497
1516
|
const to = await target(redirects.error, "/", null, ctx);
|
|
1498
|
-
|
|
1499
|
-
|
|
1517
|
+
let message = "Could not sign you in";
|
|
1518
|
+
if (error?.expose) message = error.message;
|
|
1519
|
+
else console.error(`[server:auth] ${name} callback failed:`, error);
|
|
1520
|
+
res = await redirect(`${to}?error=${encodeURIComponent(message)}`);
|
|
1500
1521
|
}
|
|
1501
1522
|
res.headers.append(
|
|
1502
1523
|
"set-cookie",
|
|
@@ -1507,12 +1528,10 @@ function entry(config2) {
|
|
|
1507
1528
|
app.get(`/auth/callback/${name}`, SPEC, callback);
|
|
1508
1529
|
}
|
|
1509
1530
|
app.post("/auth/logout", SPEC, async (ctx) => {
|
|
1510
|
-
const
|
|
1511
|
-
if (onLogout &&
|
|
1512
|
-
await onLogout(found.payload.sub, ctx);
|
|
1513
|
-
}
|
|
1531
|
+
const payload = await read(ctx, strategy).catch(() => void 0);
|
|
1532
|
+
if (onLogout && payload?.sub) await onLogout(payload.sub, ctx);
|
|
1514
1533
|
const to = await target(redirects.logout, "/", null, ctx);
|
|
1515
|
-
if (!inCookie(
|
|
1534
|
+
if (!inCookie(strategy)) return status(204);
|
|
1516
1535
|
return cookies("session", { value: null }).redirect(to);
|
|
1517
1536
|
});
|
|
1518
1537
|
}
|
|
@@ -1566,9 +1585,8 @@ var bearer2 = (ctx) => {
|
|
|
1566
1585
|
const header = ctx.headers.authorization;
|
|
1567
1586
|
if (!header) return;
|
|
1568
1587
|
const [type2, token] = header.trim().split(" ");
|
|
1569
|
-
if (type2?.toLowerCase() !== "bearer"
|
|
1570
|
-
|
|
1571
|
-
}
|
|
1588
|
+
if (type2?.toLowerCase() !== "bearer") return;
|
|
1589
|
+
if (!token) throw ServerError_default.AUTH_INVALID_HEADER({ type: type2 });
|
|
1572
1590
|
return token;
|
|
1573
1591
|
};
|
|
1574
1592
|
function entry2(options) {
|
|
@@ -1585,7 +1603,18 @@ function entry2(options) {
|
|
|
1585
1603
|
async user(ctx) {
|
|
1586
1604
|
const token = options.cookie ? ctx.cookies[options.cookie] : bearer2(ctx);
|
|
1587
1605
|
if (!token) return;
|
|
1588
|
-
|
|
1606
|
+
let claims2;
|
|
1607
|
+
try {
|
|
1608
|
+
claims2 = await check(token, issuer, allowed, claimNames);
|
|
1609
|
+
} catch (error) {
|
|
1610
|
+
if (!options.cookie) throw error;
|
|
1611
|
+
ctx.clearCookie = options.cookie;
|
|
1612
|
+
ctx.options.log?.message(
|
|
1613
|
+
"auth",
|
|
1614
|
+
`discarded a ${options.cookie} cookie that ${issuer} did not sign, or that has expired`
|
|
1615
|
+
);
|
|
1616
|
+
return;
|
|
1617
|
+
}
|
|
1589
1618
|
ctx.auth = {
|
|
1590
1619
|
issuedAt: new Date((claims2.iat ?? 0) * 1e3),
|
|
1591
1620
|
expiresAt: claims2.exp ? new Date(claims2.exp * 1e3) : void 0,
|
|
@@ -1668,8 +1697,12 @@ var vendors_default = VENDORS;
|
|
|
1668
1697
|
// src/auth/parse.ts
|
|
1669
1698
|
function parseAuth(auth2) {
|
|
1670
1699
|
if (!auth2) return null;
|
|
1671
|
-
|
|
1672
|
-
|
|
1700
|
+
if (Array.isArray(auth2)) {
|
|
1701
|
+
throw new Error(
|
|
1702
|
+
"`auth` takes one method. For several login options, list them under `providers` instead: auth: { providers: ['github', 'google'], ... }."
|
|
1703
|
+
);
|
|
1704
|
+
}
|
|
1705
|
+
return toEntry(auth2);
|
|
1673
1706
|
}
|
|
1674
1707
|
function vendorEntry(strategy, name) {
|
|
1675
1708
|
const vendor = vendors_default[name];
|
|
@@ -1711,15 +1744,15 @@ function toEntry(auth2) {
|
|
|
1711
1744
|
`Invalid auth "${auth2}": the string form is "<strategy>:<name>", like "cookie:github" to log people in, or "jwt:clerk" to check a token a vendor issued.`
|
|
1712
1745
|
);
|
|
1713
1746
|
}
|
|
1714
|
-
if (vendors_default[name]) return
|
|
1715
|
-
return
|
|
1747
|
+
if (vendors_default[name]) return vendorEntry(strategy, name);
|
|
1748
|
+
return entry({ strategy, providers: name });
|
|
1716
1749
|
}
|
|
1717
1750
|
if (typeof auth2 === "function") {
|
|
1718
|
-
return
|
|
1751
|
+
return { name: "function", user: async (ctx) => auth2(ctx) };
|
|
1719
1752
|
}
|
|
1720
1753
|
if (auth2 && typeof auth2 === "object") {
|
|
1721
|
-
if ("issuer" in auth2) return
|
|
1722
|
-
if ("providers" in auth2) return
|
|
1754
|
+
if ("issuer" in auth2) return entry2(auth2);
|
|
1755
|
+
if ("providers" in auth2) return entry(auth2);
|
|
1723
1756
|
if ("handler" in auth2) {
|
|
1724
1757
|
const instance = auth2;
|
|
1725
1758
|
const path = (instance.path ?? "/api/auth").replace(/\/$/, "");
|
|
@@ -1733,20 +1766,18 @@ function toEntry(auth2) {
|
|
|
1733
1766
|
...ctx.body ? { duplex: "half" } : {}
|
|
1734
1767
|
})
|
|
1735
1768
|
);
|
|
1736
|
-
return
|
|
1737
|
-
{
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
app.delete(wildcard, raw, forward);
|
|
1747
|
-
}
|
|
1769
|
+
return {
|
|
1770
|
+
name: `instance:${path}`,
|
|
1771
|
+
user: async (ctx) => instance.user?.(ctx),
|
|
1772
|
+
routes: (app) => {
|
|
1773
|
+
const wildcard = `${path}/*`;
|
|
1774
|
+
app.get(wildcard, raw, forward);
|
|
1775
|
+
app.post(wildcard, raw, forward);
|
|
1776
|
+
app.put(wildcard, raw, forward);
|
|
1777
|
+
app.patch(wildcard, raw, forward);
|
|
1778
|
+
app.delete(wildcard, raw, forward);
|
|
1748
1779
|
}
|
|
1749
|
-
|
|
1780
|
+
};
|
|
1750
1781
|
}
|
|
1751
1782
|
}
|
|
1752
1783
|
throw new Error(
|
|
@@ -1816,16 +1847,16 @@ var STATUS_TEXT = {
|
|
|
1816
1847
|
502: "Bad Gateway",
|
|
1817
1848
|
503: "Service Unavailable"
|
|
1818
1849
|
};
|
|
1819
|
-
var
|
|
1850
|
+
var UNITS2 = ["b", "kb", "mb", "gb", "tb"];
|
|
1820
1851
|
function formatBytes(bytes) {
|
|
1821
1852
|
if (!bytes || bytes < 0) return "0b";
|
|
1822
1853
|
const i = Math.min(
|
|
1823
1854
|
Math.floor(Math.log(bytes) / Math.log(1024)),
|
|
1824
|
-
|
|
1855
|
+
UNITS2.length - 1
|
|
1825
1856
|
);
|
|
1826
1857
|
const value = bytes / 1024 ** i;
|
|
1827
1858
|
const rounded = i === 0 ? Math.round(value) : Math.round(value * 10) / 10;
|
|
1828
|
-
return `${rounded}${
|
|
1859
|
+
return `${rounded}${UNITS2[i]}`;
|
|
1829
1860
|
}
|
|
1830
1861
|
var SCOPE_COLORS = {
|
|
1831
1862
|
start: "green",
|
|
@@ -2014,10 +2045,10 @@ function config(options = {}) {
|
|
|
2014
2045
|
options.auth || env2.AUTH || null
|
|
2015
2046
|
);
|
|
2016
2047
|
}
|
|
2017
|
-
if (settings.auth?.
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
);
|
|
2048
|
+
if (settings.auth?.name === "flow" && settings.secrets[0].startsWith("unsafe-")) {
|
|
2049
|
+
const message = "Auth needs a stable secret: credentials are signed with it, and the random per-process fallback breaks them on restart and across instances. Set the SECRETS environment variable (or the `secrets` option).";
|
|
2050
|
+
if (env2.NODE_ENV === "production") throw new Error(message);
|
|
2051
|
+
console.warn(`[server:auth] ${message}`);
|
|
2021
2052
|
}
|
|
2022
2053
|
if (options.openapi) {
|
|
2023
2054
|
const o = options.openapi;
|
|
@@ -2032,10 +2063,7 @@ function config(options = {}) {
|
|
|
2032
2063
|
});
|
|
2033
2064
|
settings.onResponse = options.onResponse;
|
|
2034
2065
|
const loc = (v) => typeof v === "string" ? v : "enabled";
|
|
2035
|
-
if (settings.auth) {
|
|
2036
|
-
const names = settings.auth.map((one) => one.name).join(", ");
|
|
2037
|
-
log.message("auth", ` enabled`);
|
|
2038
|
-
}
|
|
2066
|
+
if (settings.auth) log.message("auth", `${settings.auth.name} enabled`);
|
|
2039
2067
|
if (settings.public) log.message("public", loc(options.public));
|
|
2040
2068
|
if (settings.uploads) log.message("uploads", loc(options.uploads));
|
|
2041
2069
|
if (settings.cors) {
|
|
@@ -2162,6 +2190,12 @@ async function parseResponse(out, ctx) {
|
|
|
2162
2190
|
applyCors(out, ctx);
|
|
2163
2191
|
applySecurity(out, ctx);
|
|
2164
2192
|
out = await applyCache(out, ctx);
|
|
2193
|
+
if (ctx.clearCookie) {
|
|
2194
|
+
out.headers.append(
|
|
2195
|
+
"set-cookie",
|
|
2196
|
+
`${ctx.clearCookie}=; Path=/; Max-Age=0; HttpOnly`
|
|
2197
|
+
);
|
|
2198
|
+
}
|
|
2165
2199
|
if (ctx.time?.times?.length > 1) {
|
|
2166
2200
|
out.headers.set("Server-Timing", ctx.time.headers());
|
|
2167
2201
|
}
|
|
@@ -2412,17 +2446,11 @@ function toWeb(nodeStream) {
|
|
|
2412
2446
|
|
|
2413
2447
|
// src/auth/index.ts
|
|
2414
2448
|
function auth(app) {
|
|
2415
|
-
const
|
|
2449
|
+
const entry3 = app.settings.auth;
|
|
2416
2450
|
app.use(async function middle(ctx) {
|
|
2417
|
-
|
|
2418
|
-
const user = await entry3.user(ctx);
|
|
2419
|
-
if (user) {
|
|
2420
|
-
ctx.user = user;
|
|
2421
|
-
return;
|
|
2422
|
-
}
|
|
2423
|
-
}
|
|
2451
|
+
ctx.user = await entry3.user(ctx);
|
|
2424
2452
|
});
|
|
2425
|
-
|
|
2453
|
+
entry3.routes?.(app);
|
|
2426
2454
|
}
|
|
2427
2455
|
|
|
2428
2456
|
// src/helpers/parseRange.ts
|
|
@@ -2664,10 +2692,7 @@ function timer(ctx) {
|
|
|
2664
2692
|
async function socketUser(app, headers2, cookies2) {
|
|
2665
2693
|
if (!app.settings.auth) return void 0;
|
|
2666
2694
|
const ctx = { options: app.settings, headers: headers2, cookies: cookies2 };
|
|
2667
|
-
|
|
2668
|
-
const user = await entry3.user(ctx);
|
|
2669
|
-
if (user) return user;
|
|
2670
|
-
}
|
|
2695
|
+
return app.settings.auth.user(ctx);
|
|
2671
2696
|
}
|
|
2672
2697
|
|
|
2673
2698
|
// src/helpers/wsNode.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@server/next",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.48.1",
|
|
4
4
|
"description": "A fully-fledged web server with routing, file uploads, sessions, static files, schema validation, websockets, testing, etc.",
|
|
5
5
|
"homepage": "https://server-js.com/",
|
|
6
6
|
"repository": "github:franciscop/server-next",
|