From 7b3158c102ca3419f75dfaf340d97a1ce44d7cb7 Mon Sep 17 00:00:00 2001 From: Jesse Wierzbinski Date: Thu, 2 Jan 2025 02:55:56 +0100 Subject: [PATCH] fix(api): :ambulance: Fix incorrect builds Everything under api/ should be a route, or it messes up bundling --- .../push/subscription/index.delete.schema.ts | 31 ----- api/api/v1/push/subscription/index.delete.ts | 58 ++++++-- api/api/v1/push/subscription/index.get.ts | 56 ++++++-- .../v1/push/subscription/index.post.schema.ts | 44 ------ api/api/v1/push/subscription/index.post.ts | 108 ++++++++++----- .../v1/push/subscription/index.put.schema.ts | 43 ------ api/api/v1/push/subscription/index.put.ts | 126 ++++++++++++------ .../schemas/pushsubscription.ts | 32 +---- 8 files changed, 246 insertions(+), 252 deletions(-) delete mode 100644 api/api/v1/push/subscription/index.delete.schema.ts delete mode 100644 api/api/v1/push/subscription/index.post.schema.ts rename api/api/v1/push/subscription/index.get.schema.ts => classes/schemas/pushsubscription.ts (70%) diff --git a/api/api/v1/push/subscription/index.delete.schema.ts b/api/api/v1/push/subscription/index.delete.schema.ts deleted file mode 100644 index 4e274f14..00000000 --- a/api/api/v1/push/subscription/index.delete.schema.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { auth } from "@/api"; -import { createRoute, z } from "@hono/zod-openapi"; -import { RolePermissions } from "~/drizzle/schema"; - -export const route = createRoute({ - method: "delete", - path: "/api/v1/push/subscription", - summary: "Remove current subscription", - description: "Removes the current Web Push API subscription.", - externalDocs: { - url: "https://docs.joinmastodon.org/methods/push/#delete", - }, - middleware: [ - auth({ - auth: true, - permissions: [RolePermissions.UsePushNotifications], - scopes: ["push"], - }), - ] as const, - responses: { - 200: { - description: - "PushSubscription successfully deleted or did not exist previously.", - content: { - "application/json": { - schema: z.object({}), - }, - }, - }, - }, -}); diff --git a/api/api/v1/push/subscription/index.delete.ts b/api/api/v1/push/subscription/index.delete.ts index 9150bc88..6bd31558 100644 --- a/api/api/v1/push/subscription/index.delete.ts +++ b/api/api/v1/push/subscription/index.delete.ts @@ -1,23 +1,53 @@ -import { apiRoute } from "@/api"; +import { apiRoute, auth } from "@/api"; +import { createRoute, z } from "@hono/zod-openapi"; import { PushSubscription } from "@versia/kit/db"; import { ApiError } from "~/classes/errors/api-error"; -import { route } from "./index.delete.schema"; +import { RolePermissions } from "~/drizzle/schema"; export default apiRoute((app) => - app.openapi(route, async (context) => { - const { token } = context.get("auth"); + app.openapi( + createRoute({ + method: "delete", + path: "/api/v1/push/subscription", + summary: "Remove current subscription", + description: "Removes the current Web Push API subscription.", + externalDocs: { + url: "https://docs.joinmastodon.org/methods/push/#delete", + }, + middleware: [ + auth({ + auth: true, + permissions: [RolePermissions.UsePushNotifications], + scopes: ["push"], + }), + ] as const, + responses: { + 200: { + description: + "PushSubscription successfully deleted or did not exist previously.", + content: { + "application/json": { + schema: z.object({}), + }, + }, + }, + }, + }), + async (context) => { + const { token } = context.get("auth"); - const ps = await PushSubscription.fromToken(token); + const ps = await PushSubscription.fromToken(token); - if (!ps) { - throw new ApiError( - 404, - "No push subscription associated with this access token", - ); - } + if (!ps) { + throw new ApiError( + 404, + "No push subscription associated with this access token", + ); + } - await ps.delete(); + await ps.delete(); - return context.json({}, 200); - }), + return context.json({}, 200); + }, + ), ); diff --git a/api/api/v1/push/subscription/index.get.ts b/api/api/v1/push/subscription/index.get.ts index 22e11c20..33c8bd2b 100644 --- a/api/api/v1/push/subscription/index.get.ts +++ b/api/api/v1/push/subscription/index.get.ts @@ -1,21 +1,51 @@ -import { apiRoute } from "@/api"; +import { apiRoute, auth } from "@/api"; +import { createRoute } from "@hono/zod-openapi"; import { PushSubscription } from "@versia/kit/db"; import { ApiError } from "~/classes/errors/api-error"; -import { route } from "./index.get.schema"; +import { RolePermissions } from "~/drizzle/schema"; export default apiRoute((app) => - app.openapi(route, async (context) => { - const { token } = context.get("auth"); + app.openapi( + createRoute({ + method: "get", + path: "/api/v1/push/subscription", + summary: "Get current subscription", + description: + "View the PushSubscription currently associated with this access token.", + externalDocs: { + url: "https://docs.joinmastodon.org/methods/push/#get", + }, + middleware: [ + auth({ + auth: true, + permissions: [RolePermissions.UsePushNotifications], + scopes: ["push"], + }), + ] as const, + responses: { + 200: { + description: "WebPushSubscription", + content: { + "application/json": { + schema: PushSubscription.schema, + }, + }, + }, + }, + }), + async (context) => { + const { token } = context.get("auth"); - const ps = await PushSubscription.fromToken(token); + const ps = await PushSubscription.fromToken(token); - if (!ps) { - throw new ApiError( - 404, - "No push subscription associated with this access token", - ); - } + if (!ps) { + throw new ApiError( + 404, + "No push subscription associated with this access token", + ); + } - return context.json(ps.toApi(), 200); - }), + return context.json(ps.toApi(), 200); + }, + ), ); diff --git a/api/api/v1/push/subscription/index.post.schema.ts b/api/api/v1/push/subscription/index.post.schema.ts deleted file mode 100644 index e3cce240..00000000 --- a/api/api/v1/push/subscription/index.post.schema.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { auth, jsonOrForm } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; -import { PushSubscription } from "@versia/kit/db"; -import { RolePermissions } from "~/drizzle/schema"; -import { WebPushSubscriptionInput } from "./index.get.schema"; - -export const route = createRoute({ - method: "post", - path: "/api/v1/push/subscription", - summary: "Subscribe to push notifications", - description: - "Add a Web Push API subscription to receive notifications. Each access token can have one push subscription. If you create a new subscription, the old subscription is deleted.", - externalDocs: { - url: "https://docs.joinmastodon.org/methods/push/#create", - }, - middleware: [ - auth({ - auth: true, - permissions: [RolePermissions.UsePushNotifications], - scopes: ["push"], - }), - jsonOrForm(), - ] as const, - request: { - body: { - content: { - "application/json": { - schema: WebPushSubscriptionInput, - }, - }, - }, - }, - responses: { - 200: { - description: - "A new PushSubscription has been generated, which will send the requested alerts to your endpoint.", - content: { - "application/json": { - schema: PushSubscription.schema, - }, - }, - }, - }, -}); diff --git a/api/api/v1/push/subscription/index.post.ts b/api/api/v1/push/subscription/index.post.ts index af9f7189..6ae65f27 100644 --- a/api/api/v1/push/subscription/index.post.ts +++ b/api/api/v1/push/subscription/index.post.ts @@ -1,45 +1,87 @@ import { apiRoute } from "@/api"; +import { auth, jsonOrForm } from "@/api"; +import { createRoute } from "@hono/zod-openapi"; import { PushSubscription } from "@versia/kit/db"; import { ApiError } from "~/classes/errors/api-error"; +import { WebPushSubscriptionInput } from "~/classes/schemas/pushsubscription"; import { RolePermissions } from "~/drizzle/schema"; -import { route } from "./index.post.schema"; export default apiRoute((app) => - app.openapi(route, async (context) => { - const { user, token } = context.get("auth"); - const { subscription, data } = context.req.valid("json"); + app.openapi( + createRoute({ + method: "post", + path: "/api/v1/push/subscription", + summary: "Subscribe to push notifications", + description: + "Add a Web Push API subscription to receive notifications. Each access token can have one push subscription. If you create a new subscription, the old subscription is deleted.", + externalDocs: { + url: "https://docs.joinmastodon.org/methods/push/#create", + }, + middleware: [ + auth({ + auth: true, + permissions: [RolePermissions.UsePushNotifications], + scopes: ["push"], + }), + jsonOrForm(), + ] as const, + request: { + body: { + content: { + "application/json": { + schema: WebPushSubscriptionInput, + }, + }, + }, + }, + responses: { + 200: { + description: + "A new PushSubscription has been generated, which will send the requested alerts to your endpoint.", + content: { + "application/json": { + schema: PushSubscription.schema, + }, + }, + }, + }, + }), + async (context) => { + const { user, token } = context.get("auth"); + const { subscription, data } = context.req.valid("json"); - if ( - data.alerts["admin.report"] && - !user.hasPermission(RolePermissions.ManageReports) - ) { - throw new ApiError( - 403, - `You do not have the '${RolePermissions.ManageReports}' permission to receive report alerts`, - ); - } + if ( + data.alerts["admin.report"] && + !user.hasPermission(RolePermissions.ManageReports) + ) { + throw new ApiError( + 403, + `You do not have the '${RolePermissions.ManageReports}' permission to receive report alerts`, + ); + } - if ( - data.alerts["admin.sign_up"] && - !user.hasPermission(RolePermissions.ManageAccounts) - ) { - throw new ApiError( - 403, - `You do not have the '${RolePermissions.ManageAccounts}' permission to receive sign-up alerts`, - ); - } + if ( + data.alerts["admin.sign_up"] && + !user.hasPermission(RolePermissions.ManageAccounts) + ) { + throw new ApiError( + 403, + `You do not have the '${RolePermissions.ManageAccounts}' permission to receive sign-up alerts`, + ); + } - await PushSubscription.clearAllOfToken(token); + await PushSubscription.clearAllOfToken(token); - const ps = await PushSubscription.insert({ - alerts: data.alerts, - policy: data.policy, - endpoint: subscription.endpoint, - publicKey: subscription.keys.p256dh, - authSecret: subscription.keys.auth, - tokenId: token.id, - }); + const ps = await PushSubscription.insert({ + alerts: data.alerts, + policy: data.policy, + endpoint: subscription.endpoint, + publicKey: subscription.keys.p256dh, + authSecret: subscription.keys.auth, + tokenId: token.id, + }); - return context.json(ps.toApi(), 200); - }), + return context.json(ps.toApi(), 200); + }, + ), ); diff --git a/api/api/v1/push/subscription/index.put.schema.ts b/api/api/v1/push/subscription/index.put.schema.ts index f9b0a504..e69de29b 100644 --- a/api/api/v1/push/subscription/index.put.schema.ts +++ b/api/api/v1/push/subscription/index.put.schema.ts @@ -1,43 +0,0 @@ -import { auth, jsonOrForm } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; -import { PushSubscription } from "@versia/kit/db"; -import { RolePermissions } from "~/drizzle/schema"; -import { WebPushSubscriptionInput } from "./index.get.schema"; - -export const route = createRoute({ - method: "put", - path: "/api/v1/push/subscription", - summary: "Change types of notifications", - description: - "Updates the current push subscription. Only the data part can be updated. To change fundamentals, a new subscription must be created instead.", - externalDocs: { - url: "https://docs.joinmastodon.org/methods/push/#update", - }, - middleware: [ - auth({ - auth: true, - permissions: [RolePermissions.UsePushNotifications], - scopes: ["push"], - }), - jsonOrForm(), - ] as const, - request: { - body: { - content: { - "application/json": { - schema: WebPushSubscriptionInput.shape.data, - }, - }, - }, - }, - responses: { - 200: { - description: "The WebPushSubscription has been updated.", - content: { - "application/json": { - schema: PushSubscription.schema, - }, - }, - }, - }, -}); diff --git a/api/api/v1/push/subscription/index.put.ts b/api/api/v1/push/subscription/index.put.ts index 65579ad8..d99c9199 100644 --- a/api/api/v1/push/subscription/index.put.ts +++ b/api/api/v1/push/subscription/index.put.ts @@ -1,51 +1,91 @@ -import { apiRoute } from "@/api"; +import { apiRoute, auth, jsonOrForm } from "@/api"; +import { createRoute } from "@hono/zod-openapi"; import { PushSubscription } from "@versia/kit/db"; import { ApiError } from "~/classes/errors/api-error"; +import { WebPushSubscriptionInput } from "~/classes/schemas/pushsubscription"; import { RolePermissions } from "~/drizzle/schema"; -import { route } from "./index.put.schema"; export default apiRoute((app) => - app.openapi(route, async (context) => { - const { user, token } = context.get("auth"); - const { alerts, policy } = context.req.valid("json"); - - const ps = await PushSubscription.fromToken(token); - - if (!ps) { - throw new ApiError( - 404, - "No push subscription associated with this access token", - ); - } - - if ( - alerts["admin.report"] && - !user.hasPermission(RolePermissions.ManageReports) - ) { - throw new ApiError( - 403, - `You do not have the '${RolePermissions.ManageReports}' permission to receive report alerts`, - ); - } - - if ( - alerts["admin.sign_up"] && - !user.hasPermission(RolePermissions.ManageAccounts) - ) { - throw new ApiError( - 403, - `You do not have the '${RolePermissions.ManageAccounts}' permission to receive sign-up alerts`, - ); - } - - await ps.update({ - policy, - alerts: { - ...ps.data.alerts, - ...alerts, + app.openapi( + createRoute({ + method: "put", + path: "/api/v1/push/subscription", + summary: "Change types of notifications", + description: + "Updates the current push subscription. Only the data part can be updated. To change fundamentals, a new subscription must be created instead.", + externalDocs: { + url: "https://docs.joinmastodon.org/methods/push/#update", }, - }); + middleware: [ + auth({ + auth: true, + permissions: [RolePermissions.UsePushNotifications], + scopes: ["push"], + }), + jsonOrForm(), + ] as const, + request: { + body: { + content: { + "application/json": { + schema: WebPushSubscriptionInput.shape.data, + }, + }, + }, + }, + responses: { + 200: { + description: "The WebPushSubscription has been updated.", + content: { + "application/json": { + schema: PushSubscription.schema, + }, + }, + }, + }, + }), + async (context) => { + const { user, token } = context.get("auth"); + const { alerts, policy } = context.req.valid("json"); - return context.json(ps.toApi(), 200); - }), + const ps = await PushSubscription.fromToken(token); + + if (!ps) { + throw new ApiError( + 404, + "No push subscription associated with this access token", + ); + } + + if ( + alerts["admin.report"] && + !user.hasPermission(RolePermissions.ManageReports) + ) { + throw new ApiError( + 403, + `You do not have the '${RolePermissions.ManageReports}' permission to receive report alerts`, + ); + } + + if ( + alerts["admin.sign_up"] && + !user.hasPermission(RolePermissions.ManageAccounts) + ) { + throw new ApiError( + 403, + `You do not have the '${RolePermissions.ManageAccounts}' permission to receive sign-up alerts`, + ); + } + + await ps.update({ + policy, + alerts: { + ...ps.data.alerts, + ...alerts, + }, + }); + + return context.json(ps.toApi(), 200); + }, + ), ); diff --git a/api/api/v1/push/subscription/index.get.schema.ts b/classes/schemas/pushsubscription.ts similarity index 70% rename from api/api/v1/push/subscription/index.get.schema.ts rename to classes/schemas/pushsubscription.ts index 7032a288..5f1435fa 100644 --- a/api/api/v1/push/subscription/index.get.schema.ts +++ b/classes/schemas/pushsubscription.ts @@ -1,7 +1,5 @@ -import { auth } from "@/api"; -import { createRoute, z } from "@hono/zod-openapi"; +import { z } from "@hono/zod-openapi"; import { PushSubscription } from "@versia/kit/db"; -import { RolePermissions } from "~/drizzle/schema"; export const WebPushSubscriptionInput = z .object({ @@ -55,31 +53,3 @@ export const WebPushSubscriptionInput = z }), }) .strict(); - -export const route = createRoute({ - method: "get", - path: "/api/v1/push/subscription", - summary: "Get current subscription", - description: - "View the PushSubscription currently associated with this access token.", - externalDocs: { - url: "https://docs.joinmastodon.org/methods/push/#get", - }, - middleware: [ - auth({ - auth: true, - permissions: [RolePermissions.UsePushNotifications], - scopes: ["push"], - }), - ] as const, - responses: { - 200: { - description: "WebPushSubscription", - content: { - "application/json": { - schema: PushSubscription.schema, - }, - }, - }, - }, -});