Files
SnowLuma/.pnpm-store/v11/files/59/060f9f6a195ebbdc8ab83084e2a78c872fd87504c36b16e9d895d526f2501c343f657ead7295d5c0f33a3299c5f5d824c8e00bafdead69754375ceebcf4c04
T
TanTan 2a69b23b47
Dev Build / cleanup (push) Waiting to run
Dev Build / typecheck (push) Waiting to run
docs: 仓库链接指向本镜像仓库
2026-11-13 09:27:07 +08:00

101 lines
3.9 KiB
Plaintext

Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const require_http_exception = require("../../http-exception.js");
const require_utils_buffer = require("../../utils/buffer.js");
const require_utils_basic_auth = require("../../utils/basic-auth.js");
//#region src/middleware/basic-auth/index.ts
/**
* Basic Auth Middleware for Hono.
*
* @see {@link https://hono.dev/docs/middleware/builtin/basic-auth}
*
* @param {BasicAuthOptions} options - The options for the basic authentication middleware.
* @param {string} options.username - The username for authentication.
* @param {string} options.password - The password for authentication.
* @param {string} [options.realm="Secure Area"] - The realm attribute for the WWW-Authenticate header.
* @param {Function} [options.hashFunction] - The hash function used for secure comparison.
* @param {Function} [options.verifyUser] - The function to verify user credentials.
* @param {string | object | MessageFunction} [options.invalidUserMessage="Unauthorized"] - The invalid user message.
* @param {Function} [options.onAuthSuccess] - Callback function called on successful authentication.
* @returns {MiddlewareHandler} The middleware handler function.
* @throws {HTTPException} If neither "username and password" nor "verifyUser" options are provided.
*
* @example
* ```ts
* const app = new Hono()
*
* app.use(
* '/auth/*',
* basicAuth({
* username: 'hono',
* password: 'ahotproject',
* })
* )
*
* app.get('/auth/page', (c) => {
* return c.text('You are authorized')
* })
* ```
*
* @example
* ```ts
* // With onAuthSuccess callback
* app.use(
* '/auth/*',
* basicAuth({
* username: 'hono',
* password: 'ahotproject',
* onAuthSuccess: (c, username) => {
* c.set('user', { name: username, role: 'admin' })
* console.log(`User ${username} authenticated`)
* },
* })
* )
* ```
*/
const basicAuth = (options, ...users) => {
const usernamePasswordInOptions = "username" in options && "password" in options;
const verifyUserInOptions = "verifyUser" in options;
if (!(usernamePasswordInOptions || verifyUserInOptions)) throw new Error("basic auth middleware requires options for \"username and password\" or \"verifyUser\"");
if (!options.realm) options.realm = "Secure Area";
if (!options.invalidUserMessage) options.invalidUserMessage = "Unauthorized";
if (usernamePasswordInOptions) users.unshift({
username: options.username,
password: options.password
});
return async function basicAuth(ctx, next) {
const requestUser = require_utils_basic_auth.auth(ctx.req.raw);
if (requestUser) {
if (verifyUserInOptions) {
if (await options.verifyUser(requestUser.username, requestUser.password, ctx)) {
if (options.onAuthSuccess) await options.onAuthSuccess(ctx, requestUser.username);
await next();
return;
}
} else for (const user of users) {
const [usernameEqual, passwordEqual] = await Promise.all([require_utils_buffer.timingSafeEqual(user.username, requestUser.username, options.hashFunction), require_utils_buffer.timingSafeEqual(user.password, requestUser.password, options.hashFunction)]);
if (usernameEqual && passwordEqual) {
if (options.onAuthSuccess) await options.onAuthSuccess(ctx, requestUser.username);
await next();
return;
}
}
}
const status = 401;
const headers = { "WWW-Authenticate": "Basic realm=\"" + options.realm?.replace(/"/g, "\\\"") + "\"" };
const responseMessage = typeof options.invalidUserMessage === "function" ? await options.invalidUserMessage(ctx) : options.invalidUserMessage;
const res = typeof responseMessage === "string" ? new Response(responseMessage, {
status,
headers
}) : new Response(JSON.stringify(responseMessage), {
status,
headers: {
...headers,
"content-type": "application/json"
}
});
throw new require_http_exception.HTTPException(status, { res });
};
};
//#endregion
exports.basicAuth = basicAuth;