143 lines
No EOL
5.5 KiB
JavaScript
143 lines
No EOL
5.5 KiB
JavaScript
import { serializeCookie } from "../../core/utils/cookie.js";
|
|
import { logger } from "../../core/utils/logger.js";
|
|
import { response as newResponse } from "../../core/utils/net.js";
|
|
function getAuthPaths(isCustomAuth) {
|
|
const paths = [];
|
|
if (isCustomAuth) {
|
|
paths.push({
|
|
method: "GET",
|
|
// only match for providers with custom auth support implemented (github, google)
|
|
route: /^\/\.auth\/login\/(?<provider>github|google|dummy)\/callback(\?.*)?$/i,
|
|
function: "auth-login-provider-callback",
|
|
});
|
|
paths.push({
|
|
method: "GET",
|
|
// only match for providers with custom auth support implemented (github, google)
|
|
route: /^\/\.auth\/login\/(?<provider>github|google|dummy)(\?.*)?$/i,
|
|
function: "auth-login-provider-custom",
|
|
});
|
|
paths.push({
|
|
method: "GET",
|
|
// For providers with custom auth support not implemented, revert to old behavior
|
|
route: /^\/\.auth\/login\/(?<provider>aad|twitter|facebook|[a-z]+)(\?.*)?$/i,
|
|
function: "auth-login-provider",
|
|
});
|
|
paths.push({
|
|
method: "POST",
|
|
route: /^\/\.auth\/complete(\?.*)?$/i,
|
|
function: "auth-complete",
|
|
});
|
|
}
|
|
else {
|
|
paths.push({
|
|
method: "GET",
|
|
route: /^\/\.auth\/login\/(?<provider>aad|github|twitter|google|facebook|[a-z]+)(\?.*)?$/i,
|
|
function: "auth-login-provider",
|
|
});
|
|
}
|
|
paths.push({
|
|
method: "GET",
|
|
route: /^\/\.auth\/me(\?.*)?$/i,
|
|
function: "auth-me",
|
|
}, {
|
|
method: "GET",
|
|
route: /^\/\.auth\/logout(\?.*)?$/i,
|
|
function: "auth-logout",
|
|
}, {
|
|
method: "GET",
|
|
route: /^\/\.auth\/purge\/(?<provider>aad|github|twitter|google|facebook|[a-z]+)(\?.*)?$/i,
|
|
// locally, all purge requests are processed as logout requests
|
|
function: "auth-logout",
|
|
});
|
|
return paths;
|
|
}
|
|
async function routeMatcher(url = "/", customAuth) {
|
|
const authPaths = getAuthPaths(!!customAuth);
|
|
for (let index = 0; index < authPaths.length; index++) {
|
|
const path = authPaths[index];
|
|
const match = url.match(new RegExp(path.route));
|
|
if (match) {
|
|
let bindingData;
|
|
if (match.groups?.provider) {
|
|
bindingData = {
|
|
provider: match.groups.provider,
|
|
};
|
|
}
|
|
const func = (await import(`./routes/${path.function}.js`)).default;
|
|
return { func, bindingData };
|
|
}
|
|
}
|
|
return { func: undefined, bindingData: undefined };
|
|
}
|
|
export async function processAuth(request, response, rewriteUrl, customAuth) {
|
|
let defaultStatus = 200;
|
|
const context = {
|
|
invocationId: new Date().getTime().toString(36) + Math.random().toString(36).slice(2),
|
|
bindingData: undefined,
|
|
res: {},
|
|
};
|
|
const { func, bindingData } = await routeMatcher(rewriteUrl || request.url, customAuth);
|
|
if (func) {
|
|
context.bindingData = bindingData;
|
|
try {
|
|
await func(context, request, customAuth);
|
|
for (const key in context.res.headers) {
|
|
const element = context.res.headers[key];
|
|
if (element) {
|
|
response.setHeader(key, element);
|
|
}
|
|
}
|
|
// set auth cookies
|
|
if (context.res.cookies) {
|
|
const serializedCookies = context.res.cookies?.map((cookie) => {
|
|
if (cookie.expires) {
|
|
cookie.expires = new Date(cookie.expires);
|
|
}
|
|
return serializeCookie(cookie.name, cookie.value, cookie);
|
|
});
|
|
response.setHeader("Set-Cookie", serializedCookies);
|
|
}
|
|
// enable CORS for all requests
|
|
response.setHeader("Access-Control-Allow-Origin", request.headers.origin || "*");
|
|
response.setHeader("Access-Control-Allow-Methods", "GET,OPTIONS");
|
|
response.setHeader("Access-Control-Allow-Credentials", "true");
|
|
// set JSON response by default (if no content type was set)
|
|
if (response.hasHeader("Content-Type") === false) {
|
|
response.setHeader("Content-Type", "application/json");
|
|
}
|
|
// if response type is JSON, serialize body response
|
|
if (response.getHeader("Content-Type")?.toString().includes("json") && typeof context.res.body === "object") {
|
|
context.res.body = JSON.stringify(context.res.body);
|
|
}
|
|
}
|
|
catch (error) {
|
|
let errorMessage = `An error occurred while processing the request!`;
|
|
if (error instanceof Error) {
|
|
errorMessage = error.message;
|
|
}
|
|
logger.error(errorMessage);
|
|
defaultStatus = 500;
|
|
context.res = newResponse({
|
|
context,
|
|
status: 500,
|
|
body: {
|
|
error: errorMessage,
|
|
},
|
|
});
|
|
}
|
|
}
|
|
else {
|
|
defaultStatus = 404;
|
|
context.res = newResponse({
|
|
context,
|
|
status: 404,
|
|
headers: { ["Content-Type"]: "text/plain" },
|
|
body: "We couldn't find that page, please check the URL and try again.",
|
|
});
|
|
}
|
|
const statusCode = context.res.status || defaultStatus;
|
|
response.writeHead(statusCode);
|
|
response.end(context.res.body);
|
|
return statusCode;
|
|
}
|
|
//# sourceMappingURL=index.js.map
|