Skip to content

Conversation

@suhailnadaf509
Copy link
Contributor

@suhailnadaf509 suhailnadaf509 commented Dec 6, 2025

Summary

This PR resolves two issues related to the video/webapp integration:

  • Restores polling functionality for older events
  • Fixes anonymous room invite link redirects caused by URL routing conflicts

Changes

** Feature Flags for Video/Webapp (event.py)**

  • Added default feature flags to ensure newer video features are available for legacy events:

    • chat-moderation
    • polls
    • schedule-control
  • Merged default and event-specific flags to maintain backward compatibility

** Anonymous Room Link Routing (maindomain_urlconf.py)**

  • Introduced AnonymousInviteRedirectView to support short token URLs (e.g. /eGHhXr/)
  • Redirects to standalone SPA video view:
    /{organizer}/{event}/video/standalone/{room_id}/anonymous#invite={token}
  • Added URL pattern for 6-character alphanumeric tokens
  • Placed above presale patterns to avoid slug conflicts

Vue Router Compatibility (main.js)

  • Fixed Vue Router 4 compatibility where router.resolve() returns the route object directly

Testing

  • Verified anonymous room invite links resolve correctly to the standalone video view
  • Confirmed polling features work for both new and older events

Related Issues

  • Fixes anonymous room invite redirect bug
  • Restores polling functionality in video rooms
image

Resolves #1264

Summary by Sourcery

Restore video feature flags for legacy events and add support for anonymous room invite short-link redirects while ensuring Vue Router 4 compatibility in the webapp.

New Features:

  • Provide default video/webapp feature flags (including chat moderation, polls, and schedule control) for events that lack explicit configuration.
  • Support short anonymous room invite tokens that redirect to the standalone video SPA anonymous room view.

Bug Fixes:

  • Ensure video feature flags are correctly merged so newer features like polls work for older events.
  • Fix routing conflicts so anonymous room invite short links no longer collide with organizer/event slugs.
  • Adjust Vue router usage to be compatible with Vue Router 4’s resolve() API when locating anonymous room routes.

Enhancements:

  • Clarify and expand URL patterns for serving video assets and event talk start pages to better support client-side routing.

@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Dec 6, 2025

Reviewer's Guide

Restores default video/webapp feature flags for legacy events, adds short-token anonymous invite redirect routing to the standalone video SPA, and updates Vue Router integration for compatibility with Vue Router 4.

Sequence diagram for anonymous invite short-link redirect to standalone video SPA

sequenceDiagram
    actor AnonymousUser
    participant Browser
    participant DjangoURLConf
    participant AnonymousInviteRedirectView
    participant AnonymousInviteModel
    participant VideoSPA

    AnonymousUser->>Browser: Open short invite URL /eGHhXr/
    Browser->>DjangoURLConf: HTTP GET /eGHhXr/
    DjangoURLConf->>AnonymousInviteRedirectView: Dispatch with token=eGHhXr

    AnonymousInviteRedirectView->>AnonymousInviteModel: get(short_token=token, expires__gte=now())
    AnonymousInviteModel-->>AnonymousInviteRedirectView: AnonymousInvite(event, room, short_token)

    AnonymousInviteRedirectView->>AnonymousInviteRedirectView: Build redirect_url
    AnonymousInviteRedirectView-->>Browser: HTTP 302 Redirect /{organizer}/{event}/video/standalone/{room_id}/anonymous#invite={token}

    Browser->>VideoSPA: GET /{organizer}/{event}/video/standalone/{room_id}/anonymous#invite={token}
    VideoSPA-->>Browser: Serve SPA index.html

    Browser->>VideoSPA: Execute main.js init
    VideoSPA->>VideoSPA: router.replace(relativePath)
    VideoSPA->>VideoSPA: route = router.resolve(relativePath)
    VideoSPA->>VideoSPA: anonymousRoomId from route.params.roomId
    VideoSPA-->>Browser: Mount app with anonymousRoomId
Loading

Entity relationship diagram for AnonymousInvite and related event/video entities

erDiagram
    ORGANIZER {
        int id
        string slug
        string name
    }

    EVENT {
        int id
        string slug
        string locale
        json feature_flags
    }

    ROOM {
        int id
        string name
    }

    ANONYMOUSINVITE {
        int id
        string short_token
        datetime expires
        int event_id
        int room_id
    }

    ORGANIZER ||--o{ EVENT : organizes
    EVENT ||--o{ ROOM : has
    EVENT ||--o{ ANONYMOUSINVITE : allows
    ROOM ||--o{ ANONYMOUSINVITE : for
Loading

Updated class diagram for event feature flags and anonymous invite redirect view

classDiagram
    class Event {
        int id
        string slug
        string locale
        dict feature_flags
        dict default_feature_flags()
    }

    class AnonymousInvite {
        int id
        string short_token
        datetime expires
        int event_id
        int room_id
        AnonymousInvite get(short_token, expires__gte)
    }

    class Organizer {
        int id
        string slug
        string name
    }

    class Room {
        int id
        string name
    }

    class AnonymousInviteRedirectView {
        get(request, token, args, kwargs)
    }

    class Router {
        replace(relativePath)
        resolve(relativePath)
    }

    class WebAppInit {
        init(token, inviteToken)
    }

    Event *-- Organizer : organizer
    Event *-- Room : rooms
    Event o-- AnonymousInvite : invitations
    AnonymousInvite *-- Room : room

    AnonymousInviteRedirectView ..> AnonymousInvite : queries
    AnonymousInviteRedirectView ..> Event : uses_event_data

    WebAppInit ..> Router : uses
    Router ..> Event : navigates_video_routes

    class DefaultFeatureFlags {
        bool use_submission_comments
        bool present_multiple_times
        bool submission_public_review
        bool chat_moderation
        bool polls
        bool schedule_control
    }

    Event ..> DefaultFeatureFlags : merged_into_features
Loading

File-Level Changes

Change Details Files
Ensure video/webapp feature flags (including polls) are enabled by default for all events, including legacy ones.
  • Extend default_feature_flags() to include chat moderation, polls, and schedule control feature flags.
  • Merge default video feature flags with any event-specific feature_flags when building the injected config for the video SPA instead of using event.feature_flags alone.
app/eventyay/base/models/event.py
app/eventyay/multidomain/maindomain_urlconf.py
Add support for 6-character anonymous invite short tokens that redirect to the standalone anonymous video room SPA view.
  • Introduce AnonymousInviteRedirectView that validates non-expired AnonymousInvite short_token values and redirects to /{organizer}/{event}/video/standalone/{room_id}/anonymous#invite={token}.
  • Define an anonymous_invite_patterns URL group that matches 6-character alphanumeric short tokens, ensuring it is registered before presale_patterns_main to avoid organizer slug conflicts.
app/eventyay/multidomain/maindomain_urlconf.py
Refine event-level URL patterns for video assets, SPA routing, and the event talk page.
  • Register a generic video asset route at video/assets/ alongside the existing file-matching regex-based video asset route.
  • Adjust the event talk page route to use a regex-based re_path that supports an optional trailing slash under the event scope.
app/eventyay/multidomain/maindomain_urlconf.py
Fix Vue Router 4 compatibility when resolving routes for anonymous standalone rooms.
  • Update usage of router.resolve(relativePath) to treat the returned value as the route object directly instead of accessing a .route property.
  • Maintain logic that derives anonymousRoomId from the resolved route when its name is 'standalone:anonymous'.
app/eventyay/webapp/src/main.js

Assessment against linked issues

Issue Objective Addressed Explanation
#1264 Fix the Video component's anonymous room link so that it no longer results in an HTTP 404 and instead correctly routes the user to the appropriate video room view.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New security issues found

@suhailnadaf509 suhailnadaf509 marked this pull request as ready for review December 6, 2025 13:17
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes two issues in the video/webapp integration: restores polling functionality for older events by ensuring default feature flags are applied, and resolves anonymous room invite link redirects that were conflicting with organizer slug routing.

Key Changes:

  • Added default video feature flags (chat-moderation, polls, schedule-control) to ensure backward compatibility for legacy events
  • Introduced AnonymousInviteRedirectView to handle short token URLs and redirect to standalone video views
  • Fixed Vue Router 4 compatibility by removing deprecated .route property access from router.resolve()

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
app/eventyay/base/models/event.py Added video/webapp feature flags to defaults for backward compatibility
app/eventyay/multidomain/maindomain_urlconf.py Implemented anonymous invite redirect view, added URL patterns, and merged feature flags in VideoSPAView
app/eventyay/webapp/src/main.js Fixed Vue Router 4 compatibility by accessing route object directly from resolve()

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


# Merge default feature flags with event-specific flags to ensure
# newer features like 'polls' are available even for older events
from eventyay.base.models.event import default_feature_flags
Copy link

Copilot AI Dec 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The inline import of default_feature_flags within the view method can impact performance on every request. Consider moving this import to the top of the file with the other imports for better performance and code organization.

Move line 88 to the top-level imports section (around line 20-21 where other model imports are located).

Copilot uses AI. Check for mistakes.
@suhailnadaf509
Copy link
Contributor Author

@Sak1012 @Saksham-Sirohi @mariobehling Here are some screenshot's reagrding the changes

polling-fix.mp4

@mariobehling
Copy link
Member

@sourcery-ai review

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey there - I've reviewed your changes - here's some feedback:

Blocking issues:

  • Detected a Generic API Key, potentially exposing access to various services and sensitive operations. (link)

General comments:

  • The default_feature_flags import inside the safe_reverse closure will run on every request; consider moving this import to module level (or guarding with a local alias) unless there is a circular import issue.
  • The top-level anonymous_invite_patterns regex for any 6-character token at the root may inadvertently capture legitimate short paths (e.g. marketing slugs or future endpoints); consider namespacing these under a dedicated prefix (such as /i/<token>/) to avoid ambiguity.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The `default_feature_flags` import inside the `safe_reverse` closure will run on every request; consider moving this import to module level (or guarding with a local alias) unless there is a circular import issue.
- The top-level `anonymous_invite_patterns` regex for any 6-character token at the root may inadvertently capture legitimate short paths (e.g. marketing slugs or future endpoints); consider namespacing these under a dedicated prefix (such as `/i/<token>/`) to avoid ambiguity.

## Individual Comments

### Comment 1
<location> `app/eventyay/multidomain/maindomain_urlconf.py:162-171` </location>
<code_context>
+class AnonymousInviteRedirectView(View):
</code_context>

<issue_to_address>
**suggestion (bug_risk):** Build the redirect URL via URL reversing helpers to avoid hard‑coding the path.

The hard‑coded path is brittle if `video` routes (slugs, segments, or names) change and will break when the app is mounted under a subpath (SCRIPT_NAME). Please use `reverse` (or an existing `safe_reverse`/helper) with the route name and kwargs, then pass the reversed URL plus `#invite={token}` to `redirect()`.

Suggested implementation:

```python
class AnonymousInviteRedirectView(View):
    """
    Handle anonymous room invite short tokens (e.g., /eGHhXr/).
    Redirects to the video SPA standalone anonymous room view:
    /{organizer}/{event}/video/standalone/{room_id}/anonymous#invite={token}
    """
    def get(self, request, token, *args, **kwargs):
        try:
            invite = AnonymousInvite.objects.select_related(
                'event', 'event__organizer', 'room'
            ).get(

```

```python
        video_url = safe_reverse(
            'video:standalone_anonymous',
            kwargs={
                'organizer': invite.event.organizer.slug,
                'event': invite.event.slug,
                'room_id': invite.room_id,
            },
        )
        return redirect(f'{video_url}#invite={token}')

```

1. Ensure `redirect` is imported at the top of this file:
   - `from django.shortcuts import redirect`
2. If `safe_reverse` is not already imported in this module, import it from wherever it is defined in your project (it appears to be used earlier in the same file, so this may already be in place).
3. Replace `'video:standalone_anonymous'` with the actual URL name of the SPA standalone anonymous video route, and adjust the `kwargs` keys (`'organizer'`, `'event'`, `'room_id'`) to match the URL pattern’s parameter names (e.g., `organizer_slug`, `event_slug`, `room_id`, etc.).
4. If your project convention uses `reverse` instead of `safe_reverse` here, you can swap `safe_reverse` for `reverse` and ensure `from django.urls import reverse` is imported.
</issue_to_address>

### Comment 2
<location> `app/eventyay/multidomain/maindomain_urlconf.py:332` </location>
<code_context>
abcdefghijklmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ123456789
</code_context>

<issue_to_address>
**security (generic-api-key):** Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

*Source: gitleaks*
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

Bug(Video): Anonymous room link in Video component leads to HTTP 404

2 participants