2025-02-14 16:44:32 +01:00
import { apiRoute , reusedResponses } from "@/api" ;
2025-01-02 02:55:56 +01:00
import { auth , jsonOrForm } from "@/api" ;
import { createRoute } from "@hono/zod-openapi" ;
2025-01-02 01:29:33 +01:00
import { PushSubscription } from "@versia/kit/db" ;
2025-01-02 02:55:56 +01:00
import { WebPushSubscriptionInput } from "~/classes/schemas/pushsubscription" ;
2025-02-12 23:25:22 +01:00
import { WebPushSubscription as WebPushSubscriptionSchema } from "~/classes/schemas/pushsubscription" ;
2025-01-02 01:29:33 +01:00
import { RolePermissions } from "~/drizzle/schema" ;
export default apiRoute ( ( app ) = >
2025-01-02 02:55:56 +01:00
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" ,
} ,
2025-02-14 16:44:32 +01:00
tags : [ "Push Notifications" ] ,
2025-01-02 02:55:56 +01:00
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" : {
2025-02-12 23:25:22 +01:00
schema : WebPushSubscriptionSchema ,
2025-01-02 02:55:56 +01:00
} ,
} ,
} ,
2025-02-14 16:44:32 +01:00
. . . reusedResponses ,
2025-01-02 02:55:56 +01:00
} ,
} ) ,
async ( context ) = > {
const { user , token } = context . get ( "auth" ) ;
2025-01-02 04:13:12 +01:00
const { subscription , data , policy } = context . req . valid ( "json" ) ;
2025-01-02 01:29:33 +01:00
2025-01-02 02:55:56 +01:00
if (
data . alerts [ "admin.report" ] &&
! user . hasPermission ( RolePermissions . ManageReports )
) {
2025-01-02 03:53:38 +01:00
// This shouldn't throw an error in mastodon either
data . alerts [ "admin.report" ] = false ;
2025-01-02 02:55:56 +01:00
}
2025-01-02 01:29:33 +01:00
2025-01-02 02:55:56 +01:00
if (
data . alerts [ "admin.sign_up" ] &&
! user . hasPermission ( RolePermissions . ManageAccounts )
) {
2025-01-02 03:53:38 +01:00
data . alerts [ "admin.sign_up" ] = false ;
2025-01-02 02:55:56 +01:00
}
2025-01-02 01:29:33 +01:00
2025-01-02 02:55:56 +01:00
await PushSubscription . clearAllOfToken ( token ) ;
2025-01-02 01:29:33 +01:00
2025-01-02 02:55:56 +01:00
const ps = await PushSubscription . insert ( {
alerts : data.alerts ,
2025-01-02 04:13:12 +01:00
policy ,
2025-01-02 02:55:56 +01:00
endpoint : subscription.endpoint ,
publicKey : subscription.keys.p256dh ,
authSecret : subscription.keys.auth ,
tokenId : token.id ,
} ) ;
2025-01-02 01:29:33 +01:00
2025-01-02 02:55:56 +01:00
return context . json ( ps . toApi ( ) , 200 ) ;
} ,
) ,
2025-01-02 01:29:33 +01:00
) ;