@niledatabase/server 4.0.0-alpha.2 → 4.0.0-alpha.21
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 +65 -15
- package/dist/express.js +41 -31
- package/dist/express.js.map +1 -1
- package/dist/express.mjs +41 -31
- package/dist/express.mjs.map +1 -1
- package/dist/index.d.mts +57 -28
- package/dist/index.d.ts +57 -28
- package/dist/index.js +192 -33
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +192 -33
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -73,7 +73,7 @@ var X_NILE_SECURECOOKIES = "nile.secure_cookies";
|
|
|
73
73
|
|
|
74
74
|
// src/api/utils/request.ts
|
|
75
75
|
async function request(url, _init, config) {
|
|
76
|
-
const { info, error } = Logger(config, "[REQUEST]");
|
|
76
|
+
const { debug, info, error } = Logger(config, "[REQUEST]");
|
|
77
77
|
const { request: request2, ...init } = _init;
|
|
78
78
|
const requestUrl = new URL(request2.url);
|
|
79
79
|
const updatedHeaders = new Headers({});
|
|
@@ -91,9 +91,17 @@ async function request(url, _init, config) {
|
|
|
91
91
|
}
|
|
92
92
|
updatedHeaders.set("host", requestUrl.host);
|
|
93
93
|
if (config.api.callbackUrl) {
|
|
94
|
-
|
|
94
|
+
const cbUrl = new URL(config.api.callbackUrl);
|
|
95
|
+
debug(
|
|
96
|
+
`Obtained origin from config.api.callbackUrl ${config.api.callbackUrl}`
|
|
97
|
+
);
|
|
98
|
+
updatedHeaders.set(X_NILE_ORIGIN, cbUrl.origin);
|
|
99
|
+
} else if (config.api.origin) {
|
|
100
|
+
debug(`Obtained origin from config.api.origin ${config.api.origin}`);
|
|
101
|
+
updatedHeaders.set(X_NILE_ORIGIN, config.api.origin);
|
|
95
102
|
} else {
|
|
96
103
|
updatedHeaders.set(X_NILE_ORIGIN, requestUrl.origin);
|
|
104
|
+
debug(`Obtained origin from request ${requestUrl.origin}`);
|
|
97
105
|
}
|
|
98
106
|
const params = { ...init, headers: updatedHeaders };
|
|
99
107
|
if (params.method === "POST" || params.method === "PUT") {
|
|
@@ -420,6 +428,7 @@ var ApiConfig = class {
|
|
|
420
428
|
routes;
|
|
421
429
|
routePrefix;
|
|
422
430
|
secureCookies;
|
|
431
|
+
origin;
|
|
423
432
|
/**
|
|
424
433
|
* The client side callback url. Defaults to nothing (so nile.origin will be it), but in the cases of x-origin, you want to set this explicitly to be sure nile-auth does the right thing
|
|
425
434
|
* If this is set, any `callbackUrl` from the client will be ignored.
|
|
@@ -435,6 +444,7 @@ var ApiConfig = class {
|
|
|
435
444
|
this.basePath = getBasePath(envVarConfig);
|
|
436
445
|
this.routes = config?.api?.routes;
|
|
437
446
|
this.routePrefix = config?.api?.routePrefix;
|
|
447
|
+
this.origin = config?.api?.origin;
|
|
438
448
|
}
|
|
439
449
|
get token() {
|
|
440
450
|
return this._token;
|
|
@@ -1067,12 +1077,9 @@ async function _fetch(config, path, opts) {
|
|
|
1067
1077
|
if (response?.status === 405) {
|
|
1068
1078
|
return new ResponseError("Method not allowed", { status: 405 });
|
|
1069
1079
|
}
|
|
1070
|
-
let res;
|
|
1071
1080
|
const errorHandler = typeof response?.clone === "function" ? response.clone() : null;
|
|
1072
1081
|
let msg = "";
|
|
1073
|
-
|
|
1074
|
-
res = await response?.json();
|
|
1075
|
-
} catch (e) {
|
|
1082
|
+
const res = await response?.json().catch(async (e) => {
|
|
1076
1083
|
if (errorHandler) {
|
|
1077
1084
|
msg = await errorHandler.text();
|
|
1078
1085
|
if (msg) {
|
|
@@ -1085,7 +1092,8 @@ async function _fetch(config, path, opts) {
|
|
|
1085
1092
|
if (!msg) {
|
|
1086
1093
|
error("[fetch][response]", { e });
|
|
1087
1094
|
}
|
|
1088
|
-
|
|
1095
|
+
return e;
|
|
1096
|
+
});
|
|
1089
1097
|
if (msg) {
|
|
1090
1098
|
return new ResponseError(msg, { status: errorHandler?.status });
|
|
1091
1099
|
}
|
|
@@ -1104,7 +1112,8 @@ async function _fetch(config, path, opts) {
|
|
|
1104
1112
|
error(
|
|
1105
1113
|
`[fetch][response][status: ${errorHandler?.status}] UNHANDLED ERROR`,
|
|
1106
1114
|
{
|
|
1107
|
-
|
|
1115
|
+
response,
|
|
1116
|
+
message: await response.text()
|
|
1108
1117
|
}
|
|
1109
1118
|
);
|
|
1110
1119
|
return new ResponseError(null, {
|
|
@@ -1528,11 +1537,7 @@ function matches12(configRoutes, request2) {
|
|
|
1528
1537
|
// src/api/routes/auth/password-reset.ts
|
|
1529
1538
|
var key10 = "PASSWORD_RESET";
|
|
1530
1539
|
async function route13(req, config) {
|
|
1531
|
-
|
|
1532
|
-
const { searchParams } = new URL(req.url);
|
|
1533
|
-
if (searchParams.size > 0) {
|
|
1534
|
-
url = `${url}?${searchParams.toString()}`;
|
|
1535
|
-
}
|
|
1540
|
+
const url = proxyRoutes(config)[key10];
|
|
1536
1541
|
const res = await request(
|
|
1537
1542
|
url,
|
|
1538
1543
|
{
|
|
@@ -1645,8 +1650,16 @@ function POSTER(configRoutes, config) {
|
|
|
1645
1650
|
const { info, warn, error } = Logger(config, "[POST MATCHER]");
|
|
1646
1651
|
return async function POST5(req) {
|
|
1647
1652
|
if (matchesLog(configRoutes, req)) {
|
|
1648
|
-
|
|
1649
|
-
|
|
1653
|
+
if (req.body) {
|
|
1654
|
+
try {
|
|
1655
|
+
const text = await req.text();
|
|
1656
|
+
error(text);
|
|
1657
|
+
return new Response(null, {
|
|
1658
|
+
status: 200
|
|
1659
|
+
});
|
|
1660
|
+
} catch (e) {
|
|
1661
|
+
}
|
|
1662
|
+
}
|
|
1650
1663
|
}
|
|
1651
1664
|
if (matches3(configRoutes, req)) {
|
|
1652
1665
|
info("matches tenant users");
|
|
@@ -1771,7 +1784,7 @@ var appRoutes = (prefix = "/api") => ({
|
|
|
1771
1784
|
TENANT_USER: `${prefix}/tenants/{tenantId}/users/{userId}`,
|
|
1772
1785
|
TENANT_USERS: `${prefix}/tenants/{tenantId}/users`,
|
|
1773
1786
|
SIGNUP: `${prefix}/signup`,
|
|
1774
|
-
LOG: `${prefix}/
|
|
1787
|
+
LOG: `${prefix}/_log`
|
|
1775
1788
|
});
|
|
1776
1789
|
|
|
1777
1790
|
// src/utils/Requester/index.ts
|
|
@@ -1781,9 +1794,9 @@ var Requester = class extends Config {
|
|
|
1781
1794
|
}
|
|
1782
1795
|
async rawRequest(method, url, init, body) {
|
|
1783
1796
|
const _init = {
|
|
1784
|
-
...init,
|
|
1785
1797
|
body,
|
|
1786
|
-
method
|
|
1798
|
+
method,
|
|
1799
|
+
...init
|
|
1787
1800
|
};
|
|
1788
1801
|
const res = await _fetch(this, url, _init);
|
|
1789
1802
|
if (res instanceof ResponseError) {
|
|
@@ -1852,8 +1865,11 @@ var Requester = class extends Config {
|
|
|
1852
1865
|
}
|
|
1853
1866
|
return response;
|
|
1854
1867
|
}
|
|
1855
|
-
async get(req, url, init) {
|
|
1868
|
+
async get(req, url, init, raw = false) {
|
|
1856
1869
|
const response = await this.request("GET", url, req, init);
|
|
1870
|
+
if (raw) {
|
|
1871
|
+
return response;
|
|
1872
|
+
}
|
|
1857
1873
|
if (response && response.status >= 200 && response.status < 300) {
|
|
1858
1874
|
const cloned = response.clone();
|
|
1859
1875
|
try {
|
|
@@ -1881,8 +1897,8 @@ var Requester = class extends Config {
|
|
|
1881
1897
|
};
|
|
1882
1898
|
|
|
1883
1899
|
// src/auth/index.ts
|
|
1884
|
-
var ORIGIN = "https://us-west-2.api.dev.thenile.dev";
|
|
1885
1900
|
function serverLogin(config, handlers) {
|
|
1901
|
+
const ORIGIN = config.api.origin ?? "http://localhost:3000";
|
|
1886
1902
|
const { info, error, debug } = Logger(config, "[server side login]");
|
|
1887
1903
|
const routes = appRoutes(config.api.routePrefix);
|
|
1888
1904
|
return async function login({
|
|
@@ -1973,17 +1989,31 @@ function serverLogin(config, handlers) {
|
|
|
1973
1989
|
...baseHeaders,
|
|
1974
1990
|
cookie: [token, csrfCookie].join("; ")
|
|
1975
1991
|
});
|
|
1976
|
-
return headers;
|
|
1992
|
+
return [headers, loginRes];
|
|
1977
1993
|
};
|
|
1978
1994
|
}
|
|
1979
1995
|
var Auth = class extends Config {
|
|
1980
1996
|
headers;
|
|
1981
|
-
|
|
1997
|
+
resetHeaders;
|
|
1998
|
+
constructor(config, headers, params) {
|
|
1982
1999
|
super(config);
|
|
2000
|
+
this.logger = Logger(config, "[auth]");
|
|
1983
2001
|
this.headers = headers;
|
|
2002
|
+
this.logger = Logger(config, "[auth]");
|
|
2003
|
+
this.resetHeaders = params?.resetHeaders;
|
|
1984
2004
|
}
|
|
1985
2005
|
handleHeaders(init) {
|
|
1986
2006
|
if (this.headers) {
|
|
2007
|
+
const cburl = getCallbackUrl2(this.headers);
|
|
2008
|
+
if (cburl) {
|
|
2009
|
+
try {
|
|
2010
|
+
this.headers.set(X_NILE_ORIGIN, new URL(cburl).origin);
|
|
2011
|
+
} catch (e) {
|
|
2012
|
+
if (this.logger?.debug) {
|
|
2013
|
+
this.logger.debug("Invalid URL supplied by cookie header");
|
|
2014
|
+
}
|
|
2015
|
+
}
|
|
2016
|
+
}
|
|
1987
2017
|
if (init) {
|
|
1988
2018
|
init.headers = new Headers({ ...this.headers, ...init?.headers });
|
|
1989
2019
|
return init;
|
|
@@ -2008,6 +2038,113 @@ var Auth = class extends Config {
|
|
|
2008
2038
|
}
|
|
2009
2039
|
return session;
|
|
2010
2040
|
};
|
|
2041
|
+
get getCsrfUrl() {
|
|
2042
|
+
return "/auth/csrf";
|
|
2043
|
+
}
|
|
2044
|
+
async getCsrf(req, init, raw = false) {
|
|
2045
|
+
const _requester = new Requester(this);
|
|
2046
|
+
const _init = this.handleHeaders(init);
|
|
2047
|
+
return await _requester.get(req, this.getCsrfUrl, _init, raw);
|
|
2048
|
+
}
|
|
2049
|
+
get listProvidersUrl() {
|
|
2050
|
+
return "/auth/providers";
|
|
2051
|
+
}
|
|
2052
|
+
listProviders = async (req, init) => {
|
|
2053
|
+
const _requester = new Requester(this);
|
|
2054
|
+
const _init = this.handleHeaders(init);
|
|
2055
|
+
return await _requester.get(req, this.listProvidersUrl, _init);
|
|
2056
|
+
};
|
|
2057
|
+
get signOutUrl() {
|
|
2058
|
+
return "/auth/signout";
|
|
2059
|
+
}
|
|
2060
|
+
signOut = async (req, init) => {
|
|
2061
|
+
const _requester = new Requester(this);
|
|
2062
|
+
const _init = this.handleHeaders(init);
|
|
2063
|
+
const csrf = await this.getCsrf(
|
|
2064
|
+
req,
|
|
2065
|
+
void 0,
|
|
2066
|
+
true
|
|
2067
|
+
);
|
|
2068
|
+
const csrfHeader = getCsrfToken(csrf.headers, this.headers);
|
|
2069
|
+
const callbackUrl = req && "callbackUrl" in req ? String(req.callbackUrl) : "/";
|
|
2070
|
+
if (!csrfHeader) {
|
|
2071
|
+
this.logger?.debug && this.logger.debug("Request blocked from invalid csrf header");
|
|
2072
|
+
return new Response("Request blocked", { status: 400 });
|
|
2073
|
+
}
|
|
2074
|
+
const headers = new Headers(_init?.headers);
|
|
2075
|
+
const { csrfToken } = await csrf.json() ?? {};
|
|
2076
|
+
const cooks = getCookies(headers);
|
|
2077
|
+
if (csrfHeader) {
|
|
2078
|
+
if (cooks["__Secure-nile.csrf-token"]) {
|
|
2079
|
+
cooks["__Secure-nile.csrf-token"] = encodeURIComponent(csrfHeader);
|
|
2080
|
+
}
|
|
2081
|
+
if (cooks["nile.csrf-token"]) {
|
|
2082
|
+
cooks["nile.csrf-token"] = encodeURIComponent(csrfHeader);
|
|
2083
|
+
}
|
|
2084
|
+
}
|
|
2085
|
+
headers.set(
|
|
2086
|
+
"cookie",
|
|
2087
|
+
Object.keys(cooks).map((key12) => `${key12}=${cooks[key12]}`).join("; ")
|
|
2088
|
+
);
|
|
2089
|
+
const res = await _requester.post(req, this.signOutUrl, {
|
|
2090
|
+
method: "post",
|
|
2091
|
+
body: JSON.stringify({
|
|
2092
|
+
csrfToken,
|
|
2093
|
+
callbackUrl,
|
|
2094
|
+
json: String(true)
|
|
2095
|
+
}),
|
|
2096
|
+
..._init,
|
|
2097
|
+
headers
|
|
2098
|
+
});
|
|
2099
|
+
this.resetHeaders && this.resetHeaders();
|
|
2100
|
+
return res;
|
|
2101
|
+
};
|
|
2102
|
+
};
|
|
2103
|
+
function getCallbackUrl2(headers) {
|
|
2104
|
+
if (headers) {
|
|
2105
|
+
const cookies = getCookies(headers);
|
|
2106
|
+
if (cookies) {
|
|
2107
|
+
return cookies["__Secure-nile.callback-url"] || cookies["nile.callback-url"];
|
|
2108
|
+
}
|
|
2109
|
+
}
|
|
2110
|
+
}
|
|
2111
|
+
function getCsrfToken(headers, initHeaders) {
|
|
2112
|
+
if (headers) {
|
|
2113
|
+
const cookies = getCookies(headers);
|
|
2114
|
+
let validCookie = "";
|
|
2115
|
+
if (cookies) {
|
|
2116
|
+
validCookie = cookies["__Secure-nile.csrf-token"] || cookies["nile.csrf-token"];
|
|
2117
|
+
}
|
|
2118
|
+
if (validCookie) {
|
|
2119
|
+
return validCookie;
|
|
2120
|
+
}
|
|
2121
|
+
}
|
|
2122
|
+
if (initHeaders) {
|
|
2123
|
+
const cookies = getCookies(initHeaders);
|
|
2124
|
+
if (cookies) {
|
|
2125
|
+
return cookies["__Secure-nile.csrf-token"] || cookies["nile.csrf-token"];
|
|
2126
|
+
}
|
|
2127
|
+
}
|
|
2128
|
+
}
|
|
2129
|
+
var getCookies = (headers) => {
|
|
2130
|
+
if (!headers) return {};
|
|
2131
|
+
const cookieHeader = headers.get("cookie") || "";
|
|
2132
|
+
const setCookieHeaders = headers.get("set-cookie") || "";
|
|
2133
|
+
const allCookies = [
|
|
2134
|
+
...cookieHeader.split("; "),
|
|
2135
|
+
// Regular 'cookie' header (semicolon-separated)
|
|
2136
|
+
...setCookieHeaders.split(/,\s*(?=[^;, ]+=)/)
|
|
2137
|
+
// Smart split for 'set-cookie'
|
|
2138
|
+
].filter(Boolean);
|
|
2139
|
+
return Object.fromEntries(
|
|
2140
|
+
allCookies.map((cookie) => {
|
|
2141
|
+
const [key12, ...val] = cookie.split("=");
|
|
2142
|
+
return [
|
|
2143
|
+
decodeURIComponent(key12.trim()),
|
|
2144
|
+
decodeURIComponent(val.join("=").trim())
|
|
2145
|
+
];
|
|
2146
|
+
})
|
|
2147
|
+
);
|
|
2011
2148
|
};
|
|
2012
2149
|
|
|
2013
2150
|
// src/tenants/index.ts
|
|
@@ -2214,7 +2351,9 @@ var Api = class {
|
|
|
2214
2351
|
paths;
|
|
2215
2352
|
constructor(config) {
|
|
2216
2353
|
this.config = config;
|
|
2217
|
-
this.auth = new Auth(config
|
|
2354
|
+
this.auth = new Auth(config, void 0, {
|
|
2355
|
+
resetHeaders: this.resetHeaders
|
|
2356
|
+
});
|
|
2218
2357
|
this.users = new Users(config);
|
|
2219
2358
|
this.tenants = new Tenants(config);
|
|
2220
2359
|
this.routes = {
|
|
@@ -2244,7 +2383,7 @@ var Api = class {
|
|
|
2244
2383
|
this.routes.USERS,
|
|
2245
2384
|
this.routes.TENANTS,
|
|
2246
2385
|
this.routes.SESSION,
|
|
2247
|
-
this.routes.SIGNIN
|
|
2386
|
+
`${this.routes.SIGNIN}/{provider}`,
|
|
2248
2387
|
this.routes.PASSWORD_RESET,
|
|
2249
2388
|
this.routes.PROVIDERS,
|
|
2250
2389
|
this.routes.CSRF,
|
|
@@ -2260,27 +2399,47 @@ var Api = class {
|
|
|
2260
2399
|
delete: [this.routes.TENANT_USER, this.routes.TENANT]
|
|
2261
2400
|
};
|
|
2262
2401
|
}
|
|
2263
|
-
|
|
2402
|
+
reset = () => {
|
|
2403
|
+
this.users = new Users(this.config, this._headers);
|
|
2404
|
+
this.tenants = new Tenants(this.config, this._headers);
|
|
2405
|
+
this.auth = new Auth(this.config, this._headers, {
|
|
2406
|
+
resetHeaders: this.resetHeaders
|
|
2407
|
+
});
|
|
2408
|
+
};
|
|
2409
|
+
updateConfig = (config) => {
|
|
2264
2410
|
this.config = config;
|
|
2265
2411
|
this.handlers = Handlers(this.routes, config);
|
|
2266
|
-
}
|
|
2412
|
+
};
|
|
2413
|
+
resetHeaders = (headers) => {
|
|
2414
|
+
this._headers = new Headers(headers ?? {});
|
|
2415
|
+
this.reset();
|
|
2416
|
+
};
|
|
2267
2417
|
set headers(headers) {
|
|
2268
|
-
this.users = new Users(this.config, headers);
|
|
2269
|
-
this.tenants = new Tenants(this.config, headers);
|
|
2270
|
-
this.auth = new Auth(this.config, headers);
|
|
2271
2418
|
this._headers = headers;
|
|
2419
|
+
this.reset();
|
|
2272
2420
|
}
|
|
2273
|
-
|
|
2274
|
-
|
|
2421
|
+
get headers() {
|
|
2422
|
+
return this._headers;
|
|
2275
2423
|
}
|
|
2276
|
-
async
|
|
2424
|
+
login = async (payload, config) => {
|
|
2425
|
+
const [headers, loginRes] = await serverLogin(
|
|
2426
|
+
this.config,
|
|
2427
|
+
this.handlers
|
|
2428
|
+
)(payload);
|
|
2429
|
+
this.headers = headers;
|
|
2430
|
+
if (config?.returnResponse) {
|
|
2431
|
+
return loginRes;
|
|
2432
|
+
}
|
|
2433
|
+
return void 0;
|
|
2434
|
+
};
|
|
2435
|
+
session = async (req) => {
|
|
2277
2436
|
if (req instanceof Headers) {
|
|
2278
2437
|
return this.auth.getSession(req);
|
|
2279
2438
|
} else if (req instanceof Request) {
|
|
2280
2439
|
return auth(req, this.config);
|
|
2281
2440
|
}
|
|
2282
2441
|
return this.auth.getSession(this._headers);
|
|
2283
|
-
}
|
|
2442
|
+
};
|
|
2284
2443
|
};
|
|
2285
2444
|
|
|
2286
2445
|
// src/Server.ts
|