Forum Discussion

jaread83's avatar
jaread83
Champion
9 years ago

REST: Authentication ticket

I need to get a users authentication ticket in order to do a specific action.

Basically, the system does not allow users to 'mark all as read' from the 'unread posts' page without marking the entire community as being read. What I am trying to do is place a button on the unread page but it requires a users authentication ticket to do so.

/t5/forums/forumpage.markread/board-id/${coreNode.id}?t:ac=board-id/${coreNode.id}&t:cp=boards/contributions/markedactions&ticket=HU5c6rFKqjfb_4

Without the ticket, the URL returns as there being an authentication error. I have read in another thread someone asking the same thing but was told by Lithium that the ticket was just for their reference. But that isn't right as omitting the ticket in the query string makes the action not work. Subsequently, the ticket only works on a single user so its locked down. I need this authentication ticket to make the link work and do what I need it to do.

Is there a way to get a users authentication ticket via rest so I can use it in my component for my custom button?

6 Replies

  • PaoloT's avatar
    PaoloT
    Lithium Alumni (Retired)
    9 years ago

    Hi jaread83

     

    to my knowledge, there is no API to generate / obtain an authentication ticket. Have you checked if you can achieve the same result via our REST APIs ?

     

    Cheers,

  • jaread83's avatar
    jaread83
    Champion
    9 years ago

    I have checked the api and the authentication string does not appear in the api.

    Is there no way to initialise a 'mark all as read' custom event without the authentication ticket?

  • jaread83's avatar
    jaread83
    Champion
    9 years ago

    Even though I was unable to get the authentication via api, I have instead just used jquery to look at existing links on the page and get that authentication ticket from that instead. Bit of a dirty hack but it does what I need it to do.

    For anyone interested, I have editted the unreadposts page by adding these two components to the unreadpage quilt:

    <component id="category.widget.mark-new"/>
    <component id="category.widget.mark-read"/>

    And then I created a custom component and added it to that page:

    <#if !user.anonymous>
    <@liaAddScript>
    ;(function($) {
    
        var url = ($('.mark-community-read-link').attr('href'));
        var ticket = getURLParameter(url, 'ticket');
        var actionMenuDropDown = $('#actionMenuDropDown .lia-menu-dropdown-items');
        var buttonSeperator = '<li aria-hidden="true"><span class="lia-separator lia-component-common-widget-link-separator"><span class="lia-separator-post"></span><span class="lia-separator-pre"></span></span></li>';
        var pathname = window.location.pathname;
    
        function getURLParameter(url, name) {
            return (RegExp(name + '=' + '(.+?)(&|$)').exec(url)||[,null])[1];
        }
    
        if($('body').hasClass('lia-board')){
            var buttonMarkRead = '<li><a id="boardMarkRead" class="lia-link-navigation mark-board-read-link lia-component-board-widget-mark-read" href="/t5/forums/forumpage.markread/board-id/${coreNode.id}?t:ac=board-id/${coreNode.id}/tab/message&t:cp=boards/contributions/markedactions&ticket=' + ticket + '">Mark all posts in this Board as Read</a></li>';
            var buttonMarkNew = '<li><a id="boardMarkNew" class="lia-link-navigation mark-category-read-link lia-component-category-widget-mark-read" href="/t5/forums/forumpage.marknew/board-id/${coreNode.id}?t:ac=board-id/${coreNode.id}/tab/message&t:cp=boards/contributions/markedactions&ticket=' + ticket + '">Mark all Posts in this Board as New</a></li>';
            $(actionMenuDropDown)
                .append(buttonSeperator)
                .append(buttonMarkNew)
                .append(buttonMarkRead);
    
            if ($('.lia-panel-status-banner-note').length){
                $('#boardMarkRead').addClass('lia-link-disabled').removeAttr('href');
            };
    
        } else {
            if ($('.lia-component-category-widget-mark-read').length){
                var categoryMarkRead = $('.lia-component-category-widget-mark-read');
                var categoryMarkNew = $('.lia-component-category-widget-mark-new');
                var buttonMarkRead = '<li>'+ $(categoryMarkRead).outerHTML() +'</li>';
                var buttonMarkNew = '<li>'+ $(categoryMarkNew).outerHTML() +'</li>';
    
                $(actionMenuDropDown)
                    .append(buttonSeperator)
                    .append(buttonMarkNew)
                    .append(buttonMarkRead);
    
                categoryMarkRead.remove();
                categoryMarkNew.remove();
                
                if ($('.lia-panel-status-banner-note').length){
                    $('#categoryMarkRead').addClass('lia-link-disabled').removeAttr('href');
                };
    
            }
        };
    
        if ($('.lia-panel-status-banner-note').length && (pathname == '/t5/forums/unreadpostspage/tab/message' || pathname == '/t5/forums/unreadpostspage/tab/thread')){
            $('#communityMarkRead').addClass('lia-link-disabled').removeAttr('href');
        };
    
    })(LITHIUM.jQuery);
    </@liaAddScript>
    </#if>

    And what you end up with is this on community, category and board level:

    There is probably a much better way of doing this but this works for me. I could probably do the IF statement a bit more elegantly by using the API to detect the page type (board, category or community level) but I'm unsure how to do that.

  • PaoloT's avatar
    PaoloT
    Lithium Alumni (Retired)
    9 years ago

    CC FaisalK to advise if the above approach is suitable.

  • jaread83's avatar
    jaread83
    Champion
    9 years ago
    I am open to suggestions to make this a bit leaner if at all possible.
  • FaisalK's avatar
    FaisalK
    Lithium Alumni (Retired)
    8 years ago

    It's a clever hack but please beware of couple of things:

     

    1. Adding any portion of user controlled input can introduce potential for security issues such as cross site scripting. In this case the action ticket is being carved from the URL and injected into the page DOM which might result in injection. The cleanest way to avoid injection might be to html encode the ticket value. The action ticket should never contain special characters.  The action ticket might have an underscore but that char is usually not encoded which should make things easier.

     

    2. The action ticket is basically there to provide an anti-automation mechanism and also used as a CSRF ticket. There are various action tickets are there considered sensitive and some that are considered non-sensitive. In this case this action ticket is associated to a non-sensitive action such as marking things read/unread (and that's why it's exposed in the URL). It should be noted that exposing sensitive action tokens  is not a good idea and should never be put into the URL where is can be unintentionally exposed. The Lithium platform will never do this by design, however, Devs need to be aware of this risk.

     

    -FK