Skip to content

Commit

Permalink
chore: migrate to lucia auth (#2242)
Browse files Browse the repository at this point in the history
- Once redis/ioredis#1822 is fixed, remove
patch to ioredis
- Once Azure/azure-functions-host#162 is
fixed, remove patch to nitro that wraps console log.
- Once nitrojs/nitro#1753 is merged and released,
remove corresponding patch to nitro
- Once lucia-auth/lucia#1153 is fixed, rename
models/fields in prisma
- Once lucia-auth/lucia#1155 is merged and
released, remove custom h3 lucia middleware
- Once lucia-auth/lucia#1074 is fixed, remove
lucia types shims
- Enable CSRF protection in lucia (but then login doesn't work
anymore...)
  • Loading branch information
tobiasdiez authored Sep 24, 2023
1 parent 2b212f5 commit 59f82ed
Show file tree
Hide file tree
Showing 28 changed files with 703 additions and 784 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v3.8.1
with:
node-version: 16
node-version: 20
cache: 'yarn'

- name: Install dependencies
Expand All @@ -47,7 +47,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest]
node: [16]
node: [20]

services:
postgres:
Expand Down
25 changes: 0 additions & 25 deletions .yarn/patches/express-session-npm-1.17.3-0819dbe06c.patch

This file was deleted.

124 changes: 124 additions & 0 deletions .yarn/patches/ioredis-npm-5.3.2-58471071b1.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
diff --git a/built/index.js b/built/index.js
index 24a189578794dc3073278788fc443e6c8dc957d5..2152cb839b54377fb4fa423151839bfb5cdaed23 100644
--- a/built/index.js
+++ b/built/index.js
@@ -2,61 +2,61 @@
Object.defineProperty(exports, "__esModule", { value: true });
exports.print = exports.ReplyError = exports.SentinelIterator = exports.SentinelConnector = exports.AbstractConnector = exports.Pipeline = exports.ScanStream = exports.Command = exports.Cluster = exports.Redis = exports.default = void 0;
exports = module.exports = require("./Redis").default;
-var Redis_1 = require("./Redis");
-Object.defineProperty(exports, "default", { enumerable: true, get: function () { return Redis_1.default; } });
-var Redis_2 = require("./Redis");
-Object.defineProperty(exports, "Redis", { enumerable: true, get: function () { return Redis_2.default; } });
-var cluster_1 = require("./cluster");
-Object.defineProperty(exports, "Cluster", { enumerable: true, get: function () { return cluster_1.default; } });
-/**
- * @ignore
- */
-var Command_1 = require("./Command");
-Object.defineProperty(exports, "Command", { enumerable: true, get: function () { return Command_1.default; } });
-/**
- * @ignore
- */
-var ScanStream_1 = require("./ScanStream");
-Object.defineProperty(exports, "ScanStream", { enumerable: true, get: function () { return ScanStream_1.default; } });
-/**
- * @ignore
- */
-var Pipeline_1 = require("./Pipeline");
-Object.defineProperty(exports, "Pipeline", { enumerable: true, get: function () { return Pipeline_1.default; } });
-/**
- * @ignore
- */
-var AbstractConnector_1 = require("./connectors/AbstractConnector");
-Object.defineProperty(exports, "AbstractConnector", { enumerable: true, get: function () { return AbstractConnector_1.default; } });
-/**
- * @ignore
- */
-var SentinelConnector_1 = require("./connectors/SentinelConnector");
-Object.defineProperty(exports, "SentinelConnector", { enumerable: true, get: function () { return SentinelConnector_1.default; } });
-Object.defineProperty(exports, "SentinelIterator", { enumerable: true, get: function () { return SentinelConnector_1.SentinelIterator; } });
-// No TS typings
-exports.ReplyError = require("redis-errors").ReplyError;
-/**
- * @ignore
- */
-Object.defineProperty(exports, "Promise", {
- get() {
- console.warn("ioredis v5 does not support plugging third-party Promise library anymore. Native Promise will be used.");
- return Promise;
- },
- set(_lib) {
- console.warn("ioredis v5 does not support plugging third-party Promise library anymore. Native Promise will be used.");
- },
-});
-/**
- * @ignore
- */
-function print(err, reply) {
- if (err) {
- console.log("Error: " + err);
- }
- else {
- console.log("Reply: " + reply);
- }
-}
-exports.print = print;
+// var Redis_1 = require("./Redis");
+// Object.defineProperty(exports, "default", { enumerable: true, get: function () { return Redis_1.default; } });
+// var Redis_2 = require("./Redis");
+// Object.defineProperty(exports, "Redis", { enumerable: true, get: function () { return Redis_2.default; } });
+// var cluster_1 = require("./cluster");
+// Object.defineProperty(exports, "Cluster", { enumerable: true, get: function () { return cluster_1.default; } });
+// /**
+// * @ignore
+// */
+// var Command_1 = require("./Command");
+// Object.defineProperty(exports, "Command", { enumerable: true, get: function () { return Command_1.default; } });
+// /**
+// * @ignore
+// */
+// var ScanStream_1 = require("./ScanStream");
+// Object.defineProperty(exports, "ScanStream", { enumerable: true, get: function () { return ScanStream_1.default; } });
+// /**
+// * @ignore
+// */
+// var Pipeline_1 = require("./Pipeline");
+// Object.defineProperty(exports, "Pipeline", { enumerable: true, get: function () { return Pipeline_1.default; } });
+// /**
+// * @ignore
+// */
+// var AbstractConnector_1 = require("./connectors/AbstractConnector");
+// Object.defineProperty(exports, "AbstractConnector", { enumerable: true, get: function () { return AbstractConnector_1.default; } });
+// /**
+// * @ignore
+// */
+// var SentinelConnector_1 = require("./connectors/SentinelConnector");
+// Object.defineProperty(exports, "SentinelConnector", { enumerable: true, get: function () { return SentinelConnector_1.default; } });
+// Object.defineProperty(exports, "SentinelIterator", { enumerable: true, get: function () { return SentinelConnector_1.SentinelIterator; } });
+// // No TS typings
+// exports.ReplyError = require("redis-errors").ReplyError;
+// /**
+// * @ignore
+// */
+// Object.defineProperty(exports, "Promise", {
+// get() {
+// console.warn("ioredis v5 does not support plugging third-party Promise library anymore. Native Promise will be used.");
+// return Promise;
+// },
+// set(_lib) {
+// console.warn("ioredis v5 does not support plugging third-party Promise library anymore. Native Promise will be used.");
+// },
+// });
+// /**
+// * @ignore
+// */
+// function print(err, reply) {
+// if (err) {
+// console.log("Error: " + err);
+// }
+// else {
+// console.log("Reply: " + reply);
+// }
+// }
+// exports.print = print;
114 changes: 114 additions & 0 deletions .yarn/patches/nitropack-npm-2.6.3-72f7352600.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
diff --git a/dist/runtime/entries/azure.mjs b/dist/runtime/entries/azure.mjs
index 2ed72eb8e5f5f6b740d909bb12f62cf761599569..ac3dad70537e585d63c713048c545238a83d0d5f 100644
--- a/dist/runtime/entries/azure.mjs
+++ b/dist/runtime/entries/azure.mjs
@@ -3,6 +3,8 @@ import { parseURL } from "ufo";
import { nitroApp } from "../app.mjs";
import { getAzureParsedCookiesFromHeaders } from "../utils.azure.mjs";
import { normalizeLambdaOutgoingHeaders } from "../utils.lambda.mjs";
+import { createConsola } from "consola";
+
export async function handle(context, req) {
let url;
if (req.headers["x-ms-original-url"]) {
@@ -11,6 +13,25 @@ export async function handle(context, req) {
} else {
url = "/api/" + (req.params.url || "");
}
+ const _getLogFn = (level) => {
+ if (level < 1) {
+ return context.log.error;
+ }
+ if (level === 1) {
+ return context.log.warn;
+ }
+ return context.log;
+ }
+ const consola = createConsola({
+ reporters: [
+ {
+ log: (logObj) => {
+ _getLogFn(logObj.level)(logObj.args);
+ },
+ },
+ ],
+ });
+ consola.wrapConsole();
const { body, status, statusText, headers } = await nitroApp.localCall({
url,
headers: req.headers,
@@ -18,6 +39,7 @@ export async function handle(context, req) {
// https://github.com/Azure/azure-functions-host/issues/293
body: req.rawBody
});
+ consola.restoreConsole();
context.res = {
status,
// cookies https://learn.microsoft.com/en-us/azure/azure-functions/functions-reference-node?tabs=typescript%2Cwindows%2Cazure-cli&pivots=nodejs-model-v4#http-response
diff --git a/dist/runtime/utils.azure.mjs b/dist/runtime/utils.azure.mjs
index d0e27bd1b36683f7834ed097c07702429da3c152..0dd0309f7c73ccb709c7bee85360267f7198a4da 100644
--- a/dist/runtime/utils.azure.mjs
+++ b/dist/runtime/utils.azure.mjs
@@ -1,13 +1,56 @@
import { parse } from "cookie-es";
import { splitCookiesString } from "h3";
-import { joinHeaders } from "./utils.mjs";
export function getAzureParsedCookiesFromHeaders(headers) {
- const c = String(headers["set-cookie"]);
- if (!c || c.length === 0) {
+ const raw = headers["set-cookie"];
+ if (!raw || typeof raw === "number" || raw.length === 0) {
return [];
}
- const cookies = splitCookiesString(joinHeaders(c)).map(
- (cookie) => parse(cookie)
- );
+ const rawCookies = Array.isArray(raw) ? raw : splitCookiesString(String(raw));
+ const cookies = rawCookies.flatMap((cookie) => {
+ const entries = Object.entries(parse(cookie));
+ if (entries.length > 0) {
+ const [entry, ...rest] = entries;
+ const options = Object.fromEntries(
+ rest.map(([k, v]) => [k.toLowerCase(), v])
+ );
+ const res = {
+ name: entry[0],
+ value: entry[1],
+ domain: options.domain,
+ path: options.path,
+ expires: parseNumberOrDate(options.expires),
+ // secure: options.secure,
+ // httponly: options.httponly,
+ samesite: options.samesite,
+ maxAge: parseNumber(options.maxAge)
+ };
+ for (const key in res) {
+ if (res[key] === void 0) {
+ delete res[key];
+ }
+ }
+ return [res];
+ }
+ return [];
+ });
return cookies;
}
+function parseNumberOrDate(expires) {
+ const expiresAsNumber = parseNumber(expires);
+ if (expiresAsNumber !== void 0) {
+ return expiresAsNumber;
+ }
+ const expiresAsDate = new Date(expires);
+ if (!Number.isNaN(expiresAsDate.getTime())) {
+ return expiresAsDate;
+ }
+}
+function parseNumber(maxAge) {
+ if (!maxAge) {
+ return void 0;
+ }
+ const maxAgeAsNumber = Number(maxAge);
+ if (!Number.isNaN(maxAgeAsNumber)) {
+ return maxAgeAsNumber;
+ }
+}
15 changes: 0 additions & 15 deletions .yarn/patches/redis-mock-npm-0.56.3-967bd7c6ea.patch

This file was deleted.

18 changes: 6 additions & 12 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@
"@as-integrations/h3": "^1.1.6",
"@graphql-tools/schema": "^10.0.0",
"@he-tree/vue": "^2.5.1",
"@lucia-auth/adapter-prisma": "^3.0.1",
"@lucia-auth/adapter-session-unstorage": "^2.1.0",
"@nozomuikuta/h3-cors": "^0.2.2",
"@pinia/nuxt": "^0.4.11",
"@popperjs/core": "^2.11.8",
Expand All @@ -60,23 +62,20 @@
"@yaireo/tagify": "^4.17.9",
"autoprefixer": "^10.4.15",
"body-scroll-lock": "^4.0.0-beta.0",
"connect-redis": "^7.1.0",
"cross-fetch": "^4.0.0",
"express-session": "^1.17.3",
"graphql": "^16.8.0",
"graphql-passport": "^0.6.7",
"graphql-scalars": "^1.22.2",
"json-bigint-patch": "^0.0.8",
"lodash": "^4.17.21",
"lucia": "^2.6.0",
"nodemailer": "^6.8.0",
"passport": "^0.6.0",
"pinia": "^2.1.6",
"redis": "^4.6.8",
"reflect-metadata": "^0.1.13",
"ts-loader": "^9.4.4",
"ts-node": "^10.9.1",
"tsyringe": "^4.8.0",
"typescript": "^5.2.2",
"unstorage": "^1.9.0",
"vee-validate": "^4.11.6",
"zod": "^3.22.2"
},
Expand Down Expand Up @@ -104,12 +103,8 @@
"@tailwindcss/line-clamp": "^0.4.4",
"@tailwindcss/typography": "^0.5.10",
"@types/bcryptjs": "^2.4.3",
"@types/connect-redis": "^0.0.21",
"@types/express-session": "^1.17.7",
"@types/lodash": "^4.14.198",
"@types/nodemailer": "^6.4.7",
"@types/passport": "^1.0.12",
"@types/redis-mock": "^0.17.1",
"@types/supertest": "^2.0.12",
"@types/uuid": "^9.0.4",
"@types/yaireo__tagify": "^4.17.2",
Expand Down Expand Up @@ -144,7 +139,6 @@
"prettier": "^3.0.3",
"prettier-plugin-organize-imports": "^3.2.3",
"prisma": "^5.3.1",
"redis-mock": "^0.56.3",
"storybook": "7.0.26",
"storybook-vue-addon": "^0.4.0",
"supertest": "^6.3.3",
Expand All @@ -158,10 +152,10 @@
},
"resolutions": {
"@types/react": "https://registry.yarnpkg.com/@favware/skip-dependency/-/skip-dependency-1.2.0.tgz",
"express-session": "patch:express-session@npm%3A1.17.3#./.yarn/patches/express-session-npm-1.17.3-0819dbe06c.patch",
"mount-vue-component": "patch:mount-vue-component@npm%3A0.10.2#./.yarn/patches/mount-vue-component-npm-0.10.2-4968f76fd9.patch",
"@vue/apollo-util": "patch:@vue/apollo-util@npm%3A4.0.0-beta.6#./.yarn/patches/@vue-apollo-util-npm-4.0.0-beta.6-7e26e14eb7.patch",
"redis-mock@^0.56.3": "patch:redis-mock@npm%3A0.56.3#./.yarn/patches/redis-mock-npm-0.56.3-967bd7c6ea.patch"
"ioredis@^5.3.2": "patch:ioredis@npm%3A5.3.2#./.yarn/patches/ioredis-npm-5.3.2-58471071b1.patch",
"nitropack@^2.6.3": "patch:nitropack@npm%3A2.6.3#./.yarn/patches/nitropack-npm-2.6.3-72f7352600.patch"
},
"resolutionsComments": {
"@types/react": "Otherwise these types interfere with the types from vite: https://github.com/johnsoncodehk/volar/discussions/592#discussioncomment-1580518"
Expand Down
2 changes: 1 addition & 1 deletion server/api.e2e.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ describe('request without query', () => {
.get('/api')
.set('Apollo-Require-Preflight', 'True')

expect(response.statusCode).toBe(400)
expect(response.text).toContain(

Check failure on line 37 in server/api.e2e.test.ts

View workflow job for this annotation

GitHub Actions / Build & Deploy to Test

AssertionError: expected '' to include 'GraphQL operations must contain a non…'

at JabRefOnline/server/api.e2e.test.ts:37:27
'GraphQL operations must contain a non-empty `query`',
)
expect(response.statusCode).toBe(400)
})
})

Expand Down
3 changes: 3 additions & 0 deletions server/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import 'json-bigint-patch' // Needed for bigint support in JSON
import 'reflect-metadata' // Needed for tsyringe
import { buildContext, Context } from '../context'
import { loadSchemaWithResolvers } from '../schema'
import { configure as configureTsyringe } from './../tsyringe.config'

// Workaround for issue with Azure deploy: https://github.com/unjs/nitro/issues/351
// Original code taken from https://github.com/nodejs/node/blob/main/lib/_http_outgoing.js
Expand Down Expand Up @@ -84,6 +85,8 @@ http.IncomingMessage.Readable.prototype.unpipe = function (dest) {
}

export default defineLazyEventHandler(async () => {
configureTsyringe()

const server = new ApolloServer<Context>({
schema: await loadSchemaWithResolvers(),
introspection: true,
Expand Down
Loading

0 comments on commit 59f82ed

Please sign in to comment.