From 1fa44b8a26ef01496679bd5edcbed1c8e953febf Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Thu, 18 Jun 2026 19:21:48 +0000 Subject: [PATCH 1/2] Upgrade Next.js to 16.2.9 Fix TypeScript errors in test files caused by stricter Mongoose lean() return types and better-auth session type changes in Next 16.2. Co-Authored-By: Claude Sonnet 4.6 --- .../media/presigned/__tests__/route.test.ts | 2 +- .../app/api/payment/__tests__/helpers.test.ts | 2 +- .../payment/initiate/__tests__/route.test.ts | 4 +- .../graphql/courses/__tests__/logic.test.ts | 4 +- .../courses/__tests__/move-lesson.test.ts | 4 +- .../courses/__tests__/reorder-groups.test.ts | 2 +- .../lessons/__tests__/visibility.test.ts | 4 +- .../web/graphql/users/__tests__/logic.test.ts | 12 +- apps/web/package.json | 4 +- pnpm-lock.yaml | 190 +++++++++++++----- 10 files changed, 162 insertions(+), 66 deletions(-) diff --git a/apps/web/app/api/media/presigned/__tests__/route.test.ts b/apps/web/app/api/media/presigned/__tests__/route.test.ts index 35e8abc23..dcc8a85dc 100644 --- a/apps/web/app/api/media/presigned/__tests__/route.test.ts +++ b/apps/web/app/api/media/presigned/__tests__/route.test.ts @@ -82,7 +82,7 @@ describe("POST /api/media/presigned", () => { }); it("continues to generate a media signature with a dashboard session", async () => { - (auth.api.getSession as jest.Mock).mockResolvedValue({ + (auth.api.getSession as unknown as jest.Mock).mockResolvedValue({ user: { email: "admin@example.com" }, }); (User.findOne as jest.Mock).mockResolvedValue({ diff --git a/apps/web/app/api/payment/__tests__/helpers.test.ts b/apps/web/app/api/payment/__tests__/helpers.test.ts index a02fc7d58..af741bf3a 100644 --- a/apps/web/app/api/payment/__tests__/helpers.test.ts +++ b/apps/web/app/api/payment/__tests__/helpers.test.ts @@ -56,7 +56,7 @@ describe("payment helpers", () => { ); expect(membership.status).toBe(Constants.MembershipStatus.ACTIVE); - expect(membership.role).toBe(Constants.MembershipRole.POST); + expect((membership as any).role).toBe(Constants.MembershipRole.POST); expect(membership.save).toHaveBeenCalled(); expect(addIncludedProductsMemberships).toHaveBeenCalledWith({ domain: domain._id, diff --git a/apps/web/app/api/payment/initiate/__tests__/route.test.ts b/apps/web/app/api/payment/initiate/__tests__/route.test.ts index 8a9f35a6b..337fd5cb1 100644 --- a/apps/web/app/api/payment/initiate/__tests__/route.test.ts +++ b/apps/web/app/api/payment/initiate/__tests__/route.test.ts @@ -74,7 +74,7 @@ describe("Payment Initiate Route", () => { }, } as unknown as NextRequest; - (auth.api.getSession as jest.Mock).mockResolvedValue({ + (auth.api.getSession as unknown as jest.Mock).mockResolvedValue({ user: { email: "test@test.com", }, @@ -125,7 +125,7 @@ describe("Payment Initiate Route", () => { }); it("returns 401 if user is not authenticated", async () => { - (auth.api.getSession as jest.Mock).mockResolvedValue(null); + (auth.api.getSession as unknown as jest.Mock).mockResolvedValue(null); const response = await POST(mockRequest); expect(response.status).toBe(401); diff --git a/apps/web/graphql/courses/__tests__/logic.test.ts b/apps/web/graphql/courses/__tests__/logic.test.ts index 2a5f639d4..0d657bd38 100644 --- a/apps/web/graphql/courses/__tests__/logic.test.ts +++ b/apps/web/graphql/courses/__tests__/logic.test.ts @@ -154,7 +154,7 @@ describe("updateCourse", () => { await updateCourse( { description: JSON.stringify(updatedDescription), - id: course.courseId, + id: course.courseId as any, }, { subdomain: testDomain, @@ -209,7 +209,7 @@ describe("updateCourse", () => { const updatedCourse = await updateCourse( { description: JSON.stringify(descriptionWithTempMedia), - id: course.courseId, + id: course.courseId as any, }, { subdomain: testDomain, diff --git a/apps/web/graphql/courses/__tests__/move-lesson.test.ts b/apps/web/graphql/courses/__tests__/move-lesson.test.ts index 832ad9056..b95c342da 100644 --- a/apps/web/graphql/courses/__tests__/move-lesson.test.ts +++ b/apps/web/graphql/courses/__tests__/move-lesson.test.ts @@ -228,10 +228,10 @@ describe("moveLesson", () => { expect(updatedCourse?.groups?.[0]?.lessonsOrder).toEqual([lesson1]); expect(updatedCourse?.groups?.[1]?.lessonsOrder).toEqual([lesson2]); - const updatedLesson = await LessonModel.findOne({ + const updatedLesson = (await LessonModel.findOne({ domain: testDomain._id, lessonId: lesson2, - }).lean(); + }).lean()) as any; expect(updatedLesson?.groupId).toBe(groupId2); }); diff --git a/apps/web/graphql/courses/__tests__/reorder-groups.test.ts b/apps/web/graphql/courses/__tests__/reorder-groups.test.ts index d109b4635..53b55fab5 100644 --- a/apps/web/graphql/courses/__tests__/reorder-groups.test.ts +++ b/apps/web/graphql/courses/__tests__/reorder-groups.test.ts @@ -386,7 +386,7 @@ describe("reorderGroups", () => { await expect( reorderGroups({ courseId: ownerNoPermissionCourse.courseId, - groupIds: ownerNoPermissionCourse.groups.map((group: any) => + groupIds: ownerNoPermissionCourse.groups!.map((group: any) => group.id.toString(), ), ctx: { diff --git a/apps/web/graphql/lessons/__tests__/visibility.test.ts b/apps/web/graphql/lessons/__tests__/visibility.test.ts index 379fe957d..e0e67cce3 100644 --- a/apps/web/graphql/lessons/__tests__/visibility.test.ts +++ b/apps/web/graphql/lessons/__tests__/visibility.test.ts @@ -419,10 +419,10 @@ describe("Lesson visibility and progress", () => { expect(lesson.media?.mediaId).toBe(tempMediaId); expect(lesson.media?.file).toBeUndefined(); - const savedLesson = await LessonModel.findOne({ + const savedLesson = (await LessonModel.findOne({ lessonId: lesson.lessonId, domain: testDomain._id, - }).lean(); + }).lean()) as any; expect(savedLesson?.media?.mediaId).toBe(tempMediaId); expect(savedLesson?.media?.file).toBeUndefined(); }); diff --git a/apps/web/graphql/users/__tests__/logic.test.ts b/apps/web/graphql/users/__tests__/logic.test.ts index 8d325e180..dcc85da34 100644 --- a/apps/web/graphql/users/__tests__/logic.test.ts +++ b/apps/web/graphql/users/__tests__/logic.test.ts @@ -82,10 +82,10 @@ describe("updateUser", () => { ), ).rejects.toThrow(responses.action_not_allowed); - const owner = await UserModel.findOne({ + const owner = (await UserModel.findOne({ userId: "owner", domain: domainId, - }).lean(); + }).lean()) as any; expect(owner?.permissions).toEqual([ UIConstants.permissions.manageUsers, ]); @@ -109,10 +109,10 @@ describe("updateUser", () => { ctx, ); - const owner = await UserModel.findOne({ + const owner = (await UserModel.findOne({ userId: "owner", domain: domainId, - }).lean(); + }).lean()) as any; expect(owner?.name).toBe("Updated Owner"); expect(owner?.permissions).toEqual([ UIConstants.permissions.manageUsers, @@ -138,10 +138,10 @@ describe("updateUser", () => { ), ).rejects.toThrow(responses.action_not_allowed); - const owner = await UserModel.findOne({ + const owner = (await UserModel.findOne({ userId: "owner", domain: domainId, - }).lean(); + }).lean()) as any; expect(owner?.active).toBe(true); }); }); diff --git a/apps/web/package.json b/apps/web/package.json index 1f014d04f..e0c362141 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -85,7 +85,7 @@ "medialit": "0.2.0", "mongodb": "^6.21.0", "mongoose": "^8.22.1", - "next": "^16.0.10", + "next": "^16.2.9", "next-themes": "^0.4.6", "nodemailer": "^6.7.2", "pug": "^3.0.2", @@ -120,7 +120,7 @@ "@types/react": "19.2.4", "@types/xml2js": "^0.4.14", "eslint": "^9.12.0", - "eslint-config-next": "16.0.3", + "eslint-config-next": "^16.2.9", "eslint-config-prettier": "^9.0.0", "identity-obj-proxy": "^3.0.0", "mongodb-memory-server": "^10.1.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8dd3fbf14..398b5d08e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -296,7 +296,7 @@ importers: dependencies: '@better-auth/sso': specifier: ^1.5.6 - version: 1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(better-auth@1.5.6(@opentelemetry/api@1.9.0)(mongodb@6.21.0(@aws-sdk/credential-providers@3.797.0)(socks@2.8.4))(next@16.1.6(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(better-call@1.3.2(zod@3.24.3)) + version: 1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(better-auth@1.5.6(@opentelemetry/api@1.9.0)(mongodb@6.21.0(@aws-sdk/credential-providers@3.797.0)(socks@2.8.4))(next@16.2.9(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(better-call@1.3.2(zod@3.24.3)) '@courselit/common-logic': specifier: workspace:^ version: link:../../packages/common-logic @@ -428,7 +428,7 @@ importers: version: 1.0.0 better-auth: specifier: ^1.5.6 - version: 1.5.6(@opentelemetry/api@1.9.0)(mongodb@6.21.0(@aws-sdk/credential-providers@3.797.0)(socks@2.8.4))(next@16.1.6(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + version: 1.5.6(@opentelemetry/api@1.9.0)(mongodb@6.21.0(@aws-sdk/credential-providers@3.797.0)(socks@2.8.4))(next@16.2.9(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) chart.js: specifier: ^4.4.7 version: 4.4.9 @@ -472,8 +472,8 @@ importers: specifier: ^8.22.1 version: 8.23.1(@aws-sdk/credential-providers@3.797.0)(socks@2.8.4) next: - specifier: ^16.0.10 - version: 16.1.6(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + specifier: ^16.2.9 + version: 16.2.9(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) next-themes: specifier: ^0.4.6 version: 0.4.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0) @@ -572,8 +572,8 @@ importers: specifier: ^9.12.0 version: 9.39.1(jiti@2.6.1) eslint-config-next: - specifier: 16.0.3 - version: 16.0.3(@typescript-eslint/parser@8.46.4(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) + specifier: ^16.2.9 + version: 16.2.9(@typescript-eslint/parser@8.46.4(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) eslint-config-prettier: specifier: ^9.0.0 version: 9.1.0(eslint@9.39.1(jiti@2.6.1)) @@ -3047,8 +3047,11 @@ packages: '@next/env@16.1.6': resolution: {integrity: sha512-N1ySLuZjnAtN3kFnwhAwPvZah8RJxKasD7x1f8shFqhncnWZn4JMfg37diLNuoHsLAlrDfM3g4mawVdtAG8XLQ==} - '@next/eslint-plugin-next@16.0.3': - resolution: {integrity: sha512-6sPWmZetzFWMsz7Dhuxsdmbu3fK+/AxKRtj7OB0/3OZAI2MHB/v2FeYh271LZ9abvnM1WIwWc/5umYjx0jo5sQ==} + '@next/env@16.2.9': + resolution: {integrity: sha512-ki5VxxXfzD/9TDe13wyeTKIjQTAwBVpnr8KhRDUr8ltMUq1/NBpWNT5tiPoxiGl+PHM4X2ahSOiPk6iAimIzPg==} + + '@next/eslint-plugin-next@16.2.9': + resolution: {integrity: sha512-UZi8+YT/MLgTC9nrrn2Xd4lBYv1B7lVmtWHfPcthAI5Tt/C1LuDe6DfmtCtJ+WQod3ksY4VrKSvk3oMVAnL7qw==} '@next/swc-darwin-arm64@16.1.6': resolution: {integrity: sha512-wTzYulosJr/6nFnqGW7FrG3jfUUlEf8UjGA0/pyypJl42ExdVgC6xJgcXQ+V8QFn6niSG2Pb8+MIG1mZr2vczw==} @@ -3056,48 +3059,96 @@ packages: cpu: [arm64] os: [darwin] + '@next/swc-darwin-arm64@16.2.9': + resolution: {integrity: sha512-HkfxNYUCmcct0Xsqib5KxqMSHV4AHJq857BNRchyBDs4YS19aHzVfn1kDuBYKqLLQBjXgnkIsjV2Kd4d2wzYhw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + '@next/swc-darwin-x64@16.1.6': resolution: {integrity: sha512-BLFPYPDO+MNJsiDWbeVzqvYd4NyuRrEYVB5k2N3JfWncuHAy2IVwMAOlVQDFjj+krkWzhY2apvmekMkfQR0CUQ==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] + '@next/swc-darwin-x64@16.2.9': + resolution: {integrity: sha512-7IAtK4MeybpqRV9GRABWEhJ62mOS+rzWOzOTFie4cSEtm12xsoOMJRcECoZx3FHPzFAqN/IJtHqWAFOLfl152w==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + '@next/swc-linux-arm64-gnu@16.1.6': resolution: {integrity: sha512-OJYkCd5pj/QloBvoEcJ2XiMnlJkRv9idWA/j0ugSuA34gMT6f5b7vOiCQHVRpvStoZUknhl6/UxOXL4OwtdaBw==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] + '@next/swc-linux-arm64-gnu@16.2.9': + resolution: {integrity: sha512-hBD75iWpUtkL9SmQmcRhmLomn9jgkPzCEkbOcLgHymPEKzv+6ONy13RRiIEz/iEObjkS2Jlb5gYS2XGoS3X4rw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + '@next/swc-linux-arm64-musl@16.1.6': resolution: {integrity: sha512-S4J2v+8tT3NIO9u2q+S0G5KdvNDjXfAv06OhfOzNDaBn5rw84DGXWndOEB7d5/x852A20sW1M56vhC/tRVbccQ==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] + '@next/swc-linux-arm64-musl@16.2.9': + resolution: {integrity: sha512-qZTI3pf9SGc/obr8NkQAekBxmp1QK+kVm+VAf3BALLfFAj+1kUhkTxmrWpVos9R/UYIA8AWX2p6cGI5WdwzVUA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + '@next/swc-linux-x64-gnu@16.1.6': resolution: {integrity: sha512-2eEBDkFlMMNQnkTyPBhQOAyn2qMxyG2eE7GPH2WIDGEpEILcBPI/jdSv4t6xupSP+ot/jkfrCShLAa7+ZUPcJQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + '@next/swc-linux-x64-gnu@16.2.9': + resolution: {integrity: sha512-xm0HfRNX+UkH4R3c18ynswjj5o5uEj/7iI9p9omdtTSIsRCzQqkGMA+10nzJ4EHnYC3as65IMhbbl5fWRUWHYg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + '@next/swc-linux-x64-musl@16.1.6': resolution: {integrity: sha512-oicJwRlyOoZXVlxmIMaTq7f8pN9QNbdes0q2FXfRsPhfCi8n8JmOZJm5oo1pwDaFbnnD421rVU409M3evFbIqg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + '@next/swc-linux-x64-musl@16.2.9': + resolution: {integrity: sha512-QumimHkGEG6vM3PfEDWKyKen03NcqLOkeKB1EfcPe7VxzmEiCa4jNnMyBn/US5zcd/VE1CI+O8Ovb3lfjVHfGw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + '@next/swc-win32-arm64-msvc@16.1.6': resolution: {integrity: sha512-gQmm8izDTPgs+DCWH22kcDmuUp7NyiJgEl18bcr8irXA5N2m2O+JQIr6f3ct42GOs9c0h8QF3L5SzIxcYAAXXw==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] + '@next/swc-win32-arm64-msvc@16.2.9': + resolution: {integrity: sha512-hzQpKZvw8rAwI6A2uQh6SacCSvNAXaIkPNsWwzqqfRiIMiXMfH936skDhz1OO6KpvdKkJrgHHtqQOq5PIXOvdQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + '@next/swc-win32-x64-msvc@16.1.6': resolution: {integrity: sha512-NRfO39AIrzBnixKbjuo2YiYhB6o9d8v/ymU9m/Xk8cyVk+k7XylniXkHwjs4s70wedVffc6bQNbufk5v0xEm0A==} engines: {node: '>= 10'} cpu: [x64] os: [win32] + '@next/swc-win32-x64-msvc@16.2.9': + resolution: {integrity: sha512-qr2VL3Ce5QrwgO2yh1ujSBawrimjVKX8FGF/cOynmdYKJY0BdHpGVNIRK1tqONB10Vkm25Ub1BD2bkjWs4+96w==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + '@noble/ciphers@2.1.1': resolution: {integrity: sha512-bysYuiVfhxNJuldNXlFEitTVdNnYUc+XNJZd7Qm2a5j1vZHgY+fazadNFWFaMK/2vye0JVlxV3gHmC0WDfAOQw==} engines: {node: '>= 20.19.0'} @@ -7199,8 +7250,8 @@ packages: engines: {node: '>=6.0'} hasBin: true - eslint-config-next@16.0.3: - resolution: {integrity: sha512-5F6qDjcZldf0Y0ZbqvWvap9xzYUxyDf7/of37aeyhvkrQokj/4bT1JYWZdlWUr283aeVa+s52mPq9ogmGg+5dw==} + eslint-config-next@16.2.9: + resolution: {integrity: sha512-olGtBrs07bQchpaJWeqbk9GaMoU0oGmN/pYNEBXSbfgKngb5uHnPe37X6tVeh6DJfaWFQildvinGEOrolo5fmw==} peerDependencies: eslint: '>=9.0.0' typescript: '>=3.3.1' @@ -7555,14 +7606,6 @@ packages: fb-watchman@2.0.2: resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} - fdir@6.4.4: - resolution: {integrity: sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==} - peerDependencies: - picomatch: ^3 || ^4 - peerDependenciesMeta: - picomatch: - optional: true - fdir@6.5.0: resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} engines: {node: '>=12.0.0'} @@ -9711,6 +9754,27 @@ packages: sass: optional: true + next@16.2.9: + resolution: {integrity: sha512-MEOJiq/UvuezAdqVSceHbqDgZt1kDw2tpGVOlsdIoJsQdbN2JY2hpVG4xnXGkbdJUOEWhnRfiu/O4Hpc9Juwww==} + engines: {node: '>=20.9.0'} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.51.1 + babel-plugin-react-compiler: '*' + react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + sass: ^1.3.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@playwright/test': + optional: true + babel-plugin-react-compiler: + optional: true + sass: + optional: true + nlcst-to-string@3.1.1: resolution: {integrity: sha512-63mVyqaqt0cmn2VcI2aH6kxe1rLAmSROqHMA0i4qqg1tidkfExgpb0FGMikMCn86mw5dFtBtEANfmSSK7TjNHw==} @@ -10000,10 +10064,6 @@ packages: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} - picomatch@4.0.2: - resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} - engines: {node: '>=12'} - picomatch@4.0.4: resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} engines: {node: '>=12'} @@ -11338,10 +11398,6 @@ packages: resolution: {integrity: sha512-VKS/ZaQhhkKFMANmAOhhXVoIfBXblQxGX1myCQ2faQrfmobMftXeJPcZGp0gS07ocvGJWDLZGyOZDadDBqYIJg==} engines: {node: '>=18'} - tinyglobby@0.2.13: - resolution: {integrity: sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==} - engines: {node: '>=12.0.0'} - tinyglobby@0.2.16: resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==} engines: {node: '>=12.0.0'} @@ -13070,12 +13126,12 @@ snapshots: '@better-auth/core': 1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0) '@better-auth/utils': 0.3.1 - '@better-auth/sso@1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(better-auth@1.5.6(@opentelemetry/api@1.9.0)(mongodb@6.21.0(@aws-sdk/credential-providers@3.797.0)(socks@2.8.4))(next@16.1.6(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(better-call@1.3.2(zod@3.24.3))': + '@better-auth/sso@1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(better-auth@1.5.6(@opentelemetry/api@1.9.0)(mongodb@6.21.0(@aws-sdk/credential-providers@3.797.0)(socks@2.8.4))(next@16.2.9(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(better-call@1.3.2(zod@3.24.3))': dependencies: '@better-auth/core': 1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0) '@better-auth/utils': 0.3.1 '@better-fetch/fetch': 1.1.21 - better-auth: 1.5.6(@opentelemetry/api@1.9.0)(mongodb@6.21.0(@aws-sdk/credential-providers@3.797.0)(socks@2.8.4))(next@16.1.6(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + better-auth: 1.5.6(@opentelemetry/api@1.9.0)(mongodb@6.21.0(@aws-sdk/credential-providers@3.797.0)(socks@2.8.4))(next@16.2.9(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) better-call: 1.3.2(zod@3.24.3) fast-xml-parser: 5.8.0 jose: 6.2.2 @@ -14313,34 +14369,60 @@ snapshots: '@next/env@16.1.6': {} - '@next/eslint-plugin-next@16.0.3': + '@next/env@16.2.9': {} + + '@next/eslint-plugin-next@16.2.9': dependencies: fast-glob: 3.3.1 '@next/swc-darwin-arm64@16.1.6': optional: true + '@next/swc-darwin-arm64@16.2.9': + optional: true + '@next/swc-darwin-x64@16.1.6': optional: true + '@next/swc-darwin-x64@16.2.9': + optional: true + '@next/swc-linux-arm64-gnu@16.1.6': optional: true + '@next/swc-linux-arm64-gnu@16.2.9': + optional: true + '@next/swc-linux-arm64-musl@16.1.6': optional: true + '@next/swc-linux-arm64-musl@16.2.9': + optional: true + '@next/swc-linux-x64-gnu@16.1.6': optional: true + '@next/swc-linux-x64-gnu@16.2.9': + optional: true + '@next/swc-linux-x64-musl@16.1.6': optional: true + '@next/swc-linux-x64-musl@16.2.9': + optional: true + '@next/swc-win32-arm64-msvc@16.1.6': optional: true + '@next/swc-win32-arm64-msvc@16.2.9': + optional: true + '@next/swc-win32-x64-msvc@16.1.6': optional: true + '@next/swc-win32-x64-msvc@16.2.9': + optional: true + '@noble/ciphers@2.1.1': {} '@noble/hashes@1.8.0': {} @@ -19070,7 +19152,7 @@ snapshots: baseline-browser-mapping@2.9.19: {} - better-auth@1.5.6(@opentelemetry/api@1.9.0)(mongodb@6.21.0(@aws-sdk/credential-providers@3.797.0)(socks@2.8.4))(next@16.1.6(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0): + better-auth@1.5.6(@opentelemetry/api@1.9.0)(mongodb@6.21.0(@aws-sdk/credential-providers@3.797.0)(socks@2.8.4))(next@16.2.9(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0): dependencies: '@better-auth/core': 1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0) '@better-auth/drizzle-adapter': 1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0))(@better-auth/utils@0.3.1) @@ -19091,7 +19173,7 @@ snapshots: zod: 4.3.6 optionalDependencies: mongodb: 6.21.0(@aws-sdk/credential-providers@3.797.0)(socks@2.8.4) - next: 16.1.6(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + next: 16.2.9(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) react: 19.2.0 react-dom: 19.2.0(react@19.2.0) transitivePeerDependencies: @@ -20149,9 +20231,9 @@ snapshots: optionalDependencies: source-map: 0.6.1 - eslint-config-next@16.0.3(@typescript-eslint/parser@8.46.4(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3): + eslint-config-next@16.2.9(@typescript-eslint/parser@8.46.4(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3): dependencies: - '@next/eslint-plugin-next': 16.0.3 + '@next/eslint-plugin-next': 16.2.9 eslint: 9.39.1(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.46.4(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1)) @@ -20188,12 +20270,12 @@ snapshots: eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.46.4(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1)): dependencies: '@nolyfill/is-core-module': 1.0.39 - debug: 4.4.1 + debug: 4.4.3 eslint: 9.39.1(jiti@2.6.1) get-tsconfig: 4.10.0 is-bun-module: 2.0.0 stable-hash: 0.0.5 - tinyglobby: 0.2.13 + tinyglobby: 0.2.16 unrs-resolver: 1.7.0 optionalDependencies: eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.46.4(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.1(jiti@2.6.1)) @@ -20260,7 +20342,7 @@ snapshots: hasown: 2.0.2 jsx-ast-utils: 3.3.5 language-tags: 1.0.9 - minimatch: 3.1.2 + minimatch: 3.1.5 object.fromentries: 2.0.8 safe-regex-test: 1.1.0 string.prototype.includes: 2.0.1 @@ -20720,10 +20802,6 @@ snapshots: dependencies: bser: 2.1.1 - fdir@6.4.4(picomatch@4.0.2): - optionalDependencies: - picomatch: 4.0.2 - fdir@6.5.0(picomatch@4.0.4): optionalDependencies: picomatch: 4.0.4 @@ -23812,6 +23890,31 @@ snapshots: - '@babel/core' - babel-plugin-macros + next@16.2.9(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0): + dependencies: + '@next/env': 16.2.9 + '@swc/helpers': 0.5.15 + baseline-browser-mapping: 2.9.19 + caniuse-lite: 1.0.30001761 + postcss: 8.4.31 + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + styled-jsx: 5.1.6(@babel/core@7.26.10)(babel-plugin-macros@3.1.0)(react@19.2.0) + optionalDependencies: + '@next/swc-darwin-arm64': 16.2.9 + '@next/swc-darwin-x64': 16.2.9 + '@next/swc-linux-arm64-gnu': 16.2.9 + '@next/swc-linux-arm64-musl': 16.2.9 + '@next/swc-linux-x64-gnu': 16.2.9 + '@next/swc-linux-x64-musl': 16.2.9 + '@next/swc-win32-arm64-msvc': 16.2.9 + '@next/swc-win32-x64-msvc': 16.2.9 + '@opentelemetry/api': 1.9.0 + sharp: 0.34.5 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + nlcst-to-string@3.1.1: dependencies: '@types/nlcst': 1.0.4 @@ -24100,8 +24203,6 @@ snapshots: picomatch@2.3.1: {} - picomatch@4.0.2: {} - picomatch@4.0.4: {} pidtree@0.6.0: {} @@ -26005,11 +26106,6 @@ snapshots: tinyexec@1.1.1: {} - tinyglobby@0.2.13: - dependencies: - fdir: 6.4.4(picomatch@4.0.2) - picomatch: 4.0.2 - tinyglobby@0.2.16: dependencies: fdir: 6.5.0(picomatch@4.0.4) From 89d339fd4084c16d90a5f3f839164593d2093a25 Mon Sep 17 00:00:00 2001 From: Rajat Date: Sat, 11 Jul 2026 16:29:56 +0530 Subject: [PATCH 2/2] Critical vulnerabilities fixed; Bull queue stuck fix; Drip email link fix; --- apps/queue/package.json | 2 +- apps/queue/src/bullmq.ts | 85 +++++++ .../domain/process-ongoing-sequences/index.ts | 13 +- apps/queue/src/domain/worker.ts | 69 +++--- apps/queue/src/index.ts | 40 ++- .../worker/dispatch-notification.ts | 54 ++-- .../src/notifications/worker/notification.ts | 51 ++-- .../[id]/content/section/[section]/page.tsx | 2 +- apps/web/lib/auth-client.ts | 27 +- apps/web/package.json | 4 +- pnpm-lock.yaml | 232 ++++++++++-------- 11 files changed, 381 insertions(+), 198 deletions(-) create mode 100644 apps/queue/src/bullmq.ts diff --git a/apps/queue/package.json b/apps/queue/package.json index 4fea03127..db2e1a0a8 100644 --- a/apps/queue/package.json +++ b/apps/queue/package.json @@ -27,7 +27,7 @@ "bullmq": "^4.14.0", "express": "^4.18.2", "jsdom": "^26.1.0", - "liquidjs": "^10.11.1", + "liquidjs": "10.26.0", "mongodb": "^6.21.0", "mongoose": "^8.22.1", "nodemailer": "^6.9.2", diff --git a/apps/queue/src/bullmq.ts b/apps/queue/src/bullmq.ts new file mode 100644 index 000000000..4dd81b97b --- /dev/null +++ b/apps/queue/src/bullmq.ts @@ -0,0 +1,85 @@ +import type { Job, Worker, WorkerOptions } from "bullmq"; +import redis from "./redis"; +import { logger } from "./logger"; +import { + captureError, + captureEvent, + getDomainId, +} from "./observability/posthog"; + +export const workerOptions: WorkerOptions = { + connection: redis, + lockDuration: 5 * 60 * 1000, + stalledInterval: 30 * 1000, + maxStalledCount: 2, +}; + +export function registerWorkerEvents( + worker: Pick, + queueName: string, +) { + worker.on("ready", () => { + captureEvent({ + event: "queue_worker_ready", + source: `worker.${queueName}.ready`, + domainId: getDomainId(), + properties: { + queue_name: queueName, + }, + }); + }); + + worker.on("closed", () => { + captureEvent({ + event: "queue_worker_closed", + source: `worker.${queueName}.closed`, + domainId: getDomainId(), + properties: { + queue_name: queueName, + }, + }); + }); + + worker.on("failed", (job: Job | undefined, err: Error) => { + const domainId = getDomainId(job?.data?.domainId || job?.data?.domain); + logger.error(err); + captureError({ + error: err, + source: `worker.${queueName}.failed`, + domainId, + context: { + queue_name: queueName, + job_id: job?.id ? String(job.id) : undefined, + job_name: job?.name, + failed_reason: job?.failedReason, + attempts_made: job?.attemptsMade, + }, + }); + }); + + worker.on("stalled", (jobId: string) => { + const err = new Error(`BullMQ job stalled in ${queueName}: ${jobId}`); + logger.error(err); + captureError({ + error: err, + source: `worker.${queueName}.stalled`, + domainId: getDomainId(), + context: { + queue_name: queueName, + job_id: jobId, + }, + }); + }); + + worker.on("error", (err: Error) => { + logger.error(err); + captureError({ + error: err, + source: `worker.${queueName}.error`, + domainId: getDomainId(), + context: { + queue_name: queueName, + }, + }); + }); +} diff --git a/apps/queue/src/domain/process-ongoing-sequences/index.ts b/apps/queue/src/domain/process-ongoing-sequences/index.ts index e2b630170..5ba8b3411 100644 --- a/apps/queue/src/domain/process-ongoing-sequences/index.ts +++ b/apps/queue/src/domain/process-ongoing-sequences/index.ts @@ -1,18 +1,18 @@ import { logger } from "../../logger"; import { getDueOngoingSequences } from "../queries"; import { Worker } from "bullmq"; -import redis from "../../redis"; import sequenceQueue from "../sequence-queue"; import { processOngoingSequence } from "./process-ongoing-sequence"; import { captureError, getDomainId } from "../../observability/posthog"; +import { registerWorkerEvents, workerOptions } from "../../bullmq"; interface SequenceWorkerData { ongoingSequenceId: string; domainId?: string; } -if (process.env.NODE_ENV !== "test") { - new Worker( +export function startSequenceWorker() { + const worker = new Worker( "sequence", async (job) => { const payload = job.data as SequenceWorkerData | string; @@ -38,10 +38,15 @@ if (process.env.NODE_ENV !== "test") { ongoing_sequence_id: String(ongoingSequenceId), }, }); + throw err; } }, - { connection: redis }, + workerOptions, ); + + registerWorkerEvents(worker, "sequence"); + + return worker; } export async function processOngoingSequences(): Promise { diff --git a/apps/queue/src/domain/worker.ts b/apps/queue/src/domain/worker.ts index 8a1ac0f02..4dd8045ec 100644 --- a/apps/queue/src/domain/worker.ts +++ b/apps/queue/src/domain/worker.ts @@ -1,39 +1,44 @@ import { Worker } from "bullmq"; -import redis from "../redis"; import { logger } from "../logger"; import { captureError, getDomainId } from "../observability/posthog"; import { sendMail } from "../mail"; +import { registerWorkerEvents, workerOptions } from "../bullmq"; -const worker = new Worker( - "mail", - async (job) => { - const { to, from, subject, body, headers, domainId } = job.data; +export function startMailWorker() { + const worker = new Worker( + "mail", + async (job) => { + const { to, from, subject, body, headers, domainId } = job.data; - try { - await sendMail({ - from, - to, - subject, - html: body, - headers, - }); - } catch (err: any) { - logger.error(err); - captureError({ - error: err, - source: "worker.mail", - domainId: getDomainId(domainId), - context: { - queue_name: "mail", - job_id: String(job.id), - error_code: err?.code, - response_code: err?.responseCode, - command: err?.command, - }, - }); - } - }, - { connection: redis }, -); + try { + await sendMail({ + from, + to, + subject, + html: body, + headers, + }); + } catch (err: any) { + logger.error(err); + captureError({ + error: err, + source: "worker.mail", + domainId: getDomainId(domainId), + context: { + queue_name: "mail", + job_id: String(job.id), + error_code: err?.code, + response_code: err?.responseCode, + command: err?.command, + }, + }); + throw err; + } + }, + workerOptions, + ); -export default worker; + registerWorkerEvents(worker, "mail"); + + return worker; +} diff --git a/apps/queue/src/index.ts b/apps/queue/src/index.ts index 8ffd4ae3f..78dae150d 100644 --- a/apps/queue/src/index.ts +++ b/apps/queue/src/index.ts @@ -2,13 +2,12 @@ import express from "express"; import jobRoutes from "./job/routes"; import sseRoutes from "./sse/routes"; -// start workers -import "./domain/worker"; -import "./notifications/worker/notification"; -import "./notifications/worker/dispatch-notification"; - // start loops import { startEmailAutomation } from "./start-email-automation"; +import { startSequenceWorker } from "./domain/process-ongoing-sequences"; +import { startMailWorker } from "./domain/worker"; +import { startNotificationWorker } from "./notifications/worker/notification"; +import { startDispatchNotificationWorker } from "./notifications/worker/dispatch-notification"; import { verifyJWTMiddleware } from "./middlewares/verify-jwt"; import { captureError, @@ -18,6 +17,37 @@ import { import { initPosthogLogs } from "./observability/logs"; import { logger } from "./logger"; +const workers = + process.env.NODE_ENV === "test" + ? [] + : [ + startMailWorker(), + startNotificationWorker(), + startDispatchNotificationWorker(), + startSequenceWorker(), + ]; + +async function closeWorkers() { + await Promise.allSettled(workers.map((worker) => worker.close())); +} + +for (const signal of ["SIGINT", "SIGTERM"] as const) { + process.once(signal, () => { + closeWorkers() + .catch((err) => { + logger.error(err); + captureError({ + error: err, + source: "service.shutdown", + domainId: getDomainId(), + }); + }) + .finally(() => { + process.kill(process.pid, signal); + }); + }); +} + const app = express(); app.use(express.json()); diff --git a/apps/queue/src/notifications/worker/dispatch-notification.ts b/apps/queue/src/notifications/worker/dispatch-notification.ts index f7d0f9ca2..38edb2622 100644 --- a/apps/queue/src/notifications/worker/dispatch-notification.ts +++ b/apps/queue/src/notifications/worker/dispatch-notification.ts @@ -4,7 +4,6 @@ import { Constants, NotificationChannel as NotificationChannelType, } from "@courselit/common-models"; -import redis from "../../redis"; import { logger } from "../../logger"; import UserModel from "../../domain/model/user"; import DomainModel from "../../domain/model/domain"; @@ -18,6 +17,7 @@ import { NotificationChannel, } from "../services/channels/types"; import { captureError, getDomainId } from "../../observability/posthog"; +import { registerWorkerEvents, workerOptions } from "../../bullmq"; interface DispatchNotificationJob { domain: string | mongoose.Types.ObjectId; @@ -33,31 +33,35 @@ const channelRegistry: Record = { [Constants.NotificationChannel.EMAIL]: new EmailChannel(), }; -const worker = new Worker( - "dispatch-notification", - async (job) => { - const payload = job.data as DispatchNotificationJob; - try { - await processDispatchNotificationJob(payload); - } catch (err: any) { - logger.error(err); - captureError({ - error: err, - source: "worker.dispatch_notification", - domainId: getDomainId(payload?.domain), - context: { - queue_name: "dispatch-notification", - job_id: String(job.id), - activity_type: payload?.activityType, - }, - }); - throw err; - } - }, - { connection: redis }, -); +export function startDispatchNotificationWorker() { + const worker = new Worker( + "dispatch-notification", + async (job) => { + const payload = job.data as DispatchNotificationJob; + try { + await processDispatchNotificationJob(payload); + } catch (err: any) { + logger.error(err); + captureError({ + error: err, + source: "worker.dispatch_notification", + domainId: getDomainId(payload?.domain), + context: { + queue_name: "dispatch-notification", + job_id: String(job.id), + activity_type: payload?.activityType, + }, + }); + throw err; + } + }, + workerOptions, + ); -export default worker; + registerWorkerEvents(worker, "dispatch-notification"); + + return worker; +} async function processDispatchNotificationJob(job: DispatchNotificationJob) { if (!Object.values(Constants.ActivityType).includes(job.activityType)) { diff --git a/apps/queue/src/notifications/worker/notification.ts b/apps/queue/src/notifications/worker/notification.ts index 59ee5e23c..f1295b88d 100644 --- a/apps/queue/src/notifications/worker/notification.ts +++ b/apps/queue/src/notifications/worker/notification.ts @@ -1,32 +1,37 @@ import { Worker } from "bullmq"; -import redis from "../../redis"; import { logger } from "../../logger"; import { notificationEmitter } from "../utils/emitter"; import { captureError, getDomainId } from "../../observability/posthog"; +import { registerWorkerEvents, workerOptions } from "../../bullmq"; -const worker = new Worker( - "notification", - async (job) => { - const notification = job.data; - try { - deliverInAppNotification(notification); - } catch (err: any) { - logger.error(err); - captureError({ - error: err, - source: "worker.notification", - domainId: getDomainId(notification?.domain), - context: { - queue_name: "notification", - job_id: String(job.id), - }, - }); - } - }, - { connection: redis }, -); +export function startNotificationWorker() { + const worker = new Worker( + "notification", + async (job) => { + const notification = job.data; + try { + deliverInAppNotification(notification); + } catch (err: any) { + logger.error(err); + captureError({ + error: err, + source: "worker.notification", + domainId: getDomainId(notification?.domain), + context: { + queue_name: "notification", + job_id: String(job.id), + }, + }); + throw err; + } + }, + workerOptions, + ); -export default worker; + registerWorkerEvents(worker, "notification"); + + return worker; +} function deliverInAppNotification(notification) { notificationEmitter.emit("newNotification", notification); diff --git a/apps/web/app/(with-contexts)/dashboard/(sidebar)/product/[id]/content/section/[section]/page.tsx b/apps/web/app/(with-contexts)/dashboard/(sidebar)/product/[id]/content/section/[section]/page.tsx index 26c3b9cb1..95558e549 100644 --- a/apps/web/app/(with-contexts)/dashboard/(sidebar)/product/[id]/content/section/[section]/page.tsx +++ b/apps/web/app/(with-contexts)/dashboard/(sidebar)/product/[id]/content/section/[section]/page.tsx @@ -134,7 +134,7 @@ export default function SectionPage(props: { blockType: "text", settings: { content: - "{{address}}\n\n{{unsubscribe_link}}", + "{{address}}\n\n[Unsubscribe]({{unsubscribe_link}})", alignment: "center", fontSize: "12px", foregroundColor: "#64748b", diff --git a/apps/web/lib/auth-client.ts b/apps/web/lib/auth-client.ts index 1cca6d52e..806a07761 100644 --- a/apps/web/lib/auth-client.ts +++ b/apps/web/lib/auth-client.ts @@ -2,6 +2,31 @@ import { createAuthClient } from "better-auth/client"; import { emailOTPClient } from "better-auth/client/plugins"; import { ssoClient } from "@better-auth/sso/client"; +type AuthClientResult = Promise<{ + error?: { + message?: string; + } | null; +}>; + +type AuthClient = { + emailOtp: { + sendVerificationOtp: (input: { + email: string; + type: "sign-in"; + }) => AuthClientResult; + }; + signIn: { + emailOtp: (input: { email: string; otp: string }) => AuthClientResult; + sso: (input: { + providerId: string; + callbackURL?: string; + }) => AuthClientResult; + }; + signOut: (input?: { + fetchOptions?: { onSuccess?: () => void }; + }) => AuthClientResult; +}; + export const authClient = createAuthClient({ plugins: [emailOTPClient(), ssoClient()], -}); +}) as unknown as AuthClient; diff --git a/apps/web/package.json b/apps/web/package.json index 8bc1dd172..f0a65c277 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -26,7 +26,7 @@ ] }, "dependencies": { - "@better-auth/sso": "^1.5.6", + "@better-auth/sso": "1.6.11", "@courselit/common-logic": "workspace:^", "@courselit/common-models": "workspace:^", "@courselit/components-library": "workspace:^", @@ -70,7 +70,7 @@ "archiver": "^5.3.1", "aws4": "^1.13.2", "base-64": "^1.0.0", - "better-auth": "^1.5.6", + "better-auth": "1.6.11", "chart.js": "^4.4.7", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0c81c7e8e..2e7195baa 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -234,8 +234,8 @@ importers: specifier: ^26.1.0 version: 26.1.0 liquidjs: - specifier: ^10.11.1 - version: 10.21.0 + specifier: 10.26.0 + version: 10.26.0 mongodb: specifier: ^6.21.0 version: 6.21.0(@aws-sdk/credential-providers@3.797.0)(socks@2.8.4) @@ -295,8 +295,8 @@ importers: apps/web: dependencies: '@better-auth/sso': - specifier: ^1.5.6 - version: 1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(better-auth@1.5.6(@opentelemetry/api@1.9.0)(mongodb@6.21.0(@aws-sdk/credential-providers@3.797.0)(socks@2.8.4))(next@16.2.9(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(better-call@1.3.2(zod@3.24.3)) + specifier: 1.6.11 + version: 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0))(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-auth@1.6.11(@opentelemetry/api@1.9.0)(mongodb@6.21.0(@aws-sdk/credential-providers@3.797.0)(socks@2.8.4))(next@16.2.9(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(better-call@1.3.5(zod@3.24.3)) '@courselit/common-logic': specifier: workspace:^ version: link:../../packages/common-logic @@ -427,8 +427,8 @@ importers: specifier: ^1.0.0 version: 1.0.0 better-auth: - specifier: ^1.5.6 - version: 1.5.6(@opentelemetry/api@1.9.0)(mongodb@6.21.0(@aws-sdk/credential-providers@3.797.0)(socks@2.8.4))(next@16.2.9(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + specifier: 1.6.11 + version: 1.6.11(@opentelemetry/api@1.9.0)(mongodb@6.21.0(@aws-sdk/credential-providers@3.797.0)(socks@2.8.4))(next@16.2.9(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) chart.js: specifier: ^4.4.7 version: 4.4.9 @@ -1775,62 +1775,64 @@ packages: '@bcoe/v8-coverage@0.2.3': resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} - '@better-auth/core@1.5.6': - resolution: {integrity: sha512-Ez9DZdIMFyxHremmoLz1emFPGNQomDC1jqqBPnZ6Ci+6TiGN3R9w/Y03cJn6I8r1ycKgOzeVMZtJ/erOZ27Gsw==} + '@better-auth/core@1.6.11': + resolution: {integrity: sha512-LrwidLCV8azdMGjvtwp30nj9tIv1BwI3VhtC0UaGSjQkAVWw4bN42I8qwbxRziPeSQoj+zUVkOpxZzAWBDARtQ==} peerDependencies: - '@better-auth/utils': 0.3.1 + '@better-auth/utils': 0.4.0 '@better-fetch/fetch': 1.1.21 '@cloudflare/workers-types': '>=4' '@opentelemetry/api': ^1.9.0 - better-call: 1.3.2 + better-call: 1.3.5 jose: ^6.1.0 kysely: 0.28.17 nanostores: ^1.0.1 peerDependenciesMeta: '@cloudflare/workers-types': optional: true + '@opentelemetry/api': + optional: true - '@better-auth/drizzle-adapter@1.5.6': - resolution: {integrity: sha512-VfFFmaoFw3ug12SiSuIwzrMoHyIVmkMGWm9gZ4sXdYYVX4HboCL4m3fjzOhppcmK5OGatRuU+N1UX6wxCITcXw==} + '@better-auth/drizzle-adapter@1.6.11': + resolution: {integrity: sha512-4jpkETIGZOHCf7BK4jnu22fdN6jjomH0/HhEzkaWy3+Eppi5PYlHTF/460jrTmA3Xc+Vqwp9t282ymHiEPypGw==} peerDependencies: - '@better-auth/core': 1.5.6 - '@better-auth/utils': ^0.3.0 - drizzle-orm: '>=0.41.0' + '@better-auth/core': ^1.6.11 + '@better-auth/utils': 0.4.0 + drizzle-orm: ^0.45.2 peerDependenciesMeta: drizzle-orm: optional: true - '@better-auth/kysely-adapter@1.5.6': - resolution: {integrity: sha512-Fnf+h8WVKtw6lEOmVmiVVzDf3shJtM60AYf9XTnbdCeUd6MxN/KnaJZpkgtYnRs7a+nwtkVB+fg4lGETebGFXQ==} + '@better-auth/kysely-adapter@1.6.11': + resolution: {integrity: sha512-/g8M9RfIjdcZDnbstSUvQiINkvdNlCeZr248zwqx2/PVksQI1MhQofbzUn3RnQnbPKp0EPwpX/dR3oudRFenUg==} peerDependencies: - '@better-auth/core': 1.5.6 - '@better-auth/utils': ^0.3.0 + '@better-auth/core': ^1.6.11 + '@better-auth/utils': 0.4.0 kysely: 0.28.17 peerDependenciesMeta: kysely: optional: true - '@better-auth/memory-adapter@1.5.6': - resolution: {integrity: sha512-rS7ZsrIl5uvloUgNN0u9LOZJMMXnsZXVdUZ3MrTBKWM2KpoJjzPr9yN3Szyma5+0V7SltnzSGHPkYj2bEzzmlA==} + '@better-auth/memory-adapter@1.6.11': + resolution: {integrity: sha512-hpdfw0BBf8MuzLkIdmbcUZICbY9r/bhLO2RxSnkzT5+/O+0I0u2I8+m0YUP7vNllP/ZCKASHOYgXPLO75Z0f9Q==} peerDependencies: - '@better-auth/core': 1.5.6 - '@better-auth/utils': ^0.3.0 + '@better-auth/core': ^1.6.11 + '@better-auth/utils': 0.4.0 - '@better-auth/mongo-adapter@1.5.6': - resolution: {integrity: sha512-6+M3MS2mor8fTUV3EI1FBLP0cs6QfbN+Ovx9+XxR/GdfKIBoNFzmPEPRbdGt+ft6PvrITsUm+T70+kkHgVSP6w==} + '@better-auth/mongo-adapter@1.6.11': + resolution: {integrity: sha512-3Tor8rSv8vSEIMEaV2PFpPEuVhqc1gNoZ6eGvoh3LwExXXuj8madew6ob+H1pH7Aphn3Ar5PQ08AguT8TbwFAA==} peerDependencies: - '@better-auth/core': 1.5.6 - '@better-auth/utils': ^0.3.0 + '@better-auth/core': ^1.6.11 + '@better-auth/utils': 0.4.0 mongodb: ^6.0.0 || ^7.0.0 peerDependenciesMeta: mongodb: optional: true - '@better-auth/prisma-adapter@1.5.6': - resolution: {integrity: sha512-UxY9vQJs1Tt+O+T2YQnseDMlWmUSQvFZSBb5YiFRg7zcm+TEzujh4iX2/csA0YiZptLheovIuVWTP9nriewEBA==} + '@better-auth/prisma-adapter@1.6.11': + resolution: {integrity: sha512-Pw+7q7zTp+VSci1V+CYMvuxIbAeVMZLe4lRo46LJoAKMHfjFl5T/ycsyFvWs/DkWC7n9gZZzRDEbHp0I5FiKKw==} peerDependencies: - '@better-auth/core': 1.5.6 - '@better-auth/utils': ^0.3.0 + '@better-auth/core': ^1.6.11 + '@better-auth/utils': 0.4.0 '@prisma/client': ^5.0.0 || ^6.0.0 || ^7.0.0 prisma: ^5.0.0 || ^6.0.0 || ^7.0.0 peerDependenciesMeta: @@ -1839,21 +1841,24 @@ packages: prisma: optional: true - '@better-auth/sso@1.5.6': - resolution: {integrity: sha512-R4mC3Bj9Xy4pBz+XNjs4Z7gpukmAUc7mIgIhg0zmN7R7rjj8Uz9sBBRcf6b/+6fFyXe/mZ0f+Sc3uBaYt4hRaQ==} + '@better-auth/sso@1.6.11': + resolution: {integrity: sha512-lJHmoCayp9Woh/MPKTHDfGq7k1oQbU2yz5tIOZXl/pzrgLxV7fMGo9aJCyabHkw3GHMjBes4byC6aakHYzpZIg==} peerDependencies: - '@better-auth/core': 1.5.6 - '@better-auth/utils': 0.3.1 - better-auth: 1.5.6 - better-call: 1.3.2 + '@better-auth/core': ^1.6.11 + '@better-auth/utils': 0.4.0 + '@better-fetch/fetch': 1.1.21 + better-auth: ^1.6.11 + better-call: 1.3.5 - '@better-auth/telemetry@1.5.6': - resolution: {integrity: sha512-yXC7NSxnIFlxDkGdpD7KA+J9nqIQAPCJKe77GoaC5bWoe/DALo1MYorZfTgOafS7wrslNtsPT4feV/LJi1ubqQ==} + '@better-auth/telemetry@1.6.11': + resolution: {integrity: sha512-hsjDHc8MZbm6/AHeNdtywrWedXevnBjmdvnHTcZub+rTVjOv+Td0roI8USKuC6uUibmrl//2rJfVCsGbopihNA==} peerDependencies: - '@better-auth/core': 1.5.6 + '@better-auth/core': ^1.6.11 + '@better-auth/utils': 0.4.0 + '@better-fetch/fetch': 1.1.21 - '@better-auth/utils@0.3.1': - resolution: {integrity: sha512-+CGp4UmZSUrHHnpHhLPYu6cV+wSUSvVbZbNykxhUDocpVNTo9uFFxw/NqJlh1iC4wQ9HKKWGCKuZ5wUgS0v6Kg==} + '@better-auth/utils@0.4.0': + resolution: {integrity: sha512-RpMtLUIQAEWMgdPLNVbIF5ON2mm+CH0U3rCdUCU1VyeAUui4m38DyK7/aXMLZov2YDjG684pS1D0MBllrmgjQA==} '@better-fetch/fetch@1.1.21': resolution: {integrity: sha512-/ImESw0sskqlVR94jB+5+Pxjf+xBwDZF/N5+y2/q4EqD7IARUTSpPfIo8uf39SYpCxyOCtbyYpUrZ3F/k0zT4A==} @@ -6227,8 +6232,8 @@ packages: resolution: {integrity: sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==} hasBin: true - better-auth@1.5.6: - resolution: {integrity: sha512-QSpJTqaT1XVfWRQe/fm3PgeuwOIlz1nWX/Dx7nsHStJ382bLzmDbQk2u7IT0IJ6wS5SRxfqEE1Ev9TXontgyAQ==} + better-auth@1.6.11: + resolution: {integrity: sha512-Wwt6+q07dwIhsp6XiM7L1qSXVUWBEtNl+eZvwM778CguFqDZFBN9Pt6LtFaHl55t8Z+Zc//5kxcbgDY8/79vFQ==} peerDependencies: '@lynx-js/react': '*' '@prisma/client': ^5.0.0 || ^6.0.0 || ^7.0.0 @@ -6237,7 +6242,7 @@ packages: '@tanstack/solid-start': ^1.0.0 better-sqlite3: ^12.0.0 drizzle-kit: '>=0.31.4' - drizzle-orm: '>=0.41.0' + drizzle-orm: ^0.45.2 mongodb: ^6.0.0 || ^7.0.0 mysql2: ^3.0.0 next: ^14.0.0 || ^15.0.0 || ^16.0.0 @@ -6289,8 +6294,8 @@ packages: vue: optional: true - better-call@1.3.2: - resolution: {integrity: sha512-4cZIfrerDsNTn3cm+MhLbUePN0gdwkhSXEuG7r/zuQ8c/H7iU0/jSK5TD3FW7U0MgKHce/8jGpPYNO4Ve+4NBw==} + better-call@1.3.5: + resolution: {integrity: sha512-kOFJkBP7utAQLEYrobZm3vkTH8mXq5GNgvjc5/XEST1ilVHaxXUXfeDeFlqoETMtyqS4+3/h4ONX2i++ebZrvA==} peerDependencies: zod: ^4.0.0 peerDependenciesMeta: @@ -8964,9 +8969,9 @@ packages: engines: {node: '>=18.12.0'} hasBin: true - liquidjs@10.21.0: - resolution: {integrity: sha512-DouqxNU2jfoZzb1LinVjOc/f6ssitGIxiDJT+kEKyYqPSSSd+WmGOAhtWbVm1/n75svu4aQ+FyQ3ctd3wh1bbw==} - engines: {node: '>=14'} + liquidjs@10.26.0: + resolution: {integrity: sha512-Ub9FFNOLB9tdH/gB2MKkeU7x9NifoVidxAam6YWU7LUcy7Glumi6q5C3tDpWOEpeNaT8Cdwdb1axEdlvLSoyaQ==} + engines: {node: '>=16'} hasBin: true listr2@8.3.2: @@ -9825,6 +9830,10 @@ packages: resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + node-forge@1.4.0: + resolution: {integrity: sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ==} + engines: {node: '>= 6.13.0'} + node-gyp-build-optional-packages@5.2.2: resolution: {integrity: sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==} hasBin: true @@ -10001,6 +10010,9 @@ packages: package-manager-detector@0.2.11: resolution: {integrity: sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==} + pako@1.0.11: + resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -10937,8 +10949,8 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - samlify@2.12.0: - resolution: {integrity: sha512-ewGsHyY4kInDH0BfprlAZ1rHpH1jBmbqYiXDbuI3t1Y8h71gqEt4Z7jdCFyPHFR8jItJkbdckTijUZGg14CDlg==} + samlify@2.10.2: + resolution: {integrity: sha512-y5s1cHwclqwP8h7K2Wj9SfP1q+1S9+jrs5OAegYTLAiuFi7nDvuKqbiXLmUTvYPMpzHcX94wTY2+D604jgTKvA==} sass-formatter@0.7.9: resolution: {integrity: sha512-CWZ8XiSim+fJVG0cFLStwDvft1VI7uvXdCNJYXhDvowiv+DsbD1nXLiQ4zrE5UBvj5DWZJ93cwN0NX5PMsr1Pw==} @@ -11866,6 +11878,11 @@ packages: resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} hasBin: true + uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + deprecated: uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028). + hasBin: true + uuid@9.0.1: resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} deprecated: uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028). @@ -12173,10 +12190,6 @@ packages: resolution: {integrity: sha512-NNXnzrkDrAzalLhIUc01jO2mOzXGXh1JwPgkihcLLzw98c0WgYDmmjSh1Kl3wzaxSVWMuA+fe0WTWOBDWCBmNA==} engines: {node: '>=0.6.0'} - xpath@0.0.34: - resolution: {integrity: sha512-FxF6+rkr1rNSQrhUNYrAFJpRXNzlDoMxeXN5qI84939ylEv3qqPFKa85Oxr6tDaJKqwW6KKyo2v26TSv3k6LeA==} - engines: {node: '>=0.6.0'} - y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} @@ -13116,68 +13129,71 @@ snapshots: '@bcoe/v8-coverage@0.2.3': {} - '@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0)': + '@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0)': dependencies: - '@better-auth/utils': 0.3.1 + '@better-auth/utils': 0.4.0 '@better-fetch/fetch': 1.1.21 - '@opentelemetry/api': 1.9.0 '@opentelemetry/semantic-conventions': 1.40.0 '@standard-schema/spec': 1.1.0 - better-call: 1.3.2(zod@3.24.3) + better-call: 1.3.5(zod@3.24.3) jose: 6.2.2 kysely: 0.28.17 nanostores: 1.2.0 zod: 4.3.6 + optionalDependencies: + '@opentelemetry/api': 1.9.0 - '@better-auth/drizzle-adapter@1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0))(@better-auth/utils@0.3.1)': + '@better-auth/drizzle-adapter@1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0))(@better-auth/utils@0.4.0)': dependencies: - '@better-auth/core': 1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0) - '@better-auth/utils': 0.3.1 + '@better-auth/core': 1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0) + '@better-auth/utils': 0.4.0 - '@better-auth/kysely-adapter@1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(kysely@0.28.17)': + '@better-auth/kysely-adapter@1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0))(@better-auth/utils@0.4.0)(kysely@0.28.17)': dependencies: - '@better-auth/core': 1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0) - '@better-auth/utils': 0.3.1 + '@better-auth/core': 1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0) + '@better-auth/utils': 0.4.0 optionalDependencies: kysely: 0.28.17 - '@better-auth/memory-adapter@1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0))(@better-auth/utils@0.3.1)': + '@better-auth/memory-adapter@1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0))(@better-auth/utils@0.4.0)': dependencies: - '@better-auth/core': 1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0) - '@better-auth/utils': 0.3.1 + '@better-auth/core': 1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0) + '@better-auth/utils': 0.4.0 - '@better-auth/mongo-adapter@1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(mongodb@6.21.0(@aws-sdk/credential-providers@3.797.0)(socks@2.8.4))': + '@better-auth/mongo-adapter@1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0))(@better-auth/utils@0.4.0)(mongodb@6.21.0(@aws-sdk/credential-providers@3.797.0)(socks@2.8.4))': dependencies: - '@better-auth/core': 1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0) - '@better-auth/utils': 0.3.1 + '@better-auth/core': 1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0) + '@better-auth/utils': 0.4.0 optionalDependencies: mongodb: 6.21.0(@aws-sdk/credential-providers@3.797.0)(socks@2.8.4) - '@better-auth/prisma-adapter@1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0))(@better-auth/utils@0.3.1)': + '@better-auth/prisma-adapter@1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0))(@better-auth/utils@0.4.0)': dependencies: - '@better-auth/core': 1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0) - '@better-auth/utils': 0.3.1 + '@better-auth/core': 1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0) + '@better-auth/utils': 0.4.0 - '@better-auth/sso@1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(better-auth@1.5.6(@opentelemetry/api@1.9.0)(mongodb@6.21.0(@aws-sdk/credential-providers@3.797.0)(socks@2.8.4))(next@16.2.9(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(better-call@1.3.2(zod@3.24.3))': + '@better-auth/sso@1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0))(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-auth@1.6.11(@opentelemetry/api@1.9.0)(mongodb@6.21.0(@aws-sdk/credential-providers@3.797.0)(socks@2.8.4))(next@16.2.9(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(better-call@1.3.5(zod@3.24.3))': dependencies: - '@better-auth/core': 1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0) - '@better-auth/utils': 0.3.1 + '@better-auth/core': 1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0) + '@better-auth/utils': 0.4.0 '@better-fetch/fetch': 1.1.21 - better-auth: 1.5.6(@opentelemetry/api@1.9.0)(mongodb@6.21.0(@aws-sdk/credential-providers@3.797.0)(socks@2.8.4))(next@16.2.9(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - better-call: 1.3.2(zod@3.24.3) + better-auth: 1.6.11(@opentelemetry/api@1.9.0)(mongodb@6.21.0(@aws-sdk/credential-providers@3.797.0)(socks@2.8.4))(next@16.2.9(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + better-call: 1.3.5(zod@3.24.3) fast-xml-parser: 5.8.0 jose: 6.2.2 - samlify: 2.12.0 + samlify: 2.10.2 tldts: 6.1.86 zod: 4.3.6 - '@better-auth/telemetry@1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0))': + '@better-auth/telemetry@1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0))(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)': dependencies: - '@better-auth/core': 1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0) - '@better-auth/utils': 0.3.1 + '@better-auth/core': 1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0) + '@better-auth/utils': 0.4.0 '@better-fetch/fetch': 1.1.21 - '@better-auth/utils@0.3.1': {} + '@better-auth/utils@0.4.0': + dependencies: + '@noble/hashes': 2.0.1 '@better-fetch/fetch@1.1.21': {} @@ -19188,20 +19204,20 @@ snapshots: baseline-browser-mapping@2.9.19: {} - better-auth@1.5.6(@opentelemetry/api@1.9.0)(mongodb@6.21.0(@aws-sdk/credential-providers@3.797.0)(socks@2.8.4))(next@16.2.9(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0): + better-auth@1.6.11(@opentelemetry/api@1.9.0)(mongodb@6.21.0(@aws-sdk/credential-providers@3.797.0)(socks@2.8.4))(next@16.2.9(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0): dependencies: - '@better-auth/core': 1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0) - '@better-auth/drizzle-adapter': 1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0))(@better-auth/utils@0.3.1) - '@better-auth/kysely-adapter': 1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(kysely@0.28.17) - '@better-auth/memory-adapter': 1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0))(@better-auth/utils@0.3.1) - '@better-auth/mongo-adapter': 1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(mongodb@6.21.0(@aws-sdk/credential-providers@3.797.0)(socks@2.8.4)) - '@better-auth/prisma-adapter': 1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0))(@better-auth/utils@0.3.1) - '@better-auth/telemetry': 1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0)) - '@better-auth/utils': 0.3.1 + '@better-auth/core': 1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0) + '@better-auth/drizzle-adapter': 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0))(@better-auth/utils@0.4.0) + '@better-auth/kysely-adapter': 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0))(@better-auth/utils@0.4.0)(kysely@0.28.17) + '@better-auth/memory-adapter': 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0))(@better-auth/utils@0.4.0) + '@better-auth/mongo-adapter': 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0))(@better-auth/utils@0.4.0)(mongodb@6.21.0(@aws-sdk/credential-providers@3.797.0)(socks@2.8.4)) + '@better-auth/prisma-adapter': 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0))(@better-auth/utils@0.4.0) + '@better-auth/telemetry': 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@3.24.3))(jose@6.2.2)(kysely@0.28.17)(nanostores@1.2.0))(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21) + '@better-auth/utils': 0.4.0 '@better-fetch/fetch': 1.1.21 '@noble/ciphers': 2.1.1 '@noble/hashes': 2.0.1 - better-call: 1.3.2(zod@4.3.6) + better-call: 1.3.5(zod@4.3.6) defu: 6.1.6 jose: 6.2.2 kysely: 0.28.17 @@ -19216,18 +19232,18 @@ snapshots: - '@cloudflare/workers-types' - '@opentelemetry/api' - better-call@1.3.2(zod@3.24.3): + better-call@1.3.5(zod@3.24.3): dependencies: - '@better-auth/utils': 0.3.1 + '@better-auth/utils': 0.4.0 '@better-fetch/fetch': 1.1.21 rou3: 0.7.12 set-cookie-parser: 3.1.0 optionalDependencies: zod: 3.24.3 - better-call@1.3.2(zod@4.3.6): + better-call@1.3.5(zod@4.3.6): dependencies: - '@better-auth/utils': 0.3.1 + '@better-auth/utils': 0.4.0 '@better-fetch/fetch': 1.1.21 rou3: 0.7.12 set-cookie-parser: 3.1.0 @@ -22627,7 +22643,7 @@ snapshots: transitivePeerDependencies: - supports-color - liquidjs@10.21.0: + liquidjs@10.26.0: dependencies: commander: 10.0.1 @@ -23973,6 +23989,8 @@ snapshots: fetch-blob: 3.2.0 formdata-polyfill: 4.0.10 + node-forge@1.4.0: {} + node-gyp-build-optional-packages@5.2.2: dependencies: detect-libc: 2.1.2 @@ -24160,6 +24178,8 @@ snapshots: dependencies: quansync: 0.2.10 + pako@1.0.11: {} + parent-module@1.0.1: dependencies: callsites: 3.1.0 @@ -25409,15 +25429,19 @@ snapshots: safer-buffer@2.1.2: {} - samlify@2.12.0: + samlify@2.10.2: dependencies: '@authenio/xml-encryption': 2.0.2 '@xmldom/xmldom': 0.8.13 + camelcase: 6.3.0 + node-forge: 1.4.0 node-rsa: 1.1.1 + pako: 1.0.11 + uuid: 8.3.2 xml: 1.0.1 xml-crypto: 6.1.2 xml-escape: 1.1.0 - xpath: 0.0.34 + xpath: 0.0.32 sass-formatter@0.7.9: dependencies: @@ -26975,6 +26999,8 @@ snapshots: uuid@11.1.0: {} + uuid@8.3.2: {} + uuid@9.0.1: {} uvu@0.5.6: @@ -27291,8 +27317,6 @@ snapshots: xpath@0.0.33: {} - xpath@0.0.34: {} - y18n@5.0.8: {} yallist@3.1.1: {}