@technomoron/api-server-base 2.0.0-beta.21 → 2.0.0-beta.23
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/cjs/common/types.cjs +10 -0
- package/dist/cjs/common/types.d.ts +137 -0
- package/dist/cjs/{api-module.cjs → server/src/api-module.cjs} +8 -0
- package/dist/{esm → cjs/server/src}/api-module.d.ts +15 -0
- package/dist/cjs/{api-server-base.cjs → server/src/api-server-base.cjs} +669 -627
- package/dist/{esm → cjs/server/src}/api-server-base.d.ts +105 -78
- package/dist/cjs/{auth-api/auth-module.js → server/src/auth-api/auth-module.cjs} +96 -76
- package/dist/cjs/{auth-api → server/src/auth-api}/auth-module.d.ts +1 -1
- package/dist/cjs/{auth-api/compat-auth-storage.js → server/src/auth-api/compat-auth-storage.cjs} +4 -4
- package/dist/cjs/{auth-api/mem-auth-store.js → server/src/auth-api/mem-auth-store.cjs} +7 -7
- package/dist/cjs/{auth-api/module.js → server/src/auth-api/module.cjs} +1 -1
- package/dist/cjs/server/src/auth-api/schemas.cjs +171 -0
- package/dist/cjs/server/src/auth-api/schemas.d.ts +21 -0
- package/dist/cjs/{auth-api/sql-auth-store.js → server/src/auth-api/sql-auth-store.cjs} +8 -8
- package/dist/cjs/{auth-api/user-id.js → server/src/auth-api/user-id.cjs} +12 -3
- package/dist/{esm → cjs/server/src}/auth-cookie-options.d.ts +5 -3
- package/dist/cjs/server/src/base/client-info.cjs +285 -0
- package/dist/cjs/server/src/base/client-info.d.ts +27 -0
- package/dist/cjs/server/src/base/error-utils.cjs +50 -0
- package/dist/cjs/server/src/base/error-utils.d.ts +16 -0
- package/dist/cjs/server/src/base/request-utils.cjs +27 -0
- package/dist/cjs/server/src/base/request-utils.d.ts +8 -0
- package/dist/cjs/{index.cjs → server/src/index.cjs} +24 -15
- package/dist/{esm → cjs/server/src}/index.d.ts +7 -0
- package/dist/cjs/server/src/limiter/auth-rate-limiter.cjs +35 -0
- package/dist/cjs/server/src/limiter/auth-rate-limiter.d.ts +12 -0
- package/dist/cjs/server/src/limiter/fixed-window.cjs +41 -0
- package/dist/cjs/server/src/limiter/fixed-window.d.ts +11 -0
- package/dist/cjs/{oauth/base.js → server/src/oauth/base.cjs} +1 -0
- package/dist/cjs/{oauth → server/src/oauth}/base.d.ts +8 -1
- package/dist/cjs/{oauth/memory.js → server/src/oauth/memory.cjs} +7 -4
- package/dist/{esm → cjs/server/src}/oauth/memory.d.ts +1 -1
- package/dist/cjs/{oauth/models.js → server/src/oauth/models.cjs} +2 -2
- package/dist/cjs/{oauth/sequelize.js → server/src/oauth/sequelize.cjs} +11 -7
- package/dist/{esm → cjs/server/src}/oauth/sequelize.d.ts +1 -1
- package/dist/cjs/{passkey/base.js → server/src/passkey/base.cjs} +1 -0
- package/dist/{esm → cjs/server/src}/passkey/base.d.ts +11 -0
- package/dist/cjs/{passkey/memory.js → server/src/passkey/memory.cjs} +2 -2
- package/dist/cjs/{passkey/models.js → server/src/passkey/models.cjs} +1 -1
- package/dist/cjs/{passkey/sequelize.js → server/src/passkey/sequelize.cjs} +3 -3
- package/dist/cjs/{passkey/service.js → server/src/passkey/service.cjs} +17 -3
- package/dist/{esm → cjs/server/src}/passkey/service.d.ts +1 -1
- package/dist/cjs/{sequelize-utils.js → server/src/sequelize-utils.cjs} +4 -5
- package/dist/cjs/{token/base.js → server/src/token/base.cjs} +4 -0
- package/dist/{esm → cjs/server/src}/token/base.d.ts +7 -0
- package/dist/cjs/{token/memory.js → server/src/token/memory.cjs} +15 -20
- package/dist/cjs/{token/sequelize.js → server/src/token/sequelize.cjs} +25 -11
- package/dist/cjs/server/src/upload/memory.cjs +92 -0
- package/dist/cjs/server/src/upload/memory.d.ts +17 -0
- package/dist/cjs/server/src/upload/tus-module.cjs +270 -0
- package/dist/cjs/server/src/upload/tus-module.d.ts +38 -0
- package/dist/cjs/server/src/upload/types.d.ts +8 -0
- package/dist/cjs/{user/base.js → server/src/user/base.cjs} +1 -0
- package/dist/cjs/{user → server/src/user}/base.d.ts +9 -0
- package/dist/cjs/{user/memory.js → server/src/user/memory.cjs} +29 -7
- package/dist/cjs/{user/sequelize.js → server/src/user/sequelize.cjs} +33 -8
- package/dist/cjs/server/src/user/types.cjs +2 -0
- package/dist/esm/common/types.d.ts +137 -0
- package/dist/esm/common/types.js +9 -0
- package/dist/{cjs → esm/server/src}/api-module.d.ts +15 -0
- package/dist/esm/{api-module.js → server/src/api-module.js} +8 -0
- package/dist/{cjs → esm/server/src}/api-server-base.d.ts +105 -78
- package/dist/esm/{api-server-base.js → server/src/api-server-base.js} +658 -616
- package/dist/esm/{auth-api → server/src/auth-api}/auth-module.d.ts +1 -1
- package/dist/esm/{auth-api → server/src/auth-api}/auth-module.js +92 -72
- package/dist/esm/{auth-api → server/src/auth-api}/compat-auth-storage.js +3 -3
- package/dist/esm/server/src/auth-api/schemas.d.ts +21 -0
- package/dist/esm/server/src/auth-api/schemas.js +168 -0
- package/dist/esm/{auth-api → server/src/auth-api}/user-id.js +12 -3
- package/dist/{cjs → esm/server/src}/auth-cookie-options.d.ts +5 -3
- package/dist/esm/server/src/base/client-info.d.ts +27 -0
- package/dist/esm/server/src/base/client-info.js +282 -0
- package/dist/esm/server/src/base/error-utils.d.ts +16 -0
- package/dist/esm/server/src/base/error-utils.js +44 -0
- package/dist/esm/server/src/base/request-utils.d.ts +8 -0
- package/dist/esm/server/src/base/request-utils.js +23 -0
- package/dist/{cjs → esm/server/src}/index.d.ts +7 -0
- package/dist/esm/{index.js → server/src/index.js} +4 -0
- package/dist/esm/server/src/limiter/auth-rate-limiter.d.ts +12 -0
- package/dist/esm/server/src/limiter/auth-rate-limiter.js +32 -0
- package/dist/esm/server/src/limiter/fixed-window.d.ts +11 -0
- package/dist/esm/server/src/limiter/fixed-window.js +37 -0
- package/dist/esm/{oauth → server/src/oauth}/base.d.ts +8 -1
- package/dist/esm/server/src/oauth/base.js +3 -0
- package/dist/{cjs → esm/server/src}/oauth/memory.d.ts +1 -1
- package/dist/esm/{oauth → server/src/oauth}/memory.js +5 -2
- package/dist/{cjs → esm/server/src}/oauth/sequelize.d.ts +1 -1
- package/dist/esm/{oauth → server/src/oauth}/sequelize.js +6 -2
- package/dist/{cjs → esm/server/src}/passkey/base.d.ts +11 -0
- package/dist/esm/server/src/passkey/base.js +3 -0
- package/dist/{cjs → esm/server/src}/passkey/service.d.ts +1 -1
- package/dist/esm/{passkey → server/src/passkey}/service.js +17 -3
- package/dist/esm/{sequelize-utils.js → server/src/sequelize-utils.js} +4 -5
- package/dist/{cjs → esm/server/src}/token/base.d.ts +7 -0
- package/dist/esm/{token → server/src/token}/base.js +4 -0
- package/dist/esm/{token → server/src/token}/memory.js +14 -19
- package/dist/esm/{token → server/src/token}/sequelize.js +22 -8
- package/dist/esm/server/src/upload/memory.d.ts +17 -0
- package/dist/esm/server/src/upload/memory.js +86 -0
- package/dist/esm/server/src/upload/tus-module.d.ts +38 -0
- package/dist/esm/server/src/upload/tus-module.js +266 -0
- package/dist/esm/server/src/upload/types.d.ts +8 -0
- package/dist/esm/{user → server/src/user}/base.d.ts +9 -0
- package/dist/esm/{user → server/src/user}/base.js +1 -0
- package/dist/esm/{user → server/src/user}/memory.js +27 -5
- package/dist/esm/{user → server/src/user}/sequelize.js +30 -5
- package/dist/esm/server/src/user/types.js +1 -0
- package/docs/swagger/openapi.json +411 -125
- package/package.json +129 -134
- package/README.txt +0 -213
- package/dist/esm/oauth/base.js +0 -2
- package/dist/esm/passkey/base.js +0 -2
- /package/dist/cjs/{auth-api → server/src/auth-api}/compat-auth-storage.d.ts +0 -0
- /package/dist/cjs/{auth-api → server/src/auth-api}/mem-auth-store.d.ts +0 -0
- /package/dist/cjs/{auth-api → server/src/auth-api}/module.d.ts +0 -0
- /package/dist/cjs/{auth-api → server/src/auth-api}/sql-auth-store.d.ts +0 -0
- /package/dist/cjs/{auth-api/storage.js → server/src/auth-api/storage.cjs} +0 -0
- /package/dist/cjs/{auth-api → server/src/auth-api}/storage.d.ts +0 -0
- /package/dist/cjs/{auth-api/types.js → server/src/auth-api/types.cjs} +0 -0
- /package/dist/cjs/{auth-api → server/src/auth-api}/types.d.ts +0 -0
- /package/dist/cjs/{auth-api → server/src/auth-api}/user-id.d.ts +0 -0
- /package/dist/cjs/{auth-cookie-options.js → server/src/auth-cookie-options.cjs} +0 -0
- /package/dist/cjs/{oauth → server/src/oauth}/models.d.ts +0 -0
- /package/dist/cjs/{oauth/types.js → server/src/oauth/types.cjs} +0 -0
- /package/dist/cjs/{oauth → server/src/oauth}/types.d.ts +0 -0
- /package/dist/cjs/{passkey/config.js → server/src/passkey/config.cjs} +0 -0
- /package/dist/cjs/{passkey → server/src/passkey}/config.d.ts +0 -0
- /package/dist/cjs/{passkey → server/src/passkey}/memory.d.ts +0 -0
- /package/dist/cjs/{passkey → server/src/passkey}/models.d.ts +0 -0
- /package/dist/cjs/{passkey → server/src/passkey}/sequelize.d.ts +0 -0
- /package/dist/cjs/{passkey/types.js → server/src/passkey/types.cjs} +0 -0
- /package/dist/cjs/{passkey → server/src/passkey}/types.d.ts +0 -0
- /package/dist/cjs/{sequelize-utils.d.ts → server/src/sequelize-utils.d.ts} +0 -0
- /package/dist/cjs/{token → server/src/token}/memory.d.ts +0 -0
- /package/dist/cjs/{token → server/src/token}/sequelize.d.ts +0 -0
- /package/dist/cjs/{token/types.js → server/src/token/types.cjs} +0 -0
- /package/dist/cjs/{token → server/src/token}/types.d.ts +0 -0
- /package/dist/cjs/{user/types.js → server/src/upload/types.cjs} +0 -0
- /package/dist/cjs/{user → server/src/user}/memory.d.ts +0 -0
- /package/dist/cjs/{user → server/src/user}/sequelize.d.ts +0 -0
- /package/dist/cjs/{user → server/src/user}/types.d.ts +0 -0
- /package/dist/esm/{auth-api → server/src/auth-api}/compat-auth-storage.d.ts +0 -0
- /package/dist/esm/{auth-api → server/src/auth-api}/mem-auth-store.d.ts +0 -0
- /package/dist/esm/{auth-api → server/src/auth-api}/mem-auth-store.js +0 -0
- /package/dist/esm/{auth-api → server/src/auth-api}/module.d.ts +0 -0
- /package/dist/esm/{auth-api → server/src/auth-api}/module.js +0 -0
- /package/dist/esm/{auth-api → server/src/auth-api}/sql-auth-store.d.ts +0 -0
- /package/dist/esm/{auth-api → server/src/auth-api}/sql-auth-store.js +0 -0
- /package/dist/esm/{auth-api → server/src/auth-api}/storage.d.ts +0 -0
- /package/dist/esm/{auth-api → server/src/auth-api}/storage.js +0 -0
- /package/dist/esm/{auth-api → server/src/auth-api}/types.d.ts +0 -0
- /package/dist/esm/{auth-api → server/src/auth-api}/types.js +0 -0
- /package/dist/esm/{auth-api → server/src/auth-api}/user-id.d.ts +0 -0
- /package/dist/esm/{auth-cookie-options.js → server/src/auth-cookie-options.js} +0 -0
- /package/dist/esm/{oauth → server/src/oauth}/models.d.ts +0 -0
- /package/dist/esm/{oauth → server/src/oauth}/models.js +0 -0
- /package/dist/esm/{oauth → server/src/oauth}/types.d.ts +0 -0
- /package/dist/esm/{oauth → server/src/oauth}/types.js +0 -0
- /package/dist/esm/{passkey → server/src/passkey}/config.d.ts +0 -0
- /package/dist/esm/{passkey → server/src/passkey}/config.js +0 -0
- /package/dist/esm/{passkey → server/src/passkey}/memory.d.ts +0 -0
- /package/dist/esm/{passkey → server/src/passkey}/memory.js +0 -0
- /package/dist/esm/{passkey → server/src/passkey}/models.d.ts +0 -0
- /package/dist/esm/{passkey → server/src/passkey}/models.js +0 -0
- /package/dist/esm/{passkey → server/src/passkey}/sequelize.d.ts +0 -0
- /package/dist/esm/{passkey → server/src/passkey}/sequelize.js +0 -0
- /package/dist/esm/{passkey → server/src/passkey}/types.d.ts +0 -0
- /package/dist/esm/{passkey → server/src/passkey}/types.js +0 -0
- /package/dist/esm/{sequelize-utils.d.ts → server/src/sequelize-utils.d.ts} +0 -0
- /package/dist/esm/{token → server/src/token}/memory.d.ts +0 -0
- /package/dist/esm/{token → server/src/token}/sequelize.d.ts +0 -0
- /package/dist/esm/{token → server/src/token}/types.d.ts +0 -0
- /package/dist/esm/{token → server/src/token}/types.js +0 -0
- /package/dist/esm/{user → server/src/upload}/types.js +0 -0
- /package/dist/esm/{user → server/src/user}/memory.d.ts +0 -0
- /package/dist/esm/{user → server/src/user}/sequelize.d.ts +0 -0
- /package/dist/esm/{user → server/src/user}/types.d.ts +0 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON Schema definitions for auth module routes.
|
|
3
|
+
* These are the runtime validation source-of-truth; TypeScript interfaces
|
|
4
|
+
* in auth-module.ts remain for handler-internal typing only.
|
|
5
|
+
*/
|
|
6
|
+
/** Loose JSON Schema object type used for Fastify route schema definitions. */
|
|
7
|
+
type JsonSchema = Record<string, unknown>;
|
|
8
|
+
export declare const loginBodySchema: JsonSchema;
|
|
9
|
+
export declare const refreshBodySchema: JsonSchema;
|
|
10
|
+
export declare const logoutBodySchema: JsonSchema;
|
|
11
|
+
export declare const whoamiBodySchema: JsonSchema;
|
|
12
|
+
export declare const passkeyChallengeBodySchema: JsonSchema;
|
|
13
|
+
export declare const passkeyVerifyBodySchema: JsonSchema;
|
|
14
|
+
export declare const passkeyCredentialParamsSchema: JsonSchema;
|
|
15
|
+
export declare const impersonateBodySchema: JsonSchema;
|
|
16
|
+
export declare const deleteImpersonationQuerySchema: JsonSchema;
|
|
17
|
+
export declare const oauthProviderParamsSchema: JsonSchema;
|
|
18
|
+
export declare const oauthStartBodySchema: JsonSchema;
|
|
19
|
+
export declare const oauthAuthorizeBodySchema: JsonSchema;
|
|
20
|
+
export declare const oauthTokenBodySchema: JsonSchema;
|
|
21
|
+
export {};
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SqlAuthStore = void 0;
|
|
4
|
-
const sequelize_js_1 = require("../oauth/sequelize.
|
|
5
|
-
const config_js_1 = require("../passkey/config.
|
|
6
|
-
const sequelize_js_2 = require("../passkey/sequelize.
|
|
7
|
-
const sequelize_utils_js_1 = require("../sequelize-utils.
|
|
8
|
-
const sequelize_js_3 = require("../token/sequelize.
|
|
9
|
-
const sequelize_js_4 = require("../user/sequelize.
|
|
10
|
-
const compat_auth_storage_js_1 = require("./compat-auth-storage.
|
|
11
|
-
const user_id_js_1 = require("./user-id.
|
|
4
|
+
const sequelize_js_1 = require("../oauth/sequelize.cjs");
|
|
5
|
+
const config_js_1 = require("../passkey/config.cjs");
|
|
6
|
+
const sequelize_js_2 = require("../passkey/sequelize.cjs");
|
|
7
|
+
const sequelize_utils_js_1 = require("../sequelize-utils.cjs");
|
|
8
|
+
const sequelize_js_3 = require("../token/sequelize.cjs");
|
|
9
|
+
const sequelize_js_4 = require("../user/sequelize.cjs");
|
|
10
|
+
const compat_auth_storage_js_1 = require("./compat-auth-storage.cjs");
|
|
11
|
+
const user_id_js_1 = require("./user-id.cjs");
|
|
12
12
|
function resolveTablePrefix(...prefixes) {
|
|
13
13
|
for (const prefix of prefixes) {
|
|
14
14
|
const normalized = (0, sequelize_utils_js_1.normalizeTablePrefix)(prefix);
|
|
@@ -14,7 +14,12 @@ function normalizeComparableUserId(identifier) {
|
|
|
14
14
|
throw new Error(`Unable to normalise user identifier: ${identifier}`);
|
|
15
15
|
}
|
|
16
16
|
if (/^\d+$/.test(trimmed)) {
|
|
17
|
-
|
|
17
|
+
const num = Number(trimmed);
|
|
18
|
+
// Avoid precision loss for large numeric strings
|
|
19
|
+
if (!Number.isSafeInteger(num)) {
|
|
20
|
+
return trimmed;
|
|
21
|
+
}
|
|
22
|
+
return String(num);
|
|
18
23
|
}
|
|
19
24
|
return trimmed;
|
|
20
25
|
}
|
|
@@ -23,9 +28,13 @@ function normalizeComparableUserId(identifier) {
|
|
|
23
28
|
function normalizeNumericUserId(identifier) {
|
|
24
29
|
const normalized = normalizeComparableUserId(identifier);
|
|
25
30
|
if (/^\d+$/.test(normalized)) {
|
|
26
|
-
|
|
31
|
+
const num = Number(normalized);
|
|
32
|
+
if (!Number.isSafeInteger(num)) {
|
|
33
|
+
throw new Error(`Sequelize OAuth/Passkey store requires numeric user IDs within safe integer range: ${identifier}`);
|
|
34
|
+
}
|
|
35
|
+
return num;
|
|
27
36
|
}
|
|
28
|
-
throw new Error(`
|
|
37
|
+
throw new Error(`Sequelize OAuth/Passkey store requires numeric user IDs: ${identifier}`);
|
|
29
38
|
}
|
|
30
39
|
function normalizeStringUserId(identifier) {
|
|
31
40
|
return normalizeComparableUserId(identifier);
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { CookieOptions } from 'express-serve-static-core';
|
|
1
|
+
import type { ApiCookieOptions } from './api-server-base.js';
|
|
3
2
|
export interface AuthCookieConfig {
|
|
4
3
|
cookieSecure?: boolean | 'auto';
|
|
5
4
|
cookieSameSite?: 'lax' | 'strict' | 'none';
|
|
@@ -8,4 +7,7 @@ export interface AuthCookieConfig {
|
|
|
8
7
|
cookiePath?: string;
|
|
9
8
|
devMode?: boolean;
|
|
10
9
|
}
|
|
11
|
-
export declare function buildAuthCookieOptions(config: AuthCookieConfig, req:
|
|
10
|
+
export declare function buildAuthCookieOptions(config: AuthCookieConfig, req: {
|
|
11
|
+
headers: Record<string, string | string[] | undefined>;
|
|
12
|
+
protocol?: string;
|
|
13
|
+
}): ApiCookieOptions;
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ensureClientInfo = ensureClientInfo;
|
|
4
|
+
function normalizeIpAddress(candidate) {
|
|
5
|
+
let value = candidate.trim();
|
|
6
|
+
if (!value) {
|
|
7
|
+
return null;
|
|
8
|
+
}
|
|
9
|
+
value = value.replace(/^"+|"+$/g, '').replace(/^'+|'+$/g, '');
|
|
10
|
+
if (value.startsWith('::ffff:')) {
|
|
11
|
+
value = value.slice(7);
|
|
12
|
+
}
|
|
13
|
+
if (value.startsWith('[') && value.endsWith(']')) {
|
|
14
|
+
value = value.slice(1, -1);
|
|
15
|
+
}
|
|
16
|
+
const firstColon = value.indexOf(':');
|
|
17
|
+
const lastColon = value.lastIndexOf(':');
|
|
18
|
+
if (firstColon !== -1 && firstColon === lastColon) {
|
|
19
|
+
const maybePort = value.slice(lastColon + 1);
|
|
20
|
+
if (/^\d+$/.test(maybePort)) {
|
|
21
|
+
value = value.slice(0, lastColon);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
value = value.trim();
|
|
25
|
+
return value || null;
|
|
26
|
+
}
|
|
27
|
+
function extractForwardedFor(header) {
|
|
28
|
+
if (!header) {
|
|
29
|
+
return [];
|
|
30
|
+
}
|
|
31
|
+
const values = Array.isArray(header) ? header : [header];
|
|
32
|
+
const ips = [];
|
|
33
|
+
for (const entry of values) {
|
|
34
|
+
for (const part of entry.split(',')) {
|
|
35
|
+
const normalized = normalizeIpAddress(part);
|
|
36
|
+
if (normalized) {
|
|
37
|
+
ips.push(normalized);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return ips;
|
|
42
|
+
}
|
|
43
|
+
function extractForwardedHeader(header) {
|
|
44
|
+
if (!header) {
|
|
45
|
+
return [];
|
|
46
|
+
}
|
|
47
|
+
const values = Array.isArray(header) ? header : [header];
|
|
48
|
+
const ips = [];
|
|
49
|
+
for (const entry of values) {
|
|
50
|
+
for (const part of entry.split(',')) {
|
|
51
|
+
const match = part.match(/for=([^;]+)/i);
|
|
52
|
+
if (match) {
|
|
53
|
+
const normalized = normalizeIpAddress(match[1]);
|
|
54
|
+
if (normalized) {
|
|
55
|
+
ips.push(normalized);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return ips;
|
|
61
|
+
}
|
|
62
|
+
function detectBrowser(userAgent) {
|
|
63
|
+
const browserMatchers = [
|
|
64
|
+
{ label: 'Edge', pattern: /(Edg|Edge|EdgiOS|EdgA)\/([\d.]+)/i, versionGroup: 2 },
|
|
65
|
+
{ label: 'Chrome', pattern: /(Chrome|CriOS)\/([\d.]+)/i, versionGroup: 2 },
|
|
66
|
+
{ label: 'Firefox', pattern: /(Firefox|FxiOS)\/([\d.]+)/i, versionGroup: 2 },
|
|
67
|
+
{ label: 'Safari', pattern: /Version\/([\d.]+).*Safari/i, versionGroup: 1 },
|
|
68
|
+
{ label: 'Opera', pattern: /(OPR|Opera)\/([\d.]+)/i, versionGroup: 2 },
|
|
69
|
+
{ label: 'Brave', pattern: /Brave\/([\d.]+)/i, versionGroup: 1 },
|
|
70
|
+
{ label: 'Vivaldi', pattern: /Vivaldi\/([\d.]+)/i, versionGroup: 1 },
|
|
71
|
+
{ label: 'Electron', pattern: /Electron\/([\d.]+)/i, versionGroup: 1 },
|
|
72
|
+
{ label: 'Node', pattern: /Node\.js\/([\d.]+)/i, versionGroup: 1 },
|
|
73
|
+
{ label: 'IE', pattern: /MSIE ([\d.]+)/i, versionGroup: 1 },
|
|
74
|
+
{ label: 'IE', pattern: /Trident\/.*rv:([\d.]+)/i, versionGroup: 1 }
|
|
75
|
+
];
|
|
76
|
+
for (const matcher of browserMatchers) {
|
|
77
|
+
const m = userAgent.match(matcher.pattern);
|
|
78
|
+
if (m) {
|
|
79
|
+
const version = matcher.versionGroup ? m[matcher.versionGroup] : '';
|
|
80
|
+
return version ? `${matcher.label} ${version}` : matcher.label;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return '';
|
|
84
|
+
}
|
|
85
|
+
function detectOs(userAgent) {
|
|
86
|
+
const osMatchers = [
|
|
87
|
+
{
|
|
88
|
+
label: 'Windows',
|
|
89
|
+
pattern: /Windows NT ([\d.]+)/i,
|
|
90
|
+
transform: (match) => `Windows ${match[1]}`
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
label: 'iOS',
|
|
94
|
+
pattern: /iPhone OS ([\d_]+)/i,
|
|
95
|
+
transform: (match) => `iOS ${match[1].replace(/_/g, '.')}`
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
label: 'iPadOS',
|
|
99
|
+
pattern: /iPad; CPU OS ([\d_]+)/i,
|
|
100
|
+
transform: (match) => `iPadOS ${match[1].replace(/_/g, '.')}`
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
label: 'macOS',
|
|
104
|
+
pattern: /Mac OS X ([\d_]+)/i,
|
|
105
|
+
transform: (match) => `macOS ${match[1].replace(/_/g, '.')}`
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
label: 'Android',
|
|
109
|
+
pattern: /Android ([\d.]+)/i,
|
|
110
|
+
transform: (match) => `Android ${match[1]}`
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
label: 'ChromeOS',
|
|
114
|
+
pattern: /CrOS [^ ]+ ([\d.]+)/i,
|
|
115
|
+
transform: (match) => `ChromeOS ${match[1]}`
|
|
116
|
+
},
|
|
117
|
+
{ label: 'Linux', pattern: /Linux/i },
|
|
118
|
+
{ label: 'Unix', pattern: /X11/i }
|
|
119
|
+
];
|
|
120
|
+
for (const matcher of osMatchers) {
|
|
121
|
+
const m = userAgent.match(matcher.pattern);
|
|
122
|
+
if (m) {
|
|
123
|
+
return matcher.transform ? matcher.transform(m) : matcher.label;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return '';
|
|
127
|
+
}
|
|
128
|
+
function detectDevice(userAgent, osLabel) {
|
|
129
|
+
if (/iPhone/i.test(userAgent)) {
|
|
130
|
+
return 'iPhone';
|
|
131
|
+
}
|
|
132
|
+
if (/iPad/i.test(userAgent)) {
|
|
133
|
+
return 'iPad';
|
|
134
|
+
}
|
|
135
|
+
if (/iPod/i.test(userAgent)) {
|
|
136
|
+
return 'iPod';
|
|
137
|
+
}
|
|
138
|
+
if (/Android/i.test(userAgent)) {
|
|
139
|
+
const match = userAgent.match(/;\s*([^;]+)\s+Build/i);
|
|
140
|
+
if (match) {
|
|
141
|
+
return match[1];
|
|
142
|
+
}
|
|
143
|
+
return 'Android Device';
|
|
144
|
+
}
|
|
145
|
+
if (/Macintosh/i.test(userAgent)) {
|
|
146
|
+
return 'Mac';
|
|
147
|
+
}
|
|
148
|
+
if (/Windows/i.test(userAgent)) {
|
|
149
|
+
return 'PC';
|
|
150
|
+
}
|
|
151
|
+
if (/CrOS/i.test(userAgent)) {
|
|
152
|
+
return 'Chromebook';
|
|
153
|
+
}
|
|
154
|
+
return osLabel;
|
|
155
|
+
}
|
|
156
|
+
function parseClientAgent(userAgentHeader) {
|
|
157
|
+
const raw = Array.isArray(userAgentHeader) ? userAgentHeader[0] : userAgentHeader;
|
|
158
|
+
const ua = typeof raw === 'string' ? raw.trim() : '';
|
|
159
|
+
if (!ua) {
|
|
160
|
+
return { ua: '', browser: '', os: '', device: '' };
|
|
161
|
+
}
|
|
162
|
+
const os = detectOs(ua);
|
|
163
|
+
const browser = detectBrowser(ua);
|
|
164
|
+
const device = detectDevice(ua, os);
|
|
165
|
+
return { ua, browser, os, device };
|
|
166
|
+
}
|
|
167
|
+
function isLoopbackAddress(ip) {
|
|
168
|
+
if (ip === '::1' || ip === '0:0:0:0:0:0:0:1') {
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
171
|
+
if (ip === '0.0.0.0' || ip === '127.0.0.1') {
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
if (ip.startsWith('127.')) {
|
|
175
|
+
return true;
|
|
176
|
+
}
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
function collectSocketAddresses(req) {
|
|
180
|
+
const seen = new Set();
|
|
181
|
+
const result = [];
|
|
182
|
+
const pushNormalized = (ip) => {
|
|
183
|
+
if (!ip || seen.has(ip))
|
|
184
|
+
return;
|
|
185
|
+
seen.add(ip);
|
|
186
|
+
result.push(ip);
|
|
187
|
+
};
|
|
188
|
+
if (Array.isArray(req.ips)) {
|
|
189
|
+
for (const ip of req.ips) {
|
|
190
|
+
pushNormalized(normalizeIpAddress(ip));
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
if (typeof req.ip === 'string') {
|
|
194
|
+
pushNormalized(normalizeIpAddress(req.ip));
|
|
195
|
+
}
|
|
196
|
+
const socketAddress = req.socket?.remoteAddress;
|
|
197
|
+
if (typeof socketAddress === 'string') {
|
|
198
|
+
pushNormalized(normalizeIpAddress(socketAddress));
|
|
199
|
+
}
|
|
200
|
+
const connectionAddress = req.connection?.remoteAddress;
|
|
201
|
+
if (typeof connectionAddress === 'string') {
|
|
202
|
+
pushNormalized(normalizeIpAddress(connectionAddress));
|
|
203
|
+
}
|
|
204
|
+
return result;
|
|
205
|
+
}
|
|
206
|
+
function collectForwardedIps(req) {
|
|
207
|
+
const seen = new Set();
|
|
208
|
+
const result = [];
|
|
209
|
+
const pushNormalized = (ip) => {
|
|
210
|
+
if (!ip || seen.has(ip))
|
|
211
|
+
return;
|
|
212
|
+
seen.add(ip);
|
|
213
|
+
result.push(ip);
|
|
214
|
+
};
|
|
215
|
+
for (const ip of extractForwardedFor(req.headers['x-forwarded-for'])) {
|
|
216
|
+
pushNormalized(ip);
|
|
217
|
+
}
|
|
218
|
+
for (const ip of extractForwardedHeader(req.headers['forwarded'])) {
|
|
219
|
+
pushNormalized(ip);
|
|
220
|
+
}
|
|
221
|
+
const realIp = req.headers['x-real-ip'];
|
|
222
|
+
if (Array.isArray(realIp)) {
|
|
223
|
+
for (const value of realIp) {
|
|
224
|
+
pushNormalized(normalizeIpAddress(value));
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
else if (typeof realIp === 'string') {
|
|
228
|
+
pushNormalized(normalizeIpAddress(realIp));
|
|
229
|
+
}
|
|
230
|
+
return result;
|
|
231
|
+
}
|
|
232
|
+
function collectClientIpChain(req, trustProxy) {
|
|
233
|
+
const socketIps = collectSocketAddresses(req);
|
|
234
|
+
// trustProxy=false: ignore forwarded headers entirely
|
|
235
|
+
if (trustProxy === false) {
|
|
236
|
+
return socketIps;
|
|
237
|
+
}
|
|
238
|
+
const forwardedIps = collectForwardedIps(req);
|
|
239
|
+
// trustProxy=number: only trust that many rightmost forwarded entries
|
|
240
|
+
if (typeof trustProxy === 'number' && trustProxy >= 0) {
|
|
241
|
+
const trusted = trustProxy > 0 ? forwardedIps.slice(-trustProxy) : [];
|
|
242
|
+
const seen = new Set(trusted);
|
|
243
|
+
for (const ip of socketIps) {
|
|
244
|
+
if (!seen.has(ip)) {
|
|
245
|
+
seen.add(ip);
|
|
246
|
+
trusted.push(ip);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return trusted;
|
|
250
|
+
}
|
|
251
|
+
// trustProxy=true or undefined: trust all (backwards-compatible default)
|
|
252
|
+
const seen = new Set(forwardedIps);
|
|
253
|
+
const result = [...forwardedIps];
|
|
254
|
+
for (const ip of socketIps) {
|
|
255
|
+
if (!seen.has(ip)) {
|
|
256
|
+
seen.add(ip);
|
|
257
|
+
result.push(ip);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
return result;
|
|
261
|
+
}
|
|
262
|
+
function selectClientIp(chain) {
|
|
263
|
+
for (const ip of chain) {
|
|
264
|
+
if (!isLoopbackAddress(ip)) {
|
|
265
|
+
return ip;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
return chain[0] ?? null;
|
|
269
|
+
}
|
|
270
|
+
function buildClientInfo(req, trustProxy) {
|
|
271
|
+
const agent = parseClientAgent(req.headers['user-agent']);
|
|
272
|
+
const ipchain = collectClientIpChain(req, trustProxy);
|
|
273
|
+
const ip = selectClientIp(ipchain);
|
|
274
|
+
return {
|
|
275
|
+
...agent,
|
|
276
|
+
ip,
|
|
277
|
+
ipchain
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
function ensureClientInfo(apiReq, trustProxy) {
|
|
281
|
+
if (!apiReq.clientInfo) {
|
|
282
|
+
apiReq.clientInfo = buildClientInfo(apiReq.req, trustProxy);
|
|
283
|
+
}
|
|
284
|
+
return apiReq.clientInfo;
|
|
285
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
interface ClientInfoRequest {
|
|
2
|
+
headers: Record<string, string | string[] | undefined>;
|
|
3
|
+
ips?: string[];
|
|
4
|
+
ip?: string;
|
|
5
|
+
socket?: {
|
|
6
|
+
remoteAddress?: string;
|
|
7
|
+
};
|
|
8
|
+
connection?: {
|
|
9
|
+
remoteAddress?: string;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export interface ClientAgentProfile {
|
|
13
|
+
ua: string;
|
|
14
|
+
browser: string;
|
|
15
|
+
os: string;
|
|
16
|
+
device: string;
|
|
17
|
+
}
|
|
18
|
+
export interface ClientInfo extends ClientAgentProfile {
|
|
19
|
+
ip: string | null;
|
|
20
|
+
ipchain: string[];
|
|
21
|
+
}
|
|
22
|
+
interface ApiRequestWithClientInfo {
|
|
23
|
+
req: ClientInfoRequest;
|
|
24
|
+
clientInfo?: ClientInfo;
|
|
25
|
+
}
|
|
26
|
+
export declare function ensureClientInfo(apiReq: ApiRequestWithClientInfo, trustProxy?: boolean | number): ClientInfo;
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.guessExceptionText = guessExceptionText;
|
|
4
|
+
exports.normalizeApiErrorParams = normalizeApiErrorParams;
|
|
5
|
+
exports.isApiErrorLike = isApiErrorLike;
|
|
6
|
+
exports.asHttpStatus = asHttpStatus;
|
|
7
|
+
function guessExceptionText(error, defMsg = 'Unknown Error') {
|
|
8
|
+
const msg = [];
|
|
9
|
+
if (typeof error === 'string' && error.trim() !== '') {
|
|
10
|
+
msg.push(error);
|
|
11
|
+
}
|
|
12
|
+
else if (error && typeof error === 'object') {
|
|
13
|
+
const errorDetails = error;
|
|
14
|
+
if (typeof errorDetails.message === 'string' && errorDetails.message.trim() !== '') {
|
|
15
|
+
msg.push(errorDetails.message);
|
|
16
|
+
}
|
|
17
|
+
if (errorDetails.parent &&
|
|
18
|
+
typeof errorDetails.parent.message === 'string' &&
|
|
19
|
+
errorDetails.parent.message.trim() !== '') {
|
|
20
|
+
msg.push(errorDetails.parent.message);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return msg.length > 0 ? msg.join(' / ') : defMsg;
|
|
24
|
+
}
|
|
25
|
+
function normalizeApiErrorParams({ code, message, data, errors }) {
|
|
26
|
+
return {
|
|
27
|
+
code: typeof code === 'number' ? code : 500,
|
|
28
|
+
message: guessExceptionText(message, '[Unknown error (null/undefined)]'),
|
|
29
|
+
data: data !== undefined ? data : null,
|
|
30
|
+
errors: errors !== undefined ? errors : {}
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function isApiErrorLike(candidate) {
|
|
34
|
+
if (!candidate || typeof candidate !== 'object') {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
const maybeError = candidate;
|
|
38
|
+
return typeof maybeError.code === 'number' && typeof maybeError.message === 'string';
|
|
39
|
+
}
|
|
40
|
+
function asHttpStatus(error) {
|
|
41
|
+
if (!error || typeof error !== 'object') {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
const maybe = error;
|
|
45
|
+
const status = typeof maybe.status === 'number' ? maybe.status : maybe.statusCode;
|
|
46
|
+
if (typeof status === 'number' && status >= 400 && status <= 599) {
|
|
47
|
+
return status;
|
|
48
|
+
}
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ApiErrorParams } from '../api-server-base.js';
|
|
2
|
+
export interface ApiErrorLike {
|
|
3
|
+
code: number;
|
|
4
|
+
message: string;
|
|
5
|
+
data?: unknown;
|
|
6
|
+
errors?: unknown;
|
|
7
|
+
}
|
|
8
|
+
export declare function guessExceptionText(error: unknown, defMsg?: string): string;
|
|
9
|
+
export declare function normalizeApiErrorParams({ code, message, data, errors }: ApiErrorParams): {
|
|
10
|
+
code: number;
|
|
11
|
+
message: string;
|
|
12
|
+
data: unknown;
|
|
13
|
+
errors: Record<string, string>;
|
|
14
|
+
};
|
|
15
|
+
export declare function isApiErrorLike(candidate: unknown): candidate is ApiErrorLike;
|
|
16
|
+
export declare function asHttpStatus(error: unknown): number | null;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isPlainObject = isPlainObject;
|
|
4
|
+
exports.hydrateGetBody = hydrateGetBody;
|
|
5
|
+
function isPlainObject(value) {
|
|
6
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
const proto = Object.getPrototypeOf(value);
|
|
10
|
+
return proto === Object.prototype || proto === null;
|
|
11
|
+
}
|
|
12
|
+
function hydrateGetBody(req) {
|
|
13
|
+
if ((req.method ?? '').toUpperCase() !== 'GET') {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
const query = isPlainObject(req.query) ? req.query : null;
|
|
17
|
+
if (!query || Object.keys(query).length === 0) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const body = isPlainObject(req.body) ? req.body : null;
|
|
21
|
+
if (!body || Object.keys(body).length === 0) {
|
|
22
|
+
req.body = { ...query };
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
// Keep explicit body fields authoritative when both query and body provide the same key.
|
|
26
|
+
req.body = { ...query, ...body };
|
|
27
|
+
}
|
|
@@ -3,40 +3,49 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.MemoryOAuthStore = exports.OAuthStore = exports.MemoryPasskeyStore = exports.PasskeyStore = exports.PasskeyService = exports.MemoryTokenStore = exports.TokenStore = exports.MemoryUserStore = exports.UserStore = exports.AuthModule = exports.MemAuthStore = exports.CompositeAuthAdapter = exports.BaseAuthModule = exports.nullAuthModule = exports.BaseAuthAdapter = exports.nullAuthAdapter = exports.ApiModule = exports.ApiError = exports.ApiServer = void 0;
|
|
6
|
+
exports.TusUploadOffsetError = exports.MemoryTusUploadStore = exports.TusUploadModule = exports.createAuthRateLimitHook = exports.FixedWindowRateLimiter = exports.MemoryOAuthStore = exports.OAuthStore = exports.MemoryPasskeyStore = exports.PasskeyStore = exports.PasskeyService = exports.MemoryTokenStore = exports.TokenStore = exports.MemoryUserStore = exports.UserStore = exports.AuthModule = exports.MemAuthStore = exports.CompositeAuthAdapter = exports.BaseAuthModule = exports.nullAuthModule = exports.BaseAuthAdapter = exports.nullAuthAdapter = exports.ApiModule = exports.ApiError = exports.ApiServer = void 0;
|
|
7
7
|
var api_server_base_js_1 = require("./api-server-base.cjs");
|
|
8
8
|
Object.defineProperty(exports, "ApiServer", { enumerable: true, get: function () { return __importDefault(api_server_base_js_1).default; } });
|
|
9
9
|
var api_server_base_js_2 = require("./api-server-base.cjs");
|
|
10
10
|
Object.defineProperty(exports, "ApiError", { enumerable: true, get: function () { return api_server_base_js_2.ApiError; } });
|
|
11
11
|
var api_module_js_1 = require("./api-module.cjs");
|
|
12
12
|
Object.defineProperty(exports, "ApiModule", { enumerable: true, get: function () { return api_module_js_1.ApiModule; } });
|
|
13
|
-
var storage_js_1 = require("./auth-api/storage.
|
|
13
|
+
var storage_js_1 = require("./auth-api/storage.cjs");
|
|
14
14
|
Object.defineProperty(exports, "nullAuthAdapter", { enumerable: true, get: function () { return storage_js_1.nullAuthAdapter; } });
|
|
15
15
|
Object.defineProperty(exports, "BaseAuthAdapter", { enumerable: true, get: function () { return storage_js_1.BaseAuthAdapter; } });
|
|
16
|
-
var module_js_1 = require("./auth-api/module.
|
|
16
|
+
var module_js_1 = require("./auth-api/module.cjs");
|
|
17
17
|
Object.defineProperty(exports, "nullAuthModule", { enumerable: true, get: function () { return module_js_1.nullAuthModule; } });
|
|
18
18
|
Object.defineProperty(exports, "BaseAuthModule", { enumerable: true, get: function () { return module_js_1.BaseAuthModule; } });
|
|
19
|
-
var compat_auth_storage_js_1 = require("./auth-api/compat-auth-storage.
|
|
19
|
+
var compat_auth_storage_js_1 = require("./auth-api/compat-auth-storage.cjs");
|
|
20
20
|
Object.defineProperty(exports, "CompositeAuthAdapter", { enumerable: true, get: function () { return compat_auth_storage_js_1.CompositeAuthAdapter; } });
|
|
21
|
-
var mem_auth_store_js_1 = require("./auth-api/mem-auth-store.
|
|
21
|
+
var mem_auth_store_js_1 = require("./auth-api/mem-auth-store.cjs");
|
|
22
22
|
Object.defineProperty(exports, "MemAuthStore", { enumerable: true, get: function () { return mem_auth_store_js_1.MemAuthStore; } });
|
|
23
|
-
var auth_module_js_1 = require("./auth-api/auth-module.
|
|
23
|
+
var auth_module_js_1 = require("./auth-api/auth-module.cjs");
|
|
24
24
|
Object.defineProperty(exports, "AuthModule", { enumerable: true, get: function () { return __importDefault(auth_module_js_1).default; } });
|
|
25
|
-
var base_js_1 = require("./user/base.
|
|
25
|
+
var base_js_1 = require("./user/base.cjs");
|
|
26
26
|
Object.defineProperty(exports, "UserStore", { enumerable: true, get: function () { return base_js_1.UserStore; } });
|
|
27
|
-
var memory_js_1 = require("./user/memory.
|
|
27
|
+
var memory_js_1 = require("./user/memory.cjs");
|
|
28
28
|
Object.defineProperty(exports, "MemoryUserStore", { enumerable: true, get: function () { return memory_js_1.MemoryUserStore; } });
|
|
29
|
-
var base_js_2 = require("./token/base.
|
|
29
|
+
var base_js_2 = require("./token/base.cjs");
|
|
30
30
|
Object.defineProperty(exports, "TokenStore", { enumerable: true, get: function () { return base_js_2.TokenStore; } });
|
|
31
|
-
var memory_js_2 = require("./token/memory.
|
|
31
|
+
var memory_js_2 = require("./token/memory.cjs");
|
|
32
32
|
Object.defineProperty(exports, "MemoryTokenStore", { enumerable: true, get: function () { return memory_js_2.MemoryTokenStore; } });
|
|
33
|
-
var service_js_1 = require("./passkey/service.
|
|
33
|
+
var service_js_1 = require("./passkey/service.cjs");
|
|
34
34
|
Object.defineProperty(exports, "PasskeyService", { enumerable: true, get: function () { return service_js_1.PasskeyService; } });
|
|
35
|
-
var base_js_3 = require("./passkey/base.
|
|
35
|
+
var base_js_3 = require("./passkey/base.cjs");
|
|
36
36
|
Object.defineProperty(exports, "PasskeyStore", { enumerable: true, get: function () { return base_js_3.PasskeyStore; } });
|
|
37
|
-
var memory_js_3 = require("./passkey/memory.
|
|
37
|
+
var memory_js_3 = require("./passkey/memory.cjs");
|
|
38
38
|
Object.defineProperty(exports, "MemoryPasskeyStore", { enumerable: true, get: function () { return memory_js_3.MemoryPasskeyStore; } });
|
|
39
|
-
var base_js_4 = require("./oauth/base.
|
|
39
|
+
var base_js_4 = require("./oauth/base.cjs");
|
|
40
40
|
Object.defineProperty(exports, "OAuthStore", { enumerable: true, get: function () { return base_js_4.OAuthStore; } });
|
|
41
|
-
var memory_js_4 = require("./oauth/memory.
|
|
41
|
+
var memory_js_4 = require("./oauth/memory.cjs");
|
|
42
42
|
Object.defineProperty(exports, "MemoryOAuthStore", { enumerable: true, get: function () { return memory_js_4.MemoryOAuthStore; } });
|
|
43
|
+
var fixed_window_js_1 = require("./limiter/fixed-window.cjs");
|
|
44
|
+
Object.defineProperty(exports, "FixedWindowRateLimiter", { enumerable: true, get: function () { return fixed_window_js_1.FixedWindowRateLimiter; } });
|
|
45
|
+
var auth_rate_limiter_js_1 = require("./limiter/auth-rate-limiter.cjs");
|
|
46
|
+
Object.defineProperty(exports, "createAuthRateLimitHook", { enumerable: true, get: function () { return auth_rate_limiter_js_1.createAuthRateLimitHook; } });
|
|
47
|
+
var tus_module_js_1 = require("./upload/tus-module.cjs");
|
|
48
|
+
Object.defineProperty(exports, "TusUploadModule", { enumerable: true, get: function () { return tus_module_js_1.TusUploadModule; } });
|
|
49
|
+
var memory_js_5 = require("./upload/memory.cjs");
|
|
50
|
+
Object.defineProperty(exports, "MemoryTusUploadStore", { enumerable: true, get: function () { return memory_js_5.MemoryTusUploadStore; } });
|
|
51
|
+
Object.defineProperty(exports, "TusUploadOffsetError", { enumerable: true, get: function () { return memory_js_5.TusUploadOffsetError; } });
|
|
@@ -25,3 +25,10 @@ export { MemoryPasskeyStore } from './passkey/memory.js';
|
|
|
25
25
|
export type { PasskeyServiceConfig, PasskeyChallengeRecord, PasskeyUserDescriptor, StoredPasskeyCredential, PasskeyChallenge, PasskeyChallengeParams, PasskeyVerificationParams, PasskeyVerificationResult } from './passkey/types.js';
|
|
26
26
|
export { OAuthStore } from './oauth/base.js';
|
|
27
27
|
export { MemoryOAuthStore } from './oauth/memory.js';
|
|
28
|
+
export { FixedWindowRateLimiter } from './limiter/fixed-window.js';
|
|
29
|
+
export type { RateLimitDecision } from './limiter/fixed-window.js';
|
|
30
|
+
export { createAuthRateLimitHook } from './limiter/auth-rate-limiter.js';
|
|
31
|
+
export type { AuthRateLimitConfig } from './limiter/auth-rate-limiter.js';
|
|
32
|
+
export { TusUploadModule } from './upload/tus-module.js';
|
|
33
|
+
export { MemoryTusUploadStore, TusUploadOffsetError } from './upload/memory.js';
|
|
34
|
+
export type { TusMetadata, TusUploadRecord, TusCreateUploadInput, TusAppendInput, TusUploadStore } from './upload/types.js';
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createAuthRateLimitHook = createAuthRateLimitHook;
|
|
4
|
+
const api_server_base_js_1 = require("../api-server-base.cjs");
|
|
5
|
+
const fixed_window_js_1 = require("./fixed-window.cjs");
|
|
6
|
+
function createAuthRateLimitHook(config, limiter) {
|
|
7
|
+
if (!config || Object.keys(config).length === 0) {
|
|
8
|
+
return () => { };
|
|
9
|
+
}
|
|
10
|
+
const instance = limiter ?? new fixed_window_js_1.FixedWindowRateLimiter();
|
|
11
|
+
return (ctx) => {
|
|
12
|
+
const endpointConfig = config[ctx.endpoint];
|
|
13
|
+
if (!endpointConfig) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
const windowSec = endpointConfig.windowSec ?? 0;
|
|
17
|
+
const max = endpointConfig.max ?? 0;
|
|
18
|
+
if (windowSec <= 0 || max <= 0) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const clientIp = ctx.apiReq.getClientIp() ?? '';
|
|
22
|
+
if (!clientIp) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const key = `${ctx.endpoint}:${clientIp}`;
|
|
26
|
+
const decision = instance.check(key, max, windowSec * 1000);
|
|
27
|
+
if (!decision.allowed) {
|
|
28
|
+
throw new api_server_base_js_1.ApiError({
|
|
29
|
+
code: 429,
|
|
30
|
+
message: 'Too many requests; try again later',
|
|
31
|
+
data: { retryAfterSec: decision.retryAfterSec }
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type ApiRequest } from '../api-server-base.js';
|
|
2
|
+
import { FixedWindowRateLimiter } from './fixed-window.js';
|
|
3
|
+
type AuthRateLimitEndpoint = 'login' | 'passkey-challenge' | 'oauth-token' | 'oauth-authorize';
|
|
4
|
+
export interface AuthRateLimitConfig {
|
|
5
|
+
windowSec?: number;
|
|
6
|
+
max?: number;
|
|
7
|
+
}
|
|
8
|
+
export declare function createAuthRateLimitHook(config: Partial<Record<AuthRateLimitEndpoint, AuthRateLimitConfig>>, limiter?: FixedWindowRateLimiter): (ctx: {
|
|
9
|
+
apiReq: ApiRequest;
|
|
10
|
+
endpoint: string;
|
|
11
|
+
}) => void;
|
|
12
|
+
export {};
|