@bgord/bun 1.4.4 → 1.4.6
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.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/shield-api-key-noop.adapter.d.ts +5 -0
- package/dist/shield-api-key-noop.adapter.d.ts.map +1 -0
- package/dist/shield-api-key-noop.adapter.js +7 -0
- package/dist/shield-api-key-noop.adapter.js.map +1 -0
- package/dist/{shield-api-key.middleware.d.ts → shield-api-key.adapter.d.ts} +3 -2
- package/dist/shield-api-key.adapter.d.ts.map +1 -0
- package/dist/{shield-api-key.middleware.js → shield-api-key.adapter.js} +3 -3
- package/dist/shield-api-key.adapter.js.map +1 -0
- package/dist/shield-captcha-hcaptcha-local.adapter.d.ts +2 -2
- package/dist/shield-captcha-hcaptcha-local.adapter.d.ts.map +1 -1
- package/dist/shield-captcha-hcaptcha.adapter.d.ts +2 -2
- package/dist/shield-captcha-hcaptcha.adapter.d.ts.map +1 -1
- package/dist/shield-captcha-noop.adapter.d.ts +2 -2
- package/dist/shield-captcha-noop.adapter.d.ts.map +1 -1
- package/dist/shield-captcha-recaptcha.adapter.d.ts +2 -2
- package/dist/shield-captcha-recaptcha.adapter.d.ts.map +1 -1
- package/dist/shield-rate-limit-noop.adapter.d.ts +5 -0
- package/dist/shield-rate-limit-noop.adapter.d.ts.map +1 -0
- package/dist/shield-rate-limit-noop.adapter.js +7 -0
- package/dist/shield-rate-limit-noop.adapter.js.map +1 -0
- package/dist/{shield-rate-limit.middleware.d.ts → shield-rate-limit.adapter.d.ts} +8 -2
- package/dist/shield-rate-limit.adapter.d.ts.map +1 -0
- package/dist/shield-rate-limit.adapter.js +30 -0
- package/dist/shield-rate-limit.adapter.js.map +1 -0
- package/dist/shield.port.d.ts +5 -0
- package/dist/shield.port.d.ts.map +1 -0
- package/dist/shield.port.js +2 -0
- package/dist/shield.port.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/readme.md +5 -3
- package/src/index.ts +5 -3
- package/src/shield-api-key-noop.adapter.ts +8 -0
- package/src/{shield-api-key.middleware.ts → shield-api-key.adapter.ts} +3 -2
- package/src/shield-captcha-hcaptcha-local.adapter.ts +2 -2
- package/src/shield-captcha-hcaptcha.adapter.ts +2 -2
- package/src/shield-captcha-noop.adapter.ts +2 -2
- package/src/shield-captcha-recaptcha.adapter.ts +2 -2
- package/src/shield-rate-limit-noop.adapter.ts +8 -0
- package/src/{shield-rate-limit.middleware.ts → shield-rate-limit.adapter.ts} +16 -10
- package/src/{shield-captcha.port.ts → shield.port.ts} +1 -1
- package/dist/shield-api-key.middleware.d.ts.map +0 -1
- package/dist/shield-api-key.middleware.js.map +0 -1
- package/dist/shield-captcha.port.d.ts +0 -5
- package/dist/shield-captcha.port.d.ts.map +0 -1
- package/dist/shield-captcha.port.js +0 -2
- package/dist/shield-captcha.port.js.map +0 -1
- package/dist/shield-rate-limit.middleware.d.ts.map +0 -1
- package/dist/shield-rate-limit.middleware.js +0 -24
- package/dist/shield-rate-limit.middleware.js.map +0 -1
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -237,14 +237,16 @@ src/
|
|
|
237
237
|
├── secret-manager.port.ts
|
|
238
238
|
├── secret.vo.ts
|
|
239
239
|
├── setup.service.ts
|
|
240
|
-
├── shield-api-key.
|
|
240
|
+
├── shield-api-key-noop.adapter.ts
|
|
241
|
+
├── shield-api-key.adapter.ts
|
|
241
242
|
├── shield-auth.middleware.ts
|
|
242
243
|
├── shield-captcha-hcaptcha-local.adapter.ts
|
|
243
244
|
├── shield-captcha-hcaptcha.adapter.ts
|
|
244
245
|
├── shield-captcha-noop.adapter.ts
|
|
245
246
|
├── shield-captcha-recaptcha.adapter.ts
|
|
246
|
-
├── shield-
|
|
247
|
-
├── shield-rate-limit.
|
|
247
|
+
├── shield-rate-limit-noop.adapter.ts
|
|
248
|
+
├── shield-rate-limit.adapter.ts
|
|
249
|
+
├── shield.port.ts
|
|
248
250
|
├── simulated-error.middleware.ts
|
|
249
251
|
├── slower.middleware.ts
|
|
250
252
|
├── static-files.service.ts
|
package/src/index.ts
CHANGED
|
@@ -158,14 +158,16 @@ export * from "./secret.vo";
|
|
|
158
158
|
export * from "./secret-manager.port";
|
|
159
159
|
export * from "./secret-manager-noop.adapter";
|
|
160
160
|
export * from "./setup.service";
|
|
161
|
-
export * from "./shield
|
|
161
|
+
export * from "./shield.port";
|
|
162
|
+
export * from "./shield-api-key.adapter";
|
|
163
|
+
export * from "./shield-api-key-noop.adapter";
|
|
162
164
|
export * from "./shield-auth.middleware";
|
|
163
|
-
export * from "./shield-captcha.port";
|
|
164
165
|
export * from "./shield-captcha-hcaptcha.adapter";
|
|
165
166
|
export * from "./shield-captcha-hcaptcha-local.adapter";
|
|
166
167
|
export * from "./shield-captcha-noop.adapter";
|
|
167
168
|
export * from "./shield-captcha-recaptcha.adapter";
|
|
168
|
-
export * from "./shield-rate-limit.
|
|
169
|
+
export * from "./shield-rate-limit.adapter";
|
|
170
|
+
export * from "./shield-rate-limit-noop.adapter";
|
|
169
171
|
export * from "./simulated-error.middleware";
|
|
170
172
|
export * from "./slower.middleware";
|
|
171
173
|
export * from "./static-files.service";
|
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import type * as tools from "@bgord/tools";
|
|
2
2
|
import { createMiddleware } from "hono/factory";
|
|
3
3
|
import { HTTPException } from "hono/http-exception";
|
|
4
|
+
import type { ShieldPort } from "./shield.port";
|
|
4
5
|
|
|
5
6
|
type ApiKeyShieldConfigType = { API_KEY: tools.ApiKeyType };
|
|
6
7
|
|
|
7
8
|
export const AccessDeniedApiKeyError = new HTTPException(403, { message: "access_denied_api_key" });
|
|
8
9
|
|
|
9
|
-
export class
|
|
10
|
+
export class ShieldApiKeyAdapter implements ShieldPort {
|
|
10
11
|
static readonly HEADER_NAME = "bgord-api-key";
|
|
11
12
|
|
|
12
13
|
constructor(private readonly config: ApiKeyShieldConfigType) {}
|
|
13
14
|
|
|
14
15
|
verify = createMiddleware(async (c, next) => {
|
|
15
|
-
if (c.req.header(
|
|
16
|
+
if (c.req.header(ShieldApiKeyAdapter.HEADER_NAME) === this.config.API_KEY) return next();
|
|
16
17
|
|
|
17
18
|
throw AccessDeniedApiKeyError;
|
|
18
19
|
});
|
|
@@ -2,13 +2,13 @@ import hcaptcha from "hcaptcha";
|
|
|
2
2
|
import { createMiddleware } from "hono/factory";
|
|
3
3
|
import { HTTPException } from "hono/http-exception";
|
|
4
4
|
import type { HCaptchaSecretKeyType } from "./hcaptcha-secret-key.vo";
|
|
5
|
-
import type {
|
|
5
|
+
import type { ShieldPort } from "./shield.port";
|
|
6
6
|
|
|
7
7
|
export const AccessDeniedHcaptchaLocalError = new HTTPException(403, {
|
|
8
8
|
message: "access_denied_hcaptcha_local",
|
|
9
9
|
});
|
|
10
10
|
|
|
11
|
-
export class ShieldCaptchaHcaptchaLocalAdapter implements
|
|
11
|
+
export class ShieldCaptchaHcaptchaLocalAdapter implements ShieldPort {
|
|
12
12
|
constructor(private readonly secretKey: HCaptchaSecretKeyType) {}
|
|
13
13
|
|
|
14
14
|
verify = createMiddleware(async (_c, next) => {
|
|
@@ -2,11 +2,11 @@ import hcaptcha from "hcaptcha";
|
|
|
2
2
|
import { createMiddleware } from "hono/factory";
|
|
3
3
|
import { HTTPException } from "hono/http-exception";
|
|
4
4
|
import type { HCaptchaSecretKeyType } from "./hcaptcha-secret-key.vo";
|
|
5
|
-
import type {
|
|
5
|
+
import type { ShieldPort } from "./shield.port";
|
|
6
6
|
|
|
7
7
|
export const AccessDeniedHcaptchaError = new HTTPException(403, { message: "access_denied_hcaptcha" });
|
|
8
8
|
|
|
9
|
-
export class ShieldCaptchaHcaptchaAdapter implements
|
|
9
|
+
export class ShieldCaptchaHcaptchaAdapter implements ShieldPort {
|
|
10
10
|
constructor(private readonly secretKey: HCaptchaSecretKeyType) {}
|
|
11
11
|
|
|
12
12
|
verify = createMiddleware(async (c, next) => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createMiddleware } from "hono/factory";
|
|
2
|
-
import type {
|
|
2
|
+
import type { ShieldPort } from "./shield.port";
|
|
3
3
|
|
|
4
|
-
export class ShieldCaptchaNoopAdapter implements
|
|
4
|
+
export class ShieldCaptchaNoopAdapter implements ShieldPort {
|
|
5
5
|
verify = createMiddleware(async (_c, next) => next());
|
|
6
6
|
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { createMiddleware } from "hono/factory";
|
|
2
2
|
import { HTTPException } from "hono/http-exception";
|
|
3
3
|
import type { RecaptchaSecretKeyType } from "./recaptcha-secret-key.vo";
|
|
4
|
-
import type {
|
|
4
|
+
import type { ShieldPort } from "./shield.port";
|
|
5
5
|
|
|
6
6
|
export type RecaptchaVerifierConfigType = { secretKey: RecaptchaSecretKeyType };
|
|
7
7
|
export type RecaptchaResultType = { success: boolean; score: number };
|
|
8
8
|
|
|
9
9
|
export const AccessDeniedRecaptchaError = new HTTPException(403, { message: "access_denied_recaptcha" });
|
|
10
10
|
|
|
11
|
-
export class ShieldCaptchaRecaptchaAdapter implements
|
|
11
|
+
export class ShieldCaptchaRecaptchaAdapter implements ShieldPort {
|
|
12
12
|
constructor(private readonly config: RecaptchaVerifierConfigType) {}
|
|
13
13
|
|
|
14
14
|
verify = createMiddleware(async (c, next) => {
|
|
@@ -4,6 +4,7 @@ import { createMiddleware } from "hono/factory";
|
|
|
4
4
|
import { HTTPException } from "hono/http-exception";
|
|
5
5
|
import type { ClockPort } from "./clock.port";
|
|
6
6
|
import type { RateLimitStorePort } from "./rate-limit-store.port";
|
|
7
|
+
import type { ShieldPort } from "./shield.port";
|
|
7
8
|
|
|
8
9
|
type SubjectResolver = (c: Context) => string;
|
|
9
10
|
type RateLimitShieldOptionsType = { enabled: boolean; store: RateLimitStorePort; subject: SubjectResolver };
|
|
@@ -15,25 +16,30 @@ export const UserSubjectResolver: SubjectResolver = (c) => c.get("user")?.id ??
|
|
|
15
16
|
|
|
16
17
|
export const TooManyRequestsError = new HTTPException(429, { message: "app.too_many_requests" });
|
|
17
18
|
|
|
18
|
-
export
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
export class ShieldRateLimitAdapter implements ShieldPort {
|
|
20
|
+
constructor(
|
|
21
|
+
private readonly options: RateLimitShieldOptionsType,
|
|
22
|
+
private readonly deps: Dependencies,
|
|
23
|
+
) {}
|
|
21
24
|
|
|
22
|
-
|
|
25
|
+
verify = createMiddleware(async (c, next) => {
|
|
26
|
+
if (!this.options.enabled) return next();
|
|
23
27
|
|
|
24
|
-
|
|
28
|
+
const subject = this.options.subject(c);
|
|
29
|
+
|
|
30
|
+
let limiter = await this.options.store.get(subject);
|
|
25
31
|
|
|
26
32
|
if (!limiter) {
|
|
27
|
-
limiter = new tools.RateLimiter(options.store.ttl);
|
|
28
|
-
options.store.set(subject, limiter);
|
|
33
|
+
limiter = new tools.RateLimiter(this.options.store.ttl);
|
|
34
|
+
this.options.store.set(subject, limiter);
|
|
29
35
|
}
|
|
30
36
|
|
|
31
|
-
const check = limiter.verify(deps.Clock.now());
|
|
37
|
+
const check = limiter.verify(this.deps.Clock.now());
|
|
32
38
|
|
|
33
39
|
if (!check.allowed) throw TooManyRequestsError;
|
|
34
40
|
|
|
35
|
-
options.store.set(subject, limiter);
|
|
41
|
+
this.options.store.set(subject, limiter);
|
|
36
42
|
|
|
37
43
|
return next();
|
|
38
44
|
});
|
|
39
|
-
}
|
|
45
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"shield-api-key.middleware.d.ts","sourceRoot":"","sources":["../src/shield-api-key.middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAC;AAE3C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,KAAK,sBAAsB,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC,UAAU,CAAA;CAAE,CAAC;AAE5D,eAAO,MAAM,uBAAuB,eAA+D,CAAC;AAEpG,qBAAa,YAAY;IAGX,OAAO,CAAC,QAAQ,CAAC,MAAM;IAFnC,MAAM,CAAC,QAAQ,CAAC,WAAW,mBAAmB;gBAEjB,MAAM,EAAE,sBAAsB;IAE3D,MAAM,8DAIH;CACJ"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"shield-api-key.middleware.js","sourceRoot":"","sources":["../src/shield-api-key.middleware.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAIpD,MAAM,CAAC,MAAM,uBAAuB,GAAG,IAAI,aAAa,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,uBAAuB,EAAE,CAAC,CAAC;AAEpG,MAAM,OAAO,YAAY;IAGM;IAF7B,MAAM,CAAU,WAAW,GAAG,eAAe,CAAC;IAE9C,YAA6B,MAA8B;QAA9B,WAAM,GAAN,MAAM,CAAwB;IAAG,CAAC;IAE/D,MAAM,GAAG,gBAAgB,CAAC,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;QAC1C,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,OAAO;YAAE,OAAO,IAAI,EAAE,CAAC;QAElF,MAAM,uBAAuB,CAAC;IAChC,CAAC,CAAC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"shield-captcha.port.d.ts","sourceRoot":"","sources":["../src/shield-captcha.port.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAE9C,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,iBAAiB,CAAC;CAC3B"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"shield-captcha.port.js","sourceRoot":"","sources":["../src/shield-captcha.port.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"shield-rate-limit.middleware.d.ts","sourceRoot":"","sources":["../src/shield-rate-limit.middleware.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAEpC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAElE,KAAK,eAAe,GAAG,CAAC,CAAC,EAAE,OAAO,KAAK,MAAM,CAAC;AAC9C,KAAK,0BAA0B,GAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,kBAAkB,CAAC;IAAC,OAAO,EAAE,eAAe,CAAA;CAAE,CAAC;AAE5G,KAAK,YAAY,GAAG;IAAE,KAAK,EAAE,SAAS,CAAA;CAAE,CAAC;AAEzC,eAAO,MAAM,mBAAmB,EAAE,eAA8B,CAAC;AACjE,eAAO,MAAM,mBAAmB,EAAE,eAAoD,CAAC;AAEvF,eAAO,MAAM,oBAAoB,eAA+D,CAAC;AAEjG,eAAO,MAAM,eAAe,GAAI,SAAS,0BAA0B,EAAE,MAAM,YAAY,gEAqBtF,CAAC"}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import * as tools from "@bgord/tools";
|
|
2
|
-
import { createMiddleware } from "hono/factory";
|
|
3
|
-
import { HTTPException } from "hono/http-exception";
|
|
4
|
-
export const AnonSubjectResolver = () => "anon";
|
|
5
|
-
export const UserSubjectResolver = (c) => c.get("user")?.id ?? "anon";
|
|
6
|
-
export const TooManyRequestsError = new HTTPException(429, { message: "app.too_many_requests" });
|
|
7
|
-
export const ShieldRateLimit = (options, deps) => {
|
|
8
|
-
return createMiddleware(async (c, next) => {
|
|
9
|
-
if (!options.enabled)
|
|
10
|
-
return next();
|
|
11
|
-
const subject = options.subject(c);
|
|
12
|
-
let limiter = await options.store.get(subject);
|
|
13
|
-
if (!limiter) {
|
|
14
|
-
limiter = new tools.RateLimiter(options.store.ttl);
|
|
15
|
-
options.store.set(subject, limiter);
|
|
16
|
-
}
|
|
17
|
-
const check = limiter.verify(deps.Clock.now());
|
|
18
|
-
if (!check.allowed)
|
|
19
|
-
throw TooManyRequestsError;
|
|
20
|
-
options.store.set(subject, limiter);
|
|
21
|
-
return next();
|
|
22
|
-
});
|
|
23
|
-
};
|
|
24
|
-
//# sourceMappingURL=shield-rate-limit.middleware.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"shield-rate-limit.middleware.js","sourceRoot":"","sources":["../src/shield-rate-limit.middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAEtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AASpD,MAAM,CAAC,MAAM,mBAAmB,GAAoB,GAAG,EAAE,CAAC,MAAM,CAAC;AACjE,MAAM,CAAC,MAAM,mBAAmB,GAAoB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,MAAM,CAAC;AAEvF,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,aAAa,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,uBAAuB,EAAE,CAAC,CAAC;AAEjG,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,OAAmC,EAAE,IAAkB,EAAE,EAAE;IACzF,OAAO,gBAAgB,CAAC,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;QACxC,IAAI,CAAC,OAAO,CAAC,OAAO;YAAE,OAAO,IAAI,EAAE,CAAC;QAEpC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAEnC,IAAI,OAAO,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAE/C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,GAAG,IAAI,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACnD,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACtC,CAAC;QAED,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;QAE/C,IAAI,CAAC,KAAK,CAAC,OAAO;YAAE,MAAM,oBAAoB,CAAC;QAE/C,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAEpC,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC"}
|