Should probably have an /unshare command #197

Closed
opened 2026-02-16 17:25:44 -05:00 by yindo · 7 comments
Owner

Originally created by @monotykamary on GitHub (Jun 20, 2025).

Originally assigned to: @thdxr on GitHub.

Although I'm not victim to it, it looks surprisingly easily to misclick /share. Might need some crypto magic here and there.

Originally created by @monotykamary on GitHub (Jun 20, 2025). Originally assigned to: @thdxr on GitHub. Although I'm not victim to it, it looks surprisingly easily to misclick `/share`. Might need some crypto magic here and there.
yindo closed this issue 2026-02-16 17:25:44 -05:00
Author
Owner

@monotykamary commented on GitHub (Jun 20, 2025):

1. Authentication & Authorization

The current share system uses the session's short ID as a public identifier. For unsharing, we'll need:

  • User verification: Store a user identifier when creating shares (already exists in AppInfo)
  • Share ownership: Add an owner_id field to share records
  • Token-based auth: Generate a deletion token when sharing, or use the existing session secret

2. CLI Implementation

// Add command to registry?
SessionUnshareCommand = NewCommand("session:unshare", "unshare session", "<leader>u")
// Handle in TUI
case commands.SessionUnshareCommand:
    response, err := a.app.Client.DeleteSessionShareWithResponse(
        context.Background(),
        client.DeleteSessionShareJSONRequestBody{
            SessionID: a.app.Session.Id,
            UserID: a.app.AppInfo.UserId, // For ownership verification
        },
    )

3. Backend API Changes

Add a new endpoint /session_unshare or DELETE /session_share:

  • Verify the requesting user owns the session
  • Delete from R2 bucket
  • Clear Durable Object storage
  • Broadcast termination to connected WebSocket clients
  • Return success/error status

4. Data Cleanup Requirements

  • R2 Storage: Delete all objects under sessions/{sessionId}/
  • Durable Object: Clear all stored state and close WebSocket connections
  • Share metadata: Remove share record from any tracking system

5. Security Considerations

  • Ownership verification: Only the session creator can unshare
  • Cascading deletion: Ensure all related data is removed
  • Rate limiting: Prevent abuse of deletion endpoint
  • Audit trail: Log unshare actions for debugging
  • Grace period: Consider soft delete with recovery option

6. Edge Cases

  • Active viewers when unsharing (show graceful error)
  • Partially synced sessions
  • Network failures during deletion
  • Re-sharing after unsharing
  • Child sessions (if parent is unshared)

7. User Experience

  • Confirmation prompt before unsharing
  • Success/error notifications
  • Clear messaging for viewers when session is unshared
  • Option to list all shared sessions for management

The implementation would touch multiple parts of the system but is straightforward given the existing architecture. The key challenge is ensuring proper user authentication without making the system too complex.

@monotykamary commented on GitHub (Jun 20, 2025): ### 1. Authentication & Authorization The current share system uses the session's short ID as a public identifier. For unsharing, we'll need: - User verification: Store a user identifier when creating shares (already exists in AppInfo) - Share ownership: Add an `owner_id` field to share records - Token-based auth: Generate a deletion token when sharing, or use the existing session secret ### 2. CLI Implementation ```go // Add command to registry? SessionUnshareCommand = NewCommand("session:unshare", "unshare session", "<leader>u") ``` ```go // Handle in TUI case commands.SessionUnshareCommand: response, err := a.app.Client.DeleteSessionShareWithResponse( context.Background(), client.DeleteSessionShareJSONRequestBody{ SessionID: a.app.Session.Id, UserID: a.app.AppInfo.UserId, // For ownership verification }, ) ``` ### 3. Backend API Changes Add a new endpoint `/session_unshare` or `DELETE /session_share`: - Verify the requesting user owns the session - Delete from R2 bucket - Clear Durable Object storage - Broadcast termination to connected WebSocket clients - Return success/error status ### 4. Data Cleanup Requirements - R2 Storage: Delete all objects under `sessions/{sessionId}/` - Durable Object: Clear all stored state and close WebSocket connections - Share metadata: Remove share record from any tracking system ### 5. Security Considerations - Ownership verification: Only the session creator can unshare - Cascading deletion: Ensure all related data is removed - Rate limiting: Prevent abuse of deletion endpoint - Audit trail: Log unshare actions for debugging - Grace period: Consider soft delete with recovery option ### 6. Edge Cases - Active viewers when unsharing (show graceful error) - Partially synced sessions - Network failures during deletion - Re-sharing after unsharing - Child sessions (if parent is unshared) ### 7. User Experience - Confirmation prompt before unsharing - Success/error notifications - Clear messaging for viewers when session is unshared - Option to list all shared sessions for management The implementation would touch multiple parts of the system but is straightforward given the existing architecture. The key challenge is ensuring proper user authentication without making the system too complex.
Author
Owner

@thdxr commented on GitHub (Jun 20, 2025):

@adamdotdevin i added session_unshare to the server.ts

@thdxr commented on GitHub (Jun 20, 2025): @adamdotdevin i added session_unshare to the server.ts
Author
Owner

@tmeire commented on GitHub (Jun 21, 2025):

@adamdotdevin @thdxr I took a stab at implementing the /unshare functionality.

Is there a known issue with shares from the dev branch? When I look at a share from a dev session, the share link returns 522. The dev sessions get shared to dev.opencode.ai, but that service always returns opencode.ai urls.

Not sure yet where it fails, but the session is not deleted from the server after calling the share_delete endpoint. Current hypothesis is the secret is not passed from the tui all the way to the remote server.

@tmeire commented on GitHub (Jun 21, 2025): @adamdotdevin @thdxr I took a stab at implementing the `/unshare` functionality. ~Is there a known issue with shares from the dev branch? When I look at a share from a dev session, the share link returns 522.~ The dev sessions get shared to dev.opencode.ai, but that service [always returns opencode.ai urls](https://github.com/sst/opencode/blob/dev/packages/function/src/api.ts#L123). Not sure yet where it fails, but the session is not deleted from the server after calling the share_delete endpoint. Current hypothesis is the secret is not passed from the tui all the way to the remote server.
Author
Owner

@neoromantique commented on GitHub (Jun 30, 2025):

@thdxr in the mean time, is there a way to contact someone to invalidate a share link that was accidentally shared?

It's very unfortunate that this crucial functionality has been omitted, considering the possible scope of leaks.

@neoromantique commented on GitHub (Jun 30, 2025): @thdxr in the mean time, is there a way to contact someone to invalidate a share link that was accidentally shared? It's very unfortunate that this crucial functionality has been omitted, considering the possible scope of leaks.
Author
Owner

@adamdotdevin commented on GitHub (Jun 30, 2025):

if you delete the session, it will delete all data including share data that was sent to cloudflare; is that an option for you in the meantime? we should have /unshare in there soon

@adamdotdevin commented on GitHub (Jun 30, 2025): if you delete the session, it will delete all data including share data that was sent to cloudflare; is that an option for you in the meantime? we should have `/unshare` in there soon
Author
Owner

@neoromantique commented on GitHub (Jun 30, 2025):

if you delete the session, it will delete all data including share data that was sent to cloudflare; is that an option for you in the meantime? we should have /unshare in there soon

I assumed that deleting session would do so, but unfortunately it is still online.

And as far as I understand, /unshare would not be able to delete the previous sessions, right?

@neoromantique commented on GitHub (Jun 30, 2025): > if you delete the session, it will delete all data including share data that was sent to cloudflare; is that an option for you in the meantime? we should have `/unshare` in there soon I assumed that deleting session would do so, but unfortunately it is still online. And as far as I understand, /unshare would not be able to delete the previous sessions, right?
Author
Owner

@adamdotdevin commented on GitHub (Jul 3, 2025):

if you delete the session, it will delete all data including share data that was sent to cloudflare; is that an option for you in the meantime? we should have /unshare in there soon

I assumed that deleting session would do so, but unfortunately it is still online.

And as far as I understand, /unshare would not be able to delete the previous sessions, right?

/unshare is there now and yes, it works for previous sessions

@adamdotdevin commented on GitHub (Jul 3, 2025): > > if you delete the session, it will delete all data including share data that was sent to cloudflare; is that an option for you in the meantime? we should have `/unshare` in there soon > > I assumed that deleting session would do so, but unfortunately it is still online. > > And as far as I understand, /unshare would not be able to delete the previous sessions, right? /unshare is there now and yes, it works for previous sessions
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#197