@builder.io/qwik-auth
Version:
Qwik Auth is powered by Auth.js, a battle tested library for authentication with 3rd party providers
345 lines (344 loc) • 11.5 kB
JavaScript
;
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const qwikCity = require("@builder.io/qwik-city");
const qwik = require("@builder.io/qwik");
const core = require("@auth/core");
const build = require("@builder.io/qwik/build");
var setCookie = { exports: {} };
var defaultParseOptions = {
decodeValues: true,
map: false,
silent: false
};
function isNonEmptyString(str) {
return typeof str === "string" && !!str.trim();
}
function parseString(setCookieValue, options) {
var parts = setCookieValue.split(";").filter(isNonEmptyString);
var nameValuePairStr = parts.shift();
var parsed = parseNameValuePair(nameValuePairStr);
var name = parsed.name;
var value = parsed.value;
options = options ? Object.assign({}, defaultParseOptions, options) : defaultParseOptions;
try {
value = options.decodeValues ? decodeURIComponent(value) : value;
} catch (e) {
console.error(
"set-cookie-parser encountered an error while decoding a cookie with value '" + value + "'. Set options.decodeValues to false to disable this feature.",
e
);
}
var cookie = {
name,
value
};
parts.forEach(function(part) {
var sides = part.split("=");
var key = sides.shift().trimLeft().toLowerCase();
var value2 = sides.join("=");
if (key === "expires") {
cookie.expires = new Date(value2);
} else if (key === "max-age") {
cookie.maxAge = parseInt(value2, 10);
} else if (key === "secure") {
cookie.secure = true;
} else if (key === "httponly") {
cookie.httpOnly = true;
} else if (key === "samesite") {
cookie.sameSite = value2;
} else {
cookie[key] = value2;
}
});
return cookie;
}
function parseNameValuePair(nameValuePairStr) {
var name = "";
var value = "";
var nameValueArr = nameValuePairStr.split("=");
if (nameValueArr.length > 1) {
name = nameValueArr.shift();
value = nameValueArr.join("=");
} else {
value = nameValuePairStr;
}
return { name, value };
}
function parse(input, options) {
options = options ? Object.assign({}, defaultParseOptions, options) : defaultParseOptions;
if (!input) {
if (!options.map) {
return [];
} else {
return {};
}
}
if (input.headers) {
if (typeof input.headers.getSetCookie === "function") {
input = input.headers.getSetCookie();
} else if (input.headers["set-cookie"]) {
input = input.headers["set-cookie"];
} else {
var sch = input.headers[Object.keys(input.headers).find(function(key) {
return key.toLowerCase() === "set-cookie";
})];
if (!sch && input.headers.cookie && !options.silent) {
console.warn(
"Warning: set-cookie-parser appears to have been called on a request object. It is designed to parse Set-Cookie headers from responses, not Cookie headers from requests. Set the option {silent: true} to suppress this warning."
);
}
input = sch;
}
}
if (!Array.isArray(input)) {
input = [input];
}
options = options ? Object.assign({}, defaultParseOptions, options) : defaultParseOptions;
if (!options.map) {
return input.filter(isNonEmptyString).map(function(str) {
return parseString(str, options);
});
} else {
var cookies = {};
return input.filter(isNonEmptyString).reduce(function(cookies2, str) {
var cookie = parseString(str, options);
cookies2[cookie.name] = cookie;
return cookies2;
}, cookies);
}
}
function splitCookiesString(cookiesString) {
if (Array.isArray(cookiesString)) {
return cookiesString;
}
if (typeof cookiesString !== "string") {
return [];
}
var cookiesStrings = [];
var pos = 0;
var start;
var ch;
var lastComma;
var nextStart;
var cookiesSeparatorFound;
function skipWhitespace() {
while (pos < cookiesString.length && /\s/.test(cookiesString.charAt(pos))) {
pos += 1;
}
return pos < cookiesString.length;
}
function notSpecialChar() {
ch = cookiesString.charAt(pos);
return ch !== "=" && ch !== ";" && ch !== ",";
}
while (pos < cookiesString.length) {
start = pos;
cookiesSeparatorFound = false;
while (skipWhitespace()) {
ch = cookiesString.charAt(pos);
if (ch === ",") {
lastComma = pos;
pos += 1;
skipWhitespace();
nextStart = pos;
while (pos < cookiesString.length && notSpecialChar()) {
pos += 1;
}
if (pos < cookiesString.length && cookiesString.charAt(pos) === "=") {
cookiesSeparatorFound = true;
pos = nextStart;
cookiesStrings.push(cookiesString.substring(start, lastComma));
start = pos;
} else {
pos = lastComma + 1;
}
} else {
pos += 1;
}
}
if (!cookiesSeparatorFound || pos >= cookiesString.length) {
cookiesStrings.push(cookiesString.substring(start, cookiesString.length));
}
}
return cookiesStrings;
}
setCookie.exports = parse;
setCookie.exports.parse = parse;
var parseString_1 = setCookie.exports.parseString = parseString;
var splitCookiesString_1 = setCookie.exports.splitCookiesString = splitCookiesString;
const actions = [
"providers",
"session",
"csrf",
"signin",
"signout",
"callback",
"verify-request",
"error"
];
function serverAuthQrl(authOptions) {
const useAuthSignin = qwikCity.globalActionQrl(/* @__PURE__ */ qwik.inlinedQrl(async ({ providerId, callbackUrl: deprecated, options, authorizationParams }, req) => {
const [authOptions2] = qwik.useLexicalScope();
if (deprecated)
console.warn("\x1B[33mWARNING: callbackUrl is deprecated - use options.callbackUrl instead\x1B[0m");
const { callbackUrl = deprecated ?? defaultCallbackURL(req), ...rest } = options ?? {};
const isCredentials = providerId === "credentials";
const auth = await patchAuthOptions(authOptions2, req);
const body = new URLSearchParams({
callbackUrl
});
Object.entries(rest).forEach(([key, value]) => {
body.set(key, String(value));
});
const baseSignInUrl = `/api/auth/${isCredentials ? "callback" : "signin"}${providerId ? `/${providerId}` : ""}`;
const signInUrl = `${baseSignInUrl}?${new URLSearchParams(authorizationParams)}`;
const data = await authAction(body, req, signInUrl, auth);
req.cookie.set("authjs.callback-url", callbackUrl, {
path: "/"
});
if (data.url)
throw req.redirect(301, data.url);
}, "serverAuthQrl_useAuthSignin_globalAction_0BV7Pjvi9oE", [
authOptions
]), qwikCity.zodQrl(/* @__PURE__ */ qwik.inlinedQrl({
providerId: qwikCity.z.string().optional(),
callbackUrl: qwikCity.z.string().optional(),
options: qwikCity.z.object({
callbackUrl: qwikCity.z.string()
}).passthrough().partial().optional(),
authorizationParams: qwikCity.z.union([
qwikCity.z.string(),
qwikCity.z.custom(),
qwikCity.z.record(qwikCity.z.string())
]).optional()
}, "serverAuthQrl_useAuthSignin_globalAction_zod_Ng7oD9cW2Ss")));
const useAuthSignout = qwikCity.globalActionQrl(/* @__PURE__ */ qwik.inlinedQrl(async ({ callbackUrl }, req) => {
const [authOptions2] = qwik.useLexicalScope();
callbackUrl ?? (callbackUrl = defaultCallbackURL(req));
const auth = await patchAuthOptions(authOptions2, req);
const body = new URLSearchParams({
callbackUrl
});
await authAction(body, req, `/api/auth/signout`, auth);
}, "serverAuthQrl_useAuthSignout_globalAction_DcikjRBIaDE", [
authOptions
]), qwikCity.zodQrl(/* @__PURE__ */ qwik.inlinedQrl({
callbackUrl: qwikCity.z.string().optional()
}, "serverAuthQrl_useAuthSignout_globalAction_zod_0HkNvbn18P4")));
const useAuthSession = qwikCity.routeLoaderQrl(/* @__PURE__ */ qwik.inlinedQrl((req) => {
return req.sharedMap.get("session");
}, "serverAuthQrl_useAuthSession_routeLoader_g8XUlGCLMBQ"));
const onRequest = async (req) => {
if (build.isServer) {
const prefix = "/api/auth";
const action = req.url.pathname.slice(prefix.length + 1).split("/")[0];
const auth = await patchAuthOptions(authOptions, req);
if (actions.includes(action) && req.url.pathname.startsWith(prefix + "/")) {
const res = await core.Auth(req.request, auth);
const cookie = res.headers.get("set-cookie");
if (cookie) {
req.headers.set("set-cookie", cookie);
res.headers.delete("set-cookie");
fixCookies(req);
}
throw req.send(res);
} else {
const { data, cookie } = await getSessionData(req.request, auth);
req.sharedMap.set("session", data);
if (cookie) {
req.headers.set("set-cookie", cookie);
fixCookies(req);
}
}
}
};
return {
useAuthSignin,
useAuthSignout,
useAuthSession,
onRequest
};
}
const serverAuth$ = /* @__PURE__ */ qwik.implicit$FirstArg(serverAuthQrl);
async function authAction(body, req, path, authOptions) {
const request = new Request(new URL(path, req.request.url), {
method: req.request.method,
headers: req.request.headers,
body
});
request.headers.set("content-type", "application/x-www-form-urlencoded");
const res = await core.Auth(request, {
...authOptions,
skipCSRFCheck: core.skipCSRFCheck
});
const cookies = [];
res.headers.forEach((value, key) => {
if (key === "set-cookie")
cookies.push(value);
else if (!req.headers.has(key))
req.headers.set(key, value);
});
if (cookies.length > 0)
req.headers.set("set-cookie", cookies.join(", "));
fixCookies(req);
try {
return await res.json();
} catch (error) {
return await res.text();
}
}
const fixCookies = (req) => {
req.headers.set("set-cookie", req.headers.get("set-cookie") || "");
const cookie = req.headers.get("set-cookie");
if (cookie) {
req.headers.delete("set-cookie");
splitCookiesString_1(cookie).forEach((cookie2) => {
const { name, value, ...rest } = parseString_1(cookie2);
req.cookie.set(name, value, rest);
});
}
};
const ensureAuthMiddleware = (req) => {
const isLoggedIn = req.sharedMap.has("session");
if (!isLoggedIn)
throw req.error(403, "sfs");
};
const defaultCallbackURL = (req) => {
req.url.searchParams.delete("qaction");
return req.url.href;
};
async function getSessionData(req, options) {
options.secret ?? (options.secret = process.env.AUTH_SECRET);
options.trustHost ?? (options.trustHost = true);
const url = new URL("/api/auth/session", req.url);
const response = await core.Auth(new Request(url, {
headers: req.headers
}), options);
const { status = 200 } = response;
const data = await response.json();
const cookie = response.headers.get("set-cookie");
if (!data || !Object.keys(data).length)
return {
data: null,
cookie
};
if (status === 200)
return {
data,
cookie
};
throw new Error(data.message);
}
const patchAuthOptions = async (authOptions, req) => {
const options = await authOptions(req);
return {
...options,
basePath: "/api/auth"
};
};
exports._auto_authAction = authAction;
exports._auto_defaultCallbackURL = defaultCallbackURL;
exports._auto_patchAuthOptions = patchAuthOptions;
exports.ensureAuthMiddleware = ensureAuthMiddleware;
exports.serverAuth$ = serverAuth$;
exports.serverAuthQrl = serverAuthQrl;