From 380b1ee440c6457f204a3fd60bbd0af4cb415d9c Mon Sep 17 00:00:00 2001 From: kabin thakuri Date: Thu, 4 Jun 2026 16:44:49 +0545 Subject: [PATCH 1/7] feat(firebase): decouple package from supertokens --- packages/firebase/package.json | 4 +--- packages/firebase/src/index.ts | 6 +++--- .../src/model/notification/handlers/sendNotification.ts | 5 ++--- .../firebase/src/model/userDevice/handlers/addUserDevice.ts | 5 ++--- .../src/model/userDevice/handlers/removeUserDevice.ts | 5 ++--- pnpm-lock.yaml | 3 --- 6 files changed, 10 insertions(+), 18 deletions(-) diff --git a/packages/firebase/package.json b/packages/firebase/package.json index 2a5162f84..7af8d463f 100644 --- a/packages/firebase/package.json +++ b/packages/firebase/package.json @@ -49,7 +49,6 @@ "pg-mem": "3.0.14", "prettier": "3.8.3", "slonik": "46.8.0", - "supertokens-node": "14.1.4", "typescript": "5.9.3", "vite": "6.4.2", "vitest": "3.2.4" @@ -62,8 +61,7 @@ "fastify": ">=5.2.2", "fastify-plugin": ">=5.0.1", "mercurius": ">=16.1.0", - "slonik": ">=46.1.0", - "supertokens-node": ">=14.1.4" + "slonik": ">=46.1.0" }, "engines": { "node": ">=20" diff --git a/packages/firebase/src/index.ts b/packages/firebase/src/index.ts index 9939b7e86..b457586b1 100644 --- a/packages/firebase/src/index.ts +++ b/packages/firebase/src/index.ts @@ -1,5 +1,3 @@ -import { verifySession } from "supertokens-node/recipe/session/framework/fastify"; - import type { User } from "./types"; import notificationHandlers from "./model/notification/handlers"; @@ -7,7 +5,9 @@ import deviceHandlers from "./model/userDevice/handlers"; declare module "fastify" { interface FastifyInstance { - verifySession: typeof verifySession; + verifySession: (options?: { + sessionRequired?: boolean; + }) => (request: FastifyRequest, reply: FastifyReply) => Promise; } interface FastifyRequest { diff --git a/packages/firebase/src/model/notification/handlers/sendNotification.ts b/packages/firebase/src/model/notification/handlers/sendNotification.ts index 4a43a4ce8..add06bfbc 100644 --- a/packages/firebase/src/model/notification/handlers/sendNotification.ts +++ b/packages/firebase/src/model/notification/handlers/sendNotification.ts @@ -1,6 +1,5 @@ -import type { FastifyReply } from "fastify"; +import type { FastifyReply, FastifyRequest } from "fastify"; import type { MulticastMessage } from "firebase-admin/lib/messaging/messaging-api"; -import type { SessionRequest } from "supertokens-node/framework/fastify"; import type { TestNotificationInput } from "../../../types"; @@ -8,7 +7,7 @@ import { sendPushNotification } from "../../../lib"; import DeviceService from "../../userDevice/service"; const testPushNotification = async ( - request: SessionRequest, + request: FastifyRequest, reply: FastifyReply, ) => { const user = request.user; diff --git a/packages/firebase/src/model/userDevice/handlers/addUserDevice.ts b/packages/firebase/src/model/userDevice/handlers/addUserDevice.ts index 8f29555f2..c342a1e36 100644 --- a/packages/firebase/src/model/userDevice/handlers/addUserDevice.ts +++ b/packages/firebase/src/model/userDevice/handlers/addUserDevice.ts @@ -1,11 +1,10 @@ -import type { FastifyReply } from "fastify"; -import type { SessionRequest } from "supertokens-node/framework/fastify"; +import type { FastifyReply, FastifyRequest } from "fastify"; import type { UserDeviceCreateInput } from "../../../types"; import Service from "../service"; -const addUserDevice = async (request: SessionRequest, reply: FastifyReply) => { +const addUserDevice = async (request: FastifyRequest, reply: FastifyReply) => { const { body, config, dbSchema, slonik, user } = request; if (!user) { diff --git a/packages/firebase/src/model/userDevice/handlers/removeUserDevice.ts b/packages/firebase/src/model/userDevice/handlers/removeUserDevice.ts index f5f8504fb..3821047db 100644 --- a/packages/firebase/src/model/userDevice/handlers/removeUserDevice.ts +++ b/packages/firebase/src/model/userDevice/handlers/removeUserDevice.ts @@ -1,10 +1,9 @@ -import type { FastifyReply } from "fastify"; -import type { SessionRequest } from "supertokens-node/framework/fastify"; +import type { FastifyReply, FastifyRequest } from "fastify"; import Service from "../service"; const removeUserDevice = async ( - request: SessionRequest, + request: FastifyRequest, reply: FastifyReply, ) => { const user = request.user; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 72ce9811f..90e71264d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -182,9 +182,6 @@ importers: slonik: specifier: 46.8.0 version: 46.8.0(zod@3.25.76) - supertokens-node: - specifier: 14.1.4 - version: 14.1.4 typescript: specifier: 5.9.3 version: 5.9.3 From 4525b808c70c04048b50c3934c8c005b48528c93 Mon Sep 17 00:00:00 2001 From: kabin thakuri Date: Fri, 5 Jun 2026 14:15:23 +0545 Subject: [PATCH 2/7] fix(firebase/notification): rename 'body' to 'message' in TestNotificationInput interface --- .../src/model/notification/handlers/sendNotification.ts | 2 +- packages/firebase/src/types.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/firebase/src/model/notification/handlers/sendNotification.ts b/packages/firebase/src/model/notification/handlers/sendNotification.ts index add06bfbc..c7e688c3f 100644 --- a/packages/firebase/src/model/notification/handlers/sendNotification.ts +++ b/packages/firebase/src/model/notification/handlers/sendNotification.ts @@ -17,8 +17,8 @@ const testPushNotification = async ( } const { - body, data, + message: body, title, userId: receiverId, } = request.body as TestNotificationInput; diff --git a/packages/firebase/src/types.ts b/packages/firebase/src/types.ts index 65b7d49c9..eafb92294 100644 --- a/packages/firebase/src/types.ts +++ b/packages/firebase/src/types.ts @@ -1,10 +1,10 @@ import "@prefabs.tech/fastify-error-handler"; interface TestNotificationInput { - body: string; data?: { [key: string]: string; }; + message: string; title: string; userId: string; } From d0b0856c030eca69d6d537ba8898525b66a18857 Mon Sep 17 00:00:00 2001 From: premsgr77 Date: Tue, 4 Aug 2026 14:31:21 +0545 Subject: [PATCH 3/7] fix(firebase/notification): align GraphQL message input with REST --- packages/firebase/FEATURES.md | 2 +- packages/firebase/GUIDE.md | 4 ++-- .../firebase/src/__test__/notificationResolver.test.ts | 2 +- .../firebase/src/model/notification/graphql/resolver.ts | 9 +++++++-- .../firebase/src/model/notification/graphql/schema.ts | 2 +- 5 files changed, 12 insertions(+), 7 deletions(-) diff --git a/packages/firebase/FEATURES.md b/packages/firebase/FEATURES.md index b2caeec96..02e3712d2 100644 --- a/packages/firebase/FEATURES.md +++ b/packages/firebase/FEATURES.md @@ -106,7 +106,7 @@ 33. **`UserDeviceUpdateInput`** — partial of `UserDevice` excluding timestamps and `userId`. -34. **`TestNotificationInput`** — `{ userId, title, body, data? }`. +34. **`TestNotificationInput`** — `{ userId, title, message, data? }`. ## Constants diff --git a/packages/firebase/GUIDE.md b/packages/firebase/GUIDE.md index cd3f4e314..2e151c68f 100644 --- a/packages/firebase/GUIDE.md +++ b/packages/firebase/GUIDE.md @@ -411,7 +411,7 @@ mutation { data: { userId: "target-user-uuid" title: "New message" - body: "You have a new message" + message: "You have a new message" } ) { message @@ -528,7 +528,7 @@ import type { | `UserDevice` | `{ userId, deviceToken, createdAt: number, updatedAt: number }` | | `UserDeviceCreateInput` | `Partial>` | | `UserDeviceUpdateInput` | `Partial>` | -| `TestNotificationInput` | `{ userId, title, body, data?: Record }` | +| `TestNotificationInput` | `{ userId, title, message, data?: Record }` | ### 35. Route and table constants diff --git a/packages/firebase/src/__test__/notificationResolver.test.ts b/packages/firebase/src/__test__/notificationResolver.test.ts index d2060fa0e..f0f00cb51 100644 --- a/packages/firebase/src/__test__/notificationResolver.test.ts +++ b/packages/firebase/src/__test__/notificationResolver.test.ts @@ -39,8 +39,8 @@ const makeContext = ( const arguments_ = { data: { - body: "World", data: {}, + message: "World", title: "Hello", userId: "user-1", }, diff --git a/packages/firebase/src/model/notification/graphql/resolver.ts b/packages/firebase/src/model/notification/graphql/resolver.ts index a54955eae..8b894ac6b 100644 --- a/packages/firebase/src/model/notification/graphql/resolver.ts +++ b/packages/firebase/src/model/notification/graphql/resolver.ts @@ -11,10 +11,10 @@ const Mutation = { parent: unknown, arguments_: { data: { - body: string; data: { [key: string]: string; }; + message: string; title: string; userId: string; }; @@ -32,7 +32,12 @@ const Mutation = { } try { - const { body, data, title, userId: receiverId } = arguments_.data; + const { + data, + message: body, + title, + userId: receiverId, + } = arguments_.data; if (!receiverId) { return new mercurius.ErrorWithProps("Receiver id is required", {}, 400); diff --git a/packages/firebase/src/model/notification/graphql/schema.ts b/packages/firebase/src/model/notification/graphql/schema.ts index 194e8a777..1355e75b8 100644 --- a/packages/firebase/src/model/notification/graphql/schema.ts +++ b/packages/firebase/src/model/notification/graphql/schema.ts @@ -8,7 +8,7 @@ const notificationSchema = gql` input SendNotificationInput { userId: String! title: String! - body: String! + message: String! } type Mutation { From 3cd605ef61459b421b77afc518312c321a2086b7 Mon Sep 17 00:00:00 2001 From: premsgr77 Date: Tue, 4 Aug 2026 14:57:31 +0545 Subject: [PATCH 4/7] fix(firebase): finish decoupling docs cleanup Update firebase docs to describe the host-provided auth contract after removing the direct SuperTokens dependency. Remove leftover test and build references from the package. --- packages/firebase/FEATURES.md | 2 +- packages/firebase/GUIDE.md | 23 ++++++++----------- packages/firebase/README.md | 9 ++++---- .../firebase/src/__test__/handlers.test.ts | 1 - packages/firebase/vite.config.ts | 1 - 5 files changed, 14 insertions(+), 22 deletions(-) diff --git a/packages/firebase/FEATURES.md b/packages/firebase/FEATURES.md index 02e3712d2..a0183fb27 100644 --- a/packages/firebase/FEATURES.md +++ b/packages/firebase/FEATURES.md @@ -88,7 +88,7 @@ ## Module Augmentations -26. **`FastifyInstance.verifySession`** — declares `verifySession` (from `supertokens-node`) on the Fastify instance interface. +26. **`FastifyInstance.verifySession`** — declares a structural `verifySession` on the Fastify instance interface, expected to be decorated by the host auth plugin. 27. **`FastifyRequest.user`** — declares an optional `user: User` property on all Fastify requests. diff --git a/packages/firebase/GUIDE.md b/packages/firebase/GUIDE.md index 2e151c68f..ea495be8d 100644 --- a/packages/firebase/GUIDE.md +++ b/packages/firebase/GUIDE.md @@ -20,8 +20,7 @@ pnpm add @prefabs.tech/fastify-config \ @prefabs.tech/fastify-graphql \ @prefabs.tech/fastify-slonik \ mercurius \ - slonik \ - supertokens-node + slonik ``` ### For monorepo development (pnpm install / test / build) @@ -84,16 +83,14 @@ What we add on top: - `firebaseAdmin` — re-export of the `firebase-admin` default export, so consumers can reach the initialized app without declaring the dependency themselves. - `verifyFirebaseAppCheck` — a Fastify hook over `getAppCheck().verifyToken` (from `firebase-admin/app-check`) that adds per-route opt-in and a uniform `403` response shape. -### `supertokens-node` — Partial Passthrough +### Auth prerequisite -**Their docs:** https://www.npmjs.com/package/supertokens-node - -We use `verifySession` from `supertokens-node/recipe/session/framework/fastify` as a preHandler on every route. We do not wrap or re-export the supertokens initialization; you must configure SuperTokens in your application before registering this plugin. +All REST routes in this package call `fastify.verifySession()` as a preHandler. This package does not depend on SuperTokens directly; the host application must register an auth plugin that decorates `verifySession` and populates `request.user` before this plugin is registered. In this monorepo, that is typically `@prefabs.tech/fastify-user`. What we add on top: -- `FastifyInstance.verifySession` module augmentation so the decorator is typed everywhere. -- `FastifyRequest.user` module augmentation (`{ id: string }`) populated by your application's session middleware. +- `FastifyInstance.verifySession` module augmentation with a structural type so the decorator is typed everywhere. +- `FastifyRequest.user` module augmentation (`{ id: string }`) populated by your application's auth middleware. ### `fastify-plugin` — Full Passthrough @@ -219,10 +216,9 @@ config.firebase.notification = { Replace any default route handler with your own implementation: ```typescript -import type { FastifyReply } from "fastify"; -import type { SessionRequest } from "supertokens-node/framework/fastify"; +import type { FastifyReply, FastifyRequest } from "fastify"; -const myAddHandler = async (request: SessionRequest, reply: FastifyReply) => { +const myAddHandler = async (request: FastifyRequest, reply: FastifyReply) => { // custom logic reply.send({ ok: true }); }; @@ -652,11 +648,10 @@ async function notifyUser( ```typescript // Disable device routes; use only GraphQL for device management. // Override the notification handler with custom logic. -import type { FastifyReply } from "fastify"; -import type { SessionRequest } from "supertokens-node/framework/fastify"; +import type { FastifyReply, FastifyRequest } from "fastify"; const customSendNotification = async ( - request: SessionRequest, + request: FastifyRequest, reply: FastifyReply, ) => { // custom auditing, rate limiting, etc. diff --git a/packages/firebase/README.md b/packages/firebase/README.md index 996312c1b..4d42e2cb7 100644 --- a/packages/firebase/README.md +++ b/packages/firebase/README.md @@ -23,20 +23,19 @@ Peer dependencies (install compatible versions — see [package.json](./package. - [`fastify-plugin`](https://www.npmjs.com/package/fastify-plugin) - [`mercurius`](https://www.npmjs.com/package/mercurius) - [`slonik`](https://www.npmjs.com/package/slonik) -- [`supertokens-node`](https://www.npmjs.com/package/supertokens-node) ## Installation Install with npm: ```bash -npm install @prefabs.tech/fastify-config @prefabs.tech/fastify-error-handler @prefabs.tech/fastify-graphql @prefabs.tech/fastify-slonik @prefabs.tech/fastify-firebase fastify fastify-plugin mercurius slonik supertokens-node +npm install @prefabs.tech/fastify-config @prefabs.tech/fastify-error-handler @prefabs.tech/fastify-graphql @prefabs.tech/fastify-slonik @prefabs.tech/fastify-firebase fastify fastify-plugin mercurius slonik ``` Install with pnpm: ```bash -pnpm add --filter "@scope/project" @prefabs.tech/fastify-config @prefabs.tech/fastify-error-handler @prefabs.tech/fastify-graphql @prefabs.tech/fastify-slonik @prefabs.tech/fastify-firebase fastify fastify-plugin mercurius slonik supertokens-node +pnpm add --filter "@scope/project" @prefabs.tech/fastify-config @prefabs.tech/fastify-error-handler @prefabs.tech/fastify-graphql @prefabs.tech/fastify-slonik @prefabs.tech/fastify-firebase fastify fastify-plugin mercurius slonik ``` ## Usage @@ -105,10 +104,10 @@ const config: ApiConfig = { }; handlers: { userDevice?: { - addUserDevice: (request: SessionRequest, reply: FastifyReply) => Promise + addUserDevice: (request: FastifyRequest, reply: FastifyReply) => Promise }, notification: { - sendNotification: (request: SessionRequest, reply: FastifyReply) => Promise + sendNotification: (request: FastifyRequest, reply: FastifyReply) => Promise }, }; } diff --git a/packages/firebase/src/__test__/handlers.test.ts b/packages/firebase/src/__test__/handlers.test.ts index 2235a9e9d..e38f52153 100644 --- a/packages/firebase/src/__test__/handlers.test.ts +++ b/packages/firebase/src/__test__/handlers.test.ts @@ -255,7 +255,6 @@ describe("firebase route handlers", () => { headers: { "x-user-id": "sender-1" }, method: "POST", payload: { - body: "Body", data: { orderId: "42" }, message: "Body", title: "Title", diff --git a/packages/firebase/vite.config.ts b/packages/firebase/vite.config.ts index c7e3e1327..07b1f2bd7 100644 --- a/packages/firebase/vite.config.ts +++ b/packages/firebase/vite.config.ts @@ -26,7 +26,6 @@ export default defineConfig(({ mode }) => { // String externals match exact ids only; subpath imports // (firebase-admin/app-check) would otherwise be bundled. /^firebase-admin\//, - /^supertokens-node\//, ], output: { exports: "named", From d4f295da82a86aa7f4389a374954cc42abf9822b Mon Sep 17 00:00:00 2001 From: premsgr77 Date: Tue, 4 Aug 2026 15:07:01 +0545 Subject: [PATCH 5/7] fix(firebase/notification): restore body input Restore body as the public notification input field for REST, GraphQL, exported types, tests, and docs to avoid consumer-facing breakage from the message rename. --- packages/firebase/FEATURES.md | 2 +- packages/firebase/GUIDE.md | 4 ++-- packages/firebase/src/__test__/controllers.test.ts | 2 +- packages/firebase/src/__test__/handlers.test.ts | 4 ++-- .../firebase/src/__test__/notificationResolver.test.ts | 2 +- .../firebase/src/model/notification/graphql/resolver.ts | 9 ++------- .../firebase/src/model/notification/graphql/schema.ts | 2 +- .../src/model/notification/handlers/sendNotification.ts | 2 +- packages/firebase/src/model/notification/schema.ts | 4 ++-- packages/firebase/src/types.ts | 2 +- 10 files changed, 14 insertions(+), 19 deletions(-) diff --git a/packages/firebase/FEATURES.md b/packages/firebase/FEATURES.md index a0183fb27..55ceb0b12 100644 --- a/packages/firebase/FEATURES.md +++ b/packages/firebase/FEATURES.md @@ -106,7 +106,7 @@ 33. **`UserDeviceUpdateInput`** — partial of `UserDevice` excluding timestamps and `userId`. -34. **`TestNotificationInput`** — `{ userId, title, message, data? }`. +34. **`TestNotificationInput`** — `{ userId, title, body, data? }`. ## Constants diff --git a/packages/firebase/GUIDE.md b/packages/firebase/GUIDE.md index ea495be8d..39ba4102d 100644 --- a/packages/firebase/GUIDE.md +++ b/packages/firebase/GUIDE.md @@ -407,7 +407,7 @@ mutation { data: { userId: "target-user-uuid" title: "New message" - message: "You have a new message" + body: "You have a new message" } ) { message @@ -524,7 +524,7 @@ import type { | `UserDevice` | `{ userId, deviceToken, createdAt: number, updatedAt: number }` | | `UserDeviceCreateInput` | `Partial>` | | `UserDeviceUpdateInput` | `Partial>` | -| `TestNotificationInput` | `{ userId, title, message, data?: Record }` | +| `TestNotificationInput` | `{ userId, title, body, data?: Record }` | ### 35. Route and table constants diff --git a/packages/firebase/src/__test__/controllers.test.ts b/packages/firebase/src/__test__/controllers.test.ts index e6172efeb..83beb205f 100644 --- a/packages/firebase/src/__test__/controllers.test.ts +++ b/packages/firebase/src/__test__/controllers.test.ts @@ -71,7 +71,7 @@ describe("notification controller — custom handler overrides", async () => { await fastify.inject({ method: "POST", - payload: { message: "Hello", title: "Test", userId: "user-1" }, + payload: { body: "Hello", title: "Test", userId: "user-1" }, url: ROUTE_SEND_NOTIFICATION, }); diff --git a/packages/firebase/src/__test__/handlers.test.ts b/packages/firebase/src/__test__/handlers.test.ts index e38f52153..01c291f25 100644 --- a/packages/firebase/src/__test__/handlers.test.ts +++ b/packages/firebase/src/__test__/handlers.test.ts @@ -226,7 +226,7 @@ describe("firebase route handlers", () => { const response = await fastify.inject({ headers: { "x-user-id": "sender-1" }, method: "POST", - payload: { message: "Body", title: "Title", userId: "receiver-1" }, + payload: { body: "Body", title: "Title", userId: "receiver-1" }, url: ROUTE_SEND_NOTIFICATION, }); @@ -255,8 +255,8 @@ describe("firebase route handlers", () => { headers: { "x-user-id": "sender-1" }, method: "POST", payload: { + body: "Body", data: { orderId: "42" }, - message: "Body", title: "Title", userId: "receiver-1", }, diff --git a/packages/firebase/src/__test__/notificationResolver.test.ts b/packages/firebase/src/__test__/notificationResolver.test.ts index f0f00cb51..d2060fa0e 100644 --- a/packages/firebase/src/__test__/notificationResolver.test.ts +++ b/packages/firebase/src/__test__/notificationResolver.test.ts @@ -39,8 +39,8 @@ const makeContext = ( const arguments_ = { data: { + body: "World", data: {}, - message: "World", title: "Hello", userId: "user-1", }, diff --git a/packages/firebase/src/model/notification/graphql/resolver.ts b/packages/firebase/src/model/notification/graphql/resolver.ts index 8b894ac6b..a54955eae 100644 --- a/packages/firebase/src/model/notification/graphql/resolver.ts +++ b/packages/firebase/src/model/notification/graphql/resolver.ts @@ -11,10 +11,10 @@ const Mutation = { parent: unknown, arguments_: { data: { + body: string; data: { [key: string]: string; }; - message: string; title: string; userId: string; }; @@ -32,12 +32,7 @@ const Mutation = { } try { - const { - data, - message: body, - title, - userId: receiverId, - } = arguments_.data; + const { body, data, title, userId: receiverId } = arguments_.data; if (!receiverId) { return new mercurius.ErrorWithProps("Receiver id is required", {}, 400); diff --git a/packages/firebase/src/model/notification/graphql/schema.ts b/packages/firebase/src/model/notification/graphql/schema.ts index 1355e75b8..194e8a777 100644 --- a/packages/firebase/src/model/notification/graphql/schema.ts +++ b/packages/firebase/src/model/notification/graphql/schema.ts @@ -8,7 +8,7 @@ const notificationSchema = gql` input SendNotificationInput { userId: String! title: String! - message: String! + body: String! } type Mutation { diff --git a/packages/firebase/src/model/notification/handlers/sendNotification.ts b/packages/firebase/src/model/notification/handlers/sendNotification.ts index c7e688c3f..add06bfbc 100644 --- a/packages/firebase/src/model/notification/handlers/sendNotification.ts +++ b/packages/firebase/src/model/notification/handlers/sendNotification.ts @@ -17,8 +17,8 @@ const testPushNotification = async ( } const { + body, data, - message: body, title, userId: receiverId, } = request.body as TestNotificationInput; diff --git a/packages/firebase/src/model/notification/schema.ts b/packages/firebase/src/model/notification/schema.ts index e94b41348..fcc6a1745 100644 --- a/packages/firebase/src/model/notification/schema.ts +++ b/packages/firebase/src/model/notification/schema.ts @@ -1,11 +1,11 @@ export const sendNotificationSchema = { body: { properties: { - message: { type: "string" }, + body: { type: "string" }, title: { type: "string" }, userId: { type: "string" }, }, - required: ["title", "message", "userId"], + required: ["title", "body", "userId"], type: "object", }, description: "Send a notification to a specific user", diff --git a/packages/firebase/src/types.ts b/packages/firebase/src/types.ts index eafb92294..65b7d49c9 100644 --- a/packages/firebase/src/types.ts +++ b/packages/firebase/src/types.ts @@ -1,10 +1,10 @@ import "@prefabs.tech/fastify-error-handler"; interface TestNotificationInput { + body: string; data?: { [key: string]: string; }; - message: string; title: string; userId: string; } From a9c234ec5c9e22adcf15d095e05e44b00ddfdbb7 Mon Sep 17 00:00:00 2001 From: premsgr77 Date: Tue, 4 Aug 2026 15:28:12 +0545 Subject: [PATCH 6/7] fix(firebase): resolve auth typing docs mismatch Remove firebase's public verifySession augmentation to avoid conflicts with host auth plugins. Update the firebase docs to reflect the restored body field and auth-agnostic session examples. --- packages/firebase/FEATURES.md | 2 +- packages/firebase/GUIDE.md | 14 ++++++-------- packages/firebase/src/index.ts | 6 ------ .../firebase/src/lib/getVerifySessionPreHandler.ts | 14 ++++++++++++++ .../firebase/src/model/notification/controller.ts | 6 +++++- .../firebase/src/model/userDevice/controller.ts | 11 +++++++++-- 6 files changed, 35 insertions(+), 18 deletions(-) create mode 100644 packages/firebase/src/lib/getVerifySessionPreHandler.ts diff --git a/packages/firebase/FEATURES.md b/packages/firebase/FEATURES.md index 55ceb0b12..2fe7b9d1c 100644 --- a/packages/firebase/FEATURES.md +++ b/packages/firebase/FEATURES.md @@ -88,7 +88,7 @@ ## Module Augmentations -26. **`FastifyInstance.verifySession`** — declares a structural `verifySession` on the Fastify instance interface, expected to be decorated by the host auth plugin. +26. **Auth prerequisite** — REST routes expect a host auth plugin to decorate `fastify.verifySession()` and populate `request.user`; in this monorepo that is typically `@prefabs.tech/fastify-user`. 27. **`FastifyRequest.user`** — declares an optional `user: User` property on all Fastify requests. diff --git a/packages/firebase/GUIDE.md b/packages/firebase/GUIDE.md index 39ba4102d..ee14e3a3c 100644 --- a/packages/firebase/GUIDE.md +++ b/packages/firebase/GUIDE.md @@ -89,7 +89,6 @@ All REST routes in this package call `fastify.verifySession()` as a preHandler. What we add on top: -- `FastifyInstance.verifySession` module augmentation with a structural type so the decorator is typed everywhere. - `FastifyRequest.user` module augmentation (`{ id: string }`) populated by your application's auth middleware. ### `fastify-plugin` — Full Passthrough @@ -290,7 +289,7 @@ Requires a valid SuperTokens session. Associates the authenticated user's ID wit ```typescript // POST /user-device -// Headers: Cookie: sAccessToken=... +// Headers: authenticated session (via host auth plugin) // Body: { "deviceToken": "fcm-token-abc123" } @@ -311,7 +310,7 @@ Requires authentication. Validates that the device token belongs to the requesti ```typescript // DELETE /user-device -// Headers: Cookie: sAccessToken=... +// Headers: authenticated session (via host auth plugin) // Body: { "deviceToken": "fcm-token-abc123" } @@ -328,12 +327,12 @@ Only registered when `config.firebase.notification.test.enabled = true`. Sends a ```typescript // POST /send-notification (or your configured test path) -// Headers: Cookie: sAccessToken=... +// Headers: authenticated session (via host auth plugin) // Body: { "userId": "target-user-uuid", "title": "Hello", - "message": "World", + "body": "World", } // 200: { "message": "Notification sent successfully" } @@ -500,7 +499,6 @@ The package extends four interfaces automatically on import. No action needed ```typescript import "@prefabs.tech/fastify-firebase"; // augmentations applied on import -// fastify.verifySession is now typed // request.user is now typed as User | undefined // MercuriusContext.user is now typed as User // ApiConfig.firebase is now typed with all config options @@ -655,10 +653,10 @@ const customSendNotification = async ( reply: FastifyReply, ) => { // custom auditing, rate limiting, etc. - const { userId, title, message } = request.body as { + const { body, userId, title } = request.body as { + body: string; userId: string; title: string; - message: string; }; // ... custom logic ... reply.send({ success: true, message: "sent" }); diff --git a/packages/firebase/src/index.ts b/packages/firebase/src/index.ts index 8764f01af..67eefb13e 100644 --- a/packages/firebase/src/index.ts +++ b/packages/firebase/src/index.ts @@ -4,12 +4,6 @@ import notificationHandlers from "./model/notification/handlers"; import deviceHandlers from "./model/userDevice/handlers"; declare module "fastify" { - interface FastifyInstance { - verifySession: (options?: { - sessionRequired?: boolean; - }) => (request: FastifyRequest, reply: FastifyReply) => Promise; - } - interface FastifyRequest { user?: User; } diff --git a/packages/firebase/src/lib/getVerifySessionPreHandler.ts b/packages/firebase/src/lib/getVerifySessionPreHandler.ts new file mode 100644 index 000000000..220d2ecde --- /dev/null +++ b/packages/firebase/src/lib/getVerifySessionPreHandler.ts @@ -0,0 +1,14 @@ +import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify"; + +type AuthFastifyInstance = FastifyInstance & { + verifySession: VerifySessionDecorator; +}; + +type VerifySessionDecorator = (options?: { + sessionRequired?: boolean; +}) => (request: FastifyRequest, reply: FastifyReply) => Promise; + +const getVerifySessionPreHandler = (fastify: FastifyInstance) => + (fastify as AuthFastifyInstance).verifySession(); + +export default getVerifySessionPreHandler; diff --git a/packages/firebase/src/model/notification/controller.ts b/packages/firebase/src/model/notification/controller.ts index c00c89453..481586562 100644 --- a/packages/firebase/src/model/notification/controller.ts +++ b/packages/firebase/src/model/notification/controller.ts @@ -1,6 +1,7 @@ import type { FastifyInstance } from "fastify"; import { ROUTE_SEND_NOTIFICATION } from "../../constants"; +import getVerifySessionPreHandler from "../../lib/getVerifySessionPreHandler"; import isFirebaseEnabled from "../../middlewares/isFirebaseEnabled"; import handlers from "./handlers"; import { sendNotificationSchema } from "./schema"; @@ -17,7 +18,10 @@ const plugin = async (fastify: FastifyInstance) => { fastify.post( notificationConfig.test.path || ROUTE_SEND_NOTIFICATION, { - preHandler: [fastify.verifySession(), isFirebaseEnabled(fastify)], + preHandler: [ + getVerifySessionPreHandler(fastify), + isFirebaseEnabled(fastify), + ], schema: sendNotificationSchema, }, handlersConfig?.sendNotification || handlers.sendNotification, diff --git a/packages/firebase/src/model/userDevice/controller.ts b/packages/firebase/src/model/userDevice/controller.ts index f9285679f..01f2789ad 100644 --- a/packages/firebase/src/model/userDevice/controller.ts +++ b/packages/firebase/src/model/userDevice/controller.ts @@ -4,6 +4,7 @@ import { ROUTE_USER_DEVICE_ADD, ROUTE_USER_DEVICE_REMOVE, } from "../../constants"; +import getVerifySessionPreHandler from "../../lib/getVerifySessionPreHandler"; import isFirebaseEnabled from "../../middlewares/isFirebaseEnabled"; import handlers from "./handlers"; import { deleteUserDeviceSchema, postUserDeviceSchema } from "./schema"; @@ -14,7 +15,10 @@ const plugin = async (fastify: FastifyInstance) => { fastify.post( ROUTE_USER_DEVICE_ADD, { - preHandler: [fastify.verifySession(), isFirebaseEnabled(fastify)], + preHandler: [ + getVerifySessionPreHandler(fastify), + isFirebaseEnabled(fastify), + ], schema: postUserDeviceSchema, }, handlersConfig?.addUserDevice || handlers.addUserDevice, @@ -23,7 +27,10 @@ const plugin = async (fastify: FastifyInstance) => { fastify.delete( ROUTE_USER_DEVICE_REMOVE, { - preHandler: [fastify.verifySession(), isFirebaseEnabled(fastify)], + preHandler: [ + getVerifySessionPreHandler(fastify), + isFirebaseEnabled(fastify), + ], schema: deleteUserDeviceSchema, }, handlersConfig?.removeUserDevice || handlers.removeUserDevice, From cfa7d25ace6fa73386e5a02b38544376e092ec8f Mon Sep 17 00:00:00 2001 From: premsgr77 Date: Tue, 4 Aug 2026 18:02:05 +0545 Subject: [PATCH 7/7] refactor(firebase): type verifySession on FastifyInstance Drop the cast helper and call fastify.verifySession() directly from route controllers. --- packages/firebase/FEATURES.md | 2 +- packages/firebase/GUIDE.md | 2 ++ packages/firebase/src/index.ts | 8 ++++++++ .../firebase/src/lib/getVerifySessionPreHandler.ts | 14 -------------- .../firebase/src/model/notification/controller.ts | 6 +----- .../firebase/src/model/userDevice/controller.ts | 11 ++--------- 6 files changed, 14 insertions(+), 29 deletions(-) delete mode 100644 packages/firebase/src/lib/getVerifySessionPreHandler.ts diff --git a/packages/firebase/FEATURES.md b/packages/firebase/FEATURES.md index 2fe7b9d1c..f299d9591 100644 --- a/packages/firebase/FEATURES.md +++ b/packages/firebase/FEATURES.md @@ -88,7 +88,7 @@ ## Module Augmentations -26. **Auth prerequisite** — REST routes expect a host auth plugin to decorate `fastify.verifySession()` and populate `request.user`; in this monorepo that is typically `@prefabs.tech/fastify-user`. +26. **`FastifyInstance.verifySession`** — declares a host-provided `verifySession` preHandler factory on the Fastify instance (no SuperTokens dependency); the host auth plugin (typically `@prefabs.tech/fastify-user`) must decorate it and populate `request.user`. 27. **`FastifyRequest.user`** — declares an optional `user: User` property on all Fastify requests. diff --git a/packages/firebase/GUIDE.md b/packages/firebase/GUIDE.md index ee14e3a3c..85a980b40 100644 --- a/packages/firebase/GUIDE.md +++ b/packages/firebase/GUIDE.md @@ -89,6 +89,7 @@ All REST routes in this package call `fastify.verifySession()` as a preHandler. What we add on top: +- `FastifyInstance.verifySession` module augmentation so the host-provided decorator is typed (shape only — this package does not implement it). - `FastifyRequest.user` module augmentation (`{ id: string }`) populated by your application's auth middleware. ### `fastify-plugin` — Full Passthrough @@ -499,6 +500,7 @@ The package extends four interfaces automatically on import. No action needed ```typescript import "@prefabs.tech/fastify-firebase"; // augmentations applied on import +// fastify.verifySession is now typed (host auth plugin must decorate it) // request.user is now typed as User | undefined // MercuriusContext.user is now typed as User // ApiConfig.firebase is now typed with all config options diff --git a/packages/firebase/src/index.ts b/packages/firebase/src/index.ts index 67eefb13e..954db1480 100644 --- a/packages/firebase/src/index.ts +++ b/packages/firebase/src/index.ts @@ -1,9 +1,17 @@ +import type { FastifyReply } from "fastify"; + import type { User } from "./types"; import notificationHandlers from "./model/notification/handlers"; import deviceHandlers from "./model/userDevice/handlers"; declare module "fastify" { + interface FastifyInstance { + verifySession: (options?: { + sessionRequired?: boolean; + }) => (request: FastifyRequest, reply: FastifyReply) => Promise; + } + interface FastifyRequest { user?: User; } diff --git a/packages/firebase/src/lib/getVerifySessionPreHandler.ts b/packages/firebase/src/lib/getVerifySessionPreHandler.ts deleted file mode 100644 index 220d2ecde..000000000 --- a/packages/firebase/src/lib/getVerifySessionPreHandler.ts +++ /dev/null @@ -1,14 +0,0 @@ -import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify"; - -type AuthFastifyInstance = FastifyInstance & { - verifySession: VerifySessionDecorator; -}; - -type VerifySessionDecorator = (options?: { - sessionRequired?: boolean; -}) => (request: FastifyRequest, reply: FastifyReply) => Promise; - -const getVerifySessionPreHandler = (fastify: FastifyInstance) => - (fastify as AuthFastifyInstance).verifySession(); - -export default getVerifySessionPreHandler; diff --git a/packages/firebase/src/model/notification/controller.ts b/packages/firebase/src/model/notification/controller.ts index 481586562..c00c89453 100644 --- a/packages/firebase/src/model/notification/controller.ts +++ b/packages/firebase/src/model/notification/controller.ts @@ -1,7 +1,6 @@ import type { FastifyInstance } from "fastify"; import { ROUTE_SEND_NOTIFICATION } from "../../constants"; -import getVerifySessionPreHandler from "../../lib/getVerifySessionPreHandler"; import isFirebaseEnabled from "../../middlewares/isFirebaseEnabled"; import handlers from "./handlers"; import { sendNotificationSchema } from "./schema"; @@ -18,10 +17,7 @@ const plugin = async (fastify: FastifyInstance) => { fastify.post( notificationConfig.test.path || ROUTE_SEND_NOTIFICATION, { - preHandler: [ - getVerifySessionPreHandler(fastify), - isFirebaseEnabled(fastify), - ], + preHandler: [fastify.verifySession(), isFirebaseEnabled(fastify)], schema: sendNotificationSchema, }, handlersConfig?.sendNotification || handlers.sendNotification, diff --git a/packages/firebase/src/model/userDevice/controller.ts b/packages/firebase/src/model/userDevice/controller.ts index 01f2789ad..f9285679f 100644 --- a/packages/firebase/src/model/userDevice/controller.ts +++ b/packages/firebase/src/model/userDevice/controller.ts @@ -4,7 +4,6 @@ import { ROUTE_USER_DEVICE_ADD, ROUTE_USER_DEVICE_REMOVE, } from "../../constants"; -import getVerifySessionPreHandler from "../../lib/getVerifySessionPreHandler"; import isFirebaseEnabled from "../../middlewares/isFirebaseEnabled"; import handlers from "./handlers"; import { deleteUserDeviceSchema, postUserDeviceSchema } from "./schema"; @@ -15,10 +14,7 @@ const plugin = async (fastify: FastifyInstance) => { fastify.post( ROUTE_USER_DEVICE_ADD, { - preHandler: [ - getVerifySessionPreHandler(fastify), - isFirebaseEnabled(fastify), - ], + preHandler: [fastify.verifySession(), isFirebaseEnabled(fastify)], schema: postUserDeviceSchema, }, handlersConfig?.addUserDevice || handlers.addUserDevice, @@ -27,10 +23,7 @@ const plugin = async (fastify: FastifyInstance) => { fastify.delete( ROUTE_USER_DEVICE_REMOVE, { - preHandler: [ - getVerifySessionPreHandler(fastify), - isFirebaseEnabled(fastify), - ], + preHandler: [fastify.verifySession(), isFirebaseEnabled(fastify)], schema: deleteUserDeviceSchema, }, handlersConfig?.removeUserDevice || handlers.removeUserDevice,