one-link/node_modules/hono/dist/middleware/bearer-auth/index.js

70 lines
2.2 KiB
JavaScript

// src/middleware/bearer-auth/index.ts
import { HTTPException } from "../../http-exception.js";
import { timingSafeEqual } from "../../utils/buffer.js";
var TOKEN_STRINGS = "[A-Za-z0-9._~+/-]+=*";
var PREFIX = "Bearer";
var HEADER = "Authorization";
var bearerAuth = (options) => {
if (!("token" in options || "verifyToken" in options)) {
throw new Error('bearer auth middleware requires options for "token"');
}
if (!options.realm) {
options.realm = "";
}
if (!options.prefix) {
options.prefix = PREFIX;
}
const realm = options.realm?.replace(/"/g, '\\"');
return async function bearerAuth2(c, next) {
const headerToken = c.req.header(options.headerName || HEADER);
if (!headerToken) {
const res = new Response("Unauthorized", {
status: 401,
headers: {
"WWW-Authenticate": `${options.prefix} realm="` + realm + '"'
}
});
throw new HTTPException(401, { res });
} else {
const regexp = new RegExp("^" + options.prefix + " +(" + TOKEN_STRINGS + ") *$");
const match = regexp.exec(headerToken);
if (!match) {
const res = new Response("Bad Request", {
status: 400,
headers: {
"WWW-Authenticate": `${options.prefix} error="invalid_request"`
}
});
throw new HTTPException(400, { res });
} else {
let equal = false;
if ("verifyToken" in options) {
equal = await options.verifyToken(match[1], c);
} else if (typeof options.token === "string") {
equal = await timingSafeEqual(options.token, match[1], options.hashFunction);
} else if (Array.isArray(options.token) && options.token.length > 0) {
for (const token of options.token) {
if (await timingSafeEqual(token, match[1], options.hashFunction)) {
equal = true;
break;
}
}
}
if (!equal) {
const res = new Response("Unauthorized", {
status: 401,
headers: {
"WWW-Authenticate": `${options.prefix} error="invalid_token"`
}
});
throw new HTTPException(401, { res });
}
}
}
await next();
};
};
export {
bearerAuth
};