syntax = "proto3"; package chatto.api.v1; import "buf/validate/validate.proto"; // Browser Web Push subscription commands for the authenticated user. service PushNotificationService { // Stores or updates the caller's browser push subscription. // // The server must have Web Push configured. Clients normally call this after // the browser grants notification permission and returns a PushSubscription. rpc Subscribe(SubscribeRequest) returns (SubscribeResponse); // Removes the caller's browser push subscription by endpoint. // // The call is idempotent: removing an unknown endpoint still succeeds. rpc Unsubscribe(UnsubscribeRequest) returns (UnsubscribeResponse) { option idempotency_level = IDEMPOTENT; } // Sends a test notification to the caller's registered browser subscriptions. // Calls are rate-limited per account. Delivery failures return a generic // unavailable error without exposing the push provider's response body. rpc SendTestNotification(SendTestNotificationRequest) returns (SendTestNotificationResponse); } // Request to store a PushSubscription returned by the browser Push API. message SubscribeRequest { // Absolute HTTPS push service endpoint URL. The server rejects redirects and // destinations that resolve to private or other special-use addresses. string endpoint = 1 [(buf.validate.field).string = { min_len: 1 max_len: 4096 }]; // Client P-256 ECDH public key from PushSubscription.keys.p256dh. string p256dh = 2 [(buf.validate.field).string = { min_len: 1 max_len: 256 }]; // Authentication secret from PushSubscription.keys.auth. string auth = 3 [(buf.validate.field).string = { min_len: 1 max_len: 128 }]; // Optional browser user-agent string for device identification. optional string user_agent = 4 [(buf.validate.field).string.max_len = 512]; // URL host of the Chatto server that supplied the installed web app. The // sending server combines this with its own hostname to reconstruct the // client route. A host can include a port but no scheme, path, or user info. string client_host = 5 [(buf.validate.field).string = { min_len: 1 max_len: 255 }]; // Random per-save capability generated by the client. A cancelled save can // later remove only the record carrying this exact token, even when the same // browser PushSubscription has since moved to another account. string cleanup_token = 6 [(buf.validate.field).string = { min_len: 32 max_len: 128 }]; } // Response from storing a browser push subscription. message SubscribeResponse { reserved 1; reserved "subscribed"; } // Request to remove a browser push subscription. message UnsubscribeRequest { // Push service endpoint URL to remove. string endpoint = 1 [(buf.validate.field).string = { min_len: 1 max_len: 4096 }]; } // Response from removing a browser push subscription. message UnsubscribeResponse { reserved 1; reserved "unsubscribed"; } // Request to test the current user's registered browser push subscriptions. message SendTestNotificationRequest {} // Result of sending a test Web Push notification. message SendTestNotificationResponse { reserved 1; reserved "sent"; }