hono 4.2.0-rc.1 → 4.2.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.
@@ -43,25 +43,38 @@ const auth = (req) => {
43
43
  return { username: userPass[1], password: userPass[2] };
44
44
  };
45
45
  const basicAuth = (options, ...users) => {
46
- if (!options) {
47
- throw new Error('basic auth middleware requires options for "username and password"');
46
+ const usernamePasswordInOptions = "username" in options && "password" in options;
47
+ const verifyUserInOptions = "verifyUser" in options;
48
+ if (!(usernamePasswordInOptions || verifyUserInOptions)) {
49
+ throw new Error(
50
+ 'basic auth middleware requires options for "username and password" or "verifyUser"'
51
+ );
48
52
  }
49
53
  if (!options.realm) {
50
54
  options.realm = "Secure Area";
51
55
  }
52
- users.unshift({ username: options.username, password: options.password });
56
+ if (usernamePasswordInOptions) {
57
+ users.unshift({ username: options.username, password: options.password });
58
+ }
53
59
  return async function basicAuth2(ctx, next) {
54
60
  const requestUser = auth(ctx.req);
55
61
  if (requestUser) {
56
- for (const user of users) {
57
- const [usernameEqual, passwordEqual] = await Promise.all([
58
- (0, import_buffer.timingSafeEqual)(user.username, requestUser.username, options.hashFunction),
59
- (0, import_buffer.timingSafeEqual)(user.password, requestUser.password, options.hashFunction)
60
- ]);
61
- if (usernameEqual && passwordEqual) {
62
+ if (verifyUserInOptions) {
63
+ if (await options.verifyUser(requestUser.username, requestUser.password, ctx)) {
62
64
  await next();
63
65
  return;
64
66
  }
67
+ } else {
68
+ for (const user of users) {
69
+ const [usernameEqual, passwordEqual] = await Promise.all([
70
+ (0, import_buffer.timingSafeEqual)(user.username, requestUser.username, options.hashFunction),
71
+ (0, import_buffer.timingSafeEqual)(user.password, requestUser.password, options.hashFunction)
72
+ ]);
73
+ if (usernameEqual && passwordEqual) {
74
+ await next();
75
+ return;
76
+ }
77
+ }
65
78
  }
66
79
  }
67
80
  const res = new Response("Unauthorized", {
@@ -26,7 +26,7 @@ var import_buffer = require("../../utils/buffer");
26
26
  const TOKEN_STRINGS = "[A-Za-z0-9._~+/-]+=*";
27
27
  const PREFIX = "Bearer";
28
28
  const bearerAuth = (options) => {
29
- if (!options.token) {
29
+ if (!("token" in options || "verifyToken" in options)) {
30
30
  throw new Error('bearer auth middleware requires options for "token"');
31
31
  }
32
32
  if (!options.realm) {
@@ -59,7 +59,9 @@ const bearerAuth = (options) => {
59
59
  throw new import_http_exception.HTTPException(400, { res });
60
60
  } else {
61
61
  let equal = false;
62
- if (typeof options.token === "string") {
62
+ if ("verifyToken" in options) {
63
+ equal = await options.verifyToken(match[1], c);
64
+ } else if (typeof options.token === "string") {
63
65
  equal = await (0, import_buffer.timingSafeEqual)(options.token, match[1], options.hashFunction);
64
66
  } else if (Array.isArray(options.token) && options.token.length > 0) {
65
67
  for (const token of options.token) {
@@ -68,21 +68,22 @@ const jwt = (options) => {
68
68
  });
69
69
  }
70
70
  let payload;
71
- let msg = "";
71
+ let cause;
72
72
  try {
73
73
  payload = await import_jwt.Jwt.verify(token, options.secret, options.alg);
74
74
  } catch (e) {
75
- msg = `${e}`;
75
+ cause = e;
76
76
  }
77
77
  if (!payload) {
78
78
  throw new import_http_exception.HTTPException(401, {
79
- message: msg,
79
+ message: "Unauthorized",
80
80
  res: unauthorizedResponse({
81
81
  ctx,
82
82
  error: "invalid_token",
83
- statusText: msg,
83
+ statusText: "Unauthorized",
84
84
  errDescription: "token verification failure"
85
- })
85
+ }),
86
+ cause
86
87
  });
87
88
  }
88
89
  ctx.set("jwtPayload", payload);
@@ -17,10 +17,12 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
17
17
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
18
18
  mod
19
19
  ));
20
- var import_node_crypto = __toESM(require("node:crypto"), 1);
20
+ var nodeCrypto = __toESM(require("node:crypto"), 1);
21
21
  var import_vitest = require("vitest");
22
- import_vitest.vi.stubGlobal("crypto", import_node_crypto.default);
23
- import_vitest.vi.stubGlobal("CryptoKey", import_node_crypto.default.webcrypto.CryptoKey);
22
+ if (!globalThis.crypto) {
23
+ import_vitest.vi.stubGlobal("crypto", nodeCrypto);
24
+ import_vitest.vi.stubGlobal("CryptoKey", nodeCrypto.webcrypto.CryptoKey);
25
+ }
24
26
  class MockCache {
25
27
  name;
26
28
  store;
@@ -22,7 +22,7 @@ __export(jws_exports, {
22
22
  verifying: () => verifying
23
23
  });
24
24
  module.exports = __toCommonJS(jws_exports);
25
- var import_helper = require("../../helper");
25
+ var import_adapter = require("../../helper/adapter");
26
26
  var import_encode = require("../encode");
27
27
  var import_types = require("./types");
28
28
  var import_types2 = require("./types");
@@ -199,7 +199,7 @@ function getKeyAlgorithm(name) {
199
199
  }
200
200
  }
201
201
  function isCryptoKey(key) {
202
- const runtime = (0, import_helper.getRuntimeKey)();
202
+ const runtime = (0, import_adapter.getRuntimeKey)();
203
203
  if (runtime === "node" && !!crypto.webcrypto) {
204
204
  return key instanceof crypto.webcrypto.CryptoKey;
205
205
  }
@@ -21,25 +21,38 @@ var auth = (req) => {
21
21
  return { username: userPass[1], password: userPass[2] };
22
22
  };
23
23
  var basicAuth = (options, ...users) => {
24
- if (!options) {
25
- throw new Error('basic auth middleware requires options for "username and password"');
24
+ const usernamePasswordInOptions = "username" in options && "password" in options;
25
+ const verifyUserInOptions = "verifyUser" in options;
26
+ if (!(usernamePasswordInOptions || verifyUserInOptions)) {
27
+ throw new Error(
28
+ 'basic auth middleware requires options for "username and password" or "verifyUser"'
29
+ );
26
30
  }
27
31
  if (!options.realm) {
28
32
  options.realm = "Secure Area";
29
33
  }
30
- users.unshift({ username: options.username, password: options.password });
34
+ if (usernamePasswordInOptions) {
35
+ users.unshift({ username: options.username, password: options.password });
36
+ }
31
37
  return async function basicAuth2(ctx, next) {
32
38
  const requestUser = auth(ctx.req);
33
39
  if (requestUser) {
34
- for (const user of users) {
35
- const [usernameEqual, passwordEqual] = await Promise.all([
36
- timingSafeEqual(user.username, requestUser.username, options.hashFunction),
37
- timingSafeEqual(user.password, requestUser.password, options.hashFunction)
38
- ]);
39
- if (usernameEqual && passwordEqual) {
40
+ if (verifyUserInOptions) {
41
+ if (await options.verifyUser(requestUser.username, requestUser.password, ctx)) {
40
42
  await next();
41
43
  return;
42
44
  }
45
+ } else {
46
+ for (const user of users) {
47
+ const [usernameEqual, passwordEqual] = await Promise.all([
48
+ timingSafeEqual(user.username, requestUser.username, options.hashFunction),
49
+ timingSafeEqual(user.password, requestUser.password, options.hashFunction)
50
+ ]);
51
+ if (usernameEqual && passwordEqual) {
52
+ await next();
53
+ return;
54
+ }
55
+ }
43
56
  }
44
57
  }
45
58
  const res = new Response("Unauthorized", {
@@ -4,7 +4,7 @@ import { timingSafeEqual } from "../../utils/buffer.js";
4
4
  var TOKEN_STRINGS = "[A-Za-z0-9._~+/-]+=*";
5
5
  var PREFIX = "Bearer";
6
6
  var bearerAuth = (options) => {
7
- if (!options.token) {
7
+ if (!("token" in options || "verifyToken" in options)) {
8
8
  throw new Error('bearer auth middleware requires options for "token"');
9
9
  }
10
10
  if (!options.realm) {
@@ -37,7 +37,9 @@ var bearerAuth = (options) => {
37
37
  throw new HTTPException(400, { res });
38
38
  } else {
39
39
  let equal = false;
40
- if (typeof options.token === "string") {
40
+ if ("verifyToken" in options) {
41
+ equal = await options.verifyToken(match[1], c);
42
+ } else if (typeof options.token === "string") {
41
43
  equal = await timingSafeEqual(options.token, match[1], options.hashFunction);
42
44
  } else if (Array.isArray(options.token) && options.token.length > 0) {
43
45
  for (const token of options.token) {
@@ -43,21 +43,22 @@ var jwt = (options) => {
43
43
  });
44
44
  }
45
45
  let payload;
46
- let msg = "";
46
+ let cause;
47
47
  try {
48
48
  payload = await Jwt.verify(token, options.secret, options.alg);
49
49
  } catch (e) {
50
- msg = `${e}`;
50
+ cause = e;
51
51
  }
52
52
  if (!payload) {
53
53
  throw new HTTPException(401, {
54
- message: msg,
54
+ message: "Unauthorized",
55
55
  res: unauthorizedResponse({
56
56
  ctx,
57
57
  error: "invalid_token",
58
- statusText: msg,
58
+ statusText: "Unauthorized",
59
59
  errDescription: "token verification failure"
60
- })
60
+ }),
61
+ cause
61
62
  });
62
63
  }
63
64
  ctx.set("jwtPayload", payload);
@@ -1,8 +1,10 @@
1
1
  // src/test-utils/setup-vitest.ts
2
- import crypto from "node:crypto";
2
+ import * as nodeCrypto from "node:crypto";
3
3
  import { vi } from "vitest";
4
- vi.stubGlobal("crypto", crypto);
5
- vi.stubGlobal("CryptoKey", crypto.webcrypto.CryptoKey);
4
+ if (!globalThis.crypto) {
5
+ vi.stubGlobal("crypto", nodeCrypto);
6
+ vi.stubGlobal("CryptoKey", nodeCrypto.webcrypto.CryptoKey);
7
+ }
6
8
  var MockCache = class {
7
9
  name;
8
10
  store;
@@ -1,10 +1,17 @@
1
+ import type { Context } from '../../context';
1
2
  import type { MiddlewareHandler } from '../../types';
2
- export declare const basicAuth: (options: {
3
+ type BasicAuthOptions = {
3
4
  username: string;
4
5
  password: string;
5
6
  realm?: string;
6
7
  hashFunction?: Function;
7
- }, ...users: {
8
+ } | {
9
+ verifyUser: (username: string, password: string, c: Context) => boolean | Promise<boolean>;
10
+ realm?: string;
11
+ hashFunction?: Function;
12
+ };
13
+ export declare const basicAuth: (options: BasicAuthOptions, ...users: {
8
14
  username: string;
9
15
  password: string;
10
16
  }[]) => MiddlewareHandler;
17
+ export {};
@@ -1,7 +1,15 @@
1
+ import type { Context } from '../../context';
1
2
  import type { MiddlewareHandler } from '../../types';
2
- export declare const bearerAuth: (options: {
3
+ type BearerAuthOptions = {
3
4
  token: string | string[];
4
5
  realm?: string;
5
6
  prefix?: string;
6
7
  hashFunction?: Function;
7
- }) => MiddlewareHandler;
8
+ } | {
9
+ realm?: string;
10
+ prefix?: string;
11
+ verifyToken: (token: string, c: Context) => boolean | Promise<boolean>;
12
+ hashFunction?: Function;
13
+ };
14
+ export declare const bearerAuth: (options: BearerAuthOptions) => MiddlewareHandler;
15
+ export {};
@@ -1,5 +1,6 @@
1
1
  import type { MiddlewareHandler } from '../../types';
2
2
  import '../../context';
3
+ import type { SignatureAlgorithm } from '../../utils/jwt/jwa';
3
4
  declare module '../../context' {
4
5
  interface ContextVariableMap {
5
6
  jwtPayload: any;
@@ -8,7 +9,7 @@ declare module '../../context' {
8
9
  export declare const jwt: (options: {
9
10
  secret: string;
10
11
  cookie?: string;
11
- alg?: string;
12
+ alg?: SignatureAlgorithm;
12
13
  }) => MiddlewareHandler;
13
14
  export declare const verify: (token: string, publicKey: import("../../utils/jwt/jws").SignatureKey, alg?: "HS256" | "HS384" | "HS512" | "RS256" | "RS384" | "RS512" | "PS256" | "PS384" | "PS512" | "ES256" | "ES384" | "ES512" | "EdDSA") => Promise<any>;
14
15
  export declare const decode: (token: string) => {
@@ -1,5 +1,5 @@
1
1
  // src/utils/jwt/jws.ts
2
- import { getRuntimeKey } from "../../helper.js";
2
+ import { getRuntimeKey } from "../../helper/adapter/index.js";
3
3
  import { decodeBase64 } from "../encode.js";
4
4
  import { JwtAlgorithmNotImplemented } from "./types.js";
5
5
  import { CryptoKeyUsage } from "./types.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hono",
3
- "version": "4.2.0-rc.1",
3
+ "version": "4.2.1",
4
4
  "description": "Ultrafast web framework for the Edges",
5
5
  "main": "dist/cjs/index.js",
6
6
  "type": "module",
@@ -1,12 +0,0 @@
1
- export * from './helper/accepts';
2
- export * from './helper/adapter';
3
- export * from './helper/cookie';
4
- export * from './helper/css';
5
- export * from './helper/factory';
6
- export * from './helper/html';
7
- export * from './helper/streaming';
8
- export * from './helper/testing';
9
- export * from './helper/dev';
10
- export * from './adapter/deno/ssg';
11
- export * from './adapter/deno/websocket';
12
- export { decode as jwtDecode, sign as jwtSign, verify as jwtVerify } from './middleware/jwt';