altcha-lib 2.1.0 → 2.3.0

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.
Files changed (44) hide show
  1. package/README.md +28 -0
  2. package/dist/cjs/v2/frameworks/express.js +7 -4
  3. package/dist/cjs/v2/frameworks/fastify.js +7 -4
  4. package/dist/cjs/v2/frameworks/h3.d.ts +1 -1
  5. package/dist/cjs/v2/frameworks/h3.js +11 -4
  6. package/dist/cjs/v2/frameworks/hono.d.ts +18 -0
  7. package/dist/cjs/v2/frameworks/hono.js +9 -3
  8. package/dist/cjs/v2/frameworks/nestjs.d.ts +5 -4
  9. package/dist/cjs/v2/frameworks/nestjs.js +9 -3
  10. package/dist/cjs/v2/frameworks/nextjs.js +9 -4
  11. package/dist/cjs/v2/frameworks/shared.d.ts +4 -4
  12. package/dist/cjs/v2/frameworks/shared.js +22 -3
  13. package/dist/cjs/v2/frameworks/sveltekit.js +8 -5
  14. package/dist/cjs/v2/frameworks/types.d.ts +17 -5
  15. package/dist/cjs/v2/helpers.d.ts +0 -2
  16. package/dist/cjs/v2/helpers.js +0 -12
  17. package/dist/cjs/v2/index.d.ts +3 -1
  18. package/dist/cjs/v2/index.js +4 -1
  19. package/dist/cjs/v2/types.d.ts +54 -0
  20. package/dist/cjs/v2/verify-server.d.ts +3 -0
  21. package/dist/cjs/v2/verify-server.js +57 -0
  22. package/dist/esm/v2/frameworks/express.js +7 -4
  23. package/dist/esm/v2/frameworks/fastify.js +7 -4
  24. package/dist/esm/v2/frameworks/h3.d.ts +1 -1
  25. package/dist/esm/v2/frameworks/h3.js +12 -5
  26. package/dist/esm/v2/frameworks/hono.d.ts +18 -0
  27. package/dist/esm/v2/frameworks/hono.js +9 -3
  28. package/dist/esm/v2/frameworks/nestjs.d.ts +5 -4
  29. package/dist/esm/v2/frameworks/nestjs.js +11 -4
  30. package/dist/esm/v2/frameworks/nextjs.js +9 -4
  31. package/dist/esm/v2/frameworks/shared.d.ts +4 -4
  32. package/dist/esm/v2/frameworks/shared.js +22 -3
  33. package/dist/esm/v2/frameworks/sveltekit.js +8 -5
  34. package/dist/esm/v2/frameworks/types.d.ts +17 -5
  35. package/dist/esm/v2/helpers.d.ts +0 -2
  36. package/dist/esm/v2/helpers.js +0 -11
  37. package/dist/esm/v2/index.d.ts +3 -1
  38. package/dist/esm/v2/index.js +3 -1
  39. package/dist/esm/v2/types.d.ts +54 -0
  40. package/dist/esm/v2/verify-server.d.ts +3 -0
  41. package/dist/esm/v2/verify-server.js +54 -0
  42. package/dist/tsconfig.build.tsbuildinfo +1 -1
  43. package/dist/tsconfig.cjs.tsbuildinfo +1 -1
  44. package/package.json +4 -2
@@ -1,10 +1,11 @@
1
1
  import { createChallenge, solveChallenge, solveChallengeWorkers, verifySolution } from './pow.js';
2
2
  import { verifyFieldsHash, verifyServerSignature } from './server-signature.js';
3
+ import { verifyServer } from './verify-server.js';
3
4
  import { CappedMap } from './capped-map.js';
4
5
  import { randomInt } from './helpers.js';
5
6
  import { HmacAlgorithm } from './types.js';
6
7
  export type * from './types.js';
7
- export { CappedMap, HmacAlgorithm, createChallenge, randomInt, solveChallenge, solveChallengeWorkers, verifyFieldsHash, verifyServerSignature, verifySolution, };
8
+ export { CappedMap, HmacAlgorithm, createChallenge, randomInt, solveChallenge, solveChallengeWorkers, verifyFieldsHash, verifyServer, verifyServerSignature, verifySolution, };
8
9
  declare const _default: {
9
10
  CappedMap: typeof CappedMap;
10
11
  HmacAlgorithm: typeof HmacAlgorithm;
@@ -13,6 +14,7 @@ declare const _default: {
13
14
  solveChallenge: typeof solveChallenge;
14
15
  solveChallengeWorkers: typeof solveChallengeWorkers;
15
16
  verifyFieldsHash: typeof verifyFieldsHash;
17
+ verifyServer: typeof verifyServer;
16
18
  verifyServerSignature: typeof verifyServerSignature;
17
19
  verifySolution: typeof verifySolution;
18
20
  };
@@ -1,9 +1,10 @@
1
1
  import { createChallenge, solveChallenge, solveChallengeWorkers, verifySolution, } from './pow.js';
2
2
  import { verifyFieldsHash, verifyServerSignature } from './server-signature.js';
3
+ import { verifyServer } from './verify-server.js';
3
4
  import { CappedMap } from './capped-map.js';
4
5
  import { randomInt } from './helpers.js';
5
6
  import { HmacAlgorithm } from './types.js';
6
- export { CappedMap, HmacAlgorithm, createChallenge, randomInt, solveChallenge, solveChallengeWorkers, verifyFieldsHash, verifyServerSignature, verifySolution, };
7
+ export { CappedMap, HmacAlgorithm, createChallenge, randomInt, solveChallenge, solveChallengeWorkers, verifyFieldsHash, verifyServer, verifyServerSignature, verifySolution, };
7
8
  export default {
8
9
  CappedMap,
9
10
  HmacAlgorithm,
@@ -12,6 +13,7 @@ export default {
12
13
  solveChallenge,
13
14
  solveChallengeWorkers,
14
15
  verifyFieldsHash,
16
+ verifyServer,
15
17
  verifyServerSignature,
16
18
  verifySolution,
17
19
  };
@@ -233,6 +233,60 @@ export interface VerifyResult {
233
233
  export interface VerifyServerSignatureResult extends VerifySolutionResult {
234
234
  verificationData?: ServerSignatureVerificationData | null;
235
235
  }
236
+ export interface VerifyServerOptions {
237
+ /**
238
+ * The payload to verify, as received from `POST /v1/verify`
239
+ * (either the raw string or the decoded object).
240
+ */
241
+ payload: string | ServerSignaturePayload | Record<string, unknown>;
242
+ /**
243
+ * Full URL of the Sentinel `/v1/verify/signature` endpoint.
244
+ */
245
+ url: string;
246
+ /**
247
+ * API key secret. If provided, Sentinel checks that it matches the
248
+ * API key associated with the payload.
249
+ */
250
+ secret?: string;
251
+ /**
252
+ * Custom fetch implementation. Defaults to the global `fetch`.
253
+ */
254
+ fetch?: typeof fetch;
255
+ /**
256
+ * Additional headers to send with the request.
257
+ */
258
+ headers?: Record<string, string>;
259
+ /**
260
+ * AbortController for cancelling the verification request.
261
+ */
262
+ controller?: AbortController;
263
+ /**
264
+ * Per-attempt request timeout in milliseconds.
265
+ * Defaults to `10_000` (10 seconds).
266
+ */
267
+ timeout?: number;
268
+ /**
269
+ * Number of retry attempts after the first try.
270
+ * Defaults to `0` (no retries).
271
+ */
272
+ retries?: number;
273
+ /**
274
+ * Base delay in milliseconds between retry attempts.
275
+ * Defaults to `300`.
276
+ */
277
+ retryDelay?: number;
278
+ /**
279
+ * Backoff strategy applied to `retryDelay` between retries.
280
+ * Defaults to `'exponential'`.
281
+ */
282
+ retryBackoff?: 'fixed' | 'exponential';
283
+ }
284
+ export interface VerifyServerResult {
285
+ apiKey?: string | null;
286
+ reason?: string;
287
+ verificationData?: ServerSignatureVerificationData | null;
288
+ verified: boolean;
289
+ }
236
290
  export interface VerifySolutionOptions {
237
291
  /**
238
292
  * Challenge object to verify against, either decoded from the client payload
@@ -0,0 +1,3 @@
1
+ import type { VerifyServerOptions, VerifyServerResult } from './types.js';
2
+ /** Verifies a payload remotely via the ALTCHA Sentinel `/v1/verify/signature` API. */
3
+ export declare function verifyServer(options: VerifyServerOptions): Promise<VerifyServerResult>;
@@ -0,0 +1,54 @@
1
+ import { delay } from './helpers.js';
2
+ /** Verifies a payload remotely via the ALTCHA Sentinel `/v1/verify/signature` API. */
3
+ export async function verifyServer(options) {
4
+ const { controller, fetch: fetchImpl = fetch, headers, payload, retries = 0, retryBackoff = 'exponential', retryDelay = 300, secret, timeout = 10_000, url, } = options;
5
+ const body = JSON.stringify({ payload, secret });
6
+ for (let attempt = 0; attempt <= retries; attempt++) {
7
+ if (controller?.signal.aborted) {
8
+ return { verified: false, reason: 'ABORTED' };
9
+ }
10
+ const attemptController = new AbortController();
11
+ const onAbort = () => attemptController.abort();
12
+ controller?.signal.addEventListener('abort', onAbort);
13
+ const timer = setTimeout(() => attemptController.abort(), timeout);
14
+ try {
15
+ const response = await fetchImpl(url, {
16
+ body,
17
+ headers: {
18
+ 'Content-Type': 'application/json',
19
+ ...headers,
20
+ },
21
+ method: 'POST',
22
+ signal: attemptController.signal,
23
+ });
24
+ if (response.status === 400) {
25
+ const data = await response
26
+ .json()
27
+ .catch(() => null);
28
+ return {
29
+ verified: false,
30
+ reason: data?.error ?? `HTTP_${response.status}`,
31
+ };
32
+ }
33
+ if (!response.ok) {
34
+ throw new Error(`HTTP_${response.status}`);
35
+ }
36
+ return (await response.json());
37
+ }
38
+ catch (err) {
39
+ if (attempt >= retries) {
40
+ return {
41
+ verified: false,
42
+ reason: err instanceof Error ? err.message : 'NETWORK_ERROR',
43
+ };
44
+ }
45
+ const backoffDelay = retryBackoff === 'fixed' ? retryDelay : retryDelay * 2 ** attempt;
46
+ await delay(backoffDelay);
47
+ }
48
+ finally {
49
+ clearTimeout(timer);
50
+ controller?.signal.removeEventListener('abort', onAbort);
51
+ }
52
+ }
53
+ return { verified: false, reason: 'NETWORK_ERROR' };
54
+ }
@@ -1 +1 @@
1
- {"root":["../src/v1/helpers.ts","../src/v1/index.ts","../src/v1/types.ts","../src/v1/worker.ts","../src/v2/capped-map.ts","../src/v2/helpers.ts","../src/v2/index.ts","../src/v2/obfuscation.ts","../src/v2/pow.ts","../src/v2/server-signature.ts","../src/v2/types.ts","../src/v2/algorithms/argon2id.ts","../src/v2/algorithms/pbkdf2.ts","../src/v2/algorithms/scrypt.ts","../src/v2/algorithms/sha.ts","../src/v2/algorithms/web/pbkdf2.ts","../src/v2/algorithms/web/sha.ts","../src/v2/frameworks/express.ts","../src/v2/frameworks/fastify.ts","../src/v2/frameworks/h3.ts","../src/v2/frameworks/hono.ts","../src/v2/frameworks/nestjs.ts","../src/v2/frameworks/nextjs.ts","../src/v2/frameworks/shared.ts","../src/v2/frameworks/sveltekit.ts","../src/v2/frameworks/types.ts","../src/v2/workers/argon2id.ts","../src/v2/workers/pbkdf2.ts","../src/v2/workers/scrypt.ts","../src/v2/workers/sha.ts","../src/v2/workers/shared.ts"],"version":"5.9.3"}
1
+ {"root":["../src/v1/helpers.ts","../src/v1/index.ts","../src/v1/types.ts","../src/v1/worker.ts","../src/v2/capped-map.ts","../src/v2/helpers.ts","../src/v2/index.ts","../src/v2/obfuscation.ts","../src/v2/pow.ts","../src/v2/server-signature.ts","../src/v2/types.ts","../src/v2/verify-server.ts","../src/v2/algorithms/argon2id.ts","../src/v2/algorithms/pbkdf2.ts","../src/v2/algorithms/scrypt.ts","../src/v2/algorithms/sha.ts","../src/v2/algorithms/web/pbkdf2.ts","../src/v2/algorithms/web/sha.ts","../src/v2/frameworks/express.ts","../src/v2/frameworks/fastify.ts","../src/v2/frameworks/h3.ts","../src/v2/frameworks/hono.ts","../src/v2/frameworks/nestjs.ts","../src/v2/frameworks/nextjs.ts","../src/v2/frameworks/shared.ts","../src/v2/frameworks/sveltekit.ts","../src/v2/frameworks/types.ts","../src/v2/workers/argon2id.ts","../src/v2/workers/pbkdf2.ts","../src/v2/workers/scrypt.ts","../src/v2/workers/sha.ts","../src/v2/workers/shared.ts"],"version":"5.9.3"}
@@ -1 +1 @@
1
- {"root":["../src/v1/helpers.ts","../src/v1/index.ts","../src/v1/types.ts","../src/v1/worker.ts","../src/v2/capped-map.ts","../src/v2/helpers.ts","../src/v2/index.ts","../src/v2/obfuscation.ts","../src/v2/pow.ts","../src/v2/server-signature.ts","../src/v2/types.ts","../src/v2/algorithms/argon2id.ts","../src/v2/algorithms/pbkdf2.ts","../src/v2/algorithms/scrypt.ts","../src/v2/algorithms/sha.ts","../src/v2/algorithms/web/pbkdf2.ts","../src/v2/algorithms/web/sha.ts","../src/v2/frameworks/express.ts","../src/v2/frameworks/fastify.ts","../src/v2/frameworks/h3.ts","../src/v2/frameworks/hono.ts","../src/v2/frameworks/nestjs.ts","../src/v2/frameworks/nextjs.ts","../src/v2/frameworks/shared.ts","../src/v2/frameworks/sveltekit.ts","../src/v2/frameworks/types.ts","../src/v2/workers/argon2id.ts","../src/v2/workers/pbkdf2.ts","../src/v2/workers/scrypt.ts","../src/v2/workers/sha.ts","../src/v2/workers/shared.ts"],"version":"5.9.3"}
1
+ {"root":["../src/v1/helpers.ts","../src/v1/index.ts","../src/v1/types.ts","../src/v1/worker.ts","../src/v2/capped-map.ts","../src/v2/helpers.ts","../src/v2/index.ts","../src/v2/obfuscation.ts","../src/v2/pow.ts","../src/v2/server-signature.ts","../src/v2/types.ts","../src/v2/verify-server.ts","../src/v2/algorithms/argon2id.ts","../src/v2/algorithms/pbkdf2.ts","../src/v2/algorithms/scrypt.ts","../src/v2/algorithms/sha.ts","../src/v2/algorithms/web/pbkdf2.ts","../src/v2/algorithms/web/sha.ts","../src/v2/frameworks/express.ts","../src/v2/frameworks/fastify.ts","../src/v2/frameworks/h3.ts","../src/v2/frameworks/hono.ts","../src/v2/frameworks/nestjs.ts","../src/v2/frameworks/nextjs.ts","../src/v2/frameworks/shared.ts","../src/v2/frameworks/sveltekit.ts","../src/v2/frameworks/types.ts","../src/v2/workers/argon2id.ts","../src/v2/workers/pbkdf2.ts","../src/v2/workers/scrypt.ts","../src/v2/workers/sha.ts","../src/v2/workers/shared.ts"],"version":"5.9.3"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "altcha-lib",
3
- "version": "2.1.0",
3
+ "version": "2.3.0",
4
4
  "description": "A lightweight library for creating and verifying ALTCHA challenges on the server.",
5
5
  "author": {
6
6
  "name": "Daniel Regeci",
@@ -184,6 +184,8 @@
184
184
  },
185
185
  "overrides": {
186
186
  "cookie": "^1.1.1",
187
- "file-type": "^21.3.1"
187
+ "esbuild": "^0.28.1",
188
+ "file-type": "^21.3.1",
189
+ "multer": "^2.2.0"
188
190
  }
189
191
  }